diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index ba84e2a3..3914dc7c --- a/.gitignore +++ b/.gitignore @@ -1,36 +1,435 @@ -*.mexw64 -*.mexa64 -*.mexmaci64 -*.pdb -*.o -*.ilk -*.asv -*.deps -*.wisdom -*.exe -*.dll -*.asv -*.7z -*Copy*.cuh -*Copy*.hpp -*Copy*.cpp -*tmp.m -MULTEM_binary -MULTEM_binary.rar -MULTEM_binary.zip -compile_mex_general.m -mex_examples_general -mex_files_general -src_temporal -mex_test -.vs -bugs -design -build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Debug -build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Release -gui_bin -mex_bin -EDX -.vscode -multem.zip -multem_stable.zip +*.mexw64 +*.mexa64 +*.mexmaci64 +*.pdb +*.o +*.ilk +*.asv +*.deps +*.wisdom +*.exe +*.dll +*.asv +*.7z +*Copy*.cuh +*Copy*.hpp +*Copy*.cpp +build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Debug +build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Release +.vscode +EDX +multem.zip +multem_stable.zip +mex_example_test +multem_binary +multem_binary.rar +multem_binary.zip +compile_mex_general.m +compile_mex_test.m +mex_files_general +mex_files_test +matlab_functions_nn +mex_examples_general +others +src_temporal +tutorial +bugs +design +src - Copy +visual_studio_multem/.vs +visual_studio_multem/x64 +visual_studio_multem/multem/x64 +mex_files_multem/mex_CUDA_glnxa64.xml +mex_files_multem/mex_CUDA_maci64.xml +mex_files_multem/mex_CUDA_win64.xml +src/atomic_cross_section.cuh +src/cb_spl_intrpl.hpp +src/cpu_fcns_image.hpp +src/cgpu_spt_ptc.cuh +src/crystal_spec.hpp +src/eval_fit_atomic_columns.hpp +src/eval_fit_atomic_columns_c.hpp +src/eval_fit_atomic_columns_c_old.hpp +src/eval_fit_gaussians.hpp +src/peak_finding.cuh +src/incident_wave.cuh +src/eval_fit_gaussians.hpp +src/input_multislice.cuh +src/input_tomography.cuh +src/output_multem.hpp +src/peak_finding.cuh +src/projected_potential.cuh +src/transmission_fcn.cuh +src/wave_function.cuh +src/propagator.cuh +src/tem_simulation.cuh +src/energy_loss.cuh +src/microscope_effects.cuh +matlab_functions/atomic_radius.mat +matlab_functions/center_spec.m +matlab_functions/extract_atomic_pos_lammps.m +matlab_functions/fsd_parm_coef.mat +matlab_functions/g_Grid.m +matlab_functions/ilm_adapthisteq_3d.m +matlab_functions/ilm_add_alpha_channel.m +matlab_functions/ilm_add_filesep.m +matlab_functions/ilm_angle_btw_vectors.m +matlab_functions/ilm_apply_fs_3d_thr.m +matlab_functions/ilm_apply_jitter_jitter.m +matlab_functions/ilm_apply_mask_g_3d.m +matlab_functions/ilm_apply_mtf_g.m +matlab_functions/ilm_apply_pbc.m +matlab_functions/ilm_apply_rs_3d_thr.m +matlab_functions/ilm_apply_rs_3d_thr_2.m +matlab_functions/ilm_apply_spatial_incoh_model.m +matlab_functions/ilm_apply_tr_bw_mask.m +matlab_functions/ilm_apply_wiener_filter.m +matlab_functions/ilm_apply_wiener_filter_ast.m +matlab_functions/ilm_astra_create_parallel3d_proj_geom.m +matlab_functions/ilm_atoms_get_box_size.m +matlab_functions/ilm_at_2_data.m +matlab_functions/ilm_at_p_2_nr_grid.m +matlab_functions/ilm_at_v_2_bd.m +matlab_functions/ilm_bandwidth_limit.m +matlab_functions/ilm_bd_2_data.m +matlab_functions/ilm_bd_2_xy.m +matlab_functions/ilm_bg_subtraction_3d.m +matlab_functions/ilm_bining_image.m +matlab_functions/ilm_build_ellip_par_interp2.m +matlab_functions/ilm_calc_borders_using_at_v.m +matlab_functions/ilm_center_tr_2d_using_at_v.m +matlab_functions/ilm_chk_bound.m +matlab_functions/ilm_chk_bound_eq.m +matlab_functions/ilm_compile.m +matlab_functions/ilm_cosine_loss.m +matlab_functions/ilm_create_mtf_g.m +matlab_functions/ilm_cubic_mask.m +matlab_functions/ilm_cvt_at_v_2_A_txy.m +matlab_functions/ilm_cvt_at_v_2_tr_scy_shx_v.m +matlab_functions/ilm_cvt_at_v_bci_2_at_v_r.m +matlab_functions/ilm_cvt_at_v_r_2_at_v_bci.m +matlab_functions/ilm_cvt_A_txy_2_at_v.m +matlab_functions/ilm_cylindrical_mask.m +matlab_functions/ilm_damp_added_borders.m +matlab_functions/ilm_data_2_stack_3d.m +matlab_functions/ilm_data_2_stack_4d.m +matlab_functions/ilm_defocus_depth.m +matlab_functions/ilm_dflt_at_p.m +matlab_functions/ilm_dir.m +matlab_functions/ilm_dist_pt_2_ln_2d.m +matlab_functions/ilm_dose.m +matlab_functions/ilm_draw_line_mx.m +matlab_functions/ilm_draw_line_mx_aa.m +matlab_functions/ilm_draw_pol_mx.m +matlab_functions/ilm_ellipsoid_butterworth.m +matlab_functions/ilm_elliptical_gaussian_2d_fix_pos.m +matlab_functions/ilm_eval_ellipse_2d.m +matlab_functions/ilm_eval_ellip_interp2.m +matlab_functions/ilm_eval_rad_mtf.m +matlab_functions/ilm_extract_atomic_pos_lammps.m +matlab_functions/ilm_extract_data.m +matlab_functions/ilm_extract_region.m +matlab_functions/ilm_extract_region_using_bd.m +matlab_functions/ilm_extr_marg_frame_gfc.m +matlab_functions/ilm_extr_sq_frame_gfc.m +matlab_functions/ilm_fcc_001_xyc_2_xycg.m +matlab_functions/ilm_fcc_110_xyc_2_xycg.m +matlab_functions/ilm_fcn_butterworth.m +matlab_functions/ilm_fcn_butterworth_3d.m +matlab_functions/ilm_fcn_butterworth_rect.m +matlab_functions/ilm_fd_neighbors.m +matlab_functions/ilm_fd_tc_theta_using_sirt_3df.m +matlab_functions/ilm_fd_tc_using_sirt_3df.m +matlab_functions/ilm_fd_theta_at_p_using_sirt_3df.m +matlab_functions/ilm_fd_theta_tc_0_using_sirt_3df.m +matlab_functions/ilm_fd_theta_using_sirt_3df.m +matlab_functions/ilm_fd_tr_2d_bi.m +matlab_functions/ilm_fd_tr_2d_bi_tem.m +matlab_functions/ilm_fd_tr_2d_ri.m +matlab_functions/ilm_fd_tr_scy_shx_2d_bi.m +matlab_functions/ilm_fd_tr_scy_shx_2d_ri.m +matlab_functions/ilm_fd_tr_using_sirt_3df.m +matlab_functions/ilm_fft2.m +matlab_functions/ilm_find_center_radius_cbed.m +matlab_functions/ilm_find_closest_pos.m +matlab_functions/ilm_find_closest_xy_pos.m +matlab_functions/ilm_fitting_xtl_structure_3d.m +matlab_functions/ilm_fit_ellipse_2d.m +matlab_functions/ilm_fit_elliptical_gaussian_2d_using_fix_pos.m +matlab_functions/ilm_fit_gaussian_2d_using_fix_pos.m +matlab_functions/ilm_fit_gaussian_exp_2d_using_fix_pos.m +matlab_functions/ilm_fit_three_gaussian_2d_using_fix_pos.m +matlab_functions/ilm_fit_two_gaussian_2d_using_fix_pos.m +matlab_functions/ilm_fs_grid_2d.m +matlab_functions/ilm_fs_spatial_incoh_model.m +matlab_functions/ilm_gaussian_2d_fix_pos.m +matlab_functions/ilm_gaussian_exp_2d_fix_pos.m +matlab_functions/ilm_gaussian_win.m +matlab_functions/ilm_gauss_cv_2_data.m +matlab_functions/ilm_gen_lammps_bash.m +matlab_functions/ilm_gen_lammps_relaxation_eam_bash.m +matlab_functions/ilm_gen_lammps_relaxation_eam_in.m +matlab_functions/ilm_gen_lammps_relaxation_sr_h_hs_q_qs_sr_in.m +matlab_functions/ilm_gen_lammps_relaxation_sr_loop_h_hs_sr_in.m +matlab_functions/ilm_gen_tmg_proj.m +matlab_functions/ilm_geom_center_cp.m +matlab_functions/ilm_get_bg.m +matlab_functions/ilm_get_bin_shadow_image.m +matlab_functions/ilm_get_center_tr_2d.m +matlab_functions/ilm_get_ctr_rng.m +matlab_functions/ilm_get_displacement_center.m +matlab_functions/ilm_get_idx_0_idx_e.m +matlab_functions/ilm_get_idx_0_idx_e_2d.m +matlab_functions/ilm_get_idx_0_idx_e_3d.m +matlab_functions/ilm_get_jitter.m +matlab_functions/ilm_get_jitter_opt_flow.m +matlab_functions/ilm_get_mask_3d_thr.m +matlab_functions/ilm_gui_2d_segmentation.m +matlab_functions/ilm_gui_3d_segmentation.m +matlab_functions/ilm_gui_cbed_elliptical_fit.m +matlab_functions/ilm_gui_g_max.m +matlab_functions/ilm_gui_is_over_object.m +matlab_functions/ilm_gui_pcf_sigma.m +matlab_functions/ilm_gui_peak_finding.m +matlab_functions/ilm_gui_rotate_image.m +matlab_functions/ilm_gui_stem_registration.m +matlab_functions/ilm_gui_tomo_aligment.m +matlab_functions/ilm_g_ref_create_mask_gaussian_3d.m +matlab_functions/ilm_g_ref_opt_individual_full.m +matlab_functions/ilm_g_ref_opt_iso_A_3d.m +matlab_functions/ilm_g_ref_opt_iso_A_sigma_3d.m +matlab_functions/ilm_g_ref_opt_iso_sigma_3d.m +matlab_functions/ilm_g_ref_opt_iso_xyz_3d.m +matlab_functions/ilm_g_ref_opt_set_parm_0.m +matlab_functions/ilm_g_ref_opt_vector_3d.m +matlab_functions/ilm_g_ref_opt_vector_full.m +matlab_functions/ilm_g_ref_opt_vector_set_par_0.m +matlab_functions/ilm_g_ref_vector_create_mask_gaussian_3d.m +matlab_functions/ilm_hanning_win.m +matlab_functions/ilm_harm_osc_1d.m +matlab_functions/ilm_harm_osc_2d.m +matlab_functions/ilm_hysitron_video_proc.m +matlab_functions/ilm_idx_2_meshgrid_2d.m +matlab_functions/ilm_idx_2_meshgrid_3d.m +matlab_functions/ilm_imagesc.m +matlab_functions/ilm_image_4fold_replication.m +matlab_functions/ilm_image_centroid.m +matlab_functions/ilm_image_replication.m +matlab_functions/ilm_inv_linear_interp.m +matlab_functions/ilm_jitter_join_dxy.m +matlab_functions/ilm_jitter_opt.m +matlab_functions/ilm_jitter_opt_btw_2.m +matlab_functions/ilm_jitter_opt_flow_analytic.m +matlab_functions/ilm_jitter_rt.m +matlab_functions/ilm_jitter_rti.m +matlab_functions/ilm_jitter_rti_dxy.m +matlab_functions/ilm_jitter_rt_dxy.m +matlab_functions/ilm_jitter_xy.m +matlab_functions/ilm_laguerre.m +matlab_functions/ilm_linear_interp.m +matlab_functions/ilm_line_intxn_2d.m +matlab_functions/ilm_max_dist.m +matlab_functions/ilm_mean_abs_fdata.m +matlab_functions/ilm_mean_abs_fdata_at.m +matlab_functions/ilm_mean_data.m +matlab_functions/ilm_mean_data_at.m +matlab_functions/ilm_mean_data_nr_grid.m +matlab_functions/ilm_mean_fdata.m +matlab_functions/ilm_mean_image.m +matlab_functions/ilm_mean_std.m +matlab_functions/ilm_mean_std_ni.m +matlab_functions/ilm_mean_std_np.m +matlab_functions/ilm_mfft3d_for_fitting.m +matlab_functions/ilm_minmax_norm_image.m +matlab_functions/ilm_min_dist.m +matlab_functions/ilm_min_distance.m +matlab_functions/ilm_min_max.m +matlab_functions/ilm_min_max_ni.m +matlab_functions/ilm_min_max_np.m +matlab_functions/ilm_mrad_2_rAng.m +matlab_functions/ilm_nr_grid_2_data.m +matlab_functions/ilm_nz_data.m +matlab_functions/ilm_orien_xyz.m +matlab_functions/ilm_pca_mx.m +matlab_functions/ilm_pctf.m +matlab_functions/ilm_plot_bd.m +matlab_functions/ilm_plot_circle.m +matlab_functions/ilm_plot_circle_wc.m +matlab_functions/ilm_plot_ellipse.m +matlab_functions/ilm_plot_rectangle.m +matlab_functions/ilm_plot_vectors_3d.m +matlab_functions/ilm_pn_border.m +matlab_functions/ilm_pn_fact.m +matlab_functions/ilm_polyfit_w.m +matlab_functions/ilm_proj_cube.m +matlab_functions/ilm_propagator.m +matlab_functions/ilm_rand.m +matlab_functions/ilm_randa.m +matlab_functions/ilm_randi_r.m +matlab_functions/ilm_randn.m +matlab_functions/ilm_rand_crack_2d.m +matlab_functions/ilm_rand_gt.m +matlab_functions/ilm_rand_gt_c.m +matlab_functions/ilm_rand_im.m +matlab_functions/ilm_rand_rect_shell.m +matlab_functions/ilm_rand_spatial_incoh_coef.m +matlab_functions/ilm_rand_u.m +matlab_functions/ilm_rand_u_theta.m +matlab_functions/ilm_rand_walk_2d.m +matlab_functions/ilm_rAng_2_mrad.m +matlab_functions/ilm_read_angles_cif.m +matlab_functions/ilm_read_ap_cif.m +matlab_functions/ilm_read_ap_dump_lammps.m +matlab_functions/ilm_read_ap_lammps.m +matlab_functions/ilm_read_ap_pdb.m +matlab_functions/ilm_read_ap_xyz.m +matlab_functions/ilm_read_blo.m +matlab_functions/ilm_read_dm.m +matlab_functions/ilm_read_emd.m +matlab_functions/ilm_read_folder_as_3d.m +matlab_functions/ilm_read_info_blo.m +matlab_functions/ilm_read_info_dm.m +matlab_functions/ilm_read_info_mib.m +matlab_functions/ilm_read_info_ser.m +matlab_functions/ilm_read_info_video.m +matlab_functions/ilm_read_lat_parm_cif.m +matlab_functions/ilm_read_mib.m +matlab_functions/ilm_read_mib_4d_dir.m +matlab_functions/ilm_read_mrc.m +matlab_functions/ilm_read_ser.m +matlab_functions/ilm_read_ser_old.m +matlab_functions/ilm_read_ser_or_dm.m +matlab_functions/ilm_read_tif.m +matlab_functions/ilm_read_tif_mat.m +matlab_functions/ilm_read_tif_or_mrc.m +matlab_functions/ilm_read_video.m +matlab_functions/ilm_read_x_hdf5.m +matlab_functions/ilm_read_x_y_hdf5.m +matlab_functions/ilm_read_y_hdf5.m +matlab_functions/ilm_remove_atoms_pbc.m +matlab_functions/ilm_remove_overlaping_xy.m +matlab_functions/ilm_remove_overlaping_xyz.m +matlab_functions/ilm_remove_points_fourier_space.m +matlab_functions/ilm_remove_spike.m +matlab_functions/ilm_replace_filesep.m +matlab_functions/ilm_resc_tem_data.m +matlab_functions/ilm_resize_2_data.m +matlab_functions/ilm_retrieve_threshold.m +matlab_functions/ilm_rot_3d_tr_2d.m +matlab_functions/ilm_rot_cube_3d.m +matlab_functions/ilm_rot_mx_2d.m +matlab_functions/ilm_rot_mx_3d.m +matlab_functions/ilm_rot_tr_2d_2_data.m +matlab_functions/ilm_rs_grid_2d.m +matlab_functions/ilm_rs_spatial_incoh_model.m +matlab_functions/ilm_run.m +matlab_functions/ilm_run_nr_stem.m +matlab_functions/ilm_run_rg_stem.m +matlab_functions/ilm_r_vector_create_mask_gaussian_3d.m +matlab_functions/ilm_search_subdir.m +matlab_functions/ilm_seeds_2_voronoi_polygon.m +matlab_functions/ilm_seed_thr.m +matlab_functions/ilm_select_atoms.m +matlab_functions/ilm_select_atoms_in_box.m +matlab_functions/ilm_select_atoms_out_box.m +matlab_functions/ilm_select_pixels_around.m +matlab_functions/ilm_series_images_filtering.m +matlab_functions/ilm_series_images_remove.m +matlab_functions/ilm_set_borders.m +matlab_functions/ilm_set_bound.m +matlab_functions/ilm_set_rng_state.m +matlab_functions/ilm_sg_2_bl.m +matlab_functions/ilm_show_lattice_par.m +matlab_functions/ilm_show_pcf.m +matlab_functions/ilm_show_proj_xtl.m +matlab_functions/ilm_show_slicing.m +matlab_functions/ilm_show_xtl.m +matlab_functions/ilm_sigma_g_2_sigma_r.m +matlab_functions/ilm_sinc_2d_interpolation.m +matlab_functions/ilm_sirt_3df.m +matlab_functions/ilm_sirt_3df_patch.m +matlab_functions/ilm_sirt_3ds.m +matlab_functions/ilm_sirt_cstr_3df.m +matlab_functions/ilm_sizeof.m +matlab_functions/ilm_size_data.m +matlab_functions/ilm_size_mib.m +matlab_functions/ilm_size_tif.m +matlab_functions/ilm_size_tif_mat.m +matlab_functions/ilm_snr.m +matlab_functions/ilm_sort_files.m +matlab_functions/ilm_spec_recenter.m +matlab_functions/ilm_sphere_mask.m +matlab_functions/ilm_split_range_idx.m +matlab_functions/ilm_spt_gaussian_2d_xy.m +matlab_functions/ilm_spt_gaussian_2d_xyc.m +matlab_functions/ilm_spt_gaussian_2d_xyz.m +matlab_functions/ilm_stack_3d_2_data.m +matlab_functions/ilm_stack_4d_2_data.m +matlab_functions/ilm_stem_4d_aligment.m +matlab_functions/ilm_stem_det_resize.m +matlab_functions/ilm_swap.m +matlab_functions/ilm_TEM_Image_Model.m +matlab_functions/ilm_three_gaussian_2d_fix_pos.m +matlab_functions/ilm_tomo_dir.m +matlab_functions/ilm_tomo_mfft_2d_from_data.m +matlab_functions/ilm_tomo_mfft_2d_from_files.m +matlab_functions/ilm_tomo_ts_align.m +matlab_functions/ilm_tri_2d.m +matlab_functions/ilm_tr_2d_2_data.m +matlab_functions/ilm_tr_at_2d_2_data.m +matlab_functions/ilm_tr_rot_2d_2_data.m +matlab_functions/ilm_two_gaussian_2d_fix_pos.m +matlab_functions/ilm_ucr_create_mask.m +matlab_functions/ilm_ucr_opt_A.m +matlab_functions/ilm_ucr_opt_p_c.m +matlab_functions/ilm_ucr_opt_p_c_v.m +matlab_functions/ilm_ucr_opt_R_u.m +matlab_functions/ilm_ucr_opt_set_parm_0.m +matlab_functions/ilm_ucr_opt_sigma.m +matlab_functions/ilm_ucr_opt_v.m +matlab_functions/ilm_unit_vctr_2d.m +matlab_functions/ilm_unit_vctr_3d.m +matlab_functions/ilm_vect_assign.m +matlab_functions/ilm_write_ap_lammps.m +matlab_functions/ilm_write_ap_pdb.m +matlab_functions/ilm_write_blo.m +matlab_functions/ilm_write_gif.m +matlab_functions/ilm_write_mrc.m +matlab_functions/ilm_write_tif.m +matlab_functions/ilm_write_video.m +matlab_functions/ilm_write_x_2y_hdf5.m +matlab_functions/ilm_write_x_hdf5.m +matlab_functions/ilm_write_x_y_hdf5.m +matlab_functions/ilm_write_y_hdf5.m +matlab_functions/ilm_xtl_build.m +matlab_functions/ilm_xtl_build_base.m +matlab_functions/ilm_xtl_csn_2_sgr.m +matlab_functions/ilm_xtl_css_2_csn.m +matlab_functions/ilm_xtl_css_2_sgr.m +matlab_functions/ilm_xtl_dmt.m +matlab_functions/ilm_xtl_dsm.m +matlab_functions/ilm_xtl_dvect.m +matlab_functions/ilm_xtl_dvect_2_rvect.m +matlab_functions/ilm_xtl_omega.m +matlab_functions/ilm_xtl_rmt.m +matlab_functions/ilm_xtl_rsm.m +matlab_functions/ilm_xtl_rvect.m +matlab_functions/ilm_xtl_sgn_2_csn.m +matlab_functions/ilm_xycg_2_atoms_symm.m +matlab_functions/ilm_xycg_2_atoms_theta.m +matlab_functions/ilm_xy_2_xyc.m +matlab_functions/ilm_Z.m +matlab_functions/ilm_Z_2_str.m +matlab_functions/m2psi_tot_0.mat +matlab_functions/mexBlasLapackCPU.m +matlab_functions/multem_default_values.m +matlab_functions/nvcc_g++.xml +matlab_functions/PCTF.m +matlab_functions/R_Grid.m +matlab_functions/shape_spline.mat +matlab_functions/ShowSlicing.m +matlab_functions/show_crystal.m +matlab_functions/space_groups.mat +matlab_functions/tfm_check_stem_setup.m +matlab_functions/ToDiffScale.m +matlab_functions/xy_projected.mat \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt old mode 100644 new mode 100755 index 20d40b6b..3d90694a --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,674 +1,674 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read . \ No newline at end of file diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 618cf176..b4e8118d --- a/README.md +++ b/README.md @@ -1,108 +1,109 @@ -# MULTEM - -## Introduction -**MULTEM** is a powerful and advanced software package designed to provide researchers with a versatile tool for simulating a wide range of electron microscopy experiments. Developed by Ivan Lobato (Ivanlh20@gmail.com), MULTEM is built on a collection of C++ routines with CUDA support, enabling it to perform efficient and accurate multislice simulations for various TEM experiments. - -MULTEM uses the widely adopted multislice method to simulate electron scattering and wave propagation in a crystal. This method involves dividing the crystal into thin slices and calculating the electron scattering and wave propagation in each slice. This allows for accurate and efficient simulations of various electron microscopy experiments such as high-resolution TEM (HRTEM), scanning TEM (STEM), imaging STEM (ISTEM), electron diffraction (ED), precession electron diffraction (PED), convergent beam electron diffraction (CBED), annular dark field-TEM (ADF-TEM), annular bright field Hollow Cone (ABF-HC), energy filtered TEM (EFTEM), and electron energy loss spectroscopy (EELS). - -MULTEM's implementation is further enhanced by its support for CUDA, a parallel computing platform developed by NVIDIA. This feature enables MULTEM to use graphics processing units (GPUs) for simulations, greatly reducing computation time and increasing simulation speed. - -Currently, there are three ways to use MULTEM:: -- C++: directly using the library -- Matlab: using the provided mex interface -- GUI: using the user-friendly graphical interface - -Please note that the library is under active development and subject to change. The Matlab interface is the recommended way for researchers to use MULTEM. - -## Remarks - -In order to use the GPU capability of MULTEM, you need a Nvidia Graphic card with **compute capability greater than 3.5** and **CUDA 11.8** installed in your operating system. You can check the compute capability of your graphic card using the following nvidia website: https://developer.nvidia.com/cuda-gpus. - -### Using precompiled GUI interface - -The precompiled GUI interface is only available for Windows operating system. - -- Go to [https://github.com/Ivanlh20/MULTEM/releases](https://github.com/Ivanlh20/MULTEM/releases) and download `MULTEM_binary.7z`. -- Execute `vc_redist.x64.exe` located in `gui_bin` folder. -- Execute `multem.exe`. - -### Using precompiled mexfiles for Matlab - -The precompiled mexfiles are only available for Windows operating system and Ubuntu 18.04-based Linux distributions. - -- Go to [https://github.com/Ivanlh20/MULTEM/releases](https://github.com/Ivanlh20/MULTEM/releases) and download `MULTEM.zip`. -- Execute `vc_redist.x64.exe` located in `mex_bin` folder. (Windows only) -- Add the following folders to the Matlab path: crystalline_materials, matlab_functions and mex_bin. -- Run the examples located in 'mex_examples_multem'. - -### Building MULTEM for Matlab - -The following steps have been tested and found to work with Matlab 2022b and CUDA 11.8. It is assumed that a C++ compiler such as Visual Studio 2019 Community, g++11.3 or Clang (Xcode 10.x) is installed on your operating system. Additionally, MULTEM also requires the fftw3, BLAS, and LAPACK libraries to be installed.The following steps have been tested and found to work with Matlab 2022b and CUDA 11.8. It is assumed that a C++ compiler such as Visual Studio 2019 Community, g++11.3 or Clang (Xcode 10.x) is installed on your operating system. Additionally, MULTEM also requires the fftw3, BLAS, and LAPACK libraries to be installed. - -- Firstly, a C++ compiler must be set for Matlab by executing the following command: `mex -setup cpp`. It is important to note that Matlab 2022b only supports the compilers listed above. -- Next, add the following folders to the Matlab path: crystalline_materials, matlab_functions, and mex_bin. -- Run the script `compile_mex_multem.m`. This will create the necessary executable files to run the examples. -- Finally, run the examples located in the `mex_examples_multem folder`. - -### Troubleshooting - -- If MULTEM does not compile with the above procedures, one of the following procedures might fix it - - **for Windows:** - - - Verify the installation of Visual studio 2019 community. - - Verify the installation of Cuda 11.8 (https://developer.nvidia.com/cuda-downloads). - - **for Linux:** - - - Verify that gcc-11.3 and g++11.3 are the default compilers installed in your operating system. In Ubuntu, it can be installed by executing the following commands: - ```bash - sudo apt-get update - sudo apt-get install gcc-11.3 g++-11.3 - ``` - - - Verify the correct installation of Cuda 11.8 (https://developer.nvidia.com/cuda-downloads). - - - Verify the installation of fftw3 libraries. In Ubuntu, it can be installed by executing the following command: - ```bash - sudo apt-get install libfftw3-dev libfftw3-doc - ``` - - - Verify the installation of blas and lapack libraries. In Ubuntu, it can be installed by executing the following command: - ```bash - sudo apt-get install libblas-dev liblapack-dev - ``` - -- Verify the installation path of cuda 11.8, fftw3, blas and lapack. Their installation paths should be specified in the [ilm_mex.m](./matlab_functions/ilm_mex.m). - -**Please cite MULTEM in your publications if it helps your research:** -```bibtex - @article{LVAV16_1, - Author = {I.Lobato and S.Van Aert and J.Verbeeck}, - Journal = {Ultramicroscopy}, - Title = {Progress and new advances in simulating electron microscopy datasets using MULTEM}, - Year = {2016}, - volume = {168}, - pages = {17-27} - } - - @article{LD15_2, - Author = {I. Lobato and D. Van Dyck}, - Journal = {Ultramicroscopy}, - Title = {MULTEM: A new multislice program to perform accurate and fast electron diffraction and imaging simulations using Graphics Processing Units with CUDA}, - Year = {2015}, - volume = {156}, - pages = {9-17} - } - ``` -**if you use our parameterization of the electronscattering factors, please cite the following article:** -```bibtex - @Article{LD14_1, - Title = {{An accurate parameterization for the scattering factors, electron densities and electrostatic potentials for neutral atoms that obey all physical constraints}}, - Author = {I. Lobato and D. Van Dyck}, - Journal = {Acta Crystallographica Section A}, - Year = {2014}, - Pages = {636-649}, - Volume = {70} - } +# MULTEM + +## Introduction + +**MULTEM** is a collection of routines written in C++ with CUDA to perform accurate and fast multislice simulations for different TEM experiments as: HRTEM, STEM, ISTEM, ED, PED, CBED, ADF-TEM, ABF-HC, EFTEM and EELS. It is developed by Ivan Lobato (Ivanlh20@gmail.com). + +Currently, there are three supported ways to use MULTEM: +- C++: using the library itself +- Matlab: using the mex interface +- GUI: using the user graphical interface + +The library is under heavy development and subject to change. +The Matlab interface is the recommended way for researchers. + +## Remarks + +In order to use the GPU capability of MULTEM, you need a Nvidia Graphic card with **compute capability greater than 2.0** and **CUDA 11.0** installed in your operating system. You can check the compute capability of your graphic card using the following nvidia website: https://developer.nvidia.com/cuda-gpus. + +### Using precompiled GUI interface + +The precompiled GUI interface is only available for Windows operating system. + +- Go to [https://github.com/Ivanlh20/MULTEM/releases](https://github.com/Ivanlh20/MULTEM/releases) and download `MULTEM_binary.7z`. +- Execute `vc_redist.x64.exe` located in `gui_bin` folder. +- Execute `multem.exe`. + +### Using precompiled mexfiles for Matlab + +The precompiled mexfiles are only available for Windows operating system and Ubuntu 18.04-based Linux distributions. + +- Go to [https://github.com/Ivanlh20/MULTEM/releases](https://github.com/Ivanlh20/MULTEM/releases) and download `MULTEM.zip`. +- Execute `vc_redist.x64.exe` located in `mex_bin` folder. (Windows only) +- Add the following folders to the Matlab path: crystalline_materials, matlab_functions and mex_bin. +- Run the examples located in 'mex_examples_multem'. + +### Building MULTEM for Matlab + +The following steps work using Matlab 2020b and CUDA 11.0. It assumes that Visual studio 2017 community, g++7.5 or Clang(Xcode 10.x) compiler is installed in your operating system. Additionally, Multem also requires fftw3, blas and lapack libraries. + +- Firstly, a C++ compiler must be set for Matlab by executing the following comand: `mex -setup cpp`. Be aware that Matlab 2020b only supports the above compilers. +- Then add the following folders to the Matlab path: crystalline_materials, matlab_functions and mex_bin. +- Run the `compile_mex_multem.m` script. This will create the required executable files to run the examples. +- Run the examples located in `mex_examples_multem`. + +### Troubleshooting + +- If MULTEM does not compile with the above procedures, one of the following procedures might fix it +- Currently (v2.2.3) some of the files in the Thrust library, that ships with Cuda 10.0 are incompatible with the Multem source code. To compile Multem, this library should be replaced with the Version of Cuda 8.0. [The files can be found in the MULTEM repository](./thrust.zip). + + **for Windows:** + + - Verify the installation of Visual studio 2017 community. + - Verify the installation of Cuda 11.0 (https://developer.nvidia.com/cuda-downloads). + + **for Linux:** + + - Verify that gcc-7.5 and g++7.5 are the default compilers installed in your operating system. In Ubuntu, it can be installed by executing the following commands: + ```bash + sudo apt-get update + sudo apt-get install gcc-7.5 g++-7.5 + ``` + + - Verify the correct installation of Cuda 10.0 (https://developer.nvidia.com/cuda-downloads). + + - Verify the installation of fftw3 libraries. In Ubuntu, it can be installed by executing the following command: + ```bash + sudo apt-get install libfftw3-dev libfftw3-doc + ``` + + - Verify the installation of blas and lapack libraries. In Ubuntu, it can be installed by executing the following command: + ```bash + sudo apt-get install libblas-dev liblapack-dev + ``` + + - Replace the Thrust library folder in location: /usr/local/cuda/include/thrust + +- Verify the installation path of cuda 11.0, fftw3, blas and lapack. Their installation paths should be specified in the [ilm_mex.m](./matlab_functions/ilm_mex.m). + +**Please cite MULTEM in your publications if it helps your research:** +```bibtex + @article{LVAV16_1, + Author = {I.Lobato and S.Van Aert and J.Verbeeck}, + Journal = {Ultramicroscopy}, + Title = {Progress and new advances in simulating electron microscopy datasets using MULTEM}, + Year = {2016}, + volume = {168}, + pages = {17-27} + } + + @article{LD15_2, + Author = {I. Lobato and D. Van Dyck}, + Journal = {Ultramicroscopy}, + Title = {MULTEM: A new multislice program to perform accurate and fast electron diffraction and imaging simulations using Graphics Processing Units with CUDA}, + Year = {2015}, + volume = {156}, + pages = {9-17} + } + ``` +**if you use our parameterization of the electronscattering factors, please cite the following article:** +```bibtex + @Article{LD14_1, + Title = {{An accurate parameterization for the scattering factors, electron densities and electrostatic potentials for neutral atoms that obey all physical constraints}}, + Author = {I. Lobato and D. Van Dyck}, + Journal = {Acta Crystallographica Section A}, + Year = {2014}, + Pages = {636-649}, + Volume = {70} + } ``` \ No newline at end of file diff --git a/compile_mex_multem.m b/compile_mex_multem.m old mode 100644 new mode 100755 index d660dfde..3f479606 --- a/compile_mex_multem.m +++ b/compile_mex_multem.m @@ -1,44 +1,66 @@ -clc; clear all; -addpath('matlab_functions') - -files = { - 'mex_lambda',... - 'mex_sigma',... - 'mex_gamma',... - 'mex_fxeg_data',... - 'mex_feg',... - 'mex_fxg',... - 'mex_pr',... - 'mex_vz',... - 'mex_vr',... - 'mex_vp',... - 'mex_gmax',... - 'mex_min_spl',... - 'mex_mrad_2_rAng',... - 'mex_mrad_2_sigma',... - 'mex_fwhm_2_sigma',... - 'mex_hwhm_2_sigma',... - 'mex_iehwgd_2_sigma',... - 'mex_scherzer_defocus',... - 'mex_scherzer_aperture',... - 'mex_crystal_by_lays',... - 'mex_rdf_3d',... - 'mex_amorp_spec',... - 'mex_add_amorp_lay',... - 'mex_spec_rot',... - 'mex_spec_planes',... - 'mex_spec_slicing',... - 'mex_incident_wave',... - 'mex_propagate',... - 'mex_microscope_aberrations',... - 'mex_projected_potential',... - 'mex_transmission_function',... - 'mex_multem',... - 'mex_wave_function',... - 'mex_apply_ctf' - }; - -for file=files - disp(['Compiling ' file{1}]) - run(['mex_files_multem/',file{1}]) +% Copyright 2021 Ivan Lobato +clear;clc; + +addpath([ pwd '/matlab_functions']) + +if 0 + files = {'mex_spec_planes', ... + 'mex_spec_slicing', ... + 'mex_incident_wave', ... + 'mex_propagate', ... + 'mex_microscope_aberrations', ... + 'mex_projected_potential', ... + 'mex_transmission_function', ... + 'mex_wave_function', ... + 'mex_multem'}; +else + files = {'mex_lambda', ... + 'mex_gamma', ... + 'mex_elec_interact_parm', ... + 'mex_transf_exp_factor', ... + 'mex_rangs_2_mrad', ... + 'mex_mrad_2_rangs', ... + 'mex_mrad_2_sigma', ... + 'mex_fwhm_2_sigma', ... + 'mex_hwhm_2_sigma', ... + 'mex_iehwgd_2_sigma', ... + 'mex_scherzer_defocus', ... + 'mex_scherzer_aperture', ... + 'mex_g_max', ... + 'mex_det_min_spl', ... + 'mex_rdf', ... + 'mex_min_dist', ... + 'mex_max_dist', ... + 'mex_atomic_radius', ... + 'mex_atomic_info', ... + 'mex_feg', ... + 'mex_fxg', ... + 'mex_pr', ... + 'mex_vz', ... + 'mex_vr', ... + 'mex_vzp', ... + 'mex_fxeg_data', ... + 'mex_xtl_csn_2_sgr', ... + 'mex_xtl_css_2_csn', ... + 'mex_xtl_css_2_sgr', ... + 'mex_xtl_sgn_2_csn', ... + 'mex_xtl_build_base', ... + 'mex_xtl_build', ... + 'mex_amorp_build', ... + 'mex_amorp_lay_add', ... + 'mex_spec_rot', ... + 'mex_spec_planes', ... + 'mex_spec_slicing', ... + 'mex_incident_wave', ... + 'mex_propagate', ... + 'mex_microscope_aberrations', ... + 'mex_projected_potential', ... + 'mex_transmission_function', ... + 'mex_wave_function', ... + 'mex_multem'}; +end + +for file=files + disp(['Compiling ' file{1}]) + run(['mex_files_multem/', file{1}]) end \ No newline at end of file diff --git a/crystalline_materials/Ag001_xtl.m b/crystalline_materials/Ag001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Ag110_xtl.m b/crystalline_materials/Ag110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Al001_xtl.m b/crystalline_materials/Al001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Al110_xtl.m b/crystalline_materials/Al110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Au001_xtl.m b/crystalline_materials/Au001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Au110_xtl.m b/crystalline_materials/Au110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Cu001_xtl.m b/crystalline_materials/Cu001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Cu110_xtl.m b/crystalline_materials/Cu110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Diamond110_xtl.m b/crystalline_materials/Diamond110_xtl.m old mode 100644 new mode 100755 index 7f6b60d2..11fceef8 --- a/crystalline_materials/Diamond110_xtl.m +++ b/crystalline_materials/Diamond110_xtl.m @@ -2,22 +2,36 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 3.56/sqrt(2); - b = 3.56; - c = sqrt(2)*3.56/2; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 2; + + xtl_parm.a = 3.56/sqrt(2); + xtl_parm.b = 3.56; + xtl_parm.c = sqrt(2)*3.56/2; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; + % C = 6 % Z x y z rmsd_3d occupancy charge - xtl_parm.uLayer(1).atoms = [6, 0.00, 0.00, 0.00, rmsd_3d, occ, region, charge; 6, 0.50, 0.75, 0.00, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [6, 0.00, 0.25, 0.50, rmsd_3d, occ, region, charge; 6, 0.50, 0.50, 0.50, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + xtl_parm.base = [6, 0.00, 0.00, 0.00, rmsd_3d, occ, tag, charge;... + 6, 0.50, 0.75, 0.00, rmsd_3d, occ, tag, charge;... + 6, 0.00, 0.25, 0.50, rmsd_3d, occ, tag, charge;... + 6, 0.50, 0.50, 0.50, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/GaAs001_xtl.m b/crystalline_materials/GaAs001_xtl.m old mode 100644 new mode 100755 index b4464984..4ab52012 --- a/crystalline_materials/GaAs001_xtl.m +++ b/crystalline_materials/GaAs001_xtl.m @@ -2,25 +2,40 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 5.6537; - b = 5.6537; - c = 5.6537; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 4; + + xtl_parm.a = 5.6537; + xtl_parm.b = 5.6537; + xtl_parm.c = 5.6537; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; + % Ga = 31, As = 33; - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [31, 0.00, 0.00, 0.00, rmsd_3d, occ, region, charge; 31, 0.50, 0.50, 0.00, rmsd_3d, occ, region, charge]; %Ga - xtl_parm.uLayer(2).atoms = [33, 0.25, 0.25, 0.25, rmsd_3d, occ, region, charge; 33, 0.75, 0.75, 0.25, rmsd_3d, occ, region, charge]; %As - xtl_parm.uLayer(3).atoms = [31, 0.00, 0.50, 0.50, rmsd_3d, occ, region, charge; 31, 0.50, 0.00, 0.50, rmsd_3d, occ, region, charge]; %Ga - xtl_parm.uLayer(4).atoms = [33, 0.75, 0.25, 0.75, rmsd_3d, occ, region, charge; 33, 0.25, 0.75, 0.75, rmsd_3d, occ, region, charge]; %As + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [31, 0.00, 0.00, 0.00, rmsd_3d, occ, tag, charge;... + 31, 0.50, 0.50, 0.00, rmsd_3d, occ, tag, charge;... + 33, 0.25, 0.25, 0.25, rmsd_3d, occ, tag, charge;... + 33, 0.75, 0.75, 0.25, rmsd_3d, occ, tag, charge;... + 31, 0.00, 0.50, 0.50, rmsd_3d, occ, tag, charge;... + 31, 0.50, 0.00, 0.50, rmsd_3d, occ, tag, charge;... + 33, 0.75, 0.25, 0.75, rmsd_3d, occ, tag, charge;... + 33, 0.25, 0.75, 0.75, rmsd_3d, occ, tag, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/Ir001_xtl.m b/crystalline_materials/Ir001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Ir110_xtl.m b/crystalline_materials/Ir110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/LaAlO3001_xtl.m b/crystalline_materials/LaAlO3001_xtl.m old mode 100644 new mode 100755 index 351728d3..5abb441c --- a/crystalline_materials/LaAlO3001_xtl.m +++ b/crystalline_materials/LaAlO3001_xtl.m @@ -2,23 +2,38 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 3.7900; - b = 3.79; - c = 3.79; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 2; + + xtl_parm.a = 3.79; + xtl_parm.b = 3.79; + xtl_parm.c = 3.79; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; - % Sr = 38, Ti = 22; O = 8 - % La = 57, Al = 13; O = 8 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [57, 0.0, 0.0, 0.0, rmsd_3d, occ, region, charge; 8, 0.5, 0.5, 0.0, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [8, 0.0, 0.5, 0.5, rmsd_3d, occ, region, charge; 8, 0.5, 0.0, 0.5, rmsd_3d, occ, region, charge; 13, 0.5, 0.5, 0.5, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + + % Sr = 38, Ti = 22;O = 8 + % La = 57, Al = 13;O = 8 + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [57, 0.0, 0.0, 0.0, rmsd_3d, occ, tag, charge;... + 8, 0.5, 0.5, 0.0, rmsd_3d, occ, tag, charge;... + 8, 0.0, 0.5, 0.5, rmsd_3d, occ, tag, charge;... + 8, 0.5, 0.0, 0.5, rmsd_3d, occ, tag, charge;... + 13, 0.5, 0.5, 0.5, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/Mo001_xtl.m b/crystalline_materials/Mo001_xtl.m old mode 100644 new mode 100755 index 9244c9a9..1160ffa0 --- a/crystalline_materials/Mo001_xtl.m +++ b/crystalline_materials/Mo001_xtl.m @@ -1,23 +1,10 @@ function [atoms, lx, ly, lz, a, b, c, dz] = Mo001_xtl(na, nb, nc, ncu, rmsd_3d) - xtl_parm.na = na; - xtl_parm.nb = nb; - xtl_parm.nc = nc; - a = 3.1470; - b = 3.1470; - c = 3.1470; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 2; - occ = 1; - region = 0; - charge = 0; - % Mo = 42 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [42, 0.0, 0.0, 0.0, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [42, 0.5, 0.5, 0.5, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); - - dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + if(nargin<5) + rmsd_3d = 0.085; + end + + Z = ilm_Z('Mo'); + a = 3.147; + + [atoms, lx, ly, lz, a, b, c, dz] = bcc001_xtl(Z, a, na, nb, nc, ncu, rmsd_3d); end \ No newline at end of file diff --git a/crystalline_materials/Ni001_xtl.m b/crystalline_materials/Ni001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Ni110_xtl.m b/crystalline_materials/Ni110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Pb001_xtl.m b/crystalline_materials/Pb001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Pb110_xtl.m b/crystalline_materials/Pb110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Pd001_xtl.m b/crystalline_materials/Pd001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Pd110_xtl.m b/crystalline_materials/Pd110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/PdH001_xtl.m b/crystalline_materials/PdH001_xtl.m old mode 100644 new mode 100755 index ae70da44..4f4f2b02 --- a/crystalline_materials/PdH001_xtl.m +++ b/crystalline_materials/PdH001_xtl.m @@ -2,24 +2,40 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 4.025; - b = 4.025; - c = 4.025; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 2; + + xtl_parm.a = 4.025; + xtl_parm.b = 4.025; + xtl_parm.c = 4.025; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; + % Pd = 46, H = 1 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [46, 0.0, 0.0, 0.0, rmsd_3d, occ, region, charge; 46, 0.5, 0.5, 0.0, rmsd_3d, occ, region, charge;... - 1, 0.5, 0.0, 0.0, rmsd_3d, occ, region, charge; 1, 0.0, 0.5, 0.0, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [46, 0.0, 0.5, 0.5, rmsd_3d, occ, region, charge; 46, 0.5, 0.0, 0.5, rmsd_3d, occ, region, charge;... - 1, 0.0, 0.0, 0.5, rmsd_3d, occ, region, charge; 1, 0.5, 0.5, 0.5, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [46, 0.0, 0.0, 0.0, rmsd_3d, occ, tag, charge;... + 46, 0.5, 0.5, 0.0, rmsd_3d, occ, tag, charge;... + 1, 0.5, 0.0, 0.0, rmsd_3d, occ, tag, charge;... + 1, 0.0, 0.5, 0.0, rmsd_3d, occ, tag, charge;... + 46, 0.0, 0.5, 0.5, rmsd_3d, occ, tag, charge;... + 46, 0.5, 0.0, 0.5, rmsd_3d, occ, tag, charge;... + 1, 0.0, 0.0, 0.5, rmsd_3d, occ, tag, charge;... + 1, 0.5, 0.5, 0.5, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/Primitive_xtl.m b/crystalline_materials/Primitive_xtl.m old mode 100644 new mode 100755 index 8e7244b0..ba415155 --- a/crystalline_materials/Primitive_xtl.m +++ b/crystalline_materials/Primitive_xtl.m @@ -2,23 +2,31 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 4.0780; - b = 4.0780; - c = 4.0780; - a = 6.50; - b = 6.50; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 1; + + xtl_parm.a = 4.0780; + xtl_parm.b = 4.0780; + xtl_parm.c = 4.0780; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; - % Au = 79 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [79, 0.5, 0.5, 0.0, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [79, 0.0, 0.0, 0.0, rmsd_3d, occ, tag, charge]; + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/Pt001_xtl.m b/crystalline_materials/Pt001_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Pt110_xtl.m b/crystalline_materials/Pt110_xtl.m old mode 100644 new mode 100755 diff --git a/crystalline_materials/Si001_xtl.m b/crystalline_materials/Si001_xtl.m old mode 100644 new mode 100755 index 30d41445..57c2b1e2 --- a/crystalline_materials/Si001_xtl.m +++ b/crystalline_materials/Si001_xtl.m @@ -2,24 +2,40 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 5.4307; - b = 5.4307; - c = 5.4307; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 4; + + xtl_parm.a = 5.4307; + xtl_parm.b = 5.4307; + xtl_parm.c = 5.4307; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; + % Si = 14 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [14, 0.00, 0.00, 0.00, rmsd_3d, occ, region, charge; 14, 0.50, 0.50, 0.00, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [14, 0.25, 0.25, 0.25, rmsd_3d, occ, region, charge; 14, 0.75, 0.75, 0.25, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(3).atoms = [14, 0.00, 0.50, 0.50, rmsd_3d, occ, region, charge; 14, 0.50, 0.00, 0.50, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(4).atoms = [14, 0.25, 0.75, 0.75, rmsd_3d, occ, region, charge; 14, 0.75, 0.25, 0.75, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [14, 0.00, 0.00, 0.00, rmsd_3d, occ, tag, charge;... + 14, 0.50, 0.50, 0.00, rmsd_3d, occ, tag, charge;... + 14, 0.25, 0.25, 0.25, rmsd_3d, occ, tag, charge;... + 14, 0.75, 0.75, 0.25, rmsd_3d, occ, tag, charge;... + 14, 0.00, 0.50, 0.50, rmsd_3d, occ, tag, charge;... + 14, 0.50, 0.00, 0.50, rmsd_3d, occ, tag, charge;... + 14, 0.25, 0.75, 0.75, rmsd_3d, occ, tag, charge;... + 14, 0.75, 0.25, 0.75, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/Si110_xtl.m b/crystalline_materials/Si110_xtl.m old mode 100644 new mode 100755 index eb141581..34268964 --- a/crystalline_materials/Si110_xtl.m +++ b/crystalline_materials/Si110_xtl.m @@ -2,22 +2,36 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 5.4307/sqrt(2); - b = 5.4307; - c = sqrt(2)*5.4307/2; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 2; + + xtl_parm.a = 5.4307/sqrt(2); + xtl_parm.b = 5.4307; + xtl_parm.c = sqrt(2)*5.4307/2; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; + % Si = 14 % Z x y z rmsd_3d occupancy charge - xtl_parm.uLayer(1).atoms = [14, 0.00, 0.00, 0.00, rmsd_3d, occ, region, charge; 14, 0.50, 0.75, 0.00, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [14, 0.00, 0.25, 0.50, rmsd_3d, occ, region, charge; 14, 0.50, 0.50, 0.50, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + xtl_parm.base = [14, 0.00, 0.00, 0.00, rmsd_3d, occ, tag, charge;... + 14, 0.50, 0.75, 0.00, rmsd_3d, occ, tag, charge;... + 14, 0.00, 0.25, 0.50, rmsd_3d, occ, tag, charge;... + 14, 0.50, 0.50, 0.50, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/SrTiO3001_xtl.m b/crystalline_materials/SrTiO3001_xtl.m old mode 100644 new mode 100755 index ac1fc33b..319d5e7c --- a/crystalline_materials/SrTiO3001_xtl.m +++ b/crystalline_materials/SrTiO3001_xtl.m @@ -2,22 +2,37 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 3.9050; - b = 3.9050; - c = 3.9050; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 2; + + xtl_parm.a = 3.9050; + xtl_parm.b = 3.9050; + xtl_parm.c = 3.9050; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; - % Sr = 38, Ti = 22; O = 8 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [38, 0.0, 0.0, 0.0, rmsd_3d, occ, region, charge; 8, 0.5, 0.5, 0.0, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [8, 0.0, 0.5, 0.5, rmsd_3d, occ, region, charge; 8, 0.5, 0.0, 0.5, rmsd_3d, occ, region, charge; 22, 0.5, 0.5, 0.5, rmsd_3d, occ, region, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + + % Sr = 38, Ti = 22;O = 8 + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [38, 0.0, 0.0, 0.0, rmsd_3d, occ, tag, charge;... + 8, 0.5, 0.5, 0.0, rmsd_3d, occ, tag, charge;... + 8, 0.0, 0.5, 0.5, rmsd_3d, occ, tag, charge;... + 8, 0.5, 0.0, 0.5, rmsd_3d, occ, tag, charge;... + 22, 0.5, 0.5, 0.5, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/SrTiO3110_xtl.m b/crystalline_materials/SrTiO3110_xtl.m old mode 100644 new mode 100755 index 87cbff1b..1d356e6f --- a/crystalline_materials/SrTiO3110_xtl.m +++ b/crystalline_materials/SrTiO3110_xtl.m @@ -2,25 +2,42 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 3.9050; - b = 3.9050*sqrt(2); - c = 3.9050*sqrt(2); - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 4; + + xtl_parm.a = 3.9050; + xtl_parm.b = 3.9050*sqrt(2); + xtl_parm.c = 3.9050*sqrt(2); + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; - % Sr = 38, Ti = 22; O = 8 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [38, 0.50, 0.00, 0.00, rmsd_3d, occ, region, charge; 8, 0.50, 0.50, 0.00, rmsd_3d, occ, region, charge; 22, 0.0, 0.5, 0.0, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [8, 0.00, 0.25, 0.25, rmsd_3d, occ, region, charge; 8, 0.00, 0.75, 0.25, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(3).atoms = [8, 0.50, 0.00, 0.50, rmsd_3d, occ, region, charge; 38, 0.50, 0.50, 0.50, rmsd_3d, occ, region, charge; 22, 0.00, 0.00, 0.50, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(4).atoms = [8, 0.00, 0.25, 0.75, rmsd_3d, occ, region, charge; 8, 0.00, 0.75, 0.75, rmsd_3d, occ, region, charge]; + + % Sr = 38, Ti = 22;O = 8 + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [38, 0.50, 0.00, 0.00, rmsd_3d, occ, tag, charge;... + 8, 0.50, 0.50, 0.00, rmsd_3d, occ, tag, charge;... + 22, 0.0, 0.5, 0.0, rmsd_3d, occ, tag, charge;... + 8, 0.00, 0.25, 0.25, rmsd_3d, occ, tag, charge... + 8, 0.00, 0.75, 0.25, rmsd_3d, occ, tag, charge;... + 8, 0.50, 0.00, 0.50, rmsd_3d, occ, tag, charge;... + 38, 0.50, 0.50, 0.50, rmsd_3d, occ, tag, charge;... + 22, 0.00, 0.00, 0.50, rmsd_3d, occ, tag, charge;... + 8, 0.00, 0.25, 0.75, rmsd_3d, occ, tag, charge;... + 8, 0.00, 0.75, 0.75, rmsd_3d, occ, tag, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/YH2001_xtl.m b/crystalline_materials/YH2001_xtl.m old mode 100644 new mode 100755 index 29a92129..eb99b08c --- a/crystalline_materials/YH2001_xtl.m +++ b/crystalline_materials/YH2001_xtl.m @@ -2,25 +2,44 @@ xtl_parm.na = na; xtl_parm.nb = nb; xtl_parm.nc = nc; - a = 5.2000; - b = 5.2000; - c = 5.2000; - xtl_parm.a = a; - xtl_parm.b = b; - xtl_parm.c = c; - xtl_parm.nuLayer = 4; + + xtl_parm.a = 5.2000; + xtl_parm.b = 5.2000; + xtl_parm.c = 5.2000; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; - % Au = 79 + + %H = 1, Y = 39 % Z x y z rmsd_3d occupancy charge - xtl_parm.uLayer(1).atoms = [39, 0.0, 0.0, 0.0, rmsd_3d_Y, occ, region, charge; 39, 0.5, 0.5, 0.0, rmsd_3d_Y, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [1, 0.25, 0.25, 0.25, rmsd_3d_H, occ, region, charge; 1, 0.75, 0.25, 0.25, rmsd_3d_H, occ, region, charge; 1, 0.25, 0.75, 0.25, rmsd_3d_H, occ, region, charge; 1, 0.75, 0.75, 0.25, rmsd_3d_H, occ, region, charge]; - xtl_parm.uLayer(3).atoms = [39, 0.0, 0.5, 0.5, rmsd_3d_Y, occ, region, charge; 39, 0.5, 0.0, 0.5, rmsd_3d_Y, occ, region, charge]; - xtl_parm.uLayer(4).atoms = [1, 0.25, 0.25, 0.75, rmsd_3d_H, occ, region, charge; 1, 0.75, 0.25, 0.75, rmsd_3d_H, occ, region, charge; 1, 0.25, 0.75, 0.75, rmsd_3d_H, occ, region, charge; 1, 0.75, 0.75, 0.75, rmsd_3d_H, occ, region, charge]; + xtl_parm.base = [39, 0.0, 0.0, 0.0, rmsd_3d_Y, occ, tag, charge;... + 39, 0.5, 0.5, 0.0, rmsd_3d_Y, occ, tag, charge;... + 1, 0.25, 0.25, 0.25, rmsd_3d_H, occ, tag, charge;... + 1, 0.75, 0.25, 0.25, rmsd_3d_H, occ, tag, charge;... + 1, 0.25, 0.75, 0.25, rmsd_3d_H, occ, tag, charge;... + 1, 0.75, 0.75, 0.25, rmsd_3d_H, occ, tag, charge;... + 39, 0.0, 0.5, 0.5, rmsd_3d_Y, occ, tag, charge;... + 39, 0.5, 0.0, 0.5, rmsd_3d_Y, occ, tag, charge;... + 1, 0.25, 0.25, 0.75, rmsd_3d_H, occ, tag, charge;... + 1, 0.75, 0.25, 0.75, rmsd_3d_H, occ, tag, charge;... + 1, 0.25, 0.75, 0.75, rmsd_3d_H, occ, tag, charge;... + 1, 0.75, 0.75, 0.75, rmsd_3d_H, occ, tag, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; - lx = na*xtl_parm.a; ly = nb*xtl_parm.b; lz = nc*xtl_parm.c; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/bcc001_xtl.m b/crystalline_materials/bcc001_xtl.m new file mode 100755 index 00000000..3646b9c0 --- /dev/null +++ b/crystalline_materials/bcc001_xtl.m @@ -0,0 +1,34 @@ +function [atoms, lx, ly, lz, a, b, c, dz] = bcc001_xtl(Z, l_c, na, nb, nc, ncu, rmsd_3d) + xtl_parm.na = na; + xtl_parm.nb = nb; + xtl_parm.nc = nc; + + xtl_parm.a = l_c; + xtl_parm.b = l_c; + xtl_parm.c = l_c; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + + occ = 1; + tag = 0; + charge = 0; + + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [Z, 0.0, 0.0, 0.0, rmsd_3d, occ, tag, charge;... + Z, 0.5, 0.5, 0.5, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); + + dz = xtl_parm.c/ncu; + lx = na*xtl_parm.a;ly = nb*xtl_parm.b;lz = nc*xtl_parm.c; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; +end \ No newline at end of file diff --git a/crystalline_materials/fcc001_xtl.m b/crystalline_materials/fcc001_xtl.m old mode 100644 new mode 100755 index ecb0106a..74a449b5 --- a/crystalline_materials/fcc001_xtl.m +++ b/crystalline_materials/fcc001_xtl.m @@ -11,18 +11,22 @@ xtl_parm.beta = 90; xtl_parm.gamma = 90; - xtl_parm.nuLayer = 2; + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; occ = 1; - region = 0; + tag = 0; charge = 0; - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [Z, 0.0, 0.0, 0.0, rmsd_3d, occ, region, charge; Z, 0.5, 0.5, 0.0, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [Z, 0.0, 0.5, 0.5, rmsd_3d, occ, region, charge; Z, 0.5, 0.0, 0.5, rmsd_3d, occ, region, charge]; - - atoms = ilc_crystal_by_lays(xtl_parm); - + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [Z, 0.0, 0.0, 0.0, rmsd_3d, occ, tag, charge;... + Z, 0.5, 0.5, 0.0, rmsd_3d, occ, tag, charge;... + Z, 0.0, 0.5, 0.5, rmsd_3d, occ, tag, charge;... + Z, 0.5, 0.0, 0.5, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); + dz = xtl_parm.c/ncu; lx = na*xtl_parm.a; diff --git a/crystalline_materials/fcc110_xtl.m b/crystalline_materials/fcc110_xtl.m old mode 100644 new mode 100755 index 4eeb5e7f..6677014e --- a/crystalline_materials/fcc110_xtl.m +++ b/crystalline_materials/fcc110_xtl.m @@ -11,17 +11,19 @@ xtl_parm.beta = 90; xtl_parm.gamma = 90; - xtl_parm.nuLayer = 2; + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; occ = 1; - region = 0; + tag = 0; charge = 0; - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [Z, 0.0, 0.0, 0.0, rmsd_3d, occ, region, charge]; - xtl_parm.uLayer(2).atoms = [Z, 0.5, 0.5, 0.5, rmsd_3d, occ, region, charge]; - - atoms = ilc_crystal_by_lays(xtl_parm); + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [Z, 0.00, 0.00, 0.00, rmsd_3d, occ, tag, charge;... + Z, 0.50, 0.50, 0.50, rmsd_3d, occ, tag, charge]; + + atoms = ilc_xtl_build(xtl_parm); dz = xtl_parm.c/ncu; diff --git a/crystalline_materials/graphene.m b/crystalline_materials/graphene.m old mode 100644 new mode 100755 index 7d9ce193..289cc43d --- a/crystalline_materials/graphene.m +++ b/crystalline_materials/graphene.m @@ -1,21 +1,37 @@ -function [atoms, lx, ly, lz] = graphene(n, a, rms) +function [atoms, lx, ly, lz, a, b, c] = graphene(n, da, rms) + xtl_parm.a = 3*da; + xtl_parm.b = sqrt(3)*da; + xtl_parm.c = 2.0; + + xtl_parm.alpha = 90; + xtl_parm.beta = 90; + xtl_parm.gamma = 90; + xtl_parm.na = n; - xtl_parm.nb = round(3*n/sqrt(3)); + xtl_parm.nb = round(n*xtl_parm.a/xtl_parm.b); xtl_parm.nc = 0; - xtl_parm.a = 3*a; - xtl_parm.b = sqrt(3)*a; - xtl_parm.c = 2; - xtl_parm.nuLayer = 1; + + xtl_parm.sgn = 1; + xtl_parm.pbc = false; + xtl_parm.asym_uc = []; + occ = 1; - region = 0; + tag = 0; charge = 0; + % C = 6 - % Z x y z rmsd_3d occupancy region charge - xtl_parm.uLayer(1).atoms = [6, 0.0, 0.0, 0.0, rms, occ, region, charge;... - 6, 1/3, 0.0, 0.0, rms, occ, region, charge; 6, 1/2, 1/2, 0.0, rms, occ, region, charge; 6, 5/6, 1/2, 0.0, rms, occ, region, charge]; + % Z x y z rmsd_3d occupancy tag charge + xtl_parm.base = [6, 0.0, 0.0, 0.0, rms, occ, tag, charge;... + 6, 1/3, 0.0, 0.0, rms, occ, tag, charge;... + 6, 1/2, 1/2, 0.0, rms, occ, tag, charge;... + 6, 5/6, 1/2, 0.0, rms, occ, tag, charge]; - atoms = ilc_crystal_by_lays(xtl_parm); + atoms = ilc_xtl_build(xtl_parm); lx = xtl_parm.a*xtl_parm.na; ly = xtl_parm.b*xtl_parm.nb; lz = 0.0; + + a = xtl_parm.a; + b = xtl_parm.b; + c = xtl_parm.c; end \ No newline at end of file diff --git a/crystalline_materials/readme.txt b/crystalline_materials/readme.txt new file mode 100755 index 00000000..26e1c36f --- /dev/null +++ b/crystalline_materials/readme.txt @@ -0,0 +1,2 @@ +Check out the following website to obtained the lattice parameters: +http://periodictable.com/Properties/A/LatticeConstants.html \ No newline at end of file diff --git a/gui_multem/images/Pause.png b/gui_multem/images/Pause.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/copy.png b/gui_multem/images/copy.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/cross.png b/gui_multem/images/cross.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/cross_pointer.png b/gui_multem/images/cross_pointer.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/cut.png b/gui_multem/images/cut.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/default.png b/gui_multem/images/default.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/new.png b/gui_multem/images/new.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/open.png b/gui_multem/images/open.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/opt.png b/gui_multem/images/opt.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/paste.png b/gui_multem/images/paste.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/print.png b/gui_multem/images/print.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/save.png b/gui_multem/images/save.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/splash_screen.png b/gui_multem/images/splash_screen.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/start.png b/gui_multem/images/start.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/stop.png b/gui_multem/images/stop.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/undo.png b/gui_multem/images/undo.png old mode 100644 new mode 100755 diff --git a/gui_multem/images/view.png b/gui_multem/images/view.png old mode 100644 new mode 100755 diff --git a/gui_multem/main.cpp b/gui_multem/main.cpp old mode 100644 new mode 100755 diff --git a/gui_multem/mainwindow.cpp b/gui_multem/mainwindow.cpp old mode 100644 new mode 100755 index 268edc97..df95612c --- a/gui_multem/mainwindow.cpp +++ b/gui_multem/mainwindow.cpp @@ -2,10 +2,10 @@ #include "memory_info.cuh" #include "lin_alg_def.cuh" #include "atomic_data.hpp" -#include "atomic_data_mt.hpp" +#include "atom_data.hpp" #include "input_multislice.cuh" #include "output_multislice.hpp" -#include "tem_simulation.cuh" +#include "multislice.cuh" #include "multem.cu" #include @@ -24,7 +24,7 @@ MainWindow::MainWindow(): central_widget(new QLabel) pb_timer = new PB_Timer(this); - // set seed to generate cgpu_rand numbers + // set seed to generate random numbers qsrand(QTime::currentTime().msec()); setWindowTitle(tr("MULTEM")); @@ -2980,7 +2980,7 @@ void MainWindow::create_general_dock_widget() /*******************************************************/ ckb_pn_auto_seed = new QCheckBox(tr("auto")); - ckb_pn_auto_seed->setStatusTip(tr("Automatic cgpu_rand seed")); + ckb_pn_auto_seed->setStatusTip(tr("Automatic random seed")); /*******************************************************/ auto lyg_frozen_phonon = new QGridLayout; diff --git a/gui_multem/mainwindow.h b/gui_multem/mainwindow.h old mode 100644 new mode 100755 diff --git a/gui_multem/multem.cu b/gui_multem/multem.cu old mode 100644 new mode 100755 index e5838a92..293f7049 --- a/gui_multem/multem.cu +++ b/gui_multem/multem.cu @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ #include "stream.cuh" #include "input_multislice.cuh" #include "output_multislice.hpp" -#include "tem_simulation.cuh" +#include "multislice.cuh" template void mt_run_multislice(mt::System_Configuration &system_conf, @@ -43,9 +43,9 @@ void mt_run_multislice(mt::System_Configuration &system_conf, { mt::Multislice::ext_stop_sim = false; - mt::Multislice tem_simulation; - tem_simulation.set_input_data(&input_multislice, &stream, &fft_2d); - tem_simulation(output_multislice); + mt::Multislice multislice; + multislice.set_input_data(&input_multislice, &stream, &fft_2d); + multislice(output_multislice); } stream.synchronize(); diff --git a/gui_multem/multem.cuh b/gui_multem/multem.cuh old mode 100644 new mode 100755 index ab4cd76f..35682de8 --- a/gui_multem/multem.cuh +++ b/gui_multem/multem.cuh @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +23,7 @@ #include "stream.cuh" #include "input_multislice.cuh" #include "output_multislice.hpp" -#include "tem_simulation.cuh" +#include "multislice.cuh" template void run_multislice(mt::System_Configuration &system_conf, @@ -39,9 +39,9 @@ void run_multislice(mt::System_Configuration &system_conf, mt::FFT fft_2d; fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - mt::Multislice tem_simulation; - tem_simulation.set_input_data(&input_multislice, &stream, &fft_2d); - tem_simulation(output_multislice); + mt::Multislice multislice; + multislice.set_input_data(&input_multislice, &stream, &fft_2d); + multislice(output_multislice); stream.synchronize(); fft_2d.cleanup(); diff --git a/gui_multem/multem.pro b/gui_multem/multem.pro old mode 100644 new mode 100755 diff --git a/gui_multem/multem.pro.user b/gui_multem/multem.pro.user old mode 100644 new mode 100755 diff --git a/gui_multem/multem.qrc b/gui_multem/multem.qrc old mode 100644 new mode 100755 diff --git a/gui_multem/q_colormap.h b/gui_multem/q_colormap.h old mode 100644 new mode 100755 diff --git a/gui_multem/q_data_viewer.h b/gui_multem/q_data_viewer.h old mode 100644 new mode 100755 diff --git a/gui_multem/q_image.h b/gui_multem/q_image.h old mode 100644 new mode 100755 diff --git a/gui_multem/q_load_specimen.h b/gui_multem/q_load_specimen.h old mode 100644 new mode 100755 diff --git a/gui_multem/q_types.h b/gui_multem/q_types.h old mode 100644 new mode 100755 diff --git a/gui_multem/q_widget.cpp b/gui_multem/q_widget.cpp old mode 100644 new mode 100755 diff --git a/gui_multem/q_widget.h b/gui_multem/q_widget.h old mode 100644 new mode 100755 diff --git a/matlab_functions/+multem_input/detector.m b/matlab_functions/+multem_input/detector.m deleted file mode 100644 index c951a58c..00000000 --- a/matlab_functions/+multem_input/detector.m +++ /dev/null @@ -1,11 +0,0 @@ -classdef detector -% Detector object for Multem Input - properties - % STEM Detector - % detector_type: eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 - type(1,1) uint64 {mustBeLessThanOrEqual(type,3),mustBePositive} = 1; - cir = struct('inner_ang', 60, 'outer_ang', 180); % Inner & Outer angle(mrad) - radial = struct('x', 0, 'fx', 0); % radial detector angle(mrad) & radial sensitivity value - matrix = struct('R', 0, 'fR', 0); % 2D detector angle(mrad) & 2D sensitivity value - end -end \ No newline at end of file diff --git a/matlab_functions/+multem_input/parameters.m b/matlab_functions/+multem_input/parameters.m deleted file mode 100644 index f21fd5cc..00000000 --- a/matlab_functions/+multem_input/parameters.m +++ /dev/null @@ -1,305 +0,0 @@ -classdef parameters - % Default input class for multem - % Contains short descriptions of all parameters and a function to - % execute the simulation - - properties - system_conf = multem_input.system_conf; % System Configuration - - %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% - - interaction_model(1,1) uint64 {mustBeLessThanOrEqual(interaction_model,3),mustBePositive} = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 - potential_type(1,1) uint64 {mustBeLessThanOrEqual(potential_type,6),mustBePositive} = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - operation_mode(1,1) uint64 {mustBeLessThanOrEqual(operation_mode,2),mustBePositive} = 1; % eOM_Normal = 1, eOM_Advanced = 2 - memory_size(1,1) uint64 {mustBeNonnegative} = 0; % memory size to be used(Mb) - reverse_multislice(1,1) uint64 {mustBeLessThanOrEqual(reverse_multislice,1),mustBeNonnegative} = 0; % 1: true, 0:false - - %%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% - - pn_model(1,1) uint64 {mustBeLessThanOrEqual(pn_model,3),mustBePositive} = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 - pn_coh_contrib(1,1) uint64 {mustBeLessThanOrEqual(pn_coh_contrib,1),mustBeNonnegative} = 0; % 1: true, 0:false - pn_single_conf(1,1) uint64 {mustBeLessThanOrEqual(pn_single_conf,1),mustBeNonnegative} = 0; % 1: true, 0:false (extract single configuration) - pn_nconf(1,1) uint64 {mustBePositive} = 1; % true: specific phonon configuration, false: number of frozen phonon configurations - pn_dim(1,1) uint64 {mustBePositive} = 110; % phonon dimensions (xyz) - pn_seed(1,1) uint64 {mustBePositive} = 300183; % Random seed(frozen phonon) - %%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% - - spec_atoms = []; % Specimen atoms - spec_dz(1,1) double {mustBeNonnegative} = 0.25; % slice thick (Angstrom) - - spec_lx(1,1) double {mustBeNonnegative} = 10; % simulation box length in x direction (Angstrom) - spec_ly(1,1) double {mustBeNonnegative} = 10; % simulation box length in y direction (Angstrom) - spec_lz(1,1) double {mustBeNonnegative} = 10; % simulation box length gpuDEin z direction (Angstrom) - - spec_cryst_na(1,1) uint64 {mustBeNonnegative} = 1; % number of unit cell along a - spec_cryst_nb(1,1) uint64 {mustBeNonnegative} = 1; % number of unit cell along b - spec_cryst_nc(1,1) uint64 {mustBeNonnegative} = 1; % number of unit cell along c - spec_cryst_a(1,1) double {mustBeNonnegative} = 0; % length along a (Angstrom) - spec_cryst_b(1,1) double {mustBeNonnegative} = 0; % length along b (Angstrom) - spec_cryst_c(1,1) double {mustBeNonnegative} = 0; % length along c (Angstrom) - spec_cryst_x0(1,1) double = 0; % reference position along x direction (Angstrom) - spec_cryst_y0(1,1) double = 0; % reference position along y direction (Angstrom) - - spec_amorp = struct('z_0', 0, 'z_e', 0, 'dz', 2.0); % Include slice of amorphous layer - %%%%%%%%%%%%%%%%%%%%%%%%% Specimen Rotation %%%%%%%%%%%%%%%%%%%%%%%% - - spec_rot_theta(1,1) double {mustBeNonnegative} = 0; % angle (Degree) - spec_rot_u0(3,1) double {mustBeNonnegative} = [0 0 1]; % unitary vector - spec_rot_center_type(1,1) uint64 {mustBeLessThanOrEqual(spec_rot_center_type,2),mustBePositive} = 1; % 1: geometric center, 2: User define - spec_rot_center_p(3,1) double {mustBeNonnegative} = [0 0 0]; % rotation point - %%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% - - thick_type(1,1) uint64 {mustBeLessThanOrEqual(thick_type,3),mustBePositive} = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 - thick = 0; % Array of thickness (Angstrom) - %%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% - - potential_slicing(1,1) uint64 {mustBeLessThanOrEqual(potential_slicing,4),mustBePositive} = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - islice uint64 % retrieve the projected potential at given slices - %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - nx(1,1) double {mustBePositive} = 256; % number of pixels in x direction - ny(1,1) double {mustBePositive} = 256; % number of pixels in y direction - bwl(1,1) uint64 {mustBeLessThanOrEqual(bwl,1),mustBeNonnegative} = 0; % Band-width limit, 1: true, 0:false - - %%%%%%%%%%%%%%%%%%%%%%%% Simulation type %%%%%%%%%%%%%%%%%%%%%%%%%%% - - % Simulation type - % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, - % eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, - % eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_EELS=61, eTEMST_EFTEM=62, - % eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82, - % eTEMST_TFFS=91, eTEMST_TFRS=92 - simulation_type(1,1) uint64 = 52; % Simulation type - - %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% - - iw_type(1,1) uint64 {mustBeLessThanOrEqual(iw_type,4),mustBePositive} = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto - iw_psi double = 0; % User defined incident wave. It will be only used if iw_type=3 - iw_x double = 0; % x position - iw_y double = 0; % y position - %%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% - - E_0(1,1) double = 300; % Acceleration Voltage (keV) - theta(1,1) double = 0; % Polar angle (Angstrom) - phi(1,1) double = 0; % Azimuthal angle (Angstrom) - %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% - - illumination_model(1,1) uint64 {mustBeLessThanOrEqual(illumination_model,4),mustBePositive} = 3; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration - temporal_spatial_incoh(1,1) uint64 {mustBeLessThanOrEqual(temporal_spatial_incoh,3),mustBePositive} = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% - - cond_lens_m(1,1) double = 0.00; % Vortex momentum - - cond_lens_c_10(1,1) double = 14.0312; % [C1] Defocus (Angstrom) - cond_lens_c_12(1,1) double = 0.00; % [A1] 2-fold astigmatism (Angstrom) - cond_lens_phi_12(1,1) double = 0.00; % [phi_A1] Azimuthal angle of 2-fold astigmatism (Angstrom) - - cond_lens_c_21(1,1) double = 0.00; % [B2] Axial coma (Angstrom) - cond_lens_phi_21(1,1) double = 0.00; % [phi_B2] Azimuthal angle of axial coma (Angstrom) - cond_lens_c_23(1,1) double = 0.00; % [A2] 3-fold astigmatism (Angstrom) - cond_lens_phi_23(1,1) double = 0.00; % [phi_A2] Azimuthal angle of 3-fold astigmatism (Angstrom) - - cond_lens_c_30(1,1) double = 1e-3; % [C3] 3rd order spherical aberration (mm) - cond_lens_c_32(1,1) double = 0.00; % [S3] Axial star aberration (Angstrom) - cond_lens_phi_32(1,1) double = 0.00; % [phi_S3] Azimuthal angle of axial star aberration (Angstrom) - cond_lens_c_34(1,1) double = 0.00; % [A3] 4-fold astigmatism (Angstrom) - cond_lens_phi_34(1,1) double = 0.00; % [phi_A3] Azimuthal angle of 4-fold astigmatism (Angstrom) - - cond_lens_c_41(1,1) double = 0.00; % [B4] 4th order axial coma (Angstrom) - cond_lens_phi_41(1,1) double = 0.00; % [phi_B4] Azimuthal angle of 4th order axial coma (Angstrom) - cond_lens_c_43(1,1) double = 0.00; % [D4] 3-lobe aberration (Angstrom) - cond_lens_phi_43(1,1) double = 0.00; % [phi_D4] Azimuthal angle of 3-lobe aberration (Angstrom) - cond_lens_c_45(1,1) double = 0.00; % [A4] 5-fold astigmatism (Angstrom) - cond_lens_phi_45(1,1) double = 0.00; % [phi_A4] Azimuthal angle of 5-fold astigmatism (Angstrom) - - cond_lens_c_50(1,1) double = 0.00; % [C5] 5th order spherical aberration (mm) - cond_lens_c_52(1,1) double = 0.00; % [S5] 5th order axial star aberration (Angstrom) - cond_lens_phi_52(1,1) double = 0.00; % [phi_S5] Azimuthal angle of 5th order axial star aberration (Angstrom) - cond_lens_c_54(1,1) double = 0.00; % [R5] 5th order rosette aberration (Angstrom) - cond_lens_phi_54(1,1) double = 0.00; % [phi_R5] Azimuthal angle of 5th order rosette aberration (Angstrom) - cond_lens_c_56(1,1) double = 0.00; % [A5] 6-fold astigmatism (Angstrom) - cond_lens_phi_56(1,1) double = 0.00; % [phi_A5] Azimuthal angle of 6-fold astigmatism (Angstrom) - - cond_lens_inner_aper_ang(1,1) double = 0.00; % Inner aperture (mrad) - cond_lens_outer_aper_ang(1,1) double = 21.0; % Outer aperture (mrad) - %%%%%%%%%% source spread function %%%%%%%%%%%% - - cond_lens_si_a(1,1) double = 1.0 % Height proportion of a normalized Gaussian [0, 1] - cond_lens_si_sigma(1,1) double = 0.0072; % standard deviation: For parallel ilumination(Angstrom^-1); otherwise (Angstrom) - cond_lens_si_beta(1,1) double = 0.0; % Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) - cond_lens_si_rad_npts(1,1) uint64 = 4; % # of integration points. It will be only used if illumination_model=4 - cond_lens_si_azm_npts(1,1) uint64 = 4; % # of radial integration points. It will be only used if illumination_model=4 - %%%%%%%%% defocus spread function %%%%%%%%%%%% - - cond_lens_ti_a(1,1) double = 1.0; % Height proportion of a normalized Gaussian [0, 1] - cond_lens_ti_sigma(1,1) double = 32.0; % standard deviation (Angstrom) - cond_lens_ti_beta(1,1) double = 0.0; % Standard deviation of the defocus spread for the Exponential component - cond_lens_ti_npts(1,1) uint64 = 10; % # of integration points. It will be only used if illumination_model=4 - %%%%%%%%% zero defocus reference %%%%%%%%%%%% - - cond_lens_zero_defocus_type(1,1) uint64 {mustBeLessThanOrEqual(cond_lens_zero_defocus_type,4),mustBePositive} = 1; % eZDT_First = 1, eZDT_User_Define = 4 - cond_lens_zero_defocus_plane(1,1) double = 0.00; % It will be only used if cond_lens_zero_defocus_type = eZDT_User_Define - %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% - - obj_lens_m(1,1) double = 0; % Vortex momentum - - obj_lens_c_10(1,1) double = 14.0312; % [C1] Defocus (Angstrom) - obj_lens_c_12(1,1) double = 0.00; % [A1] 2-fold astigmatism (Angstrom) - obj_lens_phi_12(1,1) double = 0.00; % [phi_A1] Azimuthal angle of 2-fold astigmatism (Angstrom) - - obj_lens_c_21(1,1) double = 0.00; % [B2] Axial coma (Angstrom) - obj_lens_phi_21(1,1) double = 0.00; % [phi_B2] Azimuthal angle of axial coma (Angstrom) - obj_lens_c_23(1,1) double = 0.00; % [A2] 3-fold astigmatism (Angstrom) - obj_lens_phi_23(1,1) double = 0.00; % [phi_A2] Azimuthal angle of 3-fold astigmatism (Angstrom) - - obj_lens_c_30(1,1) double = 1e-03; % [C3] 3rd order spherical aberration (mm) - obj_lens_c_32(1,1) double = 0.00; % [S3] Axial star aberration (Angstrom) - obj_lens_phi_32(1,1) double = 0.00; % [phi_S3] Azimuthal angle of axial star aberration (Angstrom) - obj_lens_c_34(1,1) double = 0.00; % [A3] 4-fold astigmatism (Angstrom) - obj_lens_phi_34(1,1) double = 0.00; % [phi_A3] Azimuthal angle of 4-fold astigmatism (Angstrom) - - obj_lens_c_41(1,1) double = 0.00; % [B4] 4th order axial coma (Angstrom) - obj_lens_phi_41(1,1) double = 0.00; % [phi_B4] Azimuthal angle of 4th order axial coma (Angstrom) - obj_lens_c_43(1,1) double = 0.00; % [D4] 3-lobe aberration (Angstrom) - obj_lens_phi_43(1,1) double = 0.00; % [phi_D4] Azimuthal angle of 3-lobe aberration (Angstrom) - obj_lens_c_45(1,1) double = 0.00; % [A4] 5-fold astigmatism (Angstrom) - obj_lens_phi_45(1,1) double = 0.00; % [phi_A4] Azimuthal angle of 5-fold astigmatism (Angstrom) - - obj_lens_c_50(1,1) double = 0.00; % [C5] 5th order spherical aberration (mm) - obj_lens_c_52(1,1) double = 0.00; % [S5] 5th order axial star aberration (Angstrom) - obj_lens_phi_52(1,1) double = 0.00; % [phi_S5] Azimuthal angle of 5th order axial star aberration (Angstrom) - obj_lens_c_54(1,1) double = 0.00; % [R5] 5th order rosette aberration (Angstrom) - obj_lens_phi_54(1,1) double = 0.00; % [phi_R5] Azimuthal angle of 5th order rosette aberration (Angstrom) - obj_lens_c_56(1,1) double = 0.00; % [A5] 6-fold astigmatism (Angstrom) - obj_lens_phi_56(1,1) double = 0.00; % [phi_A5] Azimuthal angle of 6-fold astigmatism (Angstrom) - - obj_lens_inner_aper_ang(1,1) double = 0.00; % Inner aperture (mrad) - obj_lens_outer_aper_ang(1,1) double = 24.0; % Outer aperture (mrad) - %%%%%%%%%% source spread function %%%%%%%%%%%% - - obj_lens_si_a(1,1) double = 1.0 % Height proportion of a normalized Gaussian [0, 1] - obj_lens_si_sigma(1,1) double = 0.0072; % standard deviation: For parallel ilumination(Angstrom^-1); otherwise (Angstrom) - obj_lens_si_beta(1,1) double = 0.0; % Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) - obj_lens_si_rad_npts(1,1) uint64 = 4; % # of integration points. It will be only used if illumination_model=4 - obj_lens_si_azm_npts(1,1) uint64 = 4; % # of radial integration points. It will be only used if illumination_model=4 - %%%%%%%%% defocus spread function %%%%%%%%%%%% - - obj_lens_ti_a(1,1) double = 1.0; % Height proportion of a normalized Gaussian [0, 1] - obj_lens_ti_sigma(1,1) double = 32.0; % standard deviation (Angstrom) - obj_lens_ti_beta(1,1) double = 0.0; % Standard deviation of the defocus spread for the Exponential component - obj_lens_ti_npts(1,1) uint64 = 10; % # of integration points. It will be only used if illumination_model=4 - - %%%%%%%%% zero defocus reference %%%%%%%%%%%% - - obj_lens_zero_defocus_type(1,1) uint64 {mustBeLessThanOrEqual(obj_lens_zero_defocus_type,4),mustBePositive} = 1; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 - obj_lens_zero_defocus_plane(1,1) double = 0.00; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define - % %%%%%%%%%%%%%%%%%%%%%%%%%% STEM Detector %%%%%%%%%%%%%%%%%%%%%%%%%% - - detector = multem_input.detector; % detector object - %%%%%%%%%%%% Scanning area for ISTEM/STEM/EELS %%%%%%%%%%%%%%%%% - - scanning_type(1,1) uint64 {mustBeLessThanOrEqual(scanning_type,2),mustBePositive} = 2; % eST_Line = 1, eST_Area = 2 - scanning_periodic(1,1) uint64 {mustBeLessThanOrEqual(scanning_periodic,1),mustBeNonnegative} = 0; % 1: true, 0:false (periodic boundary conditions) - scanning_square_pxs(1,1) uint64 {mustBeLessThanOrEqual(scanning_square_pxs,1),mustBeNonnegative} = 1; % 0: false, 1: true - scanning_ns(1,1) uint64 {mustBePositive} = 10; % number of sampling points - scanning_x0(1,1) double = 0.00; % x-starting point (Angstrom) - scanning_y0(1,1) double = 0.00; % y-starting point (Angstrom) - scanning_xe(1,1) double = 4.078; % x-final point (Angstrom) - scanning_ye(1,1) double = 4.078; % y-final point (Angstrom) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%PED %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - ped_nrot(1,1) double = 360; % Number of orientations - ped_theta(1,1) double = 3.0; % Precession angle (degrees) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - hci_nrot(1,1) double = 360; % number of orientations - hci_theta(1,1) double = 3.0; % Precession angle (degrees) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%EELS %%%%%%%%%%%%%%%%%%%%%%%%%%%% - - eels_Z(1,1) uint64 = 79; % atomic type - eels_E_loss(1,1) double = 80.0; % Energy loss (eV) - eels_collection_angle(1,1) double = 100.0; % Collection half angle (mrad) - eels_m_selection(1,1) double = 3; % selection rule - eels_channelling_type(1,1) uint64 {mustBeLessThanOrEqual(eels_channelling_type,3),mustBePositive} = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%EFTEM %%%%%%%%%%%%%%%%%%%%%%%%%%%% - - eftem_Z(1,1) uint64 = 79; % atomic type - eftem_E_loss(1,1) double = 80.0; % Energy loss (eV) - eftem_collection_angle(1,1) double = 100.0; % Collection half angle (mrad) - eftem_m_selection(1,1) double = 3; % selection rule - eftem_channelling_type(1,1) uint64 {mustBeLessThanOrEqual(eftem_channelling_type,3),mustBePositive} = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 - - %%%%%%%%%%%%%%%%%%%%%%% OUTPUT REGION %%%%%%%%%%%%%%%%%%%%%%%%%%% - %%%% This option is not used for eTEMST_STEM and eTEMST_EELS %%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - output_area_ix_0(1,1) double = 0.0; % x-starting in pixel - output_area_iy_0(1,1) double = 0.0; % y-starting in pixel - output_area_ix_e(1,1) double = 0.0; % x-final in pixel - output_area_iy_e(1,1) double = 0.0; % y-final in pixel - end - methods - function out_mt = ilc_incident_wave(obj) - prms = obj.toStruct; - clear ilc_incident_wave; - out_mt = ilc_incident_wave(prms.system_conf, prms); - end - function out_mt = ilc_multem(obj) - prms = obj.toStruct; - clear ilc_multem; - out_mt = ilc_multem(prms.system_conf, prms); - end - function out_mt = ilc_projected_potential(obj) - prms = obj.toStruct; - clear ilc_projected_potential; - out_mt = ilc_projected_potential(prms.system_conf, prms); - end - function out_mt = ilc_propagate(obj) - prms = obj.toStruct; - clear ilc_propagate; - out_mt = ilc_propagate(prms.system_conf, prms); - end - function out_mt = ilc_microscope_aberrations(obj) - prms = obj.toStruct; - clear ilc_microscope_aberrations; - out_mt = ilc_microscope_aberrations(prms.system_conf, prms); - end - function out_mt = ilc_apply_ctf(obj) - prms = obj.toStruct; - clear ilc_propagate; - out_mt = ilc_apply_ctf(prms.system_conf, prms); - end - function out_mt = ilc_transmission_function(obj) - prms = obj.toStruct; - clear ilc_transmission_function; - out_mt = ilc_transmission_function(prms.system_conf, prms); - end - function out_mt = ilc_wave_function(obj) - prms = obj.toStruct; - clear ilc_wave_function; - out_mt = ilc_wave_function(prms.system_conf, prms); - end - function s = toStruct(class) - public_props = properties(class); - s = struct(); - for fi = 1:numel(public_props) - if isobject(class.(public_props{fi})) - sub_props = properties(class.(public_props{fi})); - for fi_s = 1:numel(sub_props) - val = class.(public_props{fi}).(sub_props{fi_s}); - if isnumeric(val) - val = double(val); - end - s.(public_props{fi}).(sub_props{fi_s}) = val; - end - else - val = class.(public_props{fi}); - if isnumeric(val) - val = double(val); - end - s.(public_props{fi}) = val; - end - end - end - end -end diff --git a/matlab_functions/+multem_input/system_conf.m b/matlab_functions/+multem_input/system_conf.m deleted file mode 100644 index f7c09414..00000000 --- a/matlab_functions/+multem_input/system_conf.m +++ /dev/null @@ -1,17 +0,0 @@ -classdef system_conf -% System Configuration object for Multem Input - properties - %%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% - - % eP_Float = 1, eP_double = 2 - precision(1,1) uint64 {mustBeLessThanOrEqual(precision,2),mustBePositive} = 1; - % eD_CPU = 1, eD_GPU = 2 - device(1,1) uint64 {mustBeLessThanOrEqual(device,2),mustBePositive} = 2; - % Number of Cores CPU (It will be used in the future) - cpu_ncores - % # of CPU Threads - cpu_nthread(1,1) uint64 {mustBePositive} = 1; - % Select GPU (for Multi-GPU Setups) - gpu_device(1,1) uint64 {mustBeNonnegative} = 0; - end -end \ No newline at end of file diff --git a/matlab_functions/ilm_Z.m b/matlab_functions/ilm_Z.m old mode 100644 new mode 100755 index f29a88a1..465a798e --- a/matlab_functions/ilm_Z.m +++ b/matlab_functions/ilm_Z.m @@ -1,18 +1,18 @@ -function[Z] = ilm_Z(str_Z) - a_str_Z = {'H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca', ... - 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Rb', 'Sr', 'Y', 'Zr', ... - 'Nb', 'Mo', 'Tc', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te', 'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', ... - 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', ... - 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn', 'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm', 'Md', 'No', 'Lr'}; - - if(ischar(str_Z)) - str_Z = {str_Z}; - end - str_Z = strtrim(str_Z); - a_str_Z = strtrim(a_str_Z); - n_str_Z = numel(str_Z); - Z = zeros(n_str_Z, 1); - for ik=1:n_str_Z - Z(ik) = find(strcmpi(str_Z{ik}, a_str_Z)); - end +function[Z] = ilm_Z(str_Z) + a_str_Z = {'H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca', ... + 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Rb', 'Sr', 'Y', 'Zr', ... + 'Nb', 'Mo', 'Tc', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te', 'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', ... + 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', ... + 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn', 'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm', 'Md', 'No', 'Lr'}; + + if(ischar(str_Z)) + str_Z = {str_Z}; + end + str_Z = strtrim(str_Z); + a_str_Z = strtrim(a_str_Z); + n_str_Z = numel(str_Z); + Z = zeros(n_str_Z, 1); + for ik=1:n_str_Z + Z(ik) = find(strcmpi(str_Z{ik}, a_str_Z)); + end end \ No newline at end of file diff --git a/matlab_functions/ilm_apply_af_tf_2d.m b/matlab_functions/ilm_apply_af_tf_2d.m new file mode 100755 index 00000000..e4cdf34a --- /dev/null +++ b/matlab_functions/ilm_apply_af_tf_2d.m @@ -0,0 +1,34 @@ +% apply affine transformation +function[im_o] = ilm_apply_af_tf_2d(system_config, im_i, dx, dy, A, txy, bg) + [ny, nx] = size(im_i, [1, 2]); + bsx = nx*dx; + bsy = ny*dy; + + A = inv(A); + txy = -1*A*reshape(txy, [], 1); + + [rx, ry, ~] = ilm_rs_grid_2d(nx, ny, bsx, bsy, 0); + p = [rx(:), ry(:)]; + p = p*(A.') + txy.'; + rx_o = reshape(p(:, 1), [ny, nx]); + ry_o = reshape(p(:, 2), [ny, nx]); + + +% im_o = griddata(rx, ry, im_i, rx_o, ry_o, 'natural'); + im_o = interp2(rx, ry, im_i, rx_o(:), ry_o(:), 'cubic', bg); + im_o = reshape(im_o, [ny, nx]); + + im_o = max(min(im_i(:)), im_o); + + if 0 + figure(1);clf; + subplot(1, 2, 1); + imagesc(im_i); + axis image; + colormap jet; + subplot(1, 2, 2); + imagesc(im_o); + axis image; + colormap bone; + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_bd_2_rect.m b/matlab_functions/ilm_bd_2_rect.m new file mode 100755 index 00000000..2e501a25 --- /dev/null +++ b/matlab_functions/ilm_bd_2_rect.m @@ -0,0 +1,3 @@ +function[rect] = ilm_bd_2_rect(lx, ly, bd_px) + rect = [bd_px(1), bd_px(3); lx-bd_px(2), ly-bd_px(4)]; +end \ No newline at end of file diff --git a/matlab_functions/ilm_build_ellip_parm_interp2.m b/matlab_functions/ilm_build_ellip_parm_interp2.m new file mode 100755 index 00000000..7625ecdd --- /dev/null +++ b/matlab_functions/ilm_build_ellip_parm_interp2.m @@ -0,0 +1,34 @@ +function [parm] = ilm_build_ellip_parm_interp2(coef, nx, ny, nx_r, ny_r, radius_r) + p_c_r = [nx_r, ny_r]/2 + 1; + + p_c = coef(1:2); + rad_a = coef(3); + rad_b = coef(4); + theta = coef(5); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + mr = ilm_rot_mx_2d(-theta); + ms = [rad_a/radius_r, 0; 0 rad_b/radius_r]; + msc = mr*ms*(mr.'); + msc = msc.'; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + parm.radius_r = radius_r; + [rx_r, ry_r] = meshgrid((1:nx_r)-p_c_r(1), (1:ny_r)-p_c_r(2)); + rxy_r = [rx_r(:), ry_r(:)]*msc; + parm.rx_r = reshape(rxy_r(:, 1), size(rx_r)); + parm.ry_r = reshape(rxy_r(:, 2), size(ry_r)); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + [parm.rx, parm.ry] = meshgrid((1:nx)-p_c(1), (1:ny)-p_c(2)); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + parm.fltr_rs = ms(1)*ms(4); + parm.p_c_r = p_c_r; + nxh_r = nx_r/2; + nyh_r = ny_r/2; + parm.ax_r = (p_c_r(1)-nxh_r):1:(p_c_r(1)+nxh_r-1); + parm.ay_r = (p_c_r(2)-nyh_r):1:(p_c_r(2)+nyh_r-1); + parm.nx_r = nx_r; + parm.ny_r = ny_r; +end diff --git a/matlab_functions/ilm_center_spec.m b/matlab_functions/ilm_center_spec.m deleted file mode 100644 index cdbc6a0d..00000000 --- a/matlab_functions/ilm_center_spec.m +++ /dev/null @@ -1,4 +0,0 @@ -function [atoms] = ilm_center_spec(atoms, lx, ly, lz) - atoms(:, 2:4) = bsxfun(@minus, atoms(:, 2:4), min(atoms(:, 2:4))); - atoms(:, 2:4) = bsxfun(@plus, atoms(:, 2:4), 0.5*([lx, ly, lz]-max(atoms(:, 2:4)))); -end \ No newline at end of file diff --git a/matlab_functions/ilm_chk_bound.m b/matlab_functions/ilm_chk_bound.m old mode 100644 new mode 100755 index fd9b6cee..59e3b7cf --- a/matlab_functions/ilm_chk_bound.m +++ b/matlab_functions/ilm_chk_bound.m @@ -1,3 +1,3 @@ -function[bb] = ilm_chk_bound(x, x_min, x_max) - bb = (x_min<=x) && (x dgx = 2/nx; + % + drx = 0.5; + dry = 0.5; + [rx, ry] = meshgrid((-nxh:(nxh-1))*drx, (-nyh:(nyh-1))*dry); + r = sqrt(rx.^2+ry.^2); + + % matlab sinc function is defines as sin(pi x)/(pi x) +% mtf = mtf_par.fun(g); + mtf_rad = ilm_eval_rad_mtf(coef_mtf, r); + + if support_bb + mtf = mtf_rad.*sinc(rx/2).*sinc(ry/2); + else + mtf = mtf_rad; + end + + if shift_bb + mtf = fftshift(mtf); + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_dflt_input_multem.m b/matlab_functions/ilm_dflt_input_multem.m old mode 100644 new mode 100755 index 9ecfd5cc..f36c11ca --- a/matlab_functions/ilm_dflt_input_multem.m +++ b/matlab_functions/ilm_dflt_input_multem.m @@ -1,260 +1,250 @@ -function [input_multem] = ilm_dflt_input_multem() - %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% - input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 - input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.operation_mode = 1; % eOM_Normal = 1, eOM_Advanced = 2 - input_multem.memory_size = 0; % memory size to be used(Mb) - input_multem.reverse_multislice = 0; % 1: true, 0:false - - %%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% - input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 - input_multem.pn_coh_contrib = 0; % 1: true, 0:false - input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) - input_multem.pn_nconf = 1; % true: specific phonon configuration, false: number of frozen phonon configurations - input_multem.pn_dim = 110; % phonon dimensions (xyz) - input_multem.pn_seed = 300183; % Random seed(frozen phonon) - - %%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% - input_multem.spec_atoms = []; % simulation box length in x direction (Ã…) - input_multem.spec_dz = 0.25; % slice thick (Ã…) - - input_multem.spec_lx = 10; % simulation box length in x direction (Ã…) - input_multem.spec_ly = 10; % simulation box length in y direction (Ã…) - input_multem.spec_lz = 10; % simulation box length gpuDEin z direction (Ã…) - - input_multem.spec_cryst_na = 1; % number of unit cell along a - input_multem.spec_cryst_nb = 1; % number of unit cell along b - input_multem.spec_cryst_nc = 1; % number of unit cell along c - input_multem.spec_cryst_a = 0; % length along a (Ã…) - input_multem.spec_cryst_b = 0; % length along b (Ã…) - input_multem.spec_cryst_c = 0; % length along c (Ã…) - input_multem.spec_cryst_x0 = 0; % reference position along x direction (Ã…) - input_multem.spec_cryst_y0 = 0; % reference position along y direction (Ã…) - - input_multem.spec_amorp(1).z_0 = 0; % Starting z position of the amorphous layer (Ã…) - input_multem.spec_amorp(1).z_e = 0; % Ending z position of the amorphous layer (Ã…) - input_multem.spec_amorp(1).dz = 2.0; % slice thick of the amorphous layer (Ã…) - - %%%%%%%%%%%%%%%%%%%%%%%%% Specimen Rotation %%%%%%%%%%%%%%%%%%%%%%%% - input_multem.spec_rot_theta = 0; % angle (º) - input_multem.spec_rot_u0 = [0 0 1]; % unitary vector - input_multem.spec_rot_center_type = 1; % 1: geometric center, 2: User define - input_multem.spec_rot_center_p = [0 0 0]; % rotation point - - %%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 - input_multem.thick = 0; % Array of thickness (Ã…) - - %%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - - %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.nx = 256; % number of pixels in x direction - input_multem.ny = 256; % number of pixels in y direction - input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - - %%%%%%%%%%%%%%%%%%%%%%%% Simulation type %%%%%%%%%%%%%%%%%%%%%%%%%%% - % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, - % eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, - % eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_EELS=61, eTEMST_EFTEM=62, - % eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82, - % eTEMST_TFFS=91, eTEMST_TFRS=92 - input_multem.simulation_type = 52; - - %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto - input_multem.iw_psi = 0; % User define incident wave. It will be only used if User_Define=3 - input_multem.iw_x = 0.0; % x position - input_multem.iw_y = 0.0; % y position - - %%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.E_0 = 300; % Acceleration Voltage (keV) - input_multem.theta = 0.0; % Polar angle (°) - input_multem.phi = 0.0; % Azimuthal angle (°) - - %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration - input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % On the optimun probe in aberration corrected ADF-STEM - % Ultramicroscopy 111(2014) 1523-1530 - % C_{nm} Krivanek --- {A, B, C, D, R}_{n} Haider notation - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% - input_multem.cond_lens_m = 0; % Vortex momentum - - input_multem.cond_lens_c_10 = 14.0312; % [C1] Defocus (Ã…) - input_multem.cond_lens_c_12 = 0.00; % [A1] 2-fold astigmatism (Ã…) - input_multem.cond_lens_phi_12 = 0.00; % [phi_A1] Azimuthal angle of 2-fold astigmatism (°) - - input_multem.cond_lens_c_21 = 0.00; % [B2] Axial coma (Ã…) - input_multem.cond_lens_phi_21 = 0.00; % [phi_B2] Azimuthal angle of axial coma (°) - input_multem.cond_lens_c_23 = 0.00; % [A2] 3-fold astigmatism (Ã…) - input_multem.cond_lens_phi_23 = 0.00; % [phi_A2] Azimuthal angle of 3-fold astigmatism (°) - - input_multem.cond_lens_c_30 = 1e-03; % [C3] 3rd order spherical aberration (mm) - input_multem.cond_lens_c_32 = 0.00; % [S3] Axial star aberration (Ã…) - input_multem.cond_lens_phi_32 = 0.00; % [phi_S3] Azimuthal angle of axial star aberration (°) - input_multem.cond_lens_c_34 = 0.00; % [A3] 4-fold astigmatism (Ã…) - input_multem.cond_lens_phi_34 = 0.0; % [phi_A3] Azimuthal angle of 4-fold astigmatism (°) - - input_multem.cond_lens_c_41 = 0.00; % [B4] 4th order axial coma (Ã…) - input_multem.cond_lens_phi_41 = 0.00; % [phi_B4] Azimuthal angle of 4th order axial coma (°) - input_multem.cond_lens_c_43 = 0.00; % [D4] 3-lobe aberration (Ã…) - input_multem.cond_lens_phi_43 = 0.00; % [phi_D4] Azimuthal angle of 3-lobe aberration (°) - input_multem.cond_lens_c_45 = 0.00; % [A4] 5-fold astigmatism (Ã…) - input_multem.cond_lens_phi_45 = 0.00; % [phi_A4] Azimuthal angle of 5-fold astigmatism (°) - - input_multem.cond_lens_c_50 = 0.00; % [C5] 5th order spherical aberration (mm) - input_multem.cond_lens_c_52 = 0.00; % [S5] 5th order axial star aberration (Ã…) - input_multem.cond_lens_phi_52 = 0.00; % [phi_S5] Azimuthal angle of 5th order axial star aberration (°) - input_multem.cond_lens_c_54 = 0.00; % [R5] 5th order rosette aberration (Ã…) - input_multem.cond_lens_phi_54 = 0.00; % [phi_R5] Azimuthal angle of 5th order rosette aberration (°) - input_multem.cond_lens_c_56 = 0.00; % [A5] 6-fold astigmatism (Ã…) - input_multem.cond_lens_phi_56 = 0.00; % [phi_A5] Azimuthal angle of 6-fold astigmatism (°) - - input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) - input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) - - %%%%%%%%% defocus spread function %%%%%%%%%%%% - dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation - input_multem.cond_lens_ti_a = 1.0; - input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation - input_multem.cond_lens_ti_beta = 1; - input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - - %%%%%%%%%% source spread function %%%%%%%%%%%% - ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation - input_multem.cond_lens_si_a = 1.0; - input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Ã…^-1); otherwise - input_multem.cond_lens_si_beta = 1.0; - input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 - input_multem.cond_lens_si_azm_npts = 12; % # of integration points. It will be only used if illumination_model=4 - - %%%%%%%%% zero defocus reference %%%%%%%%%%%% - input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 - input_multem.cond_lens_zero_defocus_plane = 0; % It will be only used if cond_lens_zero_defocus_type = eZDT_User_Define - - %%%%%%%%%%%%%%%%%%% condenser lens variable %%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%% it will be active in the future %%%%%%%%%%%%%%%%% - % 1: Vortex momentum, 2: Defocus (Ã…), 2: Third order spherical aberration (mm) - % 3: Third order spherical aberration (mm), 4: Fifth order spherical aberration (mm) - % 5: Twofold astigmatism (Ã…), 2: Defocus (Ã…), 6: Azimuthal angle of the twofold astigmatism (°) - % 7: Threefold astigmatism (Ã…), 8: Azimuthal angle of the threefold astigmatism (°) - % 9: Inner aperture (mrad), 2: Defocus (Ã…), 10: Outer aperture (mrad) - % input_multem.cdl_var_type = 0; % 0:off 1: m, 2: f, 3 Cs3, 4:Cs5, 5:mfa2, 6:afa2, 7:mfa3, 8:afa3, 9:inner_aper_ang , 10:outer_aper_ang - % input_multem.cdl_var = [-2 -1 0 1 2]; % variable array - - %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% - input_multem.obj_lens_m = 0; % Vortex momentum - - input_multem.obj_lens_c_10 = 14.0312; % [C1] Defocus (Ã…) - input_multem.obj_lens_c_12 = 0.00; % [A1] 2-fold astigmatism (Ã…) - input_multem.obj_lens_phi_12 = 0.00; % [phi_A1] Azimuthal angle of 2-fold astigmatism (°) - - input_multem.obj_lens_c_21 = 0.00; % [B2] Axial coma (Ã…) - input_multem.obj_lens_phi_21 = 0.00; % [phi_B2] Azimuthal angle of axial coma (°) - input_multem.obj_lens_c_23 = 0.00; % [A2] 3-fold astigmatism (Ã…) - input_multem.obj_lens_phi_23 = 0.00; % [phi_A2] Azimuthal angle of 3-fold astigmatism (°) - - input_multem.obj_lens_c_30 = 1e-03; % [C3] 3rd order spherical aberration (mm) - input_multem.obj_lens_c_32 = 0.00; % [S3] Axial star aberration (Ã…) - input_multem.obj_lens_phi_32 = 0.00; % [phi_S3] Azimuthal angle of axial star aberration (°) - input_multem.obj_lens_c_34 = 0.00; % [A3] 4-fold astigmatism (Ã…) - input_multem.obj_lens_phi_34 = 0.0; % [phi_A3] Azimuthal angle of 4-fold astigmatism (°) - - input_multem.obj_lens_c_41 = 0.00; % [B4] 4th order axial coma (Ã…) - input_multem.obj_lens_phi_41 = 0.00; % [phi_B4] Azimuthal angle of 4th order axial coma (°) - input_multem.obj_lens_c_43 = 0.00; % [D4] 3-lobe aberration (Ã…) - input_multem.obj_lens_phi_43 = 0.00; % [phi_D4] Azimuthal angle of 3-lobe aberration (°) - input_multem.obj_lens_c_45 = 0.00; % [A4] 5-fold astigmatism (Ã…) - input_multem.obj_lens_phi_45 = 0.00; % [phi_A4] Azimuthal angle of 5-fold astigmatism (°) - - input_multem.obj_lens_c_50 = 0.00; % [C5] 5th order spherical aberration (mm) - input_multem.obj_lens_c_52 = 0.00; % [S5] 5th order axial star aberration (Ã…) - input_multem.obj_lens_phi_52 = 0.00; % [phi_S5] Azimuthal angle of 5th order axial star aberration (°) - input_multem.obj_lens_c_54 = 0.00; % [R5] 5th order rosette aberration (Ã…) - input_multem.obj_lens_phi_54 = 0.00; % [phi_R5] Azimuthal angle of 5th order rosette aberration (°) - input_multem.obj_lens_c_56 = 0.00; % [A5] 6-fold astigmatism (Ã…) - input_multem.obj_lens_phi_56 = 0.00; % [phi_A5] Azimuthal angle of 6-fold astigmatism (°) - - input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) - input_multem.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) - - %%%%%%%%% defocus spread function %%%%%%%%%%%% - dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation - input_multem.obj_lens_ti_a = 1.0; - input_multem.obj_lens_ti_sigma = dsf_sigma; % standard deviation - input_multem.obj_lens_ti_beta = 1; - input_multem.obj_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - - %%%%%%%%%% source spread function %%%%%%%%%%%% - ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation - input_multem.obj_lens_si_a = 1.0; - input_multem.obj_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Ã…^-1); otherwise - input_multem.obj_lens_si_beta = 1.0; - input_multem.obj_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 - input_multem.obj_lens_si_azm_npts = 12; % # of integration points. It will be only used if illumination_model=4 - - %%%%%%%%% zero defocus reference %%%%%%%%%%%% - input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 - input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define - - %%%%%%%%%%%%%%%%%%%%%%%%%% STEM Detector %%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.detector.type = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 - - input_multem.detector.cir(1).inner_ang = 60; % Inner angle(mrad) - input_multem.detector.cir(1).outer_ang = 180; % Outer angle(mrad) - - input_multem.detector.radial(1).x = 0; % radial detector angle(mrad) - input_multem.detector.radial(1).fx = 0; % radial sensitivity value - - input_multem.detector.matrix(1).R = 0; % 2D detector angle(mrad) - input_multem.detector.matrix(1).fR = 0; % 2D sensitivity value - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%% Scanning area for ISTEM/STEM/EELS %%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.scanning_type = 1; % eST_Line = 1, eST_Area = 2 - input_multem.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) - input_multem.scanning_square_pxs = 1; % 0: false, 1: true - input_multem.scanning_ns = 10; % number of sampling points - input_multem.scanning_x0 = 0.0; % x-starting point (Ã…) - input_multem.scanning_y0 = 0.0; % y-starting point (Ã…) - input_multem.scanning_xe = 4.078; % x-final point (Ã…) - input_multem.scanning_ye = 4.078; % y-final point (Ã…) - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%PED %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.ped_nrot = 360; % Number of orientations - input_multem.ped_theta = 3.0; % Precession angle (degrees) - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.hci_nrot = 360; % number of orientations - input_multem.hci_theta = 3.0; % Precession angle (degrees) - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%EELS %%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.eels_Z = 79; % atomic type - input_multem.eels_E_loss = 80; % Energy loss (eV) - input_multem.eels_collection_angle = 100; % Collection half angle (mrad) - input_multem.eels_m_selection = 3; % selection rule - input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%EFTEM %%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.eftem_Z = 79; % atomic type - input_multem.eftem_E_loss = 80; % Energy loss (eV) - input_multem.eftem_collection_angle = 100; % Collection half angle (mrad) - input_multem.eftem_m_selection = 3; % selection rule - input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 - - %%%%%%%%%%%%%%%%%%%%%%% OUTPUT REGION %%%%%%%%%%%%%%%%%%%%%%%%%% - %%%% This option is not use for eTEMST_STEM and eTEMST_EELS %%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - input_multem.output_area_ix_0 = 1; % x-starting in pixel - input_multem.output_area_iy_0 = 1; % y-starting in pixel - input_multem.output_area_ix_e = 1; % x-final in pixel - input_multem.output_area_iy_e = 1; % y-final in pixel -end +function [input_multem] = ilm_dflt_input_multem() + %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% + input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 + input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.operation_mode = 1; % eOM_Normal = 1, eOM_Advanced = 2 + input_multem.memory_size = 0; % memory size to be used(Mb) + input_multem.reverse_multislice = 0; % 1: true, 0:false + + %%%%%%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%%%%%% + input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 + input_multem.atomic_vib_coh_contrib = 0; % 1: true, 0: false + input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) + input_multem.atomic_vib_nconf = 1; % true: specific phonon configuration, false: number of frozen phonon configurations + input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions [xyz] + input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + + %%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% + input_multem.spec_atoms = []; % simulation box length in x direction (Å) + + input_multem.spec_bs_x = 10; % simulation box size in x direction (Å) + input_multem.spec_bs_y = 10; % simulation box size in y direction (Å) + input_multem.spec_bs_z = 10; % simulation box size in z direction (Å) + + input_multem.spec_xtl_na = 1; % number of unit cell along a + input_multem.spec_xtl_nb = 1; % number of unit cell along b + input_multem.spec_xtl_nc = 1; % number of unit cell along c + input_multem.spec_xtl_a = 0; % length along a (Å) + input_multem.spec_xtl_b = 0; % length along b (Å) + input_multem.spec_xtl_c = 0; % length along c (Å) + input_multem.spec_xtl_x0 = 0; % reference position along x direction (Å) + input_multem.spec_xtl_y0 = 0; % reference position along y direction (Å) + + %%%%%%%%%%%%%%%%%%%%%%%%% specimen rotation %%%%%%%%%%%%%%%%%%%%%%%% + input_multem.spec_rot_theta = 0; % angle (º) + input_multem.spec_rot_u_0 = [0 0 1]; % unitary vector + input_multem.spec_rot_ctr_typ = 1; % 1: geometric center, 2: User define + input_multem.spec_rot_ctr_p = [0 0 0]; % rotation point + + %%%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + input_multem.spec_slic(1).sli_thick = 2.0; % slice thickness + input_multem.spec_slic(1).sel_typ = 1; % 1: by tag, 2: by z position + input_multem.spec_slic(1).sel_tag = 0; % tag + input_multem.spec_slic(1).sel_Z = 0; % 0: all atomic numbers + input_multem.spec_slic(1).sel_z_lim = [0, 0]; % [z_0, z_e] + input_multem.spec_slic(1).z_plns = []; % vector + %%%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%% + input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 + input_multem.thick = 0; % Array of thickness (Å) + + %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.nx = 512; % number of pixels in x direction + input_multem.ny = 512; % number of pixels in y direction + input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + + %%%%%%%%%%%%%%%% electron microscopy simulation type %%%%%%%%%%%%%%% + % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, + % eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, + % eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, + % eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, + % eTEMST_PPFS=81, eTEMST_PPRS=82, eTEMST_TFFS=91, eTEMST_TFRS=92 + input_multem.em_sim_typ = 52; % electron microscopy simulation type + + %%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.E_0 = 300; % Acceleration Voltage (keV) + input_multem.theta = 0.0; % Polar angle (º) + input_multem.phi = 0.0; % Azimuthal angle (º) + + %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.illum_mod = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration + input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % On the optimun probe in aberration corrected ADF-STEM + % Ultramicroscopy 111(2014) 1523-1530 + % C_{nm} Krivanek --- {A, B, C, D, R}_{n} Haider notation + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% + input_multem.cond_lens_m = 0; % Vortex momentum + + input_multem.cond_lens_c_10 = 14.0312; % [C1] Defocus (Å) + input_multem.cond_lens_c_12 = 0.00; % [A1] 2-fold astigmatism (Å) + input_multem.cond_lens_phi_12 = 0.00; % [phi_A1] Azimuthal angle of 2-fold astigmatism (º) + + input_multem.cond_lens_c_21 = 0.00; % [B2] Axial coma (Å) + input_multem.cond_lens_phi_21 = 0.00; % [phi_B2] Azimuthal angle of axial coma (º) + input_multem.cond_lens_c_23 = 0.00; % [A2] 3-fold astigmatism (Å) + input_multem.cond_lens_phi_23 = 0.00; % [phi_A2] Azimuthal angle of 3-fold astigmatism (º) + + input_multem.cond_lens_c_30 = 1e-03; % [C3] 3rd order spherical aberration (mm) + input_multem.cond_lens_c_32 = 0.00; % [S3] Axial star aberration (Å) + input_multem.cond_lens_phi_32 = 0.00; % [phi_S3] Azimuthal angle of axial star aberration (º) + input_multem.cond_lens_c_34 = 0.00; % [A3] 4-fold astigmatism (Å) + input_multem.cond_lens_phi_34 = 0.0; % [phi_A3] Azimuthal angle of 4-fold astigmatism (º) + + input_multem.cond_lens_c_41 = 0.00; % [B4] 4th order axial coma (Å) + input_multem.cond_lens_phi_41 = 0.00; % [phi_B4] Azimuthal angle of 4th order axial coma (º) + input_multem.cond_lens_c_43 = 0.00; % [D4] 3-lobe aberration (Å) + input_multem.cond_lens_phi_43 = 0.00; % [phi_D4] Azimuthal angle of 3-lobe aberration (º) + input_multem.cond_lens_c_45 = 0.00; % [A4] 5-fold astigmatism (Å) + input_multem.cond_lens_phi_45 = 0.00; % [phi_A4] Azimuthal angle of 5-fold astigmatism (º) + + input_multem.cond_lens_c_50 = 0.00; % [C5] 5th order spherical aberration (mm) + input_multem.cond_lens_c_52 = 0.00; % [S5] 5th order axial star aberration (Å) + input_multem.cond_lens_phi_52 = 0.00; % [phi_S5] Azimuthal angle of 5th order axial star aberration (º) + input_multem.cond_lens_c_54 = 0.00; % [R5] 5th order rosette aberration (Å) + input_multem.cond_lens_phi_54 = 0.00; % [phi_R5] Azimuthal angle of 5th order rosette aberration (º) + input_multem.cond_lens_c_56 = 0.00; % [A5] 6-fold astigmatism (Å) + input_multem.cond_lens_phi_56 = 0.00; % [phi_A5] Azimuthal angle of 6-fold astigmatism (º) + + input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) + input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + + %%%%%%%%% defocus spread function %%%%%%%%%%%% + input_multem.cond_lens_tp_inc_a = 1.0; % Height proportion of a normalized Gaussian [0, 1] + input_multem.cond_lens_tp_inc_sigma = 0.5; % Standard deviation of the source defocus spread for the Gaussian component (Å) + input_multem.cond_lens_tp_inc_beta = 0.1; % Standard deviation of the source defocus spread for the Exponential component (Å) + input_multem.cond_lens_tp_inc_npts = 10; % Number of integration points. It will be only used if illum_mod=4 + + %%%%%%%%%% source spread function %%%%%%%%%%%% + input_multem.cond_lens_spt_inc_a = 1.0; % Height proportion of a normalized Gaussian [0, 1] + input_multem.cond_lens_spt_inc_sigma = 0.5; % Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + input_multem.cond_lens_spt_inc_beta = 0.1; % Standard deviation of the source spread function for the Exponential component: For parallel ilumination(Å^-1);otherwise (Å) + input_multem.cond_lens_spt_inc_rad_npts = 8; % Number of radial integration points. It will be only used if illum_mod=4 + input_multem.cond_lens_spt_inc_azm_npts = 8; % Number of radial integration points. It will be only used if illum_mod=4 + + %%%%%%%%% zero defocus reference %%%%%%%%%%%% + input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 + input_multem.cond_lens_zero_def_plane = 0; % It will be only used if cond_lens_zero_def_typ = eZDT_User_Define + + %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% + input_multem.obj_lens_m = 0; % Vortex momentum + + input_multem.obj_lens_c_10 = 14.0312; % [C1] Defocus (Å) + input_multem.obj_lens_c_12 = 0.00; % [A1] 2-fold astigmatism (Å) + input_multem.obj_lens_phi_12 = 0.00; % [phi_A1] Azimuthal angle of 2-fold astigmatism (º) + + input_multem.obj_lens_c_21 = 0.00; % [B2] Axial coma (Å) + input_multem.obj_lens_phi_21 = 0.00; % [phi_B2] Azimuthal angle of axial coma (º) + input_multem.obj_lens_c_23 = 0.00; % [A2] 3-fold astigmatism (Å) + input_multem.obj_lens_phi_23 = 0.00; % [phi_A2] Azimuthal angle of 3-fold astigmatism (º) + + input_multem.obj_lens_c_30 = 1e-03; % [C3] 3rd order spherical aberration (mm) + input_multem.obj_lens_c_32 = 0.00; % [S3] Axial star aberration (Å) + input_multem.obj_lens_phi_32 = 0.00; % [phi_S3] Azimuthal angle of axial star aberration (º) + input_multem.obj_lens_c_34 = 0.00; % [A3] 4-fold astigmatism (Å) + input_multem.obj_lens_phi_34 = 0.0; % [phi_A3] Azimuthal angle of 4-fold astigmatism (º) + + input_multem.obj_lens_c_41 = 0.00; % [B4] 4th order axial coma (Å) + input_multem.obj_lens_phi_41 = 0.00; % [phi_B4] Azimuthal angle of 4th order axial coma (º) + input_multem.obj_lens_c_43 = 0.00; % [D4] 3-lobe aberration (Å) + input_multem.obj_lens_phi_43 = 0.00; % [phi_D4] Azimuthal angle of 3-lobe aberration (º) + input_multem.obj_lens_c_45 = 0.00; % [A4] 5-fold astigmatism (Å) + input_multem.obj_lens_phi_45 = 0.00; % [phi_A4] Azimuthal angle of 5-fold astigmatism (º) + + input_multem.obj_lens_c_50 = 0.00; % [C5] 5th order spherical aberration (mm) + input_multem.obj_lens_c_52 = 0.00; % [S5] 5th order axial star aberration (Å) + input_multem.obj_lens_phi_52 = 0.00; % [phi_S5] Azimuthal angle of 5th order axial star aberration (º) + input_multem.obj_lens_c_54 = 0.00; % [R5] 5th order rosette aberration (Å) + input_multem.obj_lens_phi_54 = 0.00; % [phi_R5] Azimuthal angle of 5th order rosette aberration (º) + input_multem.obj_lens_c_56 = 0.00; % [A5] 6-fold astigmatism (Å) + input_multem.obj_lens_phi_56 = 0.00; % [phi_A5] Azimuthal angle of 6-fold astigmatism (º) + + input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) + input_multem.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) + + %%%%%%%%% defocus spread function %%%%%%%%%%%% + input_multem.obj_lens_tp_inc_a = 1.0; % Height proportion of a normalized Gaussian [0, 1] + input_multem.obj_lens_tp_inc_sigma = 0.5; % Standard deviation of the source defocus spread for the Gaussian component (Å) + input_multem.obj_lens_tp_inc_beta = 0.1; % Standard deviation of the source defocus spread for the Exponential component (Å) + input_multem.obj_lens_tp_inc_npts = 10; % Number of integration points. It will be only used if illum_mod=4 + + %%%%%%%%% zero defocus reference %%%%%%%%%%%% + input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 + input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% Scan tag for ISTEM/STEM/EELS %%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.scan_pat_typ = 1; % espt_line = 1, espt_area = 2, espt_user_def = 3 + input_multem.scan_pat_pbc = 1; % periodic boundary conditions: 1: true, 0:false + input_multem.scan_pat_spxs = 1; % square pixel size: 1: true, 0:false + input_multem.scan_pat_nsp = 10; % number of sampling points + input_multem.scan_pat_r_0 = [0.0; 0.0]; % starting point (Å) + input_multem.scan_pat_r_e = [4.078; 4.078]; % final point (Å) + input_multem.scan_pat_r = []; % user define scanning pattern. It will be only used if User_Define=3 + + % if input_multem.scan_pat_typ = eST_User_Define, then the beam positions + % must be define in input_multem.beam_pos + + %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto + input_multem.incdt_wav_psi = 0; % User define incident wave. It will be only used if User_Define=3 + + %%%%%%%%%%%%%%%%%%%%%%%%%%% beam positions %%%%%%%%%%%%%%%%%%%%%%%% + input_multem.beam_pos = [0.0; 0.0]; % x-y positions + + %%%%%%%%%%%%%%%%%%%%%%%%%% STEM Detector %%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.detector.typ = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 + + input_multem.detector.cir(1).inner_ang = 60; % Inner angle(mrad) + input_multem.detector.cir(1).outer_ang = 180; % Outer angle(mrad) + + input_multem.detector.radial(1).x = 0; % radial detector angle(mrad) + input_multem.detector.radial(1).fx = 0; % radial sensitivity value + + input_multem.detector.matrix(1).R = 0; % 2D detector angle(mrad) + input_multem.detector.matrix(1).fR = 0; % 2D sensitivity value + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%PED %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.ped_nrot = 360; % Number of orientations + input_multem.ped_theta = 3.0; % Precession angle (degrees) + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.hci_nrot = 360; % number of orientations + input_multem.hci_theta = 3.0; % Precession angle (degrees) + + %%%%%%%%%%%%%%%%%%%%%%%%%% STEM-EELS %%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.eels_Z = 79; % atomic type + input_multem.eels_E_loss = 80; % energy loss (eV) + input_multem.eels_collection_angle = 100; % Collection half angle (mrad) + input_multem.eels_m_selection = 3; % selection rule + input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%% EFTEM %%%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.eftem_Z = 79; % atomic type + input_multem.eftem_E_loss = 80; % energy loss (eV) + input_multem.eftem_collection_angle = 100; % Collection half angle (mrad) + input_multem.eftem_m_selection = 3; % selection rule + input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 + + %%%%%%%%%%%%%%%%%%%%%%%%% output tag %%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%% This option is not used for eTEMST_STEM and eTEMST_STEM_EELS %%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + input_multem.output_area_ip_0 = [1; 1]; % Starting position in pixels + input_multem.output_area_ip_e = [1; 1]; % End position in pixels + + %%%%%%%%%%%%%%%%%%% condenser lens variable %%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%% it will be active in the future %%%%%%%%%%%%%%%%% + % 1: Vortex momentum, 2: Defocus (Å), 2: Third order spherical aberration (mm) + % 3: Third order spherical aberration (mm), 4: Fifth order spherical aberration (mm) + % 5: Twofold astigmatism (Å), 2: Defocus (Å), 6: Azimuthal angle of the twofold astigmatism (º) + % 7: Threefold astigmatism (Å), 8: Azimuthal angle of the threefold astigmatism (º) + % 9: Inner aperture (mrad), 2: Defocus (Å), 10: Outer aperture (mrad) + % input_multem.cdl_var_type = 0; % 0:off 1: m, 2: f, 3 Cs3, 4:Cs5, 5:mfa2, 6:afa2, 7:mfa3, 8:afa3, 9:inner_aper_ang , 10:outer_aper_ang + % input_multem.cdl_var = [-2 -1 0 1 2]; % variable array +end \ No newline at end of file diff --git a/matlab_functions/ilm_dflt_system_conf.m b/matlab_functions/ilm_dflt_system_conf.m new file mode 100755 index 00000000..a9a3f7e5 --- /dev/null +++ b/matlab_functions/ilm_dflt_system_conf.m @@ -0,0 +1,21 @@ +function[system_config] = ilm_dflt_system_conf(device, id_gpu) + if(nargin<2) + id_gpu = 0; + end + + if(nargin<1) + device = 2; + end + + system_config.device = device; % eD_CPU = 1, eD_GPU = 2 + system_config.precision = 1; % eP_Float = 1, eP_double = 2 + + %%%%%%%%%%%%%%%%%%%%%%%% cpu config %%%%%%%%%%%%%%%%%%%%%%%% + system_config.cpu_n_proc = 1; + system_config.cpu_n_thread = 1; + + %%%%%%%%%%%%%%%%%%%%%%%% gpu config %%%%%%%%%%%%%%%%%%%%%%%% + system_config.gpu_device = id_gpu; +% system_config.gpu_n_stream = 1; +% system_config.gpu_device = 0; +end diff --git a/matlab_functions/ilm_draw_scan_area.m b/matlab_functions/ilm_draw_scan_area.m new file mode 100755 index 00000000..a2e27b95 --- /dev/null +++ b/matlab_functions/ilm_draw_scan_area.m @@ -0,0 +1,17 @@ +% Draw area based p = [p_0;p_e] +function[] = ilm_draw_scan_area(fig, p, c) + if(nargin<3) + c = '-r'; + else + c = ['-', erase(c, '-')]; + end + lxy = diff(p, 1, 1); + + figure(fig); + hold on; + plot([p(1, 1), p(1, 1)+lxy(1)], [p(1, 2), p(1, 2)], c, ... + [p(1, 1)+lxy(1), p(1, 1)+lxy(1)], [p(1, 2), p(1, 2)+lxy(2)], c, ... + [p(1, 1)+lxy(1), p(1, 1)], [p(1, 2)+lxy(2), p(1, 2)+lxy(2)], c, ... + [p(1, 1), p(1, 1)], [p(1, 2)+lxy(2), p(1, 2)], c); + axis equal; +end \ No newline at end of file diff --git a/matlab_functions/ilm_ePIE.m b/matlab_functions/ilm_ePIE.m new file mode 100755 index 00000000..86dbad82 --- /dev/null +++ b/matlab_functions/ilm_ePIE.m @@ -0,0 +1,112 @@ +function [Obj, Probe, Psi] = ilm_ePIE(Obj_0, Probe_0, CBED, n_iter, alpha, beta) + CBED = single(CBED); + M = sqrt(ifftshift(CBED)); + + ifft2_sc = sqrt(size(CBED, 1)*size(CBED, 1)); + cbed_sc = sqrt(sum(CBED, 'all')); + + probe_0_sc = cbed_sc/sqrt(sum(abs(Probe_0).^2, 'all')); + Probe_0 = Probe_0*probe_0_sc; + + obj_0_sc = cbed_sc/sqrt(sum(abs(Obj_0.*Probe_0).^2, 'all')); + Obj_0 = Obj_0*obj_0_sc; + + for ik=1:n_iter + Psi_0 = Obj_0.*Probe_0; + Psi = fft2(ifftshift(Psi_0)); + Psi = M.*exp(1j*angle(Psi)); + Psi = fftshift(ifft2(Psi*ifft2_sc)); + + Obj_0_2 = abs(Obj_0).^2; + Probe = Probe_0 + beta*conj(Obj_0).*(Psi-Psi_0)./max(Obj_0_2, [], 'all'); + Probe = Probe*cbed_sc/sqrt(sum(abs(Probe).^2, 'all')); + + Probe_0_2 = abs(Probe_0).^2; + Obj = Obj_0 + alpha*conj(Probe_0).*(Psi-Psi_0)./max(Probe_0_2, [], 'all'); + Obj = Obj*cbed_sc/sqrt(sum(abs(Obj.*Probe).^2, 'all')); + +% disp([sum(abs(psi_0(:)).^2), sum(abs(psi(:)).^2), sum(CBED(:))]/256^2) +% disp([sum(abs(Probe_0(:)).^2), sum(abs(Probe(:)).^2)]/256^2) +% disp([sum(abs(Obj_0.*Probe_0).^2, 'all'), sum(abs(Obj.*Probe).^2, 'all')]/256^2) + + if 0 + figure(2); clf; + subplot(2, 2, 1) + imagesc(abs(Psi_0)); + axis image; + title('Module psi_0'); + colorbar; + subplot(2, 2, 3) + imagesc(angle(Psi_0)); + axis image; + colorbar; + title('Phase psi_0') + + subplot(2, 2, 2) + imagesc(abs(Psi)); + axis image; + title('Module psi'); + colorbar; + subplot(2, 2, 4) + imagesc(angle(Psi)); + axis image; + colorbar; + title('Phase psi'); + end + + if 0 + figure(1); clf; + subplot(2, 4, 1) + imagesc(abs(Obj_0)); + axis image; + title('Module Obj'); + colorbar; + subplot(2, 4, 5) + imagesc(angle(Obj_0)); + axis image; + colorbar; + title('Phase Obj') + + subplot(2, 4, 2) + imagesc(abs(Probe_0)); + axis image; + title('Module Probe'); + colorbar; + subplot(2, 4, 6) + imagesc(angle(Probe_0)); + axis image; + colorbar; + title('Phase Probe'); + + subplot(2, 4, 3) + imagesc(abs(Obj)); + axis image; + title('Module Obj'); + colorbar; + subplot(2, 4, 7) + imagesc(angle(Obj)); + axis image; + colorbar; + title('Phase Obj') + + subplot(2, 4, 4) + imagesc(abs(Probe)); + axis image; + title('Module Probe'); + colorbar; + subplot(2, 4, 8) + imagesc(angle(Probe)); + axis image; + colorbar; + title('Phase Probe'); + end + + Obj_0 = Obj; + Probe_0 = Probe; + end + + + Probe = Probe/probe_0_sc; + Obj = Obj/obj_0_sc; + Psi = Psi/(obj_0_sc*probe_0_sc); +end \ No newline at end of file diff --git a/matlab_functions/ilm_fd_tr_2d_runing_mean.m b/matlab_functions/ilm_fd_tr_2d_runing_mean.m new file mode 100755 index 00000000..d55385b8 --- /dev/null +++ b/matlab_functions/ilm_fd_tr_2d_runing_mean.m @@ -0,0 +1,82 @@ +% find shifting between images +function [at_p] = ilm_fd_tr_2d_runing_mean(system_config, data, p, sigma_g, radius, bd_0, at_p0, n_it, b_fit, ik_ref) + if(isstruct(data)) + disp('Error: The data must be as 3d stack') + return; + end + + [ny, nx, n_data] = ilm_size_data(data); + + if(nargin<10) + ik_ref = 1; % It has to be implemented in the future + end + + if(nargin<9) + b_fit = true; + end + + if(nargin<8) + n_it = 1; + end + + if(nargin<7) + at_p0 = ilm_dflt_at_p(n_data); + end + + if(nargin<6) + bd_0 = zeros(1, 4); + end + + % convert affine transformation to reference position + at_p = at_p0; + at_p(:,5:6) = at_p(:,5:6) - at_p(ik_ref, 5:6); + + % find shift between images + dx = 1; + dy = 1; + for it = 1:n_it + ik = 1; + im_ik = double(data(:, :, ik)); + im_rm = ilc_tr_2d(im_ik, 1, 1, at_p(ik, 5:6), 0); + tic; + for ik = 2:n_data + at_b = at_p(ik, :); + bd_t = ilm_at_v_2_bd(nx, ny, bd_0, at_p0(ik-1, :)); + bd_ik = ilm_set_borders(at_b(5:6)); + bd = max(bd_t, bd_ik); + + [A, txy] = ilm_cvt_at_v_2_A_txy(at_b); + im_ik = double(data(:, :, ik)); + at_p(ik, 5:6) = ilc_fd_tr_2d(system_config, im_rm/(ik-1), im_ik, dx, dy, A, txy, p, sigma_g, bd, 1, 0, b_fit, radius); + + im_rm = im_rm + ilc_tr_2d(im_ik, 1, 1, at_p(ik, 5:6), 0); + + if mod(ik, 10)==0 + t_c = toc; + disp(['iter = ', num2str(it), ' calculating shift between images #', num2str(ik-1), '_', num2str(ik), '_time=', num2str(t_c, '%5.2f')]); + tic; + end + + if 0 + [i_min,i_max] = ilm_min_max(im_ik); + figure(3); + subplot(1, 3, 1); + imagesc(im_rm/(ik-1), [i_min,i_max]); + axis image off; + colormap jet; + title(['# =:', num2str(ik)]) + subplot(1, 3, 2); + imagesc(im_ik,[i_min,i_max]); + axis image off; + colormap jet; + title(['txy = [', num2str(at_p(ik, 5), 2), ', ', num2str(at_p(ik, 6), 2), ']']) + subplot(1, 3, 3); + plot(at_p(1:ik, 5), at_p(1:ik, 6), '-or') + end + % ilm_show_pcf(system_config, double(data(:, :, ik-1)), double(data(:, :, ik)), at_b, at_p(ik, :), p, sigma_g, bd); + end + + % transform affine transformations related to the reference image + at_p(:,5:6) = at_p(:,5:6) - at_p(ik_ref, 5:6); + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_find_closest_xy_pos.m b/matlab_functions/ilm_find_closest_xy_pos.m old mode 100644 new mode 100755 diff --git a/matlab_functions/ilm_fit_pcf_2d.m b/matlab_functions/ilm_fit_pcf_2d.m new file mode 100755 index 00000000..d8fef768 --- /dev/null +++ b/matlab_functions/ilm_fit_pcf_2d.m @@ -0,0 +1,14 @@ +function [pxy] = ilm_fit_pcf_2d(pcf_2d, dx, dy, sigma_g_px) + [ny, nx] = size(pcf_2d, [1, 2]); + bsx = nx*dx; + bsy = ny*dy; + sigma_g = sigma_g_px*min(1/bsx, 1/bsy); + + [~, ixy] = max(pcf_2d(:)); + [I_row, I_col] = ind2sub([ny, nx], ixy); + pxy = [I_col, I_row].*[dx, dy]; + sigma_r = 1/(2*pi*sigma_g); + radius = 1.5*sigma_r; + + pxy = ilc_fit_peak_pos_2d(pcf_2d, dx, dy, pxy, sigma_r, radius); +end \ No newline at end of file diff --git a/matlab_functions/ilm_geom_center_cp.m b/matlab_functions/ilm_geom_center_cp.m old mode 100644 new mode 100755 index cc27f6ba..8c86da12 --- a/matlab_functions/ilm_geom_center_cp.m +++ b/matlab_functions/ilm_geom_center_cp.m @@ -1,5 +1,3 @@ -function[p0]=ilm_geom_center_cp(atoms) - p0 = mean(atoms); % rotation point - [~, ii] = sort(sqrt(sum((atoms-p0).^2, 2))); - p0 = atoms(ii(1), :); +function[p0] = ilm_geom_center_cp(atoms) + p0 = ilm_find_closest_atom_pos(mean(atoms)); end \ No newline at end of file diff --git a/matlab_functions/ilm_gui_stem_reg.m b/matlab_functions/ilm_gui_stem_reg.m new file mode 100755 index 00000000..4b26e44c --- /dev/null +++ b/matlab_functions/ilm_gui_stem_reg.m @@ -0,0 +1,1203 @@ +function[data, nr_grid, at_p] = ilm_gui_stem_reg(system_config, data_i, at_p0) + global n_data nx ny x_c y_c sigma_g_max p fim + global fz_t dx dy b_stop bb_nr p_rect_sel + global f_xy fs_ax fs_ay fs_x_c fs_y_c + global bb_shift_kpf bb_ctrl_kpf + + close all + + bb_shift_kpf = false; + bb_ctrl_kpf = false; + b_stop = false; + + if(nargin<3) + n_data = ilm_nz_data(data_i); + at_p0 = ilm_dflt_at_p(n_data); + end + + fy = 0.60; + fx = 0.75; + dm = get(0, 'MonitorPositions'); + dm = dm(1, :); + w = fx*dm(3); + h = fy*dm(4); + x0 = (1-fx)*w/2; + y0 = (1-fy)*h/2; + + fh = figure(1); clf; + set(fh, {'Name', 'Visible', 'units', 'position', 'CloseRequestFcn'}, {'STEM registration -- Software created by Ivan Lobato: Ivanlh20@gmail.com', 'on', 'pixels', [x0, y0, x0+w, y0+h], @cb_close}) + set(fh, 'MenuBar', 'none'); + set(fh, 'ToolBar', 'none'); + movegui(fh, 'center'); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ui_pnl_opt = uipanel('Parent', fh, 'Title', 'Options', 'Units', 'normalized', ..., + 'FontSize', 12, 'BackgroundColor', 'white', 'Position', [0.1 0.725 0.70 0.26]); + + pnl_x_0 = 12; + pnl_y = 3 + (4:-1:0)*35; + pnl_d = 4; + pnl_h = 24; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + pnl_w = [80, 70, 70, 50, 50, 50, 65, 40, 40, 45, 55, 55, 75, 45]; + pnl_n = length(pnl_w); + pnl_x = pnl_x_0*ones(1, pnl_n); + + for it=2:pnl_n + pnl_x(it) = pnl_x(it-1) + pnl_d + pnl_w(it-1); + end + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'Rigid Reg.', 'Position', [pnl_x(1) pnl_y(1) pnl_w(1) pnl_h]); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Reset txy', 'Position', [pnl_x(2) pnl_y(1) pnl_w(2) pnl_h], 'Callback', @cb_reset_txy); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Reset A', 'Enable', 'off', 'Position', [pnl_x(3) pnl_y(1) pnl_w(3) pnl_h], 'Callback', @cb_reset_A); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Crt. tx', 'Position', [pnl_x(4) pnl_y(1) pnl_w(4) pnl_h], 'Callback', @(src, ev)cb_crt_txy(1)); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Crt. ty', 'Position', [pnl_x(5) pnl_y(1) pnl_w(5) pnl_h], 'Callback', @(src, ev)cb_crt_txy(2)); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Crt. txy', 'Position', [pnl_x(6) pnl_y(1) pnl_w(6) pnl_h], 'Callback', @(src, ev)cb_crt_txy(3)); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Crt. A_txy', 'Enable', 'off', 'Position', [pnl_x(7) pnl_y(1) pnl_w(7) pnl_h], 'Callback', @cb_crt_A_txy); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'n_it', 'Position', [pnl_x(8) pnl_y(1) pnl_w(8) pnl_h]); + + ui_edt_rg_n_it = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '1', 'Position', [pnl_x(9) pnl_y(1) pnl_w(9) pnl_h]); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'idx_ref', 'Position', [pnl_x(10) pnl_y(1) pnl_w(10) pnl_h]); + + ui_pu_idx_ref = uicontrol('Parent', ui_pnl_opt, 'Style', 'popup', ... + 'String', num2cell(1:n_data), 'Value', 1, ... + 'Position', [pnl_x(11) pnl_y(1) pnl_w(11) pnl_h], 'Callback', @cb_idx_ref); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'Preproc', 'Position', [pnl_x(12) pnl_y(1) pnl_w(12) pnl_h]); + + ui_pu_preproc = uicontrol('Parent', ui_pnl_opt, 'Style', 'popup', ... + 'String', {'Raw', 'Laplacian', 'LCWT'}, 'Value', 2, ... + 'Position', [pnl_x(13) pnl_y(1) pnl_w(13) pnl_h], 'Callback', @cb_preproc); + + ui_edt_preproc_sigma = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '4.0', 'Enable', 'off', 'Position', [pnl_x(14) pnl_y(1) pnl_w(14) pnl_h], 'Callback', @cb_show_sel_ui_lb_data); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + pnl_w = [80, 80, 80, 45, 55, 45, 55, 45, 55, 45, 60]; + pnl_n = length(pnl_w); + pnl_x = pnl_x_0*ones(1, pnl_n); + + for it=2:pnl_n + pnl_x(it) = pnl_x(it-1) + pnl_d + pnl_w(it-1); + end + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'Non-Rigid Reg.', 'Position', [pnl_x(1) pnl_y(2) pnl_w(1) pnl_h]); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Assign A-txy', 'Position', [pnl_x(2) pnl_y(2) pnl_w(2) pnl_h], 'Callback', @cb_assign_A_txy); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Crt. nr_grid', 'Position', [pnl_x(3) pnl_y(2) pnl_w(3) pnl_h], 'Callback', @cb_crt_nr_grid); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'n_it_i', 'Position', [pnl_x(4) pnl_y(2) pnl_w(4) pnl_h]); + + ui_edt_nrg_n_it_i = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '10', 'Position', [pnl_x(5) pnl_y(2) pnl_w(5) pnl_h]); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'n_it_o', 'Position', [pnl_x(6) pnl_y(2) pnl_w(6) pnl_h]); + + ui_edt_nrg_n_it_o = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '8', 'Position', [pnl_x(7) pnl_y(2) pnl_w(7) pnl_h]); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'alpha', 'Position', [pnl_x(8) pnl_y(2) pnl_w(8) pnl_h]); + + ui_edt_alpha = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '0.5', 'Position', [pnl_x(9) pnl_y(2) pnl_w(9) pnl_h]); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'Opt.', 'Position', [pnl_x(10) pnl_y(2) pnl_w(10) pnl_h]); + + ui_pu_opt = uicontrol('Parent', ui_pnl_opt, 'Style', 'popup', ... + 'String', {'Mean', 'Poly 1', 'Poly 2', 'orig.'}, 'Position', [pnl_x(11) pnl_y(2) pnl_w(11) pnl_h]); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % 1, 2, 3, 4, 5, 6, 7 + pnl_w = [270, 50, 50, 50, 65, 100, 110]; + pnl_n = length(pnl_w); + pnl_x = pnl_x_0*ones(1, pnl_n); + + for it=2:pnl_n + pnl_x(it) = pnl_x(it-1) + pnl_d + pnl_w(it-1); + end + + ui_bg_opt = uibuttongroup('Parent', ui_pnl_opt, 'units', 'Pixels', ... + 'Position', [pnl_x(1) pnl_y(3) pnl_w(1) pnl_h], 'SelectionChangedFcn', @cb_execute_selection); + + ui_rb_select = uicontrol('Parent', ui_bg_opt, 'Style', 'radiobutton', ... + 'String', 'select', 'Position', [pnl_x_0 0 50 pnl_h]); + + ui_rb_add_bd = uicontrol('Parent', ui_bg_opt, 'Style', 'radiobutton', ... + 'String', 'add bd', 'Position', [pnl_x_0+(60+pnl_d) 0 60 pnl_h]); + + ui_rb_resize = uicontrol('Parent', ui_bg_opt, 'Style', 'radiobutton', ... + 'String', 'resize', 'Position', [pnl_x_0+(120+2*pnl_d) 0 60 pnl_h]); + + ui_rb_crop = uicontrol('Parent', ui_bg_opt, 'Style', 'radiobutton', ... + 'String', 'crop', 'Position', [pnl_x_0+(180+3*pnl_d) 0 60 pnl_h]); + + ui_edt_sampling_x = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '0', 'Position', [pnl_x(2) pnl_y(3) pnl_w(2) pnl_h]); + + ui_edt_sampling_y = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '0', 'Position', [pnl_x(3) pnl_y(3) pnl_w(3) pnl_h]); + + ui_pb_execute = uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Exec.', 'Position', [pnl_x(4) pnl_y(3) pnl_w(4) pnl_h], 'Callback', @cb_execute); + + ui_cb_reg_typ = uicontrol('Parent', ui_pnl_opt, 'Style', 'checkbox', ... + 'String', 'Rig. Reg.', 'Value', 1, 'Position', [pnl_x(5) pnl_y(3) pnl_w(5) pnl_h], 'Callback', @cb_reg_typ); + + ui_pb_show_data = uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Show rg data', 'Position', [pnl_x(6) pnl_y(3) pnl_w(6) pnl_h], 'Callback', @cb_show_data); + + ui_pb_show_avg_data = uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'show avg rg data', 'Position', [pnl_x(7) pnl_y(3) pnl_w(7) pnl_h], 'Callback', @cb_show_avg_data); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + pnl_w = [75, 75, 60, 70, 60, 60, 60, 65, 165, 60, 60]; + pnl_n = length(pnl_w); + pnl_x = pnl_x_0*ones(1, pnl_n); + + for it=2:pnl_n + pnl_x(it) = pnl_x(it-1) + pnl_d + pnl_w(it-1); + end + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'Reset data', 'Position', [pnl_x(1) pnl_y(4) pnl_w(1) pnl_h], 'Callback', @cb_reset_data); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'Sigma_g(px.)', 'Position', [pnl_x(2) pnl_y(4) pnl_w(2) pnl_h]); + + ui_edt_sigma = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', num2str(sigma_g_max/2, '%5.2f'), 'Position', [pnl_x(3) pnl_y(4) pnl_w(3) pnl_h]); + + ui_cb_rcfft = uicontrol('Parent', ui_pnl_opt, 'Style', 'checkbox', ... + 'String', 'Recal. fft', 'Value', 1, 'Position', [pnl_x(4) pnl_y(4) pnl_w(4) pnl_h]); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'Exp. FFT', 'Position', [pnl_x(5) pnl_y(4) pnl_w(5) pnl_h]); + + ui_pu_exp = uicontrol('Parent', ui_pnl_opt, 'Style', 'popup', ... + 'String', {'0.100', '0.125', '0.20', '0.25', '0.5', '0.75'}, 'Value', 3, ... + 'Position', [pnl_x(6) pnl_y(4) pnl_w(6) pnl_h], 'Callback', @(src, ev)fcn_show_ax_f_1(false)); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', 'Time(s.)', 'Position', [pnl_x(7) pnl_y(4) pnl_w(7) pnl_h]); + + ui_edt_time = uicontrol('Parent', ui_pnl_opt, 'Style', 'edit', ... + 'String', '0.05', 'Position', [pnl_x(8) pnl_y(4) pnl_w(8) pnl_h]); + + ui_txt_msg = uicontrol('Parent', ui_pnl_opt, 'Style', 'text', ... + 'String', '00.0%', 'Position', [pnl_x(9) pnl_y(4) pnl_w(9) pnl_h], 'FontSize', 13, 'FontWeight', 'bold'); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'stop', 'Position', [pnl_x(10) pnl_y(4) pnl_w(10) pnl_h], 'Callback', @cb_stop); + + uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'String', 'close', 'Position', [pnl_x(11) pnl_y(4) pnl_w(11) pnl_h], 'Callback', @cb_close); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + pnl_w = [850]; + pnl_n = length(pnl_w); + pnl_x = pnl_x_0*ones(1, pnl_n); + + for it=2:pnl_n + pnl_x(it) = pnl_x(it-1) + pnl_d + pnl_w(it-1); + end + + ui_pb_data_info = uicontrol('Parent', ui_pnl_opt, 'Style', 'pushbutton', ... + 'Enable', 'inactive', 'String', ' ', 'Position', [pnl_x(1) pnl_y(5) pnl_w(1) pnl_h]); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + d_f = 0.010; + h_f = 0.55; + w_1 = 0.16; + w_2 = h_f*h/w; + w_3 = w_2; + w_4 = w_3; + + x_1 = (1-(w_1+w_2+w_3+w_4+3*d_f))/2; + x_2 = x_1+w_1+d_f; + x_3 = x_2+w_2+d_f; + x_4 = x_3+w_3+d_f; + y_0 = 0.10; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ui_lb_data = uicontrol('Style', 'listbox', 'Units', 'normalized', ... + 'Position', [x_1 y_0 w_1 h_f], 'Callback', @cb_show_sel_ui_lb_data); + + ax_f(1) = axes('Position', [x_2 y_0 w_2 h_f], 'Visible', 'off'); + ax_f(2) = axes('Position', [x_3 y_0 w_3 h_f], 'Visible', 'off'); + ax_f(3) = axes('Position', [x_4 y_0 w_4 h_f], 'Visible', 'off'); + + fcn_init(system_config, data_i, at_p0); + + fh.WindowButtonMotionFcn = @cb_mouse_move; + fh.WindowButtonDownFcn = @cb_mouse_click; + fh.WindowScrollWheelFcn = @cb_zoom; + fh.WindowKeyPressFcn = @cb_press_key; + fh.WindowKeyReleaseFcn = @cb_release_key; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + uiwait(fh) + + function [typ] = fcn_get_activate_typ() + typ = ilm_ifelse(ui_rb_add_bd.Value, 1, 0); + typ = ilm_ifelse(ui_rb_resize.Value, 2, typ); + typ = ilm_ifelse(ui_rb_crop.Value, 3, typ); + end + + function fcn_activate_opt(typ) + if(typ==0) % select + ui_edt_sampling_x.Enable = 'off'; + ui_edt_sampling_y.Enable = 'off'; + + ui_pb_execute.Enable = 'off'; + elseif(typ==1) % add bd + ui_edt_sampling_x.String = num2str(0); + ui_edt_sampling_x.Enable = 'on'; + + ui_edt_sampling_y.String = num2str(0); + ui_edt_sampling_y.Enable = 'on'; + + ui_pb_execute.Enable = 'on'; + ui_pb_execute.Enable = 'on'; + elseif(typ==2) % resize + if(str2double(ui_edt_sampling_x.String)<64) + ui_edt_sampling_x.String = num2str(nx); + end + ui_edt_sampling_x.Enable = 'on'; + + if(str2double(ui_edt_sampling_y.String)<64) + ui_edt_sampling_y.String = num2str(ny); + end + ui_edt_sampling_y.Enable = 'off'; + + ui_pb_execute.Enable = 'on'; + elseif(typ==3) % crop + ui_edt_sampling_x.Enable = 'off'; + ui_edt_sampling_y.Enable = 'off'; + + ui_pb_execute.Enable = 'on'; + end + end + + function cb_execute_selection(source, event) + typ = fcn_get_activate_typ(); + fcn_activate_opt(typ) + end + + function cb_execute(source, event) + fcn_msn_start(); + + typ = fcn_get_activate_typ(); + + if(typ==1) % add bd + bd_x = round(str2double(ui_edt_sampling_x.String)); + bd_x = ilm_pn_border(nx, bd_x, 1); + nx_r = nx+2*bd_x; + ix_0 = bd_x + 1; + ix_e = ix_0 + nx-1; + ax = ix_0:ix_e; + + bd_y = round(str2double(ui_edt_sampling_y.String)); + bd_y = ilm_pn_border(ny, bd_y, 1); + ny_r = ny + 2*bd_y; + iy_0 = bd_y + 1; + iy_e = iy_0 + ny-1; + ay = iy_0:iy_e; + + data_t = zeros(ny_r, nx_r, n_data); + % data_t(ay, ax, :) = data; + for ik=1:n_data + im_ik = double(data(:, :, ik)); + data_t(:, :, ik) = mean(im_ik(:)); + data_t(ay, ax, ik) = im_ik; + + ui_txt_msg.String = [num2str(100*ik/n_data, '%4.1f'), ' %']; + pause(0.001); + end + + p_rect_sel_0 = p_rect_sel + [bd_x, bd_y]; + + fcn_init(system_config, data_t, at_p, p_rect_sel_0); + + ui_edt_sampling_x.String = num2str(0); + ui_edt_sampling_y.String = num2str(0); + + elseif(typ==2) % resize + nx_r = round(str2double(ui_edt_sampling_x.String)); + + if(nx_r==0) + return; + end + ny_r = round(nx_r*ny/nx); + nx_r = ilm_pn_fact(nx_r); + + data_t = zeros(ny_r, nx_r, n_data); + for ik=1:n_data + im_ik = double(data(:, :, ik)); + data_t(:, :, ik) = max(0, imresize(im_ik, [ny_r, nx_r], 'bicubic')); + + ui_txt_msg.String = [num2str(100*ik/n_data, '%4.1f'), ' %']; + pause(0.001); + end + + at_p(:, 5:6) = at_p(:, 5:6).*[nx_r/nx, ny_r/ny]; + if(mod(ny_r, 2)==1) + data_t = data_t(1:(end-1), :, :); + end + + fcn_init(system_config, data_t, at_p); + + ui_edt_sampling_x.String = num2str(0); + ui_edt_sampling_y.String = num2str(0); + elseif(typ==3) % crop + ax = p_rect_sel(1, 1):p_rect_sel(2, 1); + ay = p_rect_sel(1, 2):p_rect_sel(2, 2); + + for ik=1:n_data + [A, txy] = ilm_cvt_at_v_2_A_txy(at_p(ik, :)); + im_ik = double(data(:, :, ik)); + data(:, :, ik) = ilc_tr_at_2d(system_config, im_ik, dx, dy, A, txy, 3, 0); + ui_txt_msg.String = [num2str(100*ik/n_data, '%4.1f'), ' %']; + pause(0.001); + end + + at_p = ilm_dflt_at_p(n_data); + + fcn_init(system_config, data(ay, ax, :), at_p); + end + + fcn_msn_end(); + end + + function s = fcn_str_data_info(p_rect_sel) + s = ['[nx, ny] = [', num2str(nx), ', ', num2str(ny), ']']; + s = [s, ' - [ix_0, ix_e] = [', num2str(p_rect_sel(1, 1)), ', ', num2str(p_rect_sel(2, 1)), ']']; + s = [s, ' - [iy_0, iy_e] = [', num2str(p_rect_sel(1, 2)), ', ', num2str(p_rect_sel(2, 2)), ']']; + s = [s, ' - [nx_s, ny_s] = [', num2str(abs(p_rect_sel(2, 1)-p_rect_sel(1, 1))+1), ', ', num2str(abs(p_rect_sel(2, 2)-p_rect_sel(1, 2))+1), ']']; + end + + function fcn_init(system_config, data_i, at_p_0, p_rect_sel_0) + fcn_msn_start(); + + bb_nr = false; + + data = data_i; + [ny, nx, n_data] = ilm_size_data(data); + + if(nx>ny) + f_xy = [1, nx/ny]; + else + f_xy = [ny/nx, 1]; + end + + fs_ax = (1:nx)*f_xy(1); + fs_ay = (1:ny)*f_xy(2); + fs_x_c = nx*f_xy(1)/2 + 1; + fs_y_c = ny*f_xy(2)/2 + 1; + + dx = 1; + dy = 1; + + x_c = nx/2 + 1; + y_c = ny/2 + 1; + + if(nargin<4) + p_rect_sel_0 = [1, 1; nx, ny]; + end + + p_rect_sel = p_rect_sel_0; + + at_p = at_p_0; + + % set sigma max + sigma_g_max = min(nx/2, ny/2)-1; + + % set initial sigma + fim = fcn_mean_abs_fdata_at(system_config, data, at_p); + sigma_gt = ilc_info_lim_2d(fim); + + ui_edt_sampling_x.String = num2str(nx); + ui_edt_sampling_y.String = num2str(ny); + ui_edt_sigma.String = num2str(sigma_gt, '%5.2f'); + ui_pb_data_info.String = fcn_str_data_info(p_rect_sel); + + % set initial zoom + fz_t(1) = sigma_g_max/(2*sigma_gt); + fz_t(2) = 1; + fz_t(3) = sigma_g_max/min(sigma_g_max/2, max(sigma_g_max/5, 6*ilm_sigma_g_2_sigma_r(nx, ny, sigma_gt))); + + % plot fim + fcn_show_ax_f_1(false); + + axes(ax_f(1)); + ax = gca; + ax.Toolbar.Visible = 'off'; + + % set initial lb_data values + fcn_set_at_p_2_ui_lb_data(at_p); + + axes(ax_f(2)); + ax = gca; + ax.Toolbar.Visible = 'off'; + + axes(ax_f(3)); + ax = gca; + ax.Toolbar.Visible = 'off'; + + ui_lb_data.Value = 1; + cb_show_sel_ui_lb_data(); + + fcn_msn_end(); + end + + function [image_av] = fcn_mean_abs_fdata_at(system_config, data, at_p) + [ny, nx, n_data] = ilm_size_data(data); + + n_idx = max(2, round(n_data/2)); + a_idx = randperm(n_data, n_idx); + + image_av = zeros(ny, nx); + radius = 0.85*min(nx, ny)/2; + fbw = ilc_wd_butwth([nx, 1], [1, 1], 8, radius); + fbw = fbw.*ilc_wd_butwth([1, ny], [1, 1], 8, radius); + + for ik = a_idx + [A, txy] = ilm_cvt_at_v_2_A_txy(at_p(ik, :)); + image_ik = double(data(:, :, ik)); + [image_ik, bg_ik] = ilc_tr_at_2d(system_config, image_ik, dx, dy, A, txy, 3, 0); + image_ik = (image_ik-0.999*bg_ik).*fbw; + + image_av = image_av + abs(fft2(image_ik)); + end + + image_av = ifftshift(image_av/n_idx); + end + + function fcn_msn_start() + ui_txt_msg.String = 'Processing'; + drawnow; + end + + function fcn_msn_end() + ui_txt_msg.String = 'Done'; + drawnow; + end + + function fcn_set_at_p_2_ui_lb_data(at_p) + n_at_p = size(at_p, 1); + items{1, n_at_p} = []; + UserData{1, n_at_p} = []; + for ik=1:n_at_p + s_at_p_ik = ['[', num2str(at_p(ik, 3), '%4.3f'), ', ', num2str(at_p(ik, 4), '%4.3f'), ... + ', ', num2str(at_p(ik, 5), '%5.2f'), ', ', num2str(at_p(ik, 6), '%5.2f'), ']']; + + items{ik} = ['ik = ', num2str(ik, '%.3d'), ', at_p = ' s_at_p_ik]; + UserData{ik} = ik; + end + ui_lb_data.String = items; + ui_lb_data.UserData = UserData; + end + + function[im] = fcn_rescale_img(im_i) + alpha = str2double(ui_pu_exp.String{ui_pu_exp.Value}); + if(~isnumeric(alpha)) + alpha = 0.20; + end + + alpha = max(0.01, abs(alpha)); + + im = abs(im_i).^alpha; + end + + function fcn_set_nr_grid_0(n_data, nx, ny) + nr_grid.x = zeros(ny, nx, n_data, 'single'); + nr_grid.y = zeros(ny, nx, n_data, 'single'); + end + + function st_opt = fcn_st_preproc_st_opt() + sigma = str2double(ui_edt_preproc_sigma.String); + if(~isnumeric(sigma)) + sigma = 4.0; + end + st_opt.preproc_opt = ui_pu_preproc.Value; + st_opt.preproc_sigma = max(1.0, abs(sigma)); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + function fcn_show_ax_f_1(b_fimage_rc) + if(nargin==0) + b_fimage_rc = true; + end + + if(b_fimage_rc) + fim = fcn_mean_abs_fdata_at(system_config, data, at_p); + end + + % set axes + axes(ax_f(1)); + + % plot fimage + imagesc(fs_ax, fs_ay, fcn_rescale_img(fim)); + axis image off; + colormap bone; + + % plot circle + sigma_gt = str2double(ui_edt_sigma.String); + ilm_plot_circle(fs_x_c, fs_y_c, sigma_gt, 'red', 'f'); + + zoom(fz_t(1)); + end + + function fcn_show_ax_f_2(im, title_str) + % set axes + axes(ax_f(2)); + imagesc(im); + axis image off; + colormap bone; + title(title_str); + + bd = ilm_calc_borders_using_at_v(at_p); + p_rect_sel_atp = fcn_bd_2_p_rect_sel(bd); + ilm_plot_rectangle(p_rect_sel_atp, 'blue', 'f'); + + ilm_plot_rectangle(p_rect_sel, 'red', 'f'); + + zoom(fz_t(2)); + end + + function fcn_show_ax_f_3(im, title_str) + % set axes + axes(ax_f(3)); + imagesc(im); + axis image off; + colormap bone; + title(title_str); + + zoom(fz_t(3)); + end + + function fcn_plot_data_rg(im_r, A_r, txy_r, im_s, A_s, txy_s, p, sigma_gt, bd, title_ax_2, title_ax_3) + st_opt = fcn_st_preproc_st_opt(); + + [im_rp, im_sp] = ilm_pcf_data_tf(im_r, im_s, st_opt.preproc_opt, st_opt.preproc_sigma); + + im_rp = ilc_tr_at_2d(system_config, im_rp, dx, dy, A_r, txy_r, 3, 0); + + pcf = ilc_pcf_2d(system_config, im_rp, im_sp, dx, dy, A_s, txy_s, p, sigma_gt, bd, 3, 0); + + im_r_plot = ilc_tr_at_2d(system_config, im_r, dx, dy, A_r, txy_r, 3, 0); + fcn_show_ax_f_2(im_r_plot, title_ax_2); + + fcn_show_ax_f_3(pcf, title_ax_3); + end + + function fcn_plot_data_nrg(im_r, im_s, p, sigma_gt, bd, title_ax_2, title_ax_3) + + A = [1 0; 0 1]; + txy = [0; 0]; + + st_opt = fcn_st_preproc_st_opt(); + [im_rp, im_sp] = ilm_pcf_data_tf(im_r, im_s, st_opt.preproc_opt, st_opt.preproc_sigma); + + pcf = ilc_pcf_2d(system_config, im_rp, im_sp, dx, dy, A, txy, p, sigma_gt, bd, 3, 0); + + fcn_show_ax_f_2(im_r, title_ax_2); + + fcn_show_ax_f_3(pcf, title_ax_3); + end + + function cb_show_sel_ui_lb_data(source, event) + sigma_gt = str2double(ui_edt_sigma.String); + + if(sigma_gt>sigma_g_max) + return + end + + p = 0.05; + bd = fcn_p_rect_sel_2_bd(p_rect_sel); + + fcn_msn_start(); + + ik_r = ui_lb_data.UserData{ui_lb_data.Value}; + ik_s = ilm_ifelse(ik_r==n_data, ik_r-1, ik_r+1); + + title_ax_2 = ['Image # ', num2str(ik_r)]; + title_ax_3 = ['Pcf #= ', num2str(ik_r), ' - ', num2str(ik_s)]; + + if ui_cb_reg_typ.Value + im_r = double(data(:, :, ik_r)); + [A_r, txy_r] = ilm_cvt_at_v_2_A_txy(at_p(ik_r, :)); + + im_s = double(data(:, :, ik_s)); + [A_s, txy_s] = ilm_cvt_at_v_2_A_txy(at_p(ik_s, :)); + + fcn_plot_data_rg(im_r, A_r, txy_r, im_s, A_s, txy_s, p, sigma_gt, bd, title_ax_2, title_ax_3); + else + [Rx_i, Ry_i] = meshgrid(0:(nx-1), 0:(ny-1)); + + Rx = Rx_i + double(nr_grid.x(:, :, ik_r)); + Ry = Ry_i + double(nr_grid.y(:, :, ik_r)); + im_r = ilc_interp_rn_2d(system_config, double(data(:, :, ik_r)), Rx, Ry); + + Rx = Rx_i + double(nr_grid.x(:, :, ik_s)); + Ry = Ry_i + double(nr_grid.y(:, :, ik_s)); + im_s = ilc_interp_rn_2d(system_config, double(data(:, :, ik_s)), Rx, Ry); + + fcn_plot_data_nrg(im_r, im_s, p, sigma_gt, bd, title_ax_2, title_ax_3) + end + + fcn_msn_end(); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function fcn_show_rg_data(sigma_gt) + p = 0.05; + bd = fcn_p_rect_sel_2_bd(p_rect_sel); + for ik=2:n_data + if(b_stop) + break; + end + + title_ax_2 = ['Image # ', num2str(ik-1)]; + title_ax_3 = ['Pcf #= ', num2str(ilm_set_bound(ik-1, 1, n_data+1)), ' - ', num2str(ik)]; + + im_r = double(data(:, :, ik-1)); + [A_r, txy_r] = ilm_cvt_at_v_2_A_txy(at_p(ik-1, :)); + + im_s = double(data(:, :, ik)); + [A_s, txy_s] = ilm_cvt_at_v_2_A_txy(at_p(ik, :)); + + fcn_plot_data_rg(im_r, A_r, txy_r, im_s, A_s, txy_s, p, sigma_gt, bd, title_ax_2, title_ax_3) + + ui_txt_msg.String = [num2str(100*ik/n_data, '%4.1f'), ' %']; + + tm = str2double(ui_edt_time.String); + tm = ilm_ifelse(isnan(tm), 0.075, tm); + pause(tm); + end + b_stop = false; + end + + function fcn_show_nr_data(sigma_gt) + if(~bb_nr) + nr_grid = ilm_at_p_2_nr_grid(at_p, nx, ny); + end + + p = 0.05; + bd = fcn_p_rect_sel_2_bd(p_rect_sel); + + [Rx_i, Ry_i] = meshgrid(0:(nx-1), 0:(ny-1)); + + for ik=2:n_data + if(b_stop) + break; + end + + title_ax_2 = ['Image # ', num2str(ik-1)]; + title_ax_3 = ['Pcf #= ', num2str(ilm_set_bound(ik-1, 1, n_data+1)), ' - ', num2str(ik)]; + + Rx = Rx_i + double(nr_grid.x(:, :, ik-1)); + Ry = Ry_i + double(nr_grid.y(:, :, ik-1)); + im_r = ilc_interp_rn_2d(system_config, double(data(:, :, ik-1)), Rx, Ry); + + Rx = Rx_i + double(nr_grid.x(:, :, ik)); + Ry = Ry_i + double(nr_grid.y(:, :, ik)); + im_s = ilc_interp_rn_2d(system_config, double(data(:, :, ik)), Rx, Ry); + + fcn_plot_data_nrg(im_r, im_s, p, sigma_gt, bd, title_ax_2, title_ax_3) + + ui_txt_msg.String = [num2str(100*ik/n_data, '%4.1f'), ' %']; + + tm = str2double(ui_edt_time.String); + tm = ilm_ifelse(isnan(tm), 0.075, tm); + pause(tm); + end + b_stop = false; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function cb_reset_txy(source, event) + at_p(:, 5:6) = at_p0(:, 5:6); + + % fill in ui_lb_data + fcn_set_at_p_2_ui_lb_data(at_p); + + % select item in ui_lb_data + cb_show_sel_ui_lb_data(); + + % plot fimage + fcn_show_ax_f_1(true); + end + + function cb_reset_A(source, event) + at_p(:, 1) = 1; + at_p(:, 2:3) = 0; + at_p(:, 4) = 1; + + % fill in ui_lb_data + fcn_set_at_p_2_ui_lb_data(at_p); + + % select item in ui_lb_data + cb_show_sel_ui_lb_data(); + + % plot fimage + fcn_show_ax_f_1(true); + end + + function cb_assign_A_txy(source, event) + fcn_msn_start(); + + nr_grid = ilm_at_p_2_nr_grid(at_p, nx, ny); + cb_show_sel_ui_lb_data(); + + fcn_msn_end(); + + bb_nr = true; + end + + function cb_reset_data(source, event) + data = data_i; + n_data = ilm_nz_data(data); + [ny, nx, n_data] = ilm_size_data(data); + at_p = at_p0; + + % reset nr_grid + fcn_set_nr_grid_0(n_data, nx, ny); + + % fill in ui_lb_data + fcn_set_at_p_2_ui_lb_data(at_p); + + % plot fimage + fcn_show_ax_f_1(true); + + % select item in ui_lb_data + cb_show_sel_ui_lb_data(); + + p_rect_sel = [1, 1; nx, ny]; + + bb_nr = false; + end + + function cb_stop(source, event) + b_stop = true; + end + + function cb_preproc(source, event) + ui_edt_preproc_sigma.Enable = ilm_ifelse(ui_pu_preproc.Value==3, 'on', 'off'); + cb_show_sel_ui_lb_data(source, event); + end + + function cb_idx_ref(source, event) + idx_ref = ui_pu_idx_ref.Value; + at_p(:, 5:6) = at_p(:, 5:6) - at_p(idx_ref, 5:6); + cb_show_sel_ui_lb_data(source, event); + end + + function cb_reg_typ(source, event) + if source.Value + ui_pb_show_data.String = 'Show rg data'; + ui_pb_show_avg_data.String = 'Show avg rg data'; + else + ui_pb_show_data.String = 'Show nrg data'; + ui_pb_show_avg_data.String = 'Show avg nrg data'; + end + + cb_show_sel_ui_lb_data(); + end + + function cb_show_data(source, event) + sigma_gt = str2double(ui_edt_sigma.String); + + if(sigma_gt>sigma_g_max) + return + end + + fcn_msn_start(); + + if ui_cb_reg_typ.Value + fcn_show_rg_data(sigma_gt); + else + fcn_show_nr_data(sigma_gt); + end + + cb_show_sel_ui_lb_data(); + + fcn_msn_end(); + end + + function cb_show_avg_data(source, event) + fcn_msn_start(); + + if ui_cb_reg_typ.Value + image_avg = ilm_mean_data_at(system_config, data, at_p, 3); + fig_n = 2; + title_str = 'Average image rigid registration'; + else + image_avg = ilm_mean_data_nr_grid(system_config, data, nr_grid, 3); + fig_n = 3; + title_str = 'Average image non-rigid registration'; + end + + % set constant borders + + bd = ilm_calc_borders_using_at_v(at_p); + image_avg = ilc_repl_bdr(image_avg, bd, 3); + + figure(fig_n); + imagesc(image_avg); + axis image off; + colormap bone; + title(title_str); + + fcn_msn_end(); + + figure(fig_n); + end + + function bd = fcn_p_rect_sel_2_bd(p_rect_sel) + bd = [p_rect_sel(1, 1)-1, nx-p_rect_sel(2, 1), p_rect_sel(1, 2)-1, ny-p_rect_sel(2, 2)]; + bd(1) = max(0, bd(1)); + bd(2) = min(nx, bd(2)); + bd(3) = max(0, bd(3)); + bd(4) = min(ny, bd(4)); + end + + function p_rect = fcn_bd_2_p_rect_sel(bd) + p_rect = [bd(1)+1, nx-bd(2); bd(3)+1, ny-bd(4)].'; + p_rect(1, 1) = max(1, p_rect(1, 1)); + p_rect(2, 1) = min(nx, p_rect(2, 1)); + p_rect(1, 2) = max(1, p_rect(1, 2)); + p_rect(2, 2) = min(ny, p_rect(2, 2)); + end + + function bd = fcn_atp_p_rect_sel_2_bd(at_p, p_rect_sel) + bd = ilm_calc_borders_using_at_v(at_p); + bd_user = [p_rect_sel(1, 1)-1, nx-p_rect_sel(2, 1), p_rect_sel(1, 2)-1, ny-p_rect_sel(2, 2)]; + bd = max(bd, bd_user); + end + + function cb_crt_txy(opt) + sigma_gt = str2double(ui_edt_sigma.String); + + if(sigma_gt>sigma_g_max) + return + end + + fcn_msn_start(); + + idx_ref = ui_pu_idx_ref.Value; + at_p(:, 5:6) = at_p(:, 5:6) - at_p(idx_ref, 5:6); + + rg_n_it = str2num(ui_edt_rg_n_it.String); %#ok + b_fit = true; + sigma_rt = ilm_sigma_g_2_sigma_r(nx, ny, sigma_gt); + radius = sigma_rt; + p = 0.05; + + % calculate shifting between images + st_opt = fcn_st_preproc_st_opt(); + bd = fcn_atp_p_rect_sel_2_bd(at_p, p_rect_sel); + at_p_r = ilm_fd_tr_2d_bi(system_config, data, p, sigma_gt, radius, bd, at_p, rg_n_it, b_fit, st_opt); + + % center shifts + if idx_ref>0 + if(opt==1) + at_p(:, 5) = at_p_r(:, 5) - at_p_r(idx_ref, 5); + elseif(opt==2) + at_p(:, 6) = at_p_r(:, 6) - at_p_r(idx_ref, 6); + else + at_p(:, 5:6) = at_p_r(:, 5:6) - at_p_r(idx_ref, 5:6); + end + else + at_p = ilm_center_tr_2d_using_at_v(at_p); + end + + % fill in ui_lb_data + fcn_set_at_p_2_ui_lb_data(at_p); + + % plot fimage + fcn_show_ax_f_1(ui_cb_rcfft.Value); + + % select item in ui_lb_data + cb_show_sel_ui_lb_data(); + + fcn_msn_end(); + end + + function cb_crt_A_txy(source, event) + sigma_gt = str2double(ui_edt_sigma.String); + + if(sigma_gt>sigma_g_max) + return + end + + fcn_msn_start(); + + rg_n_it = str2num(ui_edt_rg_n_it.String); %#ok + + % find affine transformation + at_p = ilm_run_rg_stem(system_config, data, p, sigma_gt, at_p, rg_n_it); + + % fill in ui_lb_data + fcn_set_at_p_2_ui_lb_data(at_p); + + % plot fimage + fcn_show_ax_f_1(ui_cb_rcfft.Value); + + % show pcf + %fcn_show_rg_data(sigma_gt); + + % select item in ui_lb_data + cb_show_sel_ui_lb_data(); + + fcn_msn_end(); + end + + function cb_crt_nr_grid(source, event) + fcn_msn_start(); + + sigma_gt = str2double(ui_edt_sigma.String); + sigma_r = 1/(2*pi*sigma_gt*min(1/nx, 1/ny)); + alpha = str2double(ui_edt_alpha.String); + + nrg_n_it_i = str2num(ui_edt_nrg_n_it_i.String); %#ok + nrg_n_it_o = str2num(ui_edt_nrg_n_it_o.String); %#ok + + opt = ui_pu_opt.Value; + + bd = fcn_atp_p_rect_sel_2_bd(at_p, p_rect_sel); + nr_grid = ilm_run_nr_stem(system_config, data, bd, alpha, sigma_r, nr_grid, nrg_n_it_i, nrg_n_it_o, opt); + + fcn_msn_end(); + end + + function fcn_draw_circle_ax_f_1(bb_mouse_click) + C = get(ax_f(1), 'CurrentPoint'); + sigma_gt = sqrt((C(1, 1)-fs_x_c)^2+(C(1, 2)-fs_y_c)^2); + sigma_rt = ilm_sigma_g_2_sigma_r(nx, ny, sigma_gt); + + children = get(ax_f(1), 'Children'); + if bb_mouse_click + delete(findobj(children, 'Type', 'Line')); + + if(sigma_gt>sigma_g_max) + return + end + else + delete(findobj(children, 'Type', 'Line', '-and', 'Tag', 'm')); + end + + axes(ax_f(1)); + title(ax_f(1), ['sigma_g = ', num2str(sigma_gt, '%6.2f'), ' px. , sigma_r = ', num2str(sigma_rt, '%6.2f'), ' px.']); + + if bb_mouse_click + ui_edt_sigma.String = num2str(sigma_gt, '%5.2f'); + + ilm_plot_circle(fs_x_c, fs_y_c, sigma_gt, 'red', 'f'); + + cb_show_sel_ui_lb_data(); + else + ilm_plot_circle(fs_x_c, fs_y_c, sigma_gt, 'green', 'm'); + end + end + + function fcn_draw_rectangle_ax_f_2(bb_mouse_click) + C = get(ax_f(2), 'CurrentPoint'); + C = [max(1, min(nx, round(C(1, 1)))), max(1, min(ny, round(C(1, 2))))]; + + d = abs(p_rect_sel-C); + [~, ii] = min(d(:)); + + if(bb_ctrl_kpf) + if(ii<=2) + bx = ilm_ifelse(ii==1, C(1), nx-C(1)); + bx = round((nx-ilm_pn_fact(nx-2*bx, 4))/2); + ix_0 = bx+1; + ix_e = nx-bx; + p_rect_sel(:, 1) = [ix_0;ix_e]; + else + by = ilm_ifelse(ii==3, C(2), ny-C(2)); + by = round((ny-ilm_pn_fact(ny-2*by, 4))/2); + iy_0 = by+1; + iy_e = ny-by; + p_rect_sel(:, 2) = [iy_0;iy_e]; + end + elseif(bb_shift_kpf) + if(ii==1) + ix_e = p_rect_sel(2, 1); + ix_0 = round(ix_e - ilm_pn_fact(round(ix_e-C(1)+1))+1); + p_rect_sel(1, 1) = ilm_set_bound(ix_0, 1, nx); + elseif(ii==2) + ix_0 = p_rect_sel(1, 1); + ix_e = round(ilm_pn_fact(round(C(1)-ix_0+1))+ ix_0-1); + p_rect_sel(2, 1) = ilm_set_bound(ix_e, 1, nx); + elseif(ii==3) + iy_e = p_rect_sel(2, 2); + iy_0 = round(iy_e - ilm_pn_fact(round(iy_e-C(2)+1))+1); + p_rect_sel(1, 2) = ilm_set_bound(iy_0, 1, ny); + else + iy_0 = p_rect_sel(1, 2); + iy_e = round(ilm_pn_fact(round(C(2)-iy_0+1))+ iy_0-1); + p_rect_sel(2, 2) = ilm_set_bound(iy_e, 1, ny); + end + end + + children = get(ax_f(2), 'Children'); + if bb_mouse_click + delete(findobj(children, 'Type', 'Line')); + else + delete(findobj(children, 'Type', 'Line', '-and', 'Tag', 'm')); + end + + axes(ax_f(2)); + if bb_mouse_click + cb_show_sel_ui_lb_data(); + else + ilm_plot_rectangle(p_rect_sel, 'green', 'm'); + end + + ui_pb_data_info.String = fcn_str_data_info(p_rect_sel); + end + + function cb_mouse_move(source, event) + if (bb_shift_kpf || bb_ctrl_kpf) + b_ax_f = ilm_gui_is_over_object(source, ax_f); + + if(b_ax_f(1)) + if(bb_shift_kpf) + fcn_draw_circle_ax_f_1(false); + children = get(ax_f(2), 'Children'); + delete(findobj(children, 'Type', 'Line', '-and', 'Tag', 'm')); + end + elseif(b_ax_f(2)) + if((bb_shift_kpf || bb_ctrl_kpf)&& ui_rb_select.Value) + fcn_draw_rectangle_ax_f_2(false); + children = get(ax_f(1), 'Children'); + delete(findobj(children, 'Type', 'Line', '-and', 'Tag', 'm')); + end + end + end + end + + function cb_mouse_click(source, event) + if (bb_shift_kpf || bb_ctrl_kpf) + b_ax_f = ilm_gui_is_over_object(source, ax_f); + + if(b_ax_f(1)) + if(bb_shift_kpf) + fcn_draw_circle_ax_f_1(true); + end + elseif((bb_shift_kpf || bb_ctrl_kpf)&& ui_rb_select.Value) + fcn_draw_rectangle_ax_f_2(true); + end + end + end + + function cb_press_key(obj, event) + if(strcmpi(event.Key, 'delete')) + b_ui_lb_data = ilm_gui_is_over_object(obj, ui_lb_data); + if(~b_ui_lb_data) + return + end + + fcn_msn_start(); + + ik_del = ui_lb_data.UserData{ui_lb_data.Value}; + data(:, :, ik_del) = []; + n_data = ilm_nz_data(data); + + at_p(ik_del, :) = []; + nr_grid.x(:, :, ik_del) = []; + nr_grid.y(:, :, ik_del) = []; + + % fill in ui_lb_data + fcn_set_at_p_2_ui_lb_data(at_p); + ui_lb_data.Value = min(max(1, ik_del), n_data); + + % select item in ui_lb_data + cb_show_sel_ui_lb_data(); + + % plot fimage + fcn_show_ax_f_1(ui_cb_rcfft.Value); + + fcn_msn_end(); + end + + bb_shift_kpf = strcmpi(event.Modifier, 'shift'); + bb_shift_kpf = ilm_ifelse(isempty(bb_shift_kpf), 0, bb_shift_kpf); + + bb_ctrl_kpf = strcmpi(event.Modifier, 'control'); + bb_ctrl_kpf = ilm_ifelse(isempty(bb_ctrl_kpf), 0, bb_ctrl_kpf); + end + + function cb_release_key(source, event) + bb_shift_kpf = 0; + bb_ctrl_kpf = 0; + end + + function cb_zoom(source, event) + fz = 1; + if(event.VerticalScrollCount<0) + fz = 1.5; + elseif(event.VerticalScrollCount>0) + fz = 1/1.5; + end + + b_ax_f = ilm_gui_is_over_object(source, ax_f); + + if(b_ax_f(1)) + fz_t(1) = fz_t(1)*fz; + axes(ax_f(1)); + zoom(fz); + elseif(b_ax_f(2)) + fz_t(2) = fz_t(2)*fz; + axes(ax_f(2)); + zoom(fz); + elseif(b_ax_f(3)) + fz_t(3) = fz_t(3)*fz; + axes(ax_f(3)); + zoom(fz); + end + end + + function cb_close(source, event) + b_stop = true; + + if(~bb_nr) + nr_grid = ilm_at_p_2_nr_grid(at_p, nx, ny); + end + + delete(fh); + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_hist.m b/matlab_functions/ilm_hist.m new file mode 100755 index 00000000..de6ed76a --- /dev/null +++ b/matlab_functions/ilm_hist.m @@ -0,0 +1,25 @@ +function[h, h_min, h_max, dh] = ilm_hist(x, n_bin, n_left_space, n_right_space) + if nargin<4 + n_right_space = 0; + end + + if nargin<3 + n_left_space = 0; + end + + n_bin_r = n_bin - n_left_space - n_right_space; + + x = double(x); + h_min = min(x); + h_max = max(x); + dh = (h_max - h_min)/n_bin_r; + idx = floor((x - h_min)/dh)+1; + idx = n_left_space + min(n_bin_r, max(1, idx)); + + h = zeros(n_bin, 1, 'double'); + n_idx = numel(idx); + for ix=1:n_idx + ik_s = idx(ix); + h(ik_s) = h(ik_s) + 1; + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_ifelse.m b/matlab_functions/ilm_ifelse.m old mode 100644 new mode 100755 index e815d61d..672a9759 --- a/matlab_functions/ilm_ifelse.m +++ b/matlab_functions/ilm_ifelse.m @@ -1,7 +1,7 @@ -function [c] = ilm_ifelse(bb, a, b) - if(bb) - c = a; - else - c = b; - end +function [c] = ilm_ifelse(bb, a, b) + if(bb) %#ok + c = a; + else + c = b; + end end \ No newline at end of file diff --git a/matlab_functions/ilm_lambda.m b/matlab_functions/ilm_lambda.m new file mode 100755 index 00000000..0475b1a3 --- /dev/null +++ b/matlab_functions/ilm_lambda.m @@ -0,0 +1,6 @@ +% Input: E_0(keV), Output:lambda Angstrom +function [lambda] = ilm_lambda(E_0) + emass = 510.99906; % electron rest mass in keV + hc = 12.3984244; % Planck's const x speed of light + lambda = hc/sqrt(E_0*(2.0*emass + E_0)); +end \ No newline at end of file diff --git a/matlab_functions/ilm_lcwt.m b/matlab_functions/ilm_lcwt.m new file mode 100755 index 00000000..f6a75404 --- /dev/null +++ b/matlab_functions/ilm_lcwt.m @@ -0,0 +1,38 @@ +function [im_o]= ilm_lcwt(im_i, sigma) + n = 2*ceil(sigma)+1; + kn = ones(n,n); + kn = kn/sum(kn(:)); + + im_o = (im_i - mean(im_i, 'all'))/std(im_i, 0, 'all'); + + im_mean_0 = conv2(im_o, kn,'same'); + im_mean = imgaussfilt(im_mean_0, sigma, 'FilterSize', 2*ceil(2.5*sigma)+1, 'Padding', 'symmetric'); + + im_std_0 = (im_o - im_mean).^2; + im_std_0 = conv2(im_std_0, kn, 'same'); + im_std_0 = max(0.01, im_std_0); + im_std = imgaussfilt(im_std_0, sigma, 'FilterSize', 2*ceil(2.5*sigma)+1, 'Padding', 'symmetric'); + + if 0 + figure(1);clf; + subplot(2, 2, 1); + imagesc(im_mean_0); + axis image off; + colorbar; + subplot(2, 2, 2); + imagesc(im_mean); + axis image off; + colorbar; + subplot(2, 2, 3); + imagesc(im_std_0); + axis image off; + colorbar; + subplot(2, 2, 4); + imagesc(im_std); + axis image off; + colorbar; + end + + im_o = (im_o - im_mean)./im_std; + im_o = (im_o - mean(im_o, 'all'))/std(im_o, 0, 'all'); +end \ No newline at end of file diff --git a/matlab_functions/ilm_mex.m b/matlab_functions/ilm_mex.m old mode 100644 new mode 100755 index 62c11c9a..07f13f30 --- a/matlab_functions/ilm_mex.m +++ b/matlab_functions/ilm_mex.m @@ -1,222 +1,221 @@ -function [] = ilm_mex(option, m_file, src, varargin) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%% Format input data %%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - if(strcmp('../', src(1:3))) - [pathstr, ~, ~] = fileparts(pwd); - src = [pathstr, filesep, src(4:end)]; - else - [pathstr, ~, ~] = fileparts(src); - end - - nVarargs = length(varargin); - for k = 1:nVarargs - varargin{k} = strcat(src, filesep, char(varargin{k})); - end - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%%%% set cuda path %%%%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - CUDA_PATH = getenv('CUDA_PATH'); - -% CUDA_PATH = ''; - - if(isempty(CUDA_PATH)) - if(ispc) - CUDA_PATH = 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0'; - elseif(ismac) - CUDA_PATH = '/Developer/NVIDIA/CUDA-10.0'; - else - CUDA_PATH = '/usr/local/cuda-10.0'; - end - end - - CUDA_PATH = ilm_replace_filesep(CUDA_PATH); - - %%%%%%%%%%%%%%%%%%%% get cuda version %%%%%%%%%%%%%%%%%%%%%%% - idx = strfind(CUDA_PATH, filesep); - CUDA_VERSION = CUDA_PATH((idx(end)+1):end); - CUDA_VERSION = CUDA_VERSION(~isletter(CUDA_VERSION)); - CUDA_VERSION = erase(CUDA_VERSION, {'-', '_'}); - - if isempty(CUDA_VERSION) - CUDA_VERSION_PATH = [CUDA_PATH, filesep,'version.txt']; - FID = fopen(CUDA_VERSION_PATH); - data = textscan(FID,'%s'); - fclose(FID); - stringData = string(data{:}); - stringData = strsplit(stringData{3}, '.'); - CUDA_VERSION = [stringData{1}, '.', stringData{2}]; - end - - if(~exist(CUDA_PATH, 'dir')) - disp('Error - Cuda path not found') - end - - CUDA_BIN_PATH = [CUDA_PATH, filesep, 'bin']; - CUDA_INC_PATH = [CUDA_PATH, filesep, 'include']; - if(ispc) - CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib', filesep, 'x64']; - elseif(ismac) - CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; - else - CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; - end - CUDA_LIBS = '-lcudart -lcufft -lcublas'; - - %%%%%%%%%%%%%%% set NVCC compiler location %%%%%%%%%%%%%%%%%% - setenv('CUDA_PATH', CUDA_PATH); - setenv('CUDA_BIN_PATH', CUDA_BIN_PATH); - setenv('CUDA_LIB_PATH', CUDA_LIB_PATH); - setenv('CUDA_NVVM_PATH', [CUDA_PATH, filesep, 'nvvm']); - setenv('MW_NVCC_PATH', CUDA_BIN_PATH); - - %%%%%%%%%%%%%%%%%%% set card architecture %%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%% https://developer.nvidia.com/cuda-gpus %%%%%%%%%% - % https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/ - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - CUDA_VERSION_D = str2double(CUDA_VERSION); - CARD_30="-gencode=arch=compute_30,code=sm_30"; - CARD_35="-gencode=arch=compute_35,code=\"sm_35,compute_35\""; - CARD_50="-gencode=arch=compute_50,code=\"sm_50,compute_50\""; - CARD_60="-gencode=arch=compute_60,code=\"sm_60,compute_60\""; - CARD_70="-gencode=arch=compute_70,code=\"sm_70,compute_70\""; - CARD_75="-gencode=arch=compute_75,code=\"sm_75,compute_75\""; - CARD_86="-gencode=arch=compute_86,code=\"sm_86,compute_86\""; - CARD_87="-gencode=arch=compute_87,code=\"sm_87,compute_87\""; - CARD_MULT = join([CARD_30, CARD_35, CARD_50, CARD_60, CARD_70, CARD_75], ' '); - - if CUDA_VERSION_D >= 11.0 - CARD_MULT = join([CARD_MULT CARD_86, CARD_87], ' '); - end - - if 1 - % Get compute capabilities of all available devices - gpu_comp_cap = zeros(1,gpuDeviceCount); - ARCH_FLAGS = ""; - for i_dev = 1:gpuDeviceCount - gpu_comp_cap(i_dev) = str2double(replace(gpuDevice(i_dev).ComputeCapability,'.','')); - end - % avoid duplicate compiler settings - [~, id] = unique(gpu_comp_cap,'stable'); - - % Add architecture flags for all necessary compute capabilities - for i_dev = 1:numel(id) - gpu_comp_cap_str = num2str(gpu_comp_cap(id(i_dev))); - if gpu_comp_cap(id(i_dev)) < 35 - ARCH_FLAGS = join([ARCH_FLAGS, ['-gencode=arch=compute_' gpu_comp_cap_str ',code=sm_' gpu_comp_cap_str]]); - else - if gpu_comp_cap(id(i_dev)) > 75 && CUDA_VERSION_D < 11.0 - warning([gpuDevice(id(i_dev)).Name ' has compute capability ' gpuDevice(id(i_dev)).ComputeCapability ' but the Cuda version ' CUDA_VERSION ' does not support it. Attempting to compile for compute capability 7.5.']); - gpu_comp_cap_str = '75'; - end - ARCH_FLAGS = join([ARCH_FLAGS, ['-gencode=arch=compute_' gpu_comp_cap_str ',code=\"sm_' gpu_comp_cap_str ',compute_' gpu_comp_cap_str '\"']]); - end - end - else - ARCH_FLAGS = CARD_MULT; - end - - %%%%%%%%%%%%%%% read template mex_cuda file %%%%%%%%%%%%%%%%% - if(ispc) - mex_cuda_filename = 'mex_CUDA_win64.xml'; - elseif(ismac) - mex_cuda_filename = 'mex_CUDA_maci64.xml'; - else - mex_cuda_filename = 'mex_CUDA_glnxa64.xml'; - end - - %%%%%%%%%%%%%%%%%% read mex_cuda template %%%%%%%%%%%%%%%%%%%% - mex_cuda_file_in = [pathstr, filesep, 'matlab_functions', filesep, mex_cuda_filename]; - mex_cuda = fileread(mex_cuda_file_in); - - %%%%%%%%%%%%% replace string in mex_cuda file %%%%%%%%%%%%%%%% - mex_cuda = strrep(mex_cuda, 'XXX_CUDA_VER', CUDA_VERSION); - mex_cuda = strrep(mex_cuda, 'XXX_ARCH_FLAGS', ARCH_FLAGS); - - %%%%%%%%%%%%%%%%%%% save mex_cuda file %%%%%%%%%%%%%%%%%%%%%% - mex_cuda_file_out = [pwd, filesep, mex_cuda_filename]; - fid = fopen(mex_cuda_file_out, 'w+'); - fwrite(fid, mex_cuda); - fclose(fid); - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%% set library path %%%%%%%%%%%%%%%%%%%%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - if(ispc) - % OS = Windows 10 - FFTW_LIB_PATH = src; - FFTW_LIBS = '-lfftw3f-3 -lfftw3-3'; - - BLAS_LIB_PATH = src; - BLAS_LIBS = '-lblas'; - - LAPACK_LIB_PATH = src; - LAPACK_LIBS = '-llapack'; - - elseif(ismac) - % OS = /usr/bin/ld: - FFTW_LIB_PATH = []; - FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; - BLAS_LIB_PATH = []; - BLAS_LIBS = '-lblas'; - - LAPACK_LIB_PATH = []; - LAPACK_LIBS = '-llapack'; - else - % OS = scientific linux - %FFTW_LIB = '-/opt/local/lib'; - %FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; - %LAPACK_LIB = '/opt/local/lib'; - %BLAS_LAPACK_LIBS = '-lblas -llapack'; - - % OS = ubuntu - FFTW_LIB_PATH = '/usr/lib/x86_64-linux-gnu'; - FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; - - BLAS_LIB_PATH = '/usr/lib/x86_64-linux-gnu/blas'; - BLAS_LIBS = '-lblas'; - - LAPACK_LIB_PATH = '/usr/lib/x86_64-linux-gnu/lapack'; - LAPACK_LIBS = '-llapack'; - end - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - BLAS_LIBS = '-lmwblas'; - LAPACK_LIBS = '-lmwlapack '; - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - if(~exist(FFTW_LIB_PATH, 'dir')) - disp('FFTW path not found') - end - - if(~exist(BLAS_LIB_PATH, 'dir')) - disp('Blas path not found') - end - - if(~exist(LAPACK_LIB_PATH, 'dir')) - disp('Lapack path not found') - end - -% if(~ispc && ~ismac) -% mex_cuda_filename = 'nvcc_g++.xml'; -% end - - INCLUDE = ['-I"', CUDA_INC_PATH, '" -I"', src, '"']; - LIBRARY = ['-L"', CUDA_LIB_PATH, '" ', CUDA_LIBS, ' -L"', FFTW_LIB_PATH, '" ', FFTW_LIBS, ' -L"', BLAS_LIB_PATH, '" ', BLAS_LIBS, ' -L"', LAPACK_LIB_PATH, '" ', LAPACK_LIBS]; - mex_comand = ['mex -R2017b -f ', mex_cuda_filename, ' -v']; - - if (strcmpi(option, 'debug')) - mex_comand = [mex_comand, ' -g']; - end - - OUTDIR = ['-outdir ..', filesep, 'mex_bin']; - - textcommands = strjoin({mex_comand, OUTDIR, INCLUDE, LIBRARY, m_file, strjoin(varargin)}); - disp(textcommands); - eval(textcommands); - - delete(mex_cuda_file_out); -end +function [] = ilm_mex(option, m_file, src, varargin) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%% Format input data %%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if(strcmp('../', src(1:3))) + [pathstr, ~, ~] = fileparts(pwd); + src = [pathstr, filesep, src(4:end)]; + else + [pathstr, ~, ~] = fileparts(src); + end + + nVarargs = length(varargin); + for k = 1:nVarargs + varargin{k} = strcat(src, filesep, char(varargin{k})); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%% set cuda path %%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + CUDA_PATH = getenv('CUDA_PATH'); + +% CUDA_PATH = ''; + + if(isempty(CUDA_PATH)) + if(ispc) + CUDA_PATH = 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0'; + elseif(ismac) + CUDA_PATH = '/Developer/NVIDIA/CUDA-10.0'; + else + CUDA_PATH = '/usr/local/cuda-10.0'; + end + end + + CUDA_PATH = ilm_replace_filesep(CUDA_PATH); + + %%%%%%%%%%%%%%%%%%%% get cuda version %%%%%%%%%%%%%%%%%%%%%%% + idx = strfind(CUDA_PATH, filesep); + CUDA_VERSION = CUDA_PATH((idx(end)+1):end); + CUDA_VERSION = CUDA_VERSION(~isletter(CUDA_VERSION)); + CUDA_VERSION = erase(CUDA_VERSION, {'-', '_'}); + + if isempty(CUDA_VERSION) + CUDA_VERSION_PATH = [CUDA_PATH, filesep,'version.txt']; + FID = fopen(CUDA_VERSION_PATH); + data = textscan(FID,'%s'); + fclose(FID); + stringData = string(data{:}); + stringData = strsplit(stringData{3}, '.'); + CUDA_VERSION = [stringData{1}, '.', stringData{2}]; + end + + if(~exist(CUDA_PATH, 'dir')) + disp('Error - Cuda path not found') + end + + CUDA_BIN_PATH = [CUDA_PATH, filesep, 'bin']; + CUDA_INC_PATH = [CUDA_PATH, filesep, 'include']; + if(ispc) + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib', filesep, 'x64']; + elseif(ismac) + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; + else + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; + end + CUDA_LIBS = '-lcudart -lcufft -lcublas'; + + %%%%%%%%%%%%%%% set NVCC compiler location %%%%%%%%%%%%%%%%%% + setenv('CUDA_PATH', CUDA_PATH); + setenv('CUDA_BIN_PATH', CUDA_BIN_PATH); + setenv('CUDA_LIB_PATH', CUDA_LIB_PATH); + setenv('CUDA_NVVM_PATH', [CUDA_PATH, filesep, 'nvvm']); + setenv('MW_NVCC_PATH', CUDA_BIN_PATH); + + %%%%%%%%%%%%%%%%%%% set card architecture %%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%% https://developer.nvidia.com/cuda-gpus %%%%%%%%%% + % https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/ + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + CUDA_VERSION_D = str2double(CUDA_VERSION); + CARD_30="-gencode=arch=compute_30,code=sm_30"; + CARD_35="-gencode=arch=compute_35,code=\"sm_35,compute_35\""; + CARD_50="-gencode=arch=compute_50,code=\"sm_50,compute_50\""; + CARD_60="-gencode=arch=compute_60,code=\"sm_60,compute_60\""; + CARD_70="-gencode=arch=compute_70,code=\"sm_70,compute_70\""; + CARD_75="-gencode=arch=compute_75,code=\"sm_75,compute_75\""; + CARD_86="-gencode=arch=compute_86,code=\"sm_86,compute_86\""; + CARD_87="-gencode=arch=compute_87,code=\"sm_87,compute_87\""; + CARD_MULT = join([CARD_30, CARD_35, CARD_50, CARD_60, CARD_70, CARD_75], ' '); + + if CUDA_VERSION_D >= 11.0 + CARD_MULT = join([CARD_MULT CARD_86, CARD_87], ' '); + end + + if 1 + % Get compute capabilities of all available devices + gpu_comp_cap = zeros(1,gpuDeviceCount); + ARCH_FLAGS = ""; + for i_dev = 1:gpuDeviceCount + gpu_comp_cap(i_dev) = str2double(replace(gpuDevice(i_dev).ComputeCapability,'.','')); + end + % avoid duplicate compiler settings + [~, id] = unique(gpu_comp_cap,'stable'); + + % Add architecture flags for all necessary compute capabilities + for i_dev = 1:numel(id) + gpu_comp_cap_str = num2str(gpu_comp_cap(id(i_dev))); + if gpu_comp_cap(id(i_dev)) < 35 + ARCH_FLAGS = join([ARCH_FLAGS, ['-gencode=arch=compute_' gpu_comp_cap_str ',code=sm_' gpu_comp_cap_str]]); + else + if gpu_comp_cap(id(i_dev)) > 75 && CUDA_VERSION_D < 11.0 + warning([gpuDevice(id(i_dev)).Name ' has compute capability ' gpuDevice(id(i_dev)).ComputeCapability ' but the Cuda version ' CUDA_VERSION ' does not support it. Attempting to compile for compute capability 7.5.']); + gpu_comp_cap_str = '75'; + end + ARCH_FLAGS = join([ARCH_FLAGS, ['-gencode=arch=compute_' gpu_comp_cap_str ',code=\"sm_' gpu_comp_cap_str ',compute_' gpu_comp_cap_str '\"']]); + end + end + else + ARCH_FLAGS = CARD_MULT; + end + + %%%%%%%%%%%%%%% read template mex_cuda file %%%%%%%%%%%%%%%%% + if(ispc) + mex_cuda_filename = 'mex_CUDA_win64.xml'; + elseif(ismac) + mex_cuda_filename = 'mex_CUDA_maci64.xml'; + else + mex_cuda_filename = 'mex_CUDA_glnxa64.xml'; + end + + %%%%%%%%%%%%%%%%%% read mex_cuda template %%%%%%%%%%%%%%%%%%%% + mex_cuda_file_in = [pathstr, filesep, 'matlab_functions', filesep, mex_cuda_filename]; + mex_cuda = fileread(mex_cuda_file_in); + + %%%%%%%%%%%%% replace string in mex_cuda file %%%%%%%%%%%%%%%% + mex_cuda = strrep(mex_cuda, 'XXX_CUDA_VER', CUDA_VERSION); + mex_cuda = strrep(mex_cuda, 'XXX_ARCH_FLAGS', ARCH_FLAGS); + + %%%%%%%%%%%%%%%%%%% save mex_cuda file %%%%%%%%%%%%%%%%%%%%%% + mex_cuda_file_out = [pwd, filesep, mex_cuda_filename]; + fid = fopen(mex_cuda_file_out, 'w+'); + fwrite(fid, mex_cuda); + fclose(fid); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%% set library path %%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if(ispc) + % OS = Windows 10 + FFTW_LIB_PATH = src; + FFTW_LIBS = '-lfftw3f-3 -lfftw3-3'; + + BLAS_LIB_PATH = src; + BLAS_LIBS = '-lblas'; + + LAPACK_LIB_PATH = src; + LAPACK_LIBS = '-llapack'; + + elseif(ismac) + % OS = Windows 10 + FFTW_LIB_PATH = []; + FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; + BLAS_LIB_PATH = []; + BLAS_LIBS = '-lblas'; + + LAPACK_LIB_PATH = []; + LAPACK_LIBS = '-llapack'; + else + % OS = scientific linux + %FFTW_LIB = '-/opt/local/lib'; + %FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; + %LAPACK_LIB = '/opt/local/lib'; + %BLAS_LAPACK_LIBS = '-lblas -llapack'; + + % OS = ubuntu + FFTW_LIB_PATH = '/usr/lib/x86_64-linux-gnu'; + FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; + + BLAS_LIB_PATH = '/usr/lib/x86_64-linux-gnu'; + BLAS_LIBS = '-lblas'; + + LAPACK_LIB_PATH = '/usr/lib/x86_64-linux-gnu'; + LAPACK_LIBS = '-llapack'; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + BLAS_LIBS = '-lmwblas'; + LAPACK_LIBS = '-lmwlapack '; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if(~exist(FFTW_LIB_PATH, 'dir')) + disp('FFTW path not found') + end + + if(~exist(BLAS_LIB_PATH, 'dir')) + disp('Blas path not found') + end + + if(~exist(LAPACK_LIB_PATH, 'dir')) + disp('Lapack path not found') + end + +% if(~ispc && ~ismac) +% mex_cuda_filename = 'nvcc_g++.xml'; +% end + + INCLUDE = ['-I"', CUDA_INC_PATH, '" -I"', src, '"']; + LIBRARY = ['-L"', CUDA_LIB_PATH, '" ', CUDA_LIBS, ' -L"', FFTW_LIB_PATH, '" ', FFTW_LIBS, ' -L"', BLAS_LIB_PATH, '" ', BLAS_LIBS, ' -L"', LAPACK_LIB_PATH, '" ', LAPACK_LIBS]; + mex_comand = ['mex -R2018a -f ', mex_cuda_filename, ' -v']; + if (strcmpi(option, 'debug')) + mex_comand = [mex_comand, ' -g']; + end + + OUTDIR = ['-outdir ..', filesep, 'mex_bin']; + + textcommands = strjoin({mex_comand, OUTDIR, INCLUDE, LIBRARY, m_file, strjoin(varargin)}); + disp(textcommands); + eval(textcommands); + + delete(mex_cuda_file_out); +end \ No newline at end of file diff --git a/matlab_functions/ilm_mrad_2_rAng.m b/matlab_functions/ilm_mrad_2_rAng.m old mode 100644 new mode 100755 index 31f236eb..0ce18750 --- a/matlab_functions/ilm_mrad_2_rAng.m +++ b/matlab_functions/ilm_mrad_2_rAng.m @@ -2,6 +2,6 @@ function [rAng] = ilm_mrad_2_rAng(E_0, theta) emass = 510.99906; % electron rest mass in keV hc = 12.3984244; % Planck's const x speed of light - lambda = hc./sqrt(E_0.*(2.0*emass + E_0)); - rAng = theta*1e-03./lambda; -end + lambda = hc/sqrt(E_0*(2.0*emass + E_0)); + rAng = theta*1e-03/lambda; +end \ No newline at end of file diff --git a/matlab_functions/ilm_pcf_2d.m b/matlab_functions/ilm_pcf_2d.m new file mode 100755 index 00000000..58709203 --- /dev/null +++ b/matlab_functions/ilm_pcf_2d.m @@ -0,0 +1,33 @@ +function[pcf] = ilm_pcf_2d(system_config, im_r, im_s, dx, dy, sigma_g_px) + [ny, nx] = size(im_r, [1, 2]); + bsx = nx*dx; + bsy = ny*dy; + sigma_g = sigma_g_px*min(1/bsx, 1/bsy); + + [~, ~, g2] = ilm_fs_grid_2d(nx, ny, bsx, bsy, 1); + M = exp(-0.5*g2/sigma_g^2); + + fpcf = conj(fft2(fftshift(im_r))).*fft2(fftshift(im_s)); + fpcf = M.*exp(1i*angle(fpcf)); + pcf = ifftshift(real(ifft2(fpcf))); + + if 0 + figure(2);clf; + subplot(2, 2, 1); + imagesc(im_r); + axis image; + colormap jet; + subplot(2, 2, 2); + imagesc(im_s); + axis image; + colormap jet; + subplot(2, 2, 3); + imagesc(M); + axis image; + colormap jet; + subplot(2, 2, 4); + imagesc(pcf); + axis image; + colormap jet; + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_pcf_2d_wd_bd_tf.m b/matlab_functions/ilm_pcf_2d_wd_bd_tf.m new file mode 100755 index 00000000..17bacbdc --- /dev/null +++ b/matlab_functions/ilm_pcf_2d_wd_bd_tf.m @@ -0,0 +1,40 @@ +function [im_o] = ilm_pcf_2d_wd_bd_tf(system_config, im_i, dx, dy, A, txy, p, bd_px) + [ny, nx] = size(im_i, [1, 2]); + + im_o = ilm_apply_af_tf_2d(system_config, im_i, dx, dy, A, txy, 0); + + rect = ilm_bd_2_rect(nx, ny, bd_px); + rect = max(1, round(rect)); + p_c = mean(rect, 1); + + radius_x = 0.5*(nx-bd_px(1)-bd_px(2))*(1-p); + radius_y = 0.5*(ny-bd_px(3)-bd_px(4))*(1-p); + rx = (0:1:(nx-1)) - p_c(1); + ry = (0:1:(ny-1)).' - p_c(2); + n = 8; + + fx = 1./(1 + (rx/radius_x).^(2*n)); + fx_sft = max(fx(1), fx(end)); + fx = (fx - fx_sft)/(0.5-fx_sft); + fx = max(0, min(1.0, fx)); + fy = 1./(1 + (ry/radius_y).^(2*n)); + fy_sft = max(fy(1), fy(end)); + fy = (fy - fy_sft)/(0.5-fy_sft); + fy = max(0, min(1.0, fy)); + + im_o = fx.*fy.*im_o; + + if 0 + + figure(1);clf; + subplot(1, 2, 1); + imagesc(im_i); + axis image; + colormap jet; + subplot(1, 2, 2); + imagesc(im_o); + axis image; + colormap bone; + end +end + diff --git a/matlab_functions/ilm_pcf_data_tf.m b/matlab_functions/ilm_pcf_data_tf.m new file mode 100755 index 00000000..4c32d253 --- /dev/null +++ b/matlab_functions/ilm_pcf_data_tf.m @@ -0,0 +1,24 @@ +function [im_rp, im_sp] = ilm_pcf_data_tf(im_r, im_s, opt, sigma_f) + if nargin<3 + opt=1; + end + + if nargin<4 + sigma_f = 4; + end + + im_rp = double(im_r); + im_sp = double(im_s); + + if opt==2 + im_rp = del2(im_rp); + im_sp = del2(im_sp); + elseif opt==3 + im_rp = ilm_lcwt(im_rp, sigma_f); + im_sp = ilm_lcwt(im_sp, sigma_f); + else + im_rp = im_rp - mean(im_rp, 'all'); + im_sp = im_sp - mean(im_sp, 'all'); + end + +end \ No newline at end of file diff --git a/matlab_functions/ilm_rAng_2_mrad.m b/matlab_functions/ilm_rAng_2_mrad.m old mode 100644 new mode 100755 diff --git a/matlab_functions/ilm_read_2x_y_hdf5.m b/matlab_functions/ilm_read_2x_y_hdf5.m new file mode 100755 index 00000000..3c705440 --- /dev/null +++ b/matlab_functions/ilm_read_2x_y_hdf5.m @@ -0,0 +1,5 @@ +function [x, x_1, y] = ilm_read_2x_y_hdf5(fn) + x = h5read(fn, '/x'); + x_1 = h5read(fn, '/x_1'); + y = h5read(fn, '/y'); +end \ No newline at end of file diff --git a/matlab_functions/ilm_read_angles_cif.m b/matlab_functions/ilm_read_angles_cif.m old mode 100644 new mode 100755 index 7b60871d..f46f7047 --- a/matlab_functions/ilm_read_angles_cif.m +++ b/matlab_functions/ilm_read_angles_cif.m @@ -1,25 +1,25 @@ -% Read lattice parameter from cif file -function [alpha, beta, gamma] = ilm_read_angles_cif(path) - str_file = fileread(path); - str_file = strtrim(strsplit(str_file, '\n')); - - alpha = fn_extract_pattern(str_file, '_cell_angle_alpha', '%s%f%s', 2); - beta = fn_extract_pattern(str_file, '_cell_angle_beta', '%s%f%s', 2); - gamma = fn_extract_pattern(str_file, '_cell_angle_gamma', '%s%f%s', 2); -end - -function[str_out] =fn_extract_pattern(str_file, str_ss, patt, idx) - if(nargin<3) - idx = 0; - end - - str_iy = str_file{contains(str_file, str_ss)}; - ix = strfind(str_iy, str_ss); - str_iy = str_iy(ix:end); - C = textscan(str_iy, patt); - if(idx==0) - str_out = C; - else - str_out = C{idx}; - end +% Read lattice parameter from cif file +function [alpha, beta, gamma] = ilm_read_angles_cif(path) + str_file = fileread(path); + str_file = strtrim(strsplit(str_file, '\n')); + + alpha = fn_extract_pattern(str_file, '_cell_angle_alpha', '%s%f%s', 2); + beta = fn_extract_pattern(str_file, '_cell_angle_beta', '%s%f%s', 2); + gamma = fn_extract_pattern(str_file, '_cell_angle_gamma', '%s%f%s', 2); +end + +function[str_out] =fn_extract_pattern(str_file, str_ss, patt, idx) + if(nargin<3) + idx = 0; + end + + str_iy = str_file{contains(str_file, str_ss)}; + ix = strfind(str_iy, str_ss); + str_iy = str_iy(ix:end); + C = textscan(str_iy, patt); + if(idx==0) + str_out = C; + else + str_out = C{idx}; + end end \ No newline at end of file diff --git a/matlab_functions/ilm_read_ap_cif.m b/matlab_functions/ilm_read_ap_cif.m old mode 100644 new mode 100755 index c569bf5a..0e0efeab --- a/matlab_functions/ilm_read_ap_cif.m +++ b/matlab_functions/ilm_read_ap_cif.m @@ -1,185 +1,189 @@ -% Read atomic positions from cif file -% Copyright 2023 Ivan Lobato -function [atoms, lx, ly, lz] = ilm_read_ap_cif(path, rmsd_3d_0, pbc, na, nb, nc) - if(nargin<6) - nc = 1; - end - - if(nargin<5) - nb = 1; - end - - if(nargin<4) - na = 1; - end - - % for anisotropic atomic displacement check out the following website - % https://www.iucr.org/__data/iucr/cif/software/oostar/oostar_ddl1/bin/data/cifdic.c91.list.html - if(nargin<3) - pbc = true; - end - - if(nargin<2) - rmsd_3d_0 = 0.085; - end - - occ_0 = 1; - - str_file = fileread(path); - str_file = strtrim(strsplit(str_file, '\n')); - - xtl_parm.na = na; - xtl_parm.nb = nb; - xtl_parm.nc = nc; - - xtl_parm.a = fn_extract_pattern(str_file, '_cell_length_a', '%s%f%s', 2); - xtl_parm.b = fn_extract_pattern(str_file, '_cell_length_b', '%s%f%s', 2); - xtl_parm.c = fn_extract_pattern(str_file, '_cell_length_c', '%s%f%s', 2); - - xtl_parm.alpha = fn_extract_pattern(str_file, '_cell_angle_alpha', '%s%f%s', 2); - xtl_parm.beta = fn_extract_pattern(str_file, '_cell_angle_beta', '%s%f%s', 2); - xtl_parm.gamma = fn_extract_pattern(str_file, '_cell_angle_gamma', '%s%f%s', 2); - - % https://www.iucr.org/__data/iucr/cifdic_html/1/cif_core.dic/Ispace_group_IT_number.html - if(fn_get_idx(str_file, '_space_group_IT_number')>0) - xtl_parm.sgn = fn_extract_pattern(str_file, '_space_group_IT_number', '%s%d%s', 2); - else - xtl_parm.sgn = fn_extract_pattern(str_file, '_symmetry_Int_Tables_number', '%s%d%s', 2); - end - - xtl_parm.pbc = pbc; - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - iy_0 = find(contains(str_file, '_atom_site_fract_x'), 1, 'first'); - iy_0 = iy_0-1; - while ~contains(str_file{iy_0}, 'loop_') - iy_0 = iy_0-1; - end - iy_0 = iy_0 + 1; - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - iy_e = iy_0+1; - while contains(str_file{iy_e}, '_atom_site_') - iy_e = iy_e+1; - end - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - n_col = (iy_e-iy_0); - map = containers.Map(iy_0:(iy_e-1), 1:n_col); - - iy_Z = fn_get_idx(str_file, '_atom_site_type_symbol'); - iy_x = fn_get_idx(str_file, '_atom_site_fract_x'); - iy_y = fn_get_idx(str_file, '_atom_site_fract_y'); - iy_z = fn_get_idx(str_file, '_atom_site_fract_z'); - - iy_rmsd_3d = fn_get_idx(str_file, '_atom_site_B_iso_or_equiv'); - iy_occ = fn_get_idx(str_file, '_atom_site_occupancy'); - str_patt = repmat('%s', 1, n_col); - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - asym_uc = []; - n_rows = length(str_file); - iy = iy_e; - while true - if((iy>n_rows) || strcmp(str_file{iy}, '')) - break; - end - - str_text = textscan(str_file{iy}, str_patt); - if(fn_break(str_text{map(iy_Z)})) - break; - end - - Z = fn_read_Z(str_text{map(iy_Z)}{1}); - x = fn_read_number(str_text{map(iy_x)}{1}); - y = fn_read_number(str_text{map(iy_y)}{1}); - z = fn_read_number(str_text{map(iy_z)}{1}); - - % https://www.iucr.org/__data/iucr/cifdic_html/1/cif_core.dic/Iatom_site_B_iso_or_equiv.html - if(ilm_chk_bound(iy_rmsd_3d, iy_0, iy_e)) - rmsd_3d = fn_read_rmsd_3d(str_text{map(iy_rmsd_3d)}{1}, rmsd_3d_0); - else - rmsd_3d = rmsd_3d_0; - end - - % https://www.iucr.org/__data/iucr/cifdic_html/1/cif_core.dic/Iatom_site_occupancy.html - if(ilm_chk_bound(iy_occ, iy_0, iy_e)) - occ = fn_read_rmsd_3d(str_text{map(iy_occ)}{1}, occ_0); - else - occ = occ_0; - end - - asym_uc = [asym_uc;Z, x, y, z, rmsd_3d, occ]; - iy = iy + 1; - end - - xtl_parm.asym_uc = asym_uc; - xtl_parm.base = []; - - atoms = ilc_xtl_build(xtl_parm); - - xyz = atoms(:, 2:4); - xyz = xyz - min(xyz); - [lx, ly, lz] = ilm_vect_assign(max(xyz)); - atoms(:, 2:4) = xyz; - - [lx, ly, lz] = ilm_vect_assign([max(lx, xtl_parm.a), max(ly, xtl_parm.b), max(lz, xtl_parm.c)]); -end - -function[bb] =fn_break(str_ss) - if(size(str_ss, 1)>0) - str_ss = str_ss{1}; - bb = ilm_Z(str_ss(isletter(str_ss)))<1; - else - bb = true; - end -end - -function[Z] =fn_read_Z(str_ss) - Z = ilm_Z(str_ss(isletter(str_ss))); -end - -function[n] =fn_read_number(str_ss, n_0) - if(nargin<2) - n_0 = 0; - end - - str_ss = eraseBetween(str_ss, '(', ')', 'Boundaries', 'inclusive'); - n = str2double(strtrim(str_ss)); - - if(isnan(n)) - n = n_0; - end -end - -function[rmsd_3d] =fn_read_rmsd_3d(str_ss, rmsd_3d_0) - B = fn_read_number(str_ss); - if(B==0) - rmsd_3d = rmsd_3d_0; - else - rmsd_3d = sqrt(B/(8*pi^2)); - end -end - -function[idx] =fn_get_idx(str_file, str_ss) - idx = find(contains(str_file, str_ss), 1, 'first'); - if(numel(idx)==0) - idx = -1; - end -end - -function[str_out] =fn_extract_pattern(str_file, str_ss, patt, idx) - if(nargin<3) - idx = 0; - end - - str_iy = str_file{contains(str_file, str_ss)}; - ix = strfind(str_iy, str_ss); - str_iy = str_iy(ix:end); - C = textscan(str_iy, patt); - if(idx==0) - str_out = C; - else - str_out = C{idx}; - end +% Read atomic positions from cif file +% Copyright 2020 Ivan Lobato +function [atoms, lx, ly, lz] = ilm_read_ap_cif(path, rmsd_3d_0, pbc, na, nb, nc) + if(nargin<6) + nc = 1; + end + + if(nargin<5) + nb = 1; + end + + if(nargin<4) + na = 1; + end + + % for anisotropic atomic displacement check out the following website + % https://www.iucr.org/__data/iucr/cif/software/oostar/oostar_ddl1/bin/data/cifdic.c91.list.html + if(nargin<3) + pbc = true; + end + + if(nargin<2) + rmsd_3d_0 = 0.085; + end + + occ_0 = 1; + + str_file = fileread(path); + str_file = strtrim(strsplit(str_file, '\n')); + + xtl_parm.na = na; + xtl_parm.nb = nb; + xtl_parm.nc = nc; + + xtl_parm.a = fn_extract_pattern(str_file, '_cell_length_a', '%s%f%s', 2); + xtl_parm.b = fn_extract_pattern(str_file, '_cell_length_b', '%s%f%s', 2); + xtl_parm.c = fn_extract_pattern(str_file, '_cell_length_c', '%s%f%s', 2); + + xtl_parm.alpha = fn_extract_pattern(str_file, '_cell_angle_alpha', '%s%f%s', 2); + xtl_parm.beta = fn_extract_pattern(str_file, '_cell_angle_beta', '%s%f%s', 2); + xtl_parm.gamma = fn_extract_pattern(str_file, '_cell_angle_gamma', '%s%f%s', 2); + + % https://www.iucr.org/__data/iucr/cifdic_html/1/cif_core.dic/Ispace_group_IT_number.html + if(fn_get_idx(str_file, '_space_group_IT_number')>0) + xtl_parm.sgn = fn_extract_pattern(str_file, '_space_group_IT_number', '%s%d%s', 2); + else + xtl_parm.sgn = fn_extract_pattern(str_file, '_symmetry_Int_Tables_number', '%s%d%s', 2); + end + + xtl_parm.pbc = pbc; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + iy_0 = find(contains(str_file, '_atom_site_fract_x'), 1, 'first'); + iy_0 = iy_0-1; + while ~contains(str_file{iy_0}, 'loop_') + iy_0 = iy_0-1; + end + iy_0 = iy_0 + 1; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + iy_e = iy_0+1; + while contains(str_file{iy_e}, '_atom_site_') + iy_e = iy_e+1; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + n_col = (iy_e-iy_0); + map = containers.Map(iy_0:(iy_e-1), 1:n_col); + + iy_Z = fn_get_idx(str_file, '_atom_site_type_symbol'); + iy_x = fn_get_idx(str_file, '_atom_site_fract_x'); + iy_y = fn_get_idx(str_file, '_atom_site_fract_y'); + iy_z = fn_get_idx(str_file, '_atom_site_fract_z'); + + iy_rmsd_3d = fn_get_idx(str_file, '_atom_site_B_iso_or_equiv'); + iy_occ = fn_get_idx(str_file, '_atom_site_occupancy'); + str_patt = repmat('%s', 1, n_col); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + asym_uc = []; + n_rows = length(str_file); + iy = iy_e; + while true + if((iy>n_rows) || strcmp(str_file{iy}, '')) + break; + end + + str_text = textscan(str_file{iy}, str_patt); + if(fn_break(str_text{map(iy_Z)})) + break; + end + + Z = fn_read_Z(str_text{map(iy_Z)}{1}); + x = fn_read_number(str_text{map(iy_x)}{1}); + y = fn_read_number(str_text{map(iy_y)}{1}); + z = fn_read_number(str_text{map(iy_z)}{1}); + + % https://www.iucr.org/__data/iucr/cifdic_html/1/cif_core.dic/Iatom_site_B_iso_or_equiv.html + if(ilm_chk_bound(iy_rmsd_3d, iy_0, iy_e)) + rmsd_3d = fn_read_rmsd_3d(str_text{map(iy_rmsd_3d)}{1}, rmsd_3d_0); + else + rmsd_3d = rmsd_3d_0; + end + + % https://www.iucr.org/__data/iucr/cifdic_html/1/cif_core.dic/Iatom_site_occupancy.html + if(ilm_chk_bound(iy_occ, iy_0, iy_e)) + occ = fn_read_rmsd_3d(str_text{map(iy_occ)}{1}, occ_0); + else + occ = occ_0; + end + + asym_uc = [asym_uc;Z, x, y, z, rmsd_3d, occ]; + iy = iy + 1; + end + + xtl_parm.asym_uc = asym_uc; + +% xtl_parm.base = ilm_xtl_build_base(xtl_parm); +% atoms = ilc_xtl_build(xtl_parm); + + xtl_parm.base = []; + atoms = ilc_xtl_build(xtl_parm); +% ilc_xtl_build + + xyz = atoms(:, 2:4); + xyz = xyz - min(xyz); + [lx, ly, lz] = ilm_vect_assign(max(xyz)); + atoms(:, 2:4) = xyz; + + [lx, ly, lz] = ilm_vect_assign([max(lx, xtl_parm.a), max(ly, xtl_parm.b), max(lz, xtl_parm.c)]); +end + +function[bb] = fn_break(str_ss) + if(size(str_ss, 1)>0) + str_ss = str_ss{1}; + bb = ilm_Z(str_ss(isletter(str_ss)))<1; + else + bb = true; + end +end + +function[Z] =fn_read_Z(str_ss) + Z = ilm_Z(str_ss(isletter(str_ss))); +end + +function[n] =fn_read_number(str_ss, n_0) + if(nargin<2) + n_0 = 0; + end + + str_ss = eraseBetween(str_ss, '(', ')', 'Boundaries', 'inclusive'); + n = str2double(strtrim(str_ss)); + + if(isnan(n)) + n = n_0; + end +end + +function[rmsd_3d] =fn_read_rmsd_3d(str_ss, rmsd_3d_0) + B = fn_read_number(str_ss); + if(B==0) + rmsd_3d = rmsd_3d_0; + else + rmsd_3d = sqrt(B/(8*pi^2)); + end +end + +function[idx] =fn_get_idx(str_file, str_ss) + idx = find(contains(str_file, str_ss), 1, 'first'); + if(numel(idx)==0) + idx = -1; + end +end + +function[str_out] =fn_extract_pattern(str_file, str_ss, patt, idx) + if(nargin<3) + idx = 0; + end + + str_iy = str_file{contains(str_file, str_ss)}; + ix = strfind(str_iy, str_ss); + str_iy = str_iy(ix:end); + C = textscan(str_iy, patt); + if(idx==0) + str_out = C; + else + str_out = C{idx}; + end end \ No newline at end of file diff --git a/matlab_functions/ilm_read_ap_xyz.m b/matlab_functions/ilm_read_ap_xyz.m old mode 100644 new mode 100755 index 07a81857..b3b67120 --- a/matlab_functions/ilm_read_ap_xyz.m +++ b/matlab_functions/ilm_read_ap_xyz.m @@ -1,26 +1,24 @@ -% Read atomic positions from xyz file -function [atoms, lx, ly, lz] = ilm_read_ap_xyz(path, rmsd_3d) - ces = {'H','He','Li','Be','B','C','N','O','F','Ne','Na','Mg','Al','Si','P','S','Cl','Ar','K','Ca', ... - 'Sc','Ti','V','Cr','Mn','Fe','Co','Ni','Cu','Zn', 'Ga','Ge','As','Se','Br','Kr','Rb','Sr','Y','Zr', ... - 'Nb','Mo','Tc','Ru','Rh','Pd','Ag','Cd','In','Sn', 'Sb','Te','I','Xe','Cs','Ba','La','Ce','Pr','Nd',... - 'Pm','Sm','Eu','Gd','Tb','Dy','Ho','Er','Tm','Yb','Lu','Hf','Ta','W','Re','Os','Ir','Pt','Au','Hg',... - 'Tl','Pb','Bi','Po','At','Rn','Fr','Ra','Ac','Th','Pa','U','Np','Pu','Am','Cm','Bk','Cf'}; - - fid = fopen(path,'r'); - fgetl(fid); - fgetl(fid); - atoms = []; - while feof(fid) == 0 - text = strtrim(upper(sscanf(fgetl(fid),'%c'))); - if (~isempty(text)) - C = textscan(text, '%s %f %f %f'); - atoms = [atoms; [find(strcmpi(ces, strtrim(C{1}))), C{2}, C{3}, C{4}, rmsd_3d, 1.0]]; - end - end - fclose(fid); - - atoms(:,2:4) = bsxfun(@minus, atoms(:,2:4), min(atoms(:,2:4))); - lx = max(atoms(:,2)); - ly = max(atoms(:,3)); - lz = max(atoms(:,4)); +% Read atomic positions from xyz file +function [atoms, lx, ly, lz] = ilm_read_ap_xyz(path, rmsd_3d) + if(nargin<2) + rmsd_3d = 0.085; + end + + fid = fopen(path, 'r'); + fgetl(fid); + fgetl(fid); + atoms = []; + while feof(fid) == 0 + text = strtrim(upper(sscanf(fgetl(fid), '%c'))); + if (~isempty(text)) + C = textscan(text, '%s %f %f %f'); + atoms = [atoms;[ilm_Z(C{1}), C{2}, C{3}, C{4}, rmsd_3d, 1.0]]; + end + end + fclose(fid); + + xyz = atoms(:, 2:4); + xyz = xyz - min(xyz); + [lx, ly, lz] = ilm_vect_assign(max(xyz)); + atoms(:, 2:4) = xyz; end \ No newline at end of file diff --git a/matlab_functions/ilm_read_lat_parm_cif.m b/matlab_functions/ilm_read_lat_parm_cif.m old mode 100644 new mode 100755 index 147a839d..8dc3a489 --- a/matlab_functions/ilm_read_lat_parm_cif.m +++ b/matlab_functions/ilm_read_lat_parm_cif.m @@ -1,26 +1,26 @@ -% Read lattice parameter from cif file -% Copyright 2023 Ivan Lobato -function [a, b, c] = ilm_read_lat_parm_cif(path) - str_file = fileread(path); - str_file = strtrim(strsplit(str_file, '\n')); - - a = fn_extract_pattern(str_file, '_cell_length_a', '%s%f%s', 2); - b = fn_extract_pattern(str_file, '_cell_length_b', '%s%f%s', 2); - c = fn_extract_pattern(str_file, '_cell_length_c', '%s%f%s', 2); -end - -function[str_out] =fn_extract_pattern(str_file, str_ss, patt, idx) - if(nargin<3) - idx = 0; - end - - str_iy = str_file{contains(str_file, str_ss)}; - ix = strfind(str_iy, str_ss); - str_iy = str_iy(ix:end); - C = textscan(str_iy, patt); - if(idx==0) - str_out = C; - else - str_out = C{idx}; - end +% Read lattice parameter from cif file +% Copyright 2020 Ivan Lobato +function [a, b, c] = ilm_read_lat_parm_cif(path) + str_file = fileread(path); + str_file = strtrim(strsplit(str_file, '\n')); + + a = fn_extract_pattern(str_file, '_cell_length_a', '%s%f%s', 2); + b = fn_extract_pattern(str_file, '_cell_length_b', '%s%f%s', 2); + c = fn_extract_pattern(str_file, '_cell_length_c', '%s%f%s', 2); +end + +function[str_out] =fn_extract_pattern(str_file, str_ss, patt, idx) + if(nargin<3) + idx = 0; + end + + str_iy = str_file{contains(str_file, str_ss)}; + ix = strfind(str_iy, str_ss); + str_iy = str_iy(ix:end); + C = textscan(str_iy, patt); + if(idx==0) + str_out = C; + else + str_out = C{idx}; + end end \ No newline at end of file diff --git a/matlab_functions/ilm_read_len_hdf5.m b/matlab_functions/ilm_read_len_hdf5.m new file mode 100755 index 00000000..a3e8a3e3 --- /dev/null +++ b/matlab_functions/ilm_read_len_hdf5.m @@ -0,0 +1,13 @@ +function [sz] = ilm_read_len_hdf5(fn, str_var, dim) + if exist(fn, 'file') + try + info = h5info(fn, ['/', str_var]); + sz = info.Dataspace.Size(dim); + catch + sz = 0; + end + else + sz = 0; + end + +end \ No newline at end of file diff --git a/matlab_functions/ilm_read_x_y_sft_sc_hdf5.m b/matlab_functions/ilm_read_x_y_sft_sc_hdf5.m new file mode 100755 index 00000000..35a5f940 --- /dev/null +++ b/matlab_functions/ilm_read_x_y_sft_sc_hdf5.m @@ -0,0 +1,28 @@ +function [x, y, x_sft, x_sc, y_sft, y_sc] = ilm_read_x_y_sft_sc_hdf5(fn) + x = h5read(fn, '/x'); + y = h5read(fn, '/y'); + + try + x_sft = h5read(fn, '/x_sft'); + catch + x_sft = 0.0; + end + + try + x_sc = h5read(fn, '/x_sc'); + catch + x_sc = 1.0; + end + + try + y_sft = h5read(fn, '/y_sft'); + catch + y_sft = 0.0; + end + + try + y_sc = h5read(fn, '/y_sc'); + catch + y_sc = 1.0; + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_read_x_y_sft_sc_y_dr_hdf5.m b/matlab_functions/ilm_read_x_y_sft_sc_y_dr_hdf5.m new file mode 100755 index 00000000..b5e08473 --- /dev/null +++ b/matlab_functions/ilm_read_x_y_sft_sc_y_dr_hdf5.m @@ -0,0 +1,34 @@ +function [x, y, x_sft, x_sc, y_sft, y_sc, y_dr] = ilm_read_x_y_sft_sc_y_dr_hdf5(fn) + x = h5read(fn, '/x'); + y = h5read(fn, '/y'); + + try + x_sft = h5read(fn, '/x_sft'); + catch + x_sft = 0.0; + end + + try + x_sc = h5read(fn, '/x_sc'); + catch + x_sc = 1.0; + end + + try + y_sft = h5read(fn, '/y_sft'); + catch + y_sft = 0.0; + end + + try + y_sc = h5read(fn, '/y_sc'); + catch + y_sc = 1.0; + end + + try + y_dr = h5read(fn, '/y_dr'); + catch + y_dr = 1.0; + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_replace_filesep.m b/matlab_functions/ilm_replace_filesep.m index 7f53079f..c874c951 100755 --- a/matlab_functions/ilm_replace_filesep.m +++ b/matlab_functions/ilm_replace_filesep.m @@ -1,4 +1,4 @@ -function[str]=ilm_replace_filesep(str, ss_rep) +function[str] = ilm_replace_filesep(str, ss_rep) if nargin < 2 ss_rep = filesep; end diff --git a/matlab_functions/ilm_show_crystal.m b/matlab_functions/ilm_show_crystal.m deleted file mode 100644 index 334cae86..00000000 --- a/matlab_functions/ilm_show_crystal.m +++ /dev/null @@ -1,47 +0,0 @@ -function[]=ilm_show_crystal(fig, atoms, bb_clf, bb_rz) - if(nargin<4) - bb_rz = true; - end - - if(nargin<3) - bb_clf = true; - end - - aZ = unique(atoms(:, 1)); - - if(fig>0) - figure(fig); - end - - if(bb_clf) - clf; - else - hold on; - end - - str = {}; - for iZ=1:length(aZ) - hold all; - ii = find(atoms(:, 1)==aZ(iZ)); - plot3(atoms(ii, 2), atoms(ii, 3), atoms(ii, 4), 'o', 'MarkerSize', 3, 'MarkerFaceColor', 'auto'); - str{iZ} = num2str(aZ(iZ)); - end -% legend(str); - axis equal; - r_min = min(atoms(:, 2:4), [], 1); - r_max = max(atoms(:, 2:4), [], 1); - - x_min = r_min(1)-1; - x_max = r_max(1)+1; - y_min = r_min(2)-1; - y_max = r_max(2)+1; - z_min = r_min(3)-1; - z_max = r_max(3)+1; - - axis([x_min, x_max, y_min, y_max, z_min, z_max]); - view([0 0 1]); - - if(bb_rz) - set(gca, 'zdir', 'reverse'); - end -end \ No newline at end of file diff --git a/matlab_functions/ilm_show_slicing.m b/matlab_functions/ilm_show_slicing.m old mode 100644 new mode 100755 index 88560dd3..1fee017f --- a/matlab_functions/ilm_show_slicing.m +++ b/matlab_functions/ilm_show_slicing.m @@ -1,35 +1,35 @@ -function []=ilm_show_slicing(input_multem, inFP, nf) - [Atoms, Slice] = getSliceSpecimen(input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, input_multem.spec_dz, inFP, input_multem.DimFP, input_multem.SeedFP); - S = getAtomTypes(input_multem.PotPar); - z0 = min(Atoms(:, 3))-S(Atoms(1,4)).Rmax; - ze = max(Atoms(:, 3))+S(Atoms(end,4)).Rmax; - [nAtoms,~] = size(Atoms); - [nslice, ~] = size(Slice); - - xy = zeros(nAtoms, 2); - xy(:, 2) = Atoms(:, 3); - figure(nf); clf; - plot(xy(:, 1), xy(:, 2), '*k'); - for i = 1:nslice - hold on; - plot([-1 1], [Slice(i, 1) Slice(i, 1)], '-r','LineWidth',1); - set(gca,'FontSize',10,'LineWidth',2,'PlotBoxAspectRatio',[0.75 1 1]); - end - hold on; - plot([-1 1], [Slice(i, 2) Slice(i, 2)], '-r','LineWidth',1); - hold on; - ee = 0.25e-01; - plot([-1 1], [z0-ee z0-ee], '-k'); - hold on; - plot([-1 1], [ze+ee ze+ee], '-k'); - - Planes = getPlanes(input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, inFP, input_multem.DimFP, input_multem.SeedFP); - [nPlanes, ~] = size(Planes); - for i = 1:nPlanes - hold on; - plot([-1 1], [Planes(i) Planes(i)], '-b'); - set(gca,'FontSize',10,'LineWidth',1,'PlotBoxAspectRatio',[0.75 1 1]); - end - [nAtoms, nslice, nPlanes] -end - +function [] = ilm_show_slicing(input_multem, inFP, nf) + [Atoms, Slice] = getSliceSpecimen(input_multem.spec_atoms, input_multem.spec_bs_x, input_multem.spec_bs_y, input_multem.spec_slic(1).sli_thick, inFP, input_multem.DimFP, input_multem.SeedFP); + S = getAtomTypes(input_multem.pot_parm_typ); + z0 = min(Atoms(:, 3))-S(Atoms(1, 4)).Rmax; + ze = max(Atoms(:, 3))+S(Atoms(end, 4)).Rmax; + [nAtoms, ~] = size(Atoms); + [nslice, ~] = size(Slice); + + xy = zeros(nAtoms, 2); + xy(:, 2) = Atoms(:, 3); + figure(nf);clf; + plot(xy(:, 1), xy(:, 2), '*k'); + for i = 1:nslice + hold on; + plot([-1 1], [Slice(i, 1) Slice(i, 1)], '-r', 'LineWidth', 1); + set(gca, 'FontSize', 10, 'LineWidth', 2, 'PlotBoxAspectRatio', [0.75 1 1]); + end + hold on; + plot([-1 1], [Slice(i, 2) Slice(i, 2)], '-r', 'LineWidth', 1); + hold on; + ee = 0.25e-01; + plot([-1 1], [z0-ee z0-ee], '-k'); + hold on; + plot([-1 1], [ze+ee ze+ee], '-k'); + + Planes = getPlanes(input_multem.spec_atoms, input_multem.spec_bs_x, input_multem.spec_bs_y, inFP, input_multem.DimFP, input_multem.SeedFP); + [nPlanes, ~] = size(Planes); + for i = 1:nPlanes + hold on; + plot([-1 1], [Planes(i) Planes(i)], '-b'); + set(gca, 'FontSize', 10, 'LineWidth', 1, 'PlotBoxAspectRatio', [0.75 1 1]); + end + [nAtoms, nslice, nPlanes] +end + diff --git a/matlab_functions/ilm_vect_assign.m b/matlab_functions/ilm_vect_assign.m old mode 100644 new mode 100755 index d83106ba..d4757d97 --- a/matlab_functions/ilm_vect_assign.m +++ b/matlab_functions/ilm_vect_assign.m @@ -1,3 +1,3 @@ -function[varargout] = ilm_vect_assign(v) - varargout = num2cell(v); +function[varargout] = ilm_vect_assign(v) + varargout = num2cell(v); end \ No newline at end of file diff --git a/matlab_functions/ilm_wd_butwth.m b/matlab_functions/ilm_wd_butwth.m new file mode 100755 index 00000000..ec89aba8 --- /dev/null +++ b/matlab_functions/ilm_wd_butwth.m @@ -0,0 +1,42 @@ +function[fbw] = ilm_wd_butwth(bs, dr, n, r_wd, sft, r_max, p_c) + if length(p_c) == 1 + p_c = [p_c, p_c]; + end + + if length(r_max) == 1 + r_max = [r_max, r_max]; + end + + if length(r_wd) == 1 + r_wd = [r_wd, r_wd]; + end + + radius_x = r_wd(1); + radius_y = r_wd(2); + rx = (0:1:(bs(1)-1))*dr(1) - p_c(1); + ry = ((0:1:(bs(2)-1))*dr(2)).' - p_c(2); + + if bs(1)>1 + fx = 1./(1 + (rx/radius_x).^(2*n)); + fx_sft = max(fx(1), fx(end)); + fx = (fx - fx_sft)/(0.5-fx_sft); + fx = max(0, min(1.0, fx)); + else + fx = 1; + end + + if bs(2)>1 + fy = 1./(1 + (ry/radius_y).^(2*n)); + fy_sft = max(fy(1), fy(end)); + fy = (fy - fy_sft)/(0.5-fy_sft); + fy = max(0, min(1.0, fy)); + else + fy = 1; + end + + fbw = fx.*fy; + + if sft + fbw = ifftshift(fbw); + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_write_2x_y_hdf5.m b/matlab_functions/ilm_write_2x_y_hdf5.m new file mode 100755 index 00000000..19e58fa4 --- /dev/null +++ b/matlab_functions/ilm_write_2x_y_hdf5.m @@ -0,0 +1,37 @@ +function ilm_write_2x_y_hdf5(fn, x, x_1, y) + x_shape = size(x); + x_1_shape = size(x_1); + y_shape = size(y); + + if exist(fn, 'file') + try + info = h5info(fn, '/x'); + bb = isequal(info.Dataspace.Size, x_shape); + info = h5info(fn, '/x_1'); + bb = bb && isequal(info.Dataspace.Size, x_1_shape); + info = h5info(fn, '/y'); + bb = bb && isequal(info.Dataspace.Size, y_shape); + if ~bb + delete(fn) + + h5create(fn, '/x', x_shape, 'Datatype', class(x)) + h5create(fn, '/x_1', x_1_shape, 'Datatype', class(x_1)) + h5create(fn, '/y', y_shape, 'Datatype', class(y)) + end + catch + delete(fn) + + h5create(fn, '/x', x_shape, 'Datatype', class(x)) + h5create(fn, '/x_1', x_1_shape, 'Datatype', class(x_1)) + h5create(fn, '/y', y_shape, 'Datatype', class(y)) + end + else + h5create(fn, '/x', x_shape, 'Datatype', class(x)) + h5create(fn, '/x_1', x_1_shape, 'Datatype', class(x_1)) + h5create(fn, '/y', y_shape, 'Datatype', class(y)) + end + + h5write(fn, '/x', x) + h5write(fn, '/x_1', x_1) + h5write(fn, '/y', y) +end \ No newline at end of file diff --git a/matlab_functions/ilm_write_x_y_sft_sc_hdf5.m b/matlab_functions/ilm_write_x_y_sft_sc_hdf5.m new file mode 100755 index 00000000..49a444df --- /dev/null +++ b/matlab_functions/ilm_write_x_y_sft_sc_hdf5.m @@ -0,0 +1,86 @@ +function ilm_write_x_y_sft_sc_hdf5(fn, x, y, x_sft, x_sc, y_sft, y_sc) + x_shape = size(x); + y_shape = size(y); + + bb_y_sc = ~(nargin<7); + bb_y_sft = ~(nargin<6); + bb_x_sc = ~(nargin<5); + bb_x_sft = ~(nargin<4); + + if bb_x_sft + x_sft_shape = size(x_sft); + end + + if bb_x_sc + x_sc_shape = size(x_sc); + end + + if bb_y_sft + y_sft_shape = size(y_sft); + end + + if bb_y_sc + y_sc_shape = size(y_sc); + end + + bb = false; + for ik=1:4 + try + if exist(fn, 'file') + delete(fn); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + h5create(fn, '/x', x_shape, 'Datatype', class(x)); + h5create(fn, '/y', y_shape, 'Datatype', class(y)); + + if bb_x_sft + h5create(fn, '/x_sft', x_sft_shape, 'Datatype', class(x_sft)); + end + + if bb_x_sc + h5create(fn, '/x_sc', x_sc_shape, 'Datatype', class(x_sc)); + end + + if bb_y_sft + h5create(fn, '/y_sft', y_sft_shape, 'Datatype', class(y_sft)); + end + + if bb_y_sc + h5create(fn, '/y_sc', y_sc_shape, 'Datatype', class(y_sc)); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + h5write(fn, '/x', x); + h5write(fn, '/y', y); + + if bb_x_sft + h5write(fn, '/x_sft', x_sft); + end + + if bb_x_sc + h5write(fn, '/x_sc', x_sc); + end + + if bb_y_sft + h5write(fn, '/y_sft', y_sft); + end + + if bb_y_sc + h5write(fn, '/y_sc', y_sc); + end + + bb = true; + break; + catch + pause(1); + end + end + + if ~bb + disp(['data will not be saved: ', fn]); + if exist(fn, 'file') + delete(fn); + end + end +end \ No newline at end of file diff --git a/matlab_functions/ilm_write_x_y_sft_sc_y_dr_hdf5.m b/matlab_functions/ilm_write_x_y_sft_sc_y_dr_hdf5.m new file mode 100755 index 00000000..7f365ced --- /dev/null +++ b/matlab_functions/ilm_write_x_y_sft_sc_y_dr_hdf5.m @@ -0,0 +1,99 @@ +function ilm_write_x_y_sft_sc_y_dr_hdf5(fn, x, y, x_sft, x_sc, y_sft, y_sc, y_dr) + x_shape = size(x); + y_shape = size(y); + + bb_y_dr = ~(nargin<8); + bb_y_sc = ~(nargin<7); + bb_y_sft = ~(nargin<6); + bb_x_sc = ~(nargin<5); + bb_x_sft = ~(nargin<4); + + if bb_x_sft + x_sft_shape = size(x_sft); + end + + if bb_x_sc + x_sc_shape = size(x_sc); + end + + if bb_y_sft + y_sft_shape = size(y_sft); + end + + if bb_y_sc + y_sc_shape = size(y_sc); + end + + if bb_y_dr + y_dr_shape = size(y_dr); + end + + bb = false; + for ik=1:4 + try + if exist(fn, 'file') + delete(fn); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + h5create(fn, '/x', x_shape, 'Datatype', class(x)); + h5create(fn, '/y', y_shape, 'Datatype', class(y)); + + if bb_x_sft + h5create(fn, '/x_sft', x_sft_shape, 'Datatype', class(x_sft)); + end + + if bb_x_sc + h5create(fn, '/x_sc', x_sc_shape, 'Datatype', class(x_sc)); + end + + if bb_y_sft + h5create(fn, '/y_sft', y_sft_shape, 'Datatype', class(y_sft)); + end + + if bb_y_sc + h5create(fn, '/y_sc', y_sc_shape, 'Datatype', class(y_sc)); + end + + if bb_y_dr + h5create(fn, '/y_dr', y_dr_shape, 'Datatype', class(y_dr)); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + h5write(fn, '/x', x); + h5write(fn, '/y', y); + + if bb_x_sft + h5write(fn, '/x_sft', x_sft); + end + + if bb_x_sc + h5write(fn, '/x_sc', x_sc); + end + + if bb_y_sft + h5write(fn, '/y_sft', y_sft); + end + + if bb_y_sc + h5write(fn, '/y_sc', y_sc); + end + + if bb_y_dr + h5write(fn, '/y_dr', y_dr); + end + + bb = true; + break; + catch + pause(1); + end + end + + if ~bb + disp(['data will not be saved: ', fn]); + if exist(fn, 'file') + delete(fn); + end + end +end \ No newline at end of file diff --git a/matlab_functions/m2psi_tot_0.mat b/matlab_functions/m2psi_tot_0.mat old mode 100644 new mode 100755 diff --git a/matlab_functions/mex_CUDA_glnxa64.xml b/matlab_functions/mex_CUDA_glnxa64.xml old mode 100644 new mode 100755 diff --git a/matlab_functions/mex_CUDA_maci64.xml b/matlab_functions/mex_CUDA_maci64.xml old mode 100644 new mode 100755 diff --git a/matlab_functions/mex_CUDA_win64.xml b/matlab_functions/mex_CUDA_win64.xml old mode 100644 new mode 100755 index 674df2a3..d592d1e4 --- a/matlab_functions/mex_CUDA_win64.xml +++ b/matlab_functions/mex_CUDA_win64.xml @@ -1,227 +1,275 @@ - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/matlab_functions/read_psi_0_multem.m b/matlab_functions/read_psi_0_multem.m old mode 100644 new mode 100755 index eaaf2c45..3e3ee649 --- a/matlab_functions/read_psi_0_multem.m +++ b/matlab_functions/read_psi_0_multem.m @@ -1,7 +1,7 @@ -function [psi] = read_psi_0_multem(nx, ny) -psi_0 = importdata('m2psi_tot_0.mat'); -[ny0, nx0] = size(psi_0); -[Rx, Ry] = meshgrid(1+(0:(nx-1))*(nx0-1)/(nx-1), 1+(0:(ny-1))*(ny0-1)/(ny-1)); -A = interp2(psi_0, Rx, Ry); -P = exp(1i*0.5*pi*A); +function [psi] = read_psi_0_multem(nx, ny) +psi_0 = importdata('m2psi_tot_0.mat'); +[ny0, nx0] = size(psi_0); +[Rx, Ry] = meshgrid(1+(0:(nx-1))*(nx0-1)/(nx-1), 1+(0:(ny-1))*(ny0-1)/(ny-1)); +A = interp2(psi_0, Rx, Ry); +P = exp(1i*0.5*pi*A); psi = A.*P; \ No newline at end of file diff --git a/matlab_functions/reg_polyh.mat b/matlab_functions/reg_polyh.mat new file mode 100755 index 00000000..92b11836 Binary files /dev/null and b/matlab_functions/reg_polyh.mat differ diff --git a/matlab_functions/tfm_check_stem_setup.m b/matlab_functions/tfm_check_stem_setup.m old mode 100644 new mode 100755 index b82f6575..87f70f1f --- a/matlab_functions/tfm_check_stem_setup.m +++ b/matlab_functions/tfm_check_stem_setup.m @@ -1,22 +1,20 @@ function tfm_check_stem_setup(input_multem, n_detector) - + fcn_check_probe(input_multem); fcn_check_slicing(input_multem); - if nargin > 1 - fcn_check_detector_coverage(input_multem, n_detector); - end + fcn_check_detector_coverage(input_multem, n_detector); function fcn_check_probe(input_multem) - input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 - input_multem.system_conf.device = 1; % eD_CPU = 1, eD_GPU = 2 - input_multem.system_conf.cpu_nthread = 1; - input_multem.system_conf.gpu_device = 0; + system_config.precision = 1; % eP_Float = 1, eP_double = 2 + system_config.device = 1; % eD_CPU = 1, eD_GPU = 2 + system_config.cpu_nthread = 1; + system_config.gpu_device = 0; - input_multem.iw_type = 2; % 2 = convergent beam + input_multem.incdt_wav_typ = 2; % 2 = convergent beam input_multem.iw_x = 0.5*input_multem.spec_lx; input_multem.iw_y = 0.5*input_multem.spec_ly; - output_incident_wave = input_multem.ilc_incident_wave; + output_incident_wave = ilc_incident_wave(system_config, input_multem); psi_0 = output_incident_wave.psi_0; figure(1); clf @@ -40,57 +38,43 @@ function fcn_check_probe(input_multem) end function fcn_check_slicing(input_multem) - - if ~isempty(input_multem.spec_atoms) - % Slicing - [~, Slice] = ilc_spec_slicing(input_multem.toStruct); - [nslice, ~] = size(Slice); - figure(2); clf; - subplot(1,2,1); - plot(input_multem.spec_atoms(:, 2), input_multem.spec_atoms(:, 4), 'ok'); - hold on; - for i = 1:nslice - plot([min(input_multem.spec_atoms(:, 2)) max(input_multem.spec_atoms(:, 2))], [Slice(i, 1) Slice(i, 1)], '-b', [min(input_multem.spec_atoms(:, 2)) max(input_multem.spec_atoms(:, 2))], [Slice(i, 2) Slice(i, 2)], '-b'); - end - hold off; - title('Slice positions'); - ylabel('z'); - xlabel('x'); - axis equal; - axis([min(input_multem.spec_atoms(:, 2))-3 max(input_multem.spec_atoms(:, 2))+3 Slice(1, 1)-3 Slice(end, 1)+3]); + % Slicing + [atoms, Slice] = ilc_spec_slicing(input_multem); + [nslice, ~] = size(Slice); - legend({'Atom positions','Slice boundaries'},'Location','southoutside') - set(gca,'YDir','reverse') - - subplot(1,2,2); - plot3(input_multem.spec_atoms(:,2), input_multem.spec_atoms(:,3), input_multem.spec_atoms(:,4),'or'); - hold on; - if input_multem.simulation_type <= 12 - plot3([input_multem.scanning_x0; input_multem.scanning_xe; input_multem.scanning_xe; input_multem.scanning_x0;input_multem.scanning_x0],... - [input_multem.scanning_y0; input_multem.scanning_y0; input_multem.scanning_ye; input_multem.scanning_ye;input_multem.scanning_y0],... - [0; 0; 0; 0; 0],'-k'); - legend({'Atom positions','STEM Scan Field'},'Location','southoutside') - else - z0 = get_defocus_ref(input_multem); - [xp, yp, zp] = cylinder([0 2], 64); - surf(input_multem.iw_x+xp, input_multem.iw_y+yp, z0+(10*zp),'FaceAlpha',0.5,'EdgeColor','none','FaceColor','g') - surf(input_multem.iw_x+xp, input_multem.iw_y+yp, z0+(-10*zp),'FaceAlpha',0.5, 'EdgeColor','none','FaceColor','g') - plot3(input_multem.iw_x, input_multem.iw_y, z0,'xk'); - legend({'Atom positions','Probe'},'Location','southoutside') - end - - hold off; - axis equal; - title('Atom positions and Scan Field') - zlabel('z'); - xlabel('x'); - ylabel('y'); - set(gca,'ZDir','reverse') - else - fprintf(2,['No atoms are specified. Check your input structure! \n']); + figure(2); clf; + subplot(1,2,1); + plot(atoms(:, 3), atoms(:, 4), 'ok'); + hold on; + for i = 1:nslice + plot([min(atoms(:, 3)) max(atoms(:, 3))], [Slice(i, 1) Slice(i, 1)], '-b', [min(atoms(:, 3)) max(atoms(:, 3))], [Slice(i, 2) Slice(i, 2)], '-b'); end - + hold off; + title('Slice positions'); + ylabel('z'); + xlabel('x'); + axis equal; + axis([min(atoms(:, 3)) max(atoms(:, 3)) -5 input_multem.spec_lz + 5]); + legend({'Atom positions','Slice boundaries'},'Location','southoutside') + set(gca,'YDir','reverse') + + subplot(1,2,2); + plot3(input_multem.spec_atoms(:,2), input_multem.spec_atoms(:,3), input_multem.spec_atoms(:,4),'or'); + hold on; + plot3([input_multem.scanning_x0; input_multem.scanning_xe; input_multem.scanning_xe; input_multem.scanning_x0;input_multem.scanning_x0],... + [input_multem.scanning_y0; input_multem.scanning_y0; input_multem.scanning_ye; input_multem.scanning_ye;input_multem.scanning_y0],... + [0; 0; 0; 0; 0],'-k'); + hold off; + axis equal; + title('Atom positions and Scan Field') + zlabel('z'); + xlabel('x'); + ylabel('y'); + axis equal; + legend({'Atom positions','STEM Scan Field'},'Location','southoutside') + set(gca,'ZDir','reverse') + view([0 0 1]) end function fcn_check_detector_coverage(input_multem, detector) @@ -102,7 +86,8 @@ function fcn_check_detector_coverage(input_multem, detector) ly = input_multem.spec_ly; ri_detector = input_multem.detector.cir(detector).inner_ang; ro_detector = input_multem.detector.cir(detector).outer_ang; - + + clc; gmax(1)=nx/(2*lx); gmax(2) = ny/(2*ly); gmax_abs=min(gmax(:)); ri_detector = ilm_mrad_2_rAng(E_0,ri_detector); @@ -115,6 +100,7 @@ function fcn_check_detector_coverage(input_multem, detector) bwx = 2/3*(gmax_abs*cos(t)); bwy = 2/3*(gmax_abs*sin(t)); + gspace=polyshape([-gmax(1) gmax(1) gmax(1) -gmax(1)],[-gmax(2) -gmax(2) gmax(2) gmax(2)]); d=polyshape({xi,xo},{yi,yo},'Simplify',false); figure(3); clf @@ -134,23 +120,8 @@ function fcn_check_detector_coverage(input_multem, detector) if tfm_pn_fact(nx,1)~=nx && tfm_pn_fact(nx,2)~=nx && tfm_pn_fact(nx,3)~=nx fprintf(2,['Using ' num2str(nx) ' pixels in x is computationally unefficient. Consider using ' num2str(tfm_pn_fact(nx,1)) ' or ' num2str(tfm_pn_fact(nx,3)) ' instead.' '\n']) end - if tfm_pn_fact(ny,1)~=ny && tfm_pn_fact(ny,2)~=ny && tfm_pn_fact(ny,3)~=ny + if tfm_pn_fact(ny,1)~=nx && tfm_pn_fact(ny,2)~=ny && tfm_pn_fact(ny,3)~=ny fprintf(2,['Using ' num2str(ny) ' pixels in y is computationally unefficient. Consider using ' num2str(tfm_pn_fact(ny,1)) ' or ' num2str(tfm_pn_fact(ny,3)) ' instead.' '\n']) end end -end - -function z0 = get_defocus_ref(input_multem) - at_min = min(input_multem.spec_atoms(:,4)); - at_max = max(input_multem.spec_atoms(:,4)); - switch input_multem.cond_lens_zero_defocus_type - case 1 - z0 = at_min; - case 2 - z0 = (at_max -at_min)/2+at_min; - case 3 - z0 = at_max; - case 4 - z0 = input_multem.cond_lens_zero_defocus_plane; - end end \ No newline at end of file diff --git a/matlab_functions/tfm_pn_fact.m b/matlab_functions/tfm_pn_fact.m deleted file mode 100644 index d1c4d490..00000000 --- a/matlab_functions/tfm_pn_fact.m +++ /dev/null @@ -1,59 +0,0 @@ -function xo = tfm_pn_fact(x, b_min) - % Returns an integer corresponding to the closest prime number - % factorisation for computational efficiency (mainly relevant for CUDA) - % Inputs: - % x Input number - % b_min (optional) either: - % 1 (nearest solution) (default) - % 2 (next smaller solution) - % 3 (next larger solution) - - x = int64(x); - x = min(max(2,x),2^16); - p_min = 64; - - if nargin < 2 - b_min = 1; - end - - switch b_min - case 1 - x_t(1) = fcn_pn_down(x); - x_t(2) = fcn_pn_up(x); - [~,id] = sort(abs(x-x_t)); - xo = x_t(id(1)); - case 2 - x = max(3,x); - xo = fcn_pn_down(x-1); - case 3 - xo = fcn_pn_up(x+1); - end - xo = double(xo); - function x = fcn_pn_up(x) - pn = factor(x); - b_pn = fcn_b_pn(x,pn); - while b_pn - x = x + 1; - pn = factor(x); - b_pn = fcn_b_pn(x,pn); - end - end - - function x = fcn_pn_down(x) - pn = factor(x); - b_pn = fcn_b_pn(x,pn); - while b_pn - x = x - 1; - pn = factor(x); - b_pn = fcn_b_pn(x,pn); - end - end - - function b_pn = fcn_b_pn(x,pn) - if x > p_min - b_pn = any(pn>7) || ~any(pn==2); - else - b_pn = ~all(pn==2); - end - end -end \ No newline at end of file diff --git a/matlab_functions/xy_projected.mat b/matlab_functions/xy_projected.mat old mode 100644 new mode 100755 diff --git a/mex_bin/mex_binary_files.txt b/mex_bin/mex_binary_files.txt new file mode 100755 index 00000000..e69de29b diff --git a/mex_examples_multem/Pt_twin.xyz b/mex_examples_multem/Pt_twin.xyz old mode 100644 new mode 100755 diff --git a/mex_examples_multem/SrTiO3_mp-4651_conventional_standard.cif b/mex_examples_multem/SrTiO3_mp-4651_conventional_standard.cif new file mode 100755 index 00000000..10659f5e --- /dev/null +++ b/mex_examples_multem/SrTiO3_mp-4651_conventional_standard.cif @@ -0,0 +1,46 @@ +# generated using pymatgen +data_SrTiO3 +_symmetry_space_group_name_H-M 'P 1' +_cell_length_a 5.56772800 +_cell_length_b 5.56772800 +_cell_length_c 7.90710600 +_cell_angle_alpha 90.00000000 +_cell_angle_beta 90.00000000 +_cell_angle_gamma 90.00000000 +_symmetry_Int_Tables_number 1 +_chemical_formula_structural SrTiO3 +_chemical_formula_sum 'Sr4 Ti4 O12' +_cell_volume 245.11708427 +_cell_formula_units_Z 4 +loop_ + _symmetry_equiv_pos_site_id + _symmetry_equiv_pos_as_xyz + 1 'x, y, z' +loop_ + _atom_site_type_symbol + _atom_site_label + _atom_site_symmetry_multiplicity + _atom_site_fract_x + _atom_site_fract_y + _atom_site_fract_z + _atom_site_occupancy + Sr Sr0 1 0.00000000 0.50000000 0.25000000 1 + Sr Sr1 1 0.50000000 0.00000000 0.25000000 1 + Sr Sr2 1 0.50000000 0.00000000 0.75000000 1 + Sr Sr3 1 0.00000000 0.50000000 0.75000000 1 + Ti Ti4 1 0.00000000 0.00000000 0.00000000 1 + Ti Ti5 1 0.50000000 0.50000000 0.00000000 1 + Ti Ti6 1 0.50000000 0.50000000 0.50000000 1 + Ti Ti7 1 0.00000000 0.00000000 0.50000000 1 + O O8 1 0.77093350 0.27093350 0.50000000 1 + O O9 1 0.22906650 0.27093350 0.00000000 1 + O O10 1 0.77093350 0.72906650 0.00000000 1 + O O11 1 0.72906650 0.22906650 0.00000000 1 + O O12 1 0.50000000 0.50000000 0.25000000 1 + O O13 1 0.00000000 0.00000000 0.25000000 1 + O O14 1 0.27093350 0.77093350 0.00000000 1 + O O15 1 0.72906650 0.77093350 0.50000000 1 + O O16 1 0.27093350 0.22906650 0.50000000 1 + O O17 1 0.22906650 0.72906650 0.50000000 1 + O O18 1 0.00000000 0.00000000 0.75000000 1 + O O19 1 0.50000000 0.50000000 0.75000000 1 diff --git a/mex_examples_multem/example_MULTEM_CBED.m b/mex_examples_multem/example_MULTEM_CBED.m old mode 100644 new mode 100755 index cf4e8c15..e2af6174 --- a/mex_examples_multem/example_MULTEM_CBED.m +++ b/mex_examples_multem/example_MULTEM_CBED.m @@ -1,121 +1,120 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Convergent beam electron diffraction (CBED) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 21; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 40; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Si001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = 0; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 100; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 4; % 1: coherente mode, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 1110; % Defocus (�) -input_multem.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_a = 1.0; % Height proportion of a normalized Gaussian [0, 1] -input_multem.cond_lens_ti_sigma = dsf_sigma; % Standard deviation of the defocus spread for the Gaussian component (�) -input_multem.cond_lens_ti_beta = 0.0; % Standard deviation of the defocus spread for the Exponential component (�) -input_multem.cond_lens_ti_npts = 4; % Number of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_a = 1.0; % Height proportion of a normalized Gaussian [0, 1] -input_multem.cond_lens_si_sigma = ssf_sigma; % Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_beta = 0.0; % Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % Number of radial integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_azm_npts = 4; % Number of radial integration points. It will be only used if illumination_model=4 - -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 4; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -c = 1e5; -figure(1); clf; -for i=1:length(output_multislice.data) - m2psi_tot = output_multislice.data(i).m2psi_tot; - m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); - - I_min = min(m2psi_tot(:)); - I_max = max(m2psi_tot(:)); - - imagesc(output_multislice.x, output_multislice.y, m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); - axis image; - colormap hot; - pause(0.5); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Convergent beam electron diffraction (CBED) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 21; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 40;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Si001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 100; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 1110; % Defocus (Å) +input_multem.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 7; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +c = 1e5; +figure(1); clf; +for i=1:length(output_multem.data) + m2psi_tot = output_multem.data(i).m2psi_tot; + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); + + I_min = min(m2psi_tot(:)); + I_max = max(m2psi_tot(:)); + + imagesc(output_multem.x, output_multem.y, m2psi_tot, [I_min I_max]); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); + axis image; + colormap hot; + pause(0.5); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_CBEI.m b/mex_examples_multem/example_MULTEM_CBEI.m old mode 100644 new mode 100755 index 1b828fae..80231f5a --- a/mex_examples_multem/example_MULTEM_CBEI.m +++ b/mex_examples_multem/example_MULTEM_CBEI.m @@ -1,127 +1,131 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Convergent beam electron Imaging (CBEI) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 22; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 40; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Si001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = 0; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 100; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 140.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 0; % Defocus (�) -input_multem.obj_lens_c_30 = 0.00; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) -%%%%%%%%% defocus spread function %%%%%%%%%%%% -input_multem.obj_lens_ti_sigma = 0; % standard deviation (�) -input_multem.obj_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -figure(1); -for i=1:length(output_multislice.data) - imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); - axis image; - colormap hot; - pause(0.25); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Convergent beam electron image (CBEI) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 22; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 40;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Si001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 100; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 0; % Defocus (Å) +input_multem.obj_lens_c_30 = 0.00; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) +%%%%%%%%% defocus spread function %%%%%%%%%%%% +input_multem.obj_lens_tp_inc_sigma = 0; % standard deviation (Å) +input_multem.obj_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); +for i=1:length(output_multem.data) + imagesc(output_multem.data(i).m2psi_tot); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); + axis image; + colormap hot; + pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_ED.m b/mex_examples_multem/example_MULTEM_ED.m old mode 100644 new mode 100755 index 2168eb1d..2e31a36f --- a/mex_examples_multem/example_MULTEM_ED.m +++ b/mex_examples_multem/example_MULTEM_ED.m @@ -1,80 +1,83 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Electron diffraction (ED) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 31; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 40; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -c = 1e6; -figure(1); -for i=1:length(output_multislice.data) - m2psi_tot = output_multislice.data(i).m2psi_tot; - m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); - - I_min = min(m2psi_tot(:)); - I_max = max(m2psi_tot(:)); - - imagesc(m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(i))); - axis image; - colormap gray; - pause(0.25); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Convergent beam electron diffraction (CBED) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 31; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 40;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +c = 1e6; +figure(1); +for i=1:length(output_multem.data) + m2psi_tot = output_multem.data(i).m2psi_tot; + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); + + I_min = min(m2psi_tot(:)); + I_max = max(m2psi_tot(:)); + + imagesc(m2psi_tot, [I_min I_max]); + title(strcat('Total intensity - Thick = ', num2str(i))); + axis image; + colormap gray; + pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EELS.m b/mex_examples_multem/example_MULTEM_EELS.m old mode 100644 new mode 100755 index a602e52a..b85e68bf --- a/mex_examples_multem/example_MULTEM_EELS.m +++ b/mex_examples_multem/example_MULTEM_EELS.m @@ -1,120 +1,114 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% STEM electron energy loss spectroscopy (EELS) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -% eST_STEM=11, eST_ISTEM=12, eST_CBED=21, eST_CBEI=22, eST_ED=31, eST_HRTEM=32, eST_PED=41, eST_HCI=42, eST_EWFS=51, eST_EWRS=52, -% eST_EELS=61, eST_EFTEM=62, eST_ProbeFS=71, eST_ProbeRS=72, eST_PPFS=81, eST_PPRS=82,eST_TFFS=91, eST_TFRS=92 -input_multem.simulation_type = 61; -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations - -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -na = 4; nb = 4; nc = 10; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.nx = 512; -input_multem.ny = 512; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 88.7414; % Defocus (�) -input_multem.cond_lens_c_30 = 0.04; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multem.cond_lens_ti_sigma = 32; % standard deviation (�) -input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.scanning_type = 1; % eST_Line = 1, eST_Area = 2 -input_multem.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) -input_multem.scanning_ns = 10; % number of sampling points -input_multem.scanning_x0 = 2*a; % x-starting point (�) -input_multem.scanning_y0 = 2.5*b; % y-starting point (�) -input_multem.scanning_xe = 3*a; % x-final point (�) -input_multem.scanning_ye = 2.5*b; % y-final point (�) - -input_multem.eels_E_loss = 532; % Energy loss (eV) -input_multem.eels_m_selection = 3; % selection rule -input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 -input_multem.eels_collection_angle = 100; % Collection half angle (mrad) -input_multem.eels_Z = 8; % atomic type - -input_multem.eels_E_loss = 456; % Energy loss (eV) -input_multem.eels_m_selection = 3; % selection rule -input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 -input_multem.eels_collection_angle = 100; % Collection half angle (mrad) -input_multem.eels_Z = 22; % atomic type - -input_multem.eels_E_loss = 1940; % Energy loss (eV) -input_multem.eels_m_selection = 3; % selection rule -input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 -input_multem.eels_collection_angle = 100; % Collection half angle (mrad) -input_multem.eels_Z = 38; % atomic type - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; -clear ilc_multem; - -figure(1); -for i=1:length(output_multislice.data) - imagesc(output_multislice.data(i).image_tot(1).image); - title(strcat('Thk = ', num2str(i), ', det = ', num2str(j))); - axis image; - colormap gray; - pause(0.25); -end - -% cc = [1 0 1; 1 0 0; 0 0 1; 0 0 0]; -% for i=1:4 -% input_multem.eels_channelling_type = i; -% clear ilc_multem; -% tic; -% [eels] = input_multem.ilc_multem; -% toc; -% figure(1); -% hold on; -% plot(eels, 'color', cc(i, :)); +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 4; +system_config.gpu_device = 0; + +% eST_STEM=11, eST_ISTEM=12, eST_CBED=21, eST_CBEI=22, eST_ED=31, eST_HRTEM=32, eST_PED=41, eST_HCI=42, eST_EWFS=51, eST_EWRS=52, +% eST_EELS=61, eST_EFTEM=62, eST_ProbeFS=71, eST_ProbeRS=72, eST_PPFS=81, eST_PPRS=82, eST_TFFS=91, eST_TFRS=92 +input_multem.em_sim_typ = 61; +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations + +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +na = 4;nb = 4;nc = 10;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.nx = 512; +input_multem.ny = 512; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 88.7414; % Defocus (Å) +input_multem.cond_lens_c_30 = 0.04; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_spt_inc_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 8; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.scan_pat_typ = 1; % eST_Line = 1, eST_Area = 2 +input_multem.scan_pat_pbc = 1; % 1: true, 0:false (periodic boundary conditions) +input_multem.scan_pat_nsp = 10; % number of sampling points +input_multem.scan_pat_r_0 = [2*a;2.5*b]; % starting point (Å) +input_multem.scan_pat_r_e = [3*a;2.5*b]; % final point (Å) + +input_multem.eels_E_loss = 532; % Energy loss (eV) +input_multem.eels_m_selection = 3; % selection rule +input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eels_collection_angle = 100; % Collection half angle (mrad) +input_multem.eels_Z = 8; % atomic type + +input_multem.eels_E_loss = 456; % Energy loss (eV) +input_multem.eels_m_selection = 3; % selection rule +input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eels_collection_angle = 100; % Collection half angle (mrad) +input_multem.eels_Z = 22; % atomic type + +input_multem.eels_E_loss = 1940; % Energy loss (eV) +input_multem.eels_m_selection = 3; % selection rule +input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eels_collection_angle = 100; % Collection half angle (mrad) +input_multem.eels_Z = 38; % atomic type + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; +clear ilc_multem; + +figure(1); +for i=1:length(output_multem.data) + imagesc(output_multem.data(i).image_tot(1).image); + title(strcat('Thk = ', num2str(i), ', det = ', num2str(j))); + axis image; + colormap gray; + pause(0.25); +end + +% cc = [1 0 1;1 0 0; 0 0 1; 0 0 0]; +% for i=1:4 +% input_multem.eels_channelling_type = i; +% clear ilc_multem; +% tic; +% [eels] = ilc_multem(system_config, input_multem); +% toc; +% figure(1); +% hold on; +% plot(eels, 'color', cc(i, :)); % end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EFTEM.m b/mex_examples_multem/example_MULTEM_EFTEM.m old mode 100644 new mode 100755 index 4ea01057..c33677ee --- a/mex_examples_multem/example_MULTEM_EFTEM.m +++ b/mex_examples_multem/example_MULTEM_EFTEM.m @@ -1,7 +1,10 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation +% output_multislice = ilc_multem(system_config, input_multem) perform TEM simulation +% % Energy filtered transmission electron microscopy (EFTEM) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato +% +% All parameters of the input_multem structure are explained in multem_default_values() +% +% Copyright 2020 Ivan Lobato clear; clc; addpath([fileparts(pwd) filesep 'mex_bin']) @@ -9,106 +12,106 @@ addpath([fileparts(pwd) filesep 'matlab_functions']) %%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; +input_multem = multem_default_values(); % Load default values; %%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_nthread = 1; +system_config.gpu_device = 0; %%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 62; +input_multem.em_sim_typ = 62; %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% na = 8; nb = 8; nc = 5; ncu = 2; rmsd_3d = 0.085; [input_multem.spec_atoms, input_multem.spec_lx... , input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001Crystal(na, nb, nc, ncu, rmsd_3d); -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = 0; % Array of thickes (�) +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0; % Array of thickes (Å) %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multem.nx = 1024; input_multem.ny = 1024; input_multem.bwl = 0; % Band-width limit, 1: true, 0:false -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave input_multem.iw_x = input_multem.spec_lx/2; % x position input_multem.iw_y = input_multem.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 88.7414; % Defocus (�) -input_multem.cond_lens_c_30 = 0.04; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 88.7414; % Defocus (Å) +input_multem.cond_lens_c_30 = 0.04; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) %%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation -input_multem.obj_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.obj_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 +ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation +input_multem.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multem.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 0; % Defocus (�) -input_multem.obj_lens_c_30 = 0; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) +input_multem.obj_lens_c_10 = 0; % Defocus (Å) +input_multem.obj_lens_c_30 = 0; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) -input_multem.obj_lens_ti_sigma = 32; % standard deviation (�) -input_multem.obj_lens_ti_npts = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define +input_multem.obj_lens_ti_sigma = 32; % standard deviation (Å) +input_multem.obj_lens_ti_npts = 10; % # integration steps for the defocus Spread. It will be only used if illum_mod=4 +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define input_multem.eftem_E_loss = 532; % Energy loss (eV) input_multem.eftem_m_selection = 3; % selection rule @@ -130,7 +133,7 @@ clear ilc_multem; tic; -output_multislice = input_multem.ilc_multem; +output_multislice = ilc_multem(system_config, input_multem); toc; figure(1); diff --git a/mex_examples_multem/example_MULTEM_EFTEMFS.m b/mex_examples_multem/example_MULTEM_EFTEMFS.m new file mode 100755 index 00000000..6813325a --- /dev/null +++ b/mex_examples_multem/example_MULTEM_EFTEMFS.m @@ -0,0 +1,145 @@ +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Energy filtered transmission electron microscopy (EFTEM) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 71; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 4;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0; % Array of thickes (?) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (?) +input_multem.phi = 0.0; % Till ilumination (?) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 4; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 15.0; % Defocus (A) +input_multem.cond_lens_c_30 = 0.001; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (?) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (?) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (?) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (?) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (?) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(?^-1);otherwise (?) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 0; % Defocus (A) +input_multem.obj_lens_c_30 = 0; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (?) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (?) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (?) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (?) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define + +input_multem.eftem_E_loss = 532; % Energy loss (eV) +input_multem.eftem_m_selection = 3; % selection rule +input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eftem_collection_angle = 25; % Collection half angle (mrad) +input_multem.eftem_Z = 8; % atomic type + +% input_multem.eftem_E_loss = 456; % Energy loss (eV) +% input_multem.eftem_m_selection = 3; % selection rule +% input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +% input_multem.eftem_collection_angle = 25; % Collection half angle (mrad) +% input_multem.eftem_Z = 22; % atomic type +% +% input_multem.eftem_E_loss = 1940; % Energy loss (eV) +% input_multem.eftem_m_selection = 3; % selection rule +% input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +% input_multem.eftem_collection_angle = 25; % Collection half angle (mrad) +% input_multem.eftem_Z = 38; % atomic type + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); +for i=1:length(output_multem.data) + imagesc(output_multem.data(i).m2psi_tot); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); + axis image; + colormap gray; + pause(0.25); +end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EFTEMRS.m b/mex_examples_multem/example_MULTEM_EFTEMRS.m new file mode 100755 index 00000000..b50cb682 --- /dev/null +++ b/mex_examples_multem/example_MULTEM_EFTEMRS.m @@ -0,0 +1,145 @@ +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Energy filtered transmission electron microscopy (EFTEM) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 72; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 4;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0; % Array of thickes (?) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (?) +input_multem.phi = 0.0; % Till ilumination (?) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 15.0; % Defocus (A) +input_multem.cond_lens_c_30 = 0.001; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (?) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (?) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (?) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (?) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (?) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(?^-1);otherwise (?) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 0; % Defocus (A) +input_multem.obj_lens_c_30 = 0; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (?) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (?) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (?) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (?) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define + +input_multem.eftem_E_loss = 532; % Energy loss (eV) +input_multem.eftem_m_selection = 3; % selection rule +input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eftem_collection_angle = 25; % Collection half angle (mrad) +input_multem.eftem_Z = 8; % atomic type + +% input_multem.eftem_E_loss = 456; % Energy loss (eV) +% input_multem.eftem_m_selection = 3; % selection rule +% input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +% input_multem.eftem_collection_angle = 25; % Collection half angle (mrad) +% input_multem.eftem_Z = 22; % atomic type +% +% input_multem.eftem_E_loss = 1940; % Energy loss (eV) +% input_multem.eftem_m_selection = 3; % selection rule +% input_multem.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +% input_multem.eftem_collection_angle = 25; % Collection half angle (mrad) +% input_multem.eftem_Z = 38; % atomic type + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); +for i=1:length(output_multem.data) + imagesc(output_multem.data(i).m2psi_tot); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); + axis image; + colormap gray; + pause(0.25); +end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EWFS.m b/mex_examples_multem/example_MULTEM_EWFS.m old mode 100644 new mode 100755 index 9aead610..cd20548c --- a/mex_examples_multem/example_MULTEM_EWFS.m +++ b/mex_examples_multem/example_MULTEM_EWFS.m @@ -1,118 +1,122 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% % Exit wave real space (EWRS) simulation +% % All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato +% +% Copyright 2021 Ivan Lobato -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) %%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; +input_multem = ilm_dflt_input_multem(); % Load default values; %%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; %%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 51; +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 51; %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 40; ncu = 2; rmsd_3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 40;ncu = 2;rmsd_3d = 0.085; -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multem.nx = 1024; input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 140.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) %%%%%%%%% defocus spread function %%%%%%%%%%%% dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%%% source spread function %%%%%%%%%%%% ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define clear ilc_multem; tic; -output_multislice = input_multem.ilc_multem; +output_multem = ilc_multem(system_config, input_multem); toc; c = 1e6; figure(1); -for i=1:length(output_multislice.data) - m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; - if(isfield(output_multislice.data, 'm2psi_tot')) - m2psi_tot = output_multislice.data(i).m2psi_tot; +for i=1:length(output_multem.data) + m2psi_coh = abs(output_multem.data(i).psi_coh).^2; + if(isfield(output_multem.data, 'm2psi_tot')) + m2psi_tot = output_multem.data(i).m2psi_tot; else m2psi_tot = m2psi_coh; - end + end m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); m2psi_coh = log(1+c*m2psi_coh/max(m2psi_coh(:))); @@ -122,14 +126,14 @@ subplot(1, 2, 1); imagesc(m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); axis image; colormap gray; colorbar subplot(1, 2, 2); imagesc(m2psi_coh, [I_min I_max]); - title(strcat('Coherent intensity - Thick = ', num2str(output_multislice.thick(i)))); + title(strcat('Coherent intensity - Thick = ', num2str(output_multem.thick(i)))); axis image; colormap gray; colorbar diff --git a/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m b/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m old mode 100644 new mode 100755 index b2bc795f..2715b28c --- a/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m +++ b/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m @@ -1,118 +1,122 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% % Exit wave real space (EWRS) simulation +% % All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato +% +% Copyright 2021 Ivan Lobato -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) %%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; +input_multem = ilm_dflt_input_multem(); % Load default values; %%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; %%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 51; +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 51; %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 40; ncu = 2; rmsd_3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 40;ncu = 2;rmsd_3d = 0.085; -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multem.nx = 1024; input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 3.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 3.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 140.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) %%%%%%%%% defocus spread function %%%%%%%%%%%% dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%%% source spread function %%%%%%%%%%%% ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define clear ilc_multem; tic; -output_multislice = input_multem.ilc_multem; +output_multem = ilc_multem(system_config, input_multem); toc; c = 1e6; figure(1); -for i=1:length(output_multislice.data) - m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; - if(isfield(output_multislice.data, 'm2psi_tot')) - m2psi_tot = output_multislice.data(i).m2psi_tot; +for i=1:length(output_multem.data) + m2psi_coh = abs(output_multem.data(i).psi_coh).^2; + if(isfield(output_multem.data, 'm2psi_tot')) + m2psi_tot = output_multem.data(i).m2psi_tot; else m2psi_tot = m2psi_coh; - end + end m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); m2psi_coh = log(1+c*m2psi_coh/max(m2psi_coh(:))); @@ -122,14 +126,14 @@ subplot(1, 2, 1); imagesc(m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); axis image; colormap gray; colorbar subplot(1, 2, 2); imagesc(m2psi_coh, [I_min I_max]); - title(strcat('Coherent intensity - Thick = ', num2str(output_multislice.thick(i)))); + title(strcat('Coherent intensity - Thick = ', num2str(output_multem.thick(i)))); axis image; colormap gray; colorbar diff --git a/mex_examples_multem/example_MULTEM_EWRS.m b/mex_examples_multem/example_MULTEM_EWRS.m old mode 100644 new mode 100755 index b181ef1a..5b4f65cd --- a/mex_examples_multem/example_MULTEM_EWRS.m +++ b/mex_examples_multem/example_MULTEM_EWRS.m @@ -1,114 +1,127 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% % Exit wave real space (EWRS) simulation +% % All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato +% +% Copyright 2021 Ivan Lobato -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) %%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; +input_multem = ilm_dflt_input_multem(); % Load default values; %%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; %%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 52; %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 10; ncu = 2; rmsd_3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 10;ncu = 2;rmsd_3d = 0.085; -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Si110_xtl(na, nb, nc, ncu, rmsd_3d); -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) +% [input_multem.spec_atoms, input_multem.spec_bs_x... +% , input_multem.spec_bs_y, input_multem.spec_bs_z... +% , a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); + +% [input_multem.spec_atoms, input_multem.spec_bs_x... +% , input_multem.spec_bs_y, input_multem.spec_bs_z... +% , a, b, c] = graphene(na, 1.42, rmsd_3d); +% input_multem.spec_slic(1).sli_thick = 2.0; + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multem.nx = 1024; input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 140.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) %%%%%%%%% defocus spread function %%%%%%%%%%%% dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%%% source spread function %%%%%%%%%%%% ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define clear ilc_multem; tic; -output_multislice = input_multem.ilc_multem; +output_multem = ilc_multem(system_config, input_multem); toc; figure(1); -for i=1:length(output_multislice.data) - m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; - if(isfield(output_multislice.data, 'm2psi_tot')) - m2psi_tot = output_multislice.data(i).m2psi_tot; +for i=1:length(output_multem.data) + m2psi_coh = abs(output_multem.data(i).psi_coh).^2; + if(isfield(output_multem.data, 'm2psi_tot')) + m2psi_tot = output_multem.data(i).m2psi_tot; else m2psi_tot = m2psi_coh; end diff --git a/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m b/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m old mode 100644 new mode 100755 index 75c69624..16726cdd --- a/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m +++ b/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m @@ -1,117 +1,121 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% % Exit wave real space (EWRS) simulation +% % All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato +% +% Copyright 2021 Ivan Lobato -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) %%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; +input_multem = ilm_dflt_input_multem(); % Load default values; %%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; %%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 52; %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 10; ncu = 2; rmsd_3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 10;ncu = 2;rmsd_3d = 0.085; -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) %%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multem.nx = 1024; input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 3.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 3.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 140.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) %%%%%%%%% defocus spread function %%%%%%%%%%%% dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%%% source spread function %%%%%%%%%%%% ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define clear ilc_multem; tic; -output_multislice = input_multem.ilc_multem; +output_multem = ilc_multem(system_config, input_multem); toc; figure(1); -for i=1:length(output_multislice.data) - m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; - if(isfield(output_multislice.data, 'm2psi_tot')) - m2psi_tot = output_multislice.data(i).m2psi_tot; +for i=1:length(output_multem.data) + m2psi_coh = abs(output_multem.data(i).psi_coh).^2; + if(isfield(output_multem.data, 'm2psi_tot')) + m2psi_tot = output_multem.data(i).m2psi_tot; else m2psi_tot = m2psi_coh; - end + end subplot(1, 2, 1); imagesc(m2psi_tot); title(strcat('Total intensity - Thick = ', num2str(i))); diff --git a/mex_examples_multem/example_MULTEM_HCTEM.m b/mex_examples_multem/example_MULTEM_HCTEM.m old mode 100644 new mode 100755 index 042085fc..e5915a95 --- a/mex_examples_multem/example_MULTEM_HCTEM.m +++ b/mex_examples_multem/example_MULTEM_HCTEM.m @@ -1,104 +1,107 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Hollow cone transmission electron microscopy (HCTEM) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 42; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 16; nb = 16; nc = 20; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 20; % Defocus (�) -input_multem.obj_lens_c_30 = 0.04; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 25.0; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.obj_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.obj_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.hci_nrot = 30; % number of orientations -input_multem.hci_theta = 3.0; % Precession angle (degrees) - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -figure(1); -for i=1:length(output_multislice.data) - imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); - axis image; - colormap gray; - pause(0.25); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Hollow cone transmission electron microscopy (HCTEM) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 42; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 16;nb = 16;nc = 20;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation +input_multem.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 20; % Defocus (Å) +input_multem.obj_lens_c_30 = 0.04; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 25.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.obj_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.obj_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.hci_nrot = 30; % number of orientations +input_multem.hci_theta = 3.0; % Precession angle (degrees) + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); +for i=1:length(output_multem.data) + imagesc(output_multem.data(i).m2psi_tot); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); + axis image; + colormap gray; + pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_HRTEM.m b/mex_examples_multem/example_MULTEM_HRTEM.m old mode 100644 new mode 100755 index 4bd7a5c5..ccfd8098 --- a/mex_examples_multem/example_MULTEM_HRTEM.m +++ b/mex_examples_multem/example_MULTEM_HRTEM.m @@ -1,104 +1,108 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% High resolution transmission electron microscopy (HRTEM) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 32; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 16; nb = 16; nc = 20; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% - -input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 20; % Defocus (�) -input_multem.obj_lens_c_30 = 0.04; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.obj_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.obj_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation -input_multem.obj_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.obj_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.obj_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -figure(1); -for i=1:length(output_multislice.data) - imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); - axis image; - colormap gray; - pause(0.25); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% High resolution transmission electron microscopy (HRTEM) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 32; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 16;nb = 16;nc = 20;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation +input_multem.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 20; % Defocus (Å) +input_multem.obj_lens_c_30 = 0.04; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.obj_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.obj_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define + + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); +for i=1:length(output_multem.data) + imagesc(output_multem.data(i).m2psi_tot); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); + axis image; + colormap gray; + pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_ISTEM.m b/mex_examples_multem/example_MULTEM_ISTEM.m old mode 100644 new mode 100755 index e2ea7b57..21b5d7cc --- a/mex_examples_multem/example_MULTEM_ISTEM.m +++ b/mex_examples_multem/example_MULTEM_ISTEM.m @@ -1,130 +1,131 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Imaging scanning transmission electron microscopy (ISTEM) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 12; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 5; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 200; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 15.836; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 0; % Defocus (�) -input_multem.obj_lens_c_30 = 0; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) -%%%%%%%%% defocus spread function %%%%%%%%%%%% -input_multem.obj_lens_ti_sigma = 0; % standard deviation (�) -input_multem.obj_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.scanning_type = 2; % eST_Line = 1, eST_Area = 2 -input_multem.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) -input_multem.scanning_ns = 10; -input_multem.scanning_x0 = 3*a; -input_multem.scanning_y0 = 3*b; -input_multem.scanning_xe = 4*a; -input_multem.scanning_ye = 4*b; - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -figure(1); -for i=1:length(output_multislice.data) - imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); - axis image; - colormap gray; - pause(0.25); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Imaging scanning transmission electron microscopy (ISTEM) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 12; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 5;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 200; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 15.836; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 0; % Defocus (Å) +input_multem.obj_lens_c_30 = 0; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) +%%%%%%%%% defocus spread function %%%%%%%%%%%% +input_multem.obj_lens_tp_inc_sigma = 0; % standard deviation (Å) +input_multem.obj_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.scan_pat_typ = 2; % eST_Line = 1, eST_Area = 2 +input_multem.scan_pat_pbc = 1; % 1: true, 0:false (periodic boundary conditions) +input_multem.scan_pat_nsp = 10; +input_multem.scan_pat_r_0 = [3*a;3*b]; % starting point (Å) +input_multem.scan_pat_r_e = [4*a;4*b]; % final point (Å) + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); +for i=1:length(output_multem.data) + imagesc(output_multem.data(i).m2psi_tot); + title(strcat('Total intensity - Thick = ', num2str(output_multem.thick(i)))); + axis image; + colormap gray; + pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_PED.m b/mex_examples_multem/example_MULTEM_PED.m old mode 100644 new mode 100755 index b7e84968..96a706cf --- a/mex_examples_multem/example_MULTEM_PED.m +++ b/mex_examples_multem/example_MULTEM_PED.m @@ -1,101 +1,102 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% -% Precession electron diffraction (PED) simulation -% -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 41; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 16; nb = 16; nc = 30; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c:c:1000; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation -input_multem.obj_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.obj_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%%%% aperture radius %%%%%%%%%%%%%%%%% -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PED %%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.ped_nrot = 30; % number of orientations -input_multem.ped_theta = 3.0; % Precession angle (degrees) - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -c = 1e7; -figure(1); -for i=1:length(output_multislice.data) - m2psi_tot = output_multislice.data(i).m2psi_tot; - m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); - - I_min = min(m2psi_tot(:)); - I_max = max(m2psi_tot(:)); - - imagesc(output_multislice.x, output_multislice.y, m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(i))); - axis image; - colormap gray; - pause(0.5); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Precession electron diffraction (PED) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 41; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 16;nb = 16;nc = 30;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_mrad_2_sigma(input_multem.E_0, 0.02); % mrad to standard deviation +input_multem.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% aperture radius %%%%%%%%%%%%%%%%% +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%PED %%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.ped_nrot = 30; % number of orientations +input_multem.ped_theta = 3.0; % Precession angle (degrees) + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +c = 1e7; +figure(1); +for i=1:length(output_multem.data) + m2psi_tot = output_multem.data(i).m2psi_tot; + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); + + I_min = min(m2psi_tot(:)); + I_max = max(m2psi_tot(:)); + + imagesc(output_multem.x, output_multem.y, m2psi_tot, [I_min I_max]); + title(strcat('Total intensity - Thick = ', num2str(i))); + axis image; + colormap gray; + pause(0.5); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_STEM.m b/mex_examples_multem/example_MULTEM_STEM.m old mode 100644 new mode 100755 index 484899c0..65433dc0 --- a/mex_examples_multem/example_MULTEM_STEM.m +++ b/mex_examples_multem/example_MULTEM_STEM.m @@ -1,127 +1,124 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Scanning transmission electron microscopy (STEM) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 11; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 5; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au110_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c/2:c:1000; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 512; -input_multem.ny = 512; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 14.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (Ã…) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Ã…^-1); otherwise (Ã…) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_azm_npts = 12; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.scanning_type = 2; % eST_Line = 1, eST_Area = 2 -input_multem.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) -input_multem.scanning_square_pxs = 0; % 0: false, 1: true -input_multem.scanning_ns = 20; -input_multem.scanning_x0 = 3*a; -input_multem.scanning_y0 = 3*b; -input_multem.scanning_xe = 4*a; -input_multem.scanning_ye = 4*b; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Detector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.detector.type = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 -input_multem.detector.cir(1).inner_ang = 40; % Inner angle(mrad) -input_multem.detector.cir(1).outer_ang = 160; % Outer angle(mrad) -input_multem.detector.cir(2).inner_ang = 80; % Inner angle(mrad) -input_multem.detector.cir(2).outer_ang = 160; % Outer angle(mrad) - -%%%%%%%%%%%%%%%%%%%%%%%%%% run multem %%%%%%%%%%%%%%%%%%%%%%%%%% -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; -output_multislice - -figure(1); -for i=1:length(output_multislice.data) - ndet = length(input_multem.detector.cir); - for j=1:ndet - subplot(1, ndet, j); - imagesc(output_multislice.data(i).image_tot(j).image); - title(strcat('Thk = ', num2str(i), ', det = ', num2str(output_multislice.thick(j)))); - axis image; - colormap jet; - end - pause(0.5); -end +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% Scanning transmission electron microscopy (STEM) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = [0, 0]; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 11; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 5;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = c/2:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 14.0312; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multem.cond_lens_spt_inc_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.scan_pat_typ = 2; % eST_Line = 1, eST_Area = 2 +input_multem.scan_pat_pbc = 1; % 1: true, 0:false (periodic boundary conditions) +input_multem.scan_pat_nsp = 20; +input_multem.scan_pat_r_0 = [3*a;3*b]; % starting point (Å) +input_multem.scan_pat_r_e = [4*a;4*b]; % final point (Å) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Detector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.detector.typ = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 +input_multem.detector.cir(1).inner_ang = 40; % Inner angle(mrad) +input_multem.detector.cir(1).outer_ang = 160; % Outer angle(mrad) +input_multem.detector.cir(2).inner_ang = 80; % Inner angle(mrad) +input_multem.detector.cir(2).outer_ang = 160; % Outer angle(mrad) + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); +for i=1:length(output_multem.data) + ndet = length(input_multem.detector.cir); + for j=1:ndet + subplot(1, ndet, j); + imagesc(output_multem.data(i).image_tot(j).image); + title(strcat('Thk = ', num2str(i), ', det = ', num2str(output_multem.thick(j)))); + axis image; + colormap jet; + end + pause(0.25); +end diff --git a/mex_examples_multem/example_MULTEM_STEM_EELS.m b/mex_examples_multem/example_MULTEM_STEM_EELS.m old mode 100644 new mode 100755 index 5f042c2b..695e03f9 --- a/mex_examples_multem/example_MULTEM_STEM_EELS.m +++ b/mex_examples_multem/example_MULTEM_STEM_EELS.m @@ -1,143 +1,136 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% STEM electron energy loss spectroscopy (EELS) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 1; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 61; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 5; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = 0; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 1024; -input_multem.ny = 1024; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = -14.03; % Defocus (�) -input_multem.cond_lens_c_30 = 0.01; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.obj_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.obj_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -%%%%%%%%%%%%%%%%%%%%%%%%%% scanning area %%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.scanning_type = 1; % eST_Line = 1, eST_Area = 2 -input_multem.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) -input_multem.scanning_ns = 10; % number of sampling points -input_multem.scanning_x0 = 2*a; % x-starting point (�) -input_multem.scanning_y0 = 2.5*b; % y-starting point (�) -input_multem.scanning_xe = 3*a; % x-final point (�) -input_multem.scanning_ye = 2.5*b; % y-final point (�) - -input_multem.eels_E_loss = 532; % Energy loss (eV) -input_multem.eels_m_selection = 3; % selection rule -input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 -input_multem.eels_collection_angle = 100; % Collection half angle (mrad) -input_multem.eels_Z = 8; % atomic type - -input_multem.eels_E_loss = 456; % Energy loss (eV) -input_multem.eels_m_selection = 3; % selection rule -input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 -input_multem.eels_collection_angle = 100; % Collection half angle (mrad) -input_multem.eels_Z = 22; % atomic type - -% input_multem.eels_E_loss = 1940; % Energy loss (eV) -% input_multem.eels_m_selection = 3; % selection rule -% input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 -% input_multem.eels_collection_angle = 100; % Collection half angle (mrad) -% input_multem.eels_Z = 38; % atomic type - -% ilm_ilm_show_crystal(1, input_multem.spec_atoms); - -%%%%%%%%% find all atoms with Z = 22 %%%%%%%%%% -ii = find(input_multem.spec_atoms(:, 1)==22); -n_ii = length(ii); -%%%%%% do not include some Z(22) atoms %%%%%%%% -ii_s = ii(randperm(n_ii, round(0.1*n_ii))); -input_multem.spec_atoms(ii_s, 1) = 1000+ input_multem.spec_atoms(ii_s, 1); - -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -figure(1); clf; -for i=1:length(output_multislice.data) - plot(output_multislice.data(i).image_tot(1).image); - title(strcat('Thk = ', num2str(output_multislice.thick(i)))); - pause(0.25); +% output_multem = ilc_multem(system_config, input_multem) perform TEM simulation +% +% STEM electron energy loss spectroscopy (EELS) simulation +% +% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() +% +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multem = ilm_dflt_input_multem(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 61; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8;nb = 8;nc = 5;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); + +%%%%%%%%%%%%%%%%%%%%%% specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.nx = 1024; +input_multem.ny = 1024; +input_multem.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.illum_mod = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 88.7414; % Defocus (Å) +input_multem.cond_lens_c_30 = 0.04; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multem.cond_lens_tp_inc_sigma = dsf_sigma; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 5; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multem.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illum_mod=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%%%% scanning area %%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.scan_pat_typ = 1; % eST_Line = 1, eST_Area = 2 +input_multem.scan_pat_pbc = 1; % 1: true, 0:false (periodic boundary conditions) +input_multem.scan_pat_nsp = 10; % number of sampling points +input_multem.scan_pat_r_0 = [2*a;2.5*b]; % starting point (Å) +input_multem.scan_pat_r_e = [3*a;2.5*b]; % final point (Å) + +input_multem.eels_E_loss = 532; % Energy loss (eV) +input_multem.eels_m_selection = 3; % selection rule +input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eels_collection_angle = 100; % Collection half angle (mrad) +input_multem.eels_Z = 8; % atomic type + +input_multem.eels_E_loss = 456; % Energy loss (eV) +input_multem.eels_m_selection = 3; % selection rule +input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eels_collection_angle = 100; % Collection half angle (mrad) +input_multem.eels_Z = 22; % atomic type + +input_multem.eels_E_loss = 1940; % Energy loss (eV) +input_multem.eels_m_selection = 3; % selection rule +input_multem.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 +input_multem.eels_collection_angle = 100; % Collection half angle (mrad) +input_multem.eels_Z = 38; % atomic type + +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +figure(1); clf; +for i=1:length(output_multem.data) + plot(output_multem.data(i).image_tot(1).image); + title(strcat('Thk = ', num2str(output_multem.thick(i)))); + pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_add_amorphous_layer.m b/mex_examples_multem/example_add_amorphous_layer.m deleted file mode 100644 index 51a65565..00000000 --- a/mex_examples_multem/example_add_amorphous_layer.m +++ /dev/null @@ -1,40 +0,0 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -na = 20; nb = 20; nc = 30; ncu = 2; rmsd_3d = 0.085; - -[atoms, lx, ly, ~, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -lz = 20; -Z = 6; -rms_3d = 0.09; -d_min = 1.4; -seed = 1983; -rho = 2.2; -lay_pos = 1; %1: top, 2: bottom - -tic; -atoms = ilc_add_amorp_lay(atoms, lx, ly, lz, d_min, Z, rms_3d, rho, lay_pos, seed); -toc; - -ilm_show_crystal(1, atoms) -view([1 0 0]) -zlim([min(atoms(:, 4)), max(atoms(:, 4))]) - -disp([lx, ly]) -disp([min(atoms(:, 2)), max(atoms(:, 2))]) -disp([min(atoms(:, 3)), max(atoms(:, 3))]) -disp([min(atoms(:, 4)), max(atoms(:,4))]) - -% atoms(:, 4) = atoms(:, 4)-min(atoms(:, 4)); -% save_atomic_position_pdb('amorphous.pdb', atoms, a, b, c, 90, 90, 90); - -figure(2); clf; -tic; -[r, rdf] = ilc_rdf_3d(atoms, 8, 200); -toc; -plot(r, rdf,'-+r'); \ No newline at end of file diff --git a/mex_examples_multem/example_amorp_build.m b/mex_examples_multem/example_amorp_build.m new file mode 100755 index 00000000..49bcec3b --- /dev/null +++ b/mex_examples_multem/example_amorp_build.m @@ -0,0 +1,43 @@ +clear; clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +bs = [50, 50, 50]; + +Z = 6; +rms_3d = 0.09; +occ = 1.0; +tag = 0; +d_min = 1.4; +rho = 2.2; +seed = 1983; + +tic; +atoms = ilc_amorp_build(Z, rms_3d, occ, tag, bs, d_min, rho, seed); +toc; + +disp(size(atoms)) +figure(1); clf; +plot3(atoms(:, 2), atoms(:, 3), atoms(:, 4), '.r'); +axis equal; + +NA = 6.022140857e+23; + +d = 0; +lx0 = bs(1)-d; +ly0 = bs(2)-d; +lz0 = bs(3); +ii = find((0.5*d<=atoms(:, 2)) & (atoms(:, 2)<=bs(1)-0.5*d) & (0.5*d<=atoms(:, 3)) & (atoms(:, 3)<=bs(2)-0.5*d)); +% atoms = atoms(ii, :); +density = length(atoms)*12.011/(lx0*ly0*lz0*NA*(1e-8)^3); + +disp([rho, density]) +tic; +[r, rdf] = ilc_rdf(atoms(:, 2:4), 8, 200); +toc; + + +figure(2);clf; +plot(r, rdf, '-+r'); \ No newline at end of file diff --git a/mex_examples_multem/example_amorp_lay_add.m b/mex_examples_multem/example_amorp_lay_add.m new file mode 100755 index 00000000..6a702548 --- /dev/null +++ b/mex_examples_multem/example_amorp_lay_add.m @@ -0,0 +1,51 @@ +clear; clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +na = 10; nb = 10; nc = 20; ncu = 2;rmsd_3d = 0.085; + +[atoms, lx, ly, lz, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); +% ilm_show_xtl(1, atoms) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +bs = [lx, ly, 30]; + +Z = 6; +rms_3d = 0.09; +occ = 1.0; +tag = 0; +d_min = 1.4; +rho = 2.2; +lay_pos = 21; %1: top, 2: bottom +seed = 1983; + +tic; +atoms = ilc_amorp_lay_add(atoms(:, 1:5), Z, rms_3d, occ, tag, bs, d_min, rho, lay_pos, seed); +toc; + +ilm_show_xtl(1, atoms) +view([1 0 0]) +zlim([min(atoms(:, 4)), max(atoms(:, 4))]) + +disp([lx, ly]) +disp([min(atoms(:, 2)), max(atoms(:, 2))]) +disp([min(atoms(:, 3)), max(atoms(:, 3))]) +disp([min(atoms(:, 4)), max(atoms(:, 4))]) + +nbins = round((max(atoms(:, 4))-min(atoms(:, 4)))/0.1); +tic; +[x, y] = ilc_hist(atoms(:, 4), nbins); +toc; + +atoms(:, 4) = atoms(:, 4)-min(atoms(:, 4)); +% ilm_write_ap_pdb('amorphous.pdb', atoms, a, b, c, 90, 90, 90); + +figure(2); clf; +subplot(1, 2, 1); +plot(x, y, '-r'); +tic; +[r, rdf] = ilc_rdf(atoms(:, 2:4), 8, 200); +toc; +subplot(1, 2, 2); +plot(r, rdf, '-+r'); \ No newline at end of file diff --git a/mex_examples_multem/example_amorphous_specimen.m b/mex_examples_multem/example_amorphous_specimen.m deleted file mode 100644 index 8c8c1962..00000000 --- a/mex_examples_multem/example_amorphous_specimen.m +++ /dev/null @@ -1,44 +0,0 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - - -lx = 50; -ly = 50; -lz = 20; -Z = 6; -rms_3d = 0.09; -d_min = 1.4; -seed = 1983; -rho = 2.2; - -tic; -atoms = ilc_amorp_spec(lx, ly, lz, d_min, Z, rms_3d, rho, seed); -toc; - -% path = strcat('input_spec\Si_',num2str(lx), 'x', num2str(ly), 'x', num2str(lz), '_', num2str(seed), '.mat'); -% save(path, 'atoms'); -% disp([iseed, lz]); -figure(1); clf; -plot3(atoms(:, 2), atoms(:, 3), atoms(:, 4),'.r'); -axis equal; - -NA = 6.022140857e+23; - -d = 0; -lx0 = lx-d; -ly0 = ly-d; -lz0 = lz; -ii = find((0.5*d<=atoms(:,2))&(atoms(:,2)<=lx-0.5*d)&(0.5*d<=atoms(:,3))&(atoms(:,3)<=ly-0.5*d)); -% atoms = atoms(ii, :); -density = length(atoms)*12.011/(lx0*ly0*lz0*NA*(1e-8)^3) - -tic; -[r, rdf] = ilc_rdf_3d(atoms, 8, 200); -toc; - -figure(2); clf; -plot(r, rdf,'-+r'); \ No newline at end of file diff --git a/mex_examples_multem/example_apply_ctf.m b/mex_examples_multem/example_apply_ctf.m deleted file mode 100644 index 9fb33712..00000000 --- a/mex_examples_multem/example_apply_ctf.m +++ /dev/null @@ -1,115 +0,0 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% inclusion of TEM aberrerations into a exitwve simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_dim = 110; -input_multem.pn_seed = 300183; -input_multem.pn_single_conf = 0; % 1: true, 0:false -input_multem.pn_nconf = 5; - -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -input_multem.bwl = 0; - -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -na = 4; nb = 4; nc = 10; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.nx = 1024; -input_multem.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 15.836; % Defocus (�) -input_multem.obj_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) -input_multem.obj_lens_ti_sigma = 32; % standard deviation (�) -input_multem.obj_lens_ti_npts = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; -clear ilc_multem; -tic; -output_multislice_0 = input_multem.ilc_multem; -toc; - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 32; -clear ilc_multem; -tic; -output_multislice_1 = input_multem.ilc_multem; -toc; - -%%%%%%%%%%%%%%%%%%%%% apply contrast transfer function %%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = output_multislice_0.data.psi_coh; % user define incident wave -clear ilc_multem; -tic; -output_multislice_2 = input_multem.ilc_apply_ctf; -toc; - -figure(1); -subplot(1, 3, 1); -imagesc(abs(output_multislice_0.data.psi_coh).^2); -title('Total intensity'); -axis image; -colormap gray; - -subplot(1, 3, 2); -imagesc(abs(output_multislice_1.data.m2psi_tot)); -title('Total intensity'); -axis image; -colormap gray; - -subplot(1, 3, 3); -imagesc(abs(output_multislice_2.psi).^2); -title('Total intensity'); -axis image; -colormap gray; \ No newline at end of file diff --git a/mex_examples_multem/example_atomic_info.m b/mex_examples_multem/example_atomic_info.m new file mode 100755 index 00000000..99b19a07 --- /dev/null +++ b/mex_examples_multem/example_atomic_info.m @@ -0,0 +1,67 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +% S = ilc_atomic_info(pot_parm_typ) get atomic properties +% +% Pot_Par is an integer number which is link to the atomic potential parameterization + +% 1: Doyle_0_4 +% 2: Peng_0_4 +% 3: Peng_0_12 +% 4: Kirkland_0_12 +% 5: Weickenmeier_0_12 +% 6: Lobato_0_12 +% +% outputs: +% name % atom name +% Z % atomic number +% A % mass number +% m % atomic mass +% rn % experimental nuclear radius (Angs.) +% ra % experimental atomic radius (Angs.) +% eels_maj_edg % major eels edges +% eels_min_edg % minor eels edges +% feg % electron scattering factor coefficients +% fxg % x-ray scattering factor coefficients +% pr % electron density coefficients +% vr % potential coefficients +% vzp % projected potential coefficients +% +% Copyright 2021 Ivan Lobato + +clear;clc; +pot_parm_typ = 6; +tic; +S = ilc_atomic_info(pot_parm_typ); +toc; + +k = 79;cc = '-+r'; +S(k).coef(1).feg +S(k).coef(1).fxg +S(k).coef(1).pr +S(k).coef(1).vr +S(k).coef(1).vzp + +S + +figure(1); clf; +Z = (1:103)'; +y = zeros(size(Z)); +for i = 1:5 + hold on; + subplot(2, 3, i); + for j = 1:103 + y(j) = S(j).coef(1).feg.cnl(i); + end + plot(Z, y, '-*r'); + set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); + title('Non-Lineal coeeficients'); + ylabel(strcat('cnl[', num2str(i), ']'), 'FontSize', 14); + xlabel('Z', 'FontSize', 12); + xlim([1 103]); + legend(strcat('cnl[', num2str(i), ']')); + set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); +end \ No newline at end of file diff --git a/mex_examples_multem/example_atomic_radius.m b/mex_examples_multem/example_atomic_radius.m new file mode 100755 index 00000000..34386603 --- /dev/null +++ b/mex_examples_multem/example_atomic_radius.m @@ -0,0 +1,47 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +% r = ilc_atomic_radius(Pot_Par, dim, Vrl) calculates the atomic radius +% +% Pot_Par is an integer number which is link to the atomic potential parameterization +% +% 1: Doyle_0_4 +% 2: Peng_0_4 +% 3: Peng_0_12 +% 4: Kirkland_0_12 +% 5: Weickenmeier_0_12 +% 6: Lobato_0_12 +% +% dim is the dimension with possible values 2 and 3 +% +% Vrl is the atomic potential threshold in eV +% +% r(:, 1) = integral {r^2 V(r)dr} / integral{V(r)dr} +% r(:, 2) are calculated by solving the equation V(r) = Vrl +% r(:, 3) are the experimental values +% +% Copyright 2021 Ivan Lobato + +clear; clc; +dim = 3; +Vrl = 0.01; +pot_parm_typ = 6; +z = 1:103; +tic; +r = ilc_atomic_radius(pot_parm_typ, dim, Vrl); +toc; + +figure(1); clf; + +plot(z, r(:, 1), '-*r', z, r(:, 2), '-*b', z, r(:, 3), '-*k'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Atomic radius'); +ylabel('$\mathrm{radius}$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +axis([1 103 0 1.1*max(r(:))]); +legend('rms', 'Cut-off', 'Experimental'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_beam_self_interaction.m b/mex_examples_multem/example_beam_self_interaction.m old mode 100644 new mode 100755 index e7f81853..5f2ceada --- a/mex_examples_multem/example_beam_self_interaction.m +++ b/mex_examples_multem/example_beam_self_interaction.m @@ -1,129 +1,125 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -input_multem.E_0 = 200; % Acceleration Voltage (keV) -input_multem.theta = 0.00; -input_multem.phi = 0.0; - -input_multem.spec_lx = 20; -input_multem.spec_ly = 20; - -input_multem.nx = 1024; -input_multem.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = 0.0; % x position -input_multem.iw_y = 0.0; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 0; % Defocus (�) -input_multem.cond_lens_c_30 = 0.002; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multem.cond_lens_ti_sigma = 32; % standard deviation (�) -input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 - -input_multem.iw_x = 0.5*input_multem.spec_lx; -input_multem.iw_y = 0.5*input_multem.spec_ly; - -ax = 0:input_multem.spec_lx/input_multem.nx:input_multem.spec_lx; -ay = 0:input_multem.spec_ly/input_multem.ny:input_multem.spec_ly; - -df0 = ilc_scherzer_defocus(input_multem.E_0, input_multem.cond_lens_c_30); - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%% simulation box size %%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.spec_lx = 20; -input_multem.spec_ly = 20; -input_multem.iw_x = 0.5*input_multem.spec_lx; -input_multem.iw_y = 0.5*input_multem.spec_ly; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%The incoming beam at Scherzer defocus at z=0 %%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_c_10 = df0; -output_incident_wave = input_multem.ilc_incident_wave; -psi_i = output_incident_wave.psi_0; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% The incoming beam at Scherzer defocus after traveling a thickness(z=thk) % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -thk = 250; -input_multem.cond_lens_c_10 = (df0+thk); -output_incident_wave = input_multem.ilc_incident_wave; -psi_o = output_incident_wave.psi_0; - - -figure(1); -subplot(1, 2, 1); -imagesc(ax, ay, abs(psi_i).^2); -title(['intensity - df = ', num2str(df0)]); -axis image; -colormap gray; -subplot(1, 2, 2); -imagesc(ax, ay, abs(psi_o).^2); -title(['intensity - df = ', num2str(df0+thk)]); -axis image; -colormap gray; -pause(0.5); - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%% simulation box size %%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.spec_lx = 50; -input_multem.spec_ly = 50; -input_multem.iw_x = 0.5*input_multem.spec_lx; -input_multem.iw_y = 0.5*input_multem.spec_ly; -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%The incoming beam at Scherzer defocus at z=0 %%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_c_10 = df0; -output_incident_wave = input_multem.ilc_incident_wave; -psi_i = output_incident_wave.psi_0; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% The incoming beam at Scherzer defocus after traveling a thickness(z=thk) % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -thk = 250; -input_multem.cond_lens_c_10 = (df0+thk); -output_incident_wave = input_multem.ilc_incident_wave; -psi_o = output_incident_wave.psi_0; - - -figure(2); -subplot(1, 2, 1); -imagesc(ax, ay, abs(psi_i).^2); -title(['intensity - df = ', num2str(df0)]); -axis image; -colormap gray; -subplot(1, 2, 2); -imagesc(ax, ay, abs(psi_o).^2); -title(['intensity - df = ', num2str(df0+thk)]); -axis image; -colormap gray; +clear; clc; +addpath([fileparts(pwd) filesep 'mex_bin']) +addpath([fileparts(pwd) filesep 'crystalline_materials']) +addpath([fileparts(pwd) filesep 'matlab_functions']) + + +input_multem = multem_default_values(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_nthread = 4; +system_config.gpu_device = 0; + +input_multem.E_0 = 200; % Acceleration Voltage (keV) +input_multem.theta = 0.00; +input_multem.phi = 0.0; + +input_multem.spec_lx = 20; +input_multem.spec_ly = 20; + +input_multem.nx = 1024; +input_multem.ny = 1024; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave +input_multem.iw_x = 0.0; % x position +input_multem.iw_y = 0.0; % y position + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 0; % Defocus (Å) +input_multem.cond_lens_c_30 = 0.002; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_ti_sigma = 32; % standard deviation (Å) +input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illum_mod=4 + +input_multem.iw_x = 0.5*input_multem.spec_lx; +input_multem.iw_y = 0.5*input_multem.spec_ly; + +ax = 0:input_multem.spec_lx/input_multem.nx:input_multem.spec_lx; +ay = 0:input_multem.spec_ly/input_multem.ny:input_multem.spec_ly; + +df0 = ilc_scherzer_defocus(input_multem.E_0, input_multem.cond_lens_c_30); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%% simulation box size %%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_lx = 20; +input_multem.spec_ly = 20; +input_multem.iw_x = 0.5*input_multem.spec_lx; +input_multem.iw_y = 0.5*input_multem.spec_ly; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%The incoming beam at Scherzer defocus at z=0 %%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_c_10 = df0; +output_incident_wave = ilc_incident_wave(system_config, input_multem); +psi_i = output_incident_wave.psi_0; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The incoming beam at Scherzer defocus after traveling a thickness(z=thk) % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +thk = 250; +input_multem.cond_lens_c_10 = (df0+thk); +output_incident_wave = ilc_incident_wave(system_config, input_multem); +psi_o = output_incident_wave.psi_0; + + +figure(1); +subplot(1, 2, 1); +imagesc(ax, ay, abs(psi_i).^2); +title(['intensity - df = ', num2str(df0)]); +axis image; +colormap gray; +subplot(1, 2, 2); +imagesc(ax, ay, abs(psi_o).^2); +title(['intensity - df = ', num2str(df0+thk)]); +axis image; +colormap gray; +pause(0.5); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%% simulation box size %%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_lx = 50; +input_multem.spec_ly = 50; +input_multem.iw_x = 0.5*input_multem.spec_lx; +input_multem.iw_y = 0.5*input_multem.spec_ly; +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%The incoming beam at Scherzer defocus at z=0 %%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_c_10 = df0; +output_incident_wave = ilc_incident_wave(system_config, input_multem); +psi_i = output_incident_wave.psi_0; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The incoming beam at Scherzer defocus after traveling a thickness(z=thk) % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +thk = 250; +input_multem.cond_lens_c_10 = (df0+thk); +output_incident_wave = ilc_incident_wave(system_config, input_multem); +psi_o = output_incident_wave.psi_0; + + +figure(2); +subplot(1, 2, 1); +imagesc(ax, ay, abs(psi_i).^2); +title(['intensity - df = ', num2str(df0)]); +axis image; +colormap gray; +subplot(1, 2, 2); +imagesc(ax, ay, abs(psi_o).^2); +title(['intensity - df = ', num2str(df0+thk)]); +axis image; +colormap gray; pause(0.5); \ No newline at end of file diff --git a/mex_examples_multem/example_check_STEM_input.m b/mex_examples_multem/example_check_STEM_input.m old mode 100644 new mode 100755 index 21d2afb6..f90ce1a1 --- a/mex_examples_multem/example_check_STEM_input.m +++ b/mex_examples_multem/example_check_STEM_input.m @@ -8,40 +8,40 @@ probe_size = 10; %%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%%%%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; +input_multem = multem_default_values(); % Load default values; %%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 12; -input_multem.system_conf.gpu_device = 0; +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_nthread = 12; +system_config.gpu_device = 0; %%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 11; +input_multem.em_sim_typ = 11; %%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 +%%%%%%%%%%%%%%%%%%%%%%% specimen slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 3; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 100183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%% atomic vibrations model %%%%%%%%%%%%%%%%%% +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_coh_contrib = 0; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 3; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 100183; % Random seed(frozen phonon) -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%% specimen information %%%%%%%%%%%%%%%%%%%%%%% rmsd_3d = 0.0697; [atoms, lx, ly, lz] = ilm_read_ap_xyz('Pt_twin.xyz', rmsd_3d); -atoms = ilm_center_spec(atoms, lx, ly, lz); +atoms = center_spec(atoms, lx, ly, lz); % centre point p0 = [lx/2 ly/2 0]; @@ -50,7 +50,7 @@ b_crop = atoms(:,2) < (p0(1)-(lx_c/2)) | atoms(:,2) > (p0(1)+(lx_c/2)) | atoms(:,3) < (p0(2)-(lx_c/2)) | atoms(:,3) > (p0(2)+(lx_c/2)); atoms(b_crop,:) = []; -atoms = ilm_center_spec(atoms, lx_c, lx_c, lz); +atoms = center_spec(atoms, lx_c, lx_c, lz); lx = lx_c; ly = lx_c; @@ -68,14 +68,14 @@ input_multem.ny = ny; input_multem.bwl = 0; % Band-width limit, 1: true, 0:false -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%% microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% input_multem.E_0 = 300; % Acceleration Voltage (keV) input_multem.theta = 0.0; % Till ilumination (�) input_multem.phi = 0.0; % Till ilumination (�) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial +input_multem.illum_mod = 1; % 1: coherente mode, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% input_multem.cond_lens_m = 0; % Vortex momentum @@ -90,21 +90,21 @@ input_multem.cond_lens_outer_aper_ang = 21.1; % Outer aperture (mrad) %%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.scanning_type = 2; % eST_Line = 1, eST_Area = 2 -input_multem.scanning_periodic = 0; % 1: true, 0:false (periodic boundary conditions) -input_multem.scanning_ns = ceil(scan_field/dx); +input_multem.scan_pat_typ = 2; % eST_Line = 1, eST_Area = 2 +input_multem.scan_pat_pbc = 0; % 1: true, 0:false (periodic boundary conditions) +input_multem.scan_pat_nsp = ceil(scan_field/dx); input_multem.scanning_x0 = (lx-scan_field)/2; input_multem.scanning_y0 = (ly-scan_field)/2; input_multem.scanning_xe = (lx+scan_field)/2; input_multem.scanning_ye = (ly+scan_field)/2; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Detector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.detector.type = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 +input_multem.detector.typ = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 input_multem.detector.cir(1).inner_ang = 60; % Inner angle(mrad) input_multem.detector.cir(1).outer_ang = 190; % Outer angle(mrad) @@ -115,7 +115,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Run %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % clear ilc_multem; % tic; -% output_multislice = input_multem.ilc_multem; +% output_multislice = ilc_multem(system_config, input_multem); % toc; diff --git a/mex_examples_multem/example_crystal_by_layers.m b/mex_examples_multem/example_crystal_by_layers.m deleted file mode 100644 index 94fe76c1..00000000 --- a/mex_examples_multem/example_crystal_by_layers.m +++ /dev/null @@ -1,35 +0,0 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -xtl_parm.na = 10; -xtl_parm.nb = 10; -xtl_parm.nc = 10; -xtl_parm.a = 4.0780; -xtl_parm.b = 4.0780; -xtl_parm.c = 4.0780; -xtl_parm.nuLayer = 2; -occ = 1; -region = 0; -charge = 0; -% Au = 79 -%Z x y z sigma occupancy -rmsd_3d = 0.085; -xtl_parm.uLayer(1).atoms = [79, 0.0, 0.0, 0.0, rmsd_3d, occ, region, charge; 79, 0.5, 0.5, 0.0, rmsd_3d, occ, region, charge]; -xtl_parm.uLayer(2).atoms = [79, 0.0, 0.5, 0.5, rmsd_3d, occ, region, charge; 79, 0.5, 0.0, 0.5, rmsd_3d, occ, region, charge]; - -tic; -Crys3D = ilc_crystal_by_lays(xtl_parm); -toc; - -na = 1; -nb = 1; -nc = 1; -[Crys3D, lx, ly, lz, a, b, c, dz] = SrTiO3001_xtl(na, nb, nc, 2, 0.085); -[lx, ly] -% show crystal -clf; -ilm_show_crystal(1, Crys3D); \ No newline at end of file diff --git a/mex_examples_multem/example_det_min_sampling.m b/mex_examples_multem/example_det_min_sampling.m new file mode 100755 index 00000000..9f2ba64e --- /dev/null +++ b/mex_examples_multem/example_det_min_sampling.m @@ -0,0 +1,14 @@ +% Copyright 2021 Ivan Lobato + +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +E_0 = 300; +bs = [50, 35]; % simulations box size +theta = [80, 100, 120, 200, 215, 250]; % mrad + +% minimun number of pixels to cover the detector +np = ilc_det_min_spl(E_0, bs, theta); +disp(np) \ No newline at end of file diff --git a/mex_examples_multem/example_feg.m b/mex_examples_multem/example_feg.m old mode 100644 new mode 100755 index 8d263ebe..dde3d3b4 --- a/mex_examples_multem/example_feg.m +++ b/mex_examples_multem/example_feg.m @@ -1,43 +1,43 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -Z = 50; -occ = 1; -region = 0; -charge = 0; - -gmin = 0; gmax = 12; ng = 512; -dg = (gmax-gmin)/(ng-1); -g = gmin:dg:gmax; - -[f1, df1] = ilc_feg(1, Z, charge, g); -[f2, df2] = ilc_feg(2, Z, charge, g); -[f3, df3] = ilc_feg(3, Z, charge, g); -[f4, df4] = ilc_feg(4, Z, charge, g); -[f5, df5] = ilc_feg(5, Z, charge, g); -[f6, df6] = ilc_feg(6, Z, charge, g); -figure(1); clf; - -subplot(1, 2, 1); -plot(g, f1, '-k', g, f2, '-b', g, f3, '-c', g, f4, '-m', g, f5, '-r', g, f6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Electron Scattering factor'); -ylabel('$\displaystyle f_e(g)$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{g}$','interpreter','latex','FontSize',12); -xlim([0 gmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -subplot(1, 2, 2); -plot(g, df1, '-k', g, df2, '-b', g, df3, '-c', g, df4, '-m', g, df5, '-r', g, df6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Derivative of the electron Scattering factor'); -ylabel('$\displaystyle \frac{d f_e(g)}{dg}$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{g}$','interpreter','latex','FontSize',12); -xlim([0 gmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -set(gcf,'units','normalized','outerposition',[0 0 1 1]); \ No newline at end of file +% Copyright 2021 Ivan Lobato +clear;clc; +addpath([ fileparts(pwd), filesep, 'mex_bin']) + +Z = 79; +occ = 1; +tag = 0; +charge = 0; + +gmin = 0;gmax = 20;ng = 512; +dg = (gmax-gmin)/(ng-1); +g = gmin:dg:gmax; + +tic; +[f1, df1] = ilc_feg(1, Z, charge, g); +[f2, df2] = ilc_feg(2, Z, charge, g); +[f3, df3] = ilc_feg(3, Z, charge, g); +[f4, df4] = ilc_feg(4, Z, charge, g); +[f5, df5] = ilc_feg(5, Z, charge, g); +[f6, df6] = ilc_feg(6, Z, charge, g); +toc; + +figure(1); clf; + +subplot(1, 2, 1); +plot(g, f1, '-k', g, f2, '-b', g, f3, '-c', g, f4, '-m', g, f5, '-r', g, f6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Electron Scattering factor'); +ylabel('$\displaystyle f_e(g)$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{g}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 gmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +subplot(1, 2, 2); +plot(g, df1, '-k', g, df2, '-b', g, df3, '-c', g, df4, '-m', g, df5, '-r', g, df6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Derivative of the electron Scattering factor'); +ylabel('$\displaystyle \frac{d f_e(g)}{dg}$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{g}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 gmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_fxeg_data.m b/mex_examples_multem/example_fxeg_data.m new file mode 100755 index 00000000..a1d7cad7 --- /dev/null +++ b/mex_examples_multem/example_fxeg_data.m @@ -0,0 +1,27 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath([ fileparts(pwd), filesep, 'mex_bin']) + +Z = 24; dg = 1; +% Load Kirkland X-ray and electron scattering tabulated data +tic; +[g, fxg, feg] = ilc_fxeg_data(Z, dg); +toc; + +a = [3.028317848436913e+00 -9.553939330814323e+01 9.617615623521981e+01 3.597773159579877e-02 3.914928907184223e-04]; +b = [8.359115043146318e+00 1.802637902641032e+00 1.775094889570472e+00 5.481444121431137e-02 3.998289689160348e-03]; +a_0 = 0.52917721077817892; + +feg_p = sum(a.*(2+b.*g.^2)./(1+b.*g.^2).^2, 2); +% feg = (Z-fxg)./(2*pi^2*a_0*g.^2); + +figure(1); clf; +plot(g, feg, '-+r', g, feg_p, '-+b'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Tabulated electron Scattering factor'); +ylabel('$\displaystyle f_e(g)$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{g}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 g(end)]); +legend('Kirkland [0-12]'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_fxg.m b/mex_examples_multem/example_fxg.m old mode 100644 new mode 100755 index 4baaf8d5..e1e38bff --- a/mex_examples_multem/example_fxg.m +++ b/mex_examples_multem/example_fxg.m @@ -1,44 +1,43 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -Z = 49; -occ = 1; -region = 0; -charge = 0; - -gmin = 0; gmax = 20; ng = 512; -dg = (gmax-gmin)/(ng-1); -g = gmin:dg:gmax; - -[f1, df1] = ilc_fxg(1, Z, charge, g); -[f2, df2] = ilc_fxg(2, Z, charge, g); -[f3, df3] = ilc_fxg(3, Z, charge, g); -[f4, df4] = ilc_fxg(4, Z, charge, g); -[f5, df5] = ilc_fxg(5, Z, charge, g); -[f6, df6] = ilc_fxg(6, Z, charge, g); - -figure(1); clf; - -subplot(1, 2, 1); -plot(g, f1, '-k', g, f2, '-b', g, f3, '-c', g, f4, '-m', g, f5, '-r', g, f6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('X-ray Scattering factor'); -ylabel('$\displaystyle f_x(g)$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{g}$','interpreter','latex','FontSize',12); -xlim([0 gmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -subplot(1, 2, 2); -plot(g, df1, '-k', g, df2, '-b', g, df3, '-c', g, df4, '-m', g, df5, '-r', g, df6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Derivative of the X-ray Scattering factor'); -ylabel('$\displaystyle \frac{d f_x(g)}{dg}$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{g}$','interpreter','latex','FontSize',12); -xlim([0 gmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -set(gcf,'units','normalized','outerposition',[0 0 1 1]); \ No newline at end of file +% Copyright 2021 Ivan Lobato +clear;clc; +addpath([ fileparts(pwd), filesep, 'mex_bin']) + +Z = 35; +occ = 1; +tag = 0; +charge = 0; + +gmin = 0;gmax = 10;ng = 512; +dg = (gmax-gmin)/(ng-1); +g = gmin:dg:gmax; + +tic; +[f1, df1] = ilc_fxg(1, Z, charge, g); +[f2, df2] = ilc_fxg(2, Z, charge, g); +[f3, df3] = ilc_fxg(3, Z, charge, g); +[f4, df4] = ilc_fxg(4, Z, charge, g); +[f5, df5] = ilc_fxg(5, Z, charge, g); +[f6, df6] = ilc_fxg(6, Z, charge, g); +toc; + +figure(1); clf; + +subplot(1, 2, 1); +plot(g, f1, '-k', g, f2, '-b', g, f3, '-c', g, f4, '-m', g, f5, '-r', g, f6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('X-ray Scattering factor'); +ylabel('$\displaystyle f_x(g)$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{g}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 gmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +subplot(1, 2, 2); +plot(g, df1, '-k', g, df2, '-b', g, df3, '-c', g, df4, '-m', g, df5, '-r', g, df6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Derivative of the X-ray Scattering factor'); +ylabel('$\displaystyle \frac{d f_x(g)}{dg}$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{g}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 gmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_incident_wave_1.m b/mex_examples_multem/example_incident_wave_1.m old mode 100644 new mode 100755 index dcd9bc4f..988d7f17 --- a/mex_examples_multem/example_incident_wave_1.m +++ b/mex_examples_multem/example_incident_wave_1.m @@ -1,76 +1,73 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Incident wave simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; -input_multem.phi = 0.0; - -input_multem.spec_lx = 20; -input_multem.spec_ly = 20; - -input_multem.nx = 1024; -input_multem.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave -input_multem.iw_x = 0.5*input_multem.spec_lx; % x position -input_multem.iw_y = 0.5*input_multem.spec_ly; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = -150.00; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multem.cond_lens_ti_sigma = 32; % standard deviation (�) -input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -for x = (0.4:0.025:0.6)*input_multem.spec_lx - for y = (0.4:0.025:0.6)*input_multem.spec_ly - input_multem.iw_x = x; - input_multem.iw_y = y; - - tic; - output_incident_wave = input_multem.ilc_incident_wave; - toc; - psi_0 = output_incident_wave.psi_0; - sum(abs(output_incident_wave.psi_0(:)).^2) - figure(2); - subplot(1, 2, 1); - imagesc(abs(psi_0).^2); - title('intensity'); - axis image; - colormap gray; - - subplot(1, 2, 2); - imagesc(angle(psi_0)); - title('phase'); - axis image; - colormap gray; - pause(0.01); - end +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +input_multem.E_0 = 60; % Acceleration Voltage (keV) +input_multem.theta = 0.0; +input_multem.phi = 0.0; + +input_multem.spec_bs_x = 20; +input_multem.spec_bs_y = 20; + +input_multem.nx = 1024; +input_multem.ny = 1024; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 111.50; % Defocus (Å) +input_multem.cond_lens_c_30 = -0.0007; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.6634; % Outer aperture (mrad) +input_multem.cond_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_spt_inc_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 8; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +% for x = (0.5:0.1:0.6)*input_multem.spec_bs_x +% for y = (0.6:0.1:0.8)*input_multem.spec_bs_y +for x = 0.5*input_multem.spec_bs_x + for y = 0.5*input_multem.spec_bs_y + input_multem.beam_pos = [x;y]; + + tic; + output_incident_wave = ilc_incident_wave(system_config, input_multem); + toc; + psi_0 = output_incident_wave.psi_0; + sum(abs(output_incident_wave.psi_0(:)).^2) + figure(2); + subplot(1, 2, 1); + imagesc(abs(psi_0).^2); + title('intensity'); + axis image; + colormap gray; + + subplot(1, 2, 2); + imagesc(angle(psi_0)); + title('phase'); + axis image; + colormap gray; + pause(0.01); + end end \ No newline at end of file diff --git a/mex_examples_multem/example_incident_wave_2.m b/mex_examples_multem/example_incident_wave_2.m old mode 100644 new mode 100755 index a49272eb..013bdab9 --- a/mex_examples_multem/example_incident_wave_2.m +++ b/mex_examples_multem/example_incident_wave_2.m @@ -1,76 +1,69 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Incident wave simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -input_multem.E_0 = 200; % Acceleration Voltage (keV) -input_multem.theta = 0.0; -input_multem.phi = 0.0; - -input_multem.spec_lx = 50; -input_multem.spec_ly = 50; - -input_multem.nx = 1024; -input_multem.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave -input_multem.iw_x = 0.0; % x position -input_multem.iw_y = 0.0; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = -15.836; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multem.cond_lens_ti_sigma = 32; % standard deviation (�) -input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 - -for x = (0.4:0.025:0.6)*input_multem.spec_lx - for y = (0.4:0.025:0.6)*input_multem.spec_ly - - input_multem.iw_x = x; - input_multem.iw_y = y; -% input_multem.iw_x = input_multem.spec_lx/2; -% input_multem.iw_y = input_multem.spec_ly/2; - - tic; - output_incident_wave = input_multem.ilc_incident_wave; - toc; - psi_0 = flipud(output_incident_wave.psi_0); - figure(2); - subplot(1, 2, 1); - imagesc(abs(psi_0).^2); - title('intensity'); - axis image; - colormap gray; - - subplot(1, 2, 2); - imagesc(angle(psi_0)); - title('phase'); - axis image; - colormap gray; - pause(0.1); - end +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 4; +system_config.gpu_device = 0; + +input_multem.E_0 = 200; % Acceleration Voltage (keV) +input_multem.theta = 0.0; +input_multem.phi = 0.0; + +input_multem.spec_bs_x = 50; +input_multem.spec_bs_y = 50; + +input_multem.nx = 1024; +input_multem.ny = 1024; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [0; 0]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = -15.836; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_spt_inc_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 8; % # of integration points. It will be only used if illum_mod=4 + +for x = (0.4:0.025:0.6)*input_multem.spec_bs_x + for y = (0.4:0.025:0.6)*input_multem.spec_bs_y + + input_multem.beam_pos = [x;y]; + + tic; + output_incident_wave = ilc_incident_wave(system_config, input_multem); + toc; + psi_0 = flipud(output_incident_wave.psi_0); + figure(2); + subplot(1, 2, 1); + imagesc(abs(psi_0).^2); + title('intensity'); + axis image; + colormap gray; + + subplot(1, 2, 2); + imagesc(angle(psi_0)); + title('phase'); + axis image; + colormap gray; + pause(0.1); + end end \ No newline at end of file diff --git a/mex_examples_multem/example_incident_wave_3.m b/mex_examples_multem/example_incident_wave_3.m old mode 100644 new mode 100755 index 0f7bfdc9..1daccac6 --- a/mex_examples_multem/example_incident_wave_3.m +++ b/mex_examples_multem/example_incident_wave_3.m @@ -1,82 +1,77 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Incident wave simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -input_multem.E_0 = 120; % Acceleration Voltage (keV) -input_multem.theta = 0.00; -input_multem.phi = 0.0; - -input_multem.spec_lx = 200; -input_multem.spec_ly = 200; - -input_multem.nx = 1120; -input_multem.ny = 1120; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave -sum(abs(input_multem.iw_psi(:)).^2) -input_multem.iw_x = 0.0; % x position -input_multem.iw_y = 0.0; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = -100; % Defocus (�) -input_multem.cond_lens_c_30 = 0.00; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 20; % Outer aperture (mrad) -input_multem.cond_lens_ti_sigma = 32; % standard deviation (�) -input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 - -input_multem.iw_x = 0.5*input_multem.spec_lx; -input_multem.iw_y = 0.5*input_multem.spec_ly; - -df0 = -15.836; -ax = 0:input_multem.spec_lx/input_multem.nx:input_multem.spec_lx; -ay = 0:input_multem.spec_ly/input_multem.ny:input_multem.spec_ly; - -thick = 300; -for df = (df0+thick) -% input_multem.cond_lens_c_10 = df; %Angs - - tic; - output_incident_wave = input_multem.ilc_incident_wave; - toc; - psi_0 = output_incident_wave.psi_0; - sum(abs(psi_0(:)).^2) - - figure(2); - subplot(1, 2, 1); - - imagesc(ax, ay, abs(psi_0).^2); - title(strcat('intensity - df = ', num2str(df))); - axis image; - colormap gray; - - subplot(1, 2, 2); - imagesc(ax, ay, angle(psi_0)); - title(strcat('phase - df = ', num2str(df))); - axis image; - colormap gray; - pause(0.5); +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 1; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 1; +system_config.gpu_device = 0; + +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.00; +input_multem.phi = 0.0; + +input_multem.spec_bs_x = 7*4.078; +input_multem.spec_bs_y = 7*4.078; + +input_multem.nx = 1792; +input_multem.ny = 1792; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave +sum(abs(input_multem.incdt_wav_psi(:)).^2) + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [0; 0]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 0; % Defocus (Å) +input_multem.cond_lens_c_30 = 0.001; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_spt_inc_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 8; % # of integration points. It will be only used if illum_mod=4 + + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +df0 = -15.836; +ax = 0:input_multem.spec_bs_x/input_multem.nx:input_multem.spec_bs_x; +ay = 0:input_multem.spec_bs_y/input_multem.ny:input_multem.spec_bs_y; +for df = 20 + input_multem.cond_lens_c_10 = df; %Angs + + tic; + output_incident_wave = ilc_incident_wave(system_config, input_multem); + toc; + psi_0 = output_incident_wave.psi_0; + sum(abs(psi_0(:)).^2) + + figure(2); + subplot(1, 2, 1); + + imagesc(ax, ay, abs(psi_0).^2); + title(strcat('intensity - df = ', num2str(df))); + axis image; + colormap gray; + + subplot(1, 2, 2); + imagesc(ax, ay, angle(psi_0)); + title(strcat('phase - df = ', num2str(df))); + axis image; + colormap gray; + pause(0.5); end \ No newline at end of file diff --git a/mex_examples_multem/example_incident_wave_4.m b/mex_examples_multem/example_incident_wave_4.m old mode 100644 new mode 100755 index 694f8e3a..3c41a453 --- a/mex_examples_multem/example_incident_wave_4.m +++ b/mex_examples_multem/example_incident_wave_4.m @@ -1,75 +1,69 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Incident wave simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) '/mex_bin']) -addpath([fileparts(pwd) '/crystalline_materials']) -addpath([fileparts(pwd) '/matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; % Number of CPU threads -input_multem.system_conf.gpu_device = 0; % GPU device (i.e. 0, 1, 2, ... ) - -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; -input_multem.phi = 0.0; - -input_multem.nx = 1024; -input_multem.ny = 1024; - -input_multem.spec_lx = 50; -input_multem.spec_ly = 50; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave -input_multem.iw_x = 0.5*input_multem.spec_lx; % x position -input_multem.iw_y = 0.5*input_multem.spec_ly; % y position -input_multem.iw_x = 10+[0, 25, 0, 25]; % x position -input_multem.iw_y = 10+[5, 5, 25, 25]; % y position -% input_multem.iw_x = 10+[0, 25]; % x position -% input_multem.iw_y = 10+[5, 25]; % y position -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = -14.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multem.cond_lens_ti_sigma = 32; % standard deviation (�) -input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; -input_multem.cond_lens_c_10 = ilc_scherzer_defocus(input_multem.E_0, input_multem.cond_lens_c_30); - -input_multem.cond_lens_c_10 = input_multem.cond_lens_c_10; - -tic; -output_incident_wave = input_multem.ilc_incident_wave; -toc; - -psi_0 = flipud(output_incident_wave.psi_0); -figure(1); clf; -subplot(1, 2, 1); -imagesc(output_incident_wave.x, output_incident_wave.y, abs(psi_0).^2); -title('intensity'); -axis image; -colormap gray; - -subplot(1, 2, 2); -imagesc(output_incident_wave.x, output_incident_wave.y, angle(psi_0)); -title('phase'); -axis image; -colormap gray; +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_ncores = 1; % Number of Cores CPU (It will be used in the future) +system_config.cpu_n_thread = 4; % Number of CPU threads +system_config.gpu_device = 0; % GPU device (i.e. 0, 1, 2, ... ) + +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; +input_multem.phi = 0.0; + +input_multem.nx = 1024; +input_multem.ny = 1024; + +input_multem.spec_bs_x = 50; +input_multem.spec_bs_y = 50; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = -14.0312; % Defocus (Å) +input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) +input_multem.cond_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_spt_inc_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 8; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; +input_multem.cond_lens_c_10 = ilc_scherzer_defocus(input_multem.E_0, input_multem.cond_lens_c_30); + +input_multem.cond_lens_c_10 = input_multem.cond_lens_c_10; + +tic; +output_incident_wave = ilc_incident_wave(system_config, input_multem); +toc; + +psi_0 = flipud(output_incident_wave.psi_0); +figure(1); clf; +subplot(1, 2, 1); +imagesc(output_incident_wave.x, output_incident_wave.y, abs(psi_0).^2); +title('intensity'); +axis image; +colormap gray; + +subplot(1, 2, 2); +imagesc(output_incident_wave.x, output_incident_wave.y, angle(psi_0)); +title('phase'); +axis image; +colormap gray; pause(0.2); \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_STEM_matrix_detector.m b/mex_examples_multem/example_matrix_detector.m old mode 100644 new mode 100755 similarity index 62% rename from mex_examples_multem/example_MULTEM_STEM_matrix_detector.m rename to mex_examples_multem/example_matrix_detector.m index b8346378..3bf74188 --- a/mex_examples_multem/example_MULTEM_STEM_matrix_detector.m +++ b/mex_examples_multem/example_matrix_detector.m @@ -1,167 +1,162 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% Scanning transmission electron microscopy (STEM) simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% -input_multem = multem_input.parameters; % Load default values; - -%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 6; -input_multem.system_conf.gpu_device = 0; - -%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 11; - -%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_coh_contrib = 0; -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) - -%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% -na = 8; nb = 8; nc = 5; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = c/2:c:1000; % Array of thickes (�) - -%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.nx = 512; -input_multem.ny = 512; -input_multem.bwl = 0; % Band-width limit, 1: true, 0:false - -%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.illumination_model = 1; % 1: coherente mode, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 14.0312; % Defocus (�) -input_multem.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) - -%%%%%%%%% defocus spread function %%%%%%%%%%%% -dsf_sigma = ilc_iehwgd_2_sigma(32); % from defocus spread to standard deviation -input_multem.cond_lens_ti_sigma = dsf_sigma; % standard deviation (�) -input_multem.cond_lens_ti_npts = 5; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%%% source spread function %%%%%%%%%%%% -ssf_sigma = ilc_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation -input_multem.cond_lens_si_sigma = ssf_sigma; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 4; % # of integration points. It will be only used if illumination_model=4 - -%%%%%%%%% zero defocus reference %%%%%%%%%%%% -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.scanning_type = 2; % eST_Line = 1, eST_Area = 2 -input_multem.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) -input_multem.scanning_ns = 16; -input_multem.scanning_x0 = 3*a; -input_multem.scanning_y0 = 3*b; -input_multem.scanning_xe = 4*a; -input_multem.scanning_ye = 4*b; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Circular Detector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.detector.type = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 -input_multem.detector.cir(1).inner_ang = 40; % Inner angle(mrad) -input_multem.detector.cir(1).outer_ang = 160; % Outer angle(mrad) - -clear ilc_multem; -tic; -output_radial_detector = input_multem.ilc_multem; -toc; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Matrix Detector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% This yields the same detector as the radial detector above, to check -% the consistency of the results - -nxh = input_multem.nx/2; -nyh = input_multem.ny/2; -dgx = 1/input_multem.spec_lx; -dgy = 1/input_multem.spec_ly; - -detector = zeros(input_multem.ny, input_multem.nx); -[gx, gy] = meshgrid((-nxh:1:(nxh-1))*dgx, (-nyh:1:(nyh-1))*dgy); -g = sqrt(gx.^2+gy.^2); - -g_min = ilm_mrad_2_rAng(input_multem.E_0, input_multem.detector.cir(1).inner_ang); -g_max = ilm_mrad_2_rAng(input_multem.E_0, input_multem.detector.cir(1).outer_ang); -detector((g_min<=g)&(g - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_dim = 110; -input_multem.pn_seed = 300183; -input_multem.pn_single_conf = 0; % 1: true, 0:false -input_multem.pn_nconf = 5; - -input_multem.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -input_multem.bwl = 0; - -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (�) -input_multem.phi = 0.0; % Till ilumination (�) - -na = 4; nb = 4; nc = 10; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.nx = 1024; -input_multem.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 15.836; % Defocus (�) -input_multem.obj_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) -input_multem.obj_lens_ti_sigma = 32; % standard deviation (�) -input_multem.obj_lens_ti_npts = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 -input_multem.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; -clear ilc_multem; -tic; -output_multislice_0 = input_multem.ilc_multem; -toc; - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 32; -clear ilc_multem; -tic; -output_multislice_1 = input_multem.ilc_multem; -toc; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = output_multislice_0.data.psi_coh; % user define incident wave -clear ilc_multem; -tic; -output_multislice_2 = input_multem.ilc_microscope_aberrations; -toc; - -figure(1); -subplot(1, 3, 1); -imagesc(abs(output_multislice_0.data.psi_coh).^2); -title('Total intensity'); -axis image; -colormap gray; - -subplot(1, 3, 2); -imagesc(abs(output_multislice_1.data.m2psi_tot)); -title('Total intensity'); -axis image; -colormap gray; - -subplot(1, 3, 3); -imagesc(abs(output_multislice_2.m2psi)); -title('Total intensity'); -axis image; +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 4; +system_config.gpu_device = 0; + +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 52; +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +input_multem.atomic_vib_dim = [true, true, false]; +input_multem.atomic_vib_seed = 300183; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false +input_multem.atomic_vib_nconf = 5; + +input_multem.illum_mod = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +input_multem.bwl = 0; + +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +na = 4;nb = 4;nc = 10;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.nx = 1024; +input_multem.ny = 1024; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_spt_inc_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 15.836; % Defocus (Å) +input_multem.obj_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) +input_multem.obj_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.obj_lens_tp_inc_npts = 10; % # integration steps for the defocus Spread. It will be only used if illum_mod=4 +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; % It will be only used if obj_lens_zero_def_typ = eZDT_User_Define + +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 52; +clear ilc_multem; +tic; +output_multem_0 = ilc_multem(system_config, input_multem); +toc; + +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 32; +clear ilc_multem; +tic; +output_multem_1 = ilc_multem(system_config, input_multem); +toc; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = output_multem_0.data.psi_coh; % user define incident wave +clear ilc_multem; +tic; +output_multem_2 = ilc_microscope_aberrations(system_config, input_multem); +toc; + +figure(1); +subplot(1, 3, 1); +imagesc(abs(output_multem_0.data.psi_coh).^2); +title('Total intensity'); +axis image; +colormap gray; + +subplot(1, 3, 2); +imagesc(output_multem_1.data.m2psi_tot); +title('Total intensity'); +axis image; +colormap gray; + +subplot(1, 3, 3); +imagesc(output_multem_2.m2psi); +title('Total intensity'); +axis image; colormap gray; \ No newline at end of file diff --git a/mex_examples_multem/example_min_max_dist.m b/mex_examples_multem/example_min_max_dist.m new file mode 100755 index 00000000..2e49dc57 --- /dev/null +++ b/mex_examples_multem/example_min_max_dist.m @@ -0,0 +1,24 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +[x, y, z] = meshgrid(0:2:50); +r_3d = [x(:), y(:), z(:)]; +r_3d = r_3d + 0.1*rand(size(r_3d)); +r_3d = double(r_3d); + +tic; +[r, rdf] = ilc_rdf(r_3d, 5, 400); +toc; + +r_min = ilc_min_dist(r_3d); +r_max = ilc_max_dist(r_3d); + +figure(1); clf; +plot(r, rdf, '-k'); +hold on; +plot(r_min, 0.5*max(rdf), 'or') +hold on; +plot(r_max, 0.5*max(rdf), 'or') \ No newline at end of file diff --git a/mex_examples_multem/example_pr.m b/mex_examples_multem/example_pr.m old mode 100644 new mode 100755 index f3bc2f78..09f4ce40 --- a/mex_examples_multem/example_pr.m +++ b/mex_examples_multem/example_pr.m @@ -1,43 +1,42 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -Z = 79; -occ = 1; -region = 0; -charge = 0; - -rmin = 1e-05; rmax = 0.1; nr = 512; -dlnr = log(rmax/rmin)/(nr-1); r = rmin*exp((0:1:(nr-1))*dlnr); - -[f1, df1] = ilc_pr(1, Z, charge, r); -[f2, df2] = ilc_pr(2, Z, charge, r); -[f3, df3] = ilc_pr(3, Z, charge, r); -[f4, df4] = ilc_pr(4, Z, charge, r); -[f5, df5] = ilc_pr(5, Z, charge, r); -[f6, df6] = ilc_pr(6, Z, charge, r); - -figure(1); clf; - -subplot(1, 2, 1); -plot(r, f1, '-k', r, f2, '-b', r, f3, '-c', r, f4, '-m', r, f5, '-r', r, f6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Electron density'); -ylabel('$\displaystyle \rho(r)$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{r}$','interpreter','latex','FontSize',12); -xlim([0 rmax]); ylim([0 max(f6)]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -subplot(1, 2, 2); -plot(r, df1, '-k', r, df2, '-b', r, df3, '-c', r, df4, '-m', r, df5, '-r', r, df6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Derivative of the Electron density'); -ylabel('$\displaystyle \frac{d \rho(r)}{d r}$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{r}$','interpreter','latex','FontSize',12); -xlim([0 rmax]); ylim([min(df6) max(df6)]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -set(gcf,'units','normalized','outerposition',[0 0 1 1]); \ No newline at end of file +% Copyright 2021 Ivan Lobato +clear;clc; +addpath([ fileparts(pwd), filesep, 'mex_bin']) + +Z = 79; +occ = 1; +tag = 0; +charge = 0; + +rmin = 1e-05;rmax = 0.1;nr = 512; +dlnr = log(rmax/rmin)/(nr-1);r = rmin*exp((0:1:(nr-1))*dlnr); + +tic; +[f1, df1] = ilc_pr(1, Z, charge, r); +[f2, df2] = ilc_pr(2, Z, charge, r); +[f3, df3] = ilc_pr(3, Z, charge, r); +[f4, df4] = ilc_pr(4, Z, charge, r); +[f5, df5] = ilc_pr(5, Z, charge, r); +[f6, df6] = ilc_pr(6, Z, charge, r); +toc; + +figure(1); clf; + +subplot(1, 2, 1); +plot(r, f1, '-k', r, f2, '-b', r, f3, '-c', r, f4, '-m', r, f5, '-r', r, f6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Electron density'); +ylabel('$\displaystyle \rho(r)$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 rmax]);ylim([0 max(f6)]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +subplot(1, 2, 2); +plot(r, df1, '-k', r, df2, '-b', r, df3, '-c', r, df4, '-m', r, df5, '-r', r, df6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Derivative of the Electron density'); +ylabel('$\displaystyle \frac{d \rho(r)}{d r}$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 rmax]);ylim([min(df6) max(df6)]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_projected_potential.m b/mex_examples_multem/example_projected_potential.m old mode 100644 new mode 100755 index f2ec68a2..ae7559ef --- a/mex_examples_multem/example_projected_potential.m +++ b/mex_examples_multem/example_projected_potential.m @@ -1,69 +1,64 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 2; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_dim = 111; % phonon dimensions -input_multem.pn_seed = 300183; % Random seed(frozen phonon) -input_multem.pn_single_conf = 1; % 1: true, 0:false -input_multem.pn_nconf = 1; % true: phonon configuration, false: number of frozen phonon configurations - -na = 4; nb = 4; nc = 4; ncu = 2; rmsd_3d = 0.25; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.nx = 2048; -input_multem.ny = 2048; - -clear ilc_spec_slicing; -[atoms, Slice] = ilc_spec_slicing(input_multem.toStruct); - -[natoms,~] = size(atoms); [nslice, ~] = size(Slice); -for islice = 1:nslice - input_multem.islice = islice; - - input_multem.system_conf.device = 1; % eD_CPU = 1, eD_GPU = 2 - input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 - tic; - clear ilc_projected_potential; - ouput_multislice_1 = input_multem.ilc_projected_potential; - toc; - - input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 - input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 - tic; - clear ilc_projected_potential; - ouput_multislice_2 = input_multem.ilc_projected_potential; - toc; - mean(abs(ouput_multislice_1.V(:)-ouput_multislice_2.V(:))) - - figure(1); - subplot(1, 2, 1); - imagesc(ouput_multislice_1.V); - colormap gray; - axis image; - subplot(1, 2, 2); - imagesc(ouput_multislice_2.V); - colormap gray; - axis image; - disp([min(ouput_multislice_1.V(:)), min(ouput_multislice_2.V(:))]) - disp([max(ouput_multislice_1.V(:)), max(ouput_multislice_2.V(:))]) - pause(0.10); - -end +clear;clc; + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 4; +system_config.gpu_device = 0; + +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 2; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +input_multem.atomic_vib_dim = 111; % phonon dimensions +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) +input_multem.atomic_vib_sgl_conf = 1; % 1: true, 0:false +input_multem.atomic_vib_nconf = 1; % true: phonon configuration, false: number of frozen phonon configurations + +na = 4;nb = 4;nc = 4;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.nx = 2048; +input_multem.ny = 2048; + +clear ilc_spec_slicing; +[atoms, Slice] = ilc_spec_slicing(input_multem); + +[natoms, ~] = size(atoms);[nslice, ~] = size(Slice); +for islice = 1:nslice + input_multem.islice = islice; + + system_config.device = 1; % eD_CPU = 1, eD_GPU = 2 + system_config.precision = 1; % eP_Float = 1, eP_double = 2 + tic; + clear ilc_projected_potential; + output_multislice_1 = ilc_projected_potential(system_config, input_multem); + toc; + + system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 + system_config.precision = 1; % eP_Float = 1, eP_double = 2 + tic; + clear ilc_projected_potential; + output_multislice_2 = ilc_projected_potential(system_config, input_multem); + toc; + mean(abs(output_multislice_1.V(:)-output_multislice_2.V(:))) + + figure(1); + subplot(1, 2, 1); + imagesc(output_multislice_1.V); + colormap gray; + axis image; + subplot(1, 2, 2); + imagesc(output_multislice_2.V); + colormap gray; + axis image; + disp([min(output_multislice_1.V(:)), min(output_multislice_2.V(:))]) + disp([max(output_multislice_1.V(:)), max(output_multislice_2.V(:))]) + pause(0.10); + +end diff --git a/mex_examples_multem/example_propagate.m b/mex_examples_multem/example_propagate.m old mode 100644 new mode 100755 index 09ec82ab..260eb2ba --- a/mex_examples_multem/example_propagate.m +++ b/mex_examples_multem/example_propagate.m @@ -1,95 +1,89 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_dim = 110; -input_multem.pn_seed = 300183; -input_multem.pn_single_conf = 0; % 1: true, 0:false -input_multem.pn_nconf = 5; - -input_multem.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multem.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial - -input_multem.bwl = 0; - -input_multem.E_0 = 300; % Acceleration Voltage (keV) -input_multem.theta = 0.0; % Till ilumination (º) -input_multem.phi = 0.0; % Till ilumination (º) - -na = 4; nb = 4; nc = 10; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.nx = 1024; -input_multem.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = 0; % user define incident wave -input_multem.iw_x = input_multem.spec_lx/2; % x position -input_multem.iw_y = input_multem.spec_ly/2; % y position - -input_multem.simulation_type = 52; % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_EELS=61, eTEMST_EFTEM=62 -clear ilc_multem; -tic; -output_multislice = input_multem.ilc_multem; -toc; - -input_multem.obj_lens_c_10 = 10; %Angs - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = output_multislice.data.psi_coh; % user define incident wave - -input_multem.system_conf.precision = 2; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 1; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 2; -input_multem.system_conf.gpu_device = 0; -tic; -output_propagate = input_multem.ilc_propagate; -toc; - -figure(1); -subplot(2, 2, 1); -imagesc(abs(output_multislice.data.psi_coh).^2); -title('wave intensity'); -axis image; -colormap gray; - -subplot(2, 2, 2); -imagesc(angle(output_multislice.data.psi_coh)); -title('phase'); -axis image; -colormap gray; - -subplot(2, 2, 3); -imagesc(abs(output_propagate.psi).^2); -title('wave intensity'); -axis image; -colormap gray; - -subplot(2, 2, 4); -imagesc(angle(output_propagate.psi)); -title('angle'); -axis image; +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 4; +system_config.gpu_device = 0; + +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 52; +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +input_multem.atomic_vib_dim = [true, true, false]; +input_multem.atomic_vib_seed = 300183; +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false +input_multem.atomic_vib_nconf = 5; + +input_multem.illum_mod = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multem.illum_inc = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +input_multem.bwl = 0; + +input_multem.E_0 = 300; % Acceleration Voltage (keV) +input_multem.theta = 0.0; % Till ilumination (º) +input_multem.phi = 0.0; % Till ilumination (º) + +na = 4;nb = 4;nc = 10;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Cu001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.nx = 1024; +input_multem.ny = 1024; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = 0; % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +input_multem.em_sim_typ = 52; % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72 +clear ilc_multem; +tic; +output_multem = ilc_multem(system_config, input_multem); +toc; + +input_multem.obj_lens_c_10 = 10; %Angs + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = output_multem.data.psi_coh; % user define incident wave + +tic; +output_propagate = ilc_propagate(system_config, input_multem); +toc; + +figure(1); +subplot(2, 2, 1); +imagesc(abs(output_multem.data.psi_coh).^2); +title('wave intensity'); +axis image; +colormap gray; + +subplot(2, 2, 2); +imagesc(angle(output_multem.data.psi_coh)); +title('Total intensity'); +axis image; +colormap gray; + +subplot(2, 2, 3); +imagesc(abs(output_propagate.psi).^2); +title('wave intensity'); +axis image; +colormap gray; + +subplot(2, 2, 4); +imagesc(angle(output_propagate.psi)); +title('Total intensity'); +axis image; colormap gray; \ No newline at end of file diff --git a/mex_examples_multem/example_rdf_2d.m b/mex_examples_multem/example_rdf_2d.m new file mode 100755 index 00000000..9881d075 --- /dev/null +++ b/mex_examples_multem/example_rdf_2d.m @@ -0,0 +1,15 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'mex_bin']) + +[x, y] = meshgrid(0:2:50); +r_2d = [x(:), y(:)]; +r_2d = r_2d + 0.1*rand(size(r_2d)); +r_2d = double(r_2d); + +tic; +[r, rdf] = ilc_rdf(r_2d, 8, 200); +toc; + +figure(1); clf; +plot(r, rdf, '-+r'); \ No newline at end of file diff --git a/mex_examples_multem/example_rdf_3d.m b/mex_examples_multem/example_rdf_3d.m new file mode 100755 index 00000000..cbc5fc83 --- /dev/null +++ b/mex_examples_multem/example_rdf_3d.m @@ -0,0 +1,15 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'mex_bin']) + +[x, y, z] = meshgrid(0:2:50); +r_3d = [x(:), y(:), z(:)]; +r_3d = r_3d + 0.1*rand(size(r_3d)); +r_3d = double(r_3d); + +tic; +[r, rdf] = ilc_rdf(r_3d, 8, 200); +toc; + +figure(1); clf; +plot(r, rdf, '-+r'); \ No newline at end of file diff --git a/mex_examples_multem/example_specimen_creation_from_cif_file.m b/mex_examples_multem/example_specimen_creation_from_cif_file.m old mode 100644 new mode 100755 index 94712be3..ed9664bb --- a/mex_examples_multem/example_specimen_creation_from_cif_file.m +++ b/mex_examples_multem/example_specimen_creation_from_cif_file.m @@ -1,30 +1,30 @@ -% Specimen creation -% Copyright 2023 Ivan Lobato - -clear all;clc; - -ncu = 2; -rmsd_3d = 0.085; -fn = 'SrTiO3_mp-4651_conventional_standard.cif'; - -[a, b, c] = ilm_read_lat_parm_cif(fn); -na = 2; -nb = 2; -nc = 2; -rmsd_3d_0 = 0.085; -pbc = false; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -[atoms_0, lx, ly, lz] = ilm_read_ap_cif(fn, rmsd_3d_0, pbc, na, nb, nc); - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -pbc = true; -[atoms_1, lx, ly, lz] = ilm_read_ap_cif(fn, rmsd_3d_0, pbc, na, nb, nc); - -figure(1); clf; -subplot(1, 2, 1); -ilm_show_crystal(0, atoms_0, false); -title('pbc=false'); -subplot(1, 2, 2); -ilm_show_crystal(0, atoms_1, false); -title('pbc=true'); +% specimen creation +% Copyright 2020 Ivan Lobato + +clear;clc; + +ncu = 2; +rmsd_3d = 0.085; +fn = 'SrTiO3_mp-4651_conventional_standard.cif'; + +[a, b, c] = ilm_read_lat_parm_cif(fn); +na = 2; +nb = 2; +nc = 2; +rmsd_3d_0 = 0.085; +pbc = false; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +[atoms_0, lx, ly, lz] = ilm_read_ap_cif(fn, rmsd_3d_0, pbc, na, nb, nc); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +pbc = true; +[atoms_1, lx, ly, lz] = ilm_read_ap_cif(fn, rmsd_3d_0, pbc, na, nb, nc); + +figure(1); clf; +subplot(1, 2, 1); +ilm_show_xtl(0, atoms_0, false); +title('pbc=false'); +subplot(1, 2, 2); +ilm_show_xtl(0, atoms_1, false); +title('pbc=true'); \ No newline at end of file diff --git a/mex_examples_multem/example_specimen_planes.m b/mex_examples_multem/example_specimen_planes.m old mode 100644 new mode 100755 index 214ecbe4..2511f6c8 --- a/mex_examples_multem/example_specimen_planes.m +++ b/mex_examples_multem/example_specimen_planes.m @@ -1,127 +1,124 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.pn_dim = 110; -input_multem.pn_seed = 300183; -input_multem.pn_nconf = 1; - -input_multem.spec_rot_theta = 0; % final angle -input_multem.spec_rot_u0 = [1 0 0]; % unitary vector -input_multem.spec_rot_center_type = 1; % 1: geometric center, 2: User define -input_multem.spec_rot_center_p = [0 0 0]; % rotation point - -na = 6; nb = 6; nc = 10; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au110_xtl(na, nb, nc, ncu, rmsd_3d); - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz] = graphene(10, 2.46, 0.085); - -ilm_write_ap_pdb('graphene.pdb', input_multem.spec_atoms); - -% occ = 1; -% region = 0; -% charge = 0; -% [input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, lz] = graphene(1, 1.42, sqrt(0.5/(8*pi^2))); -% input_multem.spec_dz = 0.5; - -input_multem.spec_dz = 2; - -disp([min(input_multem.spec_atoms(:, 4)), max(input_multem.spec_atoms(:,4))]) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -lz = 20; -Z = 6; -rms_3d = 0.09; -d_min = 1.4; -seed = 1983; -rho = 2.2; -lay_pos = 2; %1: top, 2: bottom - -z_min = min(input_multem.spec_atoms(:, 4)); -z_max = max(input_multem.spec_atoms(:, 4)); -tic; -input_multem.spec_atoms = ilc_add_amorp_lay(input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, lz, d_min, Z, rms_3d, rho, lay_pos, seed); -toc; - -if(lay_pos==1) - input_multem.spec_amorp(1).z_0 = z_min-lz; % Starting z position of the amorphous layer (�) - input_multem.spec_amorp(1).z_e = z_min; % Ending z position of the amorphous layer (�) -else - input_multem.spec_amorp(1).z_0 = z_max; % Starting z position of the amorphous layer (�) - input_multem.spec_amorp(1).z_e = z_max+lz; % Ending z position of the amorphous layer (�) -end -input_multem.spec_amorp(1).dz = 2.0; % slice thick of the amorphous layer (�) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -lz = 10; -Z = 6; -rms_3d = 0.09; -d_min = 1.4; -seed = 1983; -rho = 2.2; -lay_pos = 1; %1: top, 2: bottom - -z_min = min(input_multem.spec_atoms(:, 4)); -z_max = max(input_multem.spec_atoms(:, 4)); - -tic; -input_multem.spec_atoms = ilc_add_amorp_lay(input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, lz, d_min, Z, rms_3d, rho, lay_pos, seed); -toc; - -if(lay_pos==1) - - input_multem.spec_amorp(2).z_0 = z_min-lz; % Starting z position of the amorphous layer (�) - input_multem.spec_amorp(2).z_e = z_min; % Ending z position of the amorphous layer (�) -else - input_multem.spec_amorp(2).z_0 = z_max; % Starting z position of the amorphous layer (�) - input_multem.spec_amorp(2).z_e = z_max+lz; % Ending z position of the amorphous layer (�) -end -input_multem.spec_amorp(2).dz = 2.0; % slice thick of the amorphous layer (�) - -ilm_show_crystal(1, input_multem.spec_atoms) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -clc; -tic; -[z_planes] = ilc_spec_planes(input_multem.toStruct); -toc; -diff(z_planes) -[nplanes, ~] = size(z_planes); -disp(['Number of slices = ', num2str(nplanes)]) - -figure(1); clf; -plot(input_multem.spec_atoms(:, 3), input_multem.spec_atoms(:, 4), 'ok'); -set(gca,'ydir','reverse'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Atomic positions'); -ylabel('y','FontSize',14); -xlabel('x','FontSize',12); -axis equal; - -for i = 1:nplanes - hold on; - plot([-2 input_multem.spec_lx], [z_planes(i) z_planes(i)], '-r'); - axis equal; -end -axis([-2, 18, min(input_multem.spec_atoms(:, 4))-5, max(input_multem.spec_atoms(:, 4))+5]); - -% nbins = floor((max(input_multem.spec_atoms(:, 4))-min(input_multem.spec_atoms(:, 4)))/0.10001); -% tic; -% [x, y] = ilc_hist(input_multem.spec_atoms(:, 4), nbins-1); -% toc; -% -% figure(2); clf; -% plot(x, y, '-+r'); -% hold on; -% ii = find(y<0.5); +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +input_multem = ilm_dflt_input_multem(); % Load default values; + +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_vib_dim = [true, true, false]; +input_multem.atomic_vib_seed = 300183; +input_multem.atomic_vib_nconf = 1; + +input_multem.spec_rot_theta = 0; % final angle +input_multem.spec_rot_u_0 = [1 0 0]; % unitary vector +input_multem.spec_rot_ctr_typ = 1; % 1: geometric center, 2: User define +input_multem.spec_rot_ctr_p = [0 0 0]; % rotation point + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +na = 6; nb = 6;nc = 10; ncu = 2; rmsd_3d = 0.15; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.spec_slic(1).sli_thick = 2; + +disp([min(input_multem.spec_atoms(:, 4)), max(input_multem.spec_atoms(:, 4))]) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +lz = 20; +Z = 6; +rms_3d = 0.09; +occ = 1; +tag = 1; +bs = [input_multem.spec_bs_x, input_multem.spec_bs_y, lz]; +d_min = 1.4; +rho = 2.2; +lay_pos = 2; %1: top, 2: bottom +seed = 1983; + +z_min = min(input_multem.spec_atoms(:, 4)); +z_max = max(input_multem.spec_atoms(:, 4)); +tic; + +input_multem.spec_atoms = ilc_amorp_lay_add(input_multem.spec_atoms, Z, rms_3d, occ, tag, bs, d_min, rho, lay_pos, seed); +toc; + +if(lay_pos==1) + input_multem.spec_slic(1).z_0 = z_min-lz; % Starting z position of the amorphous layer (Å) + input_multem.spec_slic(1).z_e = z_min; % Ending z position of the amorphous layer (Å) +else + input_multem.spec_slic(1).z_0 = z_max; % Starting z position of the amorphous layer (Å) + input_multem.spec_slic(1).z_e = z_max+lz; % Ending z position of the amorphous layer (Å) +end +input_multem.spec_slic(1).sli_thick = 2.0; % slice thick of the amorphous layer (Å) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +lz = 10; +Z = 6; +rms_3d = 0.09; +occ = 1; +tag = 1; +bs = [input_multem.spec_bs_x, input_multem.spec_bs_y, lz]; +d_min = 1.4; +rho = 2.2; +lay_pos = 1; %1: top, 2: bottom +seed = 1983; + +z_min = min(input_multem.spec_atoms(:, 4)); +z_max = max(input_multem.spec_atoms(:, 4)); + +tic; +input_multem.spec_atoms = ilc_amorp_lay_add(input_multem.spec_atoms, Z, rms_3d, occ, tag, bs, d_min, rho, lay_pos, seed); +toc; + +if(lay_pos==1) + input_multem.spec_slic(2).z_0 = z_min-lz; % Starting z position of the amorphous layer (Å) + input_multem.spec_slic(2).z_e = z_min; % Ending z position of the amorphous layer (Å) +else + input_multem.spec_slic(2).z_0 = z_max; % Starting z position of the amorphous layer (Å) + input_multem.spec_slic(2).z_e = z_max+lz; % Ending z position of the amorphous layer (Å) +end +input_multem.spec_slic(2).dz = 2.0; % slice thick of the amorphous layer (Å) + +ilm_show_xtl(1, input_multem.spec_atoms) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +clc; +tic; +[z_planes] = ilc_spec_planes(input_multem); +toc; +diff(z_planes) +[nplanes, ~] = size(z_planes); +disp(['Number of slices = ', num2str(nplanes)]) + +figure(1); clf; +plot(input_multem.spec_atoms(:, 3), input_multem.spec_atoms(:, 4), 'ok'); +set(gca, 'ydir', 'reverse'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Atomic positions'); +ylabel('y', 'FontSize', 14); +xlabel('x', 'FontSize', 12); +axis equal; + +for i = 1:nplanes + hold on; + plot([-2 input_multem.spec_bs_x], [z_planes(i) z_planes(i)], '-r'); + axis equal; +end +axis([-2, 18, min(input_multem.spec_atoms(:, 4))-5, max(input_multem.spec_atoms(:, 4))+5]); + +% nbins = floor((max(input_multem.spec_atoms(:, 4))-min(input_multem.spec_atoms(:, 4)))/0.10001); +% tic; +% [x, y] = ilc_hist(input_multem.spec_atoms(:, 4), nbins-1); +% toc; +% +% figure(2);clf; +% plot(x, y, '-+r'); +% hold on; +% ii = find(y<0.5); % plot(x(ii), y(ii), '.b'); \ No newline at end of file diff --git a/mex_examples_multem/example_specimen_rotation.m b/mex_examples_multem/example_specimen_rotation.m old mode 100644 new mode 100755 index 637f5179..401df935 --- a/mex_examples_multem/example_specimen_rotation.m +++ b/mex_examples_multem/example_specimen_rotation.m @@ -1,43 +1,38 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% -% Exit wave real space (EWRS) simulation -% -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -% create specimen -lx = 100; -ly = 100; -lz = 100; - -na = 8; nb = 8; nc = 8; ncu = 2; rmsd_3d = 0.085; - -[atoms, ~] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); -atoms = ilm_center_spec(atoms, lx, ly, lz); - -theta = 45; % angle (�) -u0 = [1 1 0]; % unitary vector -rot_point_type = 1; % 1: geometric center, 2: User define -p0 = [0 0 0]; % rotation point - -% rotate specimen -atoms_r = ilc_spec_rot(atoms, theta, u0, rot_point_type, p0); -figure(1); clf; - -subplot(1, 2, 1); -plot3(atoms(:, 2), atoms(:, 3), atoms(:, 4), 'o', 'MarkerSize', 2, 'MarkerFaceColor', 'auto'); -axis equal; -axis([0 lx 0 ly 0 lz]); -view([1 0 1]); - -subplot(1, 2, 2); -plot3(atoms_r(:, 2), atoms_r(:, 3), atoms_r(:, 4), 'o', 'MarkerSize', 2, 'MarkerFaceColor', 'auto'); -axis equal; -axis([0 lx 0 ly 0 lz]); -view([0 0 1]); \ No newline at end of file +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +% create specimen +lx = 100; +ly = 100; +lz = 100; + +na = 8; nb = 8; nc = 8; ncu = 2; rmsd_3d = 0.085; +[atoms, ~] = SrTiO3001_xtl(na, nb, nc, ncu, rmsd_3d); +atoms = ilm_spec_recenter(atoms, lx, ly, lz); +atoms = atoms(:, 1:5); + +ilm_show_xtl(1, atoms); + +theta = 45; % angle (º) +u_0 = [1 0 0]; % unitary vector +rot_point_type = 1; % 1: geometric center, 2: User define +p_0 = [0 0 0]; % rotation point + +% rotate specimen +tic; +atoms_r = ilc_spec_rot(atoms, theta, u_0, rot_point_type, p_0); +toc; + +figure(1); clf; +subplot(1, 2, 1); +ilm_show_xtl(1, atoms, false); +view([1 0 1]); +title('Raw') + +subplot(1, 2, 2); +ilm_show_xtl(1, atoms_r, false); +view([0 0 1]); +title('Rotated') \ No newline at end of file diff --git a/mex_examples_multem/example_specimen_slicing_rotation.m b/mex_examples_multem/example_specimen_slicing_rotation.m old mode 100644 new mode 100755 index 7af1e87d..4990abc7 --- a/mex_examples_multem/example_specimen_slicing_rotation.m +++ b/mex_examples_multem/example_specimen_slicing_rotation.m @@ -1,86 +1,89 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multem.simulation_type = 52; -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_dim = 110; % phonon dimensions (xyz) -input_multem.pn_seed = 300183; % Random seed(frozen phonon) -input_multem.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 100; % true: phonon configuration, false: number of frozen phonon configurations - -input_multem.spec_rot_theta = 45; % angle (�) -input_multem.spec_rot_u0 = [1 0 0]; % unitary vector -input_multem.spec_rot_center_type = 1; % 1: geometric center, 2: User define -input_multem.spec_rot_center_p = [0 0 0]; % rotation point - -na = 8; nb = 8; nc = 8; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.spec_lx = 100; -input_multem.spec_ly = 100; -input_multem.spec_lz = 100; - -[input_multem.spec_atoms] = ilm_center_spec(input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, input_multem.spec_lz); - -% get spec slicing -[atoms, Slice] = ilc_spec_slicing(input_multem.toStruct); - -ilm_show_crystal(1, atoms); - -[natoms,~] = size(atoms); -[nslice, ~] = size(Slice); - -for i = 1:nslice - figure(1); clf; - i1 = Slice(i, 5); i2 = Slice(i, 6); ii = i1:1:i2; - plot3(atoms(:, 2), atoms(:, 3), atoms(:, 4), '.k', atoms(ii, 2), atoms(ii, 3), atoms(ii, 4), 'or'); - set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); - title('Atomic positions'); - ylabel('y','FontSize',14); - xlabel('x','FontSize',12); - axis equal; - i2-i1+1 - view([1 0 0]); - pause(0.1); -end - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -natoms = size(atoms, 1); -bb = zeros(natoms, 1); -d = 0.1; -ic = 0; -xy = []; -for ia=1:natoms - if(bb(ia)<0.1) - x = atoms(ia, 2); - y = atoms(ia, 3); - ii = find(sqrt((atoms(:, 2)-x).^2+(atoms(:, 3)-y).^2) + +clear;clc; + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 4; +system_config.gpu_device = 0; + +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM_EELS=61, eTEMST_ISTEM_EELS=62, eTEMST_EFTEMFS=71, eTEMST_EFTEMRS=72, eTEMST_ProbeFS=81, eTEMST_ProbeRS=82, eTEMST_PPFS=91, eTEMST_PPRS=92, eTEMST_TFFS=101, eTEMST_TFRS=102 +input_multem.em_sim_typ = 52; +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions (xyz) +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 100; % true: phonon configuration, false: number of frozen phonon configurations + +input_multem.spec_rot_theta = 45; % angle (º) +input_multem.spec_rot_u_0 = [1 0 0]; % unitary vector +input_multem.spec_rot_ctr_typ = 1; % 1: geometric center, 2: User define +input_multem.spec_rot_ctr_p = [0 0 0]; % rotation point + +na = 8;nb = 8;nc = 8;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.spec_bs_x = 100; +input_multem.spec_bs_y = 100; +input_multem.spec_bs_z = 100; + +[input_multem.spec_atoms] = ilm_spec_recenter(input_multem.spec_atoms, input_multem.spec_bs_x, input_multem.spec_bs_y, input_multem.spec_bs_z); + +% get spec slicing +[atoms, Slice] = ilc_spec_slicing(input_multem); + +ilm_show_xtl(1, atoms); + +[natoms, ~] = size(atoms); +[nslice, ~] = size(Slice); + +for i = 1:nslice + figure(1); clf; + i1 = Slice(i, 5);i2 = Slice(i, 6);ii = i1:1:i2; + plot3(atoms(:, 2), atoms(:, 3), atoms(:, 4), '.k', atoms(ii, 2), atoms(ii, 3), atoms(ii, 4), 'or'); + set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); + title('Atomic positions'); + ylabel('y', 'FontSize', 14); + xlabel('x', 'FontSize', 12); + axis equal; + i2-i1+1 + view([1 0 0]); + pause(0.1); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +natoms = size(atoms, 1); +bb = zeros(natoms, 1); +d = 0.1; +ic = 0; +xy = []; +for ia=1:natoms + if(bb(ia)<0.1) + x = atoms(ia, 2); + y = atoms(ia, 3); + ii = find(sqrt((atoms(:, 2)-x).^2+(atoms(:, 3)-y).^2) - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.pn_dim = 111; -input_multem.pn_seed = 300183; -input_multem.pn_nconf = 1; - -input_multem.spec_rot_theta = 0; % final angle -input_multem.spec_rot_u0 = [1 0 0]; % unitary vector -input_multem.spec_rot_center_type = 1; % 1: geometric center, 2: User define -input_multem.spec_rot_center_p = [0 0 0]; % rotation point - -na = 4; nb = 4; nc = 10; ncu = 4; rmsd_3d = 0.08; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = GaAs001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.spec_dz = 5; -% get spec slicing -tic; -input_multem.pn_model = 1; -[atoms0, Slice0] = ilc_spec_slicing(input_multem.toStruct); -toc; - -[nslice0, ~] = size(Slice0); - -tic; -input_multem.pn_model = 3; -[atoms, Slice] = ilc_spec_slicing(input_multem.toStruct); -toc; - -[nslice, ~] = size(Slice); - -figure(1); clf; -plot(atoms(:, 3), atoms(:, 4), 'ok'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Atomic positions'); -ylabel('y','FontSize',14); -xlabel('x','FontSize',12); -axis equal; -axis([-2 18 -5 input_multem.spec_lz + 5]); - -for i = 1:nslice - hold on; - plot([-2 18], [Slice(i, 1) Slice(i, 1)], '-b', [-2 18], [Slice(i, 2) Slice(i, 2)], '-b'); - axis equal; - axis([-2 18 -5 input_multem.spec_lz + 5]); -end - -for i = 1:nslice0 - hold on; - plot([-2 18], [Slice0(i, 1) Slice0(i, 1)], '-r', [-2 18], [Slice0(i, 2) Slice0(i, 2)], '-r'); - axis equal; - axis([-2 18 -5 input_multem.spec_lz + 5]); +clear;clc; + +input_multem = ilm_dflt_input_multem(); % Load default values; + +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_vib_dim = 111; +input_multem.atomic_vib_seed = 300183; +input_multem.atomic_vib_nconf = 1; + +input_multem.spec_rot_theta = 0; % final angle +input_multem.spec_rot_u_0 = [1 0 0]; % unitary vector +input_multem.spec_rot_ctr_typ = 1; % 1: geometric center, 2: User define +input_multem.spec_rot_ctr_p = [0 0 0]; % rotation point + +na = 4;nb = 4;nc = 10;ncu = 4;rmsd_3d = 0.08; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = GaAs001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.spec_slic(1).sli_thick = 5; +% get spec slicing +tic; +input_multem.atomic_vib_mod = 1; +[atoms0, Slice0] = ilc_spec_slicing(input_multem); +toc; + +[nslice0, ~] = size(Slice0); + +tic; +input_multem.atomic_vib_mod = 3; +[atoms, Slice] = ilc_spec_slicing(input_multem); +toc; + +[nslice, ~] = size(Slice); +x_min = min(atoms(:, 2))-2; +x_max = max(atoms(:, 2))+2; +z_min = min(atoms(:, 4))-5; +z_max = max(atoms(:, 4))+5; + +figure(1); clf; +plot(atoms(:, 3), atoms(:, 4), 'ok'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Atomic positions'); +ylabel('y', 'FontSize', 14); +xlabel('x', 'FontSize', 12); +axis equal; +axis([x_min x_max z_min z_max]); + +for i = 1:nslice + hold on; + plot([x_min x_max], [Slice(i, 1) Slice(i, 1)], '-b', [x_min x_max], [Slice(i, 2) Slice(i, 2)], '-b'); + axis equal; + axis([x_min x_max z_min z_max]); +end + +for i = 1:nslice0 + hold on; + plot([x_min x_max], [Slice0(i, 1) Slice0(i, 1)], '-r', [x_min x_max], [Slice0(i, 2) Slice0(i, 2)], '-r'); + axis equal; + axis([x_min x_max z_min z_max]); end \ No newline at end of file diff --git a/mex_examples_multem/example_specimen_slicing_with_amorphous_layer.m b/mex_examples_multem/example_specimen_slicing_with_amorphous_layer.m old mode 100644 new mode 100755 index d693ee24..9fed6e73 --- a/mex_examples_multem/example_specimen_slicing_with_amorphous_layer.m +++ b/mex_examples_multem/example_specimen_slicing_with_amorphous_layer.m @@ -1,122 +1,123 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.pn_dim = 110; -input_multem.pn_seed = 300183; -input_multem.pn_nconf = 1; - -input_multem.spec_rot_theta = 0; % final angle -input_multem.spec_rot_u0 = [1 0 0]; % unitary vector -input_multem.spec_rot_center_type = 1; % 1: geometric center, 2: User define -input_multem.spec_rot_center_p = [0 0 0]; % rotation point - -na = 6; nb = 6; nc = 10; ncu = 4; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.spec_dz=a/2; - -disp([min(input_multem.spec_atoms(:, 4)), max(input_multem.spec_atoms(:,4))]) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -lz = 20; -Z = 6; -rms_3d = 0.09; -d_min = 1.4; -seed = 1983; -rho = 2.2; -lay_pos = 2; %1: top, 2: bottom - -z_min = min(input_multem.spec_atoms(:, 4)); -z_max = max(input_multem.spec_atoms(:, 4)); -tic; -input_multem.spec_atoms = ilc_add_amorp_lay(input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, lz, d_min, Z, rms_3d, rho, lay_pos, seed); -toc; - -if(lay_pos==1) - input_multem.spec_amorp(1).z_0 = z_min-lz; % Starting z position of the amorphous layer (�) - input_multem.spec_amorp(1).z_e = z_min; % Ending z position of the amorphous layer (�) -else - input_multem.spec_amorp(1).z_0 = z_max; % Starting z position of the amorphous layer (�) - input_multem.spec_amorp(1).z_e = z_max+lz; % Ending z position of the amorphous layer (�) -end -<<<<<<< HEAD -input_multem.spec_amorp(1).dz = 4.0; % slice thick of the amorphous layer (Å) - -======= -input_multem.spec_amorp(1).dz = 2.0; % slice thick of the amorphous layer (�) ->>>>>>> 94cc921ae7d3a0df6312674918b3608ae0ceb3a6 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% lz = 10; -% Z = 6; -% rms_3d = 0.09; -% d_min = 1.4; -% seed = 1983; -% rho = 2.2; -% lay_pos = 1; %1: top, 2: bottom -% -% z_min = min(input_multem.spec_atoms(:, 4)); -% z_max = max(input_multem.spec_atoms(:, 4)); -% -% tic; -% input_multem.spec_atoms = ilc_add_amorp_lay(input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, lz, d_min, Z, rms_3d, rho, lay_pos, seed); -% toc; -% -% if(lay_pos==1) -% input_multem.spec_amorp(2).z_0 = z_min-lz; % Starting z position of the amorphous layer (�) -% input_multem.spec_amorp(2).z_e = z_min; % Ending z position of the amorphous layer (�) -% else -% input_multem.spec_amorp(2).z_0 = z_max; % Starting z position of the amorphous layer (�) -% input_multem.spec_amorp(2).z_e = z_max+lz; % Ending z position of the amorphous layer (�) -% end -% input_multem.spec_amorp(2).dz = 2.0; % slice thick of the amorphous layer (�) - -% ilm_show_crystal(1, input_multem.spec_atoms) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -clc; -tic; -[atoms, Slice] = ilc_spec_slicing(input_multem.toStruct); -toc; -disp([min(atoms(:, 4)), max(atoms(:,4))]) - -[nslice, ~] = size(Slice); -disp(['Number of slices = ', num2str(nslice)]) - -figure(1); clf; -plot(atoms(:, 3), atoms(:, 4), 'ok'); -set(gca,'ydir','reverse'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Atomic positions'); -ylabel('y','FontSize',14); -xlabel('x','FontSize',12); -axis equal; - -for i = 1:nslice - hold on; - plot([-2 input_multem.spec_lx], [Slice(i, 1) Slice(i, 1)], '-r', [-2 input_multem.spec_lx], [Slice(i, 2) Slice(i, 2)], '-r'); - axis equal; - -end -axis([-2, 18, min(input_multem.spec_atoms(:, 4))-5, max(input_multem.spec_atoms(:, 4))+5]); - -tic; -[z_planes] = ilc_spec_planes(input_multem.toStruct); -toc; -nplanes = length(z_planes); -for i = 1:nplanes - hold on; - plot([-2 input_multem.spec_lx], [z_planes(i) z_planes(i)], '-b'); - axis equal; -end -diff(z_planes) \ No newline at end of file +clear;clc; + +input_multem = ilm_dflt_input_multem(); % Load default values; + +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_vib_dim = [true, true, false]; +input_multem.atomic_vib_seed = 300183; +input_multem.atomic_vib_nconf = 1; + +input_multem.spec_rot_theta = 0; % final angle +input_multem.spec_rot_u_0 = [1 0 0]; % unitary vector +input_multem.spec_rot_ctr_typ = 1; % 1: geometric center, 2: User define +input_multem.spec_rot_ctr_p = [0 0 0]; % rotation point + +na = 6;nb = 6;nc = 10;ncu = 4;rmsd_3d = 0.15; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.spec_slic(1).sli_thick=a/2; + +disp([min(input_multem.spec_atoms(:, 4)), max(input_multem.spec_atoms(:, 4))]) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +lz = 20; +Z = 6; +rms_3d = 0.09; +d_min = 1.4; +seed = 1983; +rho = 2.2; +lay_pos = 2; %1: top, 2: bottom + +z_min = min(input_multem.spec_atoms(:, 4)); +z_max = max(input_multem.spec_atoms(:, 4)); +tic; +input_multem.spec_atoms = ilc_amorp_lay_add(input_multem.spec_atoms, input_multem.spec_bs_x, input_multem.spec_bs_y, lz, d_min, Z, rms_3d, rho, lay_pos, seed); +toc; + +if(lay_pos==1) + input_multem.spec_slic(1).z_0 = z_min-lz; % Starting z position of the amorphous layer (Å) + input_multem.spec_slic(1).z_e = z_min; % Ending z position of the amorphous layer (Å) +else + input_multem.spec_slic(1).z_0 = z_max; % Starting z position of the amorphous layer (Å) + input_multem.spec_slic(1).z_e = z_max+lz; % Ending z position of the amorphous layer (Å) +end +input_multem.spec_slic(1).sli_thick = 2.0; % slice thick of the amorphous layer (Å) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% lz = 10; +% Z = 6; +% rms_3d = 0.09; +% d_min = 1.4; +% seed = 1983; +% rho = 2.2; +% lay_pos = 1; %1: top, 2: bottom +% +% z_min = min(input_multem.spec_atoms(:, 4)); +% z_max = max(input_multem.spec_atoms(:, 4)); +% +% tic; +% input_multem.spec_atoms = ilc_amorp_lay_add(input_multem.spec_atoms, input_multem.spec_bs_x, input_multem.spec_bs_y, lz, d_min, Z, rms_3d, rho, lay_pos, seed); +% toc; +% +% if(lay_pos==1) +% input_multem.spec_slic(2).z_0 = z_min-lz; % Starting z position of the amorphous layer (Å) +% input_multem.spec_slic(2).z_e = z_min; % Ending z position of the amorphous layer (Å) +% else +% input_multem.spec_slic(2).z_0 = z_max; % Starting z position of the amorphous layer (Å) +% input_multem.spec_slic(2).z_e = z_max+lz; % Ending z position of the amorphous layer (Å) +% end +% input_multem.spec_slic(2).dz = 2.0; % slice thick of the amorphous layer (Å) + +% ilm_show_xtl(1, input_multem.spec_atoms) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +clc; +tic; +[atoms, Slice] = ilc_spec_slicing(input_multem); +toc; +disp([min(atoms(:, 4)), max(atoms(:, 4))]) + +[nslice, ~] = size(Slice); +disp(['Number of slices = ', num2str(nslice)]) + +figure(1); clf; +plot(atoms(:, 3), atoms(:, 4), 'ok'); +set(gca, 'ydir', 'reverse'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Atomic positions'); +ylabel('y', 'FontSize', 14); +xlabel('x', 'FontSize', 12); +axis equal; + +for i = 1:nslice + hold on; + plot([-2 input_multem.spec_bs_x], [Slice(i, 1) Slice(i, 1)], '-r', [-2 input_multem.spec_bs_x], [Slice(i, 2) Slice(i, 2)], '-r'); + axis equal; + +end +axis([-2, 18, min(input_multem.spec_atoms(:, 4))-5, max(input_multem.spec_atoms(:, 4))+5]); + +tic; +[z_planes] = ilc_spec_planes(input_multem); +toc; +nplanes = length(z_planes); +for i = 1:nplanes + hold on; + plot([-2 input_multem.spec_bs_x], [z_planes(i) z_planes(i)], '-b'); + axis equal; +end +diff(z_planes) + +nbins = floor((max(atoms(:, 4))-min(atoms(:, 4)))/0.10001); +tic; +[x, y] = ilc_hist(input_multem.spec_atoms(:, 4), nbins-1); +toc; + +% figure(2);clf; +% plot(x, y, '-+r'); +% hold on; +% ii = find(y<0.5); +% plot(x(ii), y(ii), '.b'); \ No newline at end of file diff --git a/mex_examples_multem/example_specimen_slicing_zone_axis.m b/mex_examples_multem/example_specimen_slicing_zone_axis.m old mode 100644 new mode 100755 index e5c6b3f1..d817758a --- a/mex_examples_multem/example_specimen_slicing_zone_axis.m +++ b/mex_examples_multem/example_specimen_slicing_zone_axis.m @@ -1,54 +1,49 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.pn_dim = 111; -input_multem.pn_seed = 300183; -input_multem.pn_nconf = 3; - -input_multem.spec_rot_theta = 0; % final angle -input_multem.spec_rot_u0 = [1 0 0]; % unitary vector -input_multem.spec_rot_center_type = 1; % 1: geometric center, 2: User define -input_multem.spec_rot_center_p = [0 0 0]; % rotation point - -na = 4; nb = 4; nc = 20; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -% ilm_show_crystal(1, input_multem.spec_atoms); - -input_multem.spec_dz = 5.0; - -view -% get spec slicing -tic; -[atoms, Slice] = ilc_spec_slicing(input_multem.toStruct); -toc; -[natoms,~] = size(atoms); [nslice, ~] = size(Slice); - -for i = 1:nslice - figure(1); clf; - i1 = Slice(i, 5); i2 = Slice(i, 6); ii = i1:1:i2; - plot3(atoms(:, 2), atoms(:, 3), atoms(:, 4), '.k', atoms(ii, 2), atoms(ii, 3), atoms(ii, 4), 'or'); - set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); - title('Atomic positions'); - ylabel('y','FontSize',14); - xlabel('x','FontSize',12); - axis equal; - i2-i1+1 - view([1 0 0]); - pause(0.1); -end - -[size(input_multem.spec_atoms, 1), natoms, nslice] -[input_multem.spec_lx, input_multem.spec_ly, input_multem.spec_lz] \ No newline at end of file +clear;clc; + +input_multem = ilm_dflt_input_multem(); % Load default values; + +input_multem.atomic_vib_mod = 3; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_vib_dim = 111; +input_multem.atomic_vib_seed = 300183; +input_multem.atomic_vib_nconf = 3; + +input_multem.spec_rot_theta = 0; % final angle +input_multem.spec_rot_u_0 = [1 0 0]; % unitary vector +input_multem.spec_rot_ctr_typ = 1; % 1: geometric center, 2: User define +input_multem.spec_rot_ctr_p = [0 0 0]; % rotation point + +na = 4;nb = 4;nc = 20;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +% ilm_show_xtl(1, input_multem.spec_atoms); + +input_multem.spec_slic(1).sli_thick = 5.0; + +view +% get spec slicing +tic; +[atoms, Slice] = ilc_spec_slicing(input_multem); +toc; +[natoms, ~] = size(atoms);[nslice, ~] = size(Slice); + +for i = 1:nslice + figure(1); clf; + i1 = Slice(i, 5);i2 = Slice(i, 6);ii = i1:1:i2; + plot3(atoms(:, 2), atoms(:, 3), atoms(:, 4), '.k', atoms(ii, 2), atoms(ii, 3), atoms(ii, 4), 'or'); + set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); + title('Atomic positions'); + ylabel('y', 'FontSize', 14); + xlabel('x', 'FontSize', 12); + axis equal; + i2-i1+1 + view([1 0 0]); + pause(0.1); +end + +[size(input_multem.spec_atoms, 1), natoms, nslice] +[input_multem.spec_bs_x, input_multem.spec_bs_y, input_multem.spec_bs_z] \ No newline at end of file diff --git a/mex_examples_multem/example_specimen_subslicing.m b/mex_examples_multem/example_specimen_subslicing.m old mode 100644 new mode 100755 index 57256e2c..a21f7e21 --- a/mex_examples_multem/example_specimen_subslicing.m +++ b/mex_examples_multem/example_specimen_subslicing.m @@ -1,71 +1,66 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 3; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.pn_dim = 110; -input_multem.pn_seed = 300183; -input_multem.pn_nconf = 1; - -input_multem.spec_rot_theta = 0; % final angle -input_multem.spec_rot_u0 = [0 1 1]; % unitary vector -input_multem.spec_rot_center_type = 1; % 1: geometric center, 2: User define -input_multem.spec_rot_center_p = [0 0 0]; % rotation point - -input_multem.spec_lx = 10; -input_multem.spec_ly = 10; -input_multem.spec_lz = 10; -input_multem.spec_dz = 0.5; - -occ = 1; -region = 0; -charge = 0; -input_multem.spec_atoms = [29, 2, 2, 0.0, 0.8, 1.0, charge; 29, 6, 2, 0.0, 0.8, 1.0, charge]; -[input_multem.spec_atoms, input_multem.spec_lx, input_multem.spec_ly, lz] = graphene(1, 1.42, sqrt(0.5/(8*pi^2))); -input_multem.spec_dz = 0.5; - -% get spec slicing -tic; -input_multem.pn_model = 1; -[atoms0, Slice0] = ilc_spec_slicing(input_multem.toStruct); -toc; - -[nslice0, ~] = size(Slice0); - -tic; -input_multem.pn_model = 3; -[atoms, Slice] = ilc_spec_slicing(input_multem.toStruct); -toc; - -[nslice, ~] = size(Slice); - -figure(1); clf; -plot(atoms(:, 2), atoms(:, 4), '*k'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Atomic positions'); -ylabel('y','FontSize',14); -xlabel('x','FontSize',12); -axis equal; -axis([-2 input_multem.spec_lx+2 -5 input_multem.spec_lz + 5]); - - -for i = 1:nslice - hold on; - plot([-2 18], [Slice(i, 1) Slice(i, 1)], '-b', [-2 18], [Slice(i, 2) Slice(i, 2)], '-b'); - axis equal; - axis([-2 input_multem.spec_lx+2 -5 input_multem.spec_lz + 5]); -end - -for i = 1:nslice0 - hold on; - plot([-2 input_multem.spec_lx+2], [Slice0(i, 1) Slice0(i, 1)], '-r', [-2 input_multem.spec_lx+2], [Slice0(i, 2) Slice0(i, 2)], '-r'); - axis equal; - axis([-2 input_multem.spec_lx+2 -5 input_multem.spec_lz + 5]); +clear;clc; + +input_multem = ilm_dflt_input_multem(); % Load default values; + +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 3; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_vib_dim = [true, true, false]; +input_multem.atomic_vib_seed = 300183; +input_multem.atomic_vib_nconf = 1; + +input_multem.spec_rot_theta = 0; % final angle +input_multem.spec_rot_u_0 = [0 1 1]; % unitary vector +input_multem.spec_rot_ctr_typ = 1; % 1: geometric center, 2: User define +input_multem.spec_rot_ctr_p = [0 0 0]; % rotation point + +input_multem.spec_bs_x = 10; +input_multem.spec_bs_y = 10; +input_multem.spec_bs_z = 10; +input_multem.spec_slic(1).sli_thick = 0.5; + +occ = 1; +tag = 0; +charge = 0; +input_multem.spec_atoms = [29, 2, 2, 0.0, 0.8, 1.0, charge;29, 6, 2, 0.0, 0.8, 1.0, charge]; +[input_multem.spec_atoms, input_multem.spec_bs_x, input_multem.spec_bs_y, lz] = graphene(1, 1.42, sqrt(0.5/(8*pi^2))); +input_multem.spec_slic(1).sli_thick = 0.5; + +% get spec slicing +tic; +input_multem.atomic_vib_mod = 1; +[atoms0, Slice0] = ilc_spec_slicing(input_multem); +toc; + +[nslice0, ~] = size(Slice0); + +tic; +input_multem.atomic_vib_mod = 3; +[atoms, Slice] = ilc_spec_slicing(input_multem); +toc; + +[nslice, ~] = size(Slice); + +figure(1); clf; +plot(atoms(:, 2), atoms(:, 4), '*k'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Atomic positions'); +ylabel('y', 'FontSize', 14); +xlabel('x', 'FontSize', 12); +axis equal; +axis([-2 input_multem.spec_bs_x+2 -5 input_multem.spec_bs_z + 5]); + + +for i = 1:nslice + hold on; + plot([-2 18], [Slice(i, 1) Slice(i, 1)], '-b', [-2 18], [Slice(i, 2) Slice(i, 2)], '-b'); + axis equal; + axis([-2 input_multem.spec_bs_x+2 -5 input_multem.spec_bs_z + 5]); +end + +for i = 1:nslice0 + hold on; + plot([-2 input_multem.spec_bs_x+2], [Slice0(i, 1) Slice0(i, 1)], '-r', [-2 input_multem.spec_bs_x+2], [Slice0(i, 2) Slice0(i, 2)], '-r'); + axis equal; + axis([-2 input_multem.spec_bs_x+2 -5 input_multem.spec_bs_z + 5]); end \ No newline at end of file diff --git a/mex_examples_multem/example_transf_exp_factor.m b/mex_examples_multem/example_transf_exp_factor.m new file mode 100755 index 00000000..b072b851 --- /dev/null +++ b/mex_examples_multem/example_transf_exp_factor.m @@ -0,0 +1,20 @@ +% Copyright 2021 Ivan Lobato + +clear;clc; + +E_0 = [60, 80, 100, 120, 200, 300]; +sigma = ilc_elec_interact_parm_kva(E_0); % radians/(kV - Angs) +tf_exp_factor = ilc_transf_exp_factor(E_0); % radians/(V - Angs) + +f = 1e-3 + +figure(1); clf; +plot(E_0, tf_exp_factor, '-*r', E_0, sigma*f, '-*b'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +% title('Atomic radius'); +% ylabel('$\mathrm{radius}$', 'interpreter', 'latex', 'FontSize', 14); +% xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +% axis([1 103 0 1.1*max(r(:))]); +% legend('rms', 'Cut-off', 'Experimental'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_transmission_function.m b/mex_examples_multem/example_transmission_function.m old mode 100644 new mode 100755 index f6065a05..d8430165 --- a/mex_examples_multem/example_transmission_function.m +++ b/mex_examples_multem/example_transmission_function.m @@ -1,83 +1,78 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_ncores = 1; % Number of Cores CPU (It will be used in the future) -input_multem.system_conf.cpu_nthread = 4; % Number of CPU threads -input_multem.system_conf.gpu_device = 0; % GPU device (i.e. 0, 1, 2, ... ) - -input_multem.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_dim = 110; % phonon dimensions -input_multem.pn_seed = 300183; % Random seed(frozen phonon) -input_multem.pn_single_conf = 1; % 1: true, 0:false -input_multem.pn_nconf = 1; % true: phonon configuration, false: number of frozen phonon configurations - -input_multem.bwl = 0; - -input_multem.E_0 = 300; -input_multem.theta = 0.0; -input_multem.phi = 0.0; - -na = 4; nb = 4; nc =2; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -% input_multem.spec_atoms = [79 4.0 4.0 0 rmsd_3d 1.0]; -% input_multem.spec_lx = 8.0; -% input_multem.spec_ly = 8.0; -% input_multem.spec_dz = 0.5; - -input_multem.nx = 2048; -input_multem.ny = 2048; - -clear ilc_spec_slicing; -[atoms, Slice] = ilc_spec_slicing(input_multem.toStruct); - -[natoms,~] = size(atoms); [nslice, ~] = size(Slice); -for islice = 1:nslice - input_multem.islice = islice; - - input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 - input_multem.system_conf.precision = 2; % eP_Float = 1, eP_double = 2 - tic; -% clear ilc_transmission_function; - ouput_multislice_1 = input_multem.ilc_transmission_function; - toc; - - input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 - input_multem.system_conf.precision = 2; % eP_Float = 1, eP_double = 2 - tic; -% clear ilc_transmission_function; - ouput_multislice_2 = input_multem.ilc_transmission_function; - toc; - sum(abs(ouput_multislice_1.trans(:)-ouput_multislice_2.trans(:))/(input_multem.nx*input_multem.ny)) - - figure(1); - subplot(1, 3, 1); - imagesc(real(ouput_multislice_1.trans)); - colormap gray; - axis image; - subplot(1, 3, 2); - imagesc(imag(ouput_multislice_1.trans)); - colormap gray; - axis image; - subplot(1, 3, 3); - imagesc(abs(ouput_multislice_1.trans)); - colormap gray; - axis image; - num2str([islice, min(abs(ouput_multislice_1.trans(:))), max(abs(ouput_multislice_1.trans(:))), sum(abs(ouput_multislice_1.trans(:)))/(input_multem.nx*input_multem.ny)], 10) - pause(0.10); +clear;clc; + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_ncores = 1; % Number of Cores CPU (It will be used in the future) +system_config.cpu_n_thread = 4; % Number of CPU threads +system_config.gpu_device = 0; % GPU device (i.e. 0, 1, 2, ... ) + +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) +input_multem.atomic_vib_sgl_conf = 1; % 1: true, 0:false +input_multem.atomic_vib_nconf = 1; % true: phonon configuration, false: number of frozen phonon configurations + +input_multem.bwl = 0; + +input_multem.E_0 = 300; +input_multem.theta = 0.0; +input_multem.phi = 0.0; + +na = 4;nb = 4;nc =2;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +% input_multem.spec_atoms = [79 4.0 4.0 0 rmsd_3d 1.0]; +% input_multem.spec_bs_x = 8.0; +% input_multem.spec_bs_y = 8.0; +% input_multem.spec_slic(1).sli_thick = 0.5; + +input_multem.nx = 2048; +input_multem.ny = 2048; + +clear ilc_spec_slicing; +[atoms, Slice] = ilc_spec_slicing(input_multem); + +[natoms, ~] = size(atoms);[nslice, ~] = size(Slice); +for islice = 1:nslice + input_multem.islice = islice; + + system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 + system_config.precision = 2; % eP_Float = 1, eP_double = 2 + tic; +% clear ilc_transmission_function; + output_multislice_1 = ilc_transmission_function(system_config, input_multem); + toc; + + system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 + system_config.precision = 2; % eP_Float = 1, eP_double = 2 + tic; +% clear ilc_transmission_function; + output_multislice_2 = ilc_transmission_function(system_config, input_multem); + toc; + sum(abs(output_multislice_1.trans(:)-output_multislice_2.trans(:))/(input_multem.nx*input_multem.ny)) + + figure(1); + subplot(1, 3, 1); + imagesc(real(output_multislice_1.trans)); + colormap gray; + axis image; + subplot(1, 3, 2); + imagesc(imag(output_multislice_1.trans)); + colormap gray; + axis image; + subplot(1, 3, 3); + imagesc(abs(output_multislice_1.trans)); + colormap gray; + axis image; + num2str([islice, min(abs(output_multislice_1.trans(:))), max(abs(output_multislice_1.trans(:))), sum(abs(output_multislice_1.trans(:)))/(input_multem.nx*input_multem.ny)], 10) + pause(0.10); end \ No newline at end of file diff --git a/mex_examples_multem/example_vp.m b/mex_examples_multem/example_vp.m old mode 100644 new mode 100755 index 1568aeb6..a2aa6cd0 --- a/mex_examples_multem/example_vp.m +++ b/mex_examples_multem/example_vp.m @@ -1,11 +1,9 @@ -% Copyright 2023 Ivan Lobato - clear; clc; addpath([fileparts(pwd) filesep 'mex_bin']) addpath([fileparts(pwd) filesep 'crystalline_materials']) addpath([fileparts(pwd) filesep 'matlab_functions']) -Z = 49; +Z = 78; charge = 0; Rmin = 1e-02; Rmax = 5.0; nR = 512; diff --git a/mex_examples_multem/example_vr.m b/mex_examples_multem/example_vr.m old mode 100644 new mode 100755 index 61ea89e5..54149f1a --- a/mex_examples_multem/example_vr.m +++ b/mex_examples_multem/example_vr.m @@ -1,47 +1,46 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -Z = 79; -occ = 1; -region = 0; -charge = 0; - -rmin = 1e-02; rmax = 5.0; nr = 512; -dlnr = log(rmax/rmin)/(nr-1); r = rmin*exp((0:1:(nr-1))*dlnr); - -tic; -[f1, df1] = ilc_vr(1, Z, charge, r); -[f2, df2] = ilc_vr(2, Z, charge, r); -[f3, df3] = ilc_vr(3, Z, charge, r); -[f4, df4] = ilc_vr(4, Z, charge, r); -[f5, df5] = ilc_vr(5, Z, charge, r); -[f6, df6] = ilc_vr(6, Z, charge, r); -toc; - -figure(1); clf; - -subplot(1, 2, 1); -hold on; -plot(r, f1, '-k', r, f2, '-b', r, f3, '-c', r, f4, '-m', r, f5, '-r', r, f6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Atomic potential'); -ylabel('$\displaystyle V(r)$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{r}$','interpreter','latex','FontSize',12); -xlim([0 rmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -subplot(1, 2, 2); -hold on; -plot(r, df1, '-k', r, df2, '-b', r, df3, '-c', r, df4, '-m', r, df5, '-r', r, df6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Derivative of the Atomic potential'); -ylabel('$\displaystyle \frac{d V(r)}{dr}$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{r}$','interpreter','latex','FontSize',12); -xlim([0 rmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -set(gcf,'units','normalized','outerposition',[0 0 1 1]); \ No newline at end of file +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +Z = 79; +occ = 1; +tag = 0; +charge = 0; + +rmin = 1e-02;rmax = 5.0;nr = 512; +dlnr = log(rmax/rmin)/(nr-1);r = rmin*exp((0:1:(nr-1))*dlnr); + +tic; +[f1, df1] = ilc_vr(1, Z, charge, r); +[f2, df2] = ilc_vr(2, Z, charge, r); +[f3, df3] = ilc_vr(3, Z, charge, r); +[f4, df4] = ilc_vr(4, Z, charge, r); +[f5, df5] = ilc_vr(5, Z, charge, r); +[f6, df6] = ilc_vr(6, Z, charge, r); +toc; + +figure(1); clf; + +subplot(1, 2, 1); +hold on; +plot(r, f1, '-k', r, f2, '-b', r, f3, '-c', r, f4, '-m', r, f5, '-r', r, f6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Atomic potential'); +ylabel('$\displaystyle V(r)$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 rmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +subplot(1, 2, 2); +hold on; +plot(r, df1, '-k', r, df2, '-b', r, df3, '-c', r, df4, '-m', r, df5, '-r', r, df6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Derivative of the Atomic potential'); +ylabel('$\displaystyle \frac{d V(r)}{dr}$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 rmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_vz.m b/mex_examples_multem/example_vz.m old mode 100644 new mode 100755 index 8f466bf1..2660fcae --- a/mex_examples_multem/example_vz.m +++ b/mex_examples_multem/example_vz.m @@ -1,46 +1,46 @@ -% Copyright 2023 Ivan Lobato - -clear; clc; -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -Z = 51; -charge = 1; - -rmin = 1e-02; rmax = 5.0; nr = 512; -dlnr = log(rmax/rmin)/(nr-1); r = rmin*exp((0:1:(nr-1))*dlnr); -z0 = -8.0; ze = 8.0; - -tic; -[f1, df1] = ilc_vz(1, Z, charge, z0, ze, r); -[f2, df2] = ilc_vz(2, Z, charge, z0, ze, r); -[f3, df3] = ilc_vz(3, Z, charge, z0, ze, r); -[f4, df4] = ilc_vz(4, Z, charge, z0, ze, r); -[f5, df5] = ilc_vz(5, Z, charge, z0, ze, r); -[f6, df6] = ilc_vz(6, Z, charge, z0, ze, r); -toc; - -figure(1); clf; - -subplot(1, 2, 1); -hold on; -plot(r, f1, '-k', r, f2, '-b', r, f3, '-c', r, f4, '-m', r, f5, '-r', r, f6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Atomic potential'); -ylabel('$\displaystyle V(r)$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{r}$','interpreter','latex','FontSize',12); -xlim([0 rmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -subplot(1, 2, 2); -hold on; -plot(r, df1, '-k', r, df2, '-b', r, df3, '-c', r, df4, '-m', r, df5, '-r', r, df6, '-g'); -set(gca,'FontSize',12,'LineWidth',1,'PlotBoxAspectRatio',[1.25 1 1]); -title('Derivative of the Atomic potential'); -ylabel('$\displaystyle \frac{d V(r)}{dr}$','interpreter','latex','FontSize',14); -xlabel('$\mathbf{r}$','interpreter','latex','FontSize',12); -xlim([0 rmax]); -legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); - -set(gcf,'units','normalized','outerposition',[0 0 1 1]); \ No newline at end of file +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + + +Z = 79; +charge = 0; + +rmin = 1e-02;rmax = 5.0;nr = 512; +dlnr = log(rmax/rmin)/(nr-1);r = rmin*exp((0:1:(nr-1))*dlnr); +z0 = -2.0;ze = 2.0; + +tic; +[f1, df1] = ilc_vz(1, Z, charge, z0, ze, r); +[f2, df2] = ilc_vz(2, Z, charge, z0, ze, r); +[f3, df3] = ilc_vz(3, Z, charge, z0, ze, r); +[f4, df4] = ilc_vz(4, Z, charge, z0, ze, r); +[f5, df5] = ilc_vz(5, Z, charge, z0, ze, r); +[f6, df6] = ilc_vz(6, Z, charge, z0, ze, r); +toc; + +figure(1); clf; + +subplot(1, 2, 1); +hold on; +plot(r, f1, '-k', r, f2, '-b', r, f3, '-c', r, f4, '-m', r, f5, '-r', r, f6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Atomic potential'); +ylabel('$\displaystyle V(r)$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 rmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +subplot(1, 2, 2); +hold on; +plot(r, df1, '-k', r, df2, '-b', r, df3, '-c', r, df4, '-m', r, df5, '-r', r, df6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Derivative of the Atomic potential'); +ylabel('$\displaystyle \frac{d V(r)}{dr}$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{r}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 rmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_vzp.m b/mex_examples_multem/example_vzp.m new file mode 100755 index 00000000..44b401cd --- /dev/null +++ b/mex_examples_multem/example_vzp.m @@ -0,0 +1,45 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + + +Z = 79; +charge = 4; + +Rmin = 1e-03;Rmax = 5.0;nR = 512; +dlnR = log(Rmax/Rmin)/(nR-1);R = Rmin*exp((0:1:(nR-1))*dlnR); + +tic; +[f1, df1] = ilc_vzp(1, Z, charge, R); +[f2, df2] = ilc_vzp(2, Z, charge, R); +[f3, df3] = ilc_vzp(3, Z, charge, R); +[f4, df4] = ilc_vzp(4, Z, charge, R); +[f5, df5] = ilc_vzp(5, Z, charge, R); +[f6, df6] = ilc_vzp(6, Z, charge, R); +toc; + +figure(1); clf; + +subplot(1, 2, 1); +hold on; +plot(R, f1, '-k', R, f2, '-b', R, f3, '-c', R, f4, '-m', R, f5, '-r', R, f6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Projected Atomic potential'); +ylabel('$\displaystyle V(R)$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{R}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 Rmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +subplot(1, 2, 2); +hold on; +plot(R, df1, '-k', R, df2, '-b', R, df3, '-c', R, df4, '-m', R, df5, '-r', R, df6, '-g'); +set(gca, 'FontSize', 12, 'LineWidth', 1, 'PlotBoxAspectRatio', [1.25 1 1]); +title('Derivative of the Atomic potential'); +ylabel('$\displaystyle \frac{d V(R)}{dr}$', 'interpreter', 'latex', 'FontSize', 14); +xlabel('$\mathbf{R}$', 'interpreter', 'latex', 'FontSize', 12); +xlim([0 Rmax]); +legend('Doyle [0-4]', 'Peng [0-4]', 'Peng [0-12]', 'Kirkland [0-12]', 'Weickenmeier [0-12]', 'Lobato [0-12]'); + +set(gcf, 'units', 'normalized', 'outerposition', [0 0 1 1]); \ No newline at end of file diff --git a/mex_examples_multem/example_wave_function.m b/mex_examples_multem/example_wave_function.m old mode 100644 new mode 100755 index 3354031e..9308d47a --- a/mex_examples_multem/example_wave_function.m +++ b/mex_examples_multem/example_wave_function.m @@ -1,115 +1,112 @@ -% output_multislice = input_multem.ilc_multem perform TEM simulation -% All parameters of the input_multem structure are explained in ilm_dflt_input_multem() -% Copyright 2023 Ivan Lobato clear; clc; - -addpath([fileparts(pwd) filesep 'mex_bin']) -addpath([fileparts(pwd) filesep 'crystalline_materials']) -addpath([fileparts(pwd) filesep 'matlab_functions']) - -input_multem = multem_input.parameters; % Load default values; - -input_multem.system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -input_multem.system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -input_multem.system_conf.cpu_nthread = 4; -input_multem.system_conf.gpu_device = 0; - -% eTEMST_EWFS=51, eTEMST_EWRS=52 -input_multem.simulation_type = 52; -input_multem.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multem.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - -input_multem.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multem.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multem.pn_dim = 110; % phonon dimensions -input_multem.pn_seed = 300183; % Random seed(frozen phonon) -input_multem.pn_single_conf = 1; % 1: true, 0:false (extract single configuration) -input_multem.pn_nconf = 3; % true: phonon configuration, false: number of frozen phonon configurations - -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = 0; % Array of thickes - -input_multem.bwl = 0; - -input_multem.E_0 = 100; -input_multem.theta = 0.01; -input_multem.phi = 0.0; - -na = 8; nb = 8; nc = 3; ncu = 2; rmsd_3d = 0.085; - -[input_multem.spec_atoms, input_multem.spec_lx... -, input_multem.spec_ly, input_multem.spec_lz... -, a, b, c, input_multem.spec_dz] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); - -input_multem.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multem.thick = 0:2*c:1000; % Array of thickes - -input_multem.nx = 2048; -input_multem.ny = 2048; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multem.iw_type = 1; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multem.iw_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave -input_multem.iw_x = 0.5*input_multem.spec_lx; % x position -input_multem.iw_y = 0.5*input_multem.spec_ly; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.cond_lens_m = 0; % Vortex momentum -input_multem.cond_lens_c_10 = 1110; % Defocus (�) -input_multem.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) -input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multem.cond_lens_ti_sigma = 32; % standard deviation (�) -input_multem.cond_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_si_sigma = 0.2; % standard deviation: For parallel ilumination(�^-1); otherwise (�) -input_multem.cond_lens_si_rad_npts = 8; % # of integration points. It will be only used if illumination_model=4 -input_multem.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 4 -input_multem.cond_lens_zero_defocus_plane = 0; - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multem.obj_lens_m = 0; % Vortex momentum -input_multem.obj_lens_c_10 = 15.836; % Defocus (�) -input_multem.obj_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (�) -input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (�) -input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (�) -input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (�) -input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multem.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) -input_multem.obj_lens_ti_sigma = 32; % standard deviation (�) -input_multem.obj_lens_ti_npts = 10; % # of integration points. It will be only used if illumination_model=4 -input_multem.obj_lens_zero_defocus_type = 4; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multem.obj_lens_zero_defocus_plane = 5; - -input_multem.output_area_ix_0 = 1; % x-starting pixel -input_multem.output_area_iy_0 = 1; % y-starting pixel -input_multem.output_area_ix_e = 1; % x-final pixel -input_multem.output_area_iy_e = 1; % y-final pixel - -clear ilc_wave_function; -tic; -ouput_multislice = input_multem.ilc_wave_function; -toc; - -figure(1); -for ithk=1:length(ouput_multislice.thick) - psi_coh = flipud(ouput_multislice.data(ithk).psi_coh); - - subplot(1, 2, 1); - imagesc(abs(psi_coh).^2); - colormap gray; - axis image; - title(strcat('Intensity, thick = ', num2str(ithk))); - subplot(1, 2, 2); - imagesc(angle(psi_coh)); - colormap gray; - axis image; - title(strcat('Phase, thick = ', num2str(ithk))); - pause(0.25); +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + + +input_multem = ilm_dflt_input_multem(); % Load default values; + +system_config.precision = 1; % eP_Float = 1, eP_double = 2 +system_config.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_config.cpu_n_thread = 4; +system_config.gpu_device = 0; + +% eTEMST_EWFS=51, eTEMST_EWRS=52 +input_multem.em_sim_typ = 52; +input_multem.elec_spec_interact_mod = 1; % eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 +input_multem.spec_slic(1).typ = 1; % esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + +input_multem.atomic_pot_parm_typ = 6; % eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6 + +input_multem.atomic_vib_mod = 1; % eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 +input_multem.atomic_vib_dim = [true, true, false]; % phonon dimensions +input_multem.atomic_vib_seed = 300183; % Random seed(frozen phonon) +input_multem.atomic_vib_sgl_conf = 0; % 1: true, 0:false (extract single configuration) +input_multem.atomic_vib_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations + +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0; % Array of thickes + +input_multem.bwl = 0; + +input_multem.E_0 = 100; +input_multem.theta = 0.01; +input_multem.phi = 0.0; + +na = 8;nb = 8;nc = 3;ncu = 2;rmsd_3d = 0.085; + +[input_multem.spec_atoms, input_multem.spec_bs_x... +, input_multem.spec_bs_y, input_multem.spec_bs_z... +, a, b, c, input_multem.spec_slic(1).sli_thick] = Au001_xtl(na, nb, nc, ncu, rmsd_3d); + +input_multem.thick_typ = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multem.thick = 0:2*c:1000; % Array of thickes + +input_multem.nx = 2048; +input_multem.ny = 2048; + +%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.incdt_wav_typ = 1; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multem.incdt_wav_psi = read_psi_0_multem(input_multem.nx, input_multem.ny); % user define incident wave + +%%%%%%%%%%%%%%%%%%%%%%%%%%% beam position %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multem.beam_pos = [input_multem.spec_bs_x/2;input_multem.spec_bs_y/2]; + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.cond_lens_m = 0; % Vortex momentum +input_multem.cond_lens_c_10 = 1110; % Defocus (Å) +input_multem.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multem.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) +input_multem.cond_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.cond_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_spt_inc_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1);otherwise (Å) +input_multem.cond_lens_spt_inc_rad_npts = 8; % # of integration points. It will be only used if illum_mod=4 +input_multem.cond_lens_zero_def_typ = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multem.cond_lens_zero_def_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multem.obj_lens_m = 0; % Vortex momentum +input_multem.obj_lens_c_10 = 15.836; % Defocus (Å) +input_multem.obj_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multem.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multem.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multem.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multem.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multem.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multem.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multem.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) +input_multem.obj_lens_tp_inc_sigma = 32; % standard deviation (Å) +input_multem.obj_lens_tp_inc_npts = 10; % # of integration points. It will be only used if illum_mod=4 +input_multem.obj_lens_zero_def_typ = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multem.obj_lens_zero_def_plane = 0; + +input_multem.output_area_ip_0 = [1;1]; % Starting position in pixels +input_multem.output_area_ip_e = [1;1]; % End position in pixels + +clear ilc_wave_function; +tic; +output_multislice = ilc_wave_function(system_config, input_multem); +toc; + +figure(1); +for ithk=1:length(output_multislice.thick) + psi_coh = flipud(output_multislice.data(ithk).psi_coh); + + subplot(1, 2, 1); + imagesc(abs(psi_coh).^2); + colormap gray; + axis image; + title(strcat('Intensity, thick = ', num2str(ithk))); + subplot(1, 2, 2); + imagesc(angle(psi_coh)); + colormap gray; + axis image; + title(strcat('Phase, thick = ', num2str(ithk))); + pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_xtl_build.m b/mex_examples_multem/example_xtl_build.m new file mode 100755 index 00000000..0dc9df85 --- /dev/null +++ b/mex_examples_multem/example_xtl_build.m @@ -0,0 +1,44 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +xtl_parm.na = 1; +xtl_parm.nb = 1; +xtl_parm.nc = 1; + +xtl_parm.a = 4.0780; +xtl_parm.b = 4.0780; +xtl_parm.c = 4.0780; + +xtl_parm.alpha = 90; +xtl_parm.beta = 90; +xtl_parm.gamma = 90; + +xtl_parm.sgn = 1; +xtl_parm.pbc = false; + +occ = 1; +tag = 0; +charge = 0; +% Au = 79 +%Z x y z sigma occupancy tag charge +rmsd_3d = 0.085; + +xtl_parm.asym_uc = []; + +xtl_parm.base = [79, 0.0, 0.0, 0.0, rmsd_3d, occ, tag, charge;... + 79, 0.5, 0.5, 0.0, rmsd_3d, occ, tag, charge;... + 79, 0.0, 0.5, 0.5, rmsd_3d, occ, tag, charge;... + 79, 0.5, 0.0, 0.5, rmsd_3d, occ, tag, charge]; + +tic; +if 1 + atoms = ilc_xtl_build(xtl_parm); +else + atoms = ilm_xtl_build(xtl_parm); +end +toc; + +ilm_show_xtl(1, atoms); diff --git a/mex_examples_multem/example_xtl_build_base.m b/mex_examples_multem/example_xtl_build_base.m new file mode 100755 index 00000000..60c40347 --- /dev/null +++ b/mex_examples_multem/example_xtl_build_base.m @@ -0,0 +1,28 @@ +% Copyright 2021 Ivan Lobato +clear;clc; +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +xtl_parm.a = 5; +xtl_parm.b = 5; +xtl_parm.c = 5; +xtl_parm.alpha = 90; +xtl_parm.beta = 90; +xtl_parm.gamma = 90; +xtl_parm.na = 1; +xtl_parm.nb = 1; +xtl_parm.nc = 1; +xtl_parm.sgn = 120; +xtl_parm.pbc = false; +xtl_parm.asym_uc = [6, 0, 0, 0; 6, 1/4, 1/4, 1/4]; +if 1 + xtl_parm.base = ilc_xtl_build_base(xtl_parm.asym_uc, xtl_parm.sgn); +else + xtl_parm.base = ilm_xtl_build_base(xtl_parm); +end + +base = xtl_parm.base; + +ilm_show_xtl(1, base); +view([0 0 1]) \ No newline at end of file diff --git a/mex_examples_multem/example_xtl_system_space_group.m b/mex_examples_multem/example_xtl_system_space_group.m new file mode 100755 index 00000000..aff38a58 --- /dev/null +++ b/mex_examples_multem/example_xtl_system_space_group.m @@ -0,0 +1,52 @@ +clear; clc; + +addpath(['..', filesep, 'matlab_functions']) +addpath(['..', filesep, 'crystalline_materials']) +addpath(['..', filesep, 'mex_bin']) + +% triclinic or anorthic: a +% monoclinic" m +% orthorhombic: o +% tetragonal: t +% rhombohedral or trigonal: r +% hexagonal: h +% cubic: c + +css = 'triclinic'; +% css = 'cubic'; +css = 'h'; +% css = 'o'; + +% from xtl system string to xtl system number +csn_c = ilc_xtl_css_2_csn(css); +csn_m = ilm_xtl_css_2_csn(css); + +disp('from xtl system string to xtl system number') +disp(' C++ Matlab') +disp([csn_c, csn_m]) + +% from xtl system string to space group range +[sgr_0c, sgr_ec] = ilc_xtl_css_2_sgr(css); +[sgr_0m, sgr_em] = ilm_xtl_css_2_sgr(css); + +disp('from xtl system string to space group range') +disp(' C++ Matlab') +disp([sgr_0c, sgr_ec, sgr_0m, sgr_em]) +csn = csn_c; + +% from xtl system number to space group range +[sgr_0c, sgr_ec] = ilc_xtl_csn_2_sgr(csn); +[sgr_0m, sgr_em] = ilm_xtl_csn_2_sgr(csn); + +disp('from xtl system number to space group range') +disp(' C++ Matlab') +disp([sgr_0c, sgr_ec, sgr_0m, sgr_em]) + +sgn = 125; +% from space group number to xtl system number +csn_c = ilc_xtl_sgn_2_csn(sgn); +csn_m = ilm_xtl_sgn_2_csn(sgn); + +disp('from space group number to xtl system number') +disp(' C++ Matlab') +disp([csn_c, csn_m]) \ No newline at end of file diff --git a/mex_examples_multem/stem_sim_Au_def_0.00_nconf_2.mat b/mex_examples_multem/stem_sim_Au_def_0.00_nconf_2.mat deleted file mode 100644 index c7528303..00000000 Binary files a/mex_examples_multem/stem_sim_Au_def_0.00_nconf_2.mat and /dev/null differ diff --git a/mex_files_multem/ilc_add_amorp_lay.cpp b/mex_files_multem/ilc_add_amorp_lay.cpp deleted file mode 100644 index d6b0c2a9..00000000 --- a/mex_files_multem/ilc_add_amorp_lay.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2015 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "atomic_data_mt.hpp" -#include "amorp_spec.hpp" - -#include -#include "matlab_mex.cuh" - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[ ]) -{ - auto ratoms = mx_get_matrix(prhs[0]); - auto l_x = mx_get_scalar(prhs[1]); - auto l_y = mx_get_scalar(prhs[2]); - auto l_z = mx_get_scalar(prhs[3]); - auto r_min = mx_get_scalar(prhs[4]); - auto Z = mx_get_scalar(prhs[5]); - auto rms_3d = mx_get_scalar(prhs[6]); - auto rho = mx_get_scalar(prhs[7]); - auto lay_pos = (nrhs>8)?mx_get_scalar(prhs[8]):mt::eALT_Top; - int seed = (nrhs>9)?mx_get_scalar(prhs[9]):300183; - - /*******************************************************************/ - mt::Atom_Data atoms; - atoms.set_atoms(ratoms.rows, ratoms.cols, ratoms.real, l_x, l_y); - - int region = (ratoms.rows==0)?0:atoms.region_max+1; - - atoms.amorp_lay_info.resize(1); - if(lay_pos==mt::eALT_Top) - { - atoms.amorp_lay_info[0].z_0 = atoms.z_min-l_z; - atoms.amorp_lay_info[0].z_e = atoms.z_min; - atoms.amorp_lay_info[0].dz = 2.0; - atoms.amorp_lay_info[0].type = mt::eALT_Top; - atoms.amorp_lay_info[0].region = region; - } - else - { - atoms.amorp_lay_info[0].z_0 = atoms.z_max; - atoms.amorp_lay_info[0].z_e = atoms.z_max+l_z; - atoms.amorp_lay_info[0].dz = 2.0; - atoms.amorp_lay_info[0].type = mt::eALT_Bottom; - atoms.amorp_lay_info[0].region = region; - } - - mt::Amorp_Spec spec; - spec.create(atoms, r_min, Z, rms_3d, rho, seed); - - auto atomsM = mx_create_matrix(atoms.size(), 8, plhs[0]); - for(auto idx = 0; idx + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types_mt.cuh" +#include "particles.cuh" +#include "amorp_build.hpp" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float32; + + const auto Z = mex_get_num(prhs[0]); + const auto rms_3d = mex_get_num(prhs[1]); + const auto occ = mex_get_num(prhs[2]); + const auto tag = mex_get_num(prhs[3]); + const auto bs = mex_get_r_3d(prhs[4]); + const auto d_min = mex_get_num(prhs[5]); + const auto rho = mex_get_num(prhs[6]); + const dt_int32 seed = (nrhs>7)?mex_get_num(prhs[7]):300183; + + /***************************************************************************************/ + mt::R_3d r_0(0, 0, 0); + mt::Spec_Lay_Info spec_lay_info(bs, r_0, tag); + + mt::Amorp_Build amorp_build; + auto atoms = amorp_build(Z, rms_3d, occ, d_min, rho, seed, spec_lay_info); + + auto patoms = mex_create_pVctr({atoms.size(), atoms.cols_used}, plhs[0]); + atoms.cpy_to_ptr(patoms.data(), atoms.size(), 0, atoms.cols_used); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_amorp_lay_add.cpp b/mex_files_multem/ilc_amorp_lay_add.cpp new file mode 100755 index 00000000..3c09c64c --- /dev/null +++ b/mex_files_multem/ilc_amorp_lay_add.cpp @@ -0,0 +1,58 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types_mt.cuh" +#include "particles.cuh" +#include "amorp_build.hpp" + +#include +#include "matlab_mex.h" + +template +void mex_run(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + const auto patoms_i = mex_get_pvctr(prhs[0]); + const auto Z = mex_get_num(prhs[1]); + const auto rms_3d = mex_get_num(prhs[2]); + const auto occ = mex_get_num(prhs[3]); + const auto tag = mex_get_num(prhs[4]); + const auto bs = mex_get_r_3d(prhs[5]); + const auto d_min = mex_get_num(prhs[6]); + const auto rho = mex_get_num(prhs[7]); + const auto spec_lay_typ = (nrhs>8)?mex_get_enum(prhs[8]):mt::eslp_top; + const dt_int32 seed = (nrhs>9)?mex_get_num(prhs[9]):300183; + + /***************************************************************************************/ + mt::Ptc_Atom atoms(patoms_i, {0, 0, 0}, false, true); + + mt::R_3d r_0 = (mt::is_spec_lay_top(spec_lay_typ))?mt::R_3d(0, 0, atoms.z_lim.x-bs.z):mt::R_3d(0, 0, atoms.z_lim.y); + mt::Spec_Lay_Info spec_lay_info(bs, r_0, tag, spec_lay_typ); + + mt::Amorp_Build amorp_build; + amorp_build(atoms, Z, rms_3d, occ, d_min, rho, seed, spec_lay_info); + + auto patoms_o = mex_create_pVctr({atoms.size(), atoms.cols_used}, plhs[0]); + atoms.cpy_to_ptr(patoms_o.data(), atoms.size(), 0, atoms.cols_used); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + MEX_RUN_FCN_FLOAT_OUT(mex_run, 0); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_amorp_spec.cpp b/mex_files_multem/ilc_amorp_spec.cpp deleted file mode 100644 index 36bfc3c1..00000000 --- a/mex_files_multem/ilc_amorp_spec.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2015 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "atomic_data_mt.hpp" -#include "amorp_spec.hpp" - -#include -#include "matlab_mex.cuh" - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[ ]) -{ - auto l_x = mx_get_scalar(prhs[0]); - auto l_y = mx_get_scalar(prhs[1]); - auto l_z = mx_get_scalar(prhs[2]); - auto r_min = mx_get_scalar(prhs[3]); - auto Z = mx_get_scalar(prhs[4]); - auto rms_3d = mx_get_scalar(prhs[5]); - auto rho = mx_get_scalar(prhs[6]); - int seed = (nrhs>7)?mx_get_scalar(prhs[7]):300183; - - /*******************************************************************/ - mt::Atom_Data atoms; - atoms.l_x = l_x; - atoms.l_y = l_y; - - atoms.amorp_lay_info.resize(1); - atoms.amorp_lay_info[0].z_0 = 0; - atoms.amorp_lay_info[0].z_e = l_z; - atoms.amorp_lay_info[0].dz = 2.0; - atoms.amorp_lay_info[0].type = mt::eALT_Bottom; - atoms.amorp_lay_info[0].region = 0; - - mt::Amorp_Spec spec; - spec.create(atoms, r_min, Z, rms_3d, rho, seed); - - auto atomsM = mx_create_matrix(spec.m_atoms.size(), 8, plhs[0]); - for(auto idx = 0; idx - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" - -#include "microscope_effects.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; -using mt::rmatrix_c; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - /************************ simulation type **************************/ - input_multislice.simulation_type = mt::eTEMST_PropRS; - - /**************************** Specimen *****************************/ - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - T_r lz = 0; - T_r dz = 0.25; - bool pbc_xy = true; - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = false; - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************ Incident wave ****************************/ - auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); - input_multislice.set_incident_wave_type(iw_type); - - if (input_multislice.is_user_define_wave() && full) - { - auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); - mt::assign(iw_psi, input_multislice.iw_psi); - } - - // read iw_x and iw_y - auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); - auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin() + n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin() + n_iw_xy); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; - input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; - - /********************* Illumination model *************************/ - input_multislice.illumination_model = mx_get_scalar_field(mx_input_multislice, "illumination_model"); - input_multislice.temporal_spatial_incoh = mx_get_scalar_field(mx_input_multislice, "temporal_spatial_incoh"); - - /********************* source spread function *********************/ - // input_multislice.cond_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_sigma"); // standard deviation: For parallel ilumination(�^-1); otherwise (�) - // input_multislice.cond_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_rad_npts"); // # of integration points - /********************* defocus spread function ********************/ - input_multislice.cond_lens.ti_a = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.cond_lens.ti_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.cond_lens.ti_beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.cond_lens.ti_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_npts"); // Number of integration points - - /********************* source spread function *********************/ - input_multislice.cond_lens.si_a = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.cond_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.cond_lens.si_beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.cond_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_rad_npts"); // Number of radial integration points - input_multislice.cond_lens.si_azm_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_azm_npts"); - - input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /*********************** Objective lens ***************************/ - input_multislice.obj_lens.m = mx_get_scalar_field(mx_input_multislice, "obj_lens_m"); // momentum of the vortex - input_multislice.obj_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_10"); // defocus (Angstrom) - input_multislice.obj_lens.c_12 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_12"); // 2-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_12 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_21 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_21"); // Axial coma (Angstrom) - input_multislice.obj_lens.phi_21 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.obj_lens.c_23 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_23"); // 3-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_23 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_30 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_30")*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.c_32 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_32"); // Axial star aberration (Angstrom) - input_multislice.obj_lens.phi_32 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_34 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_34"); // 4-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_34 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_41 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_41"); // 4th order axial coma (Angstrom) - input_multislice.obj_lens.phi_41 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.obj_lens.c_43 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_43"); // 3-lobe aberration (Angstrom) - input_multislice.obj_lens.phi_43 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.obj_lens.c_45 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_45"); // 5-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_45 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_50 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_50")*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.c_52 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_52"); // 5th order axial star aberration (Angstrom) - input_multislice.obj_lens.phi_52 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_54"); // 5th order rosette aberration (Angstrom) - input_multislice.obj_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration(degrees-->rad) - input_multislice.obj_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_56"); // 6-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.obj_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - /********************* defocus spread function ********************/ - input_multislice.obj_lens.ti_a = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.obj_lens.ti_sigma = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.obj_lens.ti_beta = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.obj_lens.ti_npts = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_npts"); // Number of integration points - - /********************* source spread function *********************/ - input_multislice.obj_lens.si_a = mx_get_scalar_field(mx_input_multislice, "obj_lens_si_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.obj_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "obj_lens_si_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.obj_lens.si_beta = mx_get_scalar_field(mx_input_multislice, "obj_lens_si_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) - input_multislice.obj_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "obj_lens_si_rad_npts"); // Number of radial integration points - input_multislice.obj_lens.si_azm_npts = mx_get_scalar_field(mx_input_multislice, "obj_lens_si_azm_npts"); // Number of azimuth integration points - - /********************* zero defocus reference ********************/ - input_multislice.obj_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_type"); // Zero defocus type - input_multislice.obj_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_plane"); // Zero defocus position - - input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); -} - -template -void set_struct_propagate(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "psi"}; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - mx_create_set_matrix_field(mx_output_multislice, "psi", output_multislice.ny, output_multislice.nx, output_multislice.psi_coh[0]); -} - -template -void run_propagate(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - - mt::Microscope_Effects microscope_effects; - microscope_effects.set_input_data(&input_multislice, &stream, &fft_2d); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - microscope_effects.apply_ctf(output_multislice); - - stream.synchronize(); - - //output_multislice.gather(); - output_multislice.clean_temporal(); - fft_2d.cleanup(); - - set_struct_propagate(output_multislice, mx_output_multislice); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; - - if(system_conf.is_float_host()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_host()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_float_device()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_device()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } -} \ No newline at end of file diff --git a/mex_files_multem/ilc_atomic_info.cpp b/mex_files_multem/ilc_atomic_info.cpp new file mode 100755 index 00000000..286ba097 --- /dev/null +++ b/mex_files_multem/ilc_atomic_info.cpp @@ -0,0 +1,116 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_data_mt.cuh" +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +template +void set_output_data(const mt::Vctr_cpu>& atomic_info, mxArray*& mx_atomic_info) +{ + const char *field_names[] = {"Z", "m", "A", "rn", "ra", "eels_maj_edg", "eels_min_edg", "coef"}; + dt_int32 number_of_fields = 8; + mwSize dims[2] = {1, atomic_info.size()}; + + mxArray* mx_field_coef = nullptr; + const char *field_names_Coef[] = {"charge", "feg", "fxg", "pr", "vr", "vzp"}; + dt_int32 number_of_fields_Coef = 6; + mwSize dims_Coef[2] = {1, 1}; + + mxArray* mx_field_coef_par = nullptr; + const char *field_names_coef_par[] = {"cl", "cnl"}; + dt_int32 number_of_fields_coef_par = 2; + mwSize dims_coef_par[2] = {1, 1}; + + mx_atomic_info = mxCreateStructArray(2, dims, number_of_fields, field_names); + for(auto i = 0; i < atomic_info.size(); i++) + { + mex_create_set_num_field(mx_atomic_info, i, "Z", atomic_info[i].Z); + mex_create_set_num_field(mx_atomic_info, i, "m", atomic_info[i].m); + mex_create_set_num_field(mx_atomic_info, i, "A", atomic_info[i].A); + mex_create_set_num_field(mx_atomic_info, i, "rn", atomic_info[i].rn); + mex_create_set_num_field(mx_atomic_info, i, "ra", atomic_info[i].ra); + + mex_create_set_pVctr_field(mx_atomic_info, i, "eels_maj_edg", atomic_info[i].eels_maj_edg); + mex_create_set_pVctr_field(mx_atomic_info, i, "eels_min_edg", atomic_info[i].eels_min_edg); + + + mwSize dims_Coef[2] = {1, atomic_info[i].coef.size()}; + mx_field_coef = mxCreateStructArray(2, dims_Coef, number_of_fields_Coef, field_names_Coef); + mxSetField(mx_atomic_info, i, "coef", mx_field_coef); + + for(auto j = 0; j < atomic_info[i].coef.size(); j++) + { + auto &coef = atomic_info[i].coef[j]; + + /***************************************************************************************/ + mex_create_set_num_field(mx_field_coef, j, "charge", coef.charge); + + /***************************************************************************************/ + mx_field_coef_par = mxCreateStructArray(2, dims_coef_par, number_of_fields_coef_par, field_names_coef_par); + mxSetField(mx_field_coef, j, "feg", mx_field_coef_par); + mex_create_set_pVctr_field(mx_field_coef_par, "cl", coef.feg.cl); + mex_create_set_pVctr_field(mx_field_coef_par, "cnl", coef.feg.cnl); + + /***************************************************************************************/ + mx_field_coef_par = mxCreateStructArray(2, dims_coef_par, number_of_fields_coef_par, field_names_coef_par); + mxSetField(mx_field_coef, j, "fxg", mx_field_coef_par); + mex_create_set_pVctr_field(mx_field_coef_par, "cl", coef.fxg.cl); + mex_create_set_pVctr_field(mx_field_coef_par, "cnl", coef.fxg.cnl); + + /***************************************************************************************/ + mx_field_coef_par = mxCreateStructArray(2, dims_coef_par, number_of_fields_coef_par, field_names_coef_par); + mxSetField(mx_field_coef, j, "pr", mx_field_coef_par); + mex_create_set_pVctr_field(mx_field_coef_par, "cl", coef.pr.cl); + mex_create_set_pVctr_field(mx_field_coef_par, "cnl", coef.pr.cnl); + + /***************************************************************************************/ + mx_field_coef_par = mxCreateStructArray(2, dims_coef_par, number_of_fields_coef_par, field_names_coef_par); + mxSetField(mx_field_coef, j, "vr", mx_field_coef_par); + mex_create_set_pVctr_field(mx_field_coef_par, "cl", coef.vr.cl); + mex_create_set_pVctr_field(mx_field_coef_par, "cnl", coef.vr.cnl); + + /***************************************************************************************/ + mx_field_coef_par = mxCreateStructArray(2, dims_coef_par, number_of_fields_coef_par, field_names_coef_par); + mxSetField(mx_field_coef, j, "vzp", mx_field_coef_par); + mex_create_set_pVctr_field(mx_field_coef_par, "cl", coef.vzp.cl); + mex_create_set_pVctr_field(mx_field_coef_par, "cnl", coef.vzp.cnl); + + } + } +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto atomic_pot_parm_typ = mex_get_enum(prhs[0]); + + mt::Vctr_cpu> atomic_info(mt::c_n_atom_typ); + mt::Atomic_Data atomic_data_mt(atomic_pot_parm_typ); + + for(auto ik = 0; ik < atomic_info.size(); ik++) + { + auto Z = ik+1; + atomic_info[ik] = atomic_data_mt(Z, atomic_pot_parm_typ); + } + + set_output_data(atomic_info, plhs[0]); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_atomic_radius.cpp b/mex_files_multem/ilc_atomic_radius.cpp new file mode 100755 index 00000000..4abbeede --- /dev/null +++ b/mex_files_multem/ilc_atomic_radius.cpp @@ -0,0 +1,51 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_data_mt.cuh" +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_enum(prhs[0]); + auto dim = mex_get_num(prhs[1]); + auto vr_lim = mex_get_num(prhs[2]); + + /***************************************************************************************/ + auto pradius = mex_create_pVctr({mt::c_n_atom_typ, 3}, plhs[0]); + + mt::Atomic_Data atomic_data; + mt::Atomic_Fcns atomic_fcns; + + for(auto ik = 0; ik< pradius.s0(); ik++) + { + auto Z = ik+1; + auto atomic_info = atomic_data(Z, atomic_pot_parm_typ); + atomic_fcns.set_atomic_coef(atomic_info.coef[0]); + + pradius(ik, 0) = atomic_fcns.atomic_radius_rms(dim); + pradius(ik, 1) = atomic_fcns.atomic_radius_cutoff(dim, vr_lim); + pradius(ik, 2) = atomic_info.atomic_radius(); + } +} \ No newline at end of file diff --git a/mex_files_multem/ilc_crystal_by_lays.cpp b/mex_files_multem/ilc_crystal_by_lays.cpp deleted file mode 100644 index 570279ec..00000000 --- a/mex_files_multem/ilc_crystal_by_lays.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "atomic_data_mt.hpp" -#include "xtl_build.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -/*******************Matlab to layer unit cell*********************/ -void read_input_data(const mxArray *mxCrystal, int &na, int &nb, int &nc, double &a, double &b, double &c, mt::Vector, mt::e_host> &uLayer) -{ - na = mx_get_scalar_field(mxCrystal, "na"); - nb = mx_get_scalar_field(mxCrystal, "nb"); - nc = mx_get_scalar_field(mxCrystal, "nc"); - - a = mx_get_scalar_field(mxCrystal, "a"); - b = mx_get_scalar_field(mxCrystal, "b"); - c = mx_get_scalar_field(mxCrystal, "c"); - - auto nuLayer = mx_get_scalar_field(mxCrystal, "nuLayer"); - - mxArray *mexuLayer; - mexuLayer = mxGetField(mxCrystal, 0, "uLayer"); - - uLayer.resize(nuLayer); - for(auto i = 0; i < uLayer.size(); i++) - { - auto atoms = mx_get_matrix_field(mexuLayer, i, "atoms"); - uLayer[i].set_atoms(atoms.rows, atoms.cols, atoms.real); - } -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - int na, nb, nc; - double a, b, c; - mt::Vector, mt::e_host> uLayer; - mt::Atom_Data atoms; - mt::Crystal_Spec xtl_build; - - read_input_data(prhs[0], na, nb, nc, a, b, c, uLayer); - - xtl_build(na, nb, nc, a, b, c, uLayer, atoms); - - auto atomsM = mx_create_matrix(atoms.size(), 8, plhs[0]); - - for(auto i = 0; i + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" +#include "pn_fact.hpp" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto E_0 = mex_get_num(prhs[0]); + auto pbs = mex_get_pvctr(prhs[1]); + auto ptheta = mex_get_pvctr(prhs[2]); + + /***************************************************************************************/ + auto psize = mex_create_pVctr({ptheta.size(), pbs.size()}, plhs[0]); + + mt::PN_Fact pn_fact; + for (auto ik = 0; ik < ptheta.size(); ik++) + { + // from milliradians to g + auto g_max = mt::fcn_rad_2_rangs(E_0, ptheta[ik]*mt::c_mrad_2_rad); + + // g_max = nx/(2*lx) -> nx = 2*g_max*lx + for(auto ix = 0; ix< pbs.size(); ix++) + { + psize(ik, ix) = pn_fact(dt_int64(::round(2*pbs[ix]*g_max)), mt::edst_egreater_than); + } + } +} \ No newline at end of file diff --git a/mex_files_multem/ilc_elec_interact_parm_kva.cpp b/mex_files_multem/ilc_elec_interact_parm_kva.cpp new file mode 100755 index 00000000..27ac6701 --- /dev/null +++ b/mex_files_multem/ilc_elec_interact_parm_kva.cpp @@ -0,0 +1,37 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + auto psigma = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < psigma.size(); ik++) + { + psigma[ik] = mt::fcn_elec_interact_parm_kva(pE_0[ik]); + } +} \ No newline at end of file diff --git a/mex_files_multem/ilc_feg.cpp b/mex_files_multem/ilc_feg.cpp old mode 100644 new mode 100755 index 84dfd865..906520ad --- a/mex_files_multem/ilc_feg.cpp +++ b/mex_files_multem/ilc_feg.cpp @@ -1,45 +1,43 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "atomic_fcns_mt.hpp" -#include "atomic_data.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto potential_type = mx_get_scalar(prhs[0]); - auto Z = mx_get_scalar(prhs[1]); - auto charge = mx_get_scalar(prhs[2]); - auto g = mx_get_matrix(prhs[3]); - - auto feg = mx_create_matrix(g.rows, g.cols, plhs[0]); - auto dfeg = mx_create_matrix(g.rows, g.cols, plhs[1]); - - mt::Atom_Type atom_type; - mt::Atomic_Data atomic_data(potential_type); - atomic_data.To_atom_type_CPU(Z, mt::c_Vrl, mt::c_nR, 0.0, atom_type); - - mt::Atom_Cal atomic_fcns_mt; - atomic_fcns_mt.Set_Atom_Type(potential_type, charge, &atom_type); - atomic_fcns_mt.feg_dfeg(g.m_size, g.real, feg.real, dfeg.real); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_num(prhs[0]); + auto Z = mex_get_num(prhs[1]); + auto charge = mex_get_num(prhs[2]); + auto g = mex_get_pvctr(prhs[3]); + + /***************************************************************************************/ + auto feg = mex_create_pVctr(g.shape(), plhs[0]); + auto dfeg = mex_create_pVctr(g.shape(), plhs[1]); + + mt::Atomic_Info_cpu atomic_info = mt::Atomic_Data(Z, atomic_pot_parm_typ, charge); + mt::Atomic_Fcns atomic_fcns_mt(atomic_info.coef[0]); + + atomic_fcns_mt.feg_dfeg(g.ptr_32(), feg.ptr_32(), dfeg.ptr_32()); } \ No newline at end of file diff --git a/mex_files_multem/ilc_feg_parm_coef.cpp b/mex_files_multem/ilc_feg_parm_coef.cpp new file mode 100755 index 00000000..a3887713 --- /dev/null +++ b/mex_files_multem/ilc_feg_parm_coef.cpp @@ -0,0 +1,39 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_data_mt.cuh" +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_num(prhs[0]); + auto Z = mex_get_num(prhs[1]); + auto charge = mex_get_num(prhs[2]); + + /***************************************************************************************/ + mt::Atomic_Info_cpu atomic_info = mt::Atomic_Data(Z, atomic_pot_parm_typ, charge); + mex_create_set_pVctr(plhs[0], atomic_info.coef[0].feg.cl.ptr_64()); + mex_create_set_pVctr(plhs[1], atomic_info.coef[0].feg.cnl.ptr_64()); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_fwhm_2_sigma.cpp b/mex_files_multem/ilc_fwhm_2_sigma.cpp old mode 100644 new mode 100755 index 2acef2e0..b2b01c15 --- a/mex_files_multem/ilc_fwhm_2_sigma.cpp +++ b/mex_files_multem/ilc_fwhm_2_sigma.cpp @@ -1,35 +1,37 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto val = mx_get_scalar(prhs[0]); - - /******************************************************************/ - auto rAgs = mx_create_scalar(plhs[0]); - - rAgs[0] = mt::fwhm_2_sigma(val); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pfwhm = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + auto psigma = mex_create_pVctr(pfwhm.shape(), plhs[0]); + + for (auto ik = 0; ik < psigma.size(); ik++) + { + psigma[ik] = mt::fcn_fwhm_2_sigma(pfwhm[ik]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_fxeg_data.cpp b/mex_files_multem/ilc_fxeg_data.cpp old mode 100644 new mode 100755 index 0f3518f3..09a07952 --- a/mex_files_multem/ilc_fxeg_data.cpp +++ b/mex_files_multem/ilc_fxeg_data.cpp @@ -1,44 +1,40 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include -#include "fxeg_data.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - int ng; - double g[1024], g2[1024], fxg[1024], feg[1024]; - fxeg_Tabulated_Data fxeg_data; - - auto Z = mx_get_scalar(prhs[0]); - auto type = mx_get_scalar(prhs[1]); - fxeg_data.ReadTabData(Z, type, 1, ng, g, g2, fxg, feg); - - auto g_o = mx_create_matrix(ng, 1, plhs[0]); - auto fxg_o = mx_create_matrix(ng, 1, plhs[1]); - auto feg_o = mx_create_matrix(ng, 1, plhs[2]); - - std::copy(g, g + ng, g_o.real); - std::copy(fxg, fxg + ng, fxg_o.real); - std::copy(feg, feg + ng, feg_o.real); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fxeg_data.hpp" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto Z = mex_get_num(prhs[0]); + auto ndg = mex_get_num(prhs[1]); + + /***************************************************************************************/ + mt::Vctr_cpu g, fxg, feg; + mt::fxeg_Data(1, Z, ndg, g, fxg, feg); + + mex_create_set_pVctr(plhs[0], g.ptr_64()); + mex_create_set_pVctr(plhs[1], fxg.ptr_64()); + mex_create_set_pVctr(plhs[2], feg.ptr_64()); } \ No newline at end of file diff --git a/mex_files_multem/ilc_fxg.cpp b/mex_files_multem/ilc_fxg.cpp old mode 100644 new mode 100755 index 4d732ba6..91290b9f --- a/mex_files_multem/ilc_fxg.cpp +++ b/mex_files_multem/ilc_fxg.cpp @@ -1,45 +1,43 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "atomic_fcns_mt.hpp" -#include "atomic_data.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto potential_type = mx_get_scalar(prhs[0]); - auto Z = mx_get_scalar(prhs[1]); - auto charge = mx_get_scalar(prhs[2]); - auto g = mx_get_matrix(prhs[3]); - - auto fxg = mx_create_matrix(g.rows, g.cols, plhs[0]); - auto dfxg = mx_create_matrix(g.rows, g.cols, plhs[1]); - - mt::Atom_Type atom_type; - mt::Atomic_Data atomic_data(potential_type); - atomic_data.To_atom_type_CPU(Z, mt::c_Vrl, mt::c_nR, 0.0, atom_type); - - mt::Atom_Cal atomic_fcns_mt; - atomic_fcns_mt.Set_Atom_Type(potential_type, charge, &atom_type); - atomic_fcns_mt.fxg_dfxg(g.m_size, g.real, fxg.real, dfxg.real); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_num(prhs[0]); + auto Z = mex_get_num(prhs[1]); + auto charge = mex_get_num(prhs[2]); + auto g = mex_get_pvctr(prhs[3]); + + /***************************************************************************************/ + auto fxg = mex_create_pVctr(g.shape(), plhs[0]); + auto dfxg = mex_create_pVctr(g.shape(), plhs[1]); + + mt::Atomic_Info_cpu atomic_info = mt::Atomic_Data(Z, atomic_pot_parm_typ, charge); + mt::Atomic_Fcns atomic_fcns_mt(atomic_info.coef[0]); + + atomic_fcns_mt.fxg_dfxg(g.ptr_32(), fxg.ptr_32(), dfxg.ptr_32()); } \ No newline at end of file diff --git a/mex_files_multem/ilc_g_max.cpp b/mex_files_multem/ilc_g_max.cpp new file mode 100755 index 00000000..4fb239e4 --- /dev/null +++ b/mex_files_multem/ilc_g_max.cpp @@ -0,0 +1,39 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pbs = mex_get_pvctr(prhs[0]); + auto pn = mex_get_pvctr(prhs[1]); + + /***************************************************************************************/ + auto pg_max = mex_create_num(plhs[0]); + + dt_float64 v = pn[0]/pbs[0]; + for (auto ik = 1; ik < pbs.size(); ik++) + { + v = min(v, pn[0]/pbs[0]); + } + + pg_max[0] = 0.5*v; +} diff --git a/mex_files_multem/ilc_gamma.cpp b/mex_files_multem/ilc_gamma.cpp old mode 100644 new mode 100755 index 87da7c9c..baaa5a6e --- a/mex_files_multem/ilc_gamma.cpp +++ b/mex_files_multem/ilc_gamma.cpp @@ -1,35 +1,37 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - - /******************************************************************/ - auto rgamma = mx_create_scalar(plhs[0]); - - rgamma[0] = mt::get_gamma(E0); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + auto pgamma = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < pgamma.size(); ik++) + { + pgamma[ik] = mt::fcn_gamma(pE_0[ik]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_gmax.cpp b/mex_files_multem/ilc_gmax.cpp deleted file mode 100644 index fc05377a..00000000 --- a/mex_files_multem/ilc_gmax.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto lx = mx_get_scalar(prhs[0]); - auto nx = mx_get_scalar(prhs[1]); - auto ly = (nrhs > 2) ? mx_get_scalar(prhs[2]) : lx; - auto ny = (nrhs > 3) ? mx_get_scalar(prhs[3]) : nx; - - auto g_max = 0.5*min(nx / lx, ny / ly); - - /******************************************************************/ - auto rg_max = mx_create_scalar(plhs[0]); - - rg_max[0] = g_max; -} \ No newline at end of file diff --git a/mex_files_multem/ilc_hwhm_2_sigma.cpp b/mex_files_multem/ilc_hwhm_2_sigma.cpp old mode 100644 new mode 100755 index 3a417ed8..b4549006 --- a/mex_files_multem/ilc_hwhm_2_sigma.cpp +++ b/mex_files_multem/ilc_hwhm_2_sigma.cpp @@ -1,35 +1,37 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto val = mx_get_scalar(prhs[0]); - - /******************************************************************/ - auto rAgs = mx_create_scalar(plhs[0]); - - rAgs[0] = mt::hwhm_2_sigma(val); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto phwhm = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + auto psigma = mex_create_pVctr(phwhm.shape(), plhs[0]); + + for (auto ik = 0; ik < psigma.size(); ik++) + { + psigma[ik] = mt::fcn_hwhm_2_sigma(phwhm[ik]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_iehwgd_2_sigma.cpp b/mex_files_multem/ilc_iehwgd_2_sigma.cpp old mode 100644 new mode 100755 index 96799d78..f591890d --- a/mex_files_multem/ilc_iehwgd_2_sigma.cpp +++ b/mex_files_multem/ilc_iehwgd_2_sigma.cpp @@ -1,35 +1,37 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto val = mx_get_scalar(prhs[0]); - - /******************************************************************/ - auto rAgs = mx_create_scalar(plhs[0]); - - rAgs[0] = mt::iehwgd_2_sigma(val); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto piehwgd = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + auto psigma = mex_create_pVctr(piehwgd.shape(), plhs[0]); + + for (auto ik = 0; ik < psigma.size(); ik++) + { + psigma[ik] = mt::fcn_iehwgd_2_sigma(piehwgd[ik]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_incident_wave.cu b/mex_files_multem/ilc_incident_wave.cu old mode 100644 new mode 100755 index 828908a3..4c26598c --- a/mex_files_multem/ilc_incident_wave.cu +++ b/mex_files_multem/ilc_incident_wave.cu @@ -1,192 +1,156 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" - -#include "incident_wave.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; -using mt::rmatrix_c; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - input_multislice.simulation_type = mt::eTEMST_IWRS; - - /**************************** Specimen *****************************/ - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - T_r lz = 0; - T_r dz = 0.25; - bool pbc_xy = true; - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = false; - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************ Incident wave ****************************/ - auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); - input_multislice.set_incident_wave_type(iw_type); - - if(input_multislice.is_user_define_wave() && full) - { - auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); - mt::assign(iw_psi, input_multislice.iw_psi); - } - - // read iw_x and iw_y - auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); - auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin()+n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin()+n_iw_xy); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; - input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; - - /****************************** Condenser lens ********************************/ - input_multislice.cond_lens.m = mx_get_scalar_field(mx_input_multislice, "cond_lens_m"); // momentum of the vortex - input_multislice.cond_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_10"); // defocus (Angstrom) - input_multislice.cond_lens.c_12 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_12"); // 2-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_12 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_21 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_21"); // Axial coma (Angstrom) - input_multislice.cond_lens.phi_21 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.cond_lens.c_23 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_23"); // 3-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_23 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_30 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_30")*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.c_32 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_32"); // Axial star aberration (Angstrom) - input_multislice.cond_lens.phi_32 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_34 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_34"); // 4-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_34 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_41 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_41"); // 4th order axial coma (Angstrom) - input_multislice.cond_lens.phi_41 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.cond_lens.c_43 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_43"); // 3-lobe aberration (Angstrom) - input_multislice.cond_lens.phi_43 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.cond_lens.c_45 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_45"); // 5-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_45 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_50 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_50")*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.c_52 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_52"); // 5th order axial star aberration (Angstrom) - input_multislice.cond_lens.phi_52 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_54 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_54"); // 5th order rosette aberration (Angstrom) - input_multislice.cond_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) - input_multislice.cond_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_56"); // 6-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.cond_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) // outer aperture(mrad-->rad) - - input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); -} - -template -void set_struct_incident_wave(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "psi_0"}; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - mx_create_set_matrix_field(mx_output_multislice, "psi_0", output_multislice.ny, output_multislice.nx, output_multislice.psi_0[0]); -} - -template -void run_incident_wave(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - - mt::Incident_Wave incident_wave; - incident_wave.set_input_data(&input_multislice, &stream, &fft_2d); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - incident_wave(mt::eS_Real, output_multislice); - - stream.synchronize(); - - output_multislice.gather(); - output_multislice.clean_temporal(); - fft_2d.cleanup(); - - set_struct_incident_wave(output_multislice, mx_output_multislice); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; - - if(system_conf.is_float_host()) - { - run_incident_wave(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_host()) - { - run_incident_wave(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_float_device()) - { - run_incident_wave(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_device()) - { - run_incident_wave(system_conf, prhs[idx_0], plhs[0]); - } +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "cgpu_fft.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" + +#include "incident_wave.cuh" + +#include +#include "matlab_mex.h" +#include "matlab_multem_io.h" + +using mt::pMLD; +using mt::pMx_c; + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice &multem_in_parm, dt_bool full = true) +{ + using T_r = mt::Value_type;gr + + multem_in_parm.em_sim_typ = mt::eemst_iwrs; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + T_r sli_thick = 0.25; + dt_bool pbc_xy = true; + + /************************** xy sampling ****************************/ + auto nx = mex_get_num_from_field(mex_multem_in_parm, "nx"); + auto ny = mex_get_num_from_field(mex_multem_in_parm, "ny"); + dt_bool bwl = false; + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + /************************ Incident wave ****************************/ + auto iw_type = mex_get_num_from_field(mex_multem_in_parm, "iw_type"); + multem_in_parm.set_incident_wave_type(iw_type); + + if (multem_in_parm.is_user_define_wave() && full) + { + mex_read_user_define_wave(mex_multem_in_parm, multem_in_parm.iw_psi); + } + + /********************* read beam positions *************************/ + mex_read_beam_pos(mex_multem_in_parm, multem_in_parm.beam_pos_2d); + + /********************* Microscope parameter ***********************/ + multem_in_parm.E_0 = mex_get_num_from_field(mex_multem_in_parm, "E_0"); + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "theta")*mt::c_deg_2_rad; + multem_in_parm.phi = mex_get_num_from_field(mex_multem_in_parm, "phi")*mt::c_deg_2_rad; + + /*********************** Condenser lens ***************************/ + mex_read_cond_lens(mex_multem_in_parm, multem_in_parm.cond_lens); + multem_in_parm.cond_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /*********************** Objective lens ***************************/ + mex_read_obj_lens(mex_multem_in_parm, multem_in_parm.obj_lens); + multem_in_parm.obj_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + multem_in_parm.cond_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /******************** select output region ************************/ + mex_read_output_area(mex_multem_in_parm, multem_in_parm.output_area); + + /********************* validate parameters *************************/ + multem_in_parm.set_dep_var(); +} + +template +void set_struct_incident_wave(TOutput_Multem &output_multem, mxArray*& mex_output_multem) +{ + const char *field_names_output_multem[] = {"dx", "dy", "x", "y", "thick", "psi_0"}; + dt_int32 number_of_fields_output_multem = 6; + mwSize dims_output_multem[2] = {1, 1}; + + mex_output_multem = mxCreateStructArray(2, dims_output_multem, number_of_fields_output_multem, field_names_output_multem); + + mex_create_set_num_field(mex_output_multem, 0, "dx", output_multem.dx); + mex_create_set_num_field(mex_output_multem, 0, "dy", output_multem.dy); + mex_create_set_pVctr_field(mex_output_multem, "x", 1, output_multem.x.size(), output_multem.x); + mex_create_set_pVctr_field(mex_output_multem, "y", 1, output_multem.y.size(), output_multem.y); + mex_create_set_pVctr_field(mex_output_multem, "thick", 1, output_multem.thick.size(), output_multem.thick); + mex_create_set_pVctr_field(mex_output_multem, "psi_0", output_multem.ny, output_multem.nx, output_multem.psi_0[0]); +} + +template +void run_incident_wave(mt::System_Config &system_config, const mxArray* mex_multem_in_parm, mxArray*& mex_output_multem) +{ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(mex_multem_in_parm, multem_in_parm); + multem_in_parm.system_config = system_config; + + mt::Stream stream(system_config.n_stream); + mt::FFT fft_2d; + fft_2d.create_plan_2d(multem_in_parm.grid_2d.ny, multem_in_parm.grid_2d.nx, system_config.n_stream); + + mt::Incident_Wave incident_wave; + incident_wave.set_in_data(&multem_in_parm, &stream, &fft_2d); + + mt::Output_Multem output_multem; + output_multem.set_in_data(&multem_in_parm); + + incident_wave(mt::esp_real, output_multem); + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + fft_2d.cleanup(); + + set_struct_incident_wave(output_multem, mex_output_multem); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto system_config = mex_read_system_config(prhs[0]); + system_config.set_gpu(); + + dt_int32 idx_0 = (system_config.active)?1:0; + + if (system_config.is_float32_cpu()) + { + run_incident_wave(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_cpu()) + { + run_incident_wave(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float32_gpu()) + { + run_incident_wave(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_gpu()) + { + run_incident_wave(system_config, prhs[idx_0], plhs[0]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_lambda.cpp b/mex_files_multem/ilc_lambda.cpp old mode 100644 new mode 100755 index 1126b913..9eb4a052 --- a/mex_files_multem/ilc_lambda.cpp +++ b/mex_files_multem/ilc_lambda.cpp @@ -1,35 +1,37 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - - /******************************************************************/ - auto rlambda = mx_create_scalar(plhs[0]); - - rlambda[0] = mt::get_lambda(E0); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + auto plambda = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < plambda.size(); ik++) + { + plambda[ik] = mt::fcn_lambda(pE_0[ik]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_max_dist.cpp b/mex_files_multem/ilc_max_dist.cpp new file mode 100755 index 00000000..05310985 --- /dev/null +++ b/mex_files_multem/ilc_max_dist.cpp @@ -0,0 +1,63 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "particle_fcns.hpp" + +#include +#include "matlab_mex.h" + + +template +void mex_run(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pvr = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + std::tuple dist_t; + + if (pvr.m_s1==2) + { + mt::Vctr_r_2d_cpu vctr_r_2d(pvr.data(), pvr.s0()); + dist_t = mt::fcn_vctr_r_nd_dist(vctr_r_2d, std::greater()); + } + else + { + mt::Vctr_r_3d_cpu vctr_r_3d(pvr.data(), pvr.s0()); + dist_t = mt::fcn_vctr_r_nd_dist(vctr_r_3d, std::greater()); + } + + mex_create_set_num(plhs[0], std::get<0>(dist_t)); + + if (nlhs>1) + { + mex_create_set_num(plhs[1], std::get<1>(dist_t)); + } + + if (nlhs>2) + { + mex_create_set_num(plhs[2], std::get<2>(dist_t)); + } +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + MEX_RUN_FCN_FLOAT(mex_run, 0); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_microscope_aberrations.cu b/mex_files_multem/ilc_microscope_aberrations.cu old mode 100644 new mode 100755 index b1eb42ff..561d8894 --- a/mex_files_multem/ilc_microscope_aberrations.cu +++ b/mex_files_multem/ilc_microscope_aberrations.cu @@ -1,221 +1,164 @@ -/** - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "atomic_data_mt.hpp" -#include "input_multislice.cuh" -#include "output_multislice.hpp" - -#include "microscope_effects.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; -using mt::rmatrix_c; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - /************************ simulation type **************************/ - input_multislice.simulation_type = mt::eTEMST_HRTEM; - - /**************************** Specimen *****************************/ - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - T_r lz = 0; - T_r dz = 0.25; - bool pbc_xy = true; - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = false; - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************ Incident wave ****************************/ - auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); - input_multislice.set_incident_wave_type(iw_type); - - if (input_multislice.is_user_define_wave() && full) - { - auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); - mt::assign(iw_psi, input_multislice.iw_psi); - } - - // read iw_x and iw_y - auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); - auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin() + n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin() + n_iw_xy); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; - input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; - - /********************* Illumination model *************************/ - input_multislice.illumination_model = mx_get_scalar_field(mx_input_multislice, "illumination_model"); - input_multislice.temporal_spatial_incoh = mx_get_scalar_field(mx_input_multislice, "temporal_spatial_incoh"); - - /********************* source spread function *********************/ - input_multislice.cond_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_sigma"); // standard deviation: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.cond_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_rad_npts"); // # of integration points - - input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /*********************** Objective lens ***************************/ - input_multislice.obj_lens.m = mx_get_scalar_field(mx_input_multislice, "obj_lens_m"); // momentum of the vortex - input_multislice.obj_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_10"); // defocus (Angstrom) - input_multislice.obj_lens.c_12 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_12"); // 2-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_12 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_21 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_21"); // Axial coma (Angstrom) - input_multislice.obj_lens.phi_21 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.obj_lens.c_23 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_23"); // 3-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_23 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_30 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_30")*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.c_32 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_32"); // Axial star aberration (Angstrom) - input_multislice.obj_lens.phi_32 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_34 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_34"); // 4-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_34 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_41 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_41"); // 4th order axial coma (Angstrom) - input_multislice.obj_lens.phi_41 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.obj_lens.c_43 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_43"); // 3-lobe aberration (Angstrom) - input_multislice.obj_lens.phi_43 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.obj_lens.c_45 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_45"); // 5-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_45 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_50 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_50")*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.c_52 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_52"); // 5th order axial star aberration (Angstrom) - input_multislice.obj_lens.phi_52 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_54"); // 5th order rosette aberration (Angstrom) - input_multislice.obj_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration(degrees-->rad) - input_multislice.obj_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_56"); // 6-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.obj_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - /********************* defocus spread function ********************/ - input_multislice.obj_lens.ti_a = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.obj_lens.ti_sigma = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.ti_beta = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.ti_npts = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_npts"); // Number of integration points - - /********************* source spread function *********************/ - input_multislice.obj_lens.si_a = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.obj_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.si_beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_rad_npts"); // Number of radial integration points - input_multislice.obj_lens.si_azm_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_azm_npts"); // Number of azimuth integration points - - /********************* zero defocus reference ********************/ - input_multislice.obj_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_type"); // Zero defocus type - input_multislice.obj_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_plane"); // Zero defocus position - - input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); -} - -template -void set_struct_microscope_aberrations(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = { "dx", "dy", "x", "y", "thick", "m2psi" }; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = { 1, 1 }; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - mx_create_set_matrix_field(mx_output_multislice, "m2psi", output_multislice.ny, output_multislice.nx, output_multislice.m2psi_tot[0]); -} - -template -void run_microscope_aberrations(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - - mt::Microscope_Effects microscope_effects; - microscope_effects.set_input_data(&input_multislice, &stream, &fft_2d); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - microscope_effects(output_multislice); - - stream.synchronize(); - - //output_multislice.gather(); - output_multislice.clean_temporal(); - fft_2d.cleanup(); - - set_struct_microscope_aberrations(output_multislice, mx_output_multislice); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active) ? 1 : 0; - - if (system_conf.is_float_host()) - { - run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_double_host()) - { - run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_float_device()) - { - run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_double_device()) - { - run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); - } +/** + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "cgpu_fft.cuh" +#include "particles.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" + +#include "microscope_effects.cuh" + +#include +#include "matlab_mex.h" + +using mt::pMLD; +using mt::pMx_c; + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice &multem_in_parm, dt_bool full = true) +{ + using T_r = mt::Value_type; + + multem_in_parm.em_sim_typ = mt::eemst_hrtem; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + T_r bs_z = 0; + T_r sli_thick = 0.25; + dt_bool pbc_xy = true; + + /************************** xy sampling ****************************/ + auto nx = mex_get_num_from_field(mex_multem_in_parm, "nx"); + auto ny = mex_get_num_from_field(mex_multem_in_parm, "ny"); + dt_bool bwl = false; + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + /************************ Incident wave ****************************/ + auto iw_type = mex_get_num_from_field(mex_multem_in_parm, "iw_type"); + multem_in_parm.set_incident_wave_type(iw_type); + + if (multem_in_parm.is_user_define_wave() && full) + { + mex_read_user_define_wave(mex_multem_in_parm, multem_in_parm.iw_psi); + } + + /********************* read beam positions *************************/ + mex_read_beam_pos(mex_multem_in_parm, multem_in_parm.beam_pos_2d); + + /********************* Microscope parameter ***********************/ + multem_in_parm.E_0 = mex_get_num_from_field(mex_multem_in_parm, "E_0"); + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "theta")*mt::c_deg_2_rad; + multem_in_parm.phi = mex_get_num_from_field(mex_multem_in_parm, "phi")*mt::c_deg_2_rad; + + /********************* Illumination model *************************/ + multem_in_parm.illum_mod = mex_get_num_from_field(mex_multem_in_parm, "illum_mod"); + multem_in_parm.illum_inc = mex_get_num_from_field(mex_multem_in_parm, "illum_inc"); + + /*********************** Condenser lens ***************************/ + mex_read_cond_lens(mex_multem_in_parm, multem_in_parm.cond_lens); + multem_in_parm.cond_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /*********************** Objective lens ***************************/ + mex_read_obj_lens(mex_multem_in_parm, multem_in_parm.obj_lens); + multem_in_parm.obj_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /********************* zero defocus reference ********************/ + multem_in_parm.obj_lens.zero_def_typ = mt::ezdt_last; + multem_in_parm.obj_lens.zero_def_plane = 0.0; + + /******************** select output region ************************/ + mex_read_output_area(mex_multem_in_parm, multem_in_parm.output_area); + + /********************* validate parameters *************************/ + multem_in_parm.set_dep_var(); +} + +template +void set_struct_microscope_aberrations(TOutput_Multem &output_multem, mxArray*& mex_output_multem) +{ + const char *field_names_output_multem[] = { "dx", "dy", "x", "y", "thick", "m2psi" }; + dt_int32 number_of_fields_output_multem = 6; + mwSize dims_output_multem[2] = { 1, 1 }; + + mex_output_multem = mxCreateStructArray(2, dims_output_multem, number_of_fields_output_multem, field_names_output_multem); + + mex_create_set_num_field(mex_output_multem, 0, "dx", output_multem.dx); + mex_create_set_num_field(mex_output_multem, 0, "dy", output_multem.dy); + mex_create_set_pVctr_field(mex_output_multem, "x", 1, output_multem.x.size(), output_multem.x); + mex_create_set_pVctr_field(mex_output_multem, "y", 1, output_multem.y.size(), output_multem.y); + mex_create_set_pVctr_field(mex_output_multem, "thick", 1, output_multem.thick.size(), output_multem.thick); + mex_create_set_pVctr_field(mex_output_multem, "m2psi", output_multem.ny, output_multem.nx, output_multem.m2psi_tot[0]); +} + +template +void run_microscope_aberrations(mt::System_Config &system_config, const mxArray* mex_multem_in_parm, mxArray*& mex_output_multem) +{ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(mex_multem_in_parm, multem_in_parm); + multem_in_parm.system_config = system_config; + + mt::Stream stream(system_config.n_stream); + mt::FFT fft_2d; + fft_2d.create_plan_2d(multem_in_parm.grid_2d.ny, multem_in_parm.grid_2d.nx, system_config.n_stream); + + mt::Microscope_Effects microscope_effects; + microscope_effects.set_in_data(&multem_in_parm, &stream, &fft_2d); + + mt::Output_Multem output_multem; + output_multem.set_in_data(&multem_in_parm); + + microscope_effects(output_multem); + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + fft_2d.cleanup(); + + set_struct_microscope_aberrations(output_multem, mex_output_multem); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto system_config = mex_read_system_config(prhs[0]); + system_config.set_gpu(); + + dt_int32 idx_0 = (system_config.active)?1:0; + + if (system_config.is_float32_cpu()) + { + run_microscope_aberrations(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_cpu()) + { + run_microscope_aberrations(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float32_gpu()) + { + run_microscope_aberrations(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_gpu()) + { + run_microscope_aberrations(system_config, prhs[idx_0], plhs[0]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_min_dist.cpp b/mex_files_multem/ilc_min_dist.cpp new file mode 100755 index 00000000..f9b7b5f8 --- /dev/null +++ b/mex_files_multem/ilc_min_dist.cpp @@ -0,0 +1,64 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "particle_fcns.hpp" + +#include +#include "matlab_mex.h" + + +template +void mex_run(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pvr = mex_get_pvctr(prhs[0]); + + /***************************************************************************************/ + std::tuple dist_t; + + if (pvr.m_s1==2) + { + mt::Vctr_r_2d_cpu vctr_r_2d(pvr.data(), pvr.s0()); + dist_t = mt::fcn_vctr_r_nd_dist(vctr_r_2d, std::less()); + } + else + { + mt::Vctr_r_3d_cpu vctr_r_3d(pvr.data(), pvr.s0()); + dist_t = mt::fcn_vctr_r_nd_dist(vctr_r_3d, std::less()); + } + + mex_create_set_num(plhs[0], std::get<0>(dist_t)); + + if (nlhs>1) + { + mex_create_set_num(plhs[1], std::get<1>(dist_t)); + } + + if (nlhs>2) + { + mex_create_set_num(plhs[2], std::get<2>(dist_t)); + } + +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + MEX_RUN_FCN_FLOAT(mex_run, 0); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_min_spl.cpp b/mex_files_multem/ilc_min_spl.cpp deleted file mode 100644 index 6c1ead38..00000000 --- a/mex_files_multem/ilc_min_spl.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - auto lx = mx_get_scalar(prhs[1]); - auto ly = (nrhs > 3)?mx_get_scalar(prhs[2]):lx; - int idx_theta = (nrhs==3)?2:3; - auto theta = mx_get_scalar(prhs[idx_theta])*mt::c_mrad_2_rad; - - auto g_req = mt::rad_2_rAngs(E0, theta); - auto nx = static_cast(round(2*lx*g_req)); - auto ny = static_cast(round(2*ly*g_req)); - - mt::Prime_Num pm; - nx = pm(nx, mt::eDST_Closest); - ny = pm(ny, mt::eDST_Closest); - - /******************************************************************/ - auto rnx = mx_create_scalar(plhs[0]); - rnx[0] = nx; - if(nlhs>1) - { - auto rny = mx_create_scalar(plhs[1]); - rny[0] = ny; - } -} \ No newline at end of file diff --git a/mex_files_multem/ilc_mrad_2_rAng.cpp b/mex_files_multem/ilc_mrad_2_rAng.cpp deleted file mode 100644 index 1be5c31c..00000000 --- a/mex_files_multem/ilc_mrad_2_rAng.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - auto theta = mx_get_scalar(prhs[1])*mt::c_mrad_2_rad; - - /******************************************************************/ - auto rAgs = mx_create_scalar(plhs[0]); - - rAgs[0] = mt::rad_2_rAngs(E0, theta); -} \ No newline at end of file diff --git a/mex_files_multem/ilc_mrad_2_rangs.cpp b/mex_files_multem/ilc_mrad_2_rangs.cpp new file mode 100755 index 00000000..36237830 --- /dev/null +++ b/mex_files_multem/ilc_mrad_2_rangs.cpp @@ -0,0 +1,37 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + auto ptheta = mex_get_pvctr(prhs[1]); + + /***************************************************************************************/ + auto prangs = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < prangs.size(); ik++) + { + prangs[ik] = mt::fcn_rad_2_rangs(pE_0[ik], ptheta[ik]*mt::c_mrad_2_rad); + } +} \ No newline at end of file diff --git a/mex_files_multem/ilc_mrad_2_sigma.cpp b/mex_files_multem/ilc_mrad_2_sigma.cpp old mode 100644 new mode 100755 index 83bc722e..1a26c62e --- a/mex_files_multem/ilc_mrad_2_sigma.cpp +++ b/mex_files_multem/ilc_mrad_2_sigma.cpp @@ -1,36 +1,38 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - auto theta = mx_get_scalar(prhs[1])*mt::c_mrad_2_rad; - - /******************************************************************/ - auto rAgs = mx_create_scalar(plhs[0]); - - rAgs[0] = mt::rad_2_sigma(E0, theta); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + auto ptheta = mex_get_pvctr(prhs[1]); + + /***************************************************************************************/ + auto psigma = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < psigma.size(); ik++) + { + psigma[ik] = mt::fcn_rad_2_sigma(pE_0[ik], ptheta[ik]*mt::c_mrad_2_rad); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_multem.cu b/mex_files_multem/ilc_multem.cu old mode 100644 new mode 100755 index 5584bbbf..b02720f3 --- a/mex_files_multem/ilc_multem.cu +++ b/mex_files_multem/ilc_multem.cu @@ -1,546 +1,318 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "cgpu_fcns.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" -#include "atomic_data_mt.hpp" -#include "tem_simulation.cuh" -#include "timing.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; -using mt::rmatrix_c; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - /************************ simulation type **************************/ - input_multislice.simulation_type = mx_get_scalar_field(mx_input_multislice, "simulation_type"); - - /*******************************************************************/ - input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); - input_multislice.potential_type = mx_get_scalar_field(mx_input_multislice, "potential_type"); - - /*******************************************************************/ - input_multislice.operation_mode = mx_get_scalar_field(mx_input_multislice, "operation_mode"); - input_multislice.reverse_multislice = mx_get_scalar_field(mx_input_multislice, "reverse_multislice"); - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); - input_multislice.pn_coh_contrib = mx_get_scalar_field(mx_input_multislice, "pn_coh_contrib"); - input_multislice.pn_single_conf = mx_get_scalar_field(mx_input_multislice, "pn_single_conf"); - input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); - input_multislice.pn_dim.set(mx_get_scalar_field(mx_input_multislice, "pn_dim")); - input_multislice.pn_seed = mx_get_scalar_field(mx_input_multislice, "pn_seed"); - - /**************************** Specimen *****************************/ - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); - auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = true; - - if (input_multislice.is_specimen_required()) - { - auto atoms = mx_get_matrix_field(mx_input_multislice, "spec_atoms"); - - auto ct_na = mx_get_scalar_field(mx_input_multislice, "spec_cryst_na"); - auto ct_nb = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nb"); - auto ct_nc = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nc"); - auto ct_a = mx_get_scalar_field(mx_input_multislice, "spec_cryst_a"); - auto ct_b = mx_get_scalar_field(mx_input_multislice, "spec_cryst_b"); - auto ct_c = mx_get_scalar_field(mx_input_multislice, "spec_cryst_c"); - auto ct_x0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_x0"); - auto ct_y0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_y0"); - - auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); - mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for (auto i = 0; i < amorp_lay_info.size(); i++) - { - amorp_lay_info[i].z_0 = mx_get_scalar_field(mx_spec_amorp, i, "z_0"); - amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); - amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); - } - - if (full) - { - input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); - input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); - input_multislice.atoms.set_atoms(atoms.rows, atoms.cols, atoms.real, lx, ly, lz, dz); - } - - /************************ Specimen rotation *************************/ - input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; - input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); - input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); - input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); - - /************************ Specimen thickness ***********************/ - input_multislice.thick_type = mx_get_scalar_field(mx_input_multislice, "thick_type"); - if (!input_multislice.is_whole_spec() && full) - { - auto thick = mx_get_matrix_field(mx_input_multislice, "thick"); - mt::assign(thick, input_multislice.thick); - } - - /************************ Potential slicing ************************/ - input_multislice.potential_slicing = mx_get_scalar_field(mx_input_multislice, "potential_slicing"); - } - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = mx_get_scalar_field(mx_input_multislice, "bwl"); - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************ Incident wave ****************************/ - auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); - input_multislice.set_incident_wave_type(iw_type); - - if (input_multislice.is_user_define_wave() && full) - { - auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); - mt::assign(iw_psi, input_multislice.iw_psi); - } - - // read beam_x and beam_y - auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); - auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin() + n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin() + n_iw_xy); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; - input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; - - /********************* Illumination model *************************/ - input_multislice.illumination_model = mx_get_scalar_field(mx_input_multislice, "illumination_model"); - input_multislice.temporal_spatial_incoh = mx_get_scalar_field(mx_input_multislice, "temporal_spatial_incoh"); - - /*********************** Condenser lens ***************************/ - input_multislice.cond_lens.m = mx_get_scalar_field(mx_input_multislice, "cond_lens_m"); // momentum of the vortex - input_multislice.cond_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_10"); // defocus (Angstrom) - input_multislice.cond_lens.c_12 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_12"); // 2-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_12 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_21 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_21"); // Axial coma (Angstrom) - input_multislice.cond_lens.phi_21 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.cond_lens.c_23 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_23"); // 3-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_23 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_30 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_30")*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.c_32 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_32"); // Axial star aberration (Angstrom) - input_multislice.cond_lens.phi_32 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_34 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_34"); // 4-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_34 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_41 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_41"); // 4th order axial coma (Angstrom) - input_multislice.cond_lens.phi_41 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.cond_lens.c_43 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_43"); // 3-lobe aberration (Angstrom) - input_multislice.cond_lens.phi_43 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.cond_lens.c_45 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_45"); // 5-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_45 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_50 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_50")*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.c_52 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_52"); // 5th order axial star aberration (Angstrom) - input_multislice.cond_lens.phi_52 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_54 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_54"); // 5th order rosette aberration (Angstrom) - input_multislice.cond_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) - input_multislice.cond_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_56"); // 6-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.cond_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - /********************* defocus spread function ********************/ - input_multislice.cond_lens.ti_a = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.cond_lens.ti_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.cond_lens.ti_beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.cond_lens.ti_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_npts"); // Number of integration points - - /********************* source spread function *********************/ - input_multislice.cond_lens.si_a = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.cond_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.cond_lens.si_beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.cond_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_rad_npts"); // Number of radial integration points - input_multislice.cond_lens.si_azm_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_azm_npts"); - - /********************* zero defocus reference ********************/ /********************* zero defocus reference ********************/ - input_multislice.cond_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_type"); // Zero defocus type - input_multislice.cond_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_plane"); // Zero defocus position - - input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /*********************** Objective lens ***************************/ - input_multislice.obj_lens.m = mx_get_scalar_field(mx_input_multislice, "obj_lens_m"); // momentum of the vortex - input_multislice.obj_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_10"); // defocus (Angstrom) - input_multislice.obj_lens.c_12 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_12"); // 2-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_12 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_21 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_21"); // Axial coma (Angstrom) - input_multislice.obj_lens.phi_21 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.obj_lens.c_23 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_23"); // 3-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_23 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_30 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_30")*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.c_32 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_32"); // Axial star aberration (Angstrom) - input_multislice.obj_lens.phi_32 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_34 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_34"); // 4-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_34 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_41 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_41"); // 4th order axial coma (Angstrom) - input_multislice.obj_lens.phi_41 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.obj_lens.c_43 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_43"); // 3-lobe aberration (Angstrom) - input_multislice.obj_lens.phi_43 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.obj_lens.c_45 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_45"); // 5-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_45 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_50 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_50")*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.c_52 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_52"); // 5th order axial star aberration (Angstrom) - input_multislice.obj_lens.phi_52 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_54"); // 5th order rosette aberration (Angstrom) - input_multislice.obj_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration(degrees-->rad) - input_multislice.obj_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_56"); // 6-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.obj_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - /********************* defocus spread function ********************/ - input_multislice.obj_lens.ti_a = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.obj_lens.ti_sigma = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.ti_beta = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.ti_npts = mx_get_scalar_field(mx_input_multislice, "obj_lens_ti_npts"); // Number of integration points - - /********************* source spread function *********************/ - input_multislice.obj_lens.si_a = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_a"); // Height proportion of a normalized Gaussian [0, 1] - input_multislice.obj_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_sigma"); // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.si_beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_beta"); // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(Å^-1); otherwise (Å) - input_multislice.obj_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_rad_npts"); // Number of radial integration points - input_multislice.obj_lens.si_azm_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_azm_npts"); // Number of azimuth integration points - - /********************* zero defocus reference ********************/ - input_multislice.obj_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_type"); // Zero defocus type - input_multislice.obj_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_plane"); // Zero defocus position - - input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /************************** ISTEM/STEM ***************************/ - if (input_multislice.is_scanning()) - { - input_multislice.scanning.type = mx_get_scalar_field(mx_input_multislice, "scanning_type"); - input_multislice.scanning.pbc = mx_get_scalar_field(mx_input_multislice, "scanning_periodic"); - input_multislice.scanning.spxs = mx_get_scalar_field(mx_input_multislice, "scanning_square_pxs"); - input_multislice.scanning.ns = mx_get_scalar_field(mx_input_multislice, "scanning_ns"); - input_multislice.scanning.x0 = mx_get_scalar_field(mx_input_multislice, "scanning_x0"); - input_multislice.scanning.y0 = mx_get_scalar_field(mx_input_multislice, "scanning_y0"); - input_multislice.scanning.xe = mx_get_scalar_field(mx_input_multislice, "scanning_xe"); - input_multislice.scanning.ye = mx_get_scalar_field(mx_input_multislice, "scanning_ye"); - input_multislice.scanning.set_grid(); - } - - if (input_multislice.is_STEM()) - { - T_r lambda = mt::get_lambda(input_multislice.E_0); - mxArray *mx_detector = mxGetField(mx_input_multislice, 0, "detector"); - input_multislice.detector.type = mx_get_scalar_field(mx_detector, "type"); - - switch (input_multislice.detector.type) - { - case mt::eDT_Circular: - { - mx_detector = mxGetField(mx_detector, 0, "cir"); - int ndetector = mxGetN(mx_detector); - if (ndetector > 0) - { - input_multislice.detector.resize(ndetector); - for (auto i = 0; i < input_multislice.detector.size(); i++) - { - auto inner_ang = mx_get_scalar_field(mx_detector, i, "inner_ang")*mt::c_mrad_2_rad; - input_multislice.detector.g_inner[i] = sin(inner_ang) / lambda; - auto outer_ang = mx_get_scalar_field(mx_detector, i, "outer_ang")*mt::c_mrad_2_rad; - input_multislice.detector.g_outer[i] = sin(outer_ang) / lambda; - } - } - } - break; - case mt::eDT_Radial: - { - mx_detector = mxGetField(mx_detector, 0, "radial"); - int ndetector = mxGetN(mx_detector); - if (ndetector > 0) - { - input_multislice.detector.resize(ndetector); - for (auto i = 0; i < input_multislice.detector.size(); i++) - { - // auto x = mx_get_matrix_field(mx_detector, i, "x"); - // mt::assign(x, input_multislice.detector.x[i]); - // mt::scale(input_multislice.detector.x[i], 1.0/lambda); - - auto fx = mx_get_matrix_field(mx_detector, i, "fx"); - mt::assign(fx, input_multislice.detector.fx[i]); - } - } - } - break; - case mt::eDT_Matrix: - { - mx_detector = mxGetField(mx_detector, 0, "matrix"); - int ndetector = mxGetN(mx_detector); - if (ndetector > 0) - { - input_multislice.detector.resize(ndetector); - for (auto i = 0; i < input_multislice.detector.size(); i++) - { - // auto R = mx_get_matrix_field(mx_detector, i, "x"); - // mt::assign(R, input_multislice.detector.R[i]); - // mt::scale(input_multislice.detector.R[i], 1.0/lambda); - // mt::fft2_shift(input_multislice.grid_2d, input_multislice.detector.R[i]); - - auto fR = mx_get_matrix_field(mx_detector, i, "fR"); - mt::assign(fR, input_multislice.detector.fR[i]); - } - } - } - break; - } - } - else if (input_multislice.is_PED()) - { - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "ped_theta")*mt::c_deg_2_rad; - input_multislice.nrot = mx_get_scalar_field(mx_input_multislice, "ped_nrot"); - } - else if (input_multislice.is_HCTEM()) - { - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "hci_theta")*mt::c_deg_2_rad; - input_multislice.nrot = mx_get_scalar_field(mx_input_multislice, "hci_nrot"); - } - else if (input_multislice.is_EELS()) - { - mt::eSpace space = mt::eS_Reciprocal; - auto Z = mx_get_scalar_field(mx_input_multislice, "eels_Z"); - auto E_loss = mx_get_scalar_field(mx_input_multislice, "eels_E_loss")*mt::c_eV_2_keV; - auto collection_angle = mx_get_scalar_field(mx_input_multislice, "eels_collection_angle")*mt::c_mrad_2_rad; - auto m_selection = mx_get_scalar_field(mx_input_multislice, "eels_m_selection"); - auto channelling_type = mx_get_scalar_field(mx_input_multislice, "eels_channelling_type"); - - input_multislice.eels_fr.set_input_data(space, input_multislice.E_0, E_loss, m_selection, collection_angle, channelling_type, Z); - } - else if (input_multislice.is_EFTEM()) - { - mt::eSpace space = mt::eS_Real; - auto Z = mx_get_scalar_field(mx_input_multislice, "eftem_Z"); - auto E_loss = mx_get_scalar_field(mx_input_multislice, "eftem_E_loss")*mt::c_eV_2_keV; - auto collection_angle = mx_get_scalar_field(mx_input_multislice, "eftem_collection_angle")*mt::c_mrad_2_rad; - auto m_selection = mx_get_scalar_field(mx_input_multislice, "eftem_m_selection"); - auto channelling_type = mx_get_scalar_field(mx_input_multislice, "eftem_channelling_type"); - - input_multislice.eels_fr.set_input_data(space, input_multislice.E_0, E_loss, m_selection, collection_angle, channelling_type, Z); - } - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); -} - -template -void set_struct_multislice(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "data"}; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - - if (output_multislice.is_STEM() || output_multislice.is_EELS()) - { - mxArray *mx_field_data; - const char *field_names_data_full[] = { "image_tot", "image_coh" }; - const char *field_names_data_partial[] = { "image_tot" }; - const char **field_names_data = (output_multislice.pn_coh_contrib) ? field_names_data_full : field_names_data_partial; - int number_of_fields_data = (output_multislice.pn_coh_contrib) ? 2 : 1; - mwSize dims_data[2] = { 1, output_multislice.thick.size() }; - - mx_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); - mxSetField(mx_output_multislice, 0, "data", mx_field_data); - - mxArray *mx_field_detector_tot; - mxArray *mx_field_detector_coh; - const char *field_names_detector[] = { "image" }; - int number_of_fields_detector = 1; - // mwSize dims_detector[2] = {1, output_multislice.ndetector}; - mwSize dims_detector[2]; - dims_detector[0] = 1; - dims_detector[1] = output_multislice.ndetector; - - int nx = (output_multislice.scanning.is_line()) ? 1 : output_multislice.nx; - int ny = output_multislice.ny; - for (auto ithk = 0; ithk < output_multislice.thick.size(); ithk++) - { - mx_field_detector_tot = mxCreateStructArray(2, dims_detector, number_of_fields_detector, field_names_detector); - mxSetField(mx_field_data, ithk, "image_tot", mx_field_detector_tot); - if (output_multislice.pn_coh_contrib) - { - mx_field_detector_coh = mxCreateStructArray(2, dims_detector, number_of_fields_detector, field_names_detector); - mxSetField(mx_field_data, ithk, "image_coh", mx_field_detector_coh); - } - - for (auto iDet = 0; iDet < output_multislice.ndetector; iDet++) - { - mx_create_set_matrix_field(mx_field_detector_tot, iDet, "image", ny, nx, output_multislice.image_tot[ithk].image[iDet]); - if (output_multislice.pn_coh_contrib) - { - mx_create_set_matrix_field(mx_field_detector_coh, iDet, "image", ny, nx, output_multislice.image_coh[ithk].image[iDet]); - } - } - } - } - else if (output_multislice.is_EWFS_EWRS()) - { - mxArray *mx_field_data; - const char *field_names_data_full[] = { "m2psi_tot", "psi_coh" }; - const char *field_names_data_partial[] = { "psi_coh" }; - const char **field_names_data = (!output_multislice.is_EWFS_EWRS_SC()) ? field_names_data_full : field_names_data_partial; - int number_of_fields_data = (!output_multislice.is_EWFS_EWRS_SC()) ? 2 : 1; - mwSize dims_data[2] = { 1, output_multislice.thick.size() }; - - mx_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); - mxSetField(mx_output_multislice, 0, "data", mx_field_data); - - for (auto ithk = 0; ithk < output_multislice.thick.size(); ithk++) - { - if (!output_multislice.is_EWFS_EWRS_SC()) - { - mx_create_set_matrix_field(mx_field_data, ithk, "m2psi_tot", output_multislice.ny, output_multislice.nx, output_multislice.m2psi_tot[ithk]); - } - mx_create_set_matrix_field(mx_field_data, ithk, "psi_coh", output_multislice.ny, output_multislice.nx, output_multislice.psi_coh[ithk]); - } - } - else - { - mxArray *mx_field_data; - const char *field_names_data_full[] = { "m2psi_tot", "m2psi_coh" }; - const char *field_names_data_partial[] = { "m2psi_tot" }; - const char **field_names_data = (output_multislice.pn_coh_contrib) ? field_names_data_full : field_names_data_partial; - int number_of_fields_data = (output_multislice.pn_coh_contrib) ? 2 : 1; - mwSize dims_data[2] = { 1, output_multislice.thick.size() }; - - mx_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); - mxSetField(mx_output_multislice, 0, "data", mx_field_data); - - for (auto ithk = 0; ithk < output_multislice.thick.size(); ithk++) - { - mx_create_set_matrix_field(mx_field_data, ithk, "m2psi_tot", output_multislice.ny, output_multislice.nx, output_multislice.m2psi_tot[ithk]); - if (output_multislice.pn_coh_contrib) - { - mx_create_set_matrix_field(mx_field_data, ithk, "m2psi_coh", output_multislice.ny, output_multislice.nx, output_multislice.m2psi_coh[ithk]); - } - } - } -} - -template -void run_multislice(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, -mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - - mt::Multislice tem_simulation; - tem_simulation.set_input_data(&input_multislice, &stream, &fft_2d); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - tem_simulation(output_multislice); - stream.synchronize(); - - output_multislice.gather(); - output_multislice.clean_temporal(); - fft_2d.cleanup(); - - set_struct_multislice(output_multislice, mx_output_multislice); - - auto err = cudaGetLastError(); - if (err != cudaSuccess) { - mexPrintf("CUDA error: %s\n", cudaGetErrorString(err)); - } - //auto t3 = time.elapsed_ms(); - //mexPrintf("creation, execution, phase grating, deleting time = %7.5f, %7.5f, %7.5f, %7.5f\n", t1, t2, tx, t3); - //mexPrintf("send device = %d, get device = %d\n", system_conf.gpu_device, system_conf.get_device()); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; - - if (system_conf.is_float_host()) - { - //mexPrintf("cpu - float precision calculation\n"); - run_multislice(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_double_host()) - { - //mexPrintf("cpu - double precision calculation\n"); - run_multislice(system_conf, prhs[idx_0], plhs[0]); - } - if (system_conf.is_float_device()) - { - //mexPrintf("gpu - float precision calculation\n"); - run_multislice(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_double_device()) - { - //mexPrintf("gpu - double precision calculation\n"); - run_multislice(system_conf, prhs[idx_0], plhs[0]); - } - //cudaDeviceReset(); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include + +#include "types.cuh" +#include "type_traits_gen.h" +#include "fcns_gpu.h" +#include "in_classes.cuh" +#include "output_multem.hpp" +#include "particles.cuh" +#include "tem_simulation.cuh" +#include "timing.cuh" + +#include +#include "matlab_mex.h" + +using mt::pMLD; +using mt::pMx_c; + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice &multem_in_parm, dt_bool full = true) +{ + using T_r = mt::Value_type; + + /************************ simulation type **************************/ + multem_in_parm.em_sim_typ = mex_get_num_from_field(mex_multem_in_parm, "em_sim_typ"); + + /***************************************************************************************/ + multem_in_parm.elec_spec_interact_mod = mex_get_num_from_field(mex_multem_in_parm, "elec_spec_interact_mod"); + multem_in_parm.atomic_pot_parm_typ = mex_get_num_from_field(mex_multem_in_parm, "atomic_pot_parm_typ"); + + /***************************************************************************************/ + multem_in_parm.operation_mode = mex_get_num_from_field(mex_multem_in_parm, "operation_mode"); + multem_in_parm.reverse_multislice = mex_get_bool_from_field(mex_multem_in_parm, "reverse_multislice"); + + /************** Electron-Atomic_Vib interaction model **************/ + mex_read_atomic_vib(mex_multem_in_parm, multem_in_parm.atomic_vib); + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + auto bs_z = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_z"); + auto sli_thick = mex_get_num_from_field(mex_multem_in_parm, "spec_dz"); + dt_bool pbc_xy = true; + + if (multem_in_parm.is_specimen_required()) + { + if (full) + { + /************************* atomic positions ************************/ + mex_read_atoms(mex_multem_in_parm, bs_x, bs_y, bs_z, sli_thick, multem_in_parm.atoms); + } + + /************************ Specimen rotation ************************/ + mex_read_rot_in_parm(mex_multem_in_parm, multem_in_parm.rot_in_parm); + + /************************ Specimen thickness ***********************/ + multem_in_parm.thick_type = mex_get_num_from_field(mex_multem_in_parm, "thick_type"); + if (!multem_in_parm.is_sim_whole_spec() && full) + { + mex_read_spec_thick(mex_multem_in_parm, multem_in_parm.thick); + } + + /************************ Potential slicing ************************/ + multem_in_parm.spec_slic_typ = mex_get_num_from_field(mex_multem_in_parm, "spec_slic_typ"); + } + + /************************** xy sampling ****************************/ + auto nx = mex_get_num_from_field(mex_multem_in_parm, "nx"); + auto ny = mex_get_num_from_field(mex_multem_in_parm, "ny"); + dt_bool bwl = mex_get_bool_from_field(mex_multem_in_parm, "bwl"); + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + /************************ Incident wave ****************************/ + auto iw_type = mex_get_num_from_field(mex_multem_in_parm, "iw_type"); + multem_in_parm.set_incident_wave_type(iw_type); + + if (multem_in_parm.is_user_define_wave() && full) + { + mex_read_user_define_wave(mex_multem_in_parm, multem_in_parm.iw_psi); + } + + /********************* read beam positions *************************/ + mex_read_beam_pos(mex_multem_in_parm, multem_in_parm.beam_pos_2d); + + /********************* Microscope parameter ***********************/ + multem_in_parm.E_0 = mex_get_num_from_field(mex_multem_in_parm, "E_0"); + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "theta")*mt::c_deg_2_rad; + multem_in_parm.phi = mex_get_num_from_field(mex_multem_in_parm, "phi")*mt::c_deg_2_rad; + + /********************* Illumination model *************************/ + multem_in_parm.illum_mod = mex_get_num_from_field(mex_multem_in_parm, "illum_mod"); + multem_in_parm.illum_inc = mex_get_num_from_field(mex_multem_in_parm, "illum_inc"); + + /*********************** Condenser lens ***************************/ + mex_read_cond_lens(mex_multem_in_parm, multem_in_parm.cond_lens); + multem_in_parm.cond_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /*********************** Objective lens ***************************/ + mex_read_obj_lens(mex_multem_in_parm, multem_in_parm.obj_lens); + multem_in_parm.obj_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /************************** ISTEM/STEM ***************************/ + if (multem_in_parm.is_scanning()) + { + mex_read_scan(mex_multem_in_parm, multem_in_parm.scanning); + } + + if (multem_in_parm.is_STEM()) + { + mex_read_detector(mex_multem_in_parm, multem_in_parm.E_0, multem_in_parm.detector); + } + else if (multem_in_parm.is_PED()) + { + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "ped_theta")*mt::c_deg_2_rad; + multem_in_parm.nrot = mex_get_num_from_field(mex_multem_in_parm, "ped_nrot"); + } + else if (multem_in_parm.is_HCTEM()) + { + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "hci_theta")*mt::c_deg_2_rad; + multem_in_parm.nrot = mex_get_num_from_field(mex_multem_in_parm, "hci_nrot"); + } + else if (multem_in_parm.is_STEM_ISTEM_EELS()) + { + auto Z = mex_get_num_from_field(mex_multem_in_parm, "eels_Z"); + auto E_loss = mex_get_num_from_field(mex_multem_in_parm, "eels_E_loss")*mt::c_eV_2_keV; + auto coll_angle = mex_get_num_from_field(mex_multem_in_parm, "eels_coll_angle")*mt::c_mrad_2_rad; + auto m_sel = mex_get_num_from_field(mex_multem_in_parm, "eels_m_sel"); + auto chan_type = mex_get_num_from_field(mex_multem_in_parm, "eels_chan_type"); + + mt::eSpace space = mt::esp_fourier; + multem_in_parm.eels_fr.set_in_data(space, multem_in_parm.E_0, E_loss, m_sel, coll_angle, chan_type, Z); + } + else if (multem_in_parm.is_EFTEM()) + { + auto Z = mex_get_num_from_field(mex_multem_in_parm, "eftem_Z"); + auto E_loss = mex_get_num_from_field(mex_multem_in_parm, "eftem_E_loss")*mt::c_eV_2_keV; + auto coll_angle = mex_get_num_from_field(mex_multem_in_parm, "eftem_coll_angle")*mt::c_mrad_2_rad; + auto m_sel = mex_get_num_from_field(mex_multem_in_parm, "eftem_m_sel"); + auto chan_type = mex_get_num_from_field(mex_multem_in_parm, "eftem_chan_type"); + + mt::eSpace space = (multem_in_parm.is_EFTEMRS())?mt::esp_real:mt::esp_fourier; + multem_in_parm.eels_fr.set_in_data(space, multem_in_parm.E_0, E_loss, m_sel, coll_angle, chan_type, Z); + } + + /******************** select output region ************************/ + mex_read_output_area(mex_multem_in_parm, multem_in_parm.output_area); + + /********************* validate parameters *************************/ + multem_in_parm.set_dep_var(); +} + +template +void set_struct_multem(TOutput_Multem &output_multem, mxArray*& mex_output_multem) +{ + const char *field_names_output_multem[] = {"dx", "dy", "x", "y", "thick", "data"}; + dt_int32 number_of_fields_output_multem = 6; + mwSize dims_output_multem[2] = {1, 1}; + + mex_output_multem = mxCreateStructArray(2, dims_output_multem, number_of_fields_output_multem, field_names_output_multem); + + mex_create_set_num_field(mex_output_multem, 0, "dx", output_multem.dx); + mex_create_set_num_field(mex_output_multem, 0, "dy", output_multem.dy); + mex_create_set_pVctr_field(mex_output_multem, "x", 1, output_multem.x.size(), output_multem.x); + mex_create_set_pVctr_field(mex_output_multem, "y", 1, output_multem.y.size(), output_multem.y); + mex_create_set_pVctr_field(mex_output_multem, "thick", 1, output_multem.thick.size(), output_multem.thick); + + if (output_multem.is_STEM() || output_multem.is_STEM_ISTEM_EELS()) + { + mxArray* mex_field_data; + const char *field_names_data_full[] = { "image_tot", "image_coh" }; + const char *field_names_data_partial[] = { "image_tot" }; + const char **field_names_data = (output_multem.atomic_vib.coh_contrib)?field_names_data_full:field_names_data_partial; + dt_int32 number_of_fields_data = (output_multem.atomic_vib.coh_contrib)?2:1; + mwSize dims_data[2] = { 1, output_multem.thick.size() }; + + mex_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); + mxSetField(mex_output_multem, 0, "data", mex_field_data); + + mxArray* mex_field_detector_tot; + mxArray* mex_field_detector_coh; + const char *field_names_detector[] = { "image" }; + dt_int32 number_of_fields_detector = 1; + // mwSize dims_detector[2] = {1, output_multem.ndetector}; + mwSize dims_detector[2]; + dims_detector[0] = 1; + dims_detector[1] = output_multem.ndetector; + + dt_int32 nx = (output_multem.scanning.is_scan_pat_line())?1:output_multem.nx; + dt_int32 ny = output_multem.ny; + for(auto ithk = 0; ithk < output_multem.thick.size(); ithk++) + { + mex_field_detector_tot = mxCreateStructArray(2, dims_detector, number_of_fields_detector, field_names_detector); + mxSetField(mex_field_data, ithk, "image_tot", mex_field_detector_tot); + if (output_multem.atomic_vib.coh_contrib) + { + mex_field_detector_coh = mxCreateStructArray(2, dims_detector, number_of_fields_detector, field_names_detector); + mxSetField(mex_field_data, ithk, "image_coh", mex_field_detector_coh); + } + + for(auto iDet = 0; iDet < output_multem.ndetector; iDet++) + { + mex_create_set_pVctr_field(mex_field_detector_tot, iDet, "image", ny, nx, output_multem.image_tot(ithk, iDet)); + if (output_multem.atomic_vib.coh_contrib) + { + mex_create_set_pVctr_field(mex_field_detector_coh, iDet, "image", ny, nx, output_multem.image_coh(ithk, iDet)); + } + } + } + } + else if (output_multem.is_EWFS_EWRS()) + { + mxArray* mex_field_data; + const char *field_names_data_full[] = { "m2psi_tot", "psi_coh" }; + const char *field_names_data_partial[] = { "psi_coh" }; + const char **field_names_data = (!output_multem.is_EWFS_EWRS_SC())?field_names_data_full:field_names_data_partial; + dt_int32 number_of_fields_data = (!output_multem.is_EWFS_EWRS_SC())?2:1; + mwSize dims_data[2] = { 1, output_multem.thick.size() }; + + mex_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); + mxSetField(mex_output_multem, 0, "data", mex_field_data); + + for(auto ithk = 0; ithk < output_multem.thick.size(); ithk++) + { + if (!output_multem.is_EWFS_EWRS_SC()) + { + mex_create_set_pVctr_field(mex_field_data, ithk, "m2psi_tot", output_multem.ny, output_multem.nx, output_multem.m2psi_tot[ithk]); + } + mex_create_set_pVctr_field(mex_field_data, ithk, "psi_coh", output_multem.ny, output_multem.nx, output_multem.psi_coh[ithk]); + } + } + else + { + mxArray* mex_field_data; + const char *field_names_data_full[] = { "m2psi_tot", "m2psi_coh" }; + const char *field_names_data_partial[] = { "m2psi_tot" }; + const char **field_names_data = (output_multem.atomic_vib.coh_contrib)?field_names_data_full:field_names_data_partial; + dt_int32 number_of_fields_data = (output_multem.atomic_vib.coh_contrib)?2:1; + mwSize dims_data[2] = { 1, output_multem.nthk() }; + + mex_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); + mxSetField(mex_output_multem, 0, "data", mex_field_data); + + for(auto ithk = 0; ithk < output_multem.nthk(); ithk++) + { + mex_create_set_pVctr_field(mex_field_data, ithk, "m2psi_tot", output_multem.ny, output_multem.nx, output_multem.m2psi_tot[ithk]); + if (output_multem.atomic_vib.coh_contrib) + { + mex_create_set_pVctr_field(mex_field_data, ithk, "m2psi_coh", output_multem.ny, output_multem.nx, output_multem.m2psi_coh[ithk]); + } + } + } +} + +template +void run_multem(mt::System_Config &system_config, const mxArray* mex_multem_in_parm, mxArray*& mex_output_multem) +{ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(mex_multem_in_parm, multem_in_parm); + multem_in_parm.system_config = system_config; + + // multem has to be created first due to memory allocations + mt::Multem multem(&multem_in_parm); + mt::Output_Multem output_multem(&multem_in_parm, true); + + multem(output_multem); + + set_struct_multem(output_multem, mex_output_multem); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto system_config = mex_read_system_config(prhs[0]); + dt_int32 idx_0 = (system_config.active)?1:0; + + mt::d_grid_blk(1024, 1024, 0, 1); + + if (system_config.is_float32_cpu()) + { + // mexPrintf("cpu - dt_float32 precision calculation\n"); + run_multem(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_cpu()) + { + // mexPrintf("cpu - dt_float64 precision calculation\n"); + run_multem(system_config, prhs[idx_0], plhs[0]); + } + if (system_config.is_float32_gpu()) + { + mexPrintf("gpu - dt_float32 precision calculation\n"); + run_multem(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_gpu()) + { + // mexPrintf("gpu - dt_float64 precision calculation\n"); + run_multem(system_config, prhs[idx_0], plhs[0]); + } + // // cudaDeviceReset(); } \ No newline at end of file diff --git a/mex_files_multem/ilc_pr.cpp b/mex_files_multem/ilc_pr.cpp old mode 100644 new mode 100755 index 6277b2ec..87c09812 --- a/mex_files_multem/ilc_pr.cpp +++ b/mex_files_multem/ilc_pr.cpp @@ -1,45 +1,43 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "atomic_fcns_mt.hpp" -#include "atomic_data.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto potential_type = mx_get_scalar(prhs[0]); - auto Z = mx_get_scalar(prhs[1]); - auto charge = mx_get_scalar(prhs[2]); - auto r = mx_get_matrix(prhs[3]); - - auto Pr = mx_create_matrix(r.rows, r.cols, plhs[0]); - auto dPr = mx_create_matrix(r.rows, r.cols, plhs[1]); - - mt::Atom_Type atom_type; - mt::Atomic_Data atomic_data(potential_type); - atomic_data.To_atom_type_CPU(Z, mt::c_Vrl, mt::c_nR, 0.0, atom_type); - - mt::Atom_Cal atomic_fcns_mt; - atomic_fcns_mt.Set_Atom_Type(potential_type, charge, &atom_type); - atomic_fcns_mt.Pr_dPr(r.m_size, r.real, Pr.real, dPr.real); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_num(prhs[0]); + auto Z = mex_get_num(prhs[1]); + auto charge = mex_get_num(prhs[2]); + auto r = mex_get_pvctr(prhs[3]); + + /***************************************************************************************/ + auto pr = mex_create_pVctr(r.shape(), plhs[0]); + auto dpr = mex_create_pVctr(r.shape(), plhs[1]); + + mt::Atomic_Info_cpu atomic_info = mt::Atomic_Data(Z, atomic_pot_parm_typ, charge); + mt::Atomic_Fcns atomic_fcns_mt(atomic_info.coef[0]); + + atomic_fcns_mt.pr_dpr(r.ptr_32(), pr.ptr_32(), dpr.ptr_32()); } \ No newline at end of file diff --git a/mex_files_multem/ilc_projected_potential.cu b/mex_files_multem/ilc_projected_potential.cu old mode 100644 new mode 100755 index 4c800174..247b81a7 --- a/mex_files_multem/ilc_projected_potential.cu +++ b/mex_files_multem/ilc_projected_potential.cu @@ -1,181 +1,154 @@ -/* - * This file is part of MULTEM. - * Copyright 2014 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "atomic_data_mt.hpp" -#include "input_multislice.cuh" -#include "output_multislice.hpp" - -#include "projected_potential.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - /************************ simulation type **************************/ - input_multislice.simulation_type = mt::eTEMST_PPRS; - - /*******************************************************************/ - input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); - input_multislice.potential_type = mx_get_scalar_field(mx_input_multislice, "potential_type"); - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); - input_multislice.pn_coh_contrib = true; - input_multislice.pn_single_conf = true; - input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); - input_multislice.pn_dim.set(mx_get_scalar_field(mx_input_multislice, "pn_dim")); - input_multislice.pn_seed = mx_get_scalar_field(mx_input_multislice, "pn_seed"); - - /**************************** Specimen *****************************/ - auto atoms = mx_get_matrix_field(mx_input_multislice, "spec_atoms"); - - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); - auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = true; - - auto ct_na = mx_get_scalar_field(mx_input_multislice, "spec_cryst_na"); - auto ct_nb = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nb"); - auto ct_nc = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nc"); - auto ct_a = mx_get_scalar_field(mx_input_multislice, "spec_cryst_a"); - auto ct_b = mx_get_scalar_field(mx_input_multislice, "spec_cryst_b"); - auto ct_c = mx_get_scalar_field(mx_input_multislice, "spec_cryst_c"); - auto ct_x0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_x0"); - auto ct_y0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_y0"); - - auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); - mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for(auto i = 0; i(mx_spec_amorp, i, "z_0"); - amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); - amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); - } - - if(full) - { - input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); - input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); - input_multislice.atoms.set_atoms(atoms.rows, atoms.cols, atoms.real, lx, ly, lz, dz); - } - - /************************ Specimen rotation *************************/ - input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; - input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); - input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); - input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); - - /************************ Potential slicing ************************/ - input_multislice.potential_slicing = mx_get_scalar_field(mx_input_multislice, "potential_slicing"); - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = mx_get_scalar_field(mx_input_multislice, "bwl"); - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************ simulation type **************************/ - input_multislice.islice = mx_get_scalar_field(mx_input_multislice, "islice")-1; - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); - } - -template -void set_struct_projected_potential(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "V"}; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - mx_create_set_matrix_field(mx_output_multislice, "V", output_multislice.ny, output_multislice.nx, output_multislice.V[0]); -} - -template -void run_projected_potential(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - mt::Projected_Potential projected_potential; - projected_potential.set_input_data(&input_multislice, &stream); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - projected_potential.move_atoms(input_multislice.pn_nconf); - projected_potential(input_multislice.islice, output_multislice); - - stream.synchronize(); - - output_multislice.gather(); - output_multislice.clean_temporal(); - - set_struct_projected_potential(output_multislice, mx_output_multislice); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; - - if(system_conf.is_float_host()) - { - run_projected_potential(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_host()) - { - run_projected_potential(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_float_device()) - { - run_projected_potential(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_device()) - { - run_projected_potential(system_conf, prhs[idx_0], plhs[0]); - } +/* + * This file is part of Multem. + * Copyright 2014 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "particles.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" + +#include "projected_potential.cuh" + +#include +#include "matlab_mex.h" + +using mt::pMLD; + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice &multem_in_parm, dt_bool full = true) +{ + using T_r = mt::Value_type; + + /************************ simulation type **************************/ + multem_in_parm.em_sim_typ = mt::eemst_pprs; + + /***************************************************************************************/ + multem_in_parm.elec_spec_interact_mod = mex_get_num_from_field(mex_multem_in_parm, "elec_spec_interact_mod"); + multem_in_parm.atomic_pot_parm_typ = mex_get_num_from_field(mex_multem_in_parm, "atomic_pot_parm_typ"); + + /************** Electron-Atomic_Vib interaction model **************/ + mex_read_atomic_vib(mex_multem_in_parm, multem_in_parm.atomic_vib); + multem_in_parm.atomic_vib.coh_contrib = true; + multem_in_parm.atomic_vib.sgl_conf = true; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + auto bs_z = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_z"); + auto sli_thick = mex_get_num_from_field(mex_multem_in_parm, "spec_dz"); + dt_bool pbc_xy = true; + + if (full) + { + /************************* atomic positions ************************/ + mex_read_atoms(mex_multem_in_parm, bs_x, bs_y, bs_z, sli_thick, multem_in_parm.atoms); + } + + /************************ Specimen rotation ************************/ + mex_read_rot_in_parm(mex_multem_in_parm, multem_in_parm.rot_in_parm); + + /************************ Potential slicing ************************/ + multem_in_parm.spec_slic_typ = mex_get_num_from_field(mex_multem_in_parm, "spec_slic_typ"); + + /************************** xy sampling ****************************/ + auto nx = mex_get_num_from_field(mex_multem_in_parm, "nx"); + auto ny = mex_get_num_from_field(mex_multem_in_parm, "ny"); + dt_bool bwl = mex_get_bool_from_field(mex_multem_in_parm, "bwl"); + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + /************************ simulation type **************************/ + multem_in_parm.islice = mex_get_num_from_field(mex_multem_in_parm, "islice")-1; + + /******************** select output region ************************/ + mex_read_output_area(mex_multem_in_parm, multem_in_parm.output_area); + + /********************* validate parameters *************************/ + multem_in_parm.set_dep_var(); + } + +template +void set_struct_projected_potential(TOutput_Multem &output_multem, mxArray*& mex_output_multem) +{ + const char *field_names_output_multem[] = {"dx", "dy", "x", "y", "thick", "V"}; + dt_int32 number_of_fields_output_multem = 6; + mwSize dims_output_multem[2] = {1, 1}; + + mex_output_multem = mxCreateStructArray(2, dims_output_multem, number_of_fields_output_multem, field_names_output_multem); + + mex_create_set_num_field(mex_output_multem, 0, "dx", output_multem.dx); + mex_create_set_num_field(mex_output_multem, 0, "dy", output_multem.dy); + mex_create_set_pVctr_field(mex_output_multem, "x", 1, output_multem.x.size(), output_multem.x); + mex_create_set_pVctr_field(mex_output_multem, "y", 1, output_multem.y.size(), output_multem.y); + mex_create_set_pVctr_field(mex_output_multem, "thick", 1, output_multem.thick.size(), output_multem.thick); + mex_create_set_pVctr_field(mex_output_multem, "V", output_multem.ny, output_multem.nx, output_multem.V[0]); +} + +template +void run_projected_potential(mt::System_Config &system_config, const mxArray* mex_multem_in_parm, mxArray*& mex_output_multem) +{ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(mex_multem_in_parm, multem_in_parm); + multem_in_parm.system_config = system_config; + + mt::Stream stream(system_config.n_stream); + mt::Projected_Potential projected_potential; + projected_potential.set_in_data(&multem_in_parm, &stream); + + mt::Output_Multem output_multem; + output_multem.set_in_data(&multem_in_parm); + + projected_potential.move_atoms(multem_in_parm.atomic_vib.nconf); + projected_potential(multem_in_parm.islice, output_multem); + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + + set_struct_projected_potential(output_multem, mex_output_multem); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + // the output potential is in V - Angstrom + auto system_config = mex_read_system_config(prhs[0]); + system_config.set_gpu(); + + dt_int32 idx_0 = (system_config.active)?1:0; + + if (system_config.is_float32_cpu()) + { + run_projected_potential(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_cpu()) + { + run_projected_potential(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float32_gpu()) + { + run_projected_potential(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_gpu()) + { + run_projected_potential(system_config, prhs[idx_0], plhs[0]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_propagate.cu b/mex_files_multem/ilc_propagate.cu old mode 100644 new mode 100755 index d6b8aec9..8ad815db --- a/mex_files_multem/ilc_propagate.cu +++ b/mex_files_multem/ilc_propagate.cu @@ -1,163 +1,153 @@ -/** - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" - -#include "propagator.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; -using mt::rmatrix_c; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - /************************ simulation type **************************/ - input_multislice.simulation_type = mt::eTEMST_PropRS; - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mt::ePM_Still_Atom; - - /**************************** Specimen *****************************/ - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - T_r lz = 0; - T_r dz = 0.25; - bool pbc_xy = true; - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = false; - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************ Incident wave ****************************/ - auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); - input_multislice.set_incident_wave_type(iw_type); - - if(input_multislice.is_user_define_wave() && full) - { - auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); - mt::assign(iw_psi, input_multislice.iw_psi); - } - - // read iw_x and iw_y - auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); - auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin()+n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin()+n_iw_xy); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; - input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; - - /************************ Objective lens **************************/ - input_multislice.obj_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_10"); // defocus(Angstrom) - input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); - } - -template -void set_struct_propagate(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "psi"}; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - mx_create_set_matrix_field(mx_output_multislice, "psi", output_multislice.ny, output_multislice.nx, output_multislice.psi_coh[0]); -} - -template -void run_propagate(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - - mt::Propagator propagator; - propagator.set_input_data(&input_multislice, &stream, &fft_2d); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - propagator(mt::eS_Real, input_multislice.gx_0(), input_multislice.gy_0(), input_multislice.obj_lens.c_10, output_multislice); - - stream.synchronize(); - - //output_multislice.gather(); - output_multislice.clean_temporal(); - fft_2d.cleanup(); - - set_struct_propagate(output_multislice, mx_output_multislice); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; - - if(system_conf.is_float_host()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_host()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_float_device()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_device()) - { - run_propagate(system_conf, prhs[idx_0], plhs[0]); - } +/** + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "cgpu_fft.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" + +#include "propagator.cuh" + +#include +#include "matlab_mex.h" + +using mt::pMLD; +using mt::pMx_c; + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice &multem_in_parm, dt_bool full = true) +{ + using T_r = mt::Value_type; + + multem_in_parm.em_sim_typ = mt::eemst_proprs; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + T_r bs_z = 0; + T_r sli_thick = 0.25; + dt_bool pbc_xy = true; + + /************************** xy sampling ****************************/ + auto nx = mex_get_num_from_field(mex_multem_in_parm, "nx"); + auto ny = mex_get_num_from_field(mex_multem_in_parm, "ny"); + dt_bool bwl = false; + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + /************************ Incident wave ****************************/ + auto iw_type = mex_get_num_from_field(mex_multem_in_parm, "iw_type"); + multem_in_parm.set_incident_wave_type(iw_type); + + if (multem_in_parm.is_user_define_wave() && full) + { + mex_read_user_define_wave(mex_multem_in_parm, multem_in_parm.iw_psi); + } + + /********************* read beam positions ************************/ + mex_read_beam_pos(mex_multem_in_parm, multem_in_parm.beam_pos_2d); + + /********************* Microscope parameter ***********************/ + multem_in_parm.E_0 = mex_get_num_from_field(mex_multem_in_parm, "E_0"); + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "theta")*mt::c_deg_2_rad; + multem_in_parm.phi = mex_get_num_from_field(mex_multem_in_parm, "phi")*mt::c_deg_2_rad; + + /************************ Objective lens **************************/ + multem_in_parm.obj_lens.c_10 = mex_get_num_from_field(mex_multem_in_parm, "obj_lens_f"); // defocus(Angstrom) + multem_in_parm.obj_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /******************** select output region ************************/ + mex_read_output_area(mex_multem_in_parm, multem_in_parm.output_area); + + /********************* validate parameters ************************/ + multem_in_parm.set_dep_var(); + } + +template +void set_struct_propagate(TOutput_Multem &output_multem, mxArray*& mex_output_multem) +{ + const char *field_names_output_multem[] = {"dx", "dy", "x", "y", "thick", "psi"}; + dt_int32 number_of_fields_output_multem = 6; + mwSize dims_output_multem[2] = {1, 1}; + + mex_output_multem = mxCreateStructArray(2, dims_output_multem, number_of_fields_output_multem, field_names_output_multem); + + mex_create_set_num_field(mex_output_multem, 0, "dx", output_multem.dx); + mex_create_set_num_field(mex_output_multem, 0, "dy", output_multem.dy); + mex_create_set_pVctr_field(mex_output_multem, "x", 1, output_multem.x.size(), output_multem.x); + mex_create_set_pVctr_field(mex_output_multem, "y", 1, output_multem.y.size(), output_multem.y); + mex_create_set_pVctr_field(mex_output_multem, "thick", 1, output_multem.thick.size(), output_multem.thick); + mex_create_set_pVctr_field(mex_output_multem, "psi", output_multem.ny, output_multem.nx, output_multem.psi_coh[0]); +} + +template +void run_propagate(mt::System_Config &system_config, const mxArray* mex_multem_in_parm, mxArray*& mex_output_multem) +{ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(mex_multem_in_parm, multem_in_parm); + multem_in_parm.system_config = system_config; + + mt::Stream stream(system_config.n_stream); + mt::FFT fft_2d; + fft_2d.create_plan_2d(multem_in_parm.grid_2d.ny, multem_in_parm.grid_2d.nx, system_config.n_stream); + + mt::Propagator propagator; + propagator.set_in_data(&multem_in_parm, &stream, &fft_2d); + + mt::Output_Multem output_multem; + output_multem.set_in_data(&multem_in_parm); + + propagator(mt::esp_real, multem_in_parm.gx_0(), multem_in_parm.gy_0(), multem_in_parm.obj_lens.c_10 , output_multem); + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + fft_2d.cleanup(); + + set_struct_propagate(output_multem, mex_output_multem); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto system_config = mex_read_system_config(prhs[0]); + system_config.set_gpu(); + + dt_int32 idx_0 = (system_config.active)?1:0; + + if (system_config.is_float32_cpu()) + { + run_propagate(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_cpu()) + { + run_propagate(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float32_gpu()) + { + run_propagate(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_gpu()) + { + run_propagate(system_config, prhs[idx_0], plhs[0]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_rangs_2_mrad.cpp b/mex_files_multem/ilc_rangs_2_mrad.cpp new file mode 100755 index 00000000..4ece9070 --- /dev/null +++ b/mex_files_multem/ilc_rangs_2_mrad.cpp @@ -0,0 +1,38 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + auto prangs = mex_get_pvctr(prhs[1]); + + /***************************************************************************************/ + auto pmrad = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < prangs.size(); ik++) + { + pmrad[ik] = mt::fcn_rangs_2_rad(pE_0[ik], prangs[ik])/mt::c_mrad_2_rad; + } +} \ No newline at end of file diff --git a/mex_files_multem/ilc_rdf.cpp b/mex_files_multem/ilc_rdf.cpp new file mode 100755 index 00000000..3d090092 --- /dev/null +++ b/mex_files_multem/ilc_rdf.cpp @@ -0,0 +1,56 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "particle_fcns.hpp" + +#include +#include "matlab_mex.h" + +template +void mex_run(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pvr = mex_get_pvctr(prhs[0]); + auto r_max = mex_get_num(prhs[1]); + auto nr = (nrhs>2)?mex_get_num(prhs[2]):10; + + /***************************************************************************************/ + mt::Vctr_cpu r(nr); + mt::Vctr_cpu rdf(nr); + + if (pvr.m_s1==2) + { + mt::Vctr_r_2d_cpu vctr_r_2d(pvr.data(), pvr.s0()); + mt::fcn_rdf(vctr_r_2d, r_max, nr, r, rdf); + } + else + { + mt::Vctr_r_3d_cpu vctr_r_3d(pvr.data(), pvr.s0()); + mt::fcn_rdf(vctr_r_3d, r_max, nr, r, rdf); + } + + mex_create_set_pVctr(plhs[0], r.ptr_64()); + mex_create_set_pVctr(plhs[1], rdf.ptr_64()); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + MEX_RUN_FCN_FLOAT(mex_run, 0); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_rdf_3d.cpp b/mex_files_multem/ilc_rdf_3d.cpp deleted file mode 100644 index 60bf6fd2..00000000 --- a/mex_files_multem/ilc_rdf_3d.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2015 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "atomic_data_mt.hpp" -#include "cpu_fcns.hpp" - -#include -#include "matlab_mex.cuh" - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[ ]) -{ - auto ratoms = mx_get_matrix(prhs[0]); - auto r_max = mx_get_scalar(prhs[1]); - auto nr = (nrhs>2)?mx_get_scalar(prhs[2]):10; - - /*******************************************************************/ - auto rr_o = mx_create_matrix(nr, 1, plhs[0]); - auto rrdf_o = mx_create_matrix(nr, 1, plhs[1]); - - std::vector r(nr); - std::vector rdf(nr); - mt::Atom_Data atoms; - atoms.set_atoms(ratoms.rows, ratoms.cols, ratoms.real); - - mt::rdf_3d(atoms, r_max, nr, r, rdf); - - thrust::copy(r.begin(), r.end(), rr_o.begin()); - thrust::copy(rdf.begin(), rdf.end(), rrdf_o.begin()); -} \ No newline at end of file diff --git a/mex_files_multem/ilc_scherzer_aperture.cpp b/mex_files_multem/ilc_scherzer_aperture.cpp old mode 100644 new mode 100755 index fa5b23cd..0f38274b --- a/mex_files_multem/ilc_scherzer_aperture.cpp +++ b/mex_files_multem/ilc_scherzer_aperture.cpp @@ -1,37 +1,38 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - auto c_30 = mx_get_scalar(prhs[1])*mt::c_mm_2_Angs; - - /******************************************************************/ - auto rscherzer_aperture = mx_create_scalar(plhs[0]); - - rscherzer_aperture[0] = mt::get_Scherzer_aperture(E0, c_30)/mt::c_mrad_2_rad; +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + auto pc_30 = mex_get_pvctr(prhs[1]); + + /***************************************************************************************/ + auto pscherzer_aperture = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < pscherzer_aperture.size(); ik++) + { + pscherzer_aperture[ik] = mt::fcn_scherzer_aperture(pE_0[ik], pc_30[ik]*mt::c_mm_2_angs)/mt::c_mrad_2_rad; + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_scherzer_defocus.cpp b/mex_files_multem/ilc_scherzer_defocus.cpp old mode 100644 new mode 100755 index d6edae90..18276a9e --- a/mex_files_multem/ilc_scherzer_defocus.cpp +++ b/mex_files_multem/ilc_scherzer_defocus.cpp @@ -1,37 +1,38 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - auto c_30 = mx_get_scalar(prhs[1])*mt::c_mm_2_Angs; - - /******************************************************************/ - auto rscherzer_defocus = mx_create_scalar(plhs[0]); - - rscherzer_defocus[0] = mt::get_Scherzer_defocus(E0, c_30); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + auto pc_30 = mex_get_pvctr(prhs[1]); + + /***************************************************************************************/ + auto pscherzer_defocus = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (auto ik = 0; ik < pscherzer_defocus.size(); ik++) + { + pscherzer_defocus[ik] = mt::fcn_scherzer_defocus(pE_0[ik], pc_30[ik]*mt::c_mm_2_angs); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_sigma.cpp b/mex_files_multem/ilc_sigma.cpp deleted file mode 100644 index f66e0332..00000000 --- a/mex_files_multem/ilc_sigma.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "matlab_types.cuh" -#include "cgpu_fcns.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto E0 = mx_get_scalar(prhs[0]); - - /******************************************************************/ - auto rsigma = mx_create_scalar(plhs[0]); - - rsigma[0] = mt::get_sigma(E0); -} \ No newline at end of file diff --git a/mex_files_multem/ilc_spec_planes.cpp b/mex_files_multem/ilc_spec_planes.cpp old mode 100644 new mode 100755 index 4f78922a..34f739b3 --- a/mex_files_multem/ilc_spec_planes.cpp +++ b/mex_files_multem/ilc_spec_planes.cpp @@ -1,112 +1,83 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "atomic_data_mt.hpp" -#include "input_multislice.cuh" -#include "slicing.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice) -{ - using T_r = mt::Value_type; - - input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); - input_multislice.potential_type = mt::ePT_Lobato_0_12; - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); - input_multislice.pn_coh_contrib = false; - input_multislice.pn_single_conf = true; - input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); - input_multislice.pn_dim.set(mx_get_scalar_field(mx_input_multislice, "pn_dim")); - input_multislice.pn_seed = mx_get_scalar_field(mx_input_multislice, "pn_seed"); - - /**************************** Specimen *****************************/ - auto atoms = mx_get_matrix_field(mx_input_multislice, "spec_atoms"); - - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); - auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = false; - - auto ct_na = mx_get_scalar_field(mx_input_multislice, "spec_cryst_na"); - auto ct_nb = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nb"); - auto ct_nc = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nc"); - auto ct_a = mx_get_scalar_field(mx_input_multislice, "spec_cryst_a"); - auto ct_b = mx_get_scalar_field(mx_input_multislice, "spec_cryst_b"); - auto ct_c = mx_get_scalar_field(mx_input_multislice, "spec_cryst_c"); - auto ct_x0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_x0"); - auto ct_y0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_y0"); - - auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); - mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for(auto i = 0; i(mx_spec_amorp, i, "z_0"); - amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); - amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); - } - - input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); - input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); - input_multislice.atoms.set_atoms(atoms.rows, atoms.cols, atoms.real, lx, ly, lz, dz); - - /************************ Specimen rotation *************************/ - input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; - input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); - input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); - input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); - - /************************ Potential slicing ************************/ - input_multislice.potential_slicing = mx_get_scalar_field(mx_input_multislice, "potential_slicing"); - - /************************** xy sampling ****************************/ - auto nx = 1024; - auto ny = 1024; - bool bwl = false; - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - input_multislice.validate_parameters(); - } - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - /*************************Input data**************************/ - mt::Input_Multislice input_multislice; - read_input_multislice(prhs[0], input_multislice); - - /***************************************************************************/ - mt::Slicing slicing; - slicing.set_input_data(&input_multislice, &(input_multislice.atoms)); - - // /************************Output data**************************/ - auto rplanes = mx_create_matrix(slicing.z_plane.size(), 1, plhs[0]); - - rplanes.assign(slicing.z_plane.begin(), slicing.z_plane.end()); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "type_traits_gen.h" +#include "particles.cuh" +#include "multem_in_parm.cuh" +#include "spec_slic.hpp" + +#include +#include "matlab_mex.h" +#include "matlab_multem_io.h" + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, mt::Multem_In_Parm &multem_in_parm) +{ + multem_in_parm.elec_spec_interact_mod = mex_get_num_from_field(mex_multem_in_parm, "elec_spec_interact_mod"); + multem_in_parm.atomic_pot_parm_typ = mt::eappt_lobato_0_12; + + /************** Electron-Atomic_Vib interaction model **************/ + mex_read_atomic_vib(mex_multem_in_parm, multem_in_parm.atomic_vib); + multem_in_parm.atomic_vib.coh_contrib = false; + multem_in_parm.atomic_vib.sgl_conf = true; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + auto bs_z = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_z"); + auto sli_thick = mex_get_num_from_field(mex_multem_in_parm, "spec_dz"); + dt_bool pbc_xy = false; + dt_bool b_statistic = true; + + /************************* atomic positions ************************/ + mex_read_atoms(mex_multem_in_parm, {bs_x, bs_y, bs_z}, pbc_xy, b_statistic, multem_in_parm.atoms); + + /************************ Specimen rotation ************************/ + mex_read_rot_in_parm(mex_multem_in_parm, multem_in_parm.rot_in_parm); + + /************************ Potential slicing ************************/ + multem_in_parm.spec_slic_typ = mex_get_enum_from_field(mex_multem_in_parm, "spec_slic_typ"); + + /************************** xy sampling ****************************/ + auto nx = 1024; + auto ny = 1024; + dt_bool bwl = false; + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + multem_in_parm.set_dep_var(); + } + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + /*************************Input data**************************/ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(prhs[0], multem_in_parm); + + /***************************************************************************************/ + mt::Spec_Slic slicing; + slicing.set_in_data(&multem_in_parm, &(multem_in_parm.atoms)); + + // /************************Output data**************************/ + auto rplanes = mex_create_pVctr(slicing.z_plane.size(), 1, plhs[0]); + + rplanes.assign(slicing.z_plane.begin(), slicing.z_plane.end()); } \ No newline at end of file diff --git a/mex_files_multem/ilc_spec_rot.cpp b/mex_files_multem/ilc_spec_rot.cpp old mode 100644 new mode 100755 index 74cdf22c..54483a9e --- a/mex_files_multem/ilc_spec_rot.cpp +++ b/mex_files_multem/ilc_spec_rot.cpp @@ -1,69 +1,57 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "atomic_data_mt.hpp" -#include "input_multislice.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - using T = double; - - /*************************Input data**************************/ - auto r_atoms = mx_get_matrix(prhs[0]); - auto theta = mx_get_scalar(prhs[1])*mt::c_deg_2_rad; - auto r_u0 = mx_get_matrix(prhs[2]); - auto rot_point_type = mx_get_scalar(prhs[3]); - auto r_p0 = mx_get_matrix(prhs[4]); - - /************************Output data**************************/ - mt::Atom_Data atoms; - atoms.set_atoms(r_atoms.rows, r_atoms.cols, r_atoms.real); - - mt::r3d u0 = (r_u0.size()>=3)?mt::r3d(r_u0[0], r_u0[1], r_u0[2]):mt::r3d(0, 0, 1); - u0.normalized(); - mt::r3d p0 = (r_p0.size()>=3)?mt::r3d(r_p0[0], r_p0[1], r_p0[2]):mt::r3d(0, 0, 0); - - if(rot_point_type == mt::eRPT_geometric_center) - { - p0 = r3d(atoms.x_mean, atoms.y_mean, atoms.z_mean); - } - - mt::rotate_atoms(atoms, theta, u0, p0); - - auto r_atoms_o = mx_create_matrix(atoms.size(), 8, plhs[0]); - - for(auto i = 0; i + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "const_enum.h" +#include "types_mt.cuh" +#include "particles.cuh" + +#include +#include "matlab_mex.h" +#include "matlab_multem_io.h" + +template +void mex_run(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + const auto patoms_i = mex_get_pvctr(prhs[0]); + auto theta = mex_get_num(prhs[1])*mt::c_deg_2_rad; + auto u_0 = mex_get_r_3d(prhs[2], mt::R_3d(0, 0, 1)); + auto ctr_type = (nrhs>3)?mex_get_enum(prhs[3]):mt::erct_geometric_ctr; + auto ctr_p = (nrhs>4)?mex_get_r_3d(prhs[4]):mt::R_3d(0, 0, 0); + + /***************************************************************************************/ + mt::Ptc_Atom atoms(patoms_i, {0, 0, 0}, false, true); + + u_0.normalize(); + + if (mt::is_rot_ctr_geometric_ctr(ctr_type)) + { + ctr_p = mt::R_3d(atoms.r_mean.x, atoms.r_mean.y, atoms.r_mean.z); + } + + atoms.rotate(theta, u_0, ctr_p); + + auto patoms_o = mex_create_pVctr({atoms.size(), atoms.cols_used}, plhs[0]); + atoms.cpy_to_ptr(patoms_o.data(), atoms.size(), 0, atoms.cols_used); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + MEX_RUN_FCN_FLOAT_OUT(mex_run, 0); } \ No newline at end of file diff --git a/mex_files_multem/ilc_spec_slicing.cpp b/mex_files_multem/ilc_spec_slicing.cpp old mode 100644 new mode 100755 index 2ac50413..ef9694c5 --- a/mex_files_multem/ilc_spec_slicing.cpp +++ b/mex_files_multem/ilc_spec_slicing.cpp @@ -1,136 +1,108 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "atomic_data_mt.hpp" -#include "spec.hpp" -#include "input_multislice.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice) -{ - using T_r = mt::Value_type; - - input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); - input_multislice.potential_type = mt::ePT_Lobato_0_12; - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); - input_multislice.pn_coh_contrib = false; - input_multislice.pn_single_conf = true; - input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); - input_multislice.pn_dim.set(mx_get_scalar_field(mx_input_multislice, "pn_dim")); - input_multislice.pn_seed = mx_get_scalar_field(mx_input_multislice, "pn_seed"); - - /**************************** Specimen *****************************/ - auto atoms = mx_get_matrix_field(mx_input_multislice, "spec_atoms"); - - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); - auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = false; - - auto ct_na = mx_get_scalar_field(mx_input_multislice, "spec_cryst_na"); - auto ct_nb = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nb"); - auto ct_nc = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nc"); - auto ct_a = mx_get_scalar_field(mx_input_multislice, "spec_cryst_a"); - auto ct_b = mx_get_scalar_field(mx_input_multislice, "spec_cryst_b"); - auto ct_c = mx_get_scalar_field(mx_input_multislice, "spec_cryst_c"); - auto ct_x0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_x0"); - auto ct_y0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_y0"); - - auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); - mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for(auto i = 0; i(mx_spec_amorp, i, "z_0"); - amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); - amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); - } - - input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); - input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); - input_multislice.atoms.set_atoms(atoms.rows, atoms.cols, atoms.real, lx, ly, lz, dz); - - /************************ Specimen rotation *************************/ - input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; - input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); - input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); - input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); - - /************************ Potential slicing ************************/ - input_multislice.potential_slicing = mx_get_scalar_field(mx_input_multislice, "potential_slicing"); - - /************************** xy sampling ****************************/ - auto nx = 1024; - auto ny = 1024; - bool bwl = false; - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - input_multislice.validate_parameters(); - } - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - using my_type = float; - /*************************Input data**************************/ - mt::Input_Multislice input_multislice; - read_input_multislice(prhs[0], input_multislice); - - mt::Spec spec; - spec.set_input_data(&input_multislice); - spec.move_atoms(input_multislice.pn_nconf); - - // /************************Output data**************************/ - auto atomsM = mx_create_matrix(spec.atoms.size(), 8, plhs[0]); - auto sliceM = mx_create_matrix(spec.slicing.slice.size(), 6, plhs[1]); - - for(auto i = 0; i + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "type_traits_gen.h" +#include "particles.cuh" +#include "spec.hpp" +#include "in_classes.cuh" + +#include +#include "matlab_mex.h" +#include "matlab_multem_io.h" + + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice& multem_in_parm) +{ + using T_r = mt::Value_type; + + multem_in_parm.elec_spec_interact_mod = mex_get_num_from_field(mex_multem_in_parm, "elec_spec_interact_mod"); + multem_in_parm.atomic_pot_parm_typ = mt::eappt_lobato_0_12; + + /************** Electron-Atomic_Vib interaction model **************/ + mex_read_atomic_vib(mex_multem_in_parm, multem_in_parm.atomic_vib); + multem_in_parm.atomic_vib.coh_contrib = true; + multem_in_parm.atomic_vib.sgl_conf = true; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + auto bs_z = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_z"); + auto sli_thick = mex_get_num_from_field(mex_multem_in_parm, "spec_dz"); + dt_bool pbc_xy = false; + + /************************* atomic positions ************************/ + mex_read_atoms(mex_multem_in_parm, bs_x, bs_y, bs_z, sli_thick, multem_in_parm.atoms); + + /************************ Specimen rotation ************************/ + mex_read_rot_in_parm(mex_multem_in_parm, multem_in_parm.rot_in_parm); + + /************************ Potential slicing ************************/ + mex_read_spec_sli_in_parm(mex_multem_in_parm, multem_in_parm.rot_in_parm); + + /************************** xy sampling ****************************/ + auto nx = 1024; + auto ny = 1024; + dt_bool bwl = false; + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + multem_in_parm.set_dep_var(); + } + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + /*************************Input data**************************/ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(prhs[0], multem_in_parm); + + mt::Spec spec; + spec.set_in_data(&multem_in_parm); + spec.move_atoms(multem_in_parm.atomic_vib.nconf); + + // /************************Output data**************************/ + auto atomsM = mex_create_pVctr(spec.atoms.size(), 8, plhs[0]); + auto sliceM = mex_create_pVctr(spec.slicing.slice.size(), 6, plhs[1]); + + for(auto i = 0; i < atomsM.rows; i++) + { + atomsM.real[0*atomsM.rows+i] = spec.atoms.Z[i]; + atomsM.real[1*atomsM.rows+i] = spec.atoms.x[i]; + atomsM.real[2*atomsM.rows+i] = spec.atoms.y[i]; + atomsM.real[3*atomsM.rows+i] = spec.atoms.z[i]; + atomsM.real[4*atomsM.rows+i] = spec.atoms.sigma[i]; + atomsM.real[5*atomsM.rows+i] = spec.atoms.occ[i]; + atomsM.real[6*atomsM.rows+i] = spec.atoms.tag[i]; + atomsM.real[7*atomsM.rows+i] = spec.atoms.charge[i]; + } + + for(auto i = 0; i + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "fcns_cgpu_gen.h" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto pE_0 = mex_get_pvctr(prhs[0]); + auto theta = (nrhs>1)?mex_get_num(prhs[1])*mt::c_deg_2_rad:0; + + /***************************************************************************************/ + auto ptransf_exp_factor = mex_create_pVctr(pE_0.shape(), plhs[0]); + + for (dt_uint32 ik = 0; ik < ptransf_exp_factor.size(); ik++) + { + ptransf_exp_factor[ik] = mt::fcn_transf_exp_factor(pE_0[ik], theta); + } +} \ No newline at end of file diff --git a/mex_files_multem/ilc_transmission_fcn.cu b/mex_files_multem/ilc_transmission_fcn.cu new file mode 100755 index 00000000..cd48e0c7 --- /dev/null +++ b/mex_files_multem/ilc_transmission_fcn.cu @@ -0,0 +1,163 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "cgpu_fft.cuh" +#include "particles.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" + +#include "transmission_fcn.cuh" + +#include +#include "matlab_mex.h" + +using mt::pMLD; +using mt::pMx_c; + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice &multem_in_parm, dt_bool full = true) +{ + using T_r = mt::Value_type; + + /************************ simulation type **************************/ + multem_in_parm.em_sim_typ = mt::eemst_tfrs; + + /***************************************************************************************/ + multem_in_parm.elec_spec_interact_mod = mex_get_num_from_field(mex_multem_in_parm, "elec_spec_interact_mod"); + multem_in_parm.atomic_pot_parm_typ = mex_get_num_from_field(mex_multem_in_parm, "atomic_pot_parm_typ"); + + /************** Electron-Atomic_Vib interaction model **************/ + mex_read_atomic_vib(mex_multem_in_parm, multem_in_parm.atomic_vib); + multem_in_parm.atomic_vib.coh_contrib = true; + multem_in_parm.atomic_vib.sgl_conf = true; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + auto bs_z = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_z"); + auto sli_thick = mex_get_num_from_field(mex_multem_in_parm, "spec_dz"); + dt_bool pbc_xy = true; + + if (full) + { + /************************* atomic positions ************************/ + mex_read_atoms(mex_multem_in_parm, bs_x, bs_y, bs_z, sli_thick, multem_in_parm.atoms); + } + + /************************ Specimen rotation ************************/ + mex_read_rot_in_parm(mex_multem_in_parm, multem_in_parm.rot_in_parm); + + /************************ Potential slicing ************************/ + multem_in_parm.spec_slic_typ = mex_get_num_from_field(mex_multem_in_parm, "spec_slic_typ"); + + /************************** xy sampling ****************************/ + auto nx = mex_get_num_from_field(mex_multem_in_parm, "nx"); + auto ny = mex_get_num_from_field(mex_multem_in_parm, "ny"); + dt_bool bwl = mex_get_bool_from_field(mex_multem_in_parm, "bwl"); + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + /********************* Microscope parameter ***********************/ + multem_in_parm.E_0 = mex_get_num_from_field(mex_multem_in_parm, "E_0"); + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "theta")*mt::c_deg_2_rad; + multem_in_parm.phi = mex_get_num_from_field(mex_multem_in_parm, "phi")*mt::c_deg_2_rad; + + multem_in_parm.islice = mex_get_num_from_field(mex_multem_in_parm, "islice")-1; + + /******************** select output region ************************/ + mex_read_output_area(mex_multem_in_parm, multem_in_parm.output_area); + + /********************* validate parameters *************************/ + multem_in_parm.set_dep_var(); +} + +template +void set_struct_transmission_function(TOutput_Multem &output_multem, mxArray*& mex_output_multem) +{ + const char *field_names_output_multem[] = {"dx", "dy", "x", "y", "thick", "trans"}; + dt_int32 number_of_fields_output_multem = 6; + mwSize dims_output_multem[2] = {1, 1}; + + mex_output_multem = mxCreateStructArray(2, dims_output_multem, number_of_fields_output_multem, field_names_output_multem); + + mex_create_set_num_field(mex_output_multem, 0, "dx", output_multem.dx); + mex_create_set_num_field(mex_output_multem, 0, "dy", output_multem.dy); + mex_create_set_pVctr_field(mex_output_multem, "x", 1, output_multem.x.size(), output_multem.x); + mex_create_set_pVctr_field(mex_output_multem, "y", 1, output_multem.y.size(), output_multem.y); + mex_create_set_pVctr_field(mex_output_multem, "thick", 1, output_multem.thick.size(), output_multem.thick); + mex_create_set_pVctr_field(mex_output_multem, "trans", output_multem.ny, output_multem.nx, output_multem.trans[0]); +} + +template +void run_transmission_function(mt::System_Config &system_config, const mxArray* mex_multem_in_parm, mxArray*& mex_output_multem) +{ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(mex_multem_in_parm, multem_in_parm); + multem_in_parm.system_config = system_config; + + mt::Stream stream(system_config.n_stream); + mt::FFT fft_2d; + fft_2d.create_plan_2d(multem_in_parm.grid_2d.ny, multem_in_parm.grid_2d.nx, system_config.n_stream); + + mt::Transmission_Fcn transmission_fcn; + transmission_fcn.set_in_data(&multem_in_parm, &stream, &fft_2d); + + mt::Output_Multem output_multem; + output_multem.set_in_data(&multem_in_parm); + + transmission_fcn.move_atoms(multem_in_parm.atomic_vib.nconf); + transmission_fcn.trans(multem_in_parm.islice, output_multem); + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + fft_2d.cleanup(); + + set_struct_transmission_function(output_multem, mex_output_multem); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto system_config = mex_read_system_config(prhs[0]); + system_config.set_gpu(); + + dt_int32 idx_0 = (system_config.active)?1:0; + + if (system_config.is_float32_cpu()) + { + run_transmission_function(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_cpu()) + { + run_transmission_function(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float32_gpu()) + { + run_transmission_function(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_gpu()) + { + run_transmission_function(system_config, prhs[idx_0], plhs[0]); + } +} \ No newline at end of file diff --git a/mex_files_multem/ilc_transmission_function.cu b/mex_files_multem/ilc_transmission_function.cu deleted file mode 100644 index ebedf318..00000000 --- a/mex_files_multem/ilc_transmission_function.cu +++ /dev/null @@ -1,191 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "atomic_data_mt.hpp" -#include "input_multislice.cuh" -#include "output_multislice.hpp" - -#include "transmission_function.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; -using mt::rmatrix_c; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - /************************ simulation type **************************/ - input_multislice.simulation_type = mt::eTEMST_TFRS; - - /*******************************************************************/ - input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); - input_multislice.potential_type = mx_get_scalar_field(mx_input_multislice, "potential_type"); - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); - input_multislice.pn_coh_contrib = true; - input_multislice.pn_single_conf = true; - input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); - input_multislice.pn_dim.set(mx_get_scalar_field(mx_input_multislice, "pn_dim")); - input_multislice.pn_seed = mx_get_scalar_field(mx_input_multislice, "pn_seed"); - - /**************************** Specimen *****************************/ - auto atoms = mx_get_matrix_field(mx_input_multislice, "spec_atoms"); - - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); - auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = true; - - auto ct_na = mx_get_scalar_field(mx_input_multislice, "spec_cryst_na"); - auto ct_nb = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nb"); - auto ct_nc = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nc"); - auto ct_a = mx_get_scalar_field(mx_input_multislice, "spec_cryst_a"); - auto ct_b = mx_get_scalar_field(mx_input_multislice, "spec_cryst_b"); - auto ct_c = mx_get_scalar_field(mx_input_multislice, "spec_cryst_c"); - auto ct_x0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_x0"); - auto ct_y0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_y0"); - - auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); - mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for(auto i = 0; i(mx_spec_amorp, i, "z_0"); - amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); - amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); - } - - if(full) - { - input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); - input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); - input_multislice.atoms.set_atoms(atoms.rows, atoms.cols, atoms.real, lx, ly, lz, dz); - } - - /************************ Specimen rotation *************************/ - input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; - input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); - input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); - input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); - - /************************ Potential slicing ************************/ - input_multislice.potential_slicing = mx_get_scalar_field(mx_input_multislice, "potential_slicing"); - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = mx_get_scalar_field(mx_input_multislice, "bwl"); - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; - input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; - - input_multislice.islice = mx_get_scalar_field(mx_input_multislice, "islice")-1; - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); -} - -template -void set_struct_transmission_function(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "trans"}; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - mx_create_set_matrix_field(mx_output_multislice, "trans", output_multislice.ny, output_multislice.nx, output_multislice.trans[0]); -} - -template -void run_transmission_function(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - - mt::Transmission_Function transmission_function; - transmission_function.set_input_data(&input_multislice, &stream, &fft_2d); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - transmission_function.move_atoms(input_multislice.pn_nconf); - transmission_function.trans(input_multislice.islice, output_multislice); - - stream.synchronize(); - - output_multislice.gather(); - output_multislice.clean_temporal(); - fft_2d.cleanup(); - - set_struct_transmission_function(output_multislice, mx_output_multislice); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; - - if(system_conf.is_float_host()) - { - run_transmission_function(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_host()) - { - run_transmission_function(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_float_device()) - { - run_transmission_function(system_conf, prhs[idx_0], plhs[0]); - } - else if(system_conf.is_double_device()) - { - run_transmission_function(system_conf, prhs[idx_0], plhs[0]); - } -} \ No newline at end of file diff --git a/mex_files_multem/ilc_vp.cpp b/mex_files_multem/ilc_vp.cpp deleted file mode 100644 index dbfed8f4..00000000 --- a/mex_files_multem/ilc_vp.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "atomic_fcns_mt.hpp" -#include "atomic_data.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto potential_type = mx_get_scalar(prhs[0]); - auto Z = mx_get_scalar(prhs[1]); - auto charge = mx_get_scalar(prhs[2]); - auto R = mx_get_matrix(prhs[3]); - - auto VR = mx_create_matrix(R.rows, R.cols, plhs[0]); - auto dVR = mx_create_matrix(R.rows, R.cols, plhs[1]); - - mt::Atom_Type atom_type; - mt::Atomic_Data atomic_data(potential_type); - atomic_data.To_atom_type_CPU(Z, mt::c_Vrl, mt::c_nR, 0.0, atom_type); - - mt::Atom_Cal atomic_fcns_mt; - atomic_fcns_mt.Set_Atom_Type(potential_type, charge, &atom_type); - atomic_fcns_mt.VR_dVR(R.m_size, R.real, VR.real, dVR.real); -} \ No newline at end of file diff --git a/mex_files_multem/ilc_vr.cpp b/mex_files_multem/ilc_vr.cpp old mode 100644 new mode 100755 index 23e5a8bd..a26346ee --- a/mex_files_multem/ilc_vr.cpp +++ b/mex_files_multem/ilc_vr.cpp @@ -1,45 +1,43 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "atomic_fcns_mt.hpp" -#include "atomic_data.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto potential_type = mx_get_scalar(prhs[0]); - auto Z = mx_get_scalar(prhs[1]); - auto charge = mx_get_scalar(prhs[2]); - auto r = mx_get_matrix(prhs[3]); - - auto Vr = mx_create_matrix(r.rows, r.cols, plhs[0]); - auto dVr = mx_create_matrix(r.rows, r.cols, plhs[1]); - - mt::Atom_Type atom_type; - mt::Atomic_Data atomic_data(potential_type); - atomic_data.To_atom_type_CPU(Z, mt::c_Vrl, mt::c_nR, 0.0, atom_type); - - mt::Atom_Cal atomic_fcns_mt; - atomic_fcns_mt.Set_Atom_Type(potential_type, charge, &atom_type); - atomic_fcns_mt.Vr_dVr(r.m_size, r.real, Vr.real, dVr.real); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_num(prhs[0]); + auto Z = mex_get_num(prhs[1]); + auto charge = mex_get_num(prhs[2]); + auto r = mex_get_pvctr(prhs[3]); + + /***************************************************************************************/ + auto vr = mex_create_pVctr(r.shape(), plhs[0]); + auto dvr = mex_create_pVctr(r.shape(), plhs[1]); + + mt::Atomic_Info_cpu atomic_info = mt::Atomic_Data(Z, atomic_pot_parm_typ, charge); + mt::Atomic_Fcns atomic_fcns_mt(atomic_info.coef[0]); + + atomic_fcns_mt.vr_dvr(r.ptr_32(), vr.ptr_32(), dvr.ptr_32()); } \ No newline at end of file diff --git a/mex_files_multem/ilc_vz.cpp b/mex_files_multem/ilc_vz.cpp old mode 100644 new mode 100755 index 02e575f5..9b4e0677 --- a/mex_files_multem/ilc_vz.cpp +++ b/mex_files_multem/ilc_vz.cpp @@ -1,47 +1,45 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "atomic_fcns_mt.hpp" -#include "atomic_data.hpp" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto potential_type = mx_get_scalar(prhs[0]); - auto Z = mx_get_scalar(prhs[1]); - auto charge = mx_get_scalar(prhs[2]); - auto z0 = mx_get_scalar(prhs[3]); - auto ze = mx_get_scalar(prhs[4]); - auto R = mx_get_matrix(prhs[5]); - - auto VR = mx_create_matrix(R.rows, R.cols, plhs[0]); - auto dVR = mx_create_matrix(R.rows, R.cols, plhs[1]); - - mt::Atom_Type atom_type; - mt::Atomic_Data atomic_data(potential_type); - atomic_data.To_atom_type_CPU(Z, mt::c_Vrl, mt::c_nR, 0.0, atom_type); - - mt::Atom_Cal atomic_fcns_mt; - atomic_fcns_mt.Set_Atom_Type(potential_type, charge, &atom_type); - atomic_fcns_mt.Vz_dVz(z0, ze, R.m_size, R.real, VR.real, dVR.real); +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_num(prhs[0]); + auto Z = mex_get_num(prhs[1]); + auto charge = mex_get_num(prhs[2]); + auto z0 = mex_get_num(prhs[3]); + auto ze = mex_get_num(prhs[4]); + auto r = mex_get_pvctr(prhs[5]); + + /***************************************************************************************/ + auto vz = mex_create_pVctr(r.shape(), plhs[0]); + auto dvz = mex_create_pVctr(r.shape(), plhs[1]); + + mt::Atomic_Info_cpu atomic_info = mt::Atomic_Data(Z, atomic_pot_parm_typ, charge); + mt::Atomic_Fcns atomic_fcns_mt(atomic_info.coef[0]); + + atomic_fcns_mt.vz_dvz(z0, ze, r.ptr_32(), vz.ptr_32(), dvz.ptr_32()); } \ No newline at end of file diff --git a/mex_files_multem/ilc_vzp.cpp b/mex_files_multem/ilc_vzp.cpp new file mode 100755 index 00000000..759d4901 --- /dev/null +++ b/mex_files_multem/ilc_vzp.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "atomic_fcns_mt.cuh" + +#include "mex.h" +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto atomic_pot_parm_typ = mex_get_num(prhs[0]); + auto Z = mex_get_num(prhs[1]); + auto charge = mex_get_num(prhs[2]); + auto r = mex_get_pvctr(prhs[3]); + + /***************************************************************************************/ + auto vzp = mex_create_pVctr(r.shape(), plhs[0]); + auto dvzp = mex_create_pVctr(r.shape(), plhs[1]); + + mt::Atomic_Info_cpu atomic_info = mt::Atomic_Data(Z, atomic_pot_parm_typ, charge); + mt::Atomic_Fcns atomic_fcns_mt(atomic_info.coef[0]); + + atomic_fcns_mt.vzp_dvzp(r.ptr_32(), vzp.ptr_32(), dvzp.ptr_32()); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_wave_function.cu b/mex_files_multem/ilc_wave_function.cu old mode 100644 new mode 100755 index e13e2192..48e983f2 --- a/mex_files_multem/ilc_wave_function.cu +++ b/mex_files_multem/ilc_wave_function.cu @@ -1,291 +1,209 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "atomic_data_mt.hpp" -#include "slicing.hpp" -#include "input_multislice.cuh" -#include "output_multislice.hpp" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" -#include "cgpu_fcns.cuh" -#include "wave_function.cuh" - -#include -#include "matlab_mex.cuh" - -using mt::rmatrix_r; -using mt::rmatrix_c; - -template -void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice &input_multislice, bool full = true) -{ - using T_r = mt::Value_type; - - /************************ simulation type **************************/ - input_multislice.simulation_type = mx_get_scalar_field(mx_input_multislice, "simulation_type"); - input_multislice.simulation_type = (input_multislice.is_EWRS()) ? mt::eTEMST_EWRS : mt::eTEMST_EWFS; - - input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); - input_multislice.potential_type = mx_get_scalar_field(mx_input_multislice, "potential_type"); - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); - input_multislice.pn_coh_contrib = true; - input_multislice.pn_single_conf = true; - input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); - input_multislice.pn_dim.set(mx_get_scalar_field(mx_input_multislice, "pn_dim")); - input_multislice.pn_seed = mx_get_scalar_field(mx_input_multislice, "pn_seed"); - - /**************************** Specimen *****************************/ - auto atoms = mx_get_matrix_field(mx_input_multislice, "spec_atoms"); - - auto lx = mx_get_scalar_field(mx_input_multislice, "spec_lx"); - auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); - auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); - auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = true; - - auto ct_na = mx_get_scalar_field(mx_input_multislice, "spec_cryst_na"); - auto ct_nb = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nb"); - auto ct_nc = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nc"); - auto ct_a = mx_get_scalar_field(mx_input_multislice, "spec_cryst_a"); - auto ct_b = mx_get_scalar_field(mx_input_multislice, "spec_cryst_b"); - auto ct_c = mx_get_scalar_field(mx_input_multislice, "spec_cryst_c"); - auto ct_x0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_x0"); - auto ct_y0 = mx_get_scalar_field(mx_input_multislice, "spec_cryst_y0"); - - auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); - mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for (auto i = 0; i < amorp_lay_info.size(); i++) - { - amorp_lay_info[i].z_0 = mx_get_scalar_field(mx_spec_amorp, i, "z_0"); - amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); - amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); - } - - if (full) - { - input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); - input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); - input_multislice.atoms.set_atoms(atoms.rows, atoms.cols, atoms.real, lx, ly, lz, dz); - } - - /************************ Specimen rotation *************************/ - input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; - input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); - input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); - input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); - - /************************ Specimen thickness ***********************/ - input_multislice.thick_type = mx_get_scalar_field(mx_input_multislice, "thick_type"); - if (!input_multislice.is_whole_spec() && full) - { - auto thick = mx_get_matrix_field(mx_input_multislice, "thick"); - mt::assign(thick, input_multislice.thick); - } - - /************************ Potential slicing ************************/ - input_multislice.potential_slicing = mx_get_scalar_field(mx_input_multislice, "potential_slicing"); - - /************************** xy sampling ****************************/ - auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); - auto ny = mx_get_scalar_field(mx_input_multislice, "ny"); - bool bwl = mx_get_scalar_field(mx_input_multislice, "bwl"); - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************** Incident wave **************************/ - auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); - input_multislice.set_incident_wave_type(iw_type); - - if (input_multislice.is_user_define_wave() && full) - { - auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); - mt::assign(iw_psi, input_multislice.iw_psi); - } - - // read iw_x and iw_y - auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); - auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin() + n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin() + n_iw_xy); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); - input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; - input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; - - /********************* Illumination model *************************/ - input_multislice.illumination_model = mt::eIM_Coherent; - input_multislice.temporal_spatial_incoh = mt::eTSI_Temporal_Spatial; - - /*********************** Condenser lens ***************************/ - input_multislice.cond_lens.m = mx_get_scalar_field(mx_input_multislice, "cond_lens_m"); // momentum of the vortex - input_multislice.cond_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_10"); // defocus (Angstrom) - input_multislice.cond_lens.c_12 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_12"); // 2-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_12 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_21 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_21"); // Axial coma (Angstrom) - input_multislice.cond_lens.phi_21 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.cond_lens.c_23 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_23"); // 3-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_23 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_30 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_30")*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.c_32 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_32"); // Axial star aberration (Angstrom) - input_multislice.cond_lens.phi_32 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_34 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_34"); // 4-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_34 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_41 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_41"); // 4th order axial coma (Angstrom) - input_multislice.cond_lens.phi_41 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.cond_lens.c_43 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_43"); // 3-lobe aberration (Angstrom) - input_multislice.cond_lens.phi_43 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.cond_lens.c_45 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_45"); // 5-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_45 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_50 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_50")*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.c_52 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_52"); // 5th order axial star aberration (Angstrom) - input_multislice.cond_lens.phi_52 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_54 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_54"); // 5th order rosette aberration (Angstrom) - input_multislice.cond_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) - input_multislice.cond_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "cond_lens_c_56"); // 6-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "cond_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.cond_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - /********************* defocus spread function ********************/ - input_multislice.cond_lens.ti_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_sigma"); // standard deviation (Angstrom) - input_multislice.cond_lens.ti_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_ti_npts"); // # of integration points - - /********************* source spread function *********************/ - input_multislice.cond_lens.si_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_sigma"); // standard deviation: For parallel ilumination(�^-1); otherwise (�) - input_multislice.cond_lens.si_rad_npts = mx_get_scalar_field(mx_input_multislice, "cond_lens_si_rad_npts"); // # of integration points - - /********************* zero defocus reference ********************/ - input_multislice.cond_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_type"); // Zero defocus type - input_multislice.cond_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_plane"); // Zero defocus position - - input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /************************ Objective lens **************************/ - input_multislice.obj_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_type"); // Zero defocus type - input_multislice.obj_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_plane"); // Zero defocus position - - input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /********************* select output region *************************/ - input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; - input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; - input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; - input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; - - /********************* validate parameters *************************/ - input_multislice.validate_parameters(); -} - -template -void set_struct_wave_function(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) -{ - const char *field_names_output_multislice[] = { "dx", "dy", "x", "y", "thick", "data" }; - int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = { 1, 1 }; - - mxArray *mx_field_psi; - const char *field_names_psi[] = { "psi_coh" }; - int number_of_fields_psi = 1; - mwSize dims_psi[2] = { 1, output_multislice.thick.size() }; - - mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); - - mx_create_set_scalar_field(mx_output_multislice, 0, "dx", output_multislice.dx); - mx_create_set_scalar_field(mx_output_multislice, 0, "dy", output_multislice.dy); - mx_create_set_matrix_field(mx_output_multislice, "x", 1, output_multislice.x.size(), output_multislice.x); - mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); - mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - - mx_field_psi = mxCreateStructArray(2, dims_psi, number_of_fields_psi, field_names_psi); - mxSetField(mx_output_multislice, 0, "data", mx_field_psi); - - for (auto ithk = 0; ithk < output_multislice.thick.size(); ithk++) - { - mx_create_set_matrix_field(mx_field_psi, ithk, "psi_coh", output_multislice.ny, output_multislice.nx, output_multislice.psi_coh[ithk]); - } -} - -template -void run_wave_function(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) -{ - mt::Input_Multislice input_multislice; - read_input_multislice(mx_input_multislice, input_multislice); - input_multislice.system_conf = system_conf; - - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - - mt::Wave_Function wave_function; - wave_function.set_input_data(&input_multislice, &stream, &fft_2d); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); - - wave_function.move_atoms(input_multislice.pn_nconf); - wave_function.set_incident_wave(wave_function.psi_z); - wave_function.psi(1.0, wave_function.psi_z, output_multislice); - - stream.synchronize(); - - output_multislice.gather(); - output_multislice.clean_temporal(); - - fft_2d.cleanup(); - - set_struct_wave_function(output_multislice, mx_output_multislice); -} - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active) ? 1 : 0; - - if (system_conf.is_float_host()) - { - run_wave_function(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_double_host()) - { - run_wave_function(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_float_device()) - { - run_wave_function(system_conf, prhs[idx_0], plhs[0]); - } - else if (system_conf.is_double_device()) - { - run_wave_function(system_conf, prhs[idx_0], plhs[0]); - } +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "cgpu_fft.cuh" +#include "particles.cuh" +#include "spec_slic.hpp" +#include "in_classes.cuh" +#include "output_multem.hpp" +#include "fcns_cpu.h" +#include "fcns_gpu.h" +#include "fcns_gpu.h" +#include "wave_function.cuh" + +#include +#include "matlab_mex.h" + +using mt::pMLD; +using mt::pMx_c; + +template +void read_multem_in_parm(const mxArray* mex_multem_in_parm, TIn_Multislice &multem_in_parm, dt_bool full = true) +{ + using T_r = mt::Value_type; + + /************************ simulation type **************************/ + multem_in_parm.em_sim_typ = mex_get_num_from_field(mex_multem_in_parm, "em_sim_typ"); + multem_in_parm.em_sim_typ = (multem_in_parm.is_EWRS())?mt::eemst_ewrs:mt::eemst_ewfs; + + multem_in_parm.elec_spec_interact_mod = mex_get_num_from_field(mex_multem_in_parm, "elec_spec_interact_mod"); + multem_in_parm.atomic_pot_parm_typ = mex_get_num_from_field(mex_multem_in_parm, "atomic_pot_parm_typ"); + + /************** Electron-Atomic_Vib interaction model **************/ + mex_read_atomic_vib(mex_multem_in_parm, multem_in_parm.atomic_vib); + multem_in_parm.atomic_vib.coh_contrib = true; + multem_in_parm.atomic_vib.sgl_conf = true; + + /**************************** Specimen *****************************/ + auto bs_x = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_x"); + auto bs_y = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_y"); + auto bs_z = mex_get_num_from_field(mex_multem_in_parm, "spec_bs_z"); + auto sli_thick = mex_get_num_from_field(mex_multem_in_parm, "spec_dz"); + dt_bool pbc_xy = true; + + if (full) + { + /************************* atomic positions ************************/ + mex_read_atoms(mex_multem_in_parm, bs_x, bs_y, bs_z, sli_thick, multem_in_parm.atoms); + } + + /************************ Specimen rotation ************************/ + mex_read_rot_in_parm(mex_multem_in_parm, multem_in_parm.rot_in_parm); + + /************************ Specimen thickness ***********************/ + multem_in_parm.thick_type = mex_get_num_from_field(mex_multem_in_parm, "thick_type"); + if (!multem_in_parm.is_sim_whole_spec() && full) + { + mex_read_spec_thick(mex_multem_in_parm, multem_in_parm.thick); + } + + /************************ Potential slicing ************************/ + multem_in_parm.spec_slic_typ = mex_get_num_from_field(mex_multem_in_parm, "spec_slic_typ"); + + /************************** xy sampling ****************************/ + auto nx = mex_get_num_from_field(mex_multem_in_parm, "nx"); + auto ny = mex_get_num_from_field(mex_multem_in_parm, "ny"); + dt_bool bwl = mex_get_bool_from_field(mex_multem_in_parm, "bwl"); + + multem_in_parm.grid_2d.set_in_data(nx, ny, bs_x, bs_y, sli_thick, bwl, pbc_xy); + + /************************** Incident wave **************************/ + auto iw_type = mex_get_num_from_field(mex_multem_in_parm, "iw_type"); + multem_in_parm.set_incident_wave_type(iw_type); + + if (multem_in_parm.is_user_define_wave() && full) + { + mex_read_user_define_wave(mex_multem_in_parm, multem_in_parm.iw_psi); + } + + /********************* read beam positions *************************/ + mex_read_beam_pos(mex_multem_in_parm, multem_in_parm.beam_pos_2d); + + /********************* Microscope parameter ***********************/ + multem_in_parm.E_0 = mex_get_num_from_field(mex_multem_in_parm, "E_0"); + multem_in_parm.theta = mex_get_num_from_field(mex_multem_in_parm, "theta")*mt::c_deg_2_rad; + multem_in_parm.phi = mex_get_num_from_field(mex_multem_in_parm, "phi")*mt::c_deg_2_rad; + + /********************* Illumination model *************************/ + multem_in_parm.illum_mod = mt::eim_coherent; + multem_in_parm.illum_inc = mt::eii_temporal_spatial; + + /*********************** Condenser lens ***************************/ + mex_read_cond_lens(mex_multem_in_parm, multem_in_parm.cond_lens); + multem_in_parm.cond_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /*********************** Objective lens ***************************/ + mex_read_obj_lens(mex_multem_in_parm, multem_in_parm.obj_lens); + multem_in_parm.obj_lens.set_in_data(multem_in_parm.E_0, multem_in_parm.grid_2d); + + /******************** select output region ************************/ + mex_read_output_area(mex_multem_in_parm, multem_in_parm.output_area); + + /********************* validate parameters *************************/ + multem_in_parm.set_dep_var(); +} + +template +void set_struct_wave_function(TOutput_Multem &output_multem, mxArray*& mex_output_multem) +{ + const char *field_names_output_multem[] = { "dx", "dy", "x", "y", "thick", "data" }; + dt_int32 number_of_fields_output_multem = 6; + mwSize dims_output_multem[2] = { 1, 1 }; + + mxArray* mex_field_psi; + const char *field_names_psi[] = { "psi_coh" }; + dt_int32 number_of_fields_psi = 1; + mwSize dims_psi[2] = { 1, output_multem.thick.size() }; + + mex_output_multem = mxCreateStructArray(2, dims_output_multem, number_of_fields_output_multem, field_names_output_multem); + + mex_create_set_num_field(mex_output_multem, 0, "dx", output_multem.dx); + mex_create_set_num_field(mex_output_multem, 0, "dy", output_multem.dy); + mex_create_set_pVctr_field(mex_output_multem, "x", 1, output_multem.x.size(), output_multem.x); + mex_create_set_pVctr_field(mex_output_multem, "y", 1, output_multem.y.size(), output_multem.y); + mex_create_set_pVctr_field(mex_output_multem, "thick", 1, output_multem.thick.size(), output_multem.thick); + + mex_field_psi = mxCreateStructArray(2, dims_psi, number_of_fields_psi, field_names_psi); + mxSetField(mex_output_multem, 0, "data", mex_field_psi); + + for(auto ithk = 0; ithk < output_multem.thick.size(); ithk++) + { + mex_create_set_pVctr_field(mex_field_psi, ithk, "psi_coh", output_multem.ny, output_multem.nx, output_multem.psi_coh[ithk]); + } +} + +template +void run_wave_function(mt::System_Config &system_config, const mxArray* mex_multem_in_parm, mxArray*& mex_output_multem) +{ + mt::Multem_In_Parm multem_in_parm; + read_multem_in_parm(mex_multem_in_parm, multem_in_parm); + multem_in_parm.system_config = system_config; + + mt::Stream stream(system_config.n_stream); + mt::FFT fft_2d; + fft_2d.create_plan_2d(multem_in_parm.grid_2d.ny, multem_in_parm.grid_2d.nx, system_config.n_stream); + + mt::Wave_Function wave_function; + wave_function.set_in_data(&multem_in_parm, &stream, &fft_2d); + + mt::Output_Multem output_multem; + output_multem.set_in_data(&multem_in_parm); + + wave_function.move_atoms(multem_in_parm.atomic_vib.nconf); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(1.0, wave_function.psi_z, output_multem); + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + + fft_2d.cleanup(); + + set_struct_wave_function(output_multem, mex_output_multem); +} + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + auto system_config = mex_read_system_config(prhs[0]); + system_config.set_gpu(); + + dt_int32 idx_0 = (system_config.active)?1:0; + + if (system_config.is_float32_cpu()) + { + // run_wave_function(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_cpu()) + { + // run_wave_function(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float32_gpu()) + { + run_wave_function(system_config, prhs[idx_0], plhs[0]); + } + else if (system_config.is_float64_gpu()) + { + // run_wave_function(system_config, prhs[idx_0], plhs[0]); + } } \ No newline at end of file diff --git a/mex_files_multem/ilc_xtl_build.cpp b/mex_files_multem/ilc_xtl_build.cpp new file mode 100755 index 00000000..1562116b --- /dev/null +++ b/mex_files_multem/ilc_xtl_build.cpp @@ -0,0 +1,67 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "const_enum.h" +#include "particles.cuh" +#include "xtl_build_in_parm.hpp" +#include "xtl_build.hpp" + +#include +#include "matlab_mex.h" + +template +void read_xtl_build_in_parm(const mxArray* mex_xtl_build_in_parm, mt::Xtl_Build_In_Parm& xtl_build_in_parm) +{ + xtl_build_in_parm.a = mex_get_num_from_field(mex_xtl_build_in_parm, "a"); + xtl_build_in_parm.b = mex_get_num_from_field(mex_xtl_build_in_parm, "b"); + xtl_build_in_parm.c = mex_get_num_from_field(mex_xtl_build_in_parm, "c"); + + xtl_build_in_parm.alpha = mex_get_num_from_field(mex_xtl_build_in_parm, "alpha")*mt::c_deg_2_rad; + xtl_build_in_parm.beta = mex_get_num_from_field(mex_xtl_build_in_parm, "beta")*mt::c_deg_2_rad; + xtl_build_in_parm.gamma = mex_get_num_from_field(mex_xtl_build_in_parm, "gamma")*mt::c_deg_2_rad; + + xtl_build_in_parm.n_a = mex_get_num_from_field(mex_xtl_build_in_parm, "na"); + xtl_build_in_parm.n_b = mex_get_num_from_field(mex_xtl_build_in_parm, "nb"); + xtl_build_in_parm.n_c = mex_get_num_from_field(mex_xtl_build_in_parm, "nc"); + + xtl_build_in_parm.sgn = mex_get_num_from_field(mex_xtl_build_in_parm, "sgn"); + + xtl_build_in_parm.pbc = mex_get_bool_from_field(mex_xtl_build_in_parm, "pbc"); + + auto pasym_uc = mex_get_pvctr_from_field(mex_xtl_build_in_parm, "asym_uc"); + xtl_build_in_parm.asym_uc.set_ptc(pasym_uc, {0, 0, 0}, false); + + auto pbase = mex_get_pvctr_from_field(mex_xtl_build_in_parm, "base"); + xtl_build_in_parm.base.set_ptc(pbase, {0, 0, 0}, false); + } + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + mt::Xtl_Build_In_Parm xtl_build_in_parm; + read_xtl_build_in_parm(prhs[0], xtl_build_in_parm); + + mt::Xtl_Build xtl_build(xtl_build_in_parm); + auto atoms = xtl_build(); + + auto patoms = mex_create_pVctr({atoms.size(), atoms.cols_used}, plhs[0]); + atoms.cpy_to_ptr(patoms.data(), atoms.size(), 0, atoms.cols_used); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_xtl_build_base.cpp b/mex_files_multem/ilc_xtl_build_base.cpp new file mode 100755 index 00000000..3c36741b --- /dev/null +++ b/mex_files_multem/ilc_xtl_build_base.cpp @@ -0,0 +1,39 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "particles.cuh" +#include "space_group.hpp" + +#include +#include "matlab_mex.h" + +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto pasym_uc = mex_get_pvctr(prhs[0]); + auto sgn = mex_get_num(prhs[1]); + + mt::Ptc_Atom asym_uc(pasym_uc, {0, 0, 0}, false); + mt::Ptc_Atom base = mt::Space_Group(asym_uc, sgn); + + auto pbase = mex_create_pVctr({base.size(), base.cols_used}, plhs[0]); + base.cpy_to_ptr(pbase.data(), base.size(), 0, base.cols_used); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_xtl_csn_2_sgr.cpp b/mex_files_multem/ilc_xtl_csn_2_sgr.cpp new file mode 100755 index 00000000..277c82ac --- /dev/null +++ b/mex_files_multem/ilc_xtl_csn_2_sgr.cpp @@ -0,0 +1,38 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "xtl_build.hpp" + +#include +#include "matlab_mex.h" + +// from xtl system number (csn) -> space group range (sgr) +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto csn = mex_get_num(prhs[0]); + + /***************************************************************************************/ + auto sgr = mt::xtl_csn_2_sgr(csn); + + mex_create_set_num(plhs[0], sgr.first); + mex_create_set_num(plhs[1], sgr.second); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_xtl_css_2_csn.cpp b/mex_files_multem/ilc_xtl_css_2_csn.cpp new file mode 100755 index 00000000..fbf64359 --- /dev/null +++ b/mex_files_multem/ilc_xtl_css_2_csn.cpp @@ -0,0 +1,37 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "xtl_build.hpp" + +#include +#include "matlab_mex.h" + +// from xtl system string (css) -> xtl system number (csn) +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto css = mex_get_string(prhs[0]); + + /***************************************************************************************/ + auto csn = mt::xtl_css_2_csn(css); + + mex_create_set_num(plhs[0], csn); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_xtl_css_2_sgr.cpp b/mex_files_multem/ilc_xtl_css_2_sgr.cpp new file mode 100755 index 00000000..d95bd4f3 --- /dev/null +++ b/mex_files_multem/ilc_xtl_css_2_sgr.cpp @@ -0,0 +1,38 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "xtl_build.hpp" + +#include +#include "matlab_mex.h" + +// from xtl system string (css) -> space group range (sgr) +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto css = mex_get_string(prhs[0]); + + /***************************************************************************************/ + auto sgr = mt::xtl_css_2_sgr(css); + + mex_create_set_num(plhs[0], sgr.first); + mex_create_set_num(plhs[1], sgr.second); +} \ No newline at end of file diff --git a/mex_files_multem/ilc_xtl_sgn_2_csn.cpp b/mex_files_multem/ilc_xtl_sgn_2_csn.cpp new file mode 100755 index 00000000..972445d7 --- /dev/null +++ b/mex_files_multem/ilc_xtl_sgn_2_csn.cpp @@ -0,0 +1,37 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANT ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#define MATLAB_BLAS_LAPACK + +#include "xtl_build.hpp" + +#include +#include "matlab_mex.h" + +// from space group number (sgn) -> xtl system number (csn) +void mexFunction(dt_int32 nlhs, mxArray* plhs[], dt_int32 nrhs, const mxArray* prhs[]) +{ + using T = dt_float64; + + auto sgn = mex_get_num(prhs[0]); + + /***************************************************************************************/ + auto csn = mt::xtl_sgn_2_csn(sgn); + + mex_create_set_num(plhs[0], csn); +} \ No newline at end of file diff --git a/mex_files_multem/mex_Vp.m b/mex_files_multem/mex_Vp.m new file mode 100755 index 00000000..47a6d454 --- /dev/null +++ b/mex_files_multem/mex_Vp.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_vp.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_add_amorp_lay.m b/mex_files_multem/mex_add_amorp_lay.m deleted file mode 100644 index efc558ff..00000000 --- a/mex_files_multem/mex_add_amorp_lay.m +++ /dev/null @@ -1,4 +0,0 @@ -clc; clear all; -addpath('../matlab_functions') - -ilm_mex('release', 'ilc_add_amorp_lay.cpp', '../src'); diff --git a/mex_files_multem/mex_amorp_build.m b/mex_files_multem/mex_amorp_build.m new file mode 100755 index 00000000..c7ee64d6 --- /dev/null +++ b/mex_files_multem/mex_amorp_build.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_amorp_build.cpp', '../src'); diff --git a/mex_files_multem/mex_amorp_lay_add.m b/mex_files_multem/mex_amorp_lay_add.m new file mode 100755 index 00000000..e78fea01 --- /dev/null +++ b/mex_files_multem/mex_amorp_lay_add.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_amorp_lay_add.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_amorp_spec.m b/mex_files_multem/mex_amorp_spec.m deleted file mode 100644 index 0d66d890..00000000 --- a/mex_files_multem/mex_amorp_spec.m +++ /dev/null @@ -1,4 +0,0 @@ -clc; clear all; -addpath('../matlab_functions') - -ilm_mex('release', 'ilc_amorp_spec.cpp', '../src'); diff --git a/mex_files_multem/mex_apply_ctf.m b/mex_files_multem/mex_apply_ctf.m deleted file mode 100644 index f26c0186..00000000 --- a/mex_files_multem/mex_apply_ctf.m +++ /dev/null @@ -1,4 +0,0 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_apply_ctf.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_atomic_info.m b/mex_files_multem/mex_atomic_info.m new file mode 100755 index 00000000..66c37ffa --- /dev/null +++ b/mex_files_multem/mex_atomic_info.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_atomic_info.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_atomic_radius.m b/mex_files_multem/mex_atomic_radius.m new file mode 100755 index 00000000..3c910dfd --- /dev/null +++ b/mex_files_multem/mex_atomic_radius.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_atomic_radius.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_crystal_by_lays.m b/mex_files_multem/mex_crystal_by_lays.m deleted file mode 100644 index de587622..00000000 --- a/mex_files_multem/mex_crystal_by_lays.m +++ /dev/null @@ -1,3 +0,0 @@ -clc; clear all; - -ilm_mex('release', 'ilc_crystal_by_lays.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_det_min_spl.m b/mex_files_multem/mex_det_min_spl.m new file mode 100755 index 00000000..63b31f97 --- /dev/null +++ b/mex_files_multem/mex_det_min_spl.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_det_min_spl.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_elec_interact_parm.m b/mex_files_multem/mex_elec_interact_parm.m new file mode 100755 index 00000000..85ac55a6 --- /dev/null +++ b/mex_files_multem/mex_elec_interact_parm.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_elec_interact_parm_kva.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_feg.m b/mex_files_multem/mex_feg.m old mode 100644 new mode 100755 index 090342c0..8d5011e9 --- a/mex_files_multem/mex_feg.m +++ b/mex_files_multem/mex_feg.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_feg.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_feg_parm_coef.m b/mex_files_multem/mex_feg_parm_coef.m new file mode 100755 index 00000000..c640d190 --- /dev/null +++ b/mex_files_multem/mex_feg_parm_coef.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_feg_parm_coef.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_fwhm_2_sigma.m b/mex_files_multem/mex_fwhm_2_sigma.m old mode 100644 new mode 100755 index 54bc90a7..fb1e70b8 --- a/mex_files_multem/mex_fwhm_2_sigma.m +++ b/mex_files_multem/mex_fwhm_2_sigma.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_fwhm_2_sigma.cpp', '../src'); +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_fwhm_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_fxeg_data.m b/mex_files_multem/mex_fxeg_data.m old mode 100644 new mode 100755 index 82135503..ebb1e502 --- a/mex_files_multem/mex_fxeg_data.m +++ b/mex_files_multem/mex_fxeg_data.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_fxeg_data.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_fxeg_tabulated_data.m b/mex_files_multem/mex_fxeg_tabulated_data.m new file mode 100755 index 00000000..4c74bd83 --- /dev/null +++ b/mex_files_multem/mex_fxeg_tabulated_data.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_fxeg_tabulated_data.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_fxg.m b/mex_files_multem/mex_fxg.m old mode 100644 new mode 100755 index 65bc1785..2c2c0a64 --- a/mex_files_multem/mex_fxg.m +++ b/mex_files_multem/mex_fxg.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_fxg.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_g_max.m b/mex_files_multem/mex_g_max.m new file mode 100755 index 00000000..4dc53583 --- /dev/null +++ b/mex_files_multem/mex_g_max.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_g_max.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_gamma.m b/mex_files_multem/mex_gamma.m old mode 100644 new mode 100755 index 4f583edd..ea45f1ed --- a/mex_files_multem/mex_gamma.m +++ b/mex_files_multem/mex_gamma.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath('../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_gamma.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_gmax.m b/mex_files_multem/mex_gmax.m old mode 100644 new mode 100755 index 9f94ba91..eb9ba4f4 --- a/mex_files_multem/mex_gmax.m +++ b/mex_files_multem/mex_gmax.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) ilm_mex('release', 'ilc_gmax.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_hwhm_2_sigma.m b/mex_files_multem/mex_hwhm_2_sigma.m old mode 100644 new mode 100755 index c4f9defc..69704db6 --- a/mex_files_multem/mex_hwhm_2_sigma.m +++ b/mex_files_multem/mex_hwhm_2_sigma.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_hwhm_2_sigma.cpp', '../src'); +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_hwhm_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_iehwgd_2_sigma.m b/mex_files_multem/mex_iehwgd_2_sigma.m old mode 100644 new mode 100755 index db090315..b856477d --- a/mex_files_multem/mex_iehwgd_2_sigma.m +++ b/mex_files_multem/mex_iehwgd_2_sigma.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_iehwgd_2_sigma.cpp', '../src'); +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_iehwgd_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_incident_wave.m b/mex_files_multem/mex_incident_wave.m old mode 100644 new mode 100755 index b73ec1a3..d8da6d56 --- a/mex_files_multem/mex_incident_wave.m +++ b/mex_files_multem/mex_incident_wave.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_incident_wave.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_lambda.m b/mex_files_multem/mex_lambda.m old mode 100644 new mode 100755 index 3905d185..5f24d90e --- a/mex_files_multem/mex_lambda.m +++ b/mex_files_multem/mex_lambda.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_lambda.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_max_dist.m b/mex_files_multem/mex_max_dist.m new file mode 100755 index 00000000..f8559d29 --- /dev/null +++ b/mex_files_multem/mex_max_dist.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_max_dist.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_microscope_aberrations.m b/mex_files_multem/mex_microscope_aberrations.m old mode 100644 new mode 100755 index 32471e13..5a2585cf --- a/mex_files_multem/mex_microscope_aberrations.m +++ b/mex_files_multem/mex_microscope_aberrations.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_microscope_aberrations.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_min_dist.m b/mex_files_multem/mex_min_dist.m new file mode 100755 index 00000000..4f4b705e --- /dev/null +++ b/mex_files_multem/mex_min_dist.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_min_dist.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_min_spl.m b/mex_files_multem/mex_min_spl.m deleted file mode 100644 index efc2f156..00000000 --- a/mex_files_multem/mex_min_spl.m +++ /dev/null @@ -1,4 +0,0 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_min_spl.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_mrad_2_rAng.m b/mex_files_multem/mex_mrad_2_rAng.m deleted file mode 100644 index bf971006..00000000 --- a/mex_files_multem/mex_mrad_2_rAng.m +++ /dev/null @@ -1,4 +0,0 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_mrad_2_rAng.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_mrad_2_rangs.m b/mex_files_multem/mex_mrad_2_rangs.m new file mode 100755 index 00000000..95d45939 --- /dev/null +++ b/mex_files_multem/mex_mrad_2_rangs.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_mrad_2_rangs.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_mrad_2_sigma.m b/mex_files_multem/mex_mrad_2_sigma.m old mode 100644 new mode 100755 index 7f0fc301..c16f53d1 --- a/mex_files_multem/mex_mrad_2_sigma.m +++ b/mex_files_multem/mex_mrad_2_sigma.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_mrad_2_sigma.cpp', '../src'); +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_mrad_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_multem.m b/mex_files_multem/mex_multem.m old mode 100644 new mode 100755 index b846c1a3..1c9c537b --- a/mex_files_multem/mex_multem.m +++ b/mex_files_multem/mex_multem.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_multem.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_pn_fact.m b/mex_files_multem/mex_pn_fact.m old mode 100644 new mode 100755 index d1491cd8..d23e308a --- a/mex_files_multem/mex_pn_fact.m +++ b/mex_files_multem/mex_pn_fact.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_pn_fact.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_pr.m b/mex_files_multem/mex_pr.m old mode 100644 new mode 100755 index 77e5dde8..b5be907d --- a/mex_files_multem/mex_pr.m +++ b/mex_files_multem/mex_pr.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_pr.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_projected_potential.m b/mex_files_multem/mex_projected_potential.m old mode 100644 new mode 100755 index b9f20408..6b2bb631 --- a/mex_files_multem/mex_projected_potential.m +++ b/mex_files_multem/mex_projected_potential.m @@ -1,4 +1,3 @@ -clc; clear all; -addpath( '../matlab_functions') - +clc; clear; + ilm_mex('release', 'ilc_projected_potential.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_propagate.m b/mex_files_multem/mex_propagate.m old mode 100644 new mode 100755 index 46ceb427..ce88b9ba --- a/mex_files_multem/mex_propagate.m +++ b/mex_files_multem/mex_propagate.m @@ -1,4 +1,3 @@ -clc; clear all; -addpath( '../matlab_functions') - +clc; clear; + ilm_mex('release', 'ilc_propagate.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_rangs_2_mrad.m b/mex_files_multem/mex_rangs_2_mrad.m new file mode 100755 index 00000000..387f1a18 --- /dev/null +++ b/mex_files_multem/mex_rangs_2_mrad.m @@ -0,0 +1,3 @@ +clc; clear; + +ilm_mex('release', 'ilc_rangs_2_mrad.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_rdf.m b/mex_files_multem/mex_rdf.m new file mode 100755 index 00000000..fc6952bd --- /dev/null +++ b/mex_files_multem/mex_rdf.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath([ fileparts(pwd), filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_rdf.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_rdf_3d.m b/mex_files_multem/mex_rdf_3d.m deleted file mode 100644 index a96ba4a1..00000000 --- a/mex_files_multem/mex_rdf_3d.m +++ /dev/null @@ -1,4 +0,0 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_rdf_3d.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_scherzer_aperture.m b/mex_files_multem/mex_scherzer_aperture.m old mode 100644 new mode 100755 index 3fc73ed6..4c44f2ac --- a/mex_files_multem/mex_scherzer_aperture.m +++ b/mex_files_multem/mex_scherzer_aperture.m @@ -1,4 +1,3 @@ -clc; clear all; -addpath( '../matlab_functions') - +clc; clear; + ilm_mex('release', 'ilc_scherzer_aperture.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_scherzer_defocus.m b/mex_files_multem/mex_scherzer_defocus.m old mode 100644 new mode 100755 index f78c2218..4ae5c686 --- a/mex_files_multem/mex_scherzer_defocus.m +++ b/mex_files_multem/mex_scherzer_defocus.m @@ -1,4 +1,3 @@ -clc; clear all; -addpath( '../matlab_functions') - +clc; clear; + ilm_mex('release', 'ilc_scherzer_defocus.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_sigma.m b/mex_files_multem/mex_sigma.m old mode 100644 new mode 100755 index e85afa81..6d1ecb5b --- a/mex_files_multem/mex_sigma.m +++ b/mex_files_multem/mex_sigma.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_sigma.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_spec_planes.m b/mex_files_multem/mex_spec_planes.m old mode 100644 new mode 100755 index 4b7775c1..333defd5 --- a/mex_files_multem/mex_spec_planes.m +++ b/mex_files_multem/mex_spec_planes.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_spec_planes.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_spec_rot.m b/mex_files_multem/mex_spec_rot.m old mode 100644 new mode 100755 index 87fc370a..554e0dcd --- a/mex_files_multem/mex_spec_rot.m +++ b/mex_files_multem/mex_spec_rot.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_spec_rot.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_spec_slicing.m b/mex_files_multem/mex_spec_slicing.m old mode 100644 new mode 100755 index cdefdc14..cc6300a3 --- a/mex_files_multem/mex_spec_slicing.m +++ b/mex_files_multem/mex_spec_slicing.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_spec_slicing.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_transf_exp_factor.m b/mex_files_multem/mex_transf_exp_factor.m new file mode 100755 index 00000000..6a45f8b9 --- /dev/null +++ b/mex_files_multem/mex_transf_exp_factor.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_transf_exp_factor.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_transmission_function.m b/mex_files_multem/mex_transmission_function.m old mode 100644 new mode 100755 index c970a84c..a762b7bd --- a/mex_files_multem/mex_transmission_function.m +++ b/mex_files_multem/mex_transmission_function.m @@ -1,4 +1,3 @@ -clc; clear all; -addpath( '../matlab_functions') - +clc; clear; + ilm_mex('release', 'ilc_transmission_function.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_vp.m b/mex_files_multem/mex_vp.m deleted file mode 100644 index af035070..00000000 --- a/mex_files_multem/mex_vp.m +++ /dev/null @@ -1,4 +0,0 @@ -clc; clear all; -addpath( '../matlab_functions') - -ilm_mex('release', 'ilc_vp.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_vr.m b/mex_files_multem/mex_vr.m old mode 100644 new mode 100755 index 644c5c66..b91d6ba2 --- a/mex_files_multem/mex_vr.m +++ b/mex_files_multem/mex_vr.m @@ -1,4 +1,3 @@ -clc; clear all; -addpath( '../matlab_functions') - +clc; clear; + ilm_mex('release', 'ilc_vr.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_vz.m b/mex_files_multem/mex_vz.m old mode 100644 new mode 100755 index 485ab801..45a849de --- a/mex_files_multem/mex_vz.m +++ b/mex_files_multem/mex_vz.m @@ -1,4 +1,5 @@ -clc; clear all; -addpath( '../matlab_functions') - +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + ilm_mex('release', 'ilc_vz.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_vzp.m b/mex_files_multem/mex_vzp.m new file mode 100755 index 00000000..dda5fe49 --- /dev/null +++ b/mex_files_multem/mex_vzp.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_vzp.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_wave_function.m b/mex_files_multem/mex_wave_function.m old mode 100644 new mode 100755 index b0cd8d46..f6dcb109 --- a/mex_files_multem/mex_wave_function.m +++ b/mex_files_multem/mex_wave_function.m @@ -1,4 +1,3 @@ -clc; clear all; -addpath( '../matlab_functions') - +clc; clear; + ilm_mex('release', 'ilc_wave_function.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_xtl_build.m b/mex_files_multem/mex_xtl_build.m new file mode 100755 index 00000000..0264a12f --- /dev/null +++ b/mex_files_multem/mex_xtl_build.m @@ -0,0 +1,5 @@ +% Copyright 2021 Ivan Lobato +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_xtl_build.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_xtl_build_base.m b/mex_files_multem/mex_xtl_build_base.m new file mode 100755 index 00000000..92610cd0 --- /dev/null +++ b/mex_files_multem/mex_xtl_build_base.m @@ -0,0 +1,4 @@ +clc; clear; +addpath(['..', filesep, 'matlab_functions']) + +ilm_mex('release', 'ilc_xtl_build_base.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_xtl_csn_2_sgr.m b/mex_files_multem/mex_xtl_csn_2_sgr.m new file mode 100755 index 00000000..bf298d01 --- /dev/null +++ b/mex_files_multem/mex_xtl_csn_2_sgr.m @@ -0,0 +1,3 @@ +clc; clear; + +ilm_mex('release', 'ilc_xtl_csn_2_sgr.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_xtl_css_2_csn.m b/mex_files_multem/mex_xtl_css_2_csn.m new file mode 100755 index 00000000..a3713c7c --- /dev/null +++ b/mex_files_multem/mex_xtl_css_2_csn.m @@ -0,0 +1,3 @@ +clc; clear; + +ilm_mex('release', 'ilc_xtl_css_2_csn.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_xtl_css_2_sgr.m b/mex_files_multem/mex_xtl_css_2_sgr.m new file mode 100755 index 00000000..5afb9f3e --- /dev/null +++ b/mex_files_multem/mex_xtl_css_2_sgr.m @@ -0,0 +1,3 @@ +clc; clear; + +ilm_mex('release', 'ilc_xtl_css_2_sgr.cpp', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_xtl_sgn_2_csn.m b/mex_files_multem/mex_xtl_sgn_2_csn.m new file mode 100755 index 00000000..4f004ced --- /dev/null +++ b/mex_files_multem/mex_xtl_sgn_2_csn.m @@ -0,0 +1,3 @@ +clc; clear; + +ilm_mex('release', 'ilc_xtl_sgn_2_csn.cpp', '../src'); \ No newline at end of file diff --git a/src - Copy (2)/amorp_build.hpp b/src - Copy (2)/amorp_build.hpp new file mode 100755 index 00000000..6e0056cb --- /dev/null +++ b/src - Copy (2)/amorp_build.hpp @@ -0,0 +1,179 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef AMORPHOUS_BUILD_H + #define AMORPHOUS_BUILD_H + + #include "math.cuh" + #include "types.cuh" + #include "types_mt.cuh" + #include "particles.cuh" + #include "atomic_data_mt.cuh" + #include "cgpu_rand.cuh" + #include "box_occ.hpp" + + namespace mt + { + template + class Amorp_Build { + public: + Amorp_Build():n_trial(500), randu_3d() {} + + Ptc_Atom operator()(dt_int32 Z, T rms_3d, T occ, T d_min, T rho, dt_int32 seed, Spec_Lay_Info spec_lay_info) + { + // calculate number of atoms for the amorphous spec + const auto n_atoms_amorp = n_amorp_atoms(Z, rho, spec_lay_info.bs); + + Ptc_Atom atoms; + atoms.bs = spec_lay_info.bs; + atoms.cols_used = 7; + atoms.reserve(n_atoms_amorp); + + // set box occupancy input data + box_occ.set_in_data(d_min, spec_lay_info.bs, spec_lay_info.r_0); + + // set random input data + randu_3d.set_in_data(seed, spec_lay_info.bs, spec_lay_info.r_0); + + const dt_int32 tag = spec_lay_info.tag; + + dt_int32 iatom_c = 0; + for(dt_int32 iatom = 0; iatom < n_atoms_amorp; iatom++) + { + R_3d r; + if (rnd_point(atoms, r)) + { + const Ptc_s_Atom atom_ik(Z, r, rms_3d, occ, tag, c_dflt_charge); + + atoms.push_back(atom_ik); + + box_occ.set(r, iatom_c); + iatom_c++; + } + } + + atoms.shrink_to_fit(); + atoms.sort_by_z(); + + return atoms; + } + + void operator()(Ptc_Atom& atoms, dt_int32 Z, T rms_3d, T occ, T d_min, T rho, dt_int32 seed, Spec_Lay_Info spec_lay_info) + { + // calculate number of atoms for the amorphous spec + const auto n_atoms_amorp = n_amorp_atoms(Z, rho, spec_lay_info.bs); + + Ptc_Atom m_atoms; + m_atoms.bs = fmax(atoms.bs, spec_lay_info.bs); + m_atoms.cols_used = atoms.cols_used; + + // set box occupancy input data + box_occ.set_in_data(d_min, spec_lay_info.bs, spec_lay_info.r_0); + + // select atoms within the depth + const T depth = 0.1; // set depth + const T z_0 = spec_lay_info.r_0.z - depth; + const T z_e = spec_lay_info.z_e() + depth; + + m_atoms.reserve(atoms.size()); + + dt_int32 iatom_0 = 0; + for(auto iatom = 0; iatom < atoms.size(); iatom++) + { + if (fcn_chk_bound(atoms.z[iatom], z_0, z_e)) + { + const auto atom_ik = atoms.get(iatom); + m_atoms.push_back(atom_ik); + // set occupancy + box_occ.set(atom_ik.get_pos(), iatom_0); + iatom_0++; + } + } + const dt_int32 n_atoms = iatom_0 + n_atoms_amorp; + m_atoms.reserve(n_atoms); + atoms.reserve(atoms.size() + n_atoms_amorp); + + // set random input data + randu_3d.set_in_data(seed, spec_lay_info.bs, spec_lay_info.r_0); + + const dt_int32 tag = spec_lay_info.tag; + + dt_int32 iatom_c = iatom_0; + for(dt_int32 iatom = iatom_0; iatom < n_atoms; iatom++) + { + R_3d r; + if (rnd_point(m_atoms, r)) + { + const Ptc_s_Atom atom_ik(Z, r, rms_3d, occ, tag, c_dflt_charge); + + m_atoms.push_back(atom_ik); + atoms.push_back(atom_ik); + + box_occ.set(r, iatom_c); + iatom_c++; + } + } + m_atoms.clear(); + m_atoms.shrink_to_fit(); + + atoms.shrink_to_fit(); + atoms.sort_by_z(); + } + + private: + const dt_int32 n_trial; + + Randu_3d_cpu randu_3d; + + Box_Occ_3d box_occ; + + T vol(const R_3d& bs) const + { + return bs.x*bs.y*bs.z; + } + + T rho_n_A3(dt_int32 Z, T rho) const + { + Atomic_Info_cpu atomic_info = Atomic_Data(Z); + const T m = atomic_info.atomic_mass(); + + return rho*c_Na/(m*c_cm3_A3); + } + + dt_int32 n_amorp_atoms(dt_int32 Z, const T& rho, const R_3d& bs) const + { + return fcn_cceil(rho_n_A3(Z, rho)*vol(bs)); + } + + dt_bool rnd_point(const Ptc_Atom& atoms, R_3d& r_o) + { + for(auto itrial = 0; itrial < n_trial; itrial++) + { + const auto r = randu_3d(); + if (box_occ.check_r_min(atoms, r)) + { + r_o = r; + return true; + } + } + + return false; + } + }; + } +#endif \ No newline at end of file diff --git a/src/atomic_fcns_mt.hpp b/src - Copy (2)/atom_cal.hpp old mode 100644 new mode 100755 similarity index 98% rename from src/atomic_fcns_mt.hpp rename to src - Copy (2)/atom_cal.hpp index 33a82f78..06a782c9 --- a/src/atomic_fcns_mt.hpp +++ b/src - Copy (2)/atom_cal.hpp @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,8 +16,8 @@ * along with MULTEM. If not, see . */ -#ifndef ATOMIC_FCNS_MT_H -#define ATOMIC_FCNS_MT_H +#ifndef ATOM_CAL_H +#define ATOM_CAL_H #ifdef _MSC_VER #pragma once @@ -28,7 +28,7 @@ #include "math.cuh" #include "types.cuh" #include "quadrature.hpp" -#include "cgpu_fcns.cuh" +#include "host_device_functions.cuh" namespace mt { diff --git a/src/atomic_data_mt.hpp b/src - Copy (2)/atom_data.hpp old mode 100644 new mode 100755 similarity index 98% rename from src/atomic_data_mt.hpp rename to src - Copy (2)/atom_data.hpp index 8a5d1a6e..c6e05417 --- a/src/atomic_data_mt.hpp +++ b/src - Copy (2)/atom_data.hpp @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,8 +16,8 @@ * along with MULTEM. If not, see . */ -#ifndef ATOMIC_DATA_MT_H -#define ATOMIC_DATA_MT_H +#ifndef ATOM_DATA_H +#define ATOM_DATA_H #ifdef _MSC_VER #pragma once @@ -80,7 +80,7 @@ namespace mt for(int iatoms = 0; iatoms + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef ATOMIC_CROSS_SECTION_H +#define ATOMIC_CROSS_SECTION_H + +#include "math.cuh" +#include "types.cuh" +#include "traits.cuh" +#include "fft.cuh" +#include "input_multislice.cuh" +#include "output_multislice.hpp" +#include "multislice.cuh" +#include "cubic_spline.hpp" +#include "host_device_classes.cuh" +#include + +namespace mt +{ + template + class Atomic_Cross_Section{ + public: + using T_r = T; + using T_c = complex; + + Atomic_Cross_Section(): input_multislice(nullptr){} + + void set_input_data(Input_Multislice *input_multislice_i) + { + input_multislice = input_multislice_i; + } + + template + void get(TVector &r_o, TVector &fr_o) + { + /**************************multislice calculation*******************************/ + mt::Output_Multislice_Vector output_multislice; + output_multislice.set_input_data(input_multislice); + + mt::Multislice multislice; + multislice.set_input_data(input_multislice); + + multislice.run(output_multislice); + + multislice.cleanup(); + + /******************************* Cross section ********************************/ + mt::Grid_2d grid_2d; + grid_2d.assign(input_multislice->grid_2d); + + mt::Cubic_Spline spline; + auto sigma = input_multislice->atoms.sigma[0]; + + auto pr = &(output_multislice.scanning.r); + std::vector r2(pr->size()); + thrust::transform(pr->begin(), pr->end(), r2.begin(), [](T &x)->double{return x*x; }); + + auto pfr2 = &(output_multislice.image_tot[0].image[0]); + std::vector fr2(pr->size()); + fr2.assign(pfr2->begin(), pfr2->begin()+fr2.size()); + + mt::Vector, e_host> M(grid_2d.nxy()); + T x = 0.5*grid_2d.lx; + T y = 0.5*grid_2d.ly; + + // spline interpolation + spline.set_points(r2, fr2); + spline.eval_radial_function(grid_2d, x, y, M); + + // Convolution + mt::Stream stream(input_multislice->cpu_nthread); + mt::FFT fft_2d; + + mt::Gauss_Cv_2d gauss_cv_2d(&stream, &fft_2d, grid_2d); + gauss_cv_2d.set_fft_plan(); + gauss_cv_2d(sigma, M); + gauss_cv_2d.cleanup(); + + // extract radial values + std::vector r2_c(grid_2d.nyh); + std::vector fr_c(grid_2d.nyh); + int ix = grid_2d.nxh; + int ir = 0; + for(auto iy =grid_2d.nyh; iybegin(), pr->end()); + fr_o.assign(fr2.begin(), fr2.end()); + } + + private: + Input_Multislice *input_multislice; + }; + +} // namespace mt + +#endif \ No newline at end of file diff --git a/src - Copy (2)/atomic_data.hpp b/src - Copy (2)/atomic_data.hpp new file mode 100755 index 00000000..d9a1afde --- /dev/null +++ b/src - Copy (2)/atomic_data.hpp @@ -0,0 +1,1647 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef ATOMIC_DATA_H +#define ATOMIC_DATA_H + +#ifdef _MSC_VER +#pragma once +#endif // _MSC_VER + +#include +#include "math.cuh" +#include "types.cuh" +#include "atom_cal.hpp" + +namespace mt +{ + class Atomic_Data{ + public: + Atomic_Data(ePotential_Type PotPar_i = ePT_none) + { + init(); + + Load_Atomic_Data_names(); + Load_Atomic_Data(); + Load_eels_edges(); + + if(PotPar_i != ePT_none) + { + Load_Data(PotPar_i); + } + } + + // Load data tables and Parameterization + void Load_Data(ePotential_Type PotPar_i) + { + Load_Atomic_Data_names(); + Load_Atomic_Data(); + Load_eels_edges(); + + potential_type = PotPar_i; + switch(potential_type) + { + case ePT_Doyle_0_4: + Load_feg_Doyle_neutral_0_4(); + break; + case ePT_Peng_0_4: + Load_feg_Peng_neutral_0_4(); + break; + case ePT_Peng_0_12: + Load_feg_Peng_neutral_0_12(); + break; + case ePT_Kirkland_0_12: + Load_feg_Kirkland_neutral_0_12(); + break; + case ePT_Weickenmeier_0_12: + Load_feg_Weickenmeier_neutral_0_12(); + break; + case ePT_Lobato_0_12: + Load_feg_Lobato_neutral_0_12(); + break; + } + Load_feg_Peng_ion_0_4(); + } + + std::string Z_name(const int &Z) const + { + return (Z_bound(Z))? data_table[Z-1].name:""; + } + + Vector extract_major_edges(const int &Z) + { + Vector data; + data.reserve(5); + + auto &edges = data_table[Z-1].edges; + for(auto ik=0; ik<5; ik++) + { + if(nonZero(edges[ik])) + { + data.push_back(edges[ik]); + } + } + data.shrink_to_fit(); + + return data; + } + + Vector extract_minor_edges(const int &Z) + { + Vector data; + data.reserve(7); + + auto &edges = data_table[Z-1].edges; + for(auto ik=5; ik<12; ik++) + { + if(nonZero(edges[ik])) + { + data.push_back(edges[ik]); + } + } + data.shrink_to_fit(); + + return data; + } + + bool Z_bound(const int &Z) const + { + return (Z >= 1) && (Z <= c_nAtomsTypes); + } + + int mass_number(const int &Z) const + { + return (Z_bound(Z))? data_table[Z-1].A:0; + } + + double atomic_mass(const int &Z) const + { + return (Z_bound(Z))?data_table[Z-1].m:0; + } + + double nuclear_radius(const int &Z) const + { + return (Z_bound(Z))?data_table[Z-1].rn:0; + } + + double atomic_radius(const int &Z) const + { + return (Z_bound(Z))?data_table[Z-1].ra:0; + } + + template + void To_atom_type_CPU(int Z_i, double Vrl_i, int nR_i, double R_min_i, TAtom_Type &atom_type) + { + using value_type = Value_type; + + int iZ = Z_i - 1; + c_atom_type.Z = Z_i; + c_atom_type.A = data_table[iZ].A; + c_atom_type.m = data_table[iZ].m; + c_atom_type.rn_e = data_table[iZ].rn*1e-05; + c_atom_type.rn_c = (1.2e-05)*pow(static_cast(data_table[iZ].A), 1.0/3.0); + c_atom_type.ra_e = data_table[iZ].ra; + c_atom_type.ra_c = 0.0; + + R_min_i = ::fmax(c_atom_type.rn_c, R_min_i); + get_atom_coef(Z_i, Vrl_i, nR_i, R_min_i, c_atom_type); + + // ra_c and R_max + int charge = 0; + c_atom_cal.Set_Atom_Type(potential_type, charge, &c_atom_type); + c_atom_type.ra_c = 3.0*c_atom_cal.AtomicRadius_rms(3); + + if(isZero(c_atom_type.ra_c)) + { + c_atom_type.ra_c = 1.75*c_atom_type.ra_e; + } + + atom_type.assign(c_atom_type); + } + + private: + struct Data_Table + { + std::string name; + int Z; // atomic number + double m; // atomic mass + int A; // mass number + double rn; // nuclear radius + double ra; // atomic radius + Vector, e_host> feg; + Vector edges; + }; + + // initialization + void init() + { + potential_type = ePT_Lobato_0_12; + c_feg.resize(c_nAtomsIons); + c_fxg.resize(c_nAtomsIons); + c_Pr.resize(c_nAtomsIons); + c_Vr.resize(c_nAtomsIons); + c_VR.resize(c_nAtomsIons); + for(auto j = 0; j < c_feg.size(); j++) + { + c_feg[j].resize(6); + c_fxg[j].resize(6); + c_Pr[j].resize(6); + c_Vr[j].resize(6); + c_VR[j].resize(6); + } + + data_table.resize(c_nAtomsTypes); + for(auto i = 0; i < data_table.size(); i++) + { + data_table[i].edges.resize(12); + + data_table[i].feg.resize(c_nAtomsIons); // -7:1:7 + for(auto j = 0; j < data_table[i].feg.size(); j++) + { + data_table[i].feg[j].resize(6, 0); + } + } + } + + // load names + void Load_Atomic_Data_names() + { + data_table[0].name = "H"; + data_table[1].name = "He"; + data_table[2].name = "Li"; + data_table[3].name = "Be"; + data_table[4].name = "B"; + data_table[5].name = "C"; + data_table[6].name = "N"; + data_table[7].name = "O"; + data_table[8].name = "F"; + data_table[9].name = "Ne"; + data_table[10].name = "Na"; + data_table[11].name = "Mg"; + data_table[12].name = "Al"; + data_table[13].name = "Si"; + data_table[14].name = "P"; + data_table[15].name = "S"; + data_table[16].name = "Cl"; + data_table[17].name = "Ar"; + data_table[18].name = "K"; + data_table[19].name = "Ca"; + data_table[20].name = "Sc"; + data_table[21].name = "Ti"; + data_table[22].name = "V"; + data_table[23].name = "Cr"; + data_table[24].name = "Mn"; + data_table[25].name = "Fe"; + data_table[26].name = "Co"; + data_table[27].name = "Ni"; + data_table[28].name = "Cu"; + data_table[29].name = "Zn"; + data_table[30].name = "Ga"; + data_table[31].name = "Ge"; + data_table[32].name = "As"; + data_table[33].name = "Se"; + data_table[34].name = "Br"; + data_table[35].name = "Kr"; + data_table[36].name = "Rb"; + data_table[37].name = "Sr"; + data_table[38].name = "Y"; + data_table[39].name = "Zr"; + data_table[40].name = "Nb"; + data_table[41].name = "Mo"; + data_table[42].name = "Tc"; + data_table[43].name = "Ru"; + data_table[44].name = "Rh"; + data_table[45].name = "Pd"; + data_table[46].name = "Ag"; + data_table[47].name = "Cd"; + data_table[48].name = "In"; + data_table[49].name = "Sn"; + data_table[50].name = "Sb"; + data_table[51].name = "Te"; + data_table[52].name = "I"; + data_table[53].name = "Xe"; + data_table[54].name = "Cs"; + data_table[55].name = "Ba"; + data_table[56].name = "La"; + data_table[57].name = "Ce"; + data_table[58].name = "Pr"; + data_table[59].name = "Nd"; + data_table[60].name = "Pm"; + data_table[61].name = "Sm"; + data_table[62].name = "Eu"; + data_table[63].name = "Gd"; + data_table[64].name = "Tb"; + data_table[65].name = "Dy"; + data_table[66].name = "Ho"; + data_table[67].name = "Er"; + data_table[68].name = "Tm"; + data_table[69].name = "Yb"; + data_table[70].name = "Lu"; + data_table[71].name = "Hf"; + data_table[72].name = "Ta"; + data_table[73].name = "W"; + data_table[74].name = "Re"; + data_table[75].name = "Os"; + data_table[76].name = "Ir"; + data_table[77].name = "Pt"; + data_table[78].name = "Au"; + data_table[79].name = "Hg"; + data_table[80].name = "Tl"; + data_table[81].name = "Pb"; + data_table[82].name = "Bi"; + data_table[83].name = "Po"; + data_table[84].name = "At"; + data_table[85].name = "Rn"; + data_table[86].name = "Fr"; + data_table[87].name = "Ra"; + data_table[88].name = "Ac"; + data_table[89].name = "Th"; + data_table[90].name = "Pa"; + data_table[91].name = "U"; + data_table[92].name = "Np"; + data_table[93].name = "Pu"; + data_table[94].name = "Am"; + data_table[95].name = "Cm"; + data_table[96].name = "Bk"; + data_table[97].name = "Cf"; + } + + // Load atomic data tables + void Load_Atomic_Data() + { + data_table[0].Z = 1; data_table[0].A = 1; data_table[0].m = 1.00797; data_table[0].rn = 0.8777; data_table[0].ra = 0.79; + data_table[1].Z = 2; data_table[1].A = 4; data_table[1].m = 4.0026; data_table[1].rn = 1.6753; data_table[1].ra = 0.49; + data_table[2].Z = 3; data_table[2].A = 7; data_table[2].m = 6.941; data_table[2].rn = 2.4173; data_table[2].ra = 2.05; + data_table[3].Z = 4; data_table[3].A = 9; data_table[3].m = 9.01218; data_table[3].rn = 2.518; data_table[3].ra = 1.4; + data_table[4].Z = 5; data_table[4].A = 11; data_table[4].m = 10.811; data_table[4].rn = 2.406; data_table[4].ra = 1.17; + data_table[5].Z = 6; data_table[5].A = 12; data_table[5].m = 12.011; data_table[5].rn = 2.4702; data_table[5].ra = 0.91; + data_table[6].Z = 7; data_table[6].A = 14; data_table[6].m = 14.0067; data_table[6].rn = 2.5582; data_table[6].ra = 0.75; + data_table[7].Z = 8; data_table[7].A = 16; data_table[7].m = 15.9994; data_table[7].rn = 2.6991; data_table[7].ra = 0.65; + data_table[8].Z = 9; data_table[8].A = 19; data_table[8].m = 18.9984; data_table[8].rn = 2.8976; data_table[8].ra = 0.57; + data_table[9].Z = 10; data_table[9].A = 20; data_table[9].m = 20.1797; data_table[9].rn = 3.0058; data_table[9].ra = 0.51; + data_table[10].Z = 11; data_table[10].A = 23; data_table[10].m = 22.98977; data_table[10].rn = 2.9935; data_table[10].ra = 2.23; + data_table[11].Z = 12; data_table[11].A = 24; data_table[11].m = 24.305; data_table[11].rn = 3.057; data_table[11].ra = 1.72; + data_table[12].Z = 13; data_table[12].A = 27; data_table[12].m = 26.98154; data_table[12].rn = 3.061; data_table[12].ra = 1.62; + data_table[13].Z = 14; data_table[13].A = 28; data_table[13].m = 28.0855; data_table[13].rn = 3.1224; data_table[13].ra = 1.44; + data_table[14].Z = 15; data_table[14].A = 31; data_table[14].m = 30.97376; data_table[14].rn = 3.1889; data_table[14].ra = 1.23; + data_table[15].Z = 16; data_table[15].A = 32; data_table[15].m = 32.066; data_table[15].rn = 3.2847; data_table[15].ra = 1.09; + data_table[16].Z = 17; data_table[16].A = 35; data_table[16].m = 35.4527; data_table[16].rn = 3.3654; data_table[16].ra = 0.97; + data_table[17].Z = 18; data_table[17].A = 40; data_table[17].m = 39.948; data_table[17].rn = 3.4276; data_table[17].ra = 0.88; + data_table[18].Z = 19; data_table[18].A = 39; data_table[18].m = 39.0983; data_table[18].rn = 3.435; data_table[18].ra = 2.77; + data_table[19].Z = 20; data_table[19].A = 40; data_table[19].m = 40.078; data_table[19].rn = 3.4777; data_table[19].ra = 2.23; + data_table[20].Z = 21; data_table[20].A = 45; data_table[20].m = 44.9559; data_table[20].rn = 3.546; data_table[20].ra = 2.09; + data_table[21].Z = 22; data_table[21].A = 48; data_table[21].m = 47.88; data_table[21].rn = 3.5922; data_table[21].ra = 2; + data_table[22].Z = 23; data_table[22].A = 51; data_table[22].m = 50.9415; data_table[22].rn = 3.6002; data_table[22].ra = 1.92; + data_table[23].Z = 24; data_table[23].A = 52; data_table[23].m = 51.996; data_table[23].rn = 3.6452; data_table[23].ra = 1.85; + data_table[24].Z = 25; data_table[24].A = 55; data_table[24].m = 54.938; data_table[24].rn = 3.7057; data_table[24].ra = 1.79; + data_table[25].Z = 26; data_table[25].A = 56; data_table[25].m = 55.847; data_table[25].rn = 3.7384; data_table[25].ra = 1.72; + data_table[26].Z = 27; data_table[26].A = 59; data_table[26].m = 58.9332; data_table[26].rn = 3.7875; data_table[26].ra = 1.67; + data_table[27].Z = 28; data_table[27].A = 58; data_table[27].m = 58.6934; data_table[27].rn = 3.7757; data_table[27].ra = 1.62; + data_table[28].Z = 29; data_table[28].A = 63; data_table[28].m = 63.456; data_table[28].rn = 3.8823; data_table[28].ra = 1.57; + data_table[29].Z = 30; data_table[29].A = 64; data_table[29].m = 65.39; data_table[29].rn = 3.9279; data_table[29].ra = 1.53; + data_table[30].Z = 31; data_table[30].A = 69; data_table[30].m = 69.723; data_table[30].rn = 3.9973; data_table[30].ra = 1.81; + data_table[31].Z = 32; data_table[31].A = 74; data_table[31].m = 72.61; data_table[31].rn = 4.0742; data_table[31].ra = 1.52; + data_table[32].Z = 33; data_table[32].A = 75; data_table[32].m = 74.9216; data_table[32].rn = 4.0968; data_table[32].ra = 1.33; + data_table[33].Z = 34; data_table[33].A = 80; data_table[33].m = 78.96; data_table[33].rn = 4.14; data_table[33].ra = 1.22; + data_table[34].Z = 35; data_table[34].A = 79; data_table[34].m = 79.904; data_table[34].rn = 4.1629; data_table[34].ra = 1.12; + data_table[35].Z = 36; data_table[35].A = 84; data_table[35].m = 83.8; data_table[35].rn = 4.1883; data_table[35].ra = 1.03; + data_table[36].Z = 37; data_table[36].A = 85; data_table[36].m = 85.4678; data_table[36].rn = 4.2037; data_table[36].ra = 2.98; + data_table[37].Z = 38; data_table[37].A = 88; data_table[37].m = 87.62; data_table[37].rn = 4.2246; data_table[37].ra = 2.45; + data_table[38].Z = 39; data_table[38].A = 89; data_table[38].m = 88.9059; data_table[38].rn = 4.2438; data_table[38].ra = 2.27; + data_table[39].Z = 40; data_table[39].A = 90; data_table[39].m = 91.224; data_table[39].rn = 4.269; data_table[39].ra = 2.16; + data_table[40].Z = 41; data_table[40].A = 93; data_table[40].m = 92.9064; data_table[40].rn = 4.324; data_table[40].ra = 2.08; + data_table[41].Z = 42; data_table[41].A = 98; data_table[41].m = 95.94; data_table[41].rn = 4.409; data_table[41].ra = 2.01; + data_table[42].Z = 43; data_table[42].A = 98; data_table[42].m = 98; data_table[42].rn = 4.413; data_table[42].ra = 1.95; + data_table[43].Z = 44; data_table[43].A = 102; data_table[43].m = 101.07; data_table[43].rn = 4.4811; data_table[43].ra = 1.89; + data_table[44].Z = 45; data_table[44].A = 103; data_table[44].m = 102.9055; data_table[44].rn = 4.4945; data_table[44].ra = 1.83; + data_table[45].Z = 46; data_table[45].A = 106; data_table[45].m = 106.42; data_table[45].rn = 4.5324; data_table[45].ra = 1.79; + data_table[46].Z = 47; data_table[46].A = 107; data_table[46].m = 107.868; data_table[46].rn = 4.5464; data_table[46].ra = 1.75; + data_table[47].Z = 48; data_table[47].A = 114; data_table[47].m = 112.41; data_table[47].rn = 4.6068; data_table[47].ra = 1.71; + data_table[48].Z = 49; data_table[48].A = 115; data_table[48].m = 114.82; data_table[48].rn = 4.6155; data_table[48].ra = 2; + data_table[49].Z = 50; data_table[49].A = 120; data_table[49].m = 118.71; data_table[49].rn = 4.6525; data_table[49].ra = 1.72; + data_table[50].Z = 51; data_table[50].A = 121; data_table[50].m = 121.757; data_table[50].rn = 4.6802; data_table[50].ra = 1.53; + data_table[51].Z = 52; data_table[51].A = 130; data_table[51].m = 127.6; data_table[51].rn = 4.742; data_table[51].ra = 1.42; + data_table[52].Z = 53; data_table[52].A = 127; data_table[52].m = 126.9045; data_table[52].rn = 4.75; data_table[52].ra = 1.32; + data_table[53].Z = 54; data_table[53].A = 132; data_table[53].m = 131.29; data_table[53].rn = 4.785; data_table[53].ra = 1.24; + data_table[54].Z = 55; data_table[54].A = 133; data_table[54].m = 132.9054; data_table[54].rn = 4.804; data_table[54].ra = 3.34; + data_table[55].Z = 56; data_table[55].A = 138; data_table[55].m = 137.33; data_table[55].rn = 4.837; data_table[55].ra = 2.76; + data_table[56].Z = 57; data_table[56].A = 139; data_table[56].m = 138.9055; data_table[56].rn = 4.8549; data_table[56].ra = 2.74; + data_table[57].Z = 58; data_table[57].A = 140; data_table[57].m = 140.12; data_table[57].rn = 4.8773; data_table[57].ra = 2.7; + data_table[58].Z = 59; data_table[58].A = 141; data_table[58].m = 140.9077; data_table[58].rn = 4.8919; data_table[58].ra = 2.67; + data_table[59].Z = 60; data_table[59].A = 142; data_table[59].m = 144.24; data_table[59].rn = 4.9115; data_table[59].ra = 2.64; + data_table[60].Z = 61; data_table[60].A = 145; data_table[60].m = 145; data_table[60].rn = 4.953; data_table[60].ra = 2.62; + data_table[61].Z = 62; data_table[61].A = 152; data_table[61].m = 150.36; data_table[61].rn = 5.0823; data_table[61].ra = 2.59; + data_table[62].Z = 63; data_table[62].A = 153; data_table[62].m = 151.965; data_table[62].rn = 5.1093; data_table[62].ra = 2.56; + data_table[63].Z = 64; data_table[63].A = 158; data_table[63].m = 157.25; data_table[63].rn = 5.1578; data_table[63].ra = 2.54; + data_table[64].Z = 65; data_table[64].A = 159; data_table[64].m = 158.9253; data_table[64].rn = 5.06; data_table[64].ra = 2.51; + data_table[65].Z = 66; data_table[65].A = 164; data_table[65].m = 162.5; data_table[65].rn = 5.224; data_table[65].ra = 2.49; + data_table[66].Z = 67; data_table[66].A = 165; data_table[66].m = 164.9303; data_table[66].rn = 5.2022; data_table[66].ra = 2.47; + data_table[67].Z = 68; data_table[67].A = 166; data_table[67].m = 167.26; data_table[67].rn = 5.2527; data_table[67].ra = 2.45; + data_table[68].Z = 69; data_table[68].A = 169; data_table[68].m = 168.9342; data_table[68].rn = 5.2256; data_table[68].ra = 2.42; + data_table[69].Z = 70; data_table[69].A = 174; data_table[69].m = 173.04; data_table[69].rn = 5.3105; data_table[69].ra = 2.4; + data_table[70].Z = 71; data_table[70].A = 175; data_table[70].m = 174.967; data_table[70].rn = 5.37; data_table[70].ra = 2.25; + data_table[71].Z = 72; data_table[71].A = 180; data_table[71].m = 178.49; data_table[71].rn = 5.3482; data_table[71].ra = 2.16; + data_table[72].Z = 73; data_table[72].A = 181; data_table[72].m = 180.9479; data_table[72].rn = 5.3507; data_table[72].ra = 2.09; + data_table[73].Z = 74; data_table[73].A = 184; data_table[73].m = 183.85; data_table[73].rn = 5.3646; data_table[73].ra = 2.02; + data_table[74].Z = 75; data_table[74].A = 187; data_table[74].m = 186.207; data_table[74].rn = 5.3697; data_table[74].ra = 1.97; + data_table[75].Z = 76; data_table[75].A = 192; data_table[75].m = 190.2; data_table[75].rn = 5.4122; data_table[75].ra = 1.92; + data_table[76].Z = 77; data_table[76].A = 193; data_table[76].m = 192.22; data_table[76].rn = 5.402; data_table[76].ra = 1.87; + data_table[77].Z = 78; data_table[77].A = 195; data_table[77].m = 195.08; data_table[77].rn = 5.425; data_table[77].ra = 1.83; + data_table[78].Z = 79; data_table[78].A = 197; data_table[78].m = 196.9665; data_table[78].rn = 5.4379; data_table[78].ra = 1.79; + data_table[79].Z = 80; data_table[79].A = 202; data_table[79].m = 200.59; data_table[79].rn = 5.4637; data_table[79].ra = 1.76; + data_table[80].Z = 81; data_table[80].A = 205; data_table[80].m = 204.383; data_table[80].rn = 5.4757; data_table[80].ra = 2.08; + data_table[81].Z = 82; data_table[81].A = 208; data_table[81].m = 207.2; data_table[81].rn = 5.501; data_table[81].ra = 1.81; + data_table[82].Z = 83; data_table[82].A = 209; data_table[82].m = 208.9804; data_table[82].rn = 5.521; data_table[82].ra = 1.63; + data_table[83].Z = 84; data_table[83].A = 209; data_table[83].m = 209; data_table[83].rn = 5.5262; data_table[83].ra = 1.53; + data_table[84].Z = 85; data_table[84].A = 210; data_table[84].m = 210; data_table[84].rn = 5.531; data_table[84].ra = 1.43; + data_table[85].Z = 86; data_table[85].A = 222; data_table[85].m = 222; data_table[85].rn = 5.6547; data_table[85].ra = 1.34; + data_table[86].Z = 87; data_table[86].A = 223; data_table[86].m = 223; data_table[86].rn = 5.6584; data_table[86].ra = 2.7; + data_table[87].Z = 88; data_table[87].A = 226; data_table[87].m = 226.0254; data_table[87].rn = 5.684; data_table[87].ra = 2.23; + data_table[88].Z = 89; data_table[88].A = 227; data_table[88].m = 227; data_table[88].rn = 5.712; data_table[88].ra = 1.88; + data_table[89].Z = 90; data_table[89].A = 232; data_table[89].m = 232.0381; data_table[89].rn = 5.78; data_table[89].ra = 1.8; + data_table[90].Z = 91; data_table[90].A = 231; data_table[90].m = 231.0359; data_table[90].rn = 5.766; data_table[90].ra = 1.61; + data_table[91].Z = 92; data_table[91].A = 238; data_table[91].m = 238.029; data_table[91].rn = 5.8571; data_table[91].ra = 1.38; + data_table[92].Z = 93; data_table[92].A = 237; data_table[92].m = 237.0482; data_table[92].rn = 5.841; data_table[92].ra = 1.3; + data_table[93].Z = 94; data_table[93].A = 244; data_table[93].m = 244; data_table[93].rn = 5.8948; data_table[93].ra = 1.51; + data_table[94].Z = 95; data_table[94].A = 243; data_table[94].m = 243; data_table[94].rn = 5.9042; data_table[94].ra = 1.84; + data_table[95].Z = 96; data_table[95].A = 247; data_table[95].m = 247; data_table[95].rn = 5.963; data_table[95].ra = 1.84; + data_table[96].Z = 97; data_table[96].A = 247; data_table[96].m = 247; data_table[96].rn = 5.93; data_table[96].ra = 1.84; + data_table[97].Z = 98; data_table[97].A = 251; data_table[97].m = 251; data_table[97].rn = 6.02; data_table[97].ra = 1.84; + data_table[98].Z = 99; data_table[98].A = 252; data_table[98].m = 252; data_table[98].rn = 6.034; data_table[98].ra = 1.84; + data_table[99].Z = 100; data_table[99].A = 257; data_table[99].m = 257; data_table[99].rn = 6.107; data_table[99].ra = 1.84; + data_table[100].Z = 101; data_table[100].A = 258; data_table[100].m = 258; data_table[100].rn = 6.122; data_table[100].ra = 1.84; + data_table[101].Z = 102; data_table[101].A = 259; data_table[101].m = 259; data_table[101].rn = 6.137; data_table[101].ra = 1.84; + data_table[102].Z = 103; data_table[102].A = 262; data_table[102].m = 260; data_table[102].rn = 6.182; data_table[102].ra = 1.84; + } + + // Load eels edges + void Load_eels_edges() + { + data_table[0].edges[0] = 13.00; data_table[0].edges[1] = 0.00; data_table[0].edges[2] = 0.00; data_table[0].edges[3] = 0.00; data_table[0].edges[4] = 0.00; data_table[0].edges[5] = 0.00; data_table[0].edges[6] = 0.00; data_table[0].edges[7] = 0.00; data_table[0].edges[8] = 0.00; data_table[0].edges[9] = 0.00; data_table[0].edges[10] = 0.00; data_table[0].edges[11] = 0.00; + data_table[1].edges[0] = 22.00; data_table[1].edges[1] = 0.00; data_table[1].edges[2] = 0.00; data_table[1].edges[3] = 0.00; data_table[1].edges[4] = 0.00; data_table[1].edges[5] = 0.00; data_table[1].edges[6] = 0.00; data_table[1].edges[7] = 0.00; data_table[1].edges[8] = 0.00; data_table[1].edges[9] = 0.00; data_table[1].edges[10] = 0.00; data_table[1].edges[11] = 0.00; + data_table[2].edges[0] = 55.00; data_table[2].edges[1] = 0.00; data_table[2].edges[2] = 0.00; data_table[2].edges[3] = 0.00; data_table[2].edges[4] = 0.00; data_table[2].edges[5] = 0.00; data_table[2].edges[6] = 0.00; data_table[2].edges[7] = 0.00; data_table[2].edges[8] = 0.00; data_table[2].edges[9] = 0.00; data_table[2].edges[10] = 0.00; data_table[2].edges[11] = 0.00; + data_table[3].edges[0] = 111.00; data_table[3].edges[1] = 0.00; data_table[3].edges[2] = 0.00; data_table[3].edges[3] = 0.00; data_table[3].edges[4] = 0.00; data_table[3].edges[5] = 0.00; data_table[3].edges[6] = 0.00; data_table[3].edges[7] = 0.00; data_table[3].edges[8] = 0.00; data_table[3].edges[9] = 0.00; data_table[3].edges[10] = 0.00; data_table[3].edges[11] = 0.00; + data_table[4].edges[0] = 188.00; data_table[4].edges[1] = 0.00; data_table[4].edges[2] = 0.00; data_table[4].edges[3] = 0.00; data_table[4].edges[4] = 0.00; data_table[4].edges[5] = 0.00; data_table[4].edges[6] = 0.00; data_table[4].edges[7] = 0.00; data_table[4].edges[8] = 0.00; data_table[4].edges[9] = 0.00; data_table[4].edges[10] = 0.00; data_table[4].edges[11] = 0.00; + data_table[5].edges[0] = 284.00; data_table[5].edges[1] = 0.00; data_table[5].edges[2] = 0.00; data_table[5].edges[3] = 0.00; data_table[5].edges[4] = 0.00; data_table[5].edges[5] = 0.00; data_table[5].edges[6] = 0.00; data_table[5].edges[7] = 0.00; data_table[5].edges[8] = 0.00; data_table[5].edges[9] = 0.00; data_table[5].edges[10] = 0.00; data_table[5].edges[11] = 0.00; + data_table[6].edges[0] = 401.00; data_table[6].edges[1] = 0.00; data_table[6].edges[2] = 0.00; data_table[6].edges[3] = 0.00; data_table[6].edges[4] = 0.00; data_table[6].edges[5] = 0.00; data_table[6].edges[6] = 0.00; data_table[6].edges[7] = 0.00; data_table[6].edges[8] = 0.00; data_table[6].edges[9] = 0.00; data_table[6].edges[10] = 0.00; data_table[6].edges[11] = 0.00; + data_table[7].edges[0] = 532.00; data_table[7].edges[1] = 0.00; data_table[7].edges[2] = 0.00; data_table[7].edges[3] = 0.00; data_table[7].edges[4] = 0.00; data_table[7].edges[5] = 0.00; data_table[7].edges[6] = 0.00; data_table[7].edges[7] = 0.00; data_table[7].edges[8] = 0.00; data_table[7].edges[9] = 0.00; data_table[7].edges[10] = 0.00; data_table[7].edges[11] = 0.00; + data_table[8].edges[0] = 685.00; data_table[8].edges[1] = 0.00; data_table[8].edges[2] = 0.00; data_table[8].edges[3] = 0.00; data_table[8].edges[4] = 0.00; data_table[8].edges[5] = 0.00; data_table[8].edges[6] = 0.00; data_table[8].edges[7] = 0.00; data_table[8].edges[8] = 0.00; data_table[8].edges[9] = 0.00; data_table[8].edges[10] = 0.00; data_table[8].edges[11] = 0.00; + data_table[9].edges[0] = 867.00; data_table[9].edges[1] = 18.00; data_table[9].edges[2] = 0.00; data_table[9].edges[3] = 0.00; data_table[9].edges[4] = 0.00; data_table[9].edges[5] = 45.00; data_table[9].edges[6] = 0.00; data_table[9].edges[7] = 0.00; data_table[9].edges[8] = 0.00; data_table[9].edges[9] = 0.00; data_table[9].edges[10] = 0.00; data_table[9].edges[11] = 0.00; + data_table[10].edges[0] = 1072.00; data_table[10].edges[1] = 31.00; data_table[10].edges[2] = 0.00; data_table[10].edges[3] = 0.00; data_table[10].edges[4] = 0.00; data_table[10].edges[5] = 63.00; data_table[10].edges[6] = 0.00; data_table[10].edges[7] = 0.00; data_table[10].edges[8] = 0.00; data_table[10].edges[9] = 0.00; data_table[10].edges[10] = 0.00; data_table[10].edges[11] = 0.00; + data_table[11].edges[0] = 1305.00; data_table[11].edges[1] = 51.00; data_table[11].edges[2] = 0.00; data_table[11].edges[3] = 0.00; data_table[11].edges[4] = 0.00; data_table[11].edges[5] = 89.00; data_table[11].edges[6] = 0.00; data_table[11].edges[7] = 0.00; data_table[11].edges[8] = 0.00; data_table[11].edges[9] = 0.00; data_table[11].edges[10] = 0.00; data_table[11].edges[11] = 0.00; + data_table[12].edges[0] = 1560.00; data_table[12].edges[1] = 73.00; data_table[12].edges[2] = 0.00; data_table[12].edges[3] = 0.00; data_table[12].edges[4] = 0.00; data_table[12].edges[5] = 118.00; data_table[12].edges[6] = 0.00; data_table[12].edges[7] = 0.00; data_table[12].edges[8] = 0.00; data_table[12].edges[9] = 0.00; data_table[12].edges[10] = 0.00; data_table[12].edges[11] = 0.00; + data_table[13].edges[0] = 1839.00; data_table[13].edges[1] = 99.00; data_table[13].edges[2] = 0.00; data_table[13].edges[3] = 0.00; data_table[13].edges[4] = 0.00; data_table[13].edges[5] = 149.00; data_table[13].edges[6] = 0.00; data_table[13].edges[7] = 0.00; data_table[13].edges[8] = 0.00; data_table[13].edges[9] = 0.00; data_table[13].edges[10] = 0.00; data_table[13].edges[11] = 0.00; + data_table[14].edges[0] = 2146.00; data_table[14].edges[1] = 132.00; data_table[14].edges[2] = 0.00; data_table[14].edges[3] = 0.00; data_table[14].edges[4] = 0.00; data_table[14].edges[5] = 189.00; data_table[14].edges[6] = 0.00; data_table[14].edges[7] = 0.00; data_table[14].edges[8] = 0.00; data_table[14].edges[9] = 0.00; data_table[14].edges[10] = 0.00; data_table[14].edges[11] = 0.00; + data_table[15].edges[0] = 2472.00; data_table[15].edges[1] = 165.00; data_table[15].edges[2] = 0.00; data_table[15].edges[3] = 0.00; data_table[15].edges[4] = 0.00; data_table[15].edges[5] = 229.00; data_table[15].edges[6] = 0.00; data_table[15].edges[7] = 0.00; data_table[15].edges[8] = 0.00; data_table[15].edges[9] = 0.00; data_table[15].edges[10] = 0.00; data_table[15].edges[11] = 0.00; + data_table[16].edges[0] = 2822.00; data_table[16].edges[1] = 200.00; data_table[16].edges[2] = 0.00; data_table[16].edges[3] = 0.00; data_table[16].edges[4] = 0.00; data_table[16].edges[5] = 270.00; data_table[16].edges[6] = 0.00; data_table[16].edges[7] = 0.00; data_table[16].edges[8] = 0.00; data_table[16].edges[9] = 0.00; data_table[16].edges[10] = 0.00; data_table[16].edges[11] = 0.00; + data_table[17].edges[0] = 3203.00; data_table[17].edges[1] = 245.00; data_table[17].edges[2] = 12.00; data_table[17].edges[3] = 0.00; data_table[17].edges[4] = 0.00; data_table[17].edges[5] = 320.00; data_table[17].edges[6] = 25.00; data_table[17].edges[7] = 0.00; data_table[17].edges[8] = 0.00; data_table[17].edges[9] = 0.00; data_table[17].edges[10] = 0.00; data_table[17].edges[11] = 0.00; + data_table[18].edges[0] = 3607.00; data_table[18].edges[1] = 296.00; data_table[18].edges[2] = 294.00; data_table[18].edges[3] = 18.00; data_table[18].edges[4] = 0.00; data_table[18].edges[5] = 377.00; data_table[18].edges[6] = 34.00; data_table[18].edges[7] = 0.00; data_table[18].edges[8] = 0.00; data_table[18].edges[9] = 0.00; data_table[18].edges[10] = 0.00; data_table[18].edges[11] = 0.00; + data_table[19].edges[0] = 4038.00; data_table[19].edges[1] = 350.00; data_table[19].edges[2] = 346.00; data_table[19].edges[3] = 25.00; data_table[19].edges[4] = 0.00; data_table[19].edges[5] = 438.00; data_table[19].edges[6] = 44.00; data_table[19].edges[7] = 0.00; data_table[19].edges[8] = 0.00; data_table[19].edges[9] = 0.00; data_table[19].edges[10] = 0.00; data_table[19].edges[11] = 0.00; + data_table[20].edges[0] = 4493.00; data_table[20].edges[1] = 407.00; data_table[20].edges[2] = 402.00; data_table[20].edges[3] = 32.00; data_table[20].edges[4] = 0.00; data_table[20].edges[5] = 500.00; data_table[20].edges[6] = 54.00; data_table[20].edges[7] = 0.00; data_table[20].edges[8] = 0.00; data_table[20].edges[9] = 0.00; data_table[20].edges[10] = 0.00; data_table[20].edges[11] = 0.00; + data_table[21].edges[0] = 4966.00; data_table[21].edges[1] = 462.00; data_table[21].edges[2] = 456.00; data_table[21].edges[3] = 35.00; data_table[21].edges[4] = 0.00; data_table[21].edges[5] = 564.00; data_table[21].edges[6] = 60.00; data_table[21].edges[7] = 0.00; data_table[21].edges[8] = 0.00; data_table[21].edges[9] = 0.00; data_table[21].edges[10] = 0.00; data_table[21].edges[11] = 0.00; + data_table[22].edges[0] = 521.00; data_table[22].edges[1] = 513.00; data_table[22].edges[2] = 38.00; data_table[22].edges[3] = 0.00; data_table[22].edges[4] = 0.00; data_table[22].edges[5] = 628.00; data_table[22].edges[6] = 66.00; data_table[22].edges[7] = 0.00; data_table[22].edges[8] = 0.00; data_table[22].edges[9] = 0.00; data_table[22].edges[10] = 0.00; data_table[22].edges[11] = 0.00; + data_table[23].edges[0] = 584.00; data_table[23].edges[1] = 575.00; data_table[23].edges[2] = 42.00; data_table[23].edges[3] = 0.00; data_table[23].edges[4] = 0.00; data_table[23].edges[5] = 695.00; data_table[23].edges[6] = 74.00; data_table[23].edges[7] = 0.00; data_table[23].edges[8] = 0.00; data_table[23].edges[9] = 0.00; data_table[23].edges[10] = 0.00; data_table[23].edges[11] = 0.00; + data_table[24].edges[0] = 651.00; data_table[24].edges[1] = 640.00; data_table[24].edges[2] = 49.00; data_table[24].edges[3] = 0.00; data_table[24].edges[4] = 0.00; data_table[24].edges[5] = 769.00; data_table[24].edges[6] = 84.00; data_table[24].edges[7] = 0.00; data_table[24].edges[8] = 0.00; data_table[24].edges[9] = 0.00; data_table[24].edges[10] = 0.00; data_table[24].edges[11] = 0.00; + data_table[25].edges[0] = 721.00; data_table[25].edges[1] = 708.00; data_table[25].edges[2] = 54.00; data_table[25].edges[3] = 0.00; data_table[25].edges[4] = 0.00; data_table[25].edges[5] = 846.00; data_table[25].edges[6] = 93.00; data_table[25].edges[7] = 0.00; data_table[25].edges[8] = 0.00; data_table[25].edges[9] = 0.00; data_table[25].edges[10] = 0.00; data_table[25].edges[11] = 0.00; + data_table[26].edges[0] = 794.00; data_table[26].edges[1] = 779.00; data_table[26].edges[2] = 60.00; data_table[26].edges[3] = 0.00; data_table[26].edges[4] = 0.00; data_table[26].edges[5] = 926.00; data_table[26].edges[6] = 101.00; data_table[26].edges[7] = 0.00; data_table[26].edges[8] = 0.00; data_table[26].edges[9] = 0.00; data_table[26].edges[10] = 0.00; data_table[26].edges[11] = 0.00; + data_table[27].edges[0] = 872.00; data_table[27].edges[1] = 855.00; data_table[27].edges[2] = 68.00; data_table[27].edges[3] = 0.00; data_table[27].edges[4] = 0.00; data_table[27].edges[5] = 1008.00; data_table[27].edges[6] = 112.00; data_table[27].edges[7] = 0.00; data_table[27].edges[8] = 0.00; data_table[27].edges[9] = 0.00; data_table[27].edges[10] = 0.00; data_table[27].edges[11] = 0.00; + data_table[28].edges[0] = 951.00; data_table[28].edges[1] = 931.00; data_table[28].edges[2] = 74.00; data_table[28].edges[3] = 0.00; data_table[28].edges[4] = 0.00; data_table[28].edges[5] = 1096.00; data_table[28].edges[6] = 120.00; data_table[28].edges[7] = 0.00; data_table[28].edges[8] = 0.00; data_table[28].edges[9] = 0.00; data_table[28].edges[10] = 0.00; data_table[28].edges[11] = 0.00; + data_table[29].edges[0] = 1043.00; data_table[29].edges[1] = 1020.00; data_table[29].edges[2] = 0.00; data_table[29].edges[3] = 0.00; data_table[29].edges[4] = 0.00; data_table[29].edges[5] = 1194.00; data_table[29].edges[6] = 136.00; data_table[29].edges[7] = 87.00; data_table[29].edges[8] = 0.00; data_table[29].edges[9] = 0.00; data_table[29].edges[10] = 0.00; data_table[29].edges[11] = 0.00; + data_table[30].edges[0] = 1142.00; data_table[30].edges[1] = 1115.00; data_table[30].edges[2] = 0.00; data_table[30].edges[3] = 0.00; data_table[30].edges[4] = 0.00; data_table[30].edges[5] = 1298.00; data_table[30].edges[6] = 158.00; data_table[30].edges[7] = 103.00; data_table[30].edges[8] = 0.00; data_table[30].edges[9] = 0.00; data_table[30].edges[10] = 0.00; data_table[30].edges[11] = 0.00; + data_table[31].edges[0] = 1248.00; data_table[31].edges[1] = 1217.00; data_table[31].edges[2] = 29.00; data_table[31].edges[3] = 0.00; data_table[31].edges[4] = 0.00; data_table[31].edges[5] = 1414.00; data_table[31].edges[6] = 180.00; data_table[31].edges[7] = 121.00; data_table[31].edges[8] = 0.00; data_table[31].edges[9] = 0.00; data_table[31].edges[10] = 0.00; data_table[31].edges[11] = 0.00; + data_table[32].edges[0] = 1359.00; data_table[32].edges[1] = 1323.00; data_table[32].edges[2] = 41.00; data_table[32].edges[3] = 0.00; data_table[32].edges[4] = 0.00; data_table[32].edges[5] = 1526.00; data_table[32].edges[6] = 203.00; data_table[32].edges[7] = 140.00; data_table[32].edges[8] = 0.00; data_table[32].edges[9] = 0.00; data_table[32].edges[10] = 0.00; data_table[32].edges[11] = 0.00; + data_table[33].edges[0] = 1476.00; data_table[33].edges[1] = 1436.00; data_table[33].edges[2] = 57.00; data_table[33].edges[3] = 0.00; data_table[33].edges[4] = 0.00; data_table[33].edges[5] = 1654.00; data_table[33].edges[6] = 231.00; data_table[33].edges[7] = 162.00; data_table[33].edges[8] = 0.00; data_table[33].edges[9] = 0.00; data_table[33].edges[10] = 0.00; data_table[33].edges[11] = 0.00; + data_table[34].edges[0] = 1596.00; data_table[34].edges[1] = 1150.00; data_table[34].edges[2] = 69.00; data_table[34].edges[3] = 0.00; data_table[34].edges[4] = 0.00; data_table[34].edges[5] = 1782.00; data_table[34].edges[6] = 256.00; data_table[34].edges[7] = 181.00; data_table[34].edges[8] = 0.00; data_table[34].edges[9] = 0.00; data_table[34].edges[10] = 0.00; data_table[34].edges[11] = 0.00; + data_table[35].edges[0] = 1727.00; data_table[35].edges[1] = 1675.00; data_table[35].edges[2] = 89.00; data_table[35].edges[3] = 11.00; data_table[35].edges[4] = 0.00; data_table[35].edges[5] = 1921.00; data_table[35].edges[6] = 289.00; data_table[35].edges[7] = 214.00; data_table[35].edges[8] = 24.00; data_table[35].edges[9] = 0.00; data_table[35].edges[10] = 0.00; data_table[35].edges[11] = 0.00; + data_table[36].edges[0] = 1864.00; data_table[36].edges[1] = 1804.00; data_table[36].edges[2] = 110.00; data_table[36].edges[3] = 14.00; data_table[36].edges[4] = 0.00; data_table[36].edges[5] = 2065.00; data_table[36].edges[6] = 322.00; data_table[36].edges[7] = 247.00; data_table[36].edges[8] = 238.00; data_table[36].edges[9] = 29.00; data_table[36].edges[10] = 0.00; data_table[36].edges[11] = 0.00; + data_table[37].edges[0] = 2007.00; data_table[37].edges[1] = 1940.00; data_table[37].edges[2] = 133.00; data_table[37].edges[3] = 20.00; data_table[37].edges[4] = 0.00; data_table[37].edges[5] = 2216.00; data_table[37].edges[6] = 357.00; data_table[37].edges[7] = 280.00; data_table[37].edges[8] = 269.00; data_table[37].edges[9] = 38.00; data_table[37].edges[10] = 0.00; data_table[37].edges[11] = 0.00; + data_table[38].edges[0] = 2155.00; data_table[38].edges[1] = 2080.00; data_table[38].edges[2] = 157.00; data_table[38].edges[3] = 26.00; data_table[38].edges[4] = 0.00; data_table[38].edges[5] = 2372.00; data_table[38].edges[6] = 394.00; data_table[38].edges[7] = 312.00; data_table[38].edges[8] = 300.00; data_table[38].edges[9] = 45.00; data_table[38].edges[10] = 0.00; data_table[38].edges[11] = 0.00; + data_table[39].edges[0] = 2307.00; data_table[39].edges[1] = 2222.00; data_table[39].edges[2] = 180.00; data_table[39].edges[3] = 29.00; data_table[39].edges[4] = 0.00; data_table[39].edges[5] = 2532.00; data_table[39].edges[6] = 430.00; data_table[39].edges[7] = 344.00; data_table[39].edges[8] = 330.00; data_table[39].edges[9] = 51.00; data_table[39].edges[10] = 0.00; data_table[39].edges[11] = 0.00; + data_table[40].edges[0] = 2465.00; data_table[40].edges[1] = 2371.00; data_table[40].edges[2] = 205.00; data_table[40].edges[3] = 34.00; data_table[40].edges[4] = 0.00; data_table[40].edges[5] = 2698.00; data_table[40].edges[6] = 468.00; data_table[40].edges[7] = 378.00; data_table[40].edges[8] = 363.00; data_table[40].edges[9] = 58.00; data_table[40].edges[10] = 0.00; data_table[40].edges[11] = 0.00; + data_table[41].edges[0] = 2625.00; data_table[41].edges[1] = 2520.00; data_table[41].edges[2] = 227.00; data_table[41].edges[3] = 35.00; data_table[41].edges[4] = 0.00; data_table[41].edges[5] = 2865.00; data_table[41].edges[6] = 505.00; data_table[41].edges[7] = 410.00; data_table[41].edges[8] = 392.00; data_table[41].edges[9] = 62.00; data_table[41].edges[10] = 0.00; data_table[41].edges[11] = 0.00; + data_table[42].edges[0] = 2793.00; data_table[42].edges[1] = 2677.00; data_table[42].edges[2] = 253.00; data_table[42].edges[3] = 39.00; data_table[42].edges[4] = 0.00; data_table[42].edges[5] = 3042.00; data_table[42].edges[6] = 544.00; data_table[42].edges[7] = 445.00; data_table[42].edges[8] = 425.00; data_table[42].edges[9] = 68.00; data_table[42].edges[10] = 0.00; data_table[42].edges[11] = 0.00; + data_table[43].edges[0] = 2967.00; data_table[43].edges[1] = 2838.00; data_table[43].edges[2] = 279.00; data_table[43].edges[3] = 43.00; data_table[43].edges[4] = 0.00; data_table[43].edges[5] = 3224.00; data_table[43].edges[6] = 585.00; data_table[43].edges[7] = 483.00; data_table[43].edges[8] = 461.00; data_table[43].edges[9] = 75.00; data_table[43].edges[10] = 0.00; data_table[43].edges[11] = 0.00; + data_table[44].edges[0] = 3146.00; data_table[44].edges[1] = 3004.00; data_table[44].edges[2] = 307.00; data_table[44].edges[3] = 48.00; data_table[44].edges[4] = 0.00; data_table[44].edges[5] = 3412.00; data_table[44].edges[6] = 627.00; data_table[44].edges[7] = 521.00; data_table[44].edges[8] = 496.00; data_table[44].edges[9] = 81.00; data_table[44].edges[10] = 0.00; data_table[44].edges[11] = 0.00; + data_table[45].edges[0] = 3330.00; data_table[45].edges[1] = 3173.00; data_table[45].edges[2] = 335.00; data_table[45].edges[3] = 51.00; data_table[45].edges[4] = 0.00; data_table[45].edges[5] = 3604.00; data_table[45].edges[6] = 670.00; data_table[45].edges[7] = 559.00; data_table[45].edges[8] = 531.00; data_table[45].edges[9] = 86.00; data_table[45].edges[10] = 0.00; data_table[45].edges[11] = 0.00; + data_table[46].edges[0] = 3524.00; data_table[46].edges[1] = 3351.00; data_table[46].edges[2] = 367.00; data_table[46].edges[3] = 0.00; data_table[46].edges[4] = 0.00; data_table[46].edges[5] = 3806.00; data_table[46].edges[6] = 717.00; data_table[46].edges[7] = 602.00; data_table[46].edges[8] = 571.00; data_table[46].edges[9] = 95.00; data_table[46].edges[10] = 56.00; data_table[46].edges[11] = 0.00; + data_table[47].edges[0] = 3727.00; data_table[47].edges[1] = 3538.00; data_table[47].edges[2] = 404.00; data_table[47].edges[3] = 0.00; data_table[47].edges[4] = 0.00; data_table[47].edges[5] = 4018.00; data_table[47].edges[6] = 770.00; data_table[47].edges[7] = 651.00; data_table[47].edges[8] = 616.00; data_table[47].edges[9] = 108.00; data_table[47].edges[10] = 67.00; data_table[47].edges[11] = 0.00; + data_table[48].edges[0] = 3938.00; data_table[48].edges[1] = 3730.00; data_table[48].edges[2] = 443.00; data_table[48].edges[3] = 0.00; data_table[48].edges[4] = 0.00; data_table[48].edges[5] = 4237.00; data_table[48].edges[6] = 826.00; data_table[48].edges[7] = 702.00; data_table[48].edges[8] = 664.00; data_table[48].edges[9] = 122.00; data_table[48].edges[10] = 77.00; data_table[48].edges[11] = 0.00; + data_table[49].edges[0] = 4156.00; data_table[49].edges[1] = 3929.00; data_table[49].edges[2] = 485.00; data_table[49].edges[3] = 24.00; data_table[49].edges[4] = 0.00; data_table[49].edges[5] = 4465.00; data_table[49].edges[6] = 884.00; data_table[49].edges[7] = 756.00; data_table[49].edges[8] = 714.00; data_table[49].edges[9] = 136.00; data_table[49].edges[10] = 89.00; data_table[49].edges[11] = 0.00; + data_table[50].edges[0] = 4380.00; data_table[50].edges[1] = 4132.00; data_table[50].edges[2] = 528.00; data_table[50].edges[3] = 31.00; data_table[50].edges[4] = 0.00; data_table[50].edges[5] = 944.00; data_table[50].edges[6] = 812.00; data_table[50].edges[7] = 766.00; data_table[50].edges[8] = 152.00; data_table[50].edges[9] = 98.00; data_table[50].edges[10] = 0.00; data_table[50].edges[11] = 0.00; + data_table[51].edges[0] = 4612.00; data_table[51].edges[1] = 4341.00; data_table[51].edges[2] = 40.00; data_table[51].edges[3] = 572.00; data_table[51].edges[4] = 0.00; data_table[51].edges[5] = 1006.00; data_table[51].edges[6] = 870.00; data_table[51].edges[7] = 819.00; data_table[51].edges[8] = 168.00; data_table[51].edges[9] = 110.00; data_table[51].edges[10] = 0.00; data_table[51].edges[11] = 0.00; + data_table[52].edges[0] = 4852.00; data_table[52].edges[1] = 4557.00; data_table[52].edges[2] = 619.00; data_table[52].edges[3] = 50.00; data_table[52].edges[4] = 0.00; data_table[52].edges[5] = 1072.00; data_table[52].edges[6] = 930.00; data_table[52].edges[7] = 875.00; data_table[52].edges[8] = 186.00; data_table[52].edges[9] = 123.00; data_table[52].edges[10] = 0.00; data_table[52].edges[11] = 0.00; + data_table[53].edges[0] = 4782.00; data_table[53].edges[1] = 672.00; data_table[53].edges[2] = 63.00; data_table[53].edges[3] = 0.00; data_table[53].edges[4] = 0.00; data_table[53].edges[5] = 1145.00; data_table[53].edges[6] = 999.00; data_table[53].edges[7] = 937.00; data_table[53].edges[8] = 208.00; data_table[53].edges[9] = 147.00; data_table[53].edges[10] = 0.00; data_table[53].edges[11] = 0.00; + data_table[54].edges[0] = 740.00; data_table[54].edges[1] = 726.00; data_table[54].edges[2] = 76.00; data_table[54].edges[3] = 0.00; data_table[54].edges[4] = 0.00; data_table[54].edges[5] = 1217.00; data_table[54].edges[6] = 1065.00; data_table[54].edges[7] = 998.00; data_table[54].edges[8] = 231.00; data_table[54].edges[9] = 162.00; data_table[54].edges[10] = 0.00; data_table[54].edges[11] = 0.00; + data_table[55].edges[0] = 796.00; data_table[55].edges[1] = 781.00; data_table[55].edges[2] = 90.00; data_table[55].edges[3] = 15.00; data_table[55].edges[4] = 0.00; data_table[55].edges[5] = 1293.00; data_table[55].edges[6] = 1137.00; data_table[55].edges[7] = 1062.00; data_table[55].edges[8] = 253.00; data_table[55].edges[9] = 180.00; data_table[55].edges[10] = 0.00; data_table[55].edges[11] = 0.00; + data_table[56].edges[0] = 849.00; data_table[56].edges[1] = 832.00; data_table[56].edges[2] = 99.00; data_table[56].edges[3] = 14.00; data_table[56].edges[4] = 0.00; data_table[56].edges[5] = 1361.00; data_table[56].edges[6] = 1204.00; data_table[56].edges[7] = 1123.00; data_table[56].edges[8] = 270.00; data_table[56].edges[9] = 191.00; data_table[56].edges[10] = 0.00; data_table[56].edges[11] = 0.00; + data_table[57].edges[0] = 901.00; data_table[57].edges[1] = 883.00; data_table[57].edges[2] = 110.00; data_table[57].edges[3] = 20.00; data_table[57].edges[4] = 0.00; data_table[57].edges[5] = 1435.00; data_table[57].edges[6] = 1273.00; data_table[57].edges[7] = 1185.00; data_table[57].edges[8] = 290.00; data_table[57].edges[9] = 207.00; data_table[57].edges[10] = 0.00; data_table[57].edges[11] = 0.00; + data_table[58].edges[0] = 951.00; data_table[58].edges[1] = 931.00; data_table[58].edges[2] = 113.00; data_table[58].edges[3] = 22.00; data_table[58].edges[4] = 0.00; data_table[58].edges[5] = 1511.00; data_table[58].edges[6] = 1337.00; data_table[58].edges[7] = 1242.00; data_table[58].edges[8] = 305.00; data_table[58].edges[9] = 218.00; data_table[58].edges[10] = 0.00; data_table[58].edges[11] = 0.00; + data_table[59].edges[0] = 1000.00; data_table[59].edges[1] = 978.00; data_table[59].edges[2] = 118.00; data_table[59].edges[3] = 21.00; data_table[59].edges[4] = 0.00; data_table[59].edges[5] = 1575.00; data_table[59].edges[6] = 1403.00; data_table[59].edges[7] = 1297.00; data_table[59].edges[8] = 315.00; data_table[59].edges[9] = 225.00; data_table[59].edges[10] = 0.00; data_table[59].edges[11] = 0.00; + data_table[60].edges[0] = 1052.00; data_table[60].edges[1] = 1027.00; data_table[60].edges[2] = 120.00; data_table[60].edges[3] = 24.00; data_table[60].edges[4] = 0.00; data_table[60].edges[5] = 1649.00; data_table[60].edges[6] = 1471.00; data_table[60].edges[7] = 1357.00; data_table[60].edges[8] = 331.00; data_table[60].edges[9] = 236.00; data_table[60].edges[10] = 0.00; data_table[60].edges[11] = 0.00; + data_table[61].edges[0] = 1106.00; data_table[61].edges[1] = 1080.00; data_table[61].edges[2] = 129.00; data_table[61].edges[3] = 21.00; data_table[61].edges[4] = 0.00; data_table[61].edges[5] = 1723.00; data_table[61].edges[6] = 1541.00; data_table[61].edges[7] = 1420.00; data_table[61].edges[8] = 346.00; data_table[61].edges[9] = 247.00; data_table[61].edges[10] = 0.00; data_table[61].edges[11] = 0.00; + data_table[62].edges[0] = 1161.00; data_table[62].edges[1] = 1131.00; data_table[62].edges[2] = 133.00; data_table[62].edges[3] = 22.00; data_table[62].edges[4] = 0.00; data_table[62].edges[5] = 1800.00; data_table[62].edges[6] = 1614.00; data_table[62].edges[7] = 1481.00; data_table[62].edges[8] = 360.00; data_table[62].edges[9] = 257.00; data_table[62].edges[10] = 0.00; data_table[62].edges[11] = 0.00; + data_table[63].edges[0] = 1217.00; data_table[63].edges[1] = 1185.00; data_table[63].edges[2] = 140.00; data_table[63].edges[3] = 20.00; data_table[63].edges[4] = 0.00; data_table[63].edges[5] = 1881.00; data_table[63].edges[6] = 1688.00; data_table[63].edges[7] = 1544.00; data_table[63].edges[8] = 376.00; data_table[63].edges[9] = 271.00; data_table[63].edges[10] = 0.00; data_table[63].edges[11] = 0.00; + data_table[64].edges[0] = 1275.00; data_table[64].edges[1] = 1241.00; data_table[64].edges[2] = 147.00; data_table[64].edges[3] = 25.00; data_table[64].edges[4] = 0.00; data_table[64].edges[5] = 1967.00; data_table[64].edges[6] = 1768.00; data_table[64].edges[7] = 1611.00; data_table[64].edges[8] = 398.00; data_table[64].edges[9] = 285.00; data_table[64].edges[10] = 0.00; data_table[64].edges[11] = 0.00; + data_table[65].edges[0] = 1332.00; data_table[65].edges[1] = 1295.00; data_table[65].edges[2] = 154.00; data_table[65].edges[3] = 26.00; data_table[65].edges[4] = 0.00; data_table[65].edges[5] = 2047.00; data_table[65].edges[6] = 1842.00; data_table[65].edges[7] = 1676.00; data_table[65].edges[8] = 416.00; data_table[65].edges[9] = 293.00; data_table[65].edges[10] = 0.00; data_table[65].edges[11] = 0.00; + data_table[66].edges[0] = 1391.00; data_table[66].edges[1] = 1351.00; data_table[66].edges[2] = 161.00; data_table[66].edges[3] = 20.00; data_table[66].edges[4] = 0.00; data_table[66].edges[5] = 2128.00; data_table[66].edges[6] = 1923.00; data_table[66].edges[7] = 1741.00; data_table[66].edges[8] = 436.00; data_table[66].edges[9] = 307.00; data_table[66].edges[10] = 51.00; data_table[66].edges[11] = 0.00; + data_table[67].edges[0] = 1453.00; data_table[67].edges[1] = 1409.00; data_table[67].edges[2] = 168.00; data_table[67].edges[3] = 29.00; data_table[67].edges[4] = 0.00; data_table[67].edges[5] = 2206.00; data_table[67].edges[6] = 2006.00; data_table[67].edges[7] = 1812.00; data_table[67].edges[8] = 449.00; data_table[67].edges[9] = 320.00; data_table[67].edges[10] = 60.00; data_table[67].edges[11] = 0.00; + data_table[68].edges[0] = 1515.00; data_table[68].edges[1] = 1468.00; data_table[68].edges[2] = 180.00; data_table[68].edges[3] = 32.00; data_table[68].edges[4] = 0.00; data_table[68].edges[5] = 2307.00; data_table[68].edges[6] = 2090.00; data_table[68].edges[7] = 1884.00; data_table[68].edges[8] = 472.00; data_table[68].edges[9] = 337.00; data_table[68].edges[10] = 53.00; data_table[68].edges[11] = 0.00; + data_table[69].edges[0] = 1576.00; data_table[69].edges[1] = 1528.00; data_table[69].edges[2] = 185.00; data_table[69].edges[3] = 24.00; data_table[69].edges[4] = 0.00; data_table[69].edges[5] = 2398.00; data_table[69].edges[6] = 2173.00; data_table[69].edges[7] = 1950.00; data_table[69].edges[8] = 487.00; data_table[69].edges[9] = 343.00; data_table[69].edges[10] = 54.00; data_table[69].edges[11] = 0.00; + data_table[70].edges[0] = 1639.00; data_table[70].edges[1] = 1588.00; data_table[70].edges[2] = 195.00; data_table[70].edges[3] = 28.00; data_table[70].edges[4] = 0.00; data_table[70].edges[5] = 2491.00; data_table[70].edges[6] = 2263.00; data_table[70].edges[7] = 2024.00; data_table[70].edges[8] = 506.00; data_table[70].edges[9] = 359.00; data_table[70].edges[10] = 57.00; data_table[70].edges[11] = 0.00; + data_table[71].edges[0] = 1716.00; data_table[71].edges[1] = 1662.00; data_table[71].edges[2] = 31.00; data_table[71].edges[3] = 0.00; data_table[71].edges[4] = 0.00; data_table[71].edges[5] = 2601.00; data_table[71].edges[6] = 2365.00; data_table[71].edges[7] = 2108.00; data_table[71].edges[8] = 538.00; data_table[71].edges[9] = 380.00; data_table[71].edges[10] = 214.00; data_table[71].edges[11] = 65.00; + data_table[72].edges[0] = 1793.00; data_table[72].edges[1] = 1735.00; data_table[72].edges[2] = 36.00; data_table[72].edges[3] = 0.00; data_table[72].edges[4] = 0.00; data_table[72].edges[5] = 2708.00; data_table[72].edges[6] = 2469.00; data_table[72].edges[7] = 2194.00; data_table[72].edges[8] = 565.00; data_table[72].edges[9] = 404.00; data_table[72].edges[10] = 229.00; data_table[72].edges[11] = 71.00; + data_table[73].edges[0] = 1872.00; data_table[73].edges[1] = 1809.00; data_table[73].edges[2] = 36.00; data_table[73].edges[3] = 0.00; data_table[73].edges[4] = 0.00; data_table[73].edges[5] = 2820.00; data_table[73].edges[6] = 2575.00; data_table[73].edges[7] = 2281.00; data_table[73].edges[8] = 595.00; data_table[73].edges[9] = 425.00; data_table[73].edges[10] = 245.00; data_table[73].edges[11] = 77.00; + data_table[74].edges[0] = 1949.00; data_table[74].edges[1] = 1883.00; data_table[74].edges[2] = 35.00; data_table[74].edges[3] = 0.00; data_table[74].edges[4] = 0.00; data_table[74].edges[5] = 2932.00; data_table[74].edges[6] = 2682.00; data_table[74].edges[7] = 2367.00; data_table[74].edges[8] = 625.00; data_table[74].edges[9] = 444.00; data_table[74].edges[10] = 260.00; data_table[74].edges[11] = 83.00; + data_table[75].edges[0] = 2031.00; data_table[75].edges[1] = 1960.00; data_table[75].edges[2] = 45.00; data_table[75].edges[3] = 0.00; data_table[75].edges[4] = 0.00; data_table[75].edges[5] = 2792.00; data_table[75].edges[6] = 2457.00; data_table[75].edges[7] = 654.00; data_table[75].edges[8] = 468.00; data_table[75].edges[9] = 273.00; data_table[75].edges[10] = 46.00; data_table[75].edges[11] = 84.00; + data_table[76].edges[0] = 2116.00; data_table[76].edges[1] = 2040.00; data_table[76].edges[2] = 50.00; data_table[76].edges[3] = 0.00; data_table[76].edges[4] = 0.00; data_table[76].edges[5] = 2909.00; data_table[76].edges[6] = 2551.00; data_table[76].edges[7] = 690.00; data_table[76].edges[8] = 494.00; data_table[76].edges[9] = 295.00; data_table[76].edges[10] = 60.00; data_table[76].edges[11] = 95.00; + data_table[77].edges[0] = 2202.00; data_table[77].edges[1] = 2122.00; data_table[77].edges[2] = 52.00; data_table[77].edges[3] = 0.00; data_table[77].edges[4] = 0.00; data_table[77].edges[5] = 3026.00; data_table[77].edges[6] = 2645.00; data_table[77].edges[7] = 722.00; data_table[77].edges[8] = 519.00; data_table[77].edges[9] = 313.00; data_table[77].edges[10] = 102.00; data_table[77].edges[11] = 71.00; + data_table[78].edges[0] = 2291.00; data_table[78].edges[1] = 2206.00; data_table[78].edges[2] = 54.00; data_table[78].edges[3] = 0.00; data_table[78].edges[4] = 0.00; data_table[78].edges[5] = 3148.00; data_table[78].edges[6] = 2743.00; data_table[78].edges[7] = 759.00; data_table[78].edges[8] = 545.00; data_table[78].edges[9] = 334.00; data_table[78].edges[10] = 108.00; data_table[78].edges[11] = 83.00; + data_table[79].edges[0] = 2385.00; data_table[79].edges[1] = 2295.00; data_table[79].edges[2] = 58.00; data_table[79].edges[3] = 0.00; data_table[79].edges[4] = 0.00; data_table[79].edges[5] = 3278.00; data_table[79].edges[6] = 2847.00; data_table[79].edges[7] = 800.00; data_table[79].edges[8] = 571.00; data_table[79].edges[9] = 360.00; data_table[79].edges[10] = 120.00; data_table[79].edges[11] = 98.00; + data_table[80].edges[0] = 2485.00; data_table[80].edges[1] = 2389.00; data_table[80].edges[2] = 75.00; data_table[80].edges[3] = 0.00; data_table[80].edges[4] = 0.00; data_table[80].edges[5] = 3416.00; data_table[80].edges[6] = 2957.00; data_table[80].edges[7] = 845.00; data_table[80].edges[8] = 609.00; data_table[80].edges[9] = 386.00; data_table[80].edges[10] = 136.00; data_table[80].edges[11] = 118.00; + data_table[81].edges[0] = 2586.00; data_table[81].edges[1] = 2484.00; data_table[81].edges[2] = 86.00; data_table[81].edges[3] = 19.00; data_table[81].edges[4] = 0.00; data_table[81].edges[5] = 3554.00; data_table[81].edges[6] = 3066.00; data_table[81].edges[7] = 894.00; data_table[81].edges[8] = 644.00; data_table[81].edges[9] = 413.00; data_table[81].edges[10] = 147.00; data_table[81].edges[11] = 138.00; + data_table[82].edges[0] = 2688.00; data_table[82].edges[1] = 2580.00; data_table[82].edges[2] = 93.00; data_table[82].edges[3] = 24.00; data_table[82].edges[4] = 0.00; data_table[82].edges[5] = 3696.00; data_table[82].edges[6] = 3177.00; data_table[82].edges[7] = 938.00; data_table[82].edges[8] = 679.00; data_table[82].edges[9] = 440.00; data_table[82].edges[10] = 159.00; data_table[82].edges[11] = 157.00; + data_table[83].edges[0] = 3491.00; data_table[83].edges[1] = 3332.00; data_table[83].edges[2] = 0.00; data_table[83].edges[3] = 0.00; data_table[83].edges[4] = 0.00; data_table[83].edges[5] = 4046.00; data_table[83].edges[6] = 0.00; data_table[83].edges[7] = 0.00; data_table[83].edges[8] = 0.00; data_table[83].edges[9] = 0.00; data_table[83].edges[10] = 0.00; data_table[83].edges[11] = 0.00; + data_table[84].edges[0] = 0.00; data_table[84].edges[1] = 0.00; data_table[84].edges[2] = 0.00; data_table[84].edges[3] = 0.00; data_table[84].edges[4] = 0.00; data_table[84].edges[5] = 0.00; data_table[84].edges[6] = 0.00; data_table[84].edges[7] = 0.00; data_table[84].edges[8] = 0.00; data_table[84].edges[9] = 0.00; data_table[84].edges[10] = 0.00; data_table[84].edges[11] = 0.00; + data_table[85].edges[0] = 0.00; data_table[85].edges[1] = 0.00; data_table[85].edges[2] = 0.00; data_table[85].edges[3] = 0.00; data_table[85].edges[4] = 0.00; data_table[85].edges[5] = 0.00; data_table[85].edges[6] = 0.00; data_table[85].edges[7] = 0.00; data_table[85].edges[8] = 0.00; data_table[85].edges[9] = 0.00; data_table[85].edges[10] = 0.00; data_table[85].edges[11] = 0.00; + data_table[86].edges[0] = 0.00; data_table[86].edges[1] = 0.00; data_table[86].edges[2] = 0.00; data_table[86].edges[3] = 0.00; data_table[86].edges[4] = 0.00; data_table[86].edges[5] = 0.00; data_table[86].edges[6] = 0.00; data_table[86].edges[7] = 0.00; data_table[86].edges[8] = 0.00; data_table[86].edges[9] = 0.00; data_table[86].edges[10] = 0.00; data_table[86].edges[11] = 0.00; + data_table[87].edges[0] = 0.00; data_table[87].edges[1] = 0.00; data_table[87].edges[2] = 0.00; data_table[87].edges[3] = 0.00; data_table[87].edges[4] = 0.00; data_table[87].edges[5] = 0.00; data_table[87].edges[6] = 0.00; data_table[87].edges[7] = 0.00; data_table[87].edges[8] = 0.00; data_table[87].edges[9] = 0.00; data_table[87].edges[10] = 0.00; data_table[87].edges[11] = 0.00; + data_table[88].edges[0] = 0.00; data_table[88].edges[1] = 0.00; data_table[88].edges[2] = 0.00; data_table[88].edges[3] = 0.00; data_table[88].edges[4] = 0.00; data_table[88].edges[5] = 0.00; data_table[88].edges[6] = 0.00; data_table[88].edges[7] = 0.00; data_table[88].edges[8] = 0.00; data_table[88].edges[9] = 0.00; data_table[88].edges[10] = 0.00; data_table[88].edges[11] = 0.00; + data_table[89].edges[0] = 3491.00; data_table[89].edges[1] = 3332.00; data_table[89].edges[2] = 344.00; data_table[89].edges[3] = 335.00; data_table[89].edges[4] = 88.00; data_table[89].edges[5] = 4046.00; data_table[89].edges[6] = 1329.00; data_table[89].edges[7] = 967.00; data_table[89].edges[8] = 714.00; data_table[89].edges[9] = 676.00; data_table[89].edges[10] = 290.00; data_table[89].edges[11] = 182.00; + data_table[90].edges[0] = 0.00; data_table[90].edges[1] = 0.00; data_table[90].edges[2] = 0.00; data_table[90].edges[3] = 0.00; data_table[90].edges[4] = 0.00; data_table[90].edges[5] = 0.00; data_table[90].edges[6] = 0.00; data_table[90].edges[7] = 0.00; data_table[90].edges[8] = 0.00; data_table[90].edges[9] = 0.00; data_table[90].edges[10] = 0.00; data_table[90].edges[11] = 0.00; + data_table[91].edges[0] = 3728.00; data_table[91].edges[1] = 3552.00; data_table[91].edges[2] = 391.00; data_table[91].edges[3] = 381.00; data_table[91].edges[4] = 96.00; data_table[91].edges[5] = 4303.00; data_table[91].edges[6] = 1441.00; data_table[91].edges[7] = 1045.00; data_table[91].edges[8] = 780.00; data_table[91].edges[9] = 738.00; data_table[91].edges[10] = 324.00; data_table[91].edges[11] = 195.00; + data_table[92].edges[0] = 0.00; data_table[92].edges[1] = 0.00; data_table[92].edges[2] = 0.00; data_table[92].edges[3] = 0.00; data_table[92].edges[4] = 0.00; data_table[92].edges[5] = 0.00; data_table[92].edges[6] = 0.00; data_table[92].edges[7] = 0.00; data_table[92].edges[8] = 0.00; data_table[92].edges[9] = 0.00; data_table[92].edges[10] = 0.00; data_table[92].edges[11] = 0.00; + data_table[93].edges[0] = 0.00; data_table[93].edges[1] = 0.00; data_table[93].edges[2] = 0.00; data_table[93].edges[3] = 0.00; data_table[93].edges[4] = 0.00; data_table[93].edges[5] = 0.00; data_table[93].edges[6] = 0.00; data_table[93].edges[7] = 0.00; data_table[93].edges[8] = 0.00; data_table[93].edges[9] = 0.00; data_table[93].edges[10] = 0.00; data_table[93].edges[11] = 0.00; + data_table[94].edges[0] = 0.00; data_table[94].edges[1] = 0.00; data_table[94].edges[2] = 0.00; data_table[94].edges[3] = 0.00; data_table[94].edges[4] = 0.00; data_table[94].edges[5] = 0.00; data_table[94].edges[6] = 0.00; data_table[94].edges[7] = 0.00; data_table[94].edges[8] = 0.00; data_table[94].edges[9] = 0.00; data_table[94].edges[10] = 0.00; data_table[94].edges[11] = 0.00; + data_table[95].edges[0] = 0.00; data_table[95].edges[1] = 0.00; data_table[95].edges[2] = 0.00; data_table[95].edges[3] = 0.00; data_table[95].edges[4] = 0.00; data_table[95].edges[5] = 0.00; data_table[95].edges[6] = 0.00; data_table[95].edges[7] = 0.00; data_table[95].edges[8] = 0.00; data_table[95].edges[9] = 0.00; data_table[95].edges[10] = 0.00; data_table[95].edges[11] = 0.00; + data_table[96].edges[0] = 0.00; data_table[96].edges[1] = 0.00; data_table[96].edges[2] = 0.00; data_table[96].edges[3] = 0.00; data_table[96].edges[4] = 0.00; data_table[96].edges[5] = 0.00; data_table[96].edges[6] = 0.00; data_table[96].edges[7] = 0.00; data_table[96].edges[8] = 0.00; data_table[96].edges[9] = 0.00; data_table[96].edges[10] = 0.00; data_table[96].edges[11] = 0.00; + data_table[97].edges[0] = 0.00; data_table[97].edges[1] = 0.00; data_table[97].edges[2] = 0.00; data_table[97].edges[3] = 0.00; data_table[97].edges[4] = 0.00; data_table[97].edges[5] = 0.00; data_table[97].edges[6] = 0.00; data_table[97].edges[7] = 0.00; data_table[97].edges[8] = 0.00; data_table[97].edges[9] = 0.00; data_table[97].edges[10] = 0.00; data_table[97].edges[11] = 0.00; + data_table[98].edges[0] = 0.00; data_table[98].edges[1] = 0.00; data_table[98].edges[2] = 0.00; data_table[98].edges[3] = 0.00; data_table[98].edges[4] = 0.00; data_table[98].edges[5] = 0.00; data_table[98].edges[6] = 0.00; data_table[98].edges[7] = 0.00; data_table[98].edges[8] = 0.00; data_table[98].edges[9] = 0.00; data_table[98].edges[10] = 0.00; data_table[98].edges[11] = 0.00; + data_table[99].edges[0] = 0.00; data_table[99].edges[1] = 0.00; data_table[99].edges[2] = 0.00; data_table[99].edges[3] = 0.00; data_table[99].edges[4] = 0.00; data_table[99].edges[5] = 0.00; data_table[99].edges[6] = 0.00; data_table[99].edges[7] = 0.00; data_table[99].edges[8] = 0.00; data_table[99].edges[9] = 0.00; data_table[99].edges[10] = 0.00; data_table[99].edges[11] = 0.00; + data_table[100].edges[0] = 0.00; data_table[100].edges[1] = 0.00; data_table[100].edges[2] = 0.00; data_table[100].edges[3] = 0.00; data_table[100].edges[4] = 0.00; data_table[100].edges[5] = 0.00; data_table[100].edges[6] = 0.00; data_table[100].edges[7] = 0.00; data_table[100].edges[8] = 0.00; data_table[100].edges[9] = 0.00; data_table[100].edges[10] = 0.00; data_table[100].edges[11] = 0.00; + data_table[101].edges[0] = 0.00; data_table[101].edges[1] = 0.00; data_table[101].edges[2] = 0.00; data_table[101].edges[3] = 0.00; data_table[101].edges[4] = 0.00; data_table[101].edges[5] = 0.00; data_table[101].edges[6] = 0.00; data_table[101].edges[7] = 0.00; data_table[101].edges[8] = 0.00; data_table[101].edges[9] = 0.00; data_table[101].edges[10] = 0.00; data_table[101].edges[11] = 0.00; +data_table[102].edges[0] = 0.00; data_table[102].edges[1] = 0.00; data_table[102].edges[2] = 0.00; data_table[102].edges[3] = 0.00; data_table[102].edges[4] = 0.00; data_table[102].edges[5] = 0.00; data_table[102].edges[6] = 0.00; data_table[102].edges[7] = 0.00; data_table[102].edges[8] = 0.00; data_table[102].edges[9] = 0.00; data_table[102].edges[10] = 0.00; data_table[102].edges[11] = 0.00; + } + + // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] + void Load_feg_Doyle_neutral_0_4() + { + data_table[0].feg[0].cl[0] = 0.0000000000; data_table[0].feg[0].cnl[0] = 0.0000000000; data_table[0].feg[0].cl[1] = 0.0000000000; data_table[0].feg[0].cnl[1] = 0.0000000000; data_table[0].feg[0].cl[2] = 0.0000000000; data_table[0].feg[0].cnl[2] = 0.0000000000; data_table[0].feg[0].cl[3] = 0.0000000000; data_table[0].feg[0].cnl[3] = 0.0000000000; data_table[0].feg[0].cl[4] = 0.0000000000; data_table[0].feg[0].cnl[4] = 0.0000000000; data_table[0].feg[0].cl[5] = 0.0000000000; data_table[0].feg[0].cnl[5] = 0.0000000000; + data_table[1].feg[0].cl[0] = 0.0906000000; data_table[1].feg[0].cnl[0] = 18.1834000000; data_table[1].feg[0].cl[1] = 0.1814000000; data_table[1].feg[0].cnl[1] = 6.2109000000; data_table[1].feg[0].cl[2] = 0.1095000000; data_table[1].feg[0].cnl[2] = 1.8026000000; data_table[1].feg[0].cl[3] = 0.0362000000; data_table[1].feg[0].cnl[3] = 0.2844000000; data_table[1].feg[0].cl[4] = 0.0000000000; data_table[1].feg[0].cnl[4] = 0.0000000000; data_table[1].feg[0].cl[5] = 0.0000000000; data_table[1].feg[0].cnl[5] = 0.0000000000; + data_table[2].feg[0].cl[0] = 1.6108000000; data_table[2].feg[0].cnl[0] = 107.6384000000; data_table[2].feg[0].cl[1] = 1.2460000000; data_table[2].feg[0].cnl[1] = 30.4795000000; data_table[2].feg[0].cl[2] = 0.3257000000; data_table[2].feg[0].cnl[2] = 4.5331000000; data_table[2].feg[0].cl[3] = 0.0986000000; data_table[2].feg[0].cnl[3] = 0.4951000000; data_table[2].feg[0].cl[4] = 0.0000000000; data_table[2].feg[0].cnl[4] = 0.0000000000; data_table[2].feg[0].cl[5] = 0.0000000000; data_table[2].feg[0].cnl[5] = 0.0000000000; + data_table[3].feg[0].cl[0] = 1.2498000000; data_table[3].feg[0].cnl[0] = 60.8042000000; data_table[3].feg[0].cl[1] = 1.3335000000; data_table[3].feg[0].cnl[1] = 18.5914000000; data_table[3].feg[0].cl[2] = 0.3603000000; data_table[3].feg[0].cnl[2] = 3.6534000000; data_table[3].feg[0].cl[3] = 0.1055000000; data_table[3].feg[0].cnl[3] = 0.4157000000; data_table[3].feg[0].cl[4] = 0.0000000000; data_table[3].feg[0].cnl[4] = 0.0000000000; data_table[3].feg[0].cl[5] = 0.0000000000; data_table[3].feg[0].cnl[5] = 0.0000000000; + data_table[4].feg[0].cl[0] = 0.9446000000; data_table[4].feg[0].cnl[0] = 46.4438000000; data_table[4].feg[0].cl[1] = 1.3120000000; data_table[4].feg[0].cnl[1] = 14.1778000000; data_table[4].feg[0].cl[2] = 0.4188000000; data_table[4].feg[0].cnl[2] = 3.2228000000; data_table[4].feg[0].cl[3] = 0.1159000000; data_table[4].feg[0].cnl[3] = 0.3767000000; data_table[4].feg[0].cl[4] = 0.0000000000; data_table[4].feg[0].cnl[4] = 0.0000000000; data_table[4].feg[0].cl[5] = 0.0000000000; data_table[4].feg[0].cnl[5] = 0.0000000000; + data_table[5].feg[0].cl[0] = 0.7307000000; data_table[5].feg[0].cnl[0] = 36.9951000000; data_table[5].feg[0].cl[1] = 1.1951000000; data_table[5].feg[0].cnl[1] = 11.2966000000; data_table[5].feg[0].cl[2] = 0.4563000000; data_table[5].feg[0].cnl[2] = 2.8139000000; data_table[5].feg[0].cl[3] = 0.1247000000; data_table[5].feg[0].cnl[3] = 0.3456000000; data_table[5].feg[0].cl[4] = 0.0000000000; data_table[5].feg[0].cnl[4] = 0.0000000000; data_table[5].feg[0].cl[5] = 0.0000000000; data_table[5].feg[0].cnl[5] = 0.0000000000; + data_table[6].feg[0].cl[0] = 0.5717000000; data_table[6].feg[0].cnl[0] = 28.8465000000; data_table[6].feg[0].cl[1] = 1.0425000000; data_table[6].feg[0].cnl[1] = 9.0542000000; data_table[6].feg[0].cl[2] = 0.4647000000; data_table[6].feg[0].cnl[2] = 2.4213000000; data_table[6].feg[0].cl[3] = 0.1311000000; data_table[6].feg[0].cnl[3] = 0.3167000000; data_table[6].feg[0].cl[4] = 0.0000000000; data_table[6].feg[0].cnl[4] = 0.0000000000; data_table[6].feg[0].cl[5] = 0.0000000000; data_table[6].feg[0].cnl[5] = 0.0000000000; + data_table[7].feg[0].cl[0] = 0.4540000000; data_table[7].feg[0].cnl[0] = 23.7803000000; data_table[7].feg[0].cl[1] = 0.9173000000; data_table[7].feg[0].cnl[1] = 7.6220000000; data_table[7].feg[0].cl[2] = 0.4719000000; data_table[7].feg[0].cnl[2] = 2.1440000000; data_table[7].feg[0].cl[3] = 0.1384000000; data_table[7].feg[0].cnl[3] = 0.2959000000; data_table[7].feg[0].cl[4] = 0.0000000000; data_table[7].feg[0].cnl[4] = 0.0000000000; data_table[7].feg[0].cl[5] = 0.0000000000; data_table[7].feg[0].cnl[5] = 0.0000000000; + data_table[8].feg[0].cl[0] = 0.3686000000; data_table[8].feg[0].cnl[0] = 20.2390000000; data_table[8].feg[0].cl[1] = 0.8109000000; data_table[8].feg[0].cnl[1] = 6.6093000000; data_table[8].feg[0].cl[2] = 0.4751000000; data_table[8].feg[0].cnl[2] = 1.9310000000; data_table[8].feg[0].cl[3] = 0.1459000000; data_table[8].feg[0].cnl[3] = 0.2793000000; data_table[8].feg[0].cl[4] = 0.0000000000; data_table[8].feg[0].cnl[4] = 0.0000000000; data_table[8].feg[0].cl[5] = 0.0000000000; data_table[8].feg[0].cnl[5] = 0.0000000000; + data_table[9].feg[0].cl[0] = 0.3025000000; data_table[9].feg[0].cnl[0] = 17.6390000000; data_table[9].feg[0].cl[1] = 0.7202000000; data_table[9].feg[0].cnl[1] = 5.8604000000; data_table[9].feg[0].cl[2] = 0.4751000000; data_table[9].feg[0].cnl[2] = 1.7623000000; data_table[9].feg[0].cl[3] = 0.1534000000; data_table[9].feg[0].cnl[3] = 0.2656000000; data_table[9].feg[0].cl[4] = 0.0000000000; data_table[9].feg[0].cnl[4] = 0.0000000000; data_table[9].feg[0].cl[5] = 0.0000000000; data_table[9].feg[0].cnl[5] = 0.0000000000; + data_table[10].feg[0].cl[0] = 2.2406000000; data_table[10].feg[0].cnl[0] = 108.0039000000; data_table[10].feg[0].cl[1] = 1.3326000000; data_table[10].feg[0].cnl[1] = 24.5047000000; data_table[10].feg[0].cl[2] = 0.9070000000; data_table[10].feg[0].cnl[2] = 3.3914000000; data_table[10].feg[0].cl[3] = 0.2863000000; data_table[10].feg[0].cnl[3] = 0.4346000000; data_table[10].feg[0].cl[4] = 0.0000000000; data_table[10].feg[0].cnl[4] = 0.0000000000; data_table[10].feg[0].cl[5] = 0.0000000000; data_table[10].feg[0].cnl[5] = 0.0000000000; + data_table[11].feg[0].cl[0] = 2.2692000000; data_table[11].feg[0].cnl[0] = 73.6704000000; data_table[11].feg[0].cl[1] = 1.8025000000; data_table[11].feg[0].cnl[1] = 20.1749000000; data_table[11].feg[0].cl[2] = 0.8394000000; data_table[11].feg[0].cnl[2] = 3.0131000000; data_table[11].feg[0].cl[3] = 0.2892000000; data_table[11].feg[0].cnl[3] = 0.4046000000; data_table[11].feg[0].cl[4] = 0.0000000000; data_table[11].feg[0].cnl[4] = 0.0000000000; data_table[11].feg[0].cl[5] = 0.0000000000; data_table[11].feg[0].cnl[5] = 0.0000000000; + data_table[12].feg[0].cl[0] = 2.2756000000; data_table[12].feg[0].cnl[0] = 72.3220000000; data_table[12].feg[0].cl[1] = 2.4280000000; data_table[12].feg[0].cnl[1] = 19.7729000000; data_table[12].feg[0].cl[2] = 0.8578000000; data_table[12].feg[0].cnl[2] = 3.0799000000; data_table[12].feg[0].cl[3] = 0.3266000000; data_table[12].feg[0].cnl[3] = 0.4076000000; data_table[12].feg[0].cl[4] = 0.0000000000; data_table[12].feg[0].cnl[4] = 0.0000000000; data_table[12].feg[0].cl[5] = 0.0000000000; data_table[12].feg[0].cnl[5] = 0.0000000000; + data_table[13].feg[0].cl[0] = 2.1293000000; data_table[13].feg[0].cnl[0] = 57.7748000000; data_table[13].feg[0].cl[1] = 2.5333000000; data_table[13].feg[0].cnl[1] = 16.4756000000; data_table[13].feg[0].cl[2] = 0.8349000000; data_table[13].feg[0].cnl[2] = 2.6796000000; data_table[13].feg[0].cl[3] = 0.3216000000; data_table[13].feg[0].cnl[3] = 0.3860000000; data_table[13].feg[0].cl[4] = 0.0000000000; data_table[13].feg[0].cnl[4] = 0.0000000000; data_table[13].feg[0].cl[5] = 0.0000000000; data_table[13].feg[0].cnl[5] = 0.0000000000; + data_table[14].feg[0].cl[0] = 1.8882000000; data_table[14].feg[0].cnl[0] = 44.8756000000; data_table[14].feg[0].cl[1] = 2.4685000000; data_table[14].feg[0].cnl[1] = 13.5383000000; data_table[14].feg[0].cl[2] = 0.8046000000; data_table[14].feg[0].cnl[2] = 2.6424000000; data_table[14].feg[0].cl[3] = 0.3204000000; data_table[14].feg[0].cnl[3] = 0.3603000000; data_table[14].feg[0].cl[4] = 0.0000000000; data_table[14].feg[0].cnl[4] = 0.0000000000; data_table[14].feg[0].cl[5] = 0.0000000000; data_table[14].feg[0].cnl[5] = 0.0000000000; + data_table[15].feg[0].cl[0] = 1.6591000000; data_table[15].feg[0].cnl[0] = 36.6500000000; data_table[15].feg[0].cl[1] = 2.3863000000; data_table[15].feg[0].cnl[1] = 11.4881000000; data_table[15].feg[0].cl[2] = 0.7899000000; data_table[15].feg[0].cnl[2] = 2.4686000000; data_table[15].feg[0].cl[3] = 0.3208000000; data_table[15].feg[0].cnl[3] = 0.3403000000; data_table[15].feg[0].cl[4] = 0.0000000000; data_table[15].feg[0].cnl[4] = 0.0000000000; data_table[15].feg[0].cl[5] = 0.0000000000; data_table[15].feg[0].cnl[5] = 0.0000000000; + data_table[16].feg[0].cl[0] = 1.4524000000; data_table[16].feg[0].cnl[0] = 30.9352000000; data_table[16].feg[0].cl[1] = 2.2926000000; data_table[16].feg[0].cnl[1] = 9.9798000000; data_table[16].feg[0].cl[2] = 0.7874000000; data_table[16].feg[0].cnl[2] = 2.3336000000; data_table[16].feg[0].cl[3] = 0.3217000000; data_table[16].feg[0].cnl[3] = 0.3228000000; data_table[16].feg[0].cl[4] = 0.0000000000; data_table[16].feg[0].cnl[4] = 0.0000000000; data_table[16].feg[0].cl[5] = 0.0000000000; data_table[16].feg[0].cnl[5] = 0.0000000000; + data_table[17].feg[0].cl[0] = 1.2736000000; data_table[17].feg[0].cnl[0] = 26.6823000000; data_table[17].feg[0].cl[1] = 2.1894000000; data_table[17].feg[0].cnl[1] = 8.8130000000; data_table[17].feg[0].cl[2] = 0.7927000000; data_table[17].feg[0].cnl[2] = 2.2186000000; data_table[17].feg[0].cl[3] = 0.3225000000; data_table[17].feg[0].cnl[3] = 0.3071000000; data_table[17].feg[0].cl[4] = 0.0000000000; data_table[17].feg[0].cnl[4] = 0.0000000000; data_table[17].feg[0].cl[5] = 0.0000000000; data_table[17].feg[0].cnl[5] = 0.0000000000; + data_table[18].feg[0].cl[0] = 3.9507000000; data_table[18].feg[0].cnl[0] = 137.0748000000; data_table[18].feg[0].cl[1] = 2.5452000000; data_table[18].feg[0].cnl[1] = 22.4017000000; data_table[18].feg[0].cl[2] = 1.9795000000; data_table[18].feg[0].cnl[2] = 4.5319000000; data_table[18].feg[0].cl[3] = 0.4017000000; data_table[18].feg[0].cnl[3] = 0.4340000000; data_table[18].feg[0].cl[4] = 0.0000000000; data_table[18].feg[0].cnl[4] = 0.0000000000; data_table[18].feg[0].cl[5] = 0.0000000000; data_table[18].feg[0].cnl[5] = 0.0000000000; + data_table[19].feg[0].cl[0] = 4.4696000000; data_table[19].feg[0].cnl[0] = 99.5228000000; data_table[19].feg[0].cl[1] = 2.9703000000; data_table[19].feg[0].cnl[1] = 22.6958000000; data_table[19].feg[0].cl[2] = 1.9696000000; data_table[19].feg[0].cnl[2] = 4.1954000000; data_table[19].feg[0].cl[3] = 0.4818000000; data_table[19].feg[0].cnl[3] = 0.4165000000; data_table[19].feg[0].cl[4] = 0.0000000000; data_table[19].feg[0].cnl[4] = 0.0000000000; data_table[19].feg[0].cl[5] = 0.0000000000; data_table[19].feg[0].cnl[5] = 0.0000000000; + data_table[20].feg[0].cl[0] = 3.9659000000; data_table[20].feg[0].cnl[0] = 38.9597000000; data_table[20].feg[0].cl[1] = 2.9169000000; data_table[20].feg[0].cnl[1] = 20.6061000000; data_table[20].feg[0].cl[2] = 1.9254000000; data_table[20].feg[0].cnl[2] = 3.8557000000; data_table[20].feg[0].cl[3] = 0.4802000000; data_table[20].feg[0].cnl[3] = 0.3988000000; data_table[20].feg[0].cl[4] = 0.0000000000; data_table[20].feg[0].cnl[4] = 0.0000000000; data_table[20].feg[0].cl[5] = 0.0000000000; data_table[20].feg[0].cnl[5] = 0.0000000000; + data_table[21].feg[0].cl[0] = 3.5653000000; data_table[21].feg[0].cnl[0] = 81.9821000000; data_table[21].feg[0].cl[1] = 2.8181000000; data_table[21].feg[0].cnl[1] = 19.0486000000; data_table[21].feg[0].cl[2] = 1.8930000000; data_table[21].feg[0].cnl[2] = 3.5904000000; data_table[21].feg[0].cl[3] = 0.4825000000; data_table[21].feg[0].cnl[3] = 0.3855000000; data_table[21].feg[0].cl[4] = 0.0000000000; data_table[21].feg[0].cnl[4] = 0.0000000000; data_table[21].feg[0].cl[5] = 0.0000000000; data_table[21].feg[0].cnl[5] = 0.0000000000; + data_table[22].feg[0].cl[0] = 3.2449000000; data_table[22].feg[0].cnl[0] = 76.3789000000; data_table[22].feg[0].cl[1] = 2.6978000000; data_table[22].feg[0].cnl[1] = 17.7262000000; data_table[22].feg[0].cl[2] = 1.8597000000; data_table[22].feg[0].cnl[2] = 3.3632000000; data_table[22].feg[0].cl[3] = 0.4864000000; data_table[22].feg[0].cnl[3] = 0.3743000000; data_table[22].feg[0].cl[4] = 0.0000000000; data_table[22].feg[0].cnl[4] = 0.0000000000; data_table[22].feg[0].cl[5] = 0.0000000000; data_table[22].feg[0].cnl[5] = 0.0000000000; + data_table[23].feg[0].cl[0] = 2.3066000000; data_table[23].feg[0].cnl[0] = 78.4051000000; data_table[23].feg[0].cl[1] = 2.3339000000; data_table[23].feg[0].cnl[1] = 15.7851000000; data_table[23].feg[0].cl[2] = 1.8226000000; data_table[23].feg[0].cnl[2] = 3.1566000000; data_table[23].feg[0].cl[3] = 0.4901000000; data_table[23].feg[0].cnl[3] = 0.3636000000; data_table[23].feg[0].cl[4] = 0.0000000000; data_table[23].feg[0].cnl[4] = 0.0000000000; data_table[23].feg[0].cl[5] = 0.0000000000; data_table[23].feg[0].cnl[5] = 0.0000000000; + data_table[24].feg[0].cl[0] = 2.7467000000; data_table[24].feg[0].cnl[0] = 67.7862000000; data_table[24].feg[0].cl[1] = 2.4556000000; data_table[24].feg[0].cnl[1] = 15.6743000000; data_table[24].feg[0].cl[2] = 1.7923000000; data_table[24].feg[0].cnl[2] = 2.9998000000; data_table[24].feg[0].cl[3] = 0.4984000000; data_table[24].feg[0].cnl[3] = 0.3569000000; data_table[24].feg[0].cl[4] = 0.0000000000; data_table[24].feg[0].cnl[4] = 0.0000000000; data_table[24].feg[0].cl[5] = 0.0000000000; data_table[24].feg[0].cnl[5] = 0.0000000000; + data_table[25].feg[0].cl[0] = 2.5440000000; data_table[25].feg[0].cnl[0] = 64.4244000000; data_table[25].feg[0].cl[1] = 2.3434000000; data_table[25].feg[0].cnl[1] = 14.5306000000; data_table[25].feg[0].cl[2] = 1.7588000000; data_table[25].feg[0].cnl[2] = 2.8539000000; data_table[25].feg[0].cl[3] = 0.5062000000; data_table[25].feg[0].cnl[3] = 0.3502000000; data_table[25].feg[0].cl[4] = 0.0000000000; data_table[25].feg[0].cnl[4] = 0.0000000000; data_table[25].feg[0].cl[5] = 0.0000000000; data_table[25].feg[0].cnl[5] = 0.0000000000; + data_table[26].feg[0].cl[0] = 2.3668000000; data_table[26].feg[0].cnl[0] = 61.4306000000; data_table[26].feg[0].cl[1] = 2.2361000000; data_table[26].feg[0].cnl[1] = 14.1793000000; data_table[26].feg[0].cl[2] = 1.7243000000; data_table[26].feg[0].cnl[2] = 2.7247000000; data_table[26].feg[0].cl[3] = 0.5148000000; data_table[26].feg[0].cnl[3] = 0.3442000000; data_table[26].feg[0].cl[4] = 0.0000000000; data_table[26].feg[0].cnl[4] = 0.0000000000; data_table[26].feg[0].cl[5] = 0.0000000000; data_table[26].feg[0].cnl[5] = 0.0000000000; + data_table[27].feg[0].cl[0] = 2.2104000000; data_table[27].feg[0].cnl[0] = 58.7267000000; data_table[27].feg[0].cl[1] = 2.1342000000; data_table[27].feg[0].cnl[1] = 13.5530000000; data_table[27].feg[0].cl[2] = 1.6891000000; data_table[27].feg[0].cnl[2] = 2.6094000000; data_table[27].feg[0].cl[3] = 0.5238000000; data_table[27].feg[0].cnl[3] = 0.3388000000; data_table[27].feg[0].cl[4] = 0.0000000000; data_table[27].feg[0].cnl[4] = 0.0000000000; data_table[27].feg[0].cl[5] = 0.0000000000; data_table[27].feg[0].cnl[5] = 0.0000000000; + data_table[28].feg[0].cl[0] = 1.5792000000; data_table[28].feg[0].cnl[0] = 62.9403000000; data_table[28].feg[0].cl[1] = 1.8197000000; data_table[28].feg[0].cnl[1] = 12.4527000000; data_table[28].feg[0].cl[2] = 1.6576000000; data_table[28].feg[0].cnl[2] = 2.5042000000; data_table[28].feg[0].cl[3] = 0.5323000000; data_table[28].feg[0].cnl[3] = 0.3331000000; data_table[28].feg[0].cl[4] = 0.0000000000; data_table[28].feg[0].cnl[4] = 0.0000000000; data_table[28].feg[0].cl[5] = 0.0000000000; data_table[28].feg[0].cnl[5] = 0.0000000000; + data_table[29].feg[0].cl[0] = 1.9418000000; data_table[29].feg[0].cnl[0] = 54.1621000000; data_table[29].feg[0].cl[1] = 1.9501000000; data_table[29].feg[0].cnl[1] = 12.5177000000; data_table[29].feg[0].cl[2] = 1.6192000000; data_table[29].feg[0].cnl[2] = 2.4164000000; data_table[29].feg[0].cl[3] = 0.5434000000; data_table[29].feg[0].cnl[3] = 0.3295000000; data_table[29].feg[0].cl[4] = 0.0000000000; data_table[29].feg[0].cnl[4] = 0.0000000000; data_table[29].feg[0].cl[5] = 0.0000000000; data_table[29].feg[0].cnl[5] = 0.0000000000; + data_table[30].feg[0].cl[0] = 2.3205000000; data_table[30].feg[0].cnl[0] = 65.6019000000; data_table[30].feg[0].cl[1] = 2.4955000000; data_table[30].feg[0].cnl[1] = 15.4577000000; data_table[30].feg[0].cl[2] = 1.6879000000; data_table[30].feg[0].cnl[2] = 2.5806000000; data_table[30].feg[0].cl[3] = 0.5992000000; data_table[30].feg[0].cnl[3] = 0.3510000000; data_table[30].feg[0].cl[4] = 0.0000000000; data_table[30].feg[0].cnl[4] = 0.0000000000; data_table[30].feg[0].cl[5] = 0.0000000000; data_table[30].feg[0].cnl[5] = 0.0000000000; + data_table[31].feg[0].cl[0] = 2.4467000000; data_table[31].feg[0].cnl[0] = 55.8930000000; data_table[31].feg[0].cl[1] = 2.7015000000; data_table[31].feg[0].cnl[1] = 14.3930000000; data_table[31].feg[0].cl[2] = 1.6157000000; data_table[31].feg[0].cnl[2] = 2.4461000000; data_table[31].feg[0].cl[3] = 0.6009000000; data_table[31].feg[0].cnl[3] = 0.3415000000; data_table[31].feg[0].cl[4] = 0.0000000000; data_table[31].feg[0].cnl[4] = 0.0000000000; data_table[31].feg[0].cl[5] = 0.0000000000; data_table[31].feg[0].cnl[5] = 0.0000000000; + data_table[32].feg[0].cl[0] = 2.3989000000; data_table[32].feg[0].cnl[0] = 45.7179000000; data_table[32].feg[0].cl[1] = 2.7898000000; data_table[32].feg[0].cnl[1] = 32.8166000000; data_table[32].feg[0].cl[2] = 1.5288000000; data_table[32].feg[0].cnl[2] = 2.2799000000; data_table[32].feg[0].cl[3] = 0.5936000000; data_table[32].feg[0].cnl[3] = 0.3277000000; data_table[32].feg[0].cl[4] = 0.0000000000; data_table[32].feg[0].cnl[4] = 0.0000000000; data_table[32].feg[0].cl[5] = 0.0000000000; data_table[32].feg[0].cnl[5] = 0.0000000000; + data_table[33].feg[0].cl[0] = 2.2980000000; data_table[33].feg[0].cnl[0] = 38.8296000000; data_table[33].feg[0].cl[1] = 2.8541000000; data_table[33].feg[0].cnl[1] = 11.5359000000; data_table[33].feg[0].cl[2] = 1.4555000000; data_table[33].feg[0].cnl[2] = 2.1463000000; data_table[33].feg[0].cl[3] = 0.5895000000; data_table[33].feg[0].cnl[3] = 0.3163000000; data_table[33].feg[0].cl[4] = 0.0000000000; data_table[33].feg[0].cnl[4] = 0.0000000000; data_table[33].feg[0].cl[5] = 0.0000000000; data_table[33].feg[0].cnl[5] = 0.0000000000; + data_table[34].feg[0].cl[0] = 2.1659000000; data_table[34].feg[0].cnl[0] = 33.8987000000; data_table[34].feg[0].cl[1] = 2.9037000000; data_table[34].feg[0].cnl[1] = 10.4996000000; data_table[34].feg[0].cl[2] = 1.3951000000; data_table[34].feg[0].cnl[2] = 2.0413000000; data_table[34].feg[0].cl[3] = 0.5886000000; data_table[34].feg[0].cnl[3] = 0.3070000000; data_table[34].feg[0].cl[4] = 0.0000000000; data_table[34].feg[0].cnl[4] = 0.0000000000; data_table[34].feg[0].cl[5] = 0.0000000000; data_table[34].feg[0].cnl[5] = 0.0000000000; + data_table[35].feg[0].cl[0] = 2.0338000000; data_table[35].feg[0].cnl[0] = 29.9992000000; data_table[35].feg[0].cl[1] = 2.9271000000; data_table[35].feg[0].cnl[1] = 9.5977000000; data_table[35].feg[0].cl[2] = 1.3425000000; data_table[35].feg[0].cnl[2] = 1.9520000000; data_table[35].feg[0].cl[3] = 0.5888000000; data_table[35].feg[0].cnl[3] = 0.2986000000; data_table[35].feg[0].cl[4] = 0.0000000000; data_table[35].feg[0].cnl[4] = 0.0000000000; data_table[35].feg[0].cl[5] = 0.0000000000; data_table[35].feg[0].cnl[5] = 0.0000000000; + data_table[36].feg[0].cl[0] = 4.7760000000; data_table[36].feg[0].cnl[0] = 140.7821000000; data_table[36].feg[0].cl[1] = 3.8588000000; data_table[36].feg[0].cnl[1] = 18.9910000000; data_table[36].feg[0].cl[2] = 2.2339000000; data_table[36].feg[0].cnl[2] = 3.7010000000; data_table[36].feg[0].cl[3] = 0.8683000000; data_table[36].feg[0].cnl[3] = 0.4194000000; data_table[36].feg[0].cl[4] = 0.0000000000; data_table[36].feg[0].cnl[4] = 0.0000000000; data_table[36].feg[0].cl[5] = 0.0000000000; data_table[36].feg[0].cnl[5] = 0.0000000000; + data_table[37].feg[0].cl[0] = 5.8478000000; data_table[37].feg[0].cnl[0] = 104.9721000000; data_table[37].feg[0].cl[1] = 4.0026000000; data_table[37].feg[0].cnl[1] = 19.3666000000; data_table[37].feg[0].cl[2] = 2.3420000000; data_table[37].feg[0].cnl[2] = 3.7368000000; data_table[37].feg[0].cl[3] = 0.8795000000; data_table[37].feg[0].cnl[3] = 0.4142000000; data_table[37].feg[0].cl[4] = 0.0000000000; data_table[37].feg[0].cnl[4] = 0.0000000000; data_table[37].feg[0].cl[5] = 0.0000000000; data_table[37].feg[0].cnl[5] = 0.0000000000; + data_table[38].feg[0].cl[0] = 0.0000000000; data_table[38].feg[0].cnl[0] = 0.0000000000; data_table[38].feg[0].cl[1] = 0.0000000000; data_table[38].feg[0].cnl[1] = 0.0000000000; data_table[38].feg[0].cl[2] = 0.0000000000; data_table[38].feg[0].cnl[2] = 0.0000000000; data_table[38].feg[0].cl[3] = 0.0000000000; data_table[38].feg[0].cnl[3] = 0.0000000000; data_table[38].feg[0].cl[4] = 0.0000000000; data_table[38].feg[0].cnl[4] = 0.0000000000; data_table[38].feg[0].cl[5] = 0.0000000000; data_table[38].feg[0].cnl[5] = 0.0000000000; + data_table[39].feg[0].cl[0] = 0.0000000000; data_table[39].feg[0].cnl[0] = 0.0000000000; data_table[39].feg[0].cl[1] = 0.0000000000; data_table[39].feg[0].cnl[1] = 0.0000000000; data_table[39].feg[0].cl[2] = 0.0000000000; data_table[39].feg[0].cnl[2] = 0.0000000000; data_table[39].feg[0].cl[3] = 0.0000000000; data_table[39].feg[0].cnl[3] = 0.0000000000; data_table[39].feg[0].cl[4] = 0.0000000000; data_table[39].feg[0].cnl[4] = 0.0000000000; data_table[39].feg[0].cl[5] = 0.0000000000; data_table[39].feg[0].cnl[5] = 0.0000000000; + data_table[40].feg[0].cl[0] = 0.0000000000; data_table[40].feg[0].cnl[0] = 0.0000000000; data_table[40].feg[0].cl[1] = 0.0000000000; data_table[40].feg[0].cnl[1] = 0.0000000000; data_table[40].feg[0].cl[2] = 0.0000000000; data_table[40].feg[0].cnl[2] = 0.0000000000; data_table[40].feg[0].cl[3] = 0.0000000000; data_table[40].feg[0].cnl[3] = 0.0000000000; data_table[40].feg[0].cl[4] = 0.0000000000; data_table[40].feg[0].cnl[4] = 0.0000000000; data_table[40].feg[0].cl[5] = 0.0000000000; data_table[40].feg[0].cnl[5] = 0.0000000000; + data_table[41].feg[0].cl[0] = 3.1199000000; data_table[41].feg[0].cnl[0] = 72.4642000000; data_table[41].feg[0].cl[1] = 3.9061000000; data_table[41].feg[0].cnl[1] = 14.6424000000; data_table[41].feg[0].cl[2] = 2.3615000000; data_table[41].feg[0].cnl[2] = 3.2370000000; data_table[41].feg[0].cl[3] = 0.8504000000; data_table[41].feg[0].cnl[3] = 0.3662000000; data_table[41].feg[0].cl[4] = 0.0000000000; data_table[41].feg[0].cnl[4] = 0.0000000000; data_table[41].feg[0].cl[5] = 0.0000000000; data_table[41].feg[0].cnl[5] = 0.0000000000; + data_table[42].feg[0].cl[0] = 0.0000000000; data_table[42].feg[0].cnl[0] = 0.0000000000; data_table[42].feg[0].cl[1] = 0.0000000000; data_table[42].feg[0].cnl[1] = 0.0000000000; data_table[42].feg[0].cl[2] = 0.0000000000; data_table[42].feg[0].cnl[2] = 0.0000000000; data_table[42].feg[0].cl[3] = 0.0000000000; data_table[42].feg[0].cnl[3] = 0.0000000000; data_table[42].feg[0].cl[4] = 0.0000000000; data_table[42].feg[0].cnl[4] = 0.0000000000; data_table[42].feg[0].cl[5] = 0.0000000000; data_table[42].feg[0].cnl[5] = 0.0000000000; + data_table[43].feg[0].cl[0] = 0.0000000000; data_table[43].feg[0].cnl[0] = 0.0000000000; data_table[43].feg[0].cl[1] = 0.0000000000; data_table[43].feg[0].cnl[1] = 0.0000000000; data_table[43].feg[0].cl[2] = 0.0000000000; data_table[43].feg[0].cnl[2] = 0.0000000000; data_table[43].feg[0].cl[3] = 0.0000000000; data_table[43].feg[0].cnl[3] = 0.0000000000; data_table[43].feg[0].cl[4] = 0.0000000000; data_table[43].feg[0].cnl[4] = 0.0000000000; data_table[43].feg[0].cl[5] = 0.0000000000; data_table[43].feg[0].cnl[5] = 0.0000000000; + data_table[44].feg[0].cl[0] = 0.0000000000; data_table[44].feg[0].cnl[0] = 0.0000000000; data_table[44].feg[0].cl[1] = 0.0000000000; data_table[44].feg[0].cnl[1] = 0.0000000000; data_table[44].feg[0].cl[2] = 0.0000000000; data_table[44].feg[0].cnl[2] = 0.0000000000; data_table[44].feg[0].cl[3] = 0.0000000000; data_table[44].feg[0].cnl[3] = 0.0000000000; data_table[44].feg[0].cl[4] = 0.0000000000; data_table[44].feg[0].cnl[4] = 0.0000000000; data_table[44].feg[0].cl[5] = 0.0000000000; data_table[44].feg[0].cnl[5] = 0.0000000000; + data_table[45].feg[0].cl[0] = 0.0000000000; data_table[45].feg[0].cnl[0] = 0.0000000000; data_table[45].feg[0].cl[1] = 0.0000000000; data_table[45].feg[0].cnl[1] = 0.0000000000; data_table[45].feg[0].cl[2] = 0.0000000000; data_table[45].feg[0].cnl[2] = 0.0000000000; data_table[45].feg[0].cl[3] = 0.0000000000; data_table[45].feg[0].cnl[3] = 0.0000000000; data_table[45].feg[0].cl[4] = 0.0000000000; data_table[45].feg[0].cnl[4] = 0.0000000000; data_table[45].feg[0].cl[5] = 0.0000000000; data_table[45].feg[0].cnl[5] = 0.0000000000; + data_table[46].feg[0].cl[0] = 2.0355000000; data_table[46].feg[0].cnl[0] = 61.4970000000; data_table[46].feg[0].cl[1] = 3.2716000000; data_table[46].feg[0].cnl[1] = 11.3237000000; data_table[46].feg[0].cl[2] = 2.5105000000; data_table[46].feg[0].cnl[2] = 2.8456000000; data_table[46].feg[0].cl[3] = 0.8372000000; data_table[46].feg[0].cnl[3] = 0.3271000000; data_table[46].feg[0].cl[4] = 0.0000000000; data_table[46].feg[0].cnl[4] = 0.0000000000; data_table[46].feg[0].cl[5] = 0.0000000000; data_table[46].feg[0].cnl[5] = 0.0000000000; + data_table[47].feg[0].cl[0] = 2.5737000000; data_table[47].feg[0].cnl[0] = 55.6752000000; data_table[47].feg[0].cl[1] = 3.2536000000; data_table[47].feg[0].cnl[1] = 11.8376000000; data_table[47].feg[0].cl[2] = 2.5468000000; data_table[47].feg[0].cnl[2] = 2.7842000000; data_table[47].feg[0].cl[3] = 0.8379000000; data_table[47].feg[0].cnl[3] = 0.3217000000; data_table[47].feg[0].cl[4] = 0.0000000000; data_table[47].feg[0].cnl[4] = 0.0000000000; data_table[47].feg[0].cl[5] = 0.0000000000; data_table[47].feg[0].cnl[5] = 0.0000000000; + data_table[48].feg[0].cl[0] = 3.1528000000; data_table[48].feg[0].cnl[0] = 66.6492000000; data_table[48].feg[0].cl[1] = 3.5565000000; data_table[48].feg[0].cnl[1] = 14.4494000000; data_table[48].feg[0].cl[2] = 2.8180000000; data_table[48].feg[0].cnl[2] = 2.9758000000; data_table[48].feg[0].cl[3] = 0.8842000000; data_table[48].feg[0].cnl[3] = 0.3345000000; data_table[48].feg[0].cl[4] = 0.0000000000; data_table[48].feg[0].cnl[4] = 0.0000000000; data_table[48].feg[0].cl[5] = 0.0000000000; data_table[48].feg[0].cnl[5] = 0.0000000000; + data_table[49].feg[0].cl[0] = 3.4495000000; data_table[49].feg[0].cnl[0] = 59.1042000000; data_table[49].feg[0].cl[1] = 3.7349000000; data_table[49].feg[0].cnl[1] = 14.1787000000; data_table[49].feg[0].cl[2] = 2.7779000000; data_table[49].feg[0].cnl[2] = 2.8548000000; data_table[49].feg[0].cl[3] = 0.8786000000; data_table[49].feg[0].cnl[3] = 0.3270000000; data_table[49].feg[0].cl[4] = 0.0000000000; data_table[49].feg[0].cnl[4] = 0.0000000000; data_table[49].feg[0].cl[5] = 0.0000000000; data_table[49].feg[0].cnl[5] = 0.0000000000; + data_table[50].feg[0].cl[0] = 3.5644000000; data_table[50].feg[0].cnl[0] = 50.4869000000; data_table[50].feg[0].cl[1] = 3.8437000000; data_table[50].feg[0].cnl[1] = 13.3156000000; data_table[50].feg[0].cl[2] = 2.6366000000; data_table[50].feg[0].cnl[2] = 2.6909000000; data_table[50].feg[0].cl[3] = 0.8638000000; data_table[50].feg[0].cnl[3] = 0.3161000000; data_table[50].feg[0].cl[4] = 0.0000000000; data_table[50].feg[0].cnl[4] = 0.0000000000; data_table[50].feg[0].cl[5] = 0.0000000000; data_table[50].feg[0].cnl[5] = 0.0000000000; + data_table[51].feg[0].cl[0] = 0.0000000000; data_table[51].feg[0].cnl[0] = 0.0000000000; data_table[51].feg[0].cl[1] = 0.0000000000; data_table[51].feg[0].cnl[1] = 0.0000000000; data_table[51].feg[0].cl[2] = 0.0000000000; data_table[51].feg[0].cnl[2] = 0.0000000000; data_table[51].feg[0].cl[3] = 0.0000000000; data_table[51].feg[0].cnl[3] = 0.0000000000; data_table[51].feg[0].cl[4] = 0.0000000000; data_table[51].feg[0].cnl[4] = 0.0000000000; data_table[51].feg[0].cl[5] = 0.0000000000; data_table[51].feg[0].cnl[5] = 0.0000000000; + data_table[52].feg[0].cl[0] = 3.4728000000; data_table[52].feg[0].cnl[0] = 39.4411000000; data_table[52].feg[0].cl[1] = 4.0602000000; data_table[52].feg[0].cnl[1] = 11.8161000000; data_table[52].feg[0].cl[2] = 2.5215000000; data_table[52].feg[0].cnl[2] = 2.4148000000; data_table[52].feg[0].cl[3] = 0.8398000000; data_table[52].feg[0].cnl[3] = 0.2976000000; data_table[52].feg[0].cl[4] = 0.0000000000; data_table[52].feg[0].cnl[4] = 0.0000000000; data_table[52].feg[0].cl[5] = 0.0000000000; data_table[52].feg[0].cnl[5] = 0.0000000000; + data_table[53].feg[0].cl[0] = 3.3656000000; data_table[53].feg[0].cnl[0] = 35.5094000000; data_table[53].feg[0].cl[1] = 4.1468000000; data_table[53].feg[0].cnl[1] = 11.1170000000; data_table[53].feg[0].cl[2] = 2.4430000000; data_table[53].feg[0].cnl[2] = 2.2940000000; data_table[53].feg[0].cl[3] = 0.8293000000; data_table[53].feg[0].cnl[3] = 0.2892000000; data_table[53].feg[0].cl[4] = 0.0000000000; data_table[53].feg[0].cnl[4] = 0.0000000000; data_table[53].feg[0].cl[5] = 0.0000000000; data_table[53].feg[0].cnl[5] = 0.0000000000; + data_table[54].feg[0].cl[0] = 6.0620000000; data_table[54].feg[0].cnl[0] = 155.8336000000; data_table[54].feg[0].cl[1] = 5.9861000000; data_table[54].feg[0].cnl[1] = 19.6951000000; data_table[54].feg[0].cl[2] = 3.3033000000; data_table[54].feg[0].cnl[2] = 3.3354000000; data_table[54].feg[0].cl[3] = 1.0958000000; data_table[54].feg[0].cnl[3] = 0.3793000000; data_table[54].feg[0].cl[4] = 0.0000000000; data_table[54].feg[0].cnl[4] = 0.0000000000; data_table[54].feg[0].cl[5] = 0.0000000000; data_table[54].feg[0].cnl[5] = 0.0000000000; + data_table[55].feg[0].cl[0] = 7.8212000000; data_table[55].feg[0].cnl[0] = 117.6575000000; data_table[55].feg[0].cl[1] = 6.0040000000; data_table[55].feg[0].cnl[1] = 18.7782000000; data_table[55].feg[0].cl[2] = 3.2803000000; data_table[55].feg[0].cnl[2] = 3.2634000000; data_table[55].feg[0].cl[3] = 1.1030000000; data_table[55].feg[0].cnl[3] = 0.3760000000; data_table[55].feg[0].cl[4] = 0.0000000000; data_table[55].feg[0].cnl[4] = 0.0000000000; data_table[55].feg[0].cl[5] = 0.0000000000; data_table[55].feg[0].cnl[5] = 0.0000000000; + data_table[56].feg[0].cl[0] = 6.2661000000; data_table[56].feg[0].cnl[0] = 100.2983000000; data_table[56].feg[0].cl[1] = 4.8440000000; data_table[56].feg[0].cnl[1] = 16.0662000000; data_table[56].feg[0].cl[2] = 3.2023000000; data_table[56].feg[0].cnl[2] = 2.9803000000; data_table[56].feg[0].cl[3] = 1.2009000000; data_table[56].feg[0].cnl[3] = 0.3674000000; data_table[56].feg[0].cl[4] = 0.0000000000; data_table[56].feg[0].cnl[4] = 0.0000000000; data_table[56].feg[0].cl[5] = 0.0000000000; data_table[56].feg[0].cnl[5] = 0.0000000000; + data_table[57].feg[0].cl[0] = 0.0000000000; data_table[57].feg[0].cnl[0] = 0.0000000000; data_table[57].feg[0].cl[1] = 0.0000000000; data_table[57].feg[0].cnl[1] = 0.0000000000; data_table[57].feg[0].cl[2] = 0.0000000000; data_table[57].feg[0].cnl[2] = 0.0000000000; data_table[57].feg[0].cl[3] = 0.0000000000; data_table[57].feg[0].cnl[3] = 0.0000000000; data_table[57].feg[0].cl[4] = 0.0000000000; data_table[57].feg[0].cnl[4] = 0.0000000000; data_table[57].feg[0].cl[5] = 0.0000000000; data_table[57].feg[0].cnl[5] = 0.0000000000; + data_table[58].feg[0].cl[0] = 0.0000000000; data_table[58].feg[0].cnl[0] = 0.0000000000; data_table[58].feg[0].cl[1] = 0.0000000000; data_table[58].feg[0].cnl[1] = 0.0000000000; data_table[58].feg[0].cl[2] = 0.0000000000; data_table[58].feg[0].cnl[2] = 0.0000000000; data_table[58].feg[0].cl[3] = 0.0000000000; data_table[58].feg[0].cnl[3] = 0.0000000000; data_table[58].feg[0].cl[4] = 0.0000000000; data_table[58].feg[0].cnl[4] = 0.0000000000; data_table[58].feg[0].cl[5] = 0.0000000000; data_table[58].feg[0].cnl[5] = 0.0000000000; + data_table[59].feg[0].cl[0] = 0.0000000000; data_table[59].feg[0].cnl[0] = 0.0000000000; data_table[59].feg[0].cl[1] = 0.0000000000; data_table[59].feg[0].cnl[1] = 0.0000000000; data_table[59].feg[0].cl[2] = 0.0000000000; data_table[59].feg[0].cnl[2] = 0.0000000000; data_table[59].feg[0].cl[3] = 0.0000000000; data_table[59].feg[0].cnl[3] = 0.0000000000; data_table[59].feg[0].cl[4] = 0.0000000000; data_table[59].feg[0].cnl[4] = 0.0000000000; data_table[59].feg[0].cl[5] = 0.0000000000; data_table[59].feg[0].cnl[5] = 0.0000000000; + data_table[60].feg[0].cl[0] = 0.0000000000; data_table[60].feg[0].cnl[0] = 0.0000000000; data_table[60].feg[0].cl[1] = 0.0000000000; data_table[60].feg[0].cnl[1] = 0.0000000000; data_table[60].feg[0].cl[2] = 0.0000000000; data_table[60].feg[0].cnl[2] = 0.0000000000; data_table[60].feg[0].cl[3] = 0.0000000000; data_table[60].feg[0].cnl[3] = 0.0000000000; data_table[60].feg[0].cl[4] = 0.0000000000; data_table[60].feg[0].cnl[4] = 0.0000000000; data_table[60].feg[0].cl[5] = 0.0000000000; data_table[60].feg[0].cnl[5] = 0.0000000000; + data_table[61].feg[0].cl[0] = 0.0000000000; data_table[61].feg[0].cnl[0] = 0.0000000000; data_table[61].feg[0].cl[1] = 0.0000000000; data_table[61].feg[0].cnl[1] = 0.0000000000; data_table[61].feg[0].cl[2] = 0.0000000000; data_table[61].feg[0].cnl[2] = 0.0000000000; data_table[61].feg[0].cl[3] = 0.0000000000; data_table[61].feg[0].cnl[3] = 0.0000000000; data_table[61].feg[0].cl[4] = 0.0000000000; data_table[61].feg[0].cnl[4] = 0.0000000000; data_table[61].feg[0].cl[5] = 0.0000000000; data_table[61].feg[0].cnl[5] = 0.0000000000; + data_table[62].feg[0].cl[0] = 0.0000000000; data_table[62].feg[0].cnl[0] = 0.0000000000; data_table[62].feg[0].cl[1] = 0.0000000000; data_table[62].feg[0].cnl[1] = 0.0000000000; data_table[62].feg[0].cl[2] = 0.0000000000; data_table[62].feg[0].cnl[2] = 0.0000000000; data_table[62].feg[0].cl[3] = 0.0000000000; data_table[62].feg[0].cnl[3] = 0.0000000000; data_table[62].feg[0].cl[4] = 0.0000000000; data_table[62].feg[0].cnl[4] = 0.0000000000; data_table[62].feg[0].cl[5] = 0.0000000000; data_table[62].feg[0].cnl[5] = 0.0000000000; + data_table[63].feg[0].cl[0] = 0.0000000000; data_table[63].feg[0].cnl[0] = 0.0000000000; data_table[63].feg[0].cl[1] = 0.0000000000; data_table[63].feg[0].cnl[1] = 0.0000000000; data_table[63].feg[0].cl[2] = 0.0000000000; data_table[63].feg[0].cnl[2] = 0.0000000000; data_table[63].feg[0].cl[3] = 0.0000000000; data_table[63].feg[0].cnl[3] = 0.0000000000; data_table[63].feg[0].cl[4] = 0.0000000000; data_table[63].feg[0].cnl[4] = 0.0000000000; data_table[63].feg[0].cl[5] = 0.0000000000; data_table[63].feg[0].cnl[5] = 0.0000000000; + data_table[64].feg[0].cl[0] = 0.0000000000; data_table[64].feg[0].cnl[0] = 0.0000000000; data_table[64].feg[0].cl[1] = 0.0000000000; data_table[64].feg[0].cnl[1] = 0.0000000000; data_table[64].feg[0].cl[2] = 0.0000000000; data_table[64].feg[0].cnl[2] = 0.0000000000; data_table[64].feg[0].cl[3] = 0.0000000000; data_table[64].feg[0].cnl[3] = 0.0000000000; data_table[64].feg[0].cl[4] = 0.0000000000; data_table[64].feg[0].cnl[4] = 0.0000000000; data_table[64].feg[0].cl[5] = 0.0000000000; data_table[64].feg[0].cnl[5] = 0.0000000000; + data_table[65].feg[0].cl[0] = 0.0000000000; data_table[65].feg[0].cnl[0] = 0.0000000000; data_table[65].feg[0].cl[1] = 0.0000000000; data_table[65].feg[0].cnl[1] = 0.0000000000; data_table[65].feg[0].cl[2] = 0.0000000000; data_table[65].feg[0].cnl[2] = 0.0000000000; data_table[65].feg[0].cl[3] = 0.0000000000; data_table[65].feg[0].cnl[3] = 0.0000000000; data_table[65].feg[0].cl[4] = 0.0000000000; data_table[65].feg[0].cnl[4] = 0.0000000000; data_table[65].feg[0].cl[5] = 0.0000000000; data_table[65].feg[0].cnl[5] = 0.0000000000; + data_table[66].feg[0].cl[0] = 0.0000000000; data_table[66].feg[0].cnl[0] = 0.0000000000; data_table[66].feg[0].cl[1] = 0.0000000000; data_table[66].feg[0].cnl[1] = 0.0000000000; data_table[66].feg[0].cl[2] = 0.0000000000; data_table[66].feg[0].cnl[2] = 0.0000000000; data_table[66].feg[0].cl[3] = 0.0000000000; data_table[66].feg[0].cnl[3] = 0.0000000000; data_table[66].feg[0].cl[4] = 0.0000000000; data_table[66].feg[0].cnl[4] = 0.0000000000; data_table[66].feg[0].cl[5] = 0.0000000000; data_table[66].feg[0].cnl[5] = 0.0000000000; + data_table[67].feg[0].cl[0] = 0.0000000000; data_table[67].feg[0].cnl[0] = 0.0000000000; data_table[67].feg[0].cl[1] = 0.0000000000; data_table[67].feg[0].cnl[1] = 0.0000000000; data_table[67].feg[0].cl[2] = 0.0000000000; data_table[67].feg[0].cnl[2] = 0.0000000000; data_table[67].feg[0].cl[3] = 0.0000000000; data_table[67].feg[0].cnl[3] = 0.0000000000; data_table[67].feg[0].cl[4] = 0.0000000000; data_table[67].feg[0].cnl[4] = 0.0000000000; data_table[67].feg[0].cl[5] = 0.0000000000; data_table[67].feg[0].cnl[5] = 0.0000000000; + data_table[68].feg[0].cl[0] = 0.0000000000; data_table[68].feg[0].cnl[0] = 0.0000000000; data_table[68].feg[0].cl[1] = 0.0000000000; data_table[68].feg[0].cnl[1] = 0.0000000000; data_table[68].feg[0].cl[2] = 0.0000000000; data_table[68].feg[0].cnl[2] = 0.0000000000; data_table[68].feg[0].cl[3] = 0.0000000000; data_table[68].feg[0].cnl[3] = 0.0000000000; data_table[68].feg[0].cl[4] = 0.0000000000; data_table[68].feg[0].cnl[4] = 0.0000000000; data_table[68].feg[0].cl[5] = 0.0000000000; data_table[68].feg[0].cnl[5] = 0.0000000000; + data_table[69].feg[0].cl[0] = 0.0000000000; data_table[69].feg[0].cnl[0] = 0.0000000000; data_table[69].feg[0].cl[1] = 0.0000000000; data_table[69].feg[0].cnl[1] = 0.0000000000; data_table[69].feg[0].cl[2] = 0.0000000000; data_table[69].feg[0].cnl[2] = 0.0000000000; data_table[69].feg[0].cl[3] = 0.0000000000; data_table[69].feg[0].cnl[3] = 0.0000000000; data_table[69].feg[0].cl[4] = 0.0000000000; data_table[69].feg[0].cnl[4] = 0.0000000000; data_table[69].feg[0].cl[5] = 0.0000000000; data_table[69].feg[0].cnl[5] = 0.0000000000; + data_table[70].feg[0].cl[0] = 0.0000000000; data_table[70].feg[0].cnl[0] = 0.0000000000; data_table[70].feg[0].cl[1] = 0.0000000000; data_table[70].feg[0].cnl[1] = 0.0000000000; data_table[70].feg[0].cl[2] = 0.0000000000; data_table[70].feg[0].cnl[2] = 0.0000000000; data_table[70].feg[0].cl[3] = 0.0000000000; data_table[70].feg[0].cnl[3] = 0.0000000000; data_table[70].feg[0].cl[4] = 0.0000000000; data_table[70].feg[0].cnl[4] = 0.0000000000; data_table[70].feg[0].cl[5] = 0.0000000000; data_table[70].feg[0].cnl[5] = 0.0000000000; + data_table[71].feg[0].cl[0] = 0.0000000000; data_table[71].feg[0].cnl[0] = 0.0000000000; data_table[71].feg[0].cl[1] = 0.0000000000; data_table[71].feg[0].cnl[1] = 0.0000000000; data_table[71].feg[0].cl[2] = 0.0000000000; data_table[71].feg[0].cnl[2] = 0.0000000000; data_table[71].feg[0].cl[3] = 0.0000000000; data_table[71].feg[0].cnl[3] = 0.0000000000; data_table[71].feg[0].cl[4] = 0.0000000000; data_table[71].feg[0].cnl[4] = 0.0000000000; data_table[71].feg[0].cl[5] = 0.0000000000; data_table[71].feg[0].cnl[5] = 0.0000000000; + data_table[72].feg[0].cl[0] = 0.0000000000; data_table[72].feg[0].cnl[0] = 0.0000000000; data_table[72].feg[0].cl[1] = 0.0000000000; data_table[72].feg[0].cnl[1] = 0.0000000000; data_table[72].feg[0].cl[2] = 0.0000000000; data_table[72].feg[0].cnl[2] = 0.0000000000; data_table[72].feg[0].cl[3] = 0.0000000000; data_table[72].feg[0].cnl[3] = 0.0000000000; data_table[72].feg[0].cl[4] = 0.0000000000; data_table[72].feg[0].cnl[4] = 0.0000000000; data_table[72].feg[0].cl[5] = 0.0000000000; data_table[72].feg[0].cnl[5] = 0.0000000000; + data_table[73].feg[0].cl[0] = 0.0000000000; data_table[73].feg[0].cnl[0] = 0.0000000000; data_table[73].feg[0].cl[1] = 0.0000000000; data_table[73].feg[0].cnl[1] = 0.0000000000; data_table[73].feg[0].cl[2] = 0.0000000000; data_table[73].feg[0].cnl[2] = 0.0000000000; data_table[73].feg[0].cl[3] = 0.0000000000; data_table[73].feg[0].cnl[3] = 0.0000000000; data_table[73].feg[0].cl[4] = 0.0000000000; data_table[73].feg[0].cnl[4] = 0.0000000000; data_table[73].feg[0].cl[5] = 0.0000000000; data_table[73].feg[0].cnl[5] = 0.0000000000; + data_table[74].feg[0].cl[0] = 0.0000000000; data_table[74].feg[0].cnl[0] = 0.0000000000; data_table[74].feg[0].cl[1] = 0.0000000000; data_table[74].feg[0].cnl[1] = 0.0000000000; data_table[74].feg[0].cl[2] = 0.0000000000; data_table[74].feg[0].cnl[2] = 0.0000000000; data_table[74].feg[0].cl[3] = 0.0000000000; data_table[74].feg[0].cnl[3] = 0.0000000000; data_table[74].feg[0].cl[4] = 0.0000000000; data_table[74].feg[0].cnl[4] = 0.0000000000; data_table[74].feg[0].cl[5] = 0.0000000000; data_table[74].feg[0].cnl[5] = 0.0000000000; + data_table[75].feg[0].cl[0] = 0.0000000000; data_table[75].feg[0].cnl[0] = 0.0000000000; data_table[75].feg[0].cl[1] = 0.0000000000; data_table[75].feg[0].cnl[1] = 0.0000000000; data_table[75].feg[0].cl[2] = 0.0000000000; data_table[75].feg[0].cnl[2] = 0.0000000000; data_table[75].feg[0].cl[3] = 0.0000000000; data_table[75].feg[0].cnl[3] = 0.0000000000; data_table[75].feg[0].cl[4] = 0.0000000000; data_table[75].feg[0].cnl[4] = 0.0000000000; data_table[75].feg[0].cl[5] = 0.0000000000; data_table[75].feg[0].cnl[5] = 0.0000000000; + data_table[76].feg[0].cl[0] = 0.0000000000; data_table[76].feg[0].cnl[0] = 0.0000000000; data_table[76].feg[0].cl[1] = 0.0000000000; data_table[76].feg[0].cnl[1] = 0.0000000000; data_table[76].feg[0].cl[2] = 0.0000000000; data_table[76].feg[0].cnl[2] = 0.0000000000; data_table[76].feg[0].cl[3] = 0.0000000000; data_table[76].feg[0].cnl[3] = 0.0000000000; data_table[76].feg[0].cl[4] = 0.0000000000; data_table[76].feg[0].cnl[4] = 0.0000000000; data_table[76].feg[0].cl[5] = 0.0000000000; data_table[76].feg[0].cnl[5] = 0.0000000000; + data_table[77].feg[0].cl[0] = 0.0000000000; data_table[77].feg[0].cnl[0] = 0.0000000000; data_table[77].feg[0].cl[1] = 0.0000000000; data_table[77].feg[0].cnl[1] = 0.0000000000; data_table[77].feg[0].cl[2] = 0.0000000000; data_table[77].feg[0].cnl[2] = 0.0000000000; data_table[77].feg[0].cl[3] = 0.0000000000; data_table[77].feg[0].cnl[3] = 0.0000000000; data_table[77].feg[0].cl[4] = 0.0000000000; data_table[77].feg[0].cnl[4] = 0.0000000000; data_table[77].feg[0].cl[5] = 0.0000000000; data_table[77].feg[0].cnl[5] = 0.0000000000; + data_table[78].feg[0].cl[0] = 2.3880000000; data_table[78].feg[0].cnl[0] = 42.8656000000; data_table[78].feg[0].cl[1] = 4.2259000000; data_table[78].feg[0].cnl[1] = 9.7430000000; data_table[78].feg[0].cl[2] = 2.6886000000; data_table[78].feg[0].cnl[2] = 2.2641000000; data_table[78].feg[0].cl[3] = 1.2551000000; data_table[78].feg[0].cnl[3] = 0.3067000000; data_table[78].feg[0].cl[4] = 0.0000000000; data_table[78].feg[0].cnl[4] = 0.0000000000; data_table[78].feg[0].cl[5] = 0.0000000000; data_table[78].feg[0].cnl[5] = 0.0000000000; + data_table[79].feg[0].cl[0] = 2.6817000000; data_table[79].feg[0].cnl[0] = 42.8217000000; data_table[79].feg[0].cl[1] = 4.2414000000; data_table[79].feg[0].cnl[1] = 9.8557000000; data_table[79].feg[0].cl[2] = 2.7549000000; data_table[79].feg[0].cnl[2] = 2.2951000000; data_table[79].feg[0].cl[3] = 1.2706000000; data_table[79].feg[0].cnl[3] = 0.3067000000; data_table[79].feg[0].cl[4] = 0.0000000000; data_table[79].feg[0].cnl[4] = 0.0000000000; data_table[79].feg[0].cl[5] = 0.0000000000; data_table[79].feg[0].cnl[5] = 0.0000000000; + data_table[80].feg[0].cl[0] = 0.0000000000; data_table[80].feg[0].cnl[0] = 0.0000000000; data_table[80].feg[0].cl[1] = 0.0000000000; data_table[80].feg[0].cnl[1] = 0.0000000000; data_table[80].feg[0].cl[2] = 0.0000000000; data_table[80].feg[0].cnl[2] = 0.0000000000; data_table[80].feg[0].cl[3] = 0.0000000000; data_table[80].feg[0].cnl[3] = 0.0000000000; data_table[80].feg[0].cl[4] = 0.0000000000; data_table[80].feg[0].cnl[4] = 0.0000000000; data_table[80].feg[0].cl[5] = 0.0000000000; data_table[80].feg[0].cnl[5] = 0.0000000000; + data_table[81].feg[0].cl[0] = 3.5099000000; data_table[81].feg[0].cnl[0] = 52.9141000000; data_table[81].feg[0].cl[1] = 4.5523000000; data_table[81].feg[0].cnl[1] = 11.8840000000; data_table[81].feg[0].cl[2] = 3.1539000000; data_table[81].feg[0].cnl[2] = 2.5713000000; data_table[81].feg[0].cl[3] = 1.3591000000; data_table[81].feg[0].cnl[3] = 0.3205000000; data_table[81].feg[0].cl[4] = 0.0000000000; data_table[81].feg[0].cnl[4] = 0.0000000000; data_table[81].feg[0].cl[5] = 0.0000000000; data_table[81].feg[0].cnl[5] = 0.0000000000; + data_table[82].feg[0].cl[0] = 3.8412000000; data_table[82].feg[0].cnl[0] = 50.2608000000; data_table[82].feg[0].cl[1] = 4.6784000000; data_table[82].feg[0].cnl[1] = 11.9988000000; data_table[82].feg[0].cl[2] = 3.1924000000; data_table[82].feg[0].cnl[2] = 2.5598000000; data_table[82].feg[0].cl[3] = 1.3625000000; data_table[82].feg[0].cnl[3] = 0.3177000000; data_table[82].feg[0].cl[4] = 0.0000000000; data_table[82].feg[0].cnl[4] = 0.0000000000; data_table[82].feg[0].cl[5] = 0.0000000000; data_table[82].feg[0].cnl[5] = 0.0000000000; + data_table[83].feg[0].cl[0] = 0.0000000000; data_table[83].feg[0].cnl[0] = 0.0000000000; data_table[83].feg[0].cl[1] = 0.0000000000; data_table[83].feg[0].cnl[1] = 0.0000000000; data_table[83].feg[0].cl[2] = 0.0000000000; data_table[83].feg[0].cnl[2] = 0.0000000000; data_table[83].feg[0].cl[3] = 0.0000000000; data_table[83].feg[0].cnl[3] = 0.0000000000; data_table[83].feg[0].cl[4] = 0.0000000000; data_table[83].feg[0].cnl[4] = 0.0000000000; data_table[83].feg[0].cl[5] = 0.0000000000; data_table[83].feg[0].cnl[5] = 0.0000000000; + data_table[84].feg[0].cl[0] = 0.0000000000; data_table[84].feg[0].cnl[0] = 0.0000000000; data_table[84].feg[0].cl[1] = 0.0000000000; data_table[84].feg[0].cnl[1] = 0.0000000000; data_table[84].feg[0].cl[2] = 0.0000000000; data_table[84].feg[0].cnl[2] = 0.0000000000; data_table[84].feg[0].cl[3] = 0.0000000000; data_table[84].feg[0].cnl[3] = 0.0000000000; data_table[84].feg[0].cl[4] = 0.0000000000; data_table[84].feg[0].cnl[4] = 0.0000000000; data_table[84].feg[0].cl[5] = 0.0000000000; data_table[84].feg[0].cnl[5] = 0.0000000000; + data_table[85].feg[0].cl[0] = 4.0779000000; data_table[85].feg[0].cnl[0] = 28.4058000000; data_table[85].feg[0].cl[1] = 4.9778000000; data_table[85].feg[0].cnl[1] = 11.0204000000; data_table[85].feg[0].cl[2] = 3.0955000000; data_table[85].feg[0].cnl[2] = 2.3549000000; data_table[85].feg[0].cl[3] = 1.3259000000; data_table[85].feg[0].cnl[3] = 0.2991000000; data_table[85].feg[0].cl[4] = 0.0000000000; data_table[85].feg[0].cnl[4] = 0.0000000000; data_table[85].feg[0].cl[5] = 0.0000000000; data_table[85].feg[0].cnl[5] = 0.0000000000; + data_table[86].feg[0].cl[0] = 0.0000000000; data_table[86].feg[0].cnl[0] = 0.0000000000; data_table[86].feg[0].cl[1] = 0.0000000000; data_table[86].feg[0].cnl[1] = 0.0000000000; data_table[86].feg[0].cl[2] = 0.0000000000; data_table[86].feg[0].cnl[2] = 0.0000000000; data_table[86].feg[0].cl[3] = 0.0000000000; data_table[86].feg[0].cnl[3] = 0.0000000000; data_table[86].feg[0].cl[4] = 0.0000000000; data_table[86].feg[0].cnl[4] = 0.0000000000; data_table[86].feg[0].cl[5] = 0.0000000000; data_table[86].feg[0].cnl[5] = 0.0000000000; + data_table[87].feg[0].cl[0] = 0.0000000000; data_table[87].feg[0].cnl[0] = 0.0000000000; data_table[87].feg[0].cl[1] = 0.0000000000; data_table[87].feg[0].cnl[1] = 0.0000000000; data_table[87].feg[0].cl[2] = 0.0000000000; data_table[87].feg[0].cnl[2] = 0.0000000000; data_table[87].feg[0].cl[3] = 0.0000000000; data_table[87].feg[0].cnl[3] = 0.0000000000; data_table[87].feg[0].cl[4] = 0.0000000000; data_table[87].feg[0].cnl[4] = 0.0000000000; data_table[87].feg[0].cl[5] = 0.0000000000; data_table[87].feg[0].cnl[5] = 0.0000000000; + data_table[88].feg[0].cl[0] = 0.0000000000; data_table[88].feg[0].cnl[0] = 0.0000000000; data_table[88].feg[0].cl[1] = 0.0000000000; data_table[88].feg[0].cnl[1] = 0.0000000000; data_table[88].feg[0].cl[2] = 0.0000000000; data_table[88].feg[0].cnl[2] = 0.0000000000; data_table[88].feg[0].cl[3] = 0.0000000000; data_table[88].feg[0].cnl[3] = 0.0000000000; data_table[88].feg[0].cl[4] = 0.0000000000; data_table[88].feg[0].cnl[4] = 0.0000000000; data_table[88].feg[0].cl[5] = 0.0000000000; data_table[88].feg[0].cnl[5] = 0.0000000000; + data_table[89].feg[0].cl[0] = 0.0000000000; data_table[89].feg[0].cnl[0] = 0.0000000000; data_table[89].feg[0].cl[1] = 0.0000000000; data_table[89].feg[0].cnl[1] = 0.0000000000; data_table[89].feg[0].cl[2] = 0.0000000000; data_table[89].feg[0].cnl[2] = 0.0000000000; data_table[89].feg[0].cl[3] = 0.0000000000; data_table[89].feg[0].cnl[3] = 0.0000000000; data_table[89].feg[0].cl[4] = 0.0000000000; data_table[89].feg[0].cnl[4] = 0.0000000000; data_table[89].feg[0].cl[5] = 0.0000000000; data_table[89].feg[0].cnl[5] = 0.0000000000; + data_table[90].feg[0].cl[0] = 0.0000000000; data_table[90].feg[0].cnl[0] = 0.0000000000; data_table[90].feg[0].cl[1] = 0.0000000000; data_table[90].feg[0].cnl[1] = 0.0000000000; data_table[90].feg[0].cl[2] = 0.0000000000; data_table[90].feg[0].cnl[2] = 0.0000000000; data_table[90].feg[0].cl[3] = 0.0000000000; data_table[90].feg[0].cnl[3] = 0.0000000000; data_table[90].feg[0].cl[4] = 0.0000000000; data_table[90].feg[0].cnl[4] = 0.0000000000; data_table[90].feg[0].cl[5] = 0.0000000000; data_table[90].feg[0].cnl[5] = 0.0000000000; + data_table[91].feg[0].cl[0] = 6.7668000000; data_table[91].feg[0].cnl[0] = 85.9510000000; data_table[91].feg[0].cl[1] = 6.7287000000; data_table[91].feg[0].cnl[1] = 15.6415000000; data_table[91].feg[0].cl[2] = 4.0135000000; data_table[91].feg[0].cnl[2] = 2.9364000000; data_table[91].feg[0].cl[3] = 1.5607000000; data_table[91].feg[0].cnl[3] = 0.3348000000; data_table[91].feg[0].cl[4] = 0.0000000000; data_table[91].feg[0].cnl[4] = 0.0000000000; data_table[91].feg[0].cl[5] = 0.0000000000; data_table[91].feg[0].cnl[5] = 0.0000000000; + data_table[92].feg[0].cl[0] = 0.0000000000; data_table[92].feg[0].cnl[0] = 0.0000000000; data_table[92].feg[0].cl[1] = 0.0000000000; data_table[92].feg[0].cnl[1] = 0.0000000000; data_table[92].feg[0].cl[2] = 0.0000000000; data_table[92].feg[0].cnl[2] = 0.0000000000; data_table[92].feg[0].cl[3] = 0.0000000000; data_table[92].feg[0].cnl[3] = 0.0000000000; data_table[92].feg[0].cl[4] = 0.0000000000; data_table[92].feg[0].cnl[4] = 0.0000000000; data_table[92].feg[0].cl[5] = 0.0000000000; data_table[92].feg[0].cnl[5] = 0.0000000000; + data_table[93].feg[0].cl[0] = 0.0000000000; data_table[93].feg[0].cnl[0] = 0.0000000000; data_table[93].feg[0].cl[1] = 0.0000000000; data_table[93].feg[0].cnl[1] = 0.0000000000; data_table[93].feg[0].cl[2] = 0.0000000000; data_table[93].feg[0].cnl[2] = 0.0000000000; data_table[93].feg[0].cl[3] = 0.0000000000; data_table[93].feg[0].cnl[3] = 0.0000000000; data_table[93].feg[0].cl[4] = 0.0000000000; data_table[93].feg[0].cnl[4] = 0.0000000000; data_table[93].feg[0].cl[5] = 0.0000000000; data_table[93].feg[0].cnl[5] = 0.0000000000; + data_table[94].feg[0].cl[0] = 0.0000000000; data_table[94].feg[0].cnl[0] = 0.0000000000; data_table[94].feg[0].cl[1] = 0.0000000000; data_table[94].feg[0].cnl[1] = 0.0000000000; data_table[94].feg[0].cl[2] = 0.0000000000; data_table[94].feg[0].cnl[2] = 0.0000000000; data_table[94].feg[0].cl[3] = 0.0000000000; data_table[94].feg[0].cnl[3] = 0.0000000000; data_table[94].feg[0].cl[4] = 0.0000000000; data_table[94].feg[0].cnl[4] = 0.0000000000; data_table[94].feg[0].cl[5] = 0.0000000000; data_table[94].feg[0].cnl[5] = 0.0000000000; + data_table[95].feg[0].cl[0] = 0.0000000000; data_table[95].feg[0].cnl[0] = 0.0000000000; data_table[95].feg[0].cl[1] = 0.0000000000; data_table[95].feg[0].cnl[1] = 0.0000000000; data_table[95].feg[0].cl[2] = 0.0000000000; data_table[95].feg[0].cnl[2] = 0.0000000000; data_table[95].feg[0].cl[3] = 0.0000000000; data_table[95].feg[0].cnl[3] = 0.0000000000; data_table[95].feg[0].cl[4] = 0.0000000000; data_table[95].feg[0].cnl[4] = 0.0000000000; data_table[95].feg[0].cl[5] = 0.0000000000; data_table[95].feg[0].cnl[5] = 0.0000000000; + data_table[96].feg[0].cl[0] = 0.0000000000; data_table[96].feg[0].cnl[0] = 0.0000000000; data_table[96].feg[0].cl[1] = 0.0000000000; data_table[96].feg[0].cnl[1] = 0.0000000000; data_table[96].feg[0].cl[2] = 0.0000000000; data_table[96].feg[0].cnl[2] = 0.0000000000; data_table[96].feg[0].cl[3] = 0.0000000000; data_table[96].feg[0].cnl[3] = 0.0000000000; data_table[96].feg[0].cl[4] = 0.0000000000; data_table[96].feg[0].cnl[4] = 0.0000000000; data_table[96].feg[0].cl[5] = 0.0000000000; data_table[96].feg[0].cnl[5] = 0.0000000000; + data_table[97].feg[0].cl[0] = 0.0000000000; data_table[97].feg[0].cnl[0] = 0.0000000000; data_table[97].feg[0].cl[1] = 0.0000000000; data_table[97].feg[0].cnl[1] = 0.0000000000; data_table[97].feg[0].cl[2] = 0.0000000000; data_table[97].feg[0].cnl[2] = 0.0000000000; data_table[97].feg[0].cl[3] = 0.0000000000; data_table[97].feg[0].cnl[3] = 0.0000000000; data_table[97].feg[0].cl[4] = 0.0000000000; data_table[97].feg[0].cnl[4] = 0.0000000000; data_table[97].feg[0].cl[5] = 0.0000000000; data_table[97].feg[0].cnl[5] = 0.0000000000; + data_table[98].feg[0].cl[0] = 0.0000000000; data_table[98].feg[0].cnl[0] = 0.0000000000; data_table[98].feg[0].cl[1] = 0.0000000000; data_table[98].feg[0].cnl[1] = 0.0000000000; data_table[98].feg[0].cl[2] = 0.0000000000; data_table[98].feg[0].cnl[2] = 0.0000000000; data_table[98].feg[0].cl[3] = 0.0000000000; data_table[98].feg[0].cnl[3] = 0.0000000000; data_table[98].feg[0].cl[4] = 0.0000000000; data_table[98].feg[0].cnl[4] = 0.0000000000; data_table[98].feg[0].cl[5] = 0.0000000000; data_table[98].feg[0].cnl[5] = 0.0000000000; + data_table[99].feg[0].cl[0] = 0.0000000000; data_table[99].feg[0].cnl[0] = 0.0000000000; data_table[99].feg[0].cl[1] = 0.0000000000; data_table[99].feg[0].cnl[1] = 0.0000000000; data_table[99].feg[0].cl[2] = 0.0000000000; data_table[99].feg[0].cnl[2] = 0.0000000000; data_table[99].feg[0].cl[3] = 0.0000000000; data_table[99].feg[0].cnl[3] = 0.0000000000; data_table[99].feg[0].cl[4] = 0.0000000000; data_table[99].feg[0].cnl[4] = 0.0000000000; data_table[99].feg[0].cl[5] = 0.0000000000; data_table[99].feg[0].cnl[5] = 0.0000000000; + data_table[100].feg[0].cl[0] = 0.0000000000; data_table[100].feg[0].cnl[0] = 0.0000000000; data_table[100].feg[0].cl[1] = 0.0000000000; data_table[100].feg[0].cnl[1] = 0.0000000000; data_table[100].feg[0].cl[2] = 0.0000000000; data_table[100].feg[0].cnl[2] = 0.0000000000; data_table[100].feg[0].cl[3] = 0.0000000000; data_table[100].feg[0].cnl[3] = 0.0000000000; data_table[100].feg[0].cl[4] = 0.0000000000; data_table[100].feg[0].cnl[4] = 0.0000000000; data_table[100].feg[0].cl[5] = 0.0000000000; data_table[100].feg[0].cnl[5] = 0.0000000000; + data_table[101].feg[0].cl[0] = 0.0000000000; data_table[101].feg[0].cnl[0] = 0.0000000000; data_table[101].feg[0].cl[1] = 0.0000000000; data_table[101].feg[0].cnl[1] = 0.0000000000; data_table[101].feg[0].cl[2] = 0.0000000000; data_table[101].feg[0].cnl[2] = 0.0000000000; data_table[101].feg[0].cl[3] = 0.0000000000; data_table[101].feg[0].cnl[3] = 0.0000000000; data_table[101].feg[0].cl[4] = 0.0000000000; data_table[101].feg[0].cnl[4] = 0.0000000000; data_table[101].feg[0].cl[5] = 0.0000000000; data_table[101].feg[0].cnl[5] = 0.0000000000; + data_table[102].feg[0].cl[0] = 0.0000000000; data_table[102].feg[0].cnl[0] = 0.0000000000; data_table[102].feg[0].cl[1] = 0.0000000000; data_table[102].feg[0].cnl[1] = 0.0000000000; data_table[102].feg[0].cl[2] = 0.0000000000; data_table[102].feg[0].cnl[2] = 0.0000000000; data_table[102].feg[0].cl[3] = 0.0000000000; data_table[102].feg[0].cnl[3] = 0.0000000000; data_table[102].feg[0].cl[4] = 0.0000000000; data_table[102].feg[0].cnl[4] = 0.0000000000; data_table[102].feg[0].cl[5] = 0.0000000000; data_table[102].feg[0].cnl[5] = 0.0000000000; + } + + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + void Load_feg_Peng_neutral_0_4() + { + data_table[0].feg[0].cl[0] = 0.0349000000; data_table[0].feg[0].cnl[0] = 0.5347000000; data_table[0].feg[0].cl[1] = 0.1201000000; data_table[0].feg[0].cnl[1] = 3.5867000000; data_table[0].feg[0].cl[2] = 0.1970000000; data_table[0].feg[0].cnl[2] = 12.3471000000; data_table[0].feg[0].cl[3] = 0.0573000000; data_table[0].feg[0].cnl[3] = 18.9525000000; data_table[0].feg[0].cl[4] = 0.1195000000; data_table[0].feg[0].cnl[4] = 38.6269000000; data_table[0].feg[0].cl[5] = 0.0000000000; data_table[0].feg[0].cnl[5] = 0.0000000000; + data_table[1].feg[0].cl[0] = 0.0317000000; data_table[1].feg[0].cnl[0] = 0.2507000000; data_table[1].feg[0].cl[1] = 0.0838000000; data_table[1].feg[0].cnl[1] = 1.4751000000; data_table[1].feg[0].cl[2] = 0.1526000000; data_table[1].feg[0].cnl[2] = 4.4938000000; data_table[1].feg[0].cl[3] = 0.1334000000; data_table[1].feg[0].cnl[3] = 12.6646000000; data_table[1].feg[0].cl[4] = 0.0164000000; data_table[1].feg[0].cnl[4] = 31.1653000000; data_table[1].feg[0].cl[5] = 0.0000000000; data_table[1].feg[0].cnl[5] = 0.0000000000; + data_table[2].feg[0].cl[0] = 0.0750000000; data_table[2].feg[0].cnl[0] = 0.3864000000; data_table[2].feg[0].cl[1] = 0.2249000000; data_table[2].feg[0].cnl[1] = 2.9383000000; data_table[2].feg[0].cl[2] = 0.5548000000; data_table[2].feg[0].cnl[2] = 15.3829000000; data_table[2].feg[0].cl[3] = 1.4954000000; data_table[2].feg[0].cnl[3] = 53.5545000000; data_table[2].feg[0].cl[4] = 0.9354000000; data_table[2].feg[0].cnl[4] = 138.7337000000; data_table[2].feg[0].cl[5] = 0.0000000000; data_table[2].feg[0].cnl[5] = 0.0000000000; + data_table[3].feg[0].cl[0] = 0.0780000000; data_table[3].feg[0].cnl[0] = 0.3131000000; data_table[3].feg[0].cl[1] = 0.2210000000; data_table[3].feg[0].cnl[1] = 2.2381000000; data_table[3].feg[0].cl[2] = 0.6740000000; data_table[3].feg[0].cnl[2] = 10.1517000000; data_table[3].feg[0].cl[3] = 1.3867000000; data_table[3].feg[0].cnl[3] = 30.9061000000; data_table[3].feg[0].cl[4] = 0.6925000000; data_table[3].feg[0].cnl[4] = 78.3273000000; data_table[3].feg[0].cl[5] = 0.0000000000; data_table[3].feg[0].cnl[5] = 0.0000000000; + data_table[4].feg[0].cl[0] = 0.0909000000; data_table[4].feg[0].cnl[0] = 0.2995000000; data_table[4].feg[0].cl[1] = 0.2551000000; data_table[4].feg[0].cnl[1] = 2.1155000000; data_table[4].feg[0].cl[2] = 0.7738000000; data_table[4].feg[0].cnl[2] = 8.3816000000; data_table[4].feg[0].cl[3] = 1.2136000000; data_table[4].feg[0].cnl[3] = 24.1292000000; data_table[4].feg[0].cl[4] = 0.4606000000; data_table[4].feg[0].cnl[4] = 63.1314000000; data_table[4].feg[0].cl[5] = 0.0000000000; data_table[4].feg[0].cnl[5] = 0.0000000000; + data_table[5].feg[0].cl[0] = 0.0893000000; data_table[5].feg[0].cnl[0] = 0.2465000000; data_table[5].feg[0].cl[1] = 0.2563000000; data_table[5].feg[0].cnl[1] = 1.7100000000; data_table[5].feg[0].cl[2] = 0.7570000000; data_table[5].feg[0].cnl[2] = 6.4094000000; data_table[5].feg[0].cl[3] = 1.0487000000; data_table[5].feg[0].cnl[3] = 18.6113000000; data_table[5].feg[0].cl[4] = 0.3575000000; data_table[5].feg[0].cnl[4] = 50.2523000000; data_table[5].feg[0].cl[5] = 0.0000000000; data_table[5].feg[0].cnl[5] = 0.0000000000; + data_table[6].feg[0].cl[0] = 0.1022000000; data_table[6].feg[0].cnl[0] = 0.2451000000; data_table[6].feg[0].cl[1] = 0.3219000000; data_table[6].feg[0].cnl[1] = 1.7481000000; data_table[6].feg[0].cl[2] = 0.7982000000; data_table[6].feg[0].cnl[2] = 6.1925000000; data_table[6].feg[0].cl[3] = 0.8197000000; data_table[6].feg[0].cnl[3] = 17.3894000000; data_table[6].feg[0].cl[4] = 0.1715000000; data_table[6].feg[0].cnl[4] = 48.1431000000; data_table[6].feg[0].cl[5] = 0.0000000000; data_table[6].feg[0].cnl[5] = 0.0000000000; + data_table[7].feg[0].cl[0] = 0.0974000000; data_table[7].feg[0].cnl[0] = 0.2067000000; data_table[7].feg[0].cl[1] = 0.2921000000; data_table[7].feg[0].cnl[1] = 1.3815000000; data_table[7].feg[0].cl[2] = 0.6910000000; data_table[7].feg[0].cnl[2] = 4.6943000000; data_table[7].feg[0].cl[3] = 0.6990000000; data_table[7].feg[0].cnl[3] = 12.7105000000; data_table[7].feg[0].cl[4] = 0.2039000000; data_table[7].feg[0].cnl[4] = 32.4726000000; data_table[7].feg[0].cl[5] = 0.0000000000; data_table[7].feg[0].cnl[5] = 0.0000000000; + data_table[8].feg[0].cl[0] = 0.1083000000; data_table[8].feg[0].cnl[0] = 0.2057000000; data_table[8].feg[0].cl[1] = 0.3175000000; data_table[8].feg[0].cnl[1] = 1.3439000000; data_table[8].feg[0].cl[2] = 0.6487000000; data_table[8].feg[0].cnl[2] = 4.2788000000; data_table[8].feg[0].cl[3] = 0.5846000000; data_table[8].feg[0].cnl[3] = 11.3932000000; data_table[8].feg[0].cl[4] = 0.1421000000; data_table[8].feg[0].cnl[4] = 28.7881000000; data_table[8].feg[0].cl[5] = 0.0000000000; data_table[8].feg[0].cnl[5] = 0.0000000000; + data_table[9].feg[0].cl[0] = 0.1269000000; data_table[9].feg[0].cnl[0] = 0.2200000000; data_table[9].feg[0].cl[1] = 0.3535000000; data_table[9].feg[0].cnl[1] = 1.3779000000; data_table[9].feg[0].cl[2] = 0.5582000000; data_table[9].feg[0].cnl[2] = 4.0203000000; data_table[9].feg[0].cl[3] = 0.4674000000; data_table[9].feg[0].cnl[3] = 9.4934000000; data_table[9].feg[0].cl[4] = 0.1460000000; data_table[9].feg[0].cnl[4] = 23.1278000000; data_table[9].feg[0].cl[5] = 0.0000000000; data_table[9].feg[0].cnl[5] = 0.0000000000; + data_table[10].feg[0].cl[0] = 0.2142000000; data_table[10].feg[0].cnl[0] = 0.3334000000; data_table[10].feg[0].cl[1] = 0.6853000000; data_table[10].feg[0].cnl[1] = 2.3446000000; data_table[10].feg[0].cl[2] = 0.7692000000; data_table[10].feg[0].cnl[2] = 10.0830000000; data_table[10].feg[0].cl[3] = 1.6589000000; data_table[10].feg[0].cnl[3] = 48.3037000000; data_table[10].feg[0].cl[4] = 1.4482000000; data_table[10].feg[0].cnl[4] = 138.2700000000; data_table[10].feg[0].cl[5] = 0.0000000000; data_table[10].feg[0].cnl[5] = 0.0000000000; + data_table[11].feg[0].cl[0] = 0.2314000000; data_table[11].feg[0].cnl[0] = 0.3278000000; data_table[11].feg[0].cl[1] = 0.6866000000; data_table[11].feg[0].cnl[1] = 2.2720000000; data_table[11].feg[0].cl[2] = 0.9677000000; data_table[11].feg[0].cnl[2] = 10.9241000000; data_table[11].feg[0].cl[3] = 2.1882000000; data_table[11].feg[0].cnl[3] = 39.2898000000; data_table[11].feg[0].cl[4] = 1.1339000000; data_table[11].feg[0].cnl[4] = 101.9748000000; data_table[11].feg[0].cl[5] = 0.0000000000; data_table[11].feg[0].cnl[5] = 0.0000000000; + data_table[12].feg[0].cl[0] = 0.2390000000; data_table[12].feg[0].cnl[0] = 0.3138000000; data_table[12].feg[0].cl[1] = 0.6573000000; data_table[12].feg[0].cnl[1] = 2.1063000000; data_table[12].feg[0].cl[2] = 1.2011000000; data_table[12].feg[0].cnl[2] = 10.4163000000; data_table[12].feg[0].cl[3] = 2.5586000000; data_table[12].feg[0].cnl[3] = 34.4552000000; data_table[12].feg[0].cl[4] = 1.2312000000; data_table[12].feg[0].cnl[4] = 98.5344000000; data_table[12].feg[0].cl[5] = 0.0000000000; data_table[12].feg[0].cnl[5] = 0.0000000000; + data_table[13].feg[0].cl[0] = 0.2519000000; data_table[13].feg[0].cnl[0] = 0.3075000000; data_table[13].feg[0].cl[1] = 0.6372000000; data_table[13].feg[0].cnl[1] = 2.0174000000; data_table[13].feg[0].cl[2] = 1.3795000000; data_table[13].feg[0].cnl[2] = 9.6746000000; data_table[13].feg[0].cl[3] = 2.5082000000; data_table[13].feg[0].cnl[3] = 29.3744000000; data_table[13].feg[0].cl[4] = 1.0500000000; data_table[13].feg[0].cnl[4] = 80.4732000000; data_table[13].feg[0].cl[5] = 0.0000000000; data_table[13].feg[0].cnl[5] = 0.0000000000; + data_table[14].feg[0].cl[0] = 0.2548000000; data_table[14].feg[0].cnl[0] = 0.2908000000; data_table[14].feg[0].cl[1] = 0.6106000000; data_table[14].feg[0].cnl[1] = 1.8740000000; data_table[14].feg[0].cl[2] = 1.4541000000; data_table[14].feg[0].cnl[2] = 8.5176000000; data_table[14].feg[0].cl[3] = 2.3204000000; data_table[14].feg[0].cnl[3] = 24.3434000000; data_table[14].feg[0].cl[4] = 0.8477000000; data_table[14].feg[0].cnl[4] = 63.2996000000; data_table[14].feg[0].cl[5] = 0.0000000000; data_table[14].feg[0].cnl[5] = 0.0000000000; + data_table[15].feg[0].cl[0] = 0.2497000000; data_table[15].feg[0].cnl[0] = 0.2681000000; data_table[15].feg[0].cl[1] = 0.5628000000; data_table[15].feg[0].cnl[1] = 1.6711000000; data_table[15].feg[0].cl[2] = 1.3899000000; data_table[15].feg[0].cnl[2] = 7.0267000000; data_table[15].feg[0].cl[3] = 2.1865000000; data_table[15].feg[0].cnl[3] = 19.5377000000; data_table[15].feg[0].cl[4] = 0.7715000000; data_table[15].feg[0].cnl[4] = 50.3888000000; data_table[15].feg[0].cl[5] = 0.0000000000; data_table[15].feg[0].cnl[5] = 0.0000000000; + data_table[16].feg[0].cl[0] = 0.2443000000; data_table[16].feg[0].cnl[0] = 0.2468000000; data_table[16].feg[0].cl[1] = 0.5397000000; data_table[16].feg[0].cnl[1] = 1.5242000000; data_table[16].feg[0].cl[2] = 1.3919000000; data_table[16].feg[0].cnl[2] = 6.1537000000; data_table[16].feg[0].cl[3] = 2.0197000000; data_table[16].feg[0].cnl[3] = 16.6687000000; data_table[16].feg[0].cl[4] = 0.6621000000; data_table[16].feg[0].cnl[4] = 42.3086000000; data_table[16].feg[0].cl[5] = 0.0000000000; data_table[16].feg[0].cnl[5] = 0.0000000000; + data_table[17].feg[0].cl[0] = 0.2385000000; data_table[17].feg[0].cnl[0] = 0.2289000000; data_table[17].feg[0].cl[1] = 0.5017000000; data_table[17].feg[0].cnl[1] = 1.3694000000; data_table[17].feg[0].cl[2] = 1.3428000000; data_table[17].feg[0].cnl[2] = 5.2561000000; data_table[17].feg[0].cl[3] = 1.8899000000; data_table[17].feg[0].cnl[3] = 14.0928000000; data_table[17].feg[0].cl[4] = 0.6079000000; data_table[17].feg[0].cnl[4] = 35.5361000000; data_table[17].feg[0].cl[5] = 0.0000000000; data_table[17].feg[0].cnl[5] = 0.0000000000; + data_table[18].feg[0].cl[0] = 0.4115000000; data_table[18].feg[0].cnl[0] = 0.3703000000; data_table[18].feg[0].cl[1] = 1.4031000000; data_table[18].feg[0].cnl[1] = 3.3874000000; data_table[18].feg[0].cl[2] = 2.2784000000; data_table[18].feg[0].cnl[2] = 13.1029000000; data_table[18].feg[0].cl[3] = 2.6742000000; data_table[18].feg[0].cnl[3] = 68.9592000000; data_table[18].feg[0].cl[4] = 2.2162000000; data_table[18].feg[0].cnl[4] = 194.4329000000; data_table[18].feg[0].cl[5] = 0.0000000000; data_table[18].feg[0].cnl[5] = 0.0000000000; + data_table[19].feg[0].cl[0] = 0.4054000000; data_table[19].feg[0].cnl[0] = 0.3499000000; data_table[19].feg[0].cl[1] = 1.3880000000; data_table[19].feg[0].cnl[1] = 3.0991000000; data_table[19].feg[0].cl[2] = 2.1602000000; data_table[19].feg[0].cnl[2] = 11.9608000000; data_table[19].feg[0].cl[3] = 3.7532000000; data_table[19].feg[0].cnl[3] = 53.9353000000; data_table[19].feg[0].cl[4] = 2.2063000000; data_table[19].feg[0].cnl[4] = 142.3892000000; data_table[19].feg[0].cl[5] = 0.0000000000; data_table[19].feg[0].cnl[5] = 0.0000000000; + data_table[20].feg[0].cl[0] = 0.3787000000; data_table[20].feg[0].cnl[0] = 0.3133000000; data_table[20].feg[0].cl[1] = 1.2181000000; data_table[20].feg[0].cnl[1] = 2.5856000000; data_table[20].feg[0].cl[2] = 2.0594000000; data_table[20].feg[0].cnl[2] = 9.5813000000; data_table[20].feg[0].cl[3] = 3.2618000000; data_table[20].feg[0].cnl[3] = 41.7688000000; data_table[20].feg[0].cl[4] = 2.3870000000; data_table[20].feg[0].cnl[4] = 116.7282000000; data_table[20].feg[0].cl[5] = 0.0000000000; data_table[20].feg[0].cnl[5] = 0.0000000000; + data_table[21].feg[0].cl[0] = 0.3825000000; data_table[21].feg[0].cnl[0] = 0.3040000000; data_table[21].feg[0].cl[1] = 1.2598000000; data_table[21].feg[0].cnl[1] = 2.4863000000; data_table[21].feg[0].cl[2] = 2.0008000000; data_table[21].feg[0].cnl[2] = 9.2783000000; data_table[21].feg[0].cl[3] = 3.0617000000; data_table[21].feg[0].cnl[3] = 39.0751000000; data_table[21].feg[0].cl[4] = 2.0694000000; data_table[21].feg[0].cnl[4] = 109.4583000000; data_table[21].feg[0].cl[5] = 0.0000000000; data_table[21].feg[0].cnl[5] = 0.0000000000; + data_table[22].feg[0].cl[0] = 0.3876000000; data_table[22].feg[0].cnl[0] = 0.2967000000; data_table[22].feg[0].cl[1] = 1.2750000000; data_table[22].feg[0].cnl[1] = 2.3780000000; data_table[22].feg[0].cl[2] = 1.9109000000; data_table[22].feg[0].cnl[2] = 8.7981000000; data_table[22].feg[0].cl[3] = 2.8314000000; data_table[22].feg[0].cnl[3] = 35.9528000000; data_table[22].feg[0].cl[4] = 1.8979000000; data_table[22].feg[0].cnl[4] = 101.7201000000; data_table[22].feg[0].cl[5] = 0.0000000000; data_table[22].feg[0].cnl[5] = 0.0000000000; + data_table[23].feg[0].cl[0] = 0.4046000000; data_table[23].feg[0].cnl[0] = 0.2986000000; data_table[23].feg[0].cl[1] = 1.3696000000; data_table[23].feg[0].cnl[1] = 2.3958000000; data_table[23].feg[0].cl[2] = 1.8941000000; data_table[23].feg[0].cnl[2] = 9.1406000000; data_table[23].feg[0].cl[3] = 2.0800000000; data_table[23].feg[0].cnl[3] = 37.4701000000; data_table[23].feg[0].cl[4] = 1.2196000000; data_table[23].feg[0].cnl[4] = 113.7121000000; data_table[23].feg[0].cl[5] = 0.0000000000; data_table[23].feg[0].cnl[5] = 0.0000000000; + data_table[24].feg[0].cl[0] = 0.3796000000; data_table[24].feg[0].cnl[0] = 0.2699000000; data_table[24].feg[0].cl[1] = 1.2094000000; data_table[24].feg[0].cnl[1] = 2.0455000000; data_table[24].feg[0].cl[2] = 1.7815000000; data_table[24].feg[0].cnl[2] = 7.4726000000; data_table[24].feg[0].cl[3] = 2.5420000000; data_table[24].feg[0].cnl[3] = 31.0604000000; data_table[24].feg[0].cl[4] = 1.5937000000; data_table[24].feg[0].cnl[4] = 91.5622000000; data_table[24].feg[0].cl[5] = 0.0000000000; data_table[24].feg[0].cnl[5] = 0.0000000000; + data_table[25].feg[0].cl[0] = 0.3946000000; data_table[25].feg[0].cnl[0] = 0.2717000000; data_table[25].feg[0].cl[1] = 1.2725000000; data_table[25].feg[0].cnl[1] = 2.0443000000; data_table[25].feg[0].cl[2] = 1.7031000000; data_table[25].feg[0].cnl[2] = 7.6007000000; data_table[25].feg[0].cl[3] = 2.3140000000; data_table[25].feg[0].cnl[3] = 29.9714000000; data_table[25].feg[0].cl[4] = 1.4795000000; data_table[25].feg[0].cnl[4] = 86.2265000000; data_table[25].feg[0].cl[5] = 0.0000000000; data_table[25].feg[0].cnl[5] = 0.0000000000; + data_table[26].feg[0].cl[0] = 0.4118000000; data_table[26].feg[0].cnl[0] = 0.2742000000; data_table[26].feg[0].cl[1] = 1.3161000000; data_table[26].feg[0].cnl[1] = 2.0372000000; data_table[26].feg[0].cl[2] = 1.6493000000; data_table[26].feg[0].cnl[2] = 7.7205000000; data_table[26].feg[0].cl[3] = 2.1930000000; data_table[26].feg[0].cnl[3] = 29.9680000000; data_table[26].feg[0].cl[4] = 1.2830000000; data_table[26].feg[0].cnl[4] = 84.9383000000; data_table[26].feg[0].cl[5] = 0.0000000000; data_table[26].feg[0].cnl[5] = 0.0000000000; + data_table[27].feg[0].cl[0] = 0.3860000000; data_table[27].feg[0].cnl[0] = 0.2478000000; data_table[27].feg[0].cl[1] = 1.1765000000; data_table[27].feg[0].cnl[1] = 1.7660000000; data_table[27].feg[0].cl[2] = 1.5451000000; data_table[27].feg[0].cnl[2] = 6.3107000000; data_table[27].feg[0].cl[3] = 2.0730000000; data_table[27].feg[0].cnl[3] = 25.2204000000; data_table[27].feg[0].cl[4] = 1.3814000000; data_table[27].feg[0].cnl[4] = 74.3146000000; data_table[27].feg[0].cl[5] = 0.0000000000; data_table[27].feg[0].cnl[5] = 0.0000000000; + data_table[28].feg[0].cl[0] = 0.4314000000; data_table[28].feg[0].cnl[0] = 0.2694000000; data_table[28].feg[0].cl[1] = 1.3208000000; data_table[28].feg[0].cnl[1] = 1.9223000000; data_table[28].feg[0].cl[2] = 1.5236000000; data_table[28].feg[0].cnl[2] = 7.3474000000; data_table[28].feg[0].cl[3] = 1.4671000000; data_table[28].feg[0].cnl[3] = 28.9892000000; data_table[28].feg[0].cl[4] = 0.8562000000; data_table[28].feg[0].cnl[4] = 90.6246000000; data_table[28].feg[0].cl[5] = 0.0000000000; data_table[28].feg[0].cnl[5] = 0.0000000000; + data_table[29].feg[0].cl[0] = 0.4288000000; data_table[29].feg[0].cnl[0] = 0.2593000000; data_table[29].feg[0].cl[1] = 1.2646000000; data_table[29].feg[0].cnl[1] = 1.7998000000; data_table[29].feg[0].cl[2] = 1.4472000000; data_table[29].feg[0].cnl[2] = 6.7500000000; data_table[29].feg[0].cl[3] = 1.8294000000; data_table[29].feg[0].cnl[3] = 25.5860000000; data_table[29].feg[0].cl[4] = 1.0934000000; data_table[29].feg[0].cnl[4] = 73.5284000000; data_table[29].feg[0].cl[5] = 0.0000000000; data_table[29].feg[0].cnl[5] = 0.0000000000; + data_table[30].feg[0].cl[0] = 0.4818000000; data_table[30].feg[0].cnl[0] = 0.2825000000; data_table[30].feg[0].cl[1] = 1.4032000000; data_table[30].feg[0].cnl[1] = 1.9785000000; data_table[30].feg[0].cl[2] = 1.6561000000; data_table[30].feg[0].cnl[2] = 8.7546000000; data_table[30].feg[0].cl[3] = 2.4605000000; data_table[30].feg[0].cnl[3] = 32.5238000000; data_table[30].feg[0].cl[4] = 1.1054000000; data_table[30].feg[0].cnl[4] = 98.5523000000; data_table[30].feg[0].cl[5] = 0.0000000000; data_table[30].feg[0].cnl[5] = 0.0000000000; + data_table[31].feg[0].cl[0] = 0.4655000000; data_table[31].feg[0].cnl[0] = 0.2647000000; data_table[31].feg[0].cl[1] = 1.3014000000; data_table[31].feg[0].cnl[1] = 1.7926000000; data_table[31].feg[0].cl[2] = 1.6088000000; data_table[31].feg[0].cnl[2] = 7.6071000000; data_table[31].feg[0].cl[3] = 2.6998000000; data_table[31].feg[0].cnl[3] = 26.5541000000; data_table[31].feg[0].cl[4] = 1.3003000000; data_table[31].feg[0].cnl[4] = 77.5238000000; data_table[31].feg[0].cl[5] = 0.0000000000; data_table[31].feg[0].cnl[5] = 0.0000000000; + data_table[32].feg[0].cl[0] = 0.4517000000; data_table[32].feg[0].cnl[0] = 0.2493000000; data_table[32].feg[0].cl[1] = 1.2229000000; data_table[32].feg[0].cnl[1] = 1.6436000000; data_table[32].feg[0].cl[2] = 1.5852000000; data_table[32].feg[0].cnl[2] = 6.8154000000; data_table[32].feg[0].cl[3] = 2.7958000000; data_table[32].feg[0].cnl[3] = 22.3681000000; data_table[32].feg[0].cl[4] = 1.2638000000; data_table[32].feg[0].cnl[4] = 62.0390000000; data_table[32].feg[0].cl[5] = 0.0000000000; data_table[32].feg[0].cnl[5] = 0.0000000000; + data_table[33].feg[0].cl[0] = 0.4477000000; data_table[33].feg[0].cnl[0] = 0.2405000000; data_table[33].feg[0].cl[1] = 1.1678000000; data_table[33].feg[0].cnl[1] = 1.5442000000; data_table[33].feg[0].cl[2] = 1.5843000000; data_table[33].feg[0].cnl[2] = 6.3231000000; data_table[33].feg[0].cl[3] = 2.8087000000; data_table[33].feg[0].cnl[3] = 19.4610000000; data_table[33].feg[0].cl[4] = 1.1956000000; data_table[33].feg[0].cnl[4] = 52.0233000000; data_table[33].feg[0].cl[5] = 0.0000000000; data_table[33].feg[0].cnl[5] = 0.0000000000; + data_table[34].feg[0].cl[0] = 0.4798000000; data_table[34].feg[0].cnl[0] = 0.2504000000; data_table[34].feg[0].cl[1] = 1.1948000000; data_table[34].feg[0].cnl[1] = 1.5963000000; data_table[34].feg[0].cl[2] = 1.8695000000; data_table[34].feg[0].cnl[2] = 6.9653000000; data_table[34].feg[0].cl[3] = 2.6953000000; data_table[34].feg[0].cnl[3] = 19.8492000000; data_table[34].feg[0].cl[4] = 0.8203000000; data_table[34].feg[0].cnl[4] = 50.3233000000; data_table[34].feg[0].cl[5] = 0.0000000000; data_table[34].feg[0].cnl[5] = 0.0000000000; + data_table[35].feg[0].cl[0] = 0.4546000000; data_table[35].feg[0].cnl[0] = 0.2309000000; data_table[35].feg[0].cl[1] = 1.0993000000; data_table[35].feg[0].cnl[1] = 1.4279000000; data_table[35].feg[0].cl[2] = 1.7696000000; data_table[35].feg[0].cnl[2] = 5.9449000000; data_table[35].feg[0].cl[3] = 2.7068000000; data_table[35].feg[0].cnl[3] = 16.6752000000; data_table[35].feg[0].cl[4] = 0.8672000000; data_table[35].feg[0].cnl[4] = 42.2243000000; data_table[35].feg[0].cl[5] = 0.0000000000; data_table[35].feg[0].cnl[5] = 0.0000000000; + data_table[36].feg[0].cl[0] = 1.0160000000; data_table[36].feg[0].cnl[0] = 0.4853000000; data_table[36].feg[0].cl[1] = 2.8528000000; data_table[36].feg[0].cnl[1] = 5.0925000000; data_table[36].feg[0].cl[2] = 3.5466000000; data_table[36].feg[0].cnl[2] = 25.7851000000; data_table[36].feg[0].cl[3] = -7.7804000000; data_table[36].feg[0].cnl[3] = 130.4515000000; data_table[36].feg[0].cl[4] = 12.1148000000; data_table[36].feg[0].cnl[4] = 138.6775000000; data_table[36].feg[0].cl[5] = 0.0000000000; data_table[36].feg[0].cnl[5] = 0.0000000000; + data_table[37].feg[0].cl[0] = 0.6703000000; data_table[37].feg[0].cnl[0] = 0.3190000000; data_table[37].feg[0].cl[1] = 1.4926000000; data_table[37].feg[0].cnl[1] = 2.2287000000; data_table[37].feg[0].cl[2] = 3.3368000000; data_table[37].feg[0].cnl[2] = 10.3504000000; data_table[37].feg[0].cl[3] = 4.4600000000; data_table[37].feg[0].cnl[3] = 52.3291000000; data_table[37].feg[0].cl[4] = 3.1501000000; data_table[37].feg[0].cnl[4] = 151.2216000000; data_table[37].feg[0].cl[5] = 0.0000000000; data_table[37].feg[0].cnl[5] = 0.0000000000; + data_table[38].feg[0].cl[0] = 0.6894000000; data_table[38].feg[0].cnl[0] = 0.3189000000; data_table[38].feg[0].cl[1] = 1.5474000000; data_table[38].feg[0].cnl[1] = 2.2904000000; data_table[38].feg[0].cl[2] = 3.2450000000; data_table[38].feg[0].cnl[2] = 10.0062000000; data_table[38].feg[0].cl[3] = 4.2126000000; data_table[38].feg[0].cnl[3] = 44.0771000000; data_table[38].feg[0].cl[4] = 2.9764000000; data_table[38].feg[0].cnl[4] = 125.0120000000; data_table[38].feg[0].cl[5] = 0.0000000000; data_table[38].feg[0].cnl[5] = 0.0000000000; + data_table[39].feg[0].cl[0] = 0.6719000000; data_table[39].feg[0].cnl[0] = 0.3036000000; data_table[39].feg[0].cl[1] = 1.4684000000; data_table[39].feg[0].cnl[1] = 2.1249000000; data_table[39].feg[0].cl[2] = 3.1668000000; data_table[39].feg[0].cnl[2] = 8.9236000000; data_table[39].feg[0].cl[3] = 3.9557000000; data_table[39].feg[0].cnl[3] = 36.8458000000; data_table[39].feg[0].cl[4] = 2.8920000000; data_table[39].feg[0].cnl[4] = 108.2049000000; data_table[39].feg[0].cl[5] = 0.0000000000; data_table[39].feg[0].cnl[5] = 0.0000000000; + data_table[40].feg[0].cl[0] = 0.6123000000; data_table[40].feg[0].cnl[0] = 0.2709000000; data_table[40].feg[0].cl[1] = 1.2677000000; data_table[40].feg[0].cnl[1] = 1.7683000000; data_table[40].feg[0].cl[2] = 3.0348000000; data_table[40].feg[0].cnl[2] = 7.2489000000; data_table[40].feg[0].cl[3] = 3.3841000000; data_table[40].feg[0].cnl[3] = 27.9465000000; data_table[40].feg[0].cl[4] = 2.3683000000; data_table[40].feg[0].cnl[4] = 98.5624000000; data_table[40].feg[0].cl[5] = 0.0000000000; data_table[40].feg[0].cnl[5] = 0.0000000000; + data_table[41].feg[0].cl[0] = 0.6773000000; data_table[41].feg[0].cnl[0] = 0.2920000000; data_table[41].feg[0].cl[1] = 1.4798000000; data_table[41].feg[0].cnl[1] = 2.0606000000; data_table[41].feg[0].cl[2] = 3.1788000000; data_table[41].feg[0].cnl[2] = 8.1129000000; data_table[41].feg[0].cl[3] = 3.0824000000; data_table[41].feg[0].cnl[3] = 30.5336000000; data_table[41].feg[0].cl[4] = 1.8384000000; data_table[41].feg[0].cnl[4] = 100.0658000000; data_table[41].feg[0].cl[5] = 0.0000000000; data_table[41].feg[0].cnl[5] = 0.0000000000; + data_table[42].feg[0].cl[0] = 0.7082000000; data_table[42].feg[0].cnl[0] = 0.2976000000; data_table[42].feg[0].cl[1] = 1.6392000000; data_table[42].feg[0].cnl[1] = 2.2106000000; data_table[42].feg[0].cl[2] = 3.1993000000; data_table[42].feg[0].cnl[2] = 8.5246000000; data_table[42].feg[0].cl[3] = 3.4327000000; data_table[42].feg[0].cnl[3] = 33.1456000000; data_table[42].feg[0].cl[4] = 1.8711000000; data_table[42].feg[0].cnl[4] = 96.6377000000; data_table[42].feg[0].cl[5] = 0.0000000000; data_table[42].feg[0].cnl[5] = 0.0000000000; + data_table[43].feg[0].cl[0] = 0.6735000000; data_table[43].feg[0].cnl[0] = 0.2773000000; data_table[43].feg[0].cl[1] = 1.4934000000; data_table[43].feg[0].cnl[1] = 1.9716000000; data_table[43].feg[0].cl[2] = 3.0966000000; data_table[43].feg[0].cnl[2] = 7.3249000000; data_table[43].feg[0].cl[3] = 2.7254000000; data_table[43].feg[0].cnl[3] = 26.6891000000; data_table[43].feg[0].cl[4] = 1.5597000000; data_table[43].feg[0].cnl[4] = 90.5581000000; data_table[43].feg[0].cl[5] = 0.0000000000; data_table[43].feg[0].cnl[5] = 0.0000000000; + data_table[44].feg[0].cl[0] = 0.6413000000; data_table[44].feg[0].cnl[0] = 0.2580000000; data_table[44].feg[0].cl[1] = 1.3690000000; data_table[44].feg[0].cnl[1] = 1.7721000000; data_table[44].feg[0].cl[2] = 2.9854000000; data_table[44].feg[0].cnl[2] = 6.3854000000; data_table[44].feg[0].cl[3] = 2.6952000000; data_table[44].feg[0].cnl[3] = 23.2549000000; data_table[44].feg[0].cl[4] = 1.5433000000; data_table[44].feg[0].cnl[4] = 85.1517000000; data_table[44].feg[0].cl[5] = 0.0000000000; data_table[44].feg[0].cnl[5] = 0.0000000000; + data_table[45].feg[0].cl[0] = 0.5904000000; data_table[45].feg[0].cnl[0] = 0.2324000000; data_table[45].feg[0].cl[1] = 1.1775000000; data_table[45].feg[0].cnl[1] = 1.5019000000; data_table[45].feg[0].cl[2] = 2.6519000000; data_table[45].feg[0].cnl[2] = 5.1591000000; data_table[45].feg[0].cl[3] = 2.2875000000; data_table[45].feg[0].cnl[3] = 15.5428000000; data_table[45].feg[0].cl[4] = 0.8689000000; data_table[45].feg[0].cnl[4] = 46.8213000000; data_table[45].feg[0].cl[5] = 0.0000000000; data_table[45].feg[0].cnl[5] = 0.0000000000; + data_table[46].feg[0].cl[0] = 0.6377000000; data_table[46].feg[0].cnl[0] = 0.2466000000; data_table[46].feg[0].cl[1] = 1.3790000000; data_table[46].feg[0].cnl[1] = 1.6974000000; data_table[46].feg[0].cl[2] = 2.8294000000; data_table[46].feg[0].cnl[2] = 5.7656000000; data_table[46].feg[0].cl[3] = 2.3631000000; data_table[46].feg[0].cnl[3] = 20.0943000000; data_table[46].feg[0].cl[4] = 1.4553000000; data_table[46].feg[0].cnl[4] = 76.7372000000; data_table[46].feg[0].cl[5] = 0.0000000000; data_table[46].feg[0].cnl[5] = 0.0000000000; + data_table[47].feg[0].cl[0] = 0.6364000000; data_table[47].feg[0].cnl[0] = 0.2407000000; data_table[47].feg[0].cl[1] = 1.4247000000; data_table[47].feg[0].cnl[1] = 1.6823000000; data_table[47].feg[0].cl[2] = 2.7802000000; data_table[47].feg[0].cnl[2] = 5.6588000000; data_table[47].feg[0].cl[3] = 2.5973000000; data_table[47].feg[0].cnl[3] = 20.7219000000; data_table[47].feg[0].cl[4] = 1.7886000000; data_table[47].feg[0].cnl[4] = 69.1109000000; data_table[47].feg[0].cl[5] = 0.0000000000; data_table[47].feg[0].cnl[5] = 0.0000000000; + data_table[48].feg[0].cl[0] = 0.6768000000; data_table[48].feg[0].cnl[0] = 0.2522000000; data_table[48].feg[0].cl[1] = 1.6589000000; data_table[48].feg[0].cnl[1] = 1.8545000000; data_table[48].feg[0].cl[2] = 2.7740000000; data_table[48].feg[0].cnl[2] = 6.2936000000; data_table[48].feg[0].cl[3] = 3.1835000000; data_table[48].feg[0].cnl[3] = 25.1457000000; data_table[48].feg[0].cl[4] = 2.1326000000; data_table[48].feg[0].cnl[4] = 84.5448000000; data_table[48].feg[0].cl[5] = 0.0000000000; data_table[48].feg[0].cnl[5] = 0.0000000000; + data_table[49].feg[0].cl[0] = 0.7224000000; data_table[49].feg[0].cnl[0] = 0.2651000000; data_table[49].feg[0].cl[1] = 1.9610000000; data_table[49].feg[0].cnl[1] = 2.0604000000; data_table[49].feg[0].cl[2] = 2.7161000000; data_table[49].feg[0].cnl[2] = 7.3011000000; data_table[49].feg[0].cl[3] = 3.5603000000; data_table[49].feg[0].cnl[3] = 27.5493000000; data_table[49].feg[0].cl[4] = 1.8972000000; data_table[49].feg[0].cnl[4] = 81.3349000000; data_table[49].feg[0].cl[5] = 0.0000000000; data_table[49].feg[0].cnl[5] = 0.0000000000; + data_table[50].feg[0].cl[0] = 0.7106000000; data_table[50].feg[0].cnl[0] = 0.2562000000; data_table[50].feg[0].cl[1] = 1.9247000000; data_table[50].feg[0].cnl[1] = 1.9646000000; data_table[50].feg[0].cl[2] = 2.6149000000; data_table[50].feg[0].cnl[2] = 6.8852000000; data_table[50].feg[0].cl[3] = 3.8322000000; data_table[50].feg[0].cnl[3] = 24.7648000000; data_table[50].feg[0].cl[4] = 1.8899000000; data_table[50].feg[0].cnl[4] = 68.9168000000; data_table[50].feg[0].cl[5] = 0.0000000000; data_table[50].feg[0].cnl[5] = 0.0000000000; + data_table[51].feg[0].cl[0] = 0.6947000000; data_table[51].feg[0].cnl[0] = 0.2459000000; data_table[51].feg[0].cl[1] = 1.8690000000; data_table[51].feg[0].cnl[1] = 1.8542000000; data_table[51].feg[0].cl[2] = 2.5356000000; data_table[51].feg[0].cnl[2] = 6.4411000000; data_table[51].feg[0].cl[3] = 4.0013000000; data_table[51].feg[0].cnl[3] = 22.1730000000; data_table[51].feg[0].cl[4] = 1.8955000000; data_table[51].feg[0].cnl[4] = 59.2206000000; data_table[51].feg[0].cl[5] = 0.0000000000; data_table[51].feg[0].cnl[5] = 0.0000000000; + data_table[52].feg[0].cl[0] = 0.7047000000; data_table[52].feg[0].cnl[0] = 0.2455000000; data_table[52].feg[0].cl[1] = 1.9484000000; data_table[52].feg[0].cnl[1] = 1.8638000000; data_table[52].feg[0].cl[2] = 2.5940000000; data_table[52].feg[0].cnl[2] = 6.7639000000; data_table[52].feg[0].cl[3] = 4.1526000000; data_table[52].feg[0].cnl[3] = 21.8007000000; data_table[52].feg[0].cl[4] = 1.5057000000; data_table[52].feg[0].cnl[4] = 56.4395000000; data_table[52].feg[0].cl[5] = 0.0000000000; data_table[52].feg[0].cnl[5] = 0.0000000000; + data_table[53].feg[0].cl[0] = 0.6737000000; data_table[53].feg[0].cnl[0] = 0.2305000000; data_table[53].feg[0].cl[1] = 1.7908000000; data_table[53].feg[0].cnl[1] = 1.6890000000; data_table[53].feg[0].cl[2] = 2.4129000000; data_table[53].feg[0].cnl[2] = 5.8218000000; data_table[53].feg[0].cl[3] = 4.2100000000; data_table[53].feg[0].cnl[3] = 18.3928000000; data_table[53].feg[0].cl[4] = 1.7058000000; data_table[53].feg[0].cnl[4] = 47.2496000000; data_table[53].feg[0].cl[5] = 0.0000000000; data_table[53].feg[0].cnl[5] = 0.0000000000; + data_table[54].feg[0].cl[0] = 1.2704000000; data_table[54].feg[0].cnl[0] = 0.4356000000; data_table[54].feg[0].cl[1] = 3.8018000000; data_table[54].feg[0].cnl[1] = 4.2058000000; data_table[54].feg[0].cl[2] = 5.6618000000; data_table[54].feg[0].cnl[2] = 23.4342000000; data_table[54].feg[0].cl[3] = 0.9205000000; data_table[54].feg[0].cnl[3] = 136.7783000000; data_table[54].feg[0].cl[4] = 4.8105000000; data_table[54].feg[0].cnl[4] = 171.7561000000; data_table[54].feg[0].cl[5] = 0.0000000000; data_table[54].feg[0].cnl[5] = 0.0000000000; + data_table[55].feg[0].cl[0] = 0.9049000000; data_table[55].feg[0].cnl[0] = 0.3066000000; data_table[55].feg[0].cl[1] = 2.6076000000; data_table[55].feg[0].cnl[1] = 2.4363000000; data_table[55].feg[0].cl[2] = 4.8498000000; data_table[55].feg[0].cnl[2] = 12.1821000000; data_table[55].feg[0].cl[3] = 5.1603000000; data_table[55].feg[0].cnl[3] = 54.6135000000; data_table[55].feg[0].cl[4] = 4.7388000000; data_table[55].feg[0].cnl[4] = 161.9978000000; data_table[55].feg[0].cl[5] = 0.0000000000; data_table[55].feg[0].cnl[5] = 0.0000000000; + data_table[56].feg[0].cl[0] = 0.8405000000; data_table[56].feg[0].cnl[0] = 0.2791000000; data_table[56].feg[0].cl[1] = 2.3863000000; data_table[56].feg[0].cnl[1] = 2.1410000000; data_table[56].feg[0].cl[2] = 4.6139000000; data_table[56].feg[0].cnl[2] = 10.3400000000; data_table[56].feg[0].cl[3] = 5.1514000000; data_table[56].feg[0].cnl[3] = 41.9148000000; data_table[56].feg[0].cl[4] = 4.7949000000; data_table[56].feg[0].cnl[4] = 132.0204000000; data_table[56].feg[0].cl[5] = 0.0000000000; data_table[56].feg[0].cnl[5] = 0.0000000000; + data_table[57].feg[0].cl[0] = 0.8551000000; data_table[57].feg[0].cnl[0] = 0.2805000000; data_table[57].feg[0].cl[1] = 2.3915000000; data_table[57].feg[0].cnl[1] = 2.1200000000; data_table[57].feg[0].cl[2] = 4.5772000000; data_table[57].feg[0].cnl[2] = 10.1808000000; data_table[57].feg[0].cl[3] = 5.0278000000; data_table[57].feg[0].cnl[3] = 42.0633000000; data_table[57].feg[0].cl[4] = 4.5118000000; data_table[57].feg[0].cnl[4] = 130.9893000000; data_table[57].feg[0].cl[5] = 0.0000000000; data_table[57].feg[0].cnl[5] = 0.0000000000; + data_table[58].feg[0].cl[0] = 0.9096000000; data_table[58].feg[0].cnl[0] = 0.2939000000; data_table[58].feg[0].cl[1] = 2.5313000000; data_table[58].feg[0].cnl[1] = 2.2471000000; data_table[58].feg[0].cl[2] = 4.5266000000; data_table[58].feg[0].cnl[2] = 10.8266000000; data_table[58].feg[0].cl[3] = 4.6376000000; data_table[58].feg[0].cnl[3] = 48.8842000000; data_table[58].feg[0].cl[4] = 4.3690000000; data_table[58].feg[0].cnl[4] = 147.6020000000; data_table[58].feg[0].cl[5] = 0.0000000000; data_table[58].feg[0].cnl[5] = 0.0000000000; + data_table[59].feg[0].cl[0] = 0.8807000000; data_table[59].feg[0].cnl[0] = 0.2802000000; data_table[59].feg[0].cl[1] = 2.4183000000; data_table[59].feg[0].cnl[1] = 2.0836000000; data_table[59].feg[0].cl[2] = 4.4448000000; data_table[59].feg[0].cnl[2] = 10.0357000000; data_table[59].feg[0].cl[3] = 4.6858000000; data_table[59].feg[0].cnl[3] = 47.4506000000; data_table[59].feg[0].cl[4] = 4.1725000000; data_table[59].feg[0].cnl[4] = 146.9976000000; data_table[59].feg[0].cl[5] = 0.0000000000; data_table[59].feg[0].cnl[5] = 0.0000000000; + data_table[60].feg[0].cl[0] = 0.9471000000; data_table[60].feg[0].cnl[0] = 0.2977000000; data_table[60].feg[0].cl[1] = 2.5463000000; data_table[60].feg[0].cnl[1] = 2.2276000000; data_table[60].feg[0].cl[2] = 4.3523000000; data_table[60].feg[0].cnl[2] = 10.5762000000; data_table[60].feg[0].cl[3] = 4.4789000000; data_table[60].feg[0].cnl[3] = 49.3619000000; data_table[60].feg[0].cl[4] = 3.9080000000; data_table[60].feg[0].cnl[4] = 145.3580000000; data_table[60].feg[0].cl[5] = 0.0000000000; data_table[60].feg[0].cnl[5] = 0.0000000000; + data_table[61].feg[0].cl[0] = 0.9699000000; data_table[61].feg[0].cnl[0] = 0.3003000000; data_table[61].feg[0].cl[1] = 2.5837000000; data_table[61].feg[0].cnl[1] = 2.2447000000; data_table[61].feg[0].cl[2] = 4.2778000000; data_table[61].feg[0].cnl[2] = 10.6487000000; data_table[61].feg[0].cl[3] = 4.4575000000; data_table[61].feg[0].cnl[3] = 50.7994000000; data_table[61].feg[0].cl[4] = 3.5985000000; data_table[61].feg[0].cnl[4] = 146.4179000000; data_table[61].feg[0].cl[5] = 0.0000000000; data_table[61].feg[0].cnl[5] = 0.0000000000; + data_table[62].feg[0].cl[0] = 0.8694000000; data_table[62].feg[0].cnl[0] = 0.2653000000; data_table[62].feg[0].cl[1] = 2.2413000000; data_table[62].feg[0].cnl[1] = 1.8590000000; data_table[62].feg[0].cl[2] = 3.9196000000; data_table[62].feg[0].cnl[2] = 8.3998000000; data_table[62].feg[0].cl[3] = 3.9694000000; data_table[62].feg[0].cnl[3] = 36.7397000000; data_table[62].feg[0].cl[4] = 4.5498000000; data_table[62].feg[0].cnl[4] = 125.7089000000; data_table[62].feg[0].cl[5] = 0.0000000000; data_table[62].feg[0].cnl[5] = 0.0000000000; + data_table[63].feg[0].cl[0] = 0.9673000000; data_table[63].feg[0].cnl[0] = 0.2909000000; data_table[63].feg[0].cl[1] = 2.4702000000; data_table[63].feg[0].cnl[1] = 2.1014000000; data_table[63].feg[0].cl[2] = 4.1148000000; data_table[63].feg[0].cnl[2] = 9.7067000000; data_table[63].feg[0].cl[3] = 4.4972000000; data_table[63].feg[0].cnl[3] = 43.4270000000; data_table[63].feg[0].cl[4] = 3.2099000000; data_table[63].feg[0].cnl[4] = 125.9474000000; data_table[63].feg[0].cl[5] = 0.0000000000; data_table[63].feg[0].cnl[5] = 0.0000000000; + data_table[64].feg[0].cl[0] = 0.9325000000; data_table[64].feg[0].cnl[0] = 0.2761000000; data_table[64].feg[0].cl[1] = 2.3673000000; data_table[64].feg[0].cnl[1] = 1.9511000000; data_table[64].feg[0].cl[2] = 3.8791000000; data_table[64].feg[0].cnl[2] = 8.9296000000; data_table[64].feg[0].cl[3] = 3.9674000000; data_table[64].feg[0].cnl[3] = 41.5937000000; data_table[64].feg[0].cl[4] = 3.7996000000; data_table[64].feg[0].cnl[4] = 131.0122000000; data_table[64].feg[0].cl[5] = 0.0000000000; data_table[64].feg[0].cnl[5] = 0.0000000000; + data_table[65].feg[0].cl[0] = 0.9505000000; data_table[65].feg[0].cnl[0] = 0.2773000000; data_table[65].feg[0].cl[1] = 2.3705000000; data_table[65].feg[0].cnl[1] = 1.9469000000; data_table[65].feg[0].cl[2] = 3.8218000000; data_table[65].feg[0].cnl[2] = 8.8862000000; data_table[65].feg[0].cl[3] = 4.0471000000; data_table[65].feg[0].cnl[3] = 43.0938000000; data_table[65].feg[0].cl[4] = 3.4451000000; data_table[65].feg[0].cnl[4] = 133.1396000000; data_table[65].feg[0].cl[5] = 0.0000000000; data_table[65].feg[0].cnl[5] = 0.0000000000; + data_table[66].feg[0].cl[0] = 0.9248000000; data_table[66].feg[0].cnl[0] = 0.2660000000; data_table[66].feg[0].cl[1] = 2.2428000000; data_table[66].feg[0].cnl[1] = 1.8183000000; data_table[66].feg[0].cl[2] = 3.6182000000; data_table[66].feg[0].cnl[2] = 7.9655000000; data_table[66].feg[0].cl[3] = 3.7910000000; data_table[66].feg[0].cnl[3] = 33.1129000000; data_table[66].feg[0].cl[4] = 3.7912000000; data_table[66].feg[0].cnl[4] = 101.8139000000; data_table[66].feg[0].cl[5] = 0.0000000000; data_table[66].feg[0].cnl[5] = 0.0000000000; + data_table[67].feg[0].cl[0] = 1.0373000000; data_table[67].feg[0].cnl[0] = 0.2944000000; data_table[67].feg[0].cl[1] = 2.4824000000; data_table[67].feg[0].cnl[1] = 2.0797000000; data_table[67].feg[0].cl[2] = 3.6558000000; data_table[67].feg[0].cnl[2] = 9.4156000000; data_table[67].feg[0].cl[3] = 3.8925000000; data_table[67].feg[0].cnl[3] = 45.8056000000; data_table[67].feg[0].cl[4] = 3.0056000000; data_table[67].feg[0].cnl[4] = 132.7720000000; data_table[67].feg[0].cl[5] = 0.0000000000; data_table[67].feg[0].cnl[5] = 0.0000000000; + data_table[68].feg[0].cl[0] = 1.0075000000; data_table[68].feg[0].cnl[0] = 0.2816000000; data_table[68].feg[0].cl[1] = 2.3787000000; data_table[68].feg[0].cnl[1] = 1.9486000000; data_table[68].feg[0].cl[2] = 3.5440000000; data_table[68].feg[0].cnl[2] = 8.7162000000; data_table[68].feg[0].cl[3] = 3.6932000000; data_table[68].feg[0].cnl[3] = 41.8420000000; data_table[68].feg[0].cl[4] = 3.1759000000; data_table[68].feg[0].cnl[4] = 125.0320000000; data_table[68].feg[0].cl[5] = 0.0000000000; data_table[68].feg[0].cnl[5] = 0.0000000000; + data_table[69].feg[0].cl[0] = 1.0347000000; data_table[69].feg[0].cnl[0] = 0.2855000000; data_table[69].feg[0].cl[1] = 2.3911000000; data_table[69].feg[0].cnl[1] = 1.9679000000; data_table[69].feg[0].cl[2] = 3.4619000000; data_table[69].feg[0].cnl[2] = 8.7619000000; data_table[69].feg[0].cl[3] = 3.6556000000; data_table[69].feg[0].cnl[3] = 42.3304000000; data_table[69].feg[0].cl[4] = 3.0052000000; data_table[69].feg[0].cnl[4] = 125.6499000000; data_table[69].feg[0].cl[5] = 0.0000000000; data_table[69].feg[0].cnl[5] = 0.0000000000; + data_table[70].feg[0].cl[0] = 0.9927000000; data_table[70].feg[0].cnl[0] = 0.2701000000; data_table[70].feg[0].cl[1] = 2.2436000000; data_table[70].feg[0].cnl[1] = 1.8073000000; data_table[70].feg[0].cl[2] = 3.3554000000; data_table[70].feg[0].cnl[2] = 7.8112000000; data_table[70].feg[0].cl[3] = 3.7813000000; data_table[70].feg[0].cnl[3] = 34.4849000000; data_table[70].feg[0].cl[4] = 3.0994000000; data_table[70].feg[0].cnl[4] = 103.3526000000; data_table[70].feg[0].cl[5] = 0.0000000000; data_table[70].feg[0].cnl[5] = 0.0000000000; + data_table[71].feg[0].cl[0] = 1.0295000000; data_table[71].feg[0].cnl[0] = 0.2761000000; data_table[71].feg[0].cl[1] = 2.2911000000; data_table[71].feg[0].cnl[1] = 1.8625000000; data_table[71].feg[0].cl[2] = 3.4110000000; data_table[71].feg[0].cnl[2] = 8.0961000000; data_table[71].feg[0].cl[3] = 3.9497000000; data_table[71].feg[0].cnl[3] = 34.2712000000; data_table[71].feg[0].cl[4] = 2.4925000000; data_table[71].feg[0].cnl[4] = 98.5295000000; data_table[71].feg[0].cl[5] = 0.0000000000; data_table[71].feg[0].cnl[5] = 0.0000000000; + data_table[72].feg[0].cl[0] = 1.0190000000; data_table[72].feg[0].cnl[0] = 0.2694000000; data_table[72].feg[0].cl[1] = 2.2291000000; data_table[72].feg[0].cnl[1] = 1.7962000000; data_table[72].feg[0].cl[2] = 3.4097000000; data_table[72].feg[0].cnl[2] = 7.6944000000; data_table[72].feg[0].cl[3] = 3.9252000000; data_table[72].feg[0].cnl[3] = 31.0942000000; data_table[72].feg[0].cl[4] = 2.2679000000; data_table[72].feg[0].cnl[4] = 91.1089000000; data_table[72].feg[0].cl[5] = 0.0000000000; data_table[72].feg[0].cnl[5] = 0.0000000000; + data_table[73].feg[0].cl[0] = 0.9853000000; data_table[73].feg[0].cnl[0] = 0.2569000000; data_table[73].feg[0].cl[1] = 2.1167000000; data_table[73].feg[0].cnl[1] = 1.6745000000; data_table[73].feg[0].cl[2] = 3.3570000000; data_table[73].feg[0].cnl[2] = 7.0098000000; data_table[73].feg[0].cl[3] = 3.7981000000; data_table[73].feg[0].cnl[3] = 26.9234000000; data_table[73].feg[0].cl[4] = 2.2798000000; data_table[73].feg[0].cnl[4] = 81.3910000000; data_table[73].feg[0].cl[5] = 0.0000000000; data_table[73].feg[0].cnl[5] = 0.0000000000; + data_table[74].feg[0].cl[0] = 0.9914000000; data_table[74].feg[0].cnl[0] = 0.2548000000; data_table[74].feg[0].cl[1] = 2.0858000000; data_table[74].feg[0].cnl[1] = 1.6518000000; data_table[74].feg[0].cl[2] = 3.4531000000; data_table[74].feg[0].cnl[2] = 6.8845000000; data_table[74].feg[0].cl[3] = 3.8812000000; data_table[74].feg[0].cnl[3] = 26.7234000000; data_table[74].feg[0].cl[4] = 1.8526000000; data_table[74].feg[0].cnl[4] = 81.7215000000; data_table[74].feg[0].cl[5] = 0.0000000000; data_table[74].feg[0].cnl[5] = 0.0000000000; + data_table[75].feg[0].cl[0] = 0.9813000000; data_table[75].feg[0].cnl[0] = 0.2487000000; data_table[75].feg[0].cl[1] = 2.0322000000; data_table[75].feg[0].cnl[1] = 1.5973000000; data_table[75].feg[0].cl[2] = 3.3665000000; data_table[75].feg[0].cnl[2] = 6.4737000000; data_table[75].feg[0].cl[3] = 3.6235000000; data_table[75].feg[0].cnl[3] = 23.2817000000; data_table[75].feg[0].cl[4] = 1.9741000000; data_table[75].feg[0].cnl[4] = 70.9254000000; data_table[75].feg[0].cl[5] = 0.0000000000; data_table[75].feg[0].cnl[5] = 0.0000000000; + data_table[76].feg[0].cl[0] = 1.0194000000; data_table[76].feg[0].cnl[0] = 0.2554000000; data_table[76].feg[0].cl[1] = 2.0645000000; data_table[76].feg[0].cnl[1] = 1.6475000000; data_table[76].feg[0].cl[2] = 3.4425000000; data_table[76].feg[0].cnl[2] = 6.5966000000; data_table[76].feg[0].cl[3] = 3.4914000000; data_table[76].feg[0].cnl[3] = 23.2269000000; data_table[76].feg[0].cl[4] = 1.6976000000; data_table[76].feg[0].cnl[4] = 70.0272000000; data_table[76].feg[0].cl[5] = 0.0000000000; data_table[76].feg[0].cnl[5] = 0.0000000000; + data_table[77].feg[0].cl[0] = 0.9148000000; data_table[77].feg[0].cnl[0] = 0.2263000000; data_table[77].feg[0].cl[1] = 1.8096000000; data_table[77].feg[0].cnl[1] = 1.3813000000; data_table[77].feg[0].cl[2] = 3.2134000000; data_table[77].feg[0].cnl[2] = 5.3243000000; data_table[77].feg[0].cl[3] = 3.2953000000; data_table[77].feg[0].cnl[3] = 17.5987000000; data_table[77].feg[0].cl[4] = 1.5754000000; data_table[77].feg[0].cnl[4] = 60.0171000000; data_table[77].feg[0].cl[5] = 0.0000000000; data_table[77].feg[0].cnl[5] = 0.0000000000; + data_table[78].feg[0].cl[0] = 0.9674000000; data_table[78].feg[0].cnl[0] = 0.2358000000; data_table[78].feg[0].cl[1] = 1.8916000000; data_table[78].feg[0].cnl[1] = 1.4712000000; data_table[78].feg[0].cl[2] = 3.3993000000; data_table[78].feg[0].cnl[2] = 5.6758000000; data_table[78].feg[0].cl[3] = 3.0524000000; data_table[78].feg[0].cnl[3] = 18.7119000000; data_table[78].feg[0].cl[4] = 1.2607000000; data_table[78].feg[0].cnl[4] = 61.5286000000; data_table[78].feg[0].cl[5] = 0.0000000000; data_table[78].feg[0].cnl[5] = 0.0000000000; + data_table[79].feg[0].cl[0] = 1.0033000000; data_table[79].feg[0].cnl[0] = 0.2413000000; data_table[79].feg[0].cl[1] = 1.9469000000; data_table[79].feg[0].cnl[1] = 1.5298000000; data_table[79].feg[0].cl[2] = 3.4396000000; data_table[79].feg[0].cnl[2] = 5.8009000000; data_table[79].feg[0].cl[3] = 3.1548000000; data_table[79].feg[0].cnl[3] = 19.4520000000; data_table[79].feg[0].cl[4] = 1.4180000000; data_table[79].feg[0].cnl[4] = 60.5753000000; data_table[79].feg[0].cl[5] = 0.0000000000; data_table[79].feg[0].cnl[5] = 0.0000000000; + data_table[80].feg[0].cl[0] = 1.0689000000; data_table[80].feg[0].cnl[0] = 0.2540000000; data_table[80].feg[0].cl[1] = 2.1038000000; data_table[80].feg[0].cnl[1] = 1.6715000000; data_table[80].feg[0].cl[2] = 3.6039000000; data_table[80].feg[0].cnl[2] = 6.3509000000; data_table[80].feg[0].cl[3] = 3.4927000000; data_table[80].feg[0].cnl[3] = 23.1531000000; data_table[80].feg[0].cl[4] = 1.8283000000; data_table[80].feg[0].cnl[4] = 78.7099000000; data_table[80].feg[0].cl[5] = 0.0000000000; data_table[80].feg[0].cnl[5] = 0.0000000000; + data_table[81].feg[0].cl[0] = 1.0891000000; data_table[81].feg[0].cnl[0] = 0.2552000000; data_table[81].feg[0].cl[1] = 2.1867000000; data_table[81].feg[0].cnl[1] = 1.7174000000; data_table[81].feg[0].cl[2] = 3.6160000000; data_table[81].feg[0].cnl[2] = 6.5131000000; data_table[81].feg[0].cl[3] = 3.8031000000; data_table[81].feg[0].cnl[3] = 23.9170000000; data_table[81].feg[0].cl[4] = 1.8994000000; data_table[81].feg[0].cnl[4] = 74.7039000000; data_table[81].feg[0].cl[5] = 0.0000000000; data_table[81].feg[0].cnl[5] = 0.0000000000; + data_table[82].feg[0].cl[0] = 1.1007000000; data_table[82].feg[0].cnl[0] = 0.2546000000; data_table[82].feg[0].cl[1] = 2.2306000000; data_table[82].feg[0].cnl[1] = 1.7351000000; data_table[82].feg[0].cl[2] = 3.5689000000; data_table[82].feg[0].cnl[2] = 6.4948000000; data_table[82].feg[0].cl[3] = 4.1549000000; data_table[82].feg[0].cnl[3] = 23.6464000000; data_table[82].feg[0].cl[4] = 2.0382000000; data_table[82].feg[0].cnl[4] = 70.3780000000; data_table[82].feg[0].cl[5] = 0.0000000000; data_table[82].feg[0].cnl[5] = 0.0000000000; + data_table[83].feg[0].cl[0] = 1.1568000000; data_table[83].feg[0].cnl[0] = 0.2648000000; data_table[83].feg[0].cl[1] = 2.4353000000; data_table[83].feg[0].cnl[1] = 1.8786000000; data_table[83].feg[0].cl[2] = 3.6459000000; data_table[83].feg[0].cnl[2] = 7.1749000000; data_table[83].feg[0].cl[3] = 4.4064000000; data_table[83].feg[0].cnl[3] = 25.1766000000; data_table[83].feg[0].cl[4] = 1.7179000000; data_table[83].feg[0].cnl[4] = 69.2821000000; data_table[83].feg[0].cl[5] = 0.0000000000; data_table[83].feg[0].cnl[5] = 0.0000000000; + data_table[84].feg[0].cl[0] = 1.0909000000; data_table[84].feg[0].cnl[0] = 0.2466000000; data_table[84].feg[0].cl[1] = 2.1976000000; data_table[84].feg[0].cnl[1] = 1.6707000000; data_table[84].feg[0].cl[2] = 3.3831000000; data_table[84].feg[0].cnl[2] = 6.0197000000; data_table[84].feg[0].cl[3] = 4.6700000000; data_table[84].feg[0].cnl[3] = 20.7657000000; data_table[84].feg[0].cl[4] = 2.1277000000; data_table[84].feg[0].cnl[4] = 57.2663000000; data_table[84].feg[0].cl[5] = 0.0000000000; data_table[84].feg[0].cnl[5] = 0.0000000000; + data_table[85].feg[0].cl[0] = 1.0756000000; data_table[85].feg[0].cnl[0] = 0.2402000000; data_table[85].feg[0].cl[1] = 2.1630000000; data_table[85].feg[0].cnl[1] = 1.6169000000; data_table[85].feg[0].cl[2] = 3.3178000000; data_table[85].feg[0].cnl[2] = 5.7644000000; data_table[85].feg[0].cl[3] = 4.8852000000; data_table[85].feg[0].cnl[3] = 19.4568000000; data_table[85].feg[0].cl[4] = 2.0489000000; data_table[85].feg[0].cnl[4] = 52.5009000000; data_table[85].feg[0].cl[5] = 0.0000000000; data_table[85].feg[0].cnl[5] = 0.0000000000; + data_table[86].feg[0].cl[0] = 1.4282000000; data_table[86].feg[0].cnl[0] = 0.3183000000; data_table[86].feg[0].cl[1] = 3.5081000000; data_table[86].feg[0].cnl[1] = 2.6889000000; data_table[86].feg[0].cl[2] = 5.6767000000; data_table[86].feg[0].cnl[2] = 13.4816000000; data_table[86].feg[0].cl[3] = 4.1964000000; data_table[86].feg[0].cnl[3] = 54.3866000000; data_table[86].feg[0].cl[4] = 3.8946000000; data_table[86].feg[0].cnl[4] = 200.8321000000; data_table[86].feg[0].cl[5] = 0.0000000000; data_table[86].feg[0].cnl[5] = 0.0000000000; + data_table[87].feg[0].cl[0] = 1.3127000000; data_table[87].feg[0].cnl[0] = 0.2887000000; data_table[87].feg[0].cl[1] = 3.1243000000; data_table[87].feg[0].cnl[1] = 2.2897000000; data_table[87].feg[0].cl[2] = 5.2988000000; data_table[87].feg[0].cnl[2] = 10.8276000000; data_table[87].feg[0].cl[3] = 5.3891000000; data_table[87].feg[0].cnl[3] = 43.5389000000; data_table[87].feg[0].cl[4] = 5.4133000000; data_table[87].feg[0].cnl[4] = 145.6109000000; data_table[87].feg[0].cl[5] = 0.0000000000; data_table[87].feg[0].cnl[5] = 0.0000000000; + data_table[88].feg[0].cl[0] = 1.3128000000; data_table[88].feg[0].cnl[0] = 0.2861000000; data_table[88].feg[0].cl[1] = 3.1021000000; data_table[88].feg[0].cnl[1] = 2.2509000000; data_table[88].feg[0].cl[2] = 5.3385000000; data_table[88].feg[0].cnl[2] = 10.5287000000; data_table[88].feg[0].cl[3] = 5.9611000000; data_table[88].feg[0].cnl[3] = 41.7796000000; data_table[88].feg[0].cl[4] = 4.7562000000; data_table[88].feg[0].cnl[4] = 128.2973000000; data_table[88].feg[0].cl[5] = 0.0000000000; data_table[88].feg[0].cnl[5] = 0.0000000000; + data_table[89].feg[0].cl[0] = 1.2553000000; data_table[89].feg[0].cnl[0] = 0.2701000000; data_table[89].feg[0].cl[1] = 2.9178000000; data_table[89].feg[0].cnl[1] = 2.0636000000; data_table[89].feg[0].cl[2] = 5.0862000000; data_table[89].feg[0].cnl[2] = 9.3051000000; data_table[89].feg[0].cl[3] = 6.1206000000; data_table[89].feg[0].cnl[3] = 34.5977000000; data_table[89].feg[0].cl[4] = 4.7122000000; data_table[89].feg[0].cnl[4] = 107.9200000000; data_table[89].feg[0].cl[5] = 0.0000000000; data_table[89].feg[0].cnl[5] = 0.0000000000; + data_table[90].feg[0].cl[0] = 1.3218000000; data_table[90].feg[0].cnl[0] = 0.2827000000; data_table[90].feg[0].cl[1] = 3.1444000000; data_table[90].feg[0].cnl[1] = 2.2250000000; data_table[90].feg[0].cl[2] = 5.4371000000; data_table[90].feg[0].cnl[2] = 10.2454000000; data_table[90].feg[0].cl[3] = 5.6444000000; data_table[90].feg[0].cnl[3] = 41.1162000000; data_table[90].feg[0].cl[4] = 4.0107000000; data_table[90].feg[0].cnl[4] = 124.4449000000; data_table[90].feg[0].cl[5] = 0.0000000000; data_table[90].feg[0].cnl[5] = 0.0000000000; + data_table[91].feg[0].cl[0] = 1.3382000000; data_table[91].feg[0].cnl[0] = 0.2838000000; data_table[91].feg[0].cl[1] = 3.2043000000; data_table[91].feg[0].cnl[1] = 2.2452000000; data_table[91].feg[0].cl[2] = 5.4558000000; data_table[91].feg[0].cnl[2] = 10.2519000000; data_table[91].feg[0].cl[3] = 5.4839000000; data_table[91].feg[0].cnl[3] = 41.7251000000; data_table[91].feg[0].cl[4] = 3.6342000000; data_table[91].feg[0].cnl[4] = 124.9023000000; data_table[91].feg[0].cl[5] = 0.0000000000; data_table[91].feg[0].cnl[5] = 0.0000000000; + data_table[92].feg[0].cl[0] = 1.5193000000; data_table[92].feg[0].cnl[0] = 0.3213000000; data_table[92].feg[0].cl[1] = 4.0053000000; data_table[92].feg[0].cnl[1] = 2.8206000000; data_table[92].feg[0].cl[2] = 6.5327000000; data_table[92].feg[0].cnl[2] = 14.8878000000; data_table[92].feg[0].cl[3] = -0.1402000000; data_table[92].feg[0].cnl[3] = 68.9103000000; data_table[92].feg[0].cl[4] = 6.7489000000; data_table[92].feg[0].cnl[4] = 81.7257000000; data_table[92].feg[0].cl[5] = 0.0000000000; data_table[92].feg[0].cnl[5] = 0.0000000000; + data_table[93].feg[0].cl[0] = 1.3517000000; data_table[93].feg[0].cnl[0] = 0.2813000000; data_table[93].feg[0].cl[1] = 3.2937000000; data_table[93].feg[0].cnl[1] = 2.2418000000; data_table[93].feg[0].cl[2] = 5.3213000000; data_table[93].feg[0].cnl[2] = 9.9952000000; data_table[93].feg[0].cl[3] = 4.6466000000; data_table[93].feg[0].cnl[3] = 42.7939000000; data_table[93].feg[0].cl[4] = 3.5714000000; data_table[93].feg[0].cnl[4] = 132.1739000000; data_table[93].feg[0].cl[5] = 0.0000000000; data_table[93].feg[0].cnl[5] = 0.0000000000; + data_table[94].feg[0].cl[0] = 1.2135000000; data_table[94].feg[0].cnl[0] = 0.2483000000; data_table[94].feg[0].cl[1] = 2.7962000000; data_table[94].feg[0].cnl[1] = 1.8437000000; data_table[94].feg[0].cl[2] = 4.7545000000; data_table[94].feg[0].cnl[2] = 7.5421000000; data_table[94].feg[0].cl[3] = 4.5731000000; data_table[94].feg[0].cnl[3] = 29.3841000000; data_table[94].feg[0].cl[4] = 4.4786000000; data_table[94].feg[0].cnl[4] = 112.4579000000; data_table[94].feg[0].cl[5] = 0.0000000000; data_table[94].feg[0].cnl[5] = 0.0000000000; + data_table[95].feg[0].cl[0] = 1.2937000000; data_table[95].feg[0].cnl[0] = 0.2638000000; data_table[95].feg[0].cl[1] = 3.1100000000; data_table[95].feg[0].cnl[1] = 2.0341000000; data_table[95].feg[0].cl[2] = 5.0393000000; data_table[95].feg[0].cnl[2] = 8.7101000000; data_table[95].feg[0].cl[3] = 4.7546000000; data_table[95].feg[0].cnl[3] = 35.2992000000; data_table[95].feg[0].cl[4] = 3.5031000000; data_table[95].feg[0].cnl[4] = 109.4972000000; data_table[95].feg[0].cl[5] = 0.0000000000; data_table[95].feg[0].cnl[5] = 0.0000000000; + data_table[96].feg[0].cl[0] = 1.2915000000; data_table[96].feg[0].cnl[0] = 0.2611000000; data_table[96].feg[0].cl[1] = 3.1023000000; data_table[96].feg[0].cnl[1] = 2.0023000000; data_table[96].feg[0].cl[2] = 4.9309000000; data_table[96].feg[0].cnl[2] = 8.4377000000; data_table[96].feg[0].cl[3] = 4.6009000000; data_table[96].feg[0].cnl[3] = 34.1559000000; data_table[96].feg[0].cl[4] = 3.4661000000; data_table[96].feg[0].cnl[4] = 105.8911000000; data_table[96].feg[0].cl[5] = 0.0000000000; data_table[96].feg[0].cnl[5] = 0.0000000000; + data_table[97].feg[0].cl[0] = 1.2089000000; data_table[97].feg[0].cnl[0] = 0.2421000000; data_table[97].feg[0].cl[1] = 2.7391000000; data_table[97].feg[0].cnl[1] = 1.7487000000; data_table[97].feg[0].cl[2] = 4.3482000000; data_table[97].feg[0].cnl[2] = 6.7262000000; data_table[97].feg[0].cl[3] = 4.0047000000; data_table[97].feg[0].cnl[3] = 23.2153000000; data_table[97].feg[0].cl[4] = 4.6497000000; data_table[97].feg[0].cnl[4] = 80.3108000000; data_table[97].feg[0].cl[5] = 0.0000000000; data_table[97].feg[0].cnl[5] = 0.0000000000; + data_table[98].feg[0].cl[0] = 0.0000000000; data_table[98].feg[0].cnl[0] = 0.0000000000; data_table[98].feg[0].cl[1] = 0.0000000000; data_table[98].feg[0].cnl[1] = 0.0000000000; data_table[98].feg[0].cl[2] = 0.0000000000; data_table[98].feg[0].cnl[2] = 0.0000000000; data_table[98].feg[0].cl[3] = 0.0000000000; data_table[98].feg[0].cnl[3] = 0.0000000000; data_table[98].feg[0].cl[4] = 0.0000000000; data_table[98].feg[0].cnl[4] = 0.0000000000; data_table[98].feg[0].cl[5] = 0.0000000000; data_table[98].feg[0].cnl[5] = 0.0000000000; + data_table[99].feg[0].cl[0] = 0.0000000000; data_table[99].feg[0].cnl[0] = 0.0000000000; data_table[99].feg[0].cl[1] = 0.0000000000; data_table[99].feg[0].cnl[1] = 0.0000000000; data_table[99].feg[0].cl[2] = 0.0000000000; data_table[99].feg[0].cnl[2] = 0.0000000000; data_table[99].feg[0].cl[3] = 0.0000000000; data_table[99].feg[0].cnl[3] = 0.0000000000; data_table[99].feg[0].cl[4] = 0.0000000000; data_table[99].feg[0].cnl[4] = 0.0000000000; data_table[99].feg[0].cl[5] = 0.0000000000; data_table[99].feg[0].cnl[5] = 0.0000000000; + data_table[100].feg[0].cl[0] = 0.0000000000; data_table[100].feg[0].cnl[0] = 0.0000000000; data_table[100].feg[0].cl[1] = 0.0000000000; data_table[100].feg[0].cnl[1] = 0.0000000000; data_table[100].feg[0].cl[2] = 0.0000000000; data_table[100].feg[0].cnl[2] = 0.0000000000; data_table[100].feg[0].cl[3] = 0.0000000000; data_table[100].feg[0].cnl[3] = 0.0000000000; data_table[100].feg[0].cl[4] = 0.0000000000; data_table[100].feg[0].cnl[4] = 0.0000000000; data_table[100].feg[0].cl[5] = 0.0000000000; data_table[100].feg[0].cnl[5] = 0.0000000000; + data_table[101].feg[0].cl[0] = 0.0000000000; data_table[101].feg[0].cnl[0] = 0.0000000000; data_table[101].feg[0].cl[1] = 0.0000000000; data_table[101].feg[0].cnl[1] = 0.0000000000; data_table[101].feg[0].cl[2] = 0.0000000000; data_table[101].feg[0].cnl[2] = 0.0000000000; data_table[101].feg[0].cl[3] = 0.0000000000; data_table[101].feg[0].cnl[3] = 0.0000000000; data_table[101].feg[0].cl[4] = 0.0000000000; data_table[101].feg[0].cnl[4] = 0.0000000000; data_table[101].feg[0].cl[5] = 0.0000000000; data_table[101].feg[0].cnl[5] = 0.0000000000; + data_table[102].feg[0].cl[0] = 0.0000000000; data_table[102].feg[0].cnl[0] = 0.0000000000; data_table[102].feg[0].cl[1] = 0.0000000000; data_table[102].feg[0].cnl[1] = 0.0000000000; data_table[102].feg[0].cl[2] = 0.0000000000; data_table[102].feg[0].cnl[2] = 0.0000000000; data_table[102].feg[0].cl[3] = 0.0000000000; data_table[102].feg[0].cnl[3] = 0.0000000000; data_table[102].feg[0].cl[4] = 0.0000000000; data_table[102].feg[0].cnl[4] = 0.0000000000; data_table[102].feg[0].cl[5] = 0.0000000000; data_table[102].feg[0].cnl[5] = 0.0000000000; + } + + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + void Load_feg_Peng_neutral_0_12() + { + data_table[0].feg[0].cl[0] = 0.0088000000; data_table[0].feg[0].cnl[0] = 0.1152000000; data_table[0].feg[0].cl[1] = 0.0449000000; data_table[0].feg[0].cnl[1] = 1.0867000000; data_table[0].feg[0].cl[2] = 0.1481000000; data_table[0].feg[0].cnl[2] = 4.9755000000; data_table[0].feg[0].cl[3] = 0.2356000000; data_table[0].feg[0].cnl[3] = 16.5591000000; data_table[0].feg[0].cl[4] = 0.0914000000; data_table[0].feg[0].cnl[4] = 43.2743000000; data_table[0].feg[0].cl[5] = 0.0000000000; data_table[0].feg[0].cnl[5] = 0.0000000000; + data_table[1].feg[0].cl[0] = 0.0084000000; data_table[1].feg[0].cnl[0] = 0.0596000000; data_table[1].feg[0].cl[1] = 0.0443000000; data_table[1].feg[0].cnl[1] = 0.5360000000; data_table[1].feg[0].cl[2] = 0.1314000000; data_table[1].feg[0].cnl[2] = 2.4274000000; data_table[1].feg[0].cl[3] = 0.1671000000; data_table[1].feg[0].cnl[3] = 7.7852000000; data_table[1].feg[0].cl[4] = 0.0666000000; data_table[1].feg[0].cnl[4] = 20.3126000000; data_table[1].feg[0].cl[5] = 0.0000000000; data_table[1].feg[0].cnl[5] = 0.0000000000; + data_table[2].feg[0].cl[0] = 0.0478000000; data_table[2].feg[0].cnl[0] = 0.2258000000; data_table[2].feg[0].cl[1] = 0.2048000000; data_table[2].feg[0].cnl[1] = 2.1032000000; data_table[2].feg[0].cl[2] = 0.5253000000; data_table[2].feg[0].cnl[2] = 12.9349000000; data_table[2].feg[0].cl[3] = 1.5225000000; data_table[2].feg[0].cnl[3] = 50.7501000000; data_table[2].feg[0].cl[4] = 0.9853000000; data_table[2].feg[0].cnl[4] = 136.6280000000; data_table[2].feg[0].cl[5] = 0.0000000000; data_table[2].feg[0].cnl[5] = 0.0000000000; + data_table[3].feg[0].cl[0] = 0.0423000000; data_table[3].feg[0].cnl[0] = 0.1445000000; data_table[3].feg[0].cl[1] = 0.1874000000; data_table[3].feg[0].cnl[1] = 1.4180000000; data_table[3].feg[0].cl[2] = 0.6019000000; data_table[3].feg[0].cnl[2] = 8.1165000000; data_table[3].feg[0].cl[3] = 1.4311000000; data_table[3].feg[0].cnl[3] = 27.9705000000; data_table[3].feg[0].cl[4] = 0.7891000000; data_table[3].feg[0].cnl[4] = 74.8684000000; data_table[3].feg[0].cl[5] = 0.0000000000; data_table[3].feg[0].cnl[5] = 0.0000000000; + data_table[4].feg[0].cl[0] = 0.0436000000; data_table[4].feg[0].cnl[0] = 0.1207000000; data_table[4].feg[0].cl[1] = 0.1898000000; data_table[4].feg[0].cnl[1] = 1.1595000000; data_table[4].feg[0].cl[2] = 0.6788000000; data_table[4].feg[0].cnl[2] = 6.2474000000; data_table[4].feg[0].cl[3] = 1.3273000000; data_table[4].feg[0].cnl[3] = 21.0460000000; data_table[4].feg[0].cl[4] = 0.5544000000; data_table[4].feg[0].cnl[4] = 59.3619000000; data_table[4].feg[0].cl[5] = 0.0000000000; data_table[4].feg[0].cnl[5] = 0.0000000000; + data_table[5].feg[0].cl[0] = 0.0489000000; data_table[5].feg[0].cnl[0] = 0.1140000000; data_table[5].feg[0].cl[1] = 0.2091000000; data_table[5].feg[0].cnl[1] = 1.0825000000; data_table[5].feg[0].cl[2] = 0.7537000000; data_table[5].feg[0].cnl[2] = 5.4281000000; data_table[5].feg[0].cl[3] = 1.1420000000; data_table[5].feg[0].cnl[3] = 17.8811000000; data_table[5].feg[0].cl[4] = 0.3555000000; data_table[5].feg[0].cnl[4] = 51.1341000000; data_table[5].feg[0].cl[5] = 0.0000000000; data_table[5].feg[0].cnl[5] = 0.0000000000; + data_table[6].feg[0].cl[0] = 0.0267000000; data_table[6].feg[0].cnl[0] = 0.0541000000; data_table[6].feg[0].cl[1] = 0.1328000000; data_table[6].feg[0].cnl[1] = 0.5165000000; data_table[6].feg[0].cl[2] = 0.5301000000; data_table[6].feg[0].cnl[2] = 2.8207000000; data_table[6].feg[0].cl[3] = 1.1020000000; data_table[6].feg[0].cnl[3] = 10.6297000000; data_table[6].feg[0].cl[4] = 0.4215000000; data_table[6].feg[0].cnl[4] = 34.3764000000; data_table[6].feg[0].cl[5] = 0.0000000000; data_table[6].feg[0].cnl[5] = 0.0000000000; + data_table[7].feg[0].cl[0] = 0.0365000000; data_table[7].feg[0].cnl[0] = 0.0652000000; data_table[7].feg[0].cl[1] = 0.1729000000; data_table[7].feg[0].cnl[1] = 0.6184000000; data_table[7].feg[0].cl[2] = 0.5805000000; data_table[7].feg[0].cnl[2] = 2.9449000000; data_table[7].feg[0].cl[3] = 0.8814000000; data_table[7].feg[0].cnl[3] = 9.6298000000; data_table[7].feg[0].cl[4] = 0.3121000000; data_table[7].feg[0].cnl[4] = 28.2194000000; data_table[7].feg[0].cl[5] = 0.0000000000; data_table[7].feg[0].cnl[5] = 0.0000000000; + data_table[8].feg[0].cl[0] = 0.0382000000; data_table[8].feg[0].cnl[0] = 0.0613000000; data_table[8].feg[0].cl[1] = 0.1822000000; data_table[8].feg[0].cnl[1] = 0.5753000000; data_table[8].feg[0].cl[2] = 0.5972000000; data_table[8].feg[0].cnl[2] = 2.6858000000; data_table[8].feg[0].cl[3] = 0.7707000000; data_table[8].feg[0].cnl[3] = 8.8214000000; data_table[8].feg[0].cl[4] = 0.2130000000; data_table[8].feg[0].cnl[4] = 25.6668000000; data_table[8].feg[0].cl[5] = 0.0000000000; data_table[8].feg[0].cnl[5] = 0.0000000000; + data_table[9].feg[0].cl[0] = 0.0380000000; data_table[9].feg[0].cnl[0] = 0.0554000000; data_table[9].feg[0].cl[1] = 0.1785000000; data_table[9].feg[0].cnl[1] = 0.5087000000; data_table[9].feg[0].cl[2] = 0.5494000000; data_table[9].feg[0].cnl[2] = 2.2639000000; data_table[9].feg[0].cl[3] = 0.6942000000; data_table[9].feg[0].cnl[3] = 7.3316000000; data_table[9].feg[0].cl[4] = 0.1918000000; data_table[9].feg[0].cnl[4] = 21.6912000000; data_table[9].feg[0].cl[5] = 0.0000000000; data_table[9].feg[0].cnl[5] = 0.0000000000; + data_table[10].feg[0].cl[0] = 0.1260000000; data_table[10].feg[0].cnl[0] = 0.1684000000; data_table[10].feg[0].cl[1] = 0.6442000000; data_table[10].feg[0].cnl[1] = 1.7150000000; data_table[10].feg[0].cl[2] = 0.8893000000; data_table[10].feg[0].cnl[2] = 8.8386000000; data_table[10].feg[0].cl[3] = 1.8197000000; data_table[10].feg[0].cnl[3] = 50.8265000000; data_table[10].feg[0].cl[4] = 1.2988000000; data_table[10].feg[0].cnl[4] = 147.2073000000; data_table[10].feg[0].cl[5] = 0.0000000000; data_table[10].feg[0].cnl[5] = 0.0000000000; + data_table[11].feg[0].cl[0] = 0.1130000000; data_table[11].feg[0].cnl[0] = 0.1356000000; data_table[11].feg[0].cl[1] = 0.5575000000; data_table[11].feg[0].cnl[1] = 1.3579000000; data_table[11].feg[0].cl[2] = 0.9046000000; data_table[11].feg[0].cnl[2] = 6.9255000000; data_table[11].feg[0].cl[3] = 2.1580000000; data_table[11].feg[0].cnl[3] = 32.3165000000; data_table[11].feg[0].cl[4] = 1.4735000000; data_table[11].feg[0].cnl[4] = 92.1138000000; data_table[11].feg[0].cl[5] = 0.0000000000; data_table[11].feg[0].cnl[5] = 0.0000000000; + data_table[12].feg[0].cl[0] = 0.1165000000; data_table[12].feg[0].cnl[0] = 0.1295000000; data_table[12].feg[0].cl[1] = 0.5504000000; data_table[12].feg[0].cnl[1] = 1.2619000000; data_table[12].feg[0].cl[2] = 1.0179000000; data_table[12].feg[0].cnl[2] = 6.8242000000; data_table[12].feg[0].cl[3] = 2.6295000000; data_table[12].feg[0].cnl[3] = 28.4577000000; data_table[12].feg[0].cl[4] = 1.5711000000; data_table[12].feg[0].cnl[4] = 88.4750000000; data_table[12].feg[0].cl[5] = 0.0000000000; data_table[12].feg[0].cnl[5] = 0.0000000000; + data_table[13].feg[0].cl[0] = 0.0567000000; data_table[13].feg[0].cnl[0] = 0.0582000000; data_table[13].feg[0].cl[1] = 0.3365000000; data_table[13].feg[0].cnl[1] = 0.6155000000; data_table[13].feg[0].cl[2] = 0.8104000000; data_table[13].feg[0].cnl[2] = 3.2522000000; data_table[13].feg[0].cl[3] = 2.4960000000; data_table[13].feg[0].cnl[3] = 16.7929000000; data_table[13].feg[0].cl[4] = 2.1186000000; data_table[13].feg[0].cnl[4] = 57.6767000000; data_table[13].feg[0].cl[5] = 0.0000000000; data_table[13].feg[0].cnl[5] = 0.0000000000; + data_table[14].feg[0].cl[0] = 0.1005000000; data_table[14].feg[0].cnl[0] = 0.0977000000; data_table[14].feg[0].cl[1] = 0.4615000000; data_table[14].feg[0].cnl[1] = 0.9084000000; data_table[14].feg[0].cl[2] = 1.0663000000; data_table[14].feg[0].cnl[2] = 4.9654000000; data_table[14].feg[0].cl[3] = 2.5854000000; data_table[14].feg[0].cnl[3] = 18.5471000000; data_table[14].feg[0].cl[4] = 1.2725000000; data_table[14].feg[0].cnl[4] = 54.3648000000; data_table[14].feg[0].cl[5] = 0.0000000000; data_table[14].feg[0].cnl[5] = 0.0000000000; + data_table[15].feg[0].cl[0] = 0.0915000000; data_table[15].feg[0].cnl[0] = 0.0838000000; data_table[15].feg[0].cl[1] = 0.4312000000; data_table[15].feg[0].cnl[1] = 0.7788000000; data_table[15].feg[0].cl[2] = 1.0847000000; data_table[15].feg[0].cnl[2] = 4.3462000000; data_table[15].feg[0].cl[3] = 2.4671000000; data_table[15].feg[0].cnl[3] = 15.5846000000; data_table[15].feg[0].cl[4] = 1.0852000000; data_table[15].feg[0].cnl[4] = 44.6365000000; data_table[15].feg[0].cl[5] = 0.0000000000; data_table[15].feg[0].cnl[5] = 0.0000000000; + data_table[16].feg[0].cl[0] = 0.0799000000; data_table[16].feg[0].cnl[0] = 0.0694000000; data_table[16].feg[0].cl[1] = 0.3891000000; data_table[16].feg[0].cnl[1] = 0.6443000000; data_table[16].feg[0].cl[2] = 1.0037000000; data_table[16].feg[0].cnl[2] = 3.5351000000; data_table[16].feg[0].cl[3] = 2.3332000000; data_table[16].feg[0].cnl[3] = 12.5058000000; data_table[16].feg[0].cl[4] = 1.0507000000; data_table[16].feg[0].cnl[4] = 35.8633000000; data_table[16].feg[0].cl[5] = 0.0000000000; data_table[16].feg[0].cnl[5] = 0.0000000000; + data_table[17].feg[0].cl[0] = 0.1044000000; data_table[17].feg[0].cnl[0] = 0.0853000000; data_table[17].feg[0].cl[1] = 0.4551000000; data_table[17].feg[0].cnl[1] = 0.7701000000; data_table[17].feg[0].cl[2] = 1.4232000000; data_table[17].feg[0].cnl[2] = 4.4684000000; data_table[17].feg[0].cl[3] = 2.1533000000; data_table[17].feg[0].cnl[3] = 14.5864000000; data_table[17].feg[0].cl[4] = 0.4459000000; data_table[17].feg[0].cnl[4] = 41.2474000000; data_table[17].feg[0].cl[5] = 0.0000000000; data_table[17].feg[0].cnl[5] = 0.0000000000; + data_table[18].feg[0].cl[0] = 0.2149000000; data_table[18].feg[0].cnl[0] = 0.1660000000; data_table[18].feg[0].cl[1] = 0.8703000000; data_table[18].feg[0].cnl[1] = 1.6906000000; data_table[18].feg[0].cl[2] = 2.4999000000; data_table[18].feg[0].cnl[2] = 8.7447000000; data_table[18].feg[0].cl[3] = 2.3591000000; data_table[18].feg[0].cnl[3] = 46.7825000000; data_table[18].feg[0].cl[4] = 3.0318000000; data_table[18].feg[0].cnl[4] = 165.6923000000; data_table[18].feg[0].cl[5] = 0.0000000000; data_table[18].feg[0].cnl[5] = 0.0000000000; + data_table[19].feg[0].cl[0] = 0.2355000000; data_table[19].feg[0].cnl[0] = 0.1742000000; data_table[19].feg[0].cl[1] = 0.9916000000; data_table[19].feg[0].cnl[1] = 1.8329000000; data_table[19].feg[0].cl[2] = 2.3959000000; data_table[19].feg[0].cnl[2] = 8.8407000000; data_table[19].feg[0].cl[3] = 3.7252000000; data_table[19].feg[0].cnl[3] = 47.4583000000; data_table[19].feg[0].cl[4] = 2.5647000000; data_table[19].feg[0].cnl[4] = 134.9613000000; data_table[19].feg[0].cl[5] = 0.0000000000; data_table[19].feg[0].cnl[5] = 0.0000000000; + data_table[20].feg[0].cl[0] = 0.4636000000; data_table[20].feg[0].cnl[0] = 0.3682000000; data_table[20].feg[0].cl[1] = 2.0802000000; data_table[20].feg[0].cnl[1] = 4.0312000000; data_table[20].feg[0].cl[2] = 2.9003000000; data_table[20].feg[0].cnl[2] = 22.6493000000; data_table[20].feg[0].cl[3] = 1.4193000000; data_table[20].feg[0].cnl[3] = 71.8200000000; data_table[20].feg[0].cl[4] = 2.4323000000; data_table[20].feg[0].cnl[4] = 103.3691000000; data_table[20].feg[0].cl[5] = 0.0000000000; data_table[20].feg[0].cnl[5] = 0.0000000000; + data_table[21].feg[0].cl[0] = 0.2123000000; data_table[21].feg[0].cnl[0] = 0.1399000000; data_table[21].feg[0].cl[1] = 0.8960000000; data_table[21].feg[0].cnl[1] = 1.4568000000; data_table[21].feg[0].cl[2] = 2.1765000000; data_table[21].feg[0].cnl[2] = 6.7534000000; data_table[21].feg[0].cl[3] = 3.0436000000; data_table[21].feg[0].cnl[3] = 33.1168000000; data_table[21].feg[0].cl[4] = 2.4439000000; data_table[21].feg[0].cnl[4] = 101.8238000000; data_table[21].feg[0].cl[5] = 0.0000000000; data_table[21].feg[0].cnl[5] = 0.0000000000; + data_table[22].feg[0].cl[0] = 0.2369000000; data_table[22].feg[0].cnl[0] = 0.1505000000; data_table[22].feg[0].cl[1] = 1.0774000000; data_table[22].feg[0].cnl[1] = 1.6392000000; data_table[22].feg[0].cl[2] = 2.1894000000; data_table[22].feg[0].cnl[2] = 7.5691000000; data_table[22].feg[0].cl[3] = 3.0825000000; data_table[22].feg[0].cnl[3] = 36.8741000000; data_table[22].feg[0].cl[4] = 1.7190000000; data_table[22].feg[0].cnl[4] = 107.8517000000; data_table[22].feg[0].cl[5] = 0.0000000000; data_table[22].feg[0].cnl[5] = 0.0000000000; + data_table[23].feg[0].cl[0] = 0.1970000000; data_table[23].feg[0].cnl[0] = 0.1197000000; data_table[23].feg[0].cl[1] = 0.8228000000; data_table[23].feg[0].cnl[1] = 1.1985000000; data_table[23].feg[0].cl[2] = 2.0200000000; data_table[23].feg[0].cnl[2] = 5.4097000000; data_table[23].feg[0].cl[3] = 2.1717000000; data_table[23].feg[0].cnl[3] = 25.2361000000; data_table[23].feg[0].cl[4] = 1.7516000000; data_table[23].feg[0].cnl[4] = 94.4290000000; data_table[23].feg[0].cl[5] = 0.0000000000; data_table[23].feg[0].cnl[5] = 0.0000000000; + data_table[24].feg[0].cl[0] = 0.1943000000; data_table[24].feg[0].cnl[0] = 0.1135000000; data_table[24].feg[0].cl[1] = 0.8190000000; data_table[24].feg[0].cnl[1] = 1.1313000000; data_table[24].feg[0].cl[2] = 1.9296000000; data_table[24].feg[0].cnl[2] = 5.0341000000; data_table[24].feg[0].cl[3] = 2.4968000000; data_table[24].feg[0].cnl[3] = 24.1798000000; data_table[24].feg[0].cl[4] = 2.0625000000; data_table[24].feg[0].cnl[4] = 80.5598000000; data_table[24].feg[0].cl[5] = 0.0000000000; data_table[24].feg[0].cnl[5] = 0.0000000000; + data_table[25].feg[0].cl[0] = 0.1929000000; data_table[25].feg[0].cnl[0] = 0.1087000000; data_table[25].feg[0].cl[1] = 0.8239000000; data_table[25].feg[0].cnl[1] = 1.0806000000; data_table[25].feg[0].cl[2] = 1.8689000000; data_table[25].feg[0].cnl[2] = 4.7637000000; data_table[25].feg[0].cl[3] = 2.3694000000; data_table[25].feg[0].cnl[3] = 22.8500000000; data_table[25].feg[0].cl[4] = 1.9060000000; data_table[25].feg[0].cnl[4] = 76.7309000000; data_table[25].feg[0].cl[5] = 0.0000000000; data_table[25].feg[0].cnl[5] = 0.0000000000; + data_table[26].feg[0].cl[0] = 0.2186000000; data_table[26].feg[0].cnl[0] = 0.1182000000; data_table[26].feg[0].cl[1] = 0.9861000000; data_table[26].feg[0].cnl[1] = 1.2300000000; data_table[26].feg[0].cl[2] = 1.8540000000; data_table[26].feg[0].cnl[2] = 5.4177000000; data_table[26].feg[0].cl[3] = 2.3258000000; data_table[26].feg[0].cnl[3] = 25.7602000000; data_table[26].feg[0].cl[4] = 1.4685000000; data_table[26].feg[0].cnl[4] = 80.8542000000; data_table[26].feg[0].cl[5] = 0.0000000000; data_table[26].feg[0].cnl[5] = 0.0000000000; + data_table[27].feg[0].cl[0] = 0.2313000000; data_table[27].feg[0].cnl[0] = 0.1210000000; data_table[27].feg[0].cl[1] = 1.0657000000; data_table[27].feg[0].cnl[1] = 1.2691000000; data_table[27].feg[0].cl[2] = 1.8229000000; data_table[27].feg[0].cnl[2] = 5.6870000000; data_table[27].feg[0].cl[3] = 2.2609000000; data_table[27].feg[0].cnl[3] = 27.0917000000; data_table[27].feg[0].cl[4] = 1.1883000000; data_table[27].feg[0].cnl[4] = 83.0285000000; data_table[27].feg[0].cl[5] = 0.0000000000; data_table[27].feg[0].cnl[5] = 0.0000000000; + data_table[28].feg[0].cl[0] = 0.3501000000; data_table[28].feg[0].cnl[0] = 0.1867000000; data_table[28].feg[0].cl[1] = 1.6558000000; data_table[28].feg[0].cnl[1] = 1.9917000000; data_table[28].feg[0].cl[2] = 1.9582000000; data_table[28].feg[0].cnl[2] = 11.3396000000; data_table[28].feg[0].cl[3] = 0.2134000000; data_table[28].feg[0].cnl[3] = 53.2619000000; data_table[28].feg[0].cl[4] = 1.4109000000; data_table[28].feg[0].cnl[4] = 63.2520000000; data_table[28].feg[0].cl[5] = 0.0000000000; data_table[28].feg[0].cnl[5] = 0.0000000000; + data_table[29].feg[0].cl[0] = 0.1780000000; data_table[29].feg[0].cnl[0] = 0.0876000000; data_table[29].feg[0].cl[1] = 0.8096000000; data_table[29].feg[0].cnl[1] = 0.8650000000; data_table[29].feg[0].cl[2] = 1.6744000000; data_table[29].feg[0].cnl[2] = 3.8612000000; data_table[29].feg[0].cl[3] = 1.9499000000; data_table[29].feg[0].cnl[3] = 18.8726000000; data_table[29].feg[0].cl[4] = 1.4495000000; data_table[29].feg[0].cnl[4] = 64.7016000000; data_table[29].feg[0].cl[5] = 0.0000000000; data_table[29].feg[0].cnl[5] = 0.0000000000; + data_table[30].feg[0].cl[0] = 0.2135000000; data_table[30].feg[0].cnl[0] = 0.1020000000; data_table[30].feg[0].cl[1] = 0.9768000000; data_table[30].feg[0].cnl[1] = 1.0219000000; data_table[30].feg[0].cl[2] = 1.6669000000; data_table[30].feg[0].cnl[2] = 4.6275000000; data_table[30].feg[0].cl[3] = 2.5662000000; data_table[30].feg[0].cnl[3] = 22.8742000000; data_table[30].feg[0].cl[4] = 1.6790000000; data_table[30].feg[0].cnl[4] = 80.1535000000; data_table[30].feg[0].cl[5] = 0.0000000000; data_table[30].feg[0].cnl[5] = 0.0000000000; + data_table[31].feg[0].cl[0] = 0.2135000000; data_table[31].feg[0].cnl[0] = 0.0989000000; data_table[31].feg[0].cl[1] = 0.9761000000; data_table[31].feg[0].cnl[1] = 0.9845000000; data_table[31].feg[0].cl[2] = 1.6555000000; data_table[31].feg[0].cnl[2] = 4.5527000000; data_table[31].feg[0].cl[3] = 2.8938000000; data_table[31].feg[0].cnl[3] = 21.5563000000; data_table[31].feg[0].cl[4] = 1.6356000000; data_table[31].feg[0].cnl[4] = 70.3903000000; data_table[31].feg[0].cl[5] = 0.0000000000; data_table[31].feg[0].cnl[5] = 0.0000000000; + data_table[32].feg[0].cl[0] = 0.2059000000; data_table[32].feg[0].cnl[0] = 0.0926000000; data_table[32].feg[0].cl[1] = 0.9518000000; data_table[32].feg[0].cnl[1] = 0.9182000000; data_table[32].feg[0].cl[2] = 1.6372000000; data_table[32].feg[0].cnl[2] = 4.3291000000; data_table[32].feg[0].cl[3] = 3.0490000000; data_table[32].feg[0].cnl[3] = 19.2996000000; data_table[32].feg[0].cl[4] = 1.4756000000; data_table[32].feg[0].cnl[4] = 58.9329000000; data_table[32].feg[0].cl[5] = 0.0000000000; data_table[32].feg[0].cnl[5] = 0.0000000000; + data_table[33].feg[0].cl[0] = 0.1574000000; data_table[33].feg[0].cnl[0] = 0.0686000000; data_table[33].feg[0].cl[1] = 0.7614000000; data_table[33].feg[0].cnl[1] = 0.6808000000; data_table[33].feg[0].cl[2] = 1.4834000000; data_table[33].feg[0].cnl[2] = 3.1163000000; data_table[33].feg[0].cl[3] = 3.0016000000; data_table[33].feg[0].cnl[3] = 14.3458000000; data_table[33].feg[0].cl[4] = 1.7978000000; data_table[33].feg[0].cnl[4] = 44.0455000000; data_table[33].feg[0].cl[5] = 0.0000000000; data_table[33].feg[0].cnl[5] = 0.0000000000; + data_table[34].feg[0].cl[0] = 0.1899000000; data_table[34].feg[0].cnl[0] = 0.0810000000; data_table[34].feg[0].cl[1] = 0.8983000000; data_table[34].feg[0].cnl[1] = 0.7957000000; data_table[34].feg[0].cl[2] = 1.6358000000; data_table[34].feg[0].cnl[2] = 3.9054000000; data_table[34].feg[0].cl[3] = 3.1845000000; data_table[34].feg[0].cnl[3] = 15.7701000000; data_table[34].feg[0].cl[4] = 1.1518000000; data_table[34].feg[0].cnl[4] = 45.6124000000; data_table[34].feg[0].cl[5] = 0.0000000000; data_table[34].feg[0].cnl[5] = 0.0000000000; + data_table[35].feg[0].cl[0] = 0.1742000000; data_table[35].feg[0].cnl[0] = 0.0723000000; data_table[35].feg[0].cl[1] = 0.8447000000; data_table[35].feg[0].cnl[1] = 0.7123000000; data_table[35].feg[0].cl[2] = 1.5944000000; data_table[35].feg[0].cnl[2] = 3.5192000000; data_table[35].feg[0].cl[3] = 3.1507000000; data_table[35].feg[0].cnl[3] = 13.7724000000; data_table[35].feg[0].cl[4] = 1.1338000000; data_table[35].feg[0].cnl[4] = 39.1148000000; data_table[35].feg[0].cl[5] = 0.0000000000; data_table[35].feg[0].cnl[5] = 0.0000000000; + data_table[36].feg[0].cl[0] = 0.3781000000; data_table[36].feg[0].cnl[0] = 0.1557000000; data_table[36].feg[0].cl[1] = 1.4904000000; data_table[36].feg[0].cnl[1] = 1.5347000000; data_table[36].feg[0].cl[2] = 3.5753000000; data_table[36].feg[0].cnl[2] = 9.9947000000; data_table[36].feg[0].cl[3] = 3.0031000000; data_table[36].feg[0].cnl[3] = 51.4251000000; data_table[36].feg[0].cl[4] = 3.3272000000; data_table[36].feg[0].cnl[4] = 185.9828000000; data_table[36].feg[0].cl[5] = 0.0000000000; data_table[36].feg[0].cnl[5] = 0.0000000000; + data_table[37].feg[0].cl[0] = 0.3723000000; data_table[37].feg[0].cnl[0] = 0.1480000000; data_table[37].feg[0].cl[1] = 1.4598000000; data_table[37].feg[0].cnl[1] = 1.4643000000; data_table[37].feg[0].cl[2] = 3.5124000000; data_table[37].feg[0].cnl[2] = 9.2320000000; data_table[37].feg[0].cl[3] = 4.4612000000; data_table[37].feg[0].cnl[3] = 49.8807000000; data_table[37].feg[0].cl[4] = 3.3031000000; data_table[37].feg[0].cnl[4] = 148.0937000000; data_table[37].feg[0].cl[5] = 0.0000000000; data_table[37].feg[0].cnl[5] = 0.0000000000; + data_table[38].feg[0].cl[0] = 0.3234000000; data_table[38].feg[0].cnl[0] = 0.1244000000; data_table[38].feg[0].cl[1] = 1.2737000000; data_table[38].feg[0].cnl[1] = 1.1948000000; data_table[38].feg[0].cl[2] = 3.2115000000; data_table[38].feg[0].cnl[2] = 7.2756000000; data_table[38].feg[0].cl[3] = 4.0563000000; data_table[38].feg[0].cnl[3] = 34.1430000000; data_table[38].feg[0].cl[4] = 3.7962000000; data_table[38].feg[0].cnl[4] = 111.2079000000; data_table[38].feg[0].cl[5] = 0.0000000000; data_table[38].feg[0].cnl[5] = 0.0000000000; + data_table[39].feg[0].cl[0] = 0.2997000000; data_table[39].feg[0].cnl[0] = 0.1121000000; data_table[39].feg[0].cl[1] = 1.1879000000; data_table[39].feg[0].cnl[1] = 1.0638000000; data_table[39].feg[0].cl[2] = 3.1075000000; data_table[39].feg[0].cnl[2] = 6.3891000000; data_table[39].feg[0].cl[3] = 3.9740000000; data_table[39].feg[0].cnl[3] = 28.7081000000; data_table[39].feg[0].cl[4] = 3.5769000000; data_table[39].feg[0].cnl[4] = 97.4289000000; data_table[39].feg[0].cl[5] = 0.0000000000; data_table[39].feg[0].cnl[5] = 0.0000000000; + data_table[40].feg[0].cl[0] = 0.1680000000; data_table[40].feg[0].cnl[0] = 0.0597000000; data_table[40].feg[0].cl[1] = 0.9370000000; data_table[40].feg[0].cnl[1] = 0.6524000000; data_table[40].feg[0].cl[2] = 2.7300000000; data_table[40].feg[0].cnl[2] = 4.4317000000; data_table[40].feg[0].cl[3] = 3.8150000000; data_table[40].feg[0].cnl[3] = 19.5540000000; data_table[40].feg[0].cl[4] = 3.0053000000; data_table[40].feg[0].cnl[4] = 85.5011000000; data_table[40].feg[0].cl[5] = 0.0000000000; data_table[40].feg[0].cnl[5] = 0.0000000000; + data_table[41].feg[0].cl[0] = 0.3069000000; data_table[41].feg[0].cnl[0] = 0.1101000000; data_table[41].feg[0].cl[1] = 1.1714000000; data_table[41].feg[0].cnl[1] = 1.0222000000; data_table[41].feg[0].cl[2] = 3.2293000000; data_table[41].feg[0].cnl[2] = 5.9613000000; data_table[41].feg[0].cl[3] = 3.4254000000; data_table[41].feg[0].cnl[3] = 25.1965000000; data_table[41].feg[0].cl[4] = 2.1224000000; data_table[41].feg[0].cnl[4] = 93.5831000000; data_table[41].feg[0].cl[5] = 0.0000000000; data_table[41].feg[0].cnl[5] = 0.0000000000; + data_table[42].feg[0].cl[0] = 0.2928000000; data_table[42].feg[0].cnl[0] = 0.1020000000; data_table[42].feg[0].cl[1] = 1.1267000000; data_table[42].feg[0].cnl[1] = 0.9481000000; data_table[42].feg[0].cl[2] = 3.1675000000; data_table[42].feg[0].cnl[2] = 5.4713000000; data_table[42].feg[0].cl[3] = 3.6619000000; data_table[42].feg[0].cnl[3] = 23.8153000000; data_table[42].feg[0].cl[4] = 2.5942000000; data_table[42].feg[0].cnl[4] = 82.8991000000; data_table[42].feg[0].cl[5] = 0.0000000000; data_table[42].feg[0].cnl[5] = 0.0000000000; + data_table[43].feg[0].cl[0] = 0.2604000000; data_table[43].feg[0].cnl[0] = 0.0887000000; data_table[43].feg[0].cl[1] = 1.0442000000; data_table[43].feg[0].cnl[1] = 0.8240000000; data_table[43].feg[0].cl[2] = 3.0761000000; data_table[43].feg[0].cnl[2] = 4.8278000000; data_table[43].feg[0].cl[3] = 3.2175000000; data_table[43].feg[0].cnl[3] = 19.8977000000; data_table[43].feg[0].cl[4] = 1.9448000000; data_table[43].feg[0].cnl[4] = 80.4566000000; data_table[43].feg[0].cl[5] = 0.0000000000; data_table[43].feg[0].cnl[5] = 0.0000000000; + data_table[44].feg[0].cl[0] = 0.2713000000; data_table[44].feg[0].cnl[0] = 0.0907000000; data_table[44].feg[0].cl[1] = 1.0556000000; data_table[44].feg[0].cnl[1] = 0.8324000000; data_table[44].feg[0].cl[2] = 3.1416000000; data_table[44].feg[0].cnl[2] = 4.7702000000; data_table[44].feg[0].cl[3] = 3.0451000000; data_table[44].feg[0].cnl[3] = 19.7862000000; data_table[44].feg[0].cl[4] = 1.7179000000; data_table[44].feg[0].cnl[4] = 80.2540000000; data_table[44].feg[0].cl[5] = 0.0000000000; data_table[44].feg[0].cnl[5] = 0.0000000000; + data_table[45].feg[0].cl[0] = 0.2003000000; data_table[45].feg[0].cnl[0] = 0.0659000000; data_table[45].feg[0].cl[1] = 0.8779000000; data_table[45].feg[0].cnl[1] = 0.6111000000; data_table[45].feg[0].cl[2] = 2.6135000000; data_table[45].feg[0].cnl[2] = 3.5563000000; data_table[45].feg[0].cl[3] = 2.8594000000; data_table[45].feg[0].cnl[3] = 12.7638000000; data_table[45].feg[0].cl[4] = 1.0258000000; data_table[45].feg[0].cnl[4] = 44.4283000000; data_table[45].feg[0].cl[5] = 0.0000000000; data_table[45].feg[0].cnl[5] = 0.0000000000; + data_table[46].feg[0].cl[0] = 0.2739000000; data_table[46].feg[0].cnl[0] = 0.0881000000; data_table[46].feg[0].cl[1] = 1.0503000000; data_table[46].feg[0].cnl[1] = 0.8028000000; data_table[46].feg[0].cl[2] = 3.1564000000; data_table[46].feg[0].cnl[2] = 4.4451000000; data_table[46].feg[0].cl[3] = 2.7543000000; data_table[46].feg[0].cnl[3] = 18.7011000000; data_table[46].feg[0].cl[4] = 1.4328000000; data_table[46].feg[0].cnl[4] = 79.2633000000; data_table[46].feg[0].cl[5] = 0.0000000000; data_table[46].feg[0].cnl[5] = 0.0000000000; + data_table[47].feg[0].cl[0] = 0.3072000000; data_table[47].feg[0].cnl[0] = 0.0966000000; data_table[47].feg[0].cl[1] = 1.1303000000; data_table[47].feg[0].cnl[1] = 0.8856000000; data_table[47].feg[0].cl[2] = 3.2046000000; data_table[47].feg[0].cnl[2] = 4.6273000000; data_table[47].feg[0].cl[3] = 2.9329000000; data_table[47].feg[0].cnl[3] = 20.6789000000; data_table[47].feg[0].cl[4] = 1.6560000000; data_table[47].feg[0].cnl[4] = 73.4723000000; data_table[47].feg[0].cl[5] = 0.0000000000; data_table[47].feg[0].cnl[5] = 0.0000000000; + data_table[48].feg[0].cl[0] = 0.3564000000; data_table[48].feg[0].cnl[0] = 0.1091000000; data_table[48].feg[0].cl[1] = 1.3011000000; data_table[48].feg[0].cnl[1] = 1.0452000000; data_table[48].feg[0].cl[2] = 3.2424000000; data_table[48].feg[0].cnl[2] = 5.0900000000; data_table[48].feg[0].cl[3] = 3.4839000000; data_table[48].feg[0].cnl[3] = 24.6578000000; data_table[48].feg[0].cl[4] = 2.0459000000; data_table[48].feg[0].cnl[4] = 88.0513000000; data_table[48].feg[0].cl[5] = 0.0000000000; data_table[48].feg[0].cnl[5] = 0.0000000000; + data_table[49].feg[0].cl[0] = 0.2966000000; data_table[49].feg[0].cnl[0] = 0.0896000000; data_table[49].feg[0].cl[1] = 1.1157000000; data_table[49].feg[0].cnl[1] = 0.8268000000; data_table[49].feg[0].cl[2] = 3.0973000000; data_table[49].feg[0].cnl[2] = 4.2242000000; data_table[49].feg[0].cl[3] = 3.8156000000; data_table[49].feg[0].cnl[3] = 20.6900000000; data_table[49].feg[0].cl[4] = 2.5281000000; data_table[49].feg[0].cnl[4] = 71.3399000000; data_table[49].feg[0].cl[5] = 0.0000000000; data_table[49].feg[0].cnl[5] = 0.0000000000; + data_table[50].feg[0].cl[0] = 0.2725000000; data_table[50].feg[0].cnl[0] = 0.0809000000; data_table[50].feg[0].cl[1] = 1.0651000000; data_table[50].feg[0].cnl[1] = 0.7488000000; data_table[50].feg[0].cl[2] = 2.9940000000; data_table[50].feg[0].cnl[2] = 3.8710000000; data_table[50].feg[0].cl[3] = 4.0697000000; data_table[50].feg[0].cnl[3] = 18.8800000000; data_table[50].feg[0].cl[4] = 2.5682000000; data_table[50].feg[0].cnl[4] = 60.6499000000; data_table[50].feg[0].cl[5] = 0.0000000000; data_table[50].feg[0].cnl[5] = 0.0000000000; + data_table[51].feg[0].cl[0] = 0.2422000000; data_table[51].feg[0].cnl[0] = 0.0708000000; data_table[51].feg[0].cl[1] = 0.9692000000; data_table[51].feg[0].cnl[1] = 0.6472000000; data_table[51].feg[0].cl[2] = 2.8114000000; data_table[51].feg[0].cnl[2] = 3.3609000000; data_table[51].feg[0].cl[3] = 4.1509000000; data_table[51].feg[0].cnl[3] = 16.0752000000; data_table[51].feg[0].cl[4] = 2.8161000000; data_table[51].feg[0].cnl[4] = 50.1724000000; data_table[51].feg[0].cl[5] = 0.0000000000; data_table[51].feg[0].cnl[5] = 0.0000000000; + data_table[52].feg[0].cl[0] = 0.2617000000; data_table[52].feg[0].cnl[0] = 0.0749000000; data_table[52].feg[0].cl[1] = 1.0325000000; data_table[52].feg[0].cnl[1] = 0.6914000000; data_table[52].feg[0].cl[2] = 2.8097000000; data_table[52].feg[0].cnl[2] = 3.4634000000; data_table[52].feg[0].cl[3] = 4.4809000000; data_table[52].feg[0].cnl[3] = 16.3603000000; data_table[52].feg[0].cl[4] = 2.3190000000; data_table[52].feg[0].cnl[4] = 48.2522000000; data_table[52].feg[0].cl[5] = 0.0000000000; data_table[52].feg[0].cnl[5] = 0.0000000000; + data_table[53].feg[0].cl[0] = 0.2334000000; data_table[53].feg[0].cnl[0] = 0.0655000000; data_table[53].feg[0].cl[1] = 0.9496000000; data_table[53].feg[0].cnl[1] = 0.6050000000; data_table[53].feg[0].cl[2] = 2.6381000000; data_table[53].feg[0].cnl[2] = 3.0389000000; data_table[53].feg[0].cl[3] = 4.4680000000; data_table[53].feg[0].cnl[3] = 14.0809000000; data_table[53].feg[0].cl[4] = 2.5020000000; data_table[53].feg[0].cnl[4] = 41.0005000000; data_table[53].feg[0].cl[5] = 0.0000000000; data_table[53].feg[0].cnl[5] = 0.0000000000; + data_table[54].feg[0].cl[0] = 0.5713000000; data_table[54].feg[0].cnl[0] = 0.1626000000; data_table[54].feg[0].cl[1] = 2.4866000000; data_table[54].feg[0].cnl[1] = 1.8213000000; data_table[54].feg[0].cl[2] = 4.9795000000; data_table[54].feg[0].cnl[2] = 11.1049000000; data_table[54].feg[0].cl[3] = 4.0198000000; data_table[54].feg[0].cnl[3] = 49.0568000000; data_table[54].feg[0].cl[4] = 4.4403000000; data_table[54].feg[0].cnl[4] = 202.9987000000; data_table[54].feg[0].cl[5] = 0.0000000000; data_table[54].feg[0].cnl[5] = 0.0000000000; + data_table[55].feg[0].cl[0] = 0.5229000000; data_table[55].feg[0].cnl[0] = 0.1434000000; data_table[55].feg[0].cl[1] = 2.2874000000; data_table[55].feg[0].cnl[1] = 1.6019000000; data_table[55].feg[0].cl[2] = 4.7243000000; data_table[55].feg[0].cnl[2] = 9.4511000000; data_table[55].feg[0].cl[3] = 5.0807000000; data_table[55].feg[0].cnl[3] = 42.7685000000; data_table[55].feg[0].cl[4] = 5.6389000000; data_table[55].feg[0].cnl[4] = 148.4969000000; data_table[55].feg[0].cl[5] = 0.0000000000; data_table[55].feg[0].cnl[5] = 0.0000000000; + data_table[56].feg[0].cl[0] = 0.5461000000; data_table[56].feg[0].cnl[0] = 0.1479000000; data_table[56].feg[0].cl[1] = 2.3856000000; data_table[56].feg[0].cnl[1] = 1.6552000000; data_table[56].feg[0].cl[2] = 5.0653000000; data_table[56].feg[0].cnl[2] = 10.0059000000; data_table[56].feg[0].cl[3] = 5.7601000000; data_table[56].feg[0].cnl[3] = 47.3245000000; data_table[56].feg[0].cl[4] = 4.0463000000; data_table[56].feg[0].cnl[4] = 145.8464000000; data_table[56].feg[0].cl[5] = 0.0000000000; data_table[56].feg[0].cnl[5] = 0.0000000000; + data_table[57].feg[0].cl[0] = 0.2227000000; data_table[57].feg[0].cnl[0] = 0.0571000000; data_table[57].feg[0].cl[1] = 1.0760000000; data_table[57].feg[0].cnl[1] = 0.5946000000; data_table[57].feg[0].cl[2] = 2.9482000000; data_table[57].feg[0].cnl[2] = 3.2022000000; data_table[57].feg[0].cl[3] = 5.8496000000; data_table[57].feg[0].cnl[3] = 16.4253000000; data_table[57].feg[0].cl[4] = 7.1834000000; data_table[57].feg[0].cnl[4] = 95.7030000000; data_table[57].feg[0].cl[5] = 0.0000000000; data_table[57].feg[0].cnl[5] = 0.0000000000; + data_table[58].feg[0].cl[0] = 0.5237000000; data_table[58].feg[0].cnl[0] = 0.1360000000; data_table[58].feg[0].cl[1] = 2.2913000000; data_table[58].feg[0].cnl[1] = 1.5068000000; data_table[58].feg[0].cl[2] = 4.6161000000; data_table[58].feg[0].cnl[2] = 8.8213000000; data_table[58].feg[0].cl[3] = 4.7233000000; data_table[58].feg[0].cnl[3] = 41.9536000000; data_table[58].feg[0].cl[4] = 4.8173000000; data_table[58].feg[0].cnl[4] = 141.2424000000; data_table[58].feg[0].cl[5] = 0.0000000000; data_table[58].feg[0].cnl[5] = 0.0000000000; + data_table[59].feg[0].cl[0] = 0.5368000000; data_table[59].feg[0].cnl[0] = 0.1378000000; data_table[59].feg[0].cl[1] = 2.3301000000; data_table[59].feg[0].cnl[1] = 1.5140000000; data_table[59].feg[0].cl[2] = 4.6058000000; data_table[59].feg[0].cnl[2] = 8.8719000000; data_table[59].feg[0].cl[3] = 4.6621000000; data_table[59].feg[0].cnl[3] = 43.5967000000; data_table[59].feg[0].cl[4] = 4.4622000000; data_table[59].feg[0].cnl[4] = 141.8065000000; data_table[59].feg[0].cl[5] = 0.0000000000; data_table[59].feg[0].cnl[5] = 0.0000000000; + data_table[60].feg[0].cl[0] = 0.5232000000; data_table[60].feg[0].cnl[0] = 0.1317000000; data_table[60].feg[0].cl[1] = 2.2627000000; data_table[60].feg[0].cnl[1] = 1.4336000000; data_table[60].feg[0].cl[2] = 4.4552000000; data_table[60].feg[0].cnl[2] = 8.3087000000; data_table[60].feg[0].cl[3] = 4.4787000000; data_table[60].feg[0].cnl[3] = 40.6010000000; data_table[60].feg[0].cl[4] = 4.5073000000; data_table[60].feg[0].cnl[4] = 135.9196000000; data_table[60].feg[0].cl[5] = 0.0000000000; data_table[60].feg[0].cnl[5] = 0.0000000000; + data_table[61].feg[0].cl[0] = 0.5162000000; data_table[61].feg[0].cnl[0] = 0.1279000000; data_table[61].feg[0].cl[1] = 2.2302000000; data_table[61].feg[0].cnl[1] = 1.3811000000; data_table[61].feg[0].cl[2] = 4.3449000000; data_table[61].feg[0].cnl[2] = 7.9629000000; data_table[61].feg[0].cl[3] = 4.3598000000; data_table[61].feg[0].cnl[3] = 39.1213000000; data_table[61].feg[0].cl[4] = 4.4292000000; data_table[61].feg[0].cnl[4] = 132.7846000000; data_table[61].feg[0].cl[5] = 0.0000000000; data_table[61].feg[0].cnl[5] = 0.0000000000; + data_table[62].feg[0].cl[0] = 0.5272000000; data_table[62].feg[0].cnl[0] = 0.1285000000; data_table[62].feg[0].cl[1] = 2.2844000000; data_table[62].feg[0].cnl[1] = 1.3943000000; data_table[62].feg[0].cl[2] = 4.3361000000; data_table[62].feg[0].cnl[2] = 8.1081000000; data_table[62].feg[0].cl[3] = 4.3178000000; data_table[62].feg[0].cnl[3] = 40.9631000000; data_table[62].feg[0].cl[4] = 4.0908000000; data_table[62].feg[0].cnl[4] = 134.1233000000; data_table[62].feg[0].cl[5] = 0.0000000000; data_table[62].feg[0].cnl[5] = 0.0000000000; + data_table[63].feg[0].cl[0] = 0.9664000000; data_table[63].feg[0].cnl[0] = 0.2641000000; data_table[63].feg[0].cl[1] = 3.4052000000; data_table[63].feg[0].cnl[1] = 2.6586000000; data_table[63].feg[0].cl[2] = 5.0803000000; data_table[63].feg[0].cnl[2] = 16.2213000000; data_table[63].feg[0].cl[3] = 1.4991000000; data_table[63].feg[0].cnl[3] = 80.2060000000; data_table[63].feg[0].cl[4] = 4.2528000000; data_table[63].feg[0].cnl[4] = 92.5359000000; data_table[63].feg[0].cl[5] = 0.0000000000; data_table[63].feg[0].cnl[5] = 0.0000000000; + data_table[64].feg[0].cl[0] = 0.5110000000; data_table[64].feg[0].cnl[0] = 0.1210000000; data_table[64].feg[0].cl[1] = 2.1570000000; data_table[64].feg[0].cnl[1] = 1.2704000000; data_table[64].feg[0].cl[2] = 4.0308000000; data_table[64].feg[0].cnl[2] = 7.1368000000; data_table[64].feg[0].cl[3] = 3.9936000000; data_table[64].feg[0].cnl[3] = 35.0354000000; data_table[64].feg[0].cl[4] = 4.2466000000; data_table[64].feg[0].cnl[4] = 123.5062000000; data_table[64].feg[0].cl[5] = 0.0000000000; data_table[64].feg[0].cnl[5] = 0.0000000000; + data_table[65].feg[0].cl[0] = 0.4974000000; data_table[65].feg[0].cnl[0] = 0.1157000000; data_table[65].feg[0].cl[1] = 2.1097000000; data_table[65].feg[0].cnl[1] = 1.2108000000; data_table[65].feg[0].cl[2] = 3.8906000000; data_table[65].feg[0].cnl[2] = 6.7377000000; data_table[65].feg[0].cl[3] = 3.8100000000; data_table[65].feg[0].cnl[3] = 32.4150000000; data_table[65].feg[0].cl[4] = 4.3084000000; data_table[65].feg[0].cnl[4] = 116.9225000000; data_table[65].feg[0].cl[5] = 0.0000000000; data_table[65].feg[0].cnl[5] = 0.0000000000; + data_table[66].feg[0].cl[0] = 0.4679000000; data_table[66].feg[0].cnl[0] = 0.1069000000; data_table[66].feg[0].cl[1] = 1.9693000000; data_table[66].feg[0].cnl[1] = 1.0994000000; data_table[66].feg[0].cl[2] = 3.7191000000; data_table[66].feg[0].cnl[2] = 5.9769000000; data_table[66].feg[0].cl[3] = 3.9632000000; data_table[66].feg[0].cnl[3] = 27.1491000000; data_table[66].feg[0].cl[4] = 4.2432000000; data_table[66].feg[0].cnl[4] = 96.3119000000; data_table[66].feg[0].cl[5] = 0.0000000000; data_table[66].feg[0].cnl[5] = 0.0000000000; + data_table[67].feg[0].cl[0] = 0.5034000000; data_table[67].feg[0].cnl[0] = 0.1141000000; data_table[67].feg[0].cl[1] = 2.1088000000; data_table[67].feg[0].cnl[1] = 1.1769000000; data_table[67].feg[0].cl[2] = 3.8232000000; data_table[67].feg[0].cnl[2] = 6.6087000000; data_table[67].feg[0].cl[3] = 3.7299000000; data_table[67].feg[0].cnl[3] = 33.4332000000; data_table[67].feg[0].cl[4] = 3.8963000000; data_table[67].feg[0].cnl[4] = 116.4913000000; data_table[67].feg[0].cl[5] = 0.0000000000; data_table[67].feg[0].cnl[5] = 0.0000000000; + data_table[68].feg[0].cl[0] = 0.4839000000; data_table[68].feg[0].cnl[0] = 0.1081000000; data_table[68].feg[0].cl[1] = 2.0262000000; data_table[68].feg[0].cnl[1] = 1.1012000000; data_table[68].feg[0].cl[2] = 3.6851000000; data_table[68].feg[0].cnl[2] = 6.1114000000; data_table[68].feg[0].cl[3] = 3.5874000000; data_table[68].feg[0].cnl[3] = 30.3728000000; data_table[68].feg[0].cl[4] = 4.0037000000; data_table[68].feg[0].cnl[4] = 110.5988000000; data_table[68].feg[0].cl[5] = 0.0000000000; data_table[68].feg[0].cnl[5] = 0.0000000000; + data_table[69].feg[0].cl[0] = 0.5221000000; data_table[69].feg[0].cnl[0] = 0.1148000000; data_table[69].feg[0].cl[1] = 2.1695000000; data_table[69].feg[0].cnl[1] = 1.1860000000; data_table[69].feg[0].cl[2] = 3.7567000000; data_table[69].feg[0].cnl[2] = 6.7520000000; data_table[69].feg[0].cl[3] = 3.6685000000; data_table[69].feg[0].cnl[3] = 35.6807000000; data_table[69].feg[0].cl[4] = 3.4274000000; data_table[69].feg[0].cnl[4] = 118.0692000000; data_table[69].feg[0].cl[5] = 0.0000000000; data_table[69].feg[0].cnl[5] = 0.0000000000; + data_table[70].feg[0].cl[0] = 0.4680000000; data_table[70].feg[0].cnl[0] = 0.1015000000; data_table[70].feg[0].cl[1] = 1.9466000000; data_table[70].feg[0].cnl[1] = 1.0195000000; data_table[70].feg[0].cl[2] = 3.5428000000; data_table[70].feg[0].cnl[2] = 5.6058000000; data_table[70].feg[0].cl[3] = 3.8490000000; data_table[70].feg[0].cnl[3] = 27.4899000000; data_table[70].feg[0].cl[4] = 3.6594000000; data_table[70].feg[0].cnl[4] = 95.2846000000; data_table[70].feg[0].cl[5] = 0.0000000000; data_table[70].feg[0].cnl[5] = 0.0000000000; + data_table[71].feg[0].cl[0] = 0.4048000000; data_table[71].feg[0].cnl[0] = 0.0868000000; data_table[71].feg[0].cl[1] = 1.7370000000; data_table[71].feg[0].cnl[1] = 0.8585000000; data_table[71].feg[0].cl[2] = 3.3399000000; data_table[71].feg[0].cnl[2] = 4.6378000000; data_table[71].feg[0].cl[3] = 3.9448000000; data_table[71].feg[0].cnl[3] = 21.6900000000; data_table[71].feg[0].cl[4] = 3.7293000000; data_table[71].feg[0].cnl[4] = 80.2408000000; data_table[71].feg[0].cl[5] = 0.0000000000; data_table[71].feg[0].cnl[5] = 0.0000000000; + data_table[72].feg[0].cl[0] = 0.3835000000; data_table[72].feg[0].cnl[0] = 0.0810000000; data_table[72].feg[0].cl[1] = 1.6747000000; data_table[72].feg[0].cnl[1] = 0.8020000000; data_table[72].feg[0].cl[2] = 3.2986000000; data_table[72].feg[0].cnl[2] = 4.3545000000; data_table[72].feg[0].cl[3] = 4.0462000000; data_table[72].feg[0].cnl[3] = 19.9644000000; data_table[72].feg[0].cl[4] = 3.4303000000; data_table[72].feg[0].cnl[4] = 73.6337000000; data_table[72].feg[0].cl[5] = 0.0000000000; data_table[72].feg[0].cnl[5] = 0.0000000000; + data_table[73].feg[0].cl[0] = 0.3661000000; data_table[73].feg[0].cnl[0] = 0.0761000000; data_table[73].feg[0].cl[1] = 1.6191000000; data_table[73].feg[0].cnl[1] = 0.7543000000; data_table[73].feg[0].cl[2] = 3.2455000000; data_table[73].feg[0].cnl[2] = 4.0952000000; data_table[73].feg[0].cl[3] = 4.0856000000; data_table[73].feg[0].cnl[3] = 18.2886000000; data_table[73].feg[0].cl[4] = 3.2064000000; data_table[73].feg[0].cnl[4] = 68.0967000000; data_table[73].feg[0].cl[5] = 0.0000000000; data_table[73].feg[0].cnl[5] = 0.0000000000; + data_table[74].feg[0].cl[0] = 0.3933000000; data_table[74].feg[0].cnl[0] = 0.0806000000; data_table[74].feg[0].cl[1] = 1.6973000000; data_table[74].feg[0].cnl[1] = 0.7972000000; data_table[74].feg[0].cl[2] = 3.4202000000; data_table[74].feg[0].cnl[2] = 4.4237000000; data_table[74].feg[0].cl[3] = 4.1274000000; data_table[74].feg[0].cnl[3] = 19.5692000000; data_table[74].feg[0].cl[4] = 2.6158000000; data_table[74].feg[0].cnl[4] = 68.7477000000; data_table[74].feg[0].cl[5] = 0.0000000000; data_table[74].feg[0].cnl[5] = 0.0000000000; + data_table[75].feg[0].cl[0] = 0.3854000000; data_table[75].feg[0].cnl[0] = 0.0787000000; data_table[75].feg[0].cl[1] = 1.6555000000; data_table[75].feg[0].cnl[1] = 0.7638000000; data_table[75].feg[0].cl[2] = 3.4129000000; data_table[75].feg[0].cnl[2] = 4.2441000000; data_table[75].feg[0].cl[3] = 4.1111000000; data_table[75].feg[0].cnl[3] = 18.3700000000; data_table[75].feg[0].cl[4] = 2.4106000000; data_table[75].feg[0].cnl[4] = 65.1071000000; data_table[75].feg[0].cl[5] = 0.0000000000; data_table[75].feg[0].cnl[5] = 0.0000000000; + data_table[76].feg[0].cl[0] = 0.3510000000; data_table[76].feg[0].cnl[0] = 0.0706000000; data_table[76].feg[0].cl[1] = 1.5620000000; data_table[76].feg[0].cnl[1] = 0.6904000000; data_table[76].feg[0].cl[2] = 3.2946000000; data_table[76].feg[0].cnl[2] = 3.8266000000; data_table[76].feg[0].cl[3] = 4.0615000000; data_table[76].feg[0].cnl[3] = 16.0812000000; data_table[76].feg[0].cl[4] = 2.4382000000; data_table[76].feg[0].cnl[4] = 58.7638000000; data_table[76].feg[0].cl[5] = 0.0000000000; data_table[76].feg[0].cnl[5] = 0.0000000000; + data_table[77].feg[0].cl[0] = 0.3083000000; data_table[77].feg[0].cnl[0] = 0.0609000000; data_table[77].feg[0].cl[1] = 1.4158000000; data_table[77].feg[0].cnl[1] = 0.5993000000; data_table[77].feg[0].cl[2] = 2.9662000000; data_table[77].feg[0].cnl[2] = 3.1921000000; data_table[77].feg[0].cl[3] = 3.9349000000; data_table[77].feg[0].cnl[3] = 12.5285000000; data_table[77].feg[0].cl[4] = 2.1709000000; data_table[77].feg[0].cnl[4] = 49.7675000000; data_table[77].feg[0].cl[5] = 0.0000000000; data_table[77].feg[0].cnl[5] = 0.0000000000; + data_table[78].feg[0].cl[0] = 0.3055000000; data_table[78].feg[0].cnl[0] = 0.0596000000; data_table[78].feg[0].cl[1] = 1.3945000000; data_table[78].feg[0].cnl[1] = 0.5827000000; data_table[78].feg[0].cl[2] = 2.9617000000; data_table[78].feg[0].cnl[2] = 3.1035000000; data_table[78].feg[0].cl[3] = 3.8990000000; data_table[78].feg[0].cnl[3] = 11.9693000000; data_table[78].feg[0].cl[4] = 2.0026000000; data_table[78].feg[0].cnl[4] = 47.9106000000; data_table[78].feg[0].cl[5] = 0.0000000000; data_table[78].feg[0].cnl[5] = 0.0000000000; + data_table[79].feg[0].cl[0] = 0.3593000000; data_table[79].feg[0].cnl[0] = 0.0694000000; data_table[79].feg[0].cl[1] = 1.5736000000; data_table[79].feg[0].cnl[1] = 0.6758000000; data_table[79].feg[0].cl[2] = 3.5237000000; data_table[79].feg[0].cnl[2] = 3.8457000000; data_table[79].feg[0].cl[3] = 3.8109000000; data_table[79].feg[0].cnl[3] = 15.6203000000; data_table[79].feg[0].cl[4] = 1.6953000000; data_table[79].feg[0].cnl[4] = 56.6614000000; data_table[79].feg[0].cl[5] = 0.0000000000; data_table[79].feg[0].cnl[5] = 0.0000000000; + data_table[80].feg[0].cl[0] = 0.3511000000; data_table[80].feg[0].cnl[0] = 0.0672000000; data_table[80].feg[0].cl[1] = 1.5489000000; data_table[80].feg[0].cnl[1] = 0.6522000000; data_table[80].feg[0].cl[2] = 3.5676000000; data_table[80].feg[0].cnl[2] = 3.7420000000; data_table[80].feg[0].cl[3] = 4.0900000000; data_table[80].feg[0].cnl[3] = 15.9791000000; data_table[80].feg[0].cl[4] = 2.5251000000; data_table[80].feg[0].cnl[4] = 65.1354000000; data_table[80].feg[0].cl[5] = 0.0000000000; data_table[80].feg[0].cnl[5] = 0.0000000000; + data_table[81].feg[0].cl[0] = 0.3540000000; data_table[81].feg[0].cnl[0] = 0.0668000000; data_table[81].feg[0].cl[1] = 1.5453000000; data_table[81].feg[0].cnl[1] = 0.6465000000; data_table[81].feg[0].cl[2] = 3.5975000000; data_table[81].feg[0].cnl[2] = 3.6968000000; data_table[81].feg[0].cl[3] = 4.3152000000; data_table[81].feg[0].cnl[3] = 16.2056000000; data_table[81].feg[0].cl[4] = 2.7743000000; data_table[81].feg[0].cnl[4] = 61.4909000000; data_table[81].feg[0].cl[5] = 0.0000000000; data_table[81].feg[0].cnl[5] = 0.0000000000; + data_table[82].feg[0].cl[0] = 0.3530000000; data_table[82].feg[0].cnl[0] = 0.0661000000; data_table[82].feg[0].cl[1] = 1.5258000000; data_table[82].feg[0].cnl[1] = 0.6324000000; data_table[82].feg[0].cl[2] = 3.5815000000; data_table[82].feg[0].cnl[2] = 3.5906000000; data_table[82].feg[0].cl[3] = 4.5532000000; data_table[82].feg[0].cnl[3] = 15.9962000000; data_table[82].feg[0].cl[4] = 3.0714000000; data_table[82].feg[0].cnl[4] = 57.5760000000; data_table[82].feg[0].cl[5] = 0.0000000000; data_table[82].feg[0].cnl[5] = 0.0000000000; + data_table[83].feg[0].cl[0] = 0.3673000000; data_table[83].feg[0].cnl[0] = 0.0678000000; data_table[83].feg[0].cl[1] = 1.5772000000; data_table[83].feg[0].cnl[1] = 0.6527000000; data_table[83].feg[0].cl[2] = 3.7079000000; data_table[83].feg[0].cnl[2] = 3.7396000000; data_table[83].feg[0].cl[3] = 4.8582000000; data_table[83].feg[0].cnl[3] = 17.0668000000; data_table[83].feg[0].cl[4] = 2.8440000000; data_table[83].feg[0].cnl[4] = 55.9789000000; data_table[83].feg[0].cl[5] = 0.0000000000; data_table[83].feg[0].cnl[5] = 0.0000000000; + data_table[84].feg[0].cl[0] = 0.3547000000; data_table[84].feg[0].cnl[0] = 0.0649000000; data_table[84].feg[0].cl[1] = 1.5206000000; data_table[84].feg[0].cnl[1] = 0.6188000000; data_table[84].feg[0].cl[2] = 3.5621000000; data_table[84].feg[0].cnl[2] = 3.4696000000; data_table[84].feg[0].cl[3] = 5.0184000000; data_table[84].feg[0].cnl[3] = 15.6090000000; data_table[84].feg[0].cl[4] = 3.0075000000; data_table[84].feg[0].cnl[4] = 49.4818000000; data_table[84].feg[0].cl[5] = 0.0000000000; data_table[84].feg[0].cnl[5] = 0.0000000000; + data_table[85].feg[0].cl[0] = 0.4586000000; data_table[85].feg[0].cnl[0] = 0.0831000000; data_table[85].feg[0].cl[1] = 1.7781000000; data_table[85].feg[0].cnl[1] = 0.7840000000; data_table[85].feg[0].cl[2] = 3.9877000000; data_table[85].feg[0].cnl[2] = 4.3599000000; data_table[85].feg[0].cl[3] = 5.7273000000; data_table[85].feg[0].cnl[3] = 20.0128000000; data_table[85].feg[0].cl[4] = 1.5460000000; data_table[85].feg[0].cnl[4] = 62.1535000000; data_table[85].feg[0].cl[5] = 0.0000000000; data_table[85].feg[0].cnl[5] = 0.0000000000; + data_table[86].feg[0].cl[0] = 0.8282000000; data_table[86].feg[0].cnl[0] = 0.1515000000; data_table[86].feg[0].cl[1] = 2.9941000000; data_table[86].feg[0].cnl[1] = 1.6163000000; data_table[86].feg[0].cl[2] = 5.6597000000; data_table[86].feg[0].cnl[2] = 9.7752000000; data_table[86].feg[0].cl[3] = 4.9292000000; data_table[86].feg[0].cnl[3] = 42.8480000000; data_table[86].feg[0].cl[4] = 4.2889000000; data_table[86].feg[0].cnl[4] = 190.7366000000; data_table[86].feg[0].cl[5] = 0.0000000000; data_table[86].feg[0].cnl[5] = 0.0000000000; + data_table[87].feg[0].cl[0] = 1.4129000000; data_table[87].feg[0].cnl[0] = 0.2921000000; data_table[87].feg[0].cl[1] = 4.4269000000; data_table[87].feg[0].cnl[1] = 3.1381000000; data_table[87].feg[0].cl[2] = 7.0460000000; data_table[87].feg[0].cnl[2] = 19.6767000000; data_table[87].feg[0].cl[3] = -1.0573000000; data_table[87].feg[0].cnl[3] = 102.0436000000; data_table[87].feg[0].cl[4] = 8.6430000000; data_table[87].feg[0].cnl[4] = 113.9798000000; data_table[87].feg[0].cl[5] = 0.0000000000; data_table[87].feg[0].cnl[5] = 0.0000000000; + data_table[88].feg[0].cl[0] = 0.7169000000; data_table[88].feg[0].cnl[0] = 0.1263000000; data_table[88].feg[0].cl[1] = 2.5710000000; data_table[88].feg[0].cnl[1] = 1.2900000000; data_table[88].feg[0].cl[2] = 5.1791000000; data_table[88].feg[0].cnl[2] = 7.3686000000; data_table[88].feg[0].cl[3] = 6.3484000000; data_table[88].feg[0].cnl[3] = 32.4490000000; data_table[88].feg[0].cl[4] = 5.6474000000; data_table[88].feg[0].cnl[4] = 118.0558000000; data_table[88].feg[0].cl[5] = 0.0000000000; data_table[88].feg[0].cnl[5] = 0.0000000000; + data_table[89].feg[0].cl[0] = 0.6958000000; data_table[89].feg[0].cnl[0] = 0.1211000000; data_table[89].feg[0].cl[1] = 2.4936000000; data_table[89].feg[0].cnl[1] = 1.2247000000; data_table[89].feg[0].cl[2] = 5.1269000000; data_table[89].feg[0].cnl[2] = 6.9398000000; data_table[89].feg[0].cl[3] = 6.6988000000; data_table[89].feg[0].cnl[3] = 30.0991000000; data_table[89].feg[0].cl[4] = 5.0799000000; data_table[89].feg[0].cnl[4] = 105.1960000000; data_table[89].feg[0].cl[5] = 0.0000000000; data_table[89].feg[0].cnl[5] = 0.0000000000; + data_table[90].feg[0].cl[0] = 1.2502000000; data_table[90].feg[0].cnl[0] = 0.2415000000; data_table[90].feg[0].cl[1] = 4.2284000000; data_table[90].feg[0].cnl[1] = 2.6442000000; data_table[90].feg[0].cl[2] = 7.0489000000; data_table[90].feg[0].cnl[2] = 16.3313000000; data_table[90].feg[0].cl[3] = 1.1390000000; data_table[90].feg[0].cnl[3] = 73.5757000000; data_table[90].feg[0].cl[4] = 5.8222000000; data_table[90].feg[0].cnl[4] = 91.9401000000; data_table[90].feg[0].cl[5] = 0.0000000000; data_table[90].feg[0].cnl[5] = 0.0000000000; + data_table[91].feg[0].cl[0] = 0.6410000000; data_table[91].feg[0].cnl[0] = 0.1097000000; data_table[91].feg[0].cl[1] = 2.2643000000; data_table[91].feg[0].cnl[1] = 1.0644000000; data_table[91].feg[0].cl[2] = 4.8713000000; data_table[91].feg[0].cnl[2] = 5.7907000000; data_table[91].feg[0].cl[3] = 5.9287000000; data_table[91].feg[0].cnl[3] = 25.0261000000; data_table[91].feg[0].cl[4] = 5.3935000000; data_table[91].feg[0].cnl[4] = 101.3899000000; data_table[91].feg[0].cl[5] = 0.0000000000; data_table[91].feg[0].cnl[5] = 0.0000000000; + data_table[92].feg[0].cl[0] = 0.6938000000; data_table[92].feg[0].cnl[0] = 0.1171000000; data_table[92].feg[0].cl[1] = 2.4652000000; data_table[92].feg[0].cnl[1] = 1.1757000000; data_table[92].feg[0].cl[2] = 5.1227000000; data_table[92].feg[0].cnl[2] = 6.4053000000; data_table[92].feg[0].cl[3] = 5.5965000000; data_table[92].feg[0].cnl[3] = 27.5217000000; data_table[92].feg[0].cl[4] = 4.8543000000; data_table[92].feg[0].cnl[4] = 103.0482000000; data_table[92].feg[0].cl[5] = 0.0000000000; data_table[92].feg[0].cnl[5] = 0.0000000000; + data_table[93].feg[0].cl[0] = 0.6902000000; data_table[93].feg[0].cnl[0] = 0.1153000000; data_table[93].feg[0].cl[1] = 2.4509000000; data_table[93].feg[0].cnl[1] = 1.1545000000; data_table[93].feg[0].cl[2] = 5.1284000000; data_table[93].feg[0].cnl[2] = 6.2291000000; data_table[93].feg[0].cl[3] = 5.0339000000; data_table[93].feg[0].cnl[3] = 27.0741000000; data_table[93].feg[0].cl[4] = 4.8575000000; data_table[93].feg[0].cnl[4] = 111.3150000000; data_table[93].feg[0].cl[5] = 0.0000000000; data_table[93].feg[0].cnl[5] = 0.0000000000; + data_table[94].feg[0].cl[0] = 0.7577000000; data_table[94].feg[0].cnl[0] = 0.1257000000; data_table[94].feg[0].cl[1] = 2.7264000000; data_table[94].feg[0].cnl[1] = 1.3044000000; data_table[94].feg[0].cl[2] = 5.4184000000; data_table[94].feg[0].cnl[2] = 7.1035000000; data_table[94].feg[0].cl[3] = 4.8198000000; data_table[94].feg[0].cnl[3] = 32.4649000000; data_table[94].feg[0].cl[4] = 4.1013000000; data_table[94].feg[0].cnl[4] = 118.8647000000; data_table[94].feg[0].cl[5] = 0.0000000000; data_table[94].feg[0].cnl[5] = 0.0000000000; + data_table[95].feg[0].cl[0] = 0.7567000000; data_table[95].feg[0].cnl[0] = 0.1239000000; data_table[95].feg[0].cl[1] = 2.7565000000; data_table[95].feg[0].cnl[1] = 1.2979000000; data_table[95].feg[0].cl[2] = 5.4364000000; data_table[95].feg[0].cnl[2] = 7.0798000000; data_table[95].feg[0].cl[3] = 5.1918000000; data_table[95].feg[0].cnl[3] = 32.7871000000; data_table[95].feg[0].cl[4] = 3.5643000000; data_table[95].feg[0].cnl[4] = 110.1512000000; data_table[95].feg[0].cl[5] = 0.0000000000; data_table[95].feg[0].cnl[5] = 0.0000000000; + data_table[96].feg[0].cl[0] = 0.7492000000; data_table[96].feg[0].cnl[0] = 0.1217000000; data_table[96].feg[0].cl[1] = 2.7267000000; data_table[96].feg[0].cnl[1] = 1.2651000000; data_table[96].feg[0].cl[2] = 5.3521000000; data_table[96].feg[0].cnl[2] = 6.8101000000; data_table[96].feg[0].cl[3] = 5.0369000000; data_table[96].feg[0].cnl[3] = 31.6088000000; data_table[96].feg[0].cl[4] = 3.5321000000; data_table[96].feg[0].cnl[4] = 106.4853000000; data_table[96].feg[0].cl[5] = 0.0000000000; data_table[96].feg[0].cnl[5] = 0.0000000000; + data_table[97].feg[0].cl[0] = 0.8100000000; data_table[97].feg[0].cnl[0] = 0.1310000000; data_table[97].feg[0].cl[1] = 3.0001000000; data_table[97].feg[0].cnl[1] = 1.4038000000; data_table[97].feg[0].cl[2] = 5.4635000000; data_table[97].feg[0].cnl[2] = 7.6057000000; data_table[97].feg[0].cl[3] = 4.1756000000; data_table[97].feg[0].cnl[3] = 34.0186000000; data_table[97].feg[0].cl[4] = 3.5066000000; data_table[97].feg[0].cnl[4] = 90.5226000000; data_table[97].feg[0].cl[5] = 0.0000000000; data_table[97].feg[0].cnl[5] = 0.0000000000; + data_table[98].feg[0].cl[0] = 0.0000000000; data_table[98].feg[0].cnl[0] = 0.0000000000; data_table[98].feg[0].cl[1] = 0.0000000000; data_table[98].feg[0].cnl[1] = 0.0000000000; data_table[98].feg[0].cl[2] = 0.0000000000; data_table[98].feg[0].cnl[2] = 0.0000000000; data_table[98].feg[0].cl[3] = 0.0000000000; data_table[98].feg[0].cnl[3] = 0.0000000000; data_table[98].feg[0].cl[4] = 0.0000000000; data_table[98].feg[0].cnl[4] = 0.0000000000; data_table[98].feg[0].cl[5] = 0.0000000000; data_table[98].feg[0].cnl[5] = 0.0000000000; + data_table[99].feg[0].cl[0] = 0.0000000000; data_table[99].feg[0].cnl[0] = 0.0000000000; data_table[99].feg[0].cl[1] = 0.0000000000; data_table[99].feg[0].cnl[1] = 0.0000000000; data_table[99].feg[0].cl[2] = 0.0000000000; data_table[99].feg[0].cnl[2] = 0.0000000000; data_table[99].feg[0].cl[3] = 0.0000000000; data_table[99].feg[0].cnl[3] = 0.0000000000; data_table[99].feg[0].cl[4] = 0.0000000000; data_table[99].feg[0].cnl[4] = 0.0000000000; data_table[99].feg[0].cl[5] = 0.0000000000; data_table[99].feg[0].cnl[5] = 0.0000000000; + data_table[100].feg[0].cl[0] = 0.0000000000; data_table[100].feg[0].cnl[0] = 0.0000000000; data_table[100].feg[0].cl[1] = 0.0000000000; data_table[100].feg[0].cnl[1] = 0.0000000000; data_table[100].feg[0].cl[2] = 0.0000000000; data_table[100].feg[0].cnl[2] = 0.0000000000; data_table[100].feg[0].cl[3] = 0.0000000000; data_table[100].feg[0].cnl[3] = 0.0000000000; data_table[100].feg[0].cl[4] = 0.0000000000; data_table[100].feg[0].cnl[4] = 0.0000000000; data_table[100].feg[0].cl[5] = 0.0000000000; data_table[100].feg[0].cnl[5] = 0.0000000000; + data_table[101].feg[0].cl[0] = 0.0000000000; data_table[101].feg[0].cnl[0] = 0.0000000000; data_table[101].feg[0].cl[1] = 0.0000000000; data_table[101].feg[0].cnl[1] = 0.0000000000; data_table[101].feg[0].cl[2] = 0.0000000000; data_table[101].feg[0].cnl[2] = 0.0000000000; data_table[101].feg[0].cl[3] = 0.0000000000; data_table[101].feg[0].cnl[3] = 0.0000000000; data_table[101].feg[0].cl[4] = 0.0000000000; data_table[101].feg[0].cnl[4] = 0.0000000000; data_table[101].feg[0].cl[5] = 0.0000000000; data_table[101].feg[0].cnl[5] = 0.0000000000; + data_table[102].feg[0].cl[0] = 0.0000000000; data_table[102].feg[0].cnl[0] = 0.0000000000; data_table[102].feg[0].cl[1] = 0.0000000000; data_table[102].feg[0].cnl[1] = 0.0000000000; data_table[102].feg[0].cl[2] = 0.0000000000; data_table[102].feg[0].cnl[2] = 0.0000000000; data_table[102].feg[0].cl[3] = 0.0000000000; data_table[102].feg[0].cnl[3] = 0.0000000000; data_table[102].feg[0].cl[4] = 0.0000000000; data_table[102].feg[0].cnl[4] = 0.0000000000; data_table[102].feg[0].cl[5] = 0.0000000000; data_table[102].feg[0].cnl[5] = 0.0000000000; + } + + // 4: Kirkland parameterization - 3 Yukawa + 3 Gaussians - [0, 12] + void Load_feg_Kirkland_neutral_0_12() + { + data_table[0].feg[0].cl[0] = 0.0042029832; data_table[0].feg[0].cnl[0] = 0.2253508880; data_table[0].feg[0].cl[1] = 0.0627762505; data_table[0].feg[0].cnl[1] = 0.2253669500; data_table[0].feg[0].cl[2] = 0.0300907347; data_table[0].feg[0].cnl[2] = 0.2253317560; data_table[0].feg[0].cl[3] = 0.0677756695; data_table[0].feg[0].cnl[3] = 4.3885400100; data_table[0].feg[0].cl[4] = 0.0035660924; data_table[0].feg[0].cnl[4] = 0.4038848230; data_table[0].feg[0].cl[5] = 0.0276135815; data_table[0].feg[0].cnl[5] = 1.4449016600; + data_table[1].feg[0].cl[0] = 0.0000187544; data_table[1].feg[0].cnl[0] = 0.2124279970; data_table[1].feg[0].cl[1] = 0.0004105958; data_table[1].feg[0].cnl[1] = 0.3322122790; data_table[1].feg[0].cl[2] = 0.1963000590; data_table[1].feg[0].cnl[2] = 0.5173251520; data_table[1].feg[0].cl[3] = 0.0083601574; data_table[1].feg[0].cnl[3] = 0.3666682390; data_table[1].feg[0].cl[4] = 0.0295102022; data_table[1].feg[0].cnl[4] = 1.3717182700; data_table[1].feg[0].cl[5] = 0.0000004659; data_table[1].feg[0].cnl[5] = 37576.8025000000; + data_table[2].feg[0].cl[0] = 0.0745843816; data_table[2].feg[0].cnl[0] = 0.8811514240; data_table[2].feg[0].cl[1] = 0.0715382250; data_table[2].feg[0].cnl[1] = 0.0459142904; data_table[2].feg[0].cl[2] = 0.1453152290; data_table[2].feg[0].cnl[2] = 0.8813017140; data_table[2].feg[0].cl[3] = 1.1212576900; data_table[2].feg[0].cnl[3] = 18.8483665000; data_table[2].feg[0].cl[4] = 0.0025173653; data_table[2].feg[0].cnl[4] = 0.1591899950; data_table[2].feg[0].cl[5] = 0.3584349710; data_table[2].feg[0].cnl[5] = 6.1237100000; + data_table[3].feg[0].cl[0] = 0.0611642897; data_table[3].feg[0].cnl[0] = 0.0990182132; data_table[3].feg[0].cl[1] = 0.1257550340; data_table[3].feg[0].cnl[1] = 0.0990272412; data_table[3].feg[0].cl[2] = 0.2008315480; data_table[3].feg[0].cnl[2] = 1.8739250900; data_table[3].feg[0].cl[3] = 0.7872428760; data_table[3].feg[0].cnl[3] = 9.3279492900; data_table[3].feg[0].cl[4] = 0.0015884785; data_table[3].feg[0].cnl[4] = 0.0891900236; data_table[3].feg[0].cl[5] = 0.2739620310; data_table[3].feg[0].cnl[5] = 3.2068765800; + data_table[4].feg[0].cl[0] = 0.1257160660; data_table[4].feg[0].cnl[0] = 0.1482588300; data_table[4].feg[0].cl[1] = 0.1733144520; data_table[4].feg[0].cnl[1] = 0.1482572160; data_table[4].feg[0].cl[2] = 0.1847748110; data_table[4].feg[0].cnl[2] = 3.3422731100; data_table[4].feg[0].cl[3] = 0.1952502210; data_table[4].feg[0].cnl[3] = 1.9733946300; data_table[4].feg[0].cl[4] = 0.5296420750; data_table[4].feg[0].cnl[4] = 5.7003555300; data_table[4].feg[0].cl[5] = 0.0010823050; data_table[4].feg[0].cnl[5] = 0.0564857237; + data_table[5].feg[0].cl[0] = 0.2120807670; data_table[5].feg[0].cnl[0] = 0.2086054170; data_table[5].feg[0].cl[1] = 0.1998118650; data_table[5].feg[0].cnl[1] = 0.2086101860; data_table[5].feg[0].cl[2] = 0.1682543850; data_table[5].feg[0].cnl[2] = 5.5787077300; data_table[5].feg[0].cl[3] = 0.1420483600; data_table[5].feg[0].cnl[3] = 1.3331188700; data_table[5].feg[0].cl[4] = 0.3638306720; data_table[5].feg[0].cnl[4] = 3.8080026300; data_table[5].feg[0].cl[5] = 0.0008350120; data_table[5].feg[0].cnl[5] = 0.0403982620; + data_table[6].feg[0].cl[0] = 0.5330155540; data_table[6].feg[0].cnl[0] = 0.2909525150; data_table[6].feg[0].cl[1] = 0.0529008883; data_table[6].feg[0].cnl[1] = 10.3547896000; data_table[6].feg[0].cl[2] = 0.0924159648; data_table[6].feg[0].cnl[2] = 10.3540028000; data_table[6].feg[0].cl[3] = 0.2617991010; data_table[6].feg[0].cnl[3] = 2.7625272300; data_table[6].feg[0].cl[4] = 0.0008802621; data_table[6].feg[0].cnl[4] = 0.0347681236; data_table[6].feg[0].cl[5] = 0.1101665550; data_table[6].feg[0].cnl[5] = 0.9934217360; + data_table[7].feg[0].cl[0] = 0.3399692040; data_table[7].feg[0].cnl[0] = 0.3815702800; data_table[7].feg[0].cl[1] = 0.3075701720; data_table[7].feg[0].cnl[1] = 0.3815714360; data_table[7].feg[0].cl[2] = 0.1303690720; data_table[7].feg[0].cnl[2] = 19.1919745000; data_table[7].feg[0].cl[3] = 0.0883326058; data_table[7].feg[0].cnl[3] = 0.7606355250; data_table[7].feg[0].cl[4] = 0.1965867000; data_table[7].feg[0].cnl[4] = 2.0740109400; data_table[7].feg[0].cl[5] = 0.0009962200; data_table[7].feg[0].cnl[5] = 0.0303266869; + data_table[8].feg[0].cl[0] = 0.2305605930; data_table[8].feg[0].cnl[0] = 0.4807542130; data_table[8].feg[0].cl[1] = 0.5268896480; data_table[8].feg[0].cnl[1] = 0.4807638950; data_table[8].feg[0].cl[2] = 0.1243467550; data_table[8].feg[0].cnl[2] = 39.5306720000; data_table[8].feg[0].cl[3] = 0.0012461689; data_table[8].feg[0].cnl[3] = 0.0262181803; data_table[8].feg[0].cl[4] = 0.0720452555; data_table[8].feg[0].cnl[4] = 0.5924955930; data_table[8].feg[0].cl[5] = 0.1530757770; data_table[8].feg[0].cnl[5] = 1.5912767100; + data_table[9].feg[0].cl[0] = 0.4083717710; data_table[9].feg[0].cnl[0] = 0.5882286270; data_table[9].feg[0].cl[1] = 0.4544188580; data_table[9].feg[0].cnl[1] = 0.5882886550; data_table[9].feg[0].cl[2] = 0.1445649230; data_table[9].feg[0].cnl[2] = 121.2460130000; data_table[9].feg[0].cl[3] = 0.0591531395; data_table[9].feg[0].cnl[3] = 0.4639635400; data_table[9].feg[0].cl[4] = 0.1240037180; data_table[9].feg[0].cnl[4] = 1.2341302500; data_table[9].feg[0].cl[5] = 0.0016498604; data_table[9].feg[0].cnl[5] = 0.0205869217; + data_table[10].feg[0].cl[0] = 0.1364716620; data_table[10].feg[0].cnl[0] = 0.0499965301; data_table[10].feg[0].cl[1] = 0.7706778650; data_table[10].feg[0].cnl[1] = 0.8818996640; data_table[10].feg[0].cl[2] = 0.1568620140; data_table[10].feg[0].cnl[2] = 16.1768579000; data_table[10].feg[0].cl[3] = 0.9968215130; data_table[10].feg[0].cnl[3] = 20.0132610000; data_table[10].feg[0].cl[4] = 0.0380304670; data_table[10].feg[0].cnl[4] = 0.2605162540; data_table[10].feg[0].cl[5] = 0.1276850890; data_table[10].feg[0].cnl[5] = 0.6995593290; + data_table[11].feg[0].cl[0] = 0.3043841210; data_table[11].feg[0].cnl[0] = 0.0842014377; data_table[11].feg[0].cl[1] = 0.7562705630; data_table[11].feg[0].cnl[1] = 1.6406559800; data_table[11].feg[0].cl[2] = 0.1011648090; data_table[11].feg[0].cnl[2] = 29.7142975000; data_table[11].feg[0].cl[3] = 0.0345203403; data_table[11].feg[0].cnl[3] = 0.2165960940; data_table[11].feg[0].cl[4] = 0.9717513270; data_table[11].feg[0].cnl[4] = 12.1236852000; data_table[11].feg[0].cl[5] = 0.1205930120; data_table[11].feg[0].cnl[5] = 0.5608658380; + data_table[12].feg[0].cl[0] = 0.7774194240; data_table[12].feg[0].cnl[0] = 2.7105822700; data_table[12].feg[0].cl[1] = 0.0578312036; data_table[12].feg[0].cnl[1] = 71.7532098000; data_table[12].feg[0].cl[2] = 0.4263864990; data_table[12].feg[0].cnl[2] = 0.0913331555; data_table[12].feg[0].cl[3] = 0.1134072200; data_table[12].feg[0].cnl[3] = 0.4488674510; data_table[12].feg[0].cl[4] = 0.7901140350; data_table[12].feg[0].cnl[4] = 8.6636671800; data_table[12].feg[0].cl[5] = 0.0323293496; data_table[12].feg[0].cnl[5] = 0.1785034630; + data_table[13].feg[0].cl[0] = 1.0654389200; data_table[13].feg[0].cnl[0] = 1.0411845500; data_table[13].feg[0].cl[1] = 0.1201436910; data_table[13].feg[0].cnl[1] = 68.7113368000; data_table[13].feg[0].cl[2] = 0.1809152630; data_table[13].feg[0].cnl[2] = 0.0887533926; data_table[13].feg[0].cl[3] = 1.1206562000; data_table[13].feg[0].cnl[3] = 3.7006261900; data_table[13].feg[0].cl[4] = 0.0305452816; data_table[13].feg[0].cnl[4] = 0.2140978970; data_table[13].feg[0].cl[5] = 1.5996350200; data_table[13].feg[0].cnl[5] = 9.9909663800; + data_table[14].feg[0].cl[0] = 1.0528444700; data_table[14].feg[0].cnl[0] = 1.3196259000; data_table[14].feg[0].cl[1] = 0.2994402840; data_table[14].feg[0].cnl[1] = 0.1284605200; data_table[14].feg[0].cl[2] = 0.1174607480; data_table[14].feg[0].cnl[2] = 102.1901630000; data_table[14].feg[0].cl[3] = 0.9606434520; data_table[14].feg[0].cnl[3] = 2.8747755500; data_table[14].feg[0].cl[4] = 0.0263555748; data_table[14].feg[0].cnl[4] = 0.1820768440; data_table[14].feg[0].cl[5] = 1.3805933000; data_table[14].feg[0].cnl[5] = 7.4916552600; + data_table[15].feg[0].cl[0] = 1.0164691600; data_table[15].feg[0].cnl[0] = 1.6918196500; data_table[15].feg[0].cl[1] = 0.4417667480; data_table[15].feg[0].cnl[1] = 0.1741802880; data_table[15].feg[0].cl[2] = 0.1215038630; data_table[15].feg[0].cnl[2] = 167.0110910000; data_table[15].feg[0].cl[3] = 0.8279666700; data_table[15].feg[0].cnl[3] = 2.3034281000; data_table[15].feg[0].cl[4] = 0.0233022533; data_table[15].feg[0].cnl[4] = 0.1569541500; data_table[15].feg[0].cl[5] = 1.1830284600; data_table[15].feg[0].cnl[5] = 5.8578289100; + data_table[16].feg[0].cl[0] = 0.9442211160; data_table[16].feg[0].cnl[0] = 0.2400523740; data_table[16].feg[0].cl[1] = 0.4373220490; data_table[16].feg[0].cnl[1] = 9.3051043900; data_table[16].feg[0].cl[2] = 0.2545479260; data_table[16].feg[0].cnl[2] = 9.3048634600; data_table[16].feg[0].cl[3] = 0.0547763323; data_table[16].feg[0].cnl[3] = 0.1686556880; data_table[16].feg[0].cl[4] = 0.8000874880; data_table[16].feg[0].cnl[4] = 2.9784977400; data_table[16].feg[0].cl[5] = 0.0107488641; data_table[16].feg[0].cnl[5] = 0.0684240646; + data_table[17].feg[0].cl[0] = 1.0698328800; data_table[17].feg[0].cnl[0] = 0.2877910220; data_table[17].feg[0].cl[1] = 0.4246317860; data_table[17].feg[0].cnl[1] = 12.4156957000; data_table[17].feg[0].cl[2] = 0.2438979490; data_table[17].feg[0].cnl[2] = 12.4158868000; data_table[17].feg[0].cl[3] = 0.0479446296; data_table[17].feg[0].cnl[3] = 0.1369797960; data_table[17].feg[0].cl[4] = 0.7649589520; data_table[17].feg[0].cnl[4] = 2.4394072900; data_table[17].feg[0].cl[5] = 0.0082312843; data_table[17].feg[0].cnl[5] = 0.0527258749; + data_table[18].feg[0].cl[0] = 0.6927178650; data_table[18].feg[0].cnl[0] = 7.1084999000; data_table[18].feg[0].cl[1] = 0.9651610850; data_table[18].feg[0].cnl[1] = 0.3575329010; data_table[18].feg[0].cl[2] = 0.1484665880; data_table[18].feg[0].cnl[2] = 0.0393763275; data_table[18].feg[0].cl[3] = 0.0264645027; data_table[18].feg[0].cnl[3] = 0.1035913210; data_table[18].feg[0].cl[4] = 1.8088376800; data_table[18].feg[0].cnl[4] = 32.2845199000; data_table[18].feg[0].cl[5] = 0.5439000180; data_table[18].feg[0].cnl[5] = 1.6779137400; + data_table[19].feg[0].cl[0] = 0.3669028710; data_table[19].feg[0].cnl[0] = 0.0614274129; data_table[19].feg[0].cl[1] = 0.8663789990; data_table[19].feg[0].cnl[1] = 0.5708817270; data_table[19].feg[0].cl[2] = 0.6672033000; data_table[19].feg[0].cnl[2] = 7.8296563900; data_table[19].feg[0].cl[3] = 0.4877436360; data_table[19].feg[0].cnl[3] = 1.3253131800; data_table[19].feg[0].cl[4] = 1.8240631400; data_table[19].feg[0].cnl[4] = 21.0056032000; data_table[19].feg[0].cl[5] = 0.0220248453; data_table[19].feg[0].cnl[5] = 0.0911853450; + data_table[20].feg[0].cl[0] = 0.3788717770; data_table[20].feg[0].cnl[0] = 0.0698910162; data_table[20].feg[0].cl[1] = 0.9000225050; data_table[20].feg[0].cnl[1] = 0.5210615410; data_table[20].feg[0].cl[2] = 0.7152889140; data_table[20].feg[0].cnl[2] = 7.8770792000; data_table[20].feg[0].cl[3] = 0.0188640973; data_table[20].feg[0].cnl[3] = 0.0817512708; data_table[20].feg[0].cl[4] = 0.4079459490; data_table[20].feg[0].cnl[4] = 1.1114138800; data_table[20].feg[0].cl[5] = 1.6178654000; data_table[20].feg[0].cnl[5] = 18.0840759000; + data_table[21].feg[0].cl[0] = 0.3623832670; data_table[21].feg[0].cnl[0] = 0.0754707114; data_table[21].feg[0].cl[1] = 0.9842329660; data_table[21].feg[0].cnl[1] = 0.4977573090; data_table[21].feg[0].cl[2] = 0.7417156420; data_table[21].feg[0].cnl[2] = 8.1765939100; data_table[21].feg[0].cl[3] = 0.3625552690; data_table[21].feg[0].cnl[3] = 0.9555249060; data_table[21].feg[0].cl[4] = 1.4915939000; data_table[21].feg[0].cnl[4] = 16.2221677000; data_table[21].feg[0].cl[5] = 0.0161659509; data_table[21].feg[0].cnl[5] = 0.0733140839; + data_table[22].feg[0].cl[0] = 0.3529613780; data_table[22].feg[0].cnl[0] = 0.0819204103; data_table[22].feg[0].cl[1] = 0.7467910140; data_table[22].feg[0].cnl[1] = 8.8118951100; data_table[22].feg[0].cl[2] = 1.0836406800; data_table[22].feg[0].cnl[2] = 0.5106460750; data_table[22].feg[0].cl[3] = 1.3901361000; data_table[22].feg[0].cnl[3] = 14.8901841000; data_table[22].feg[0].cl[4] = 0.3312733560; data_table[22].feg[0].cnl[4] = 0.8385430790; data_table[22].feg[0].cl[5] = 0.0140422612; data_table[22].feg[0].cnl[5] = 0.0657432678; + data_table[23].feg[0].cl[0] = 1.3434837900; data_table[23].feg[0].cnl[0] = 1.2581435300; data_table[23].feg[0].cl[1] = 0.5070403280; data_table[23].feg[0].cnl[1] = 11.5042811000; data_table[23].feg[0].cl[2] = 0.4263589550; data_table[23].feg[0].cnl[2] = 0.0853660389; data_table[23].feg[0].cl[3] = 0.0117241826; data_table[23].feg[0].cnl[3] = 0.0600177061; data_table[23].feg[0].cl[4] = 0.5119665160; data_table[23].feg[0].cnl[4] = 1.5377245100; data_table[23].feg[0].cl[5] = 0.3382858280; data_table[23].feg[0].cnl[5] = 0.6624183190; + data_table[24].feg[0].cl[0] = 0.3266976130; data_table[24].feg[0].cnl[0] = 0.0888813083; data_table[24].feg[0].cl[1] = 0.7172970000; data_table[24].feg[0].cnl[1] = 11.1300198000; data_table[24].feg[0].cl[2] = 1.3321246400; data_table[24].feg[0].cnl[2] = 0.5821411040; data_table[24].feg[0].cl[3] = 0.2808017020; data_table[24].feg[0].cnl[3] = 0.6715831450; data_table[24].feg[0].cl[4] = 1.1549924100; data_table[24].feg[0].cnl[4] = 12.6825395000; data_table[24].feg[0].cl[5] = 0.0111984488; data_table[24].feg[0].cnl[5] = 0.0532334467; + data_table[25].feg[0].cl[0] = 0.3134548470; data_table[25].feg[0].cnl[0] = 0.0899325756; data_table[25].feg[0].cl[1] = 0.6892900160; data_table[25].feg[0].cnl[1] = 13.0366038000; data_table[25].feg[0].cl[2] = 1.4714153100; data_table[25].feg[0].cnl[2] = 0.6333452910; data_table[25].feg[0].cl[3] = 1.0329868800; data_table[25].feg[0].cnl[3] = 11.6783425000; data_table[25].feg[0].cl[4] = 0.2582802850; data_table[25].feg[0].cnl[4] = 0.6091164460; data_table[25].feg[0].cl[5] = 0.0103460690; data_table[25].feg[0].cnl[5] = 0.0481610627; + data_table[26].feg[0].cl[0] = 0.3158782780; data_table[26].feg[0].cnl[0] = 0.0946683246; data_table[26].feg[0].cl[1] = 1.6013900500; data_table[26].feg[0].cnl[1] = 0.6994364490; data_table[26].feg[0].cl[2] = 0.6563943380; data_table[26].feg[0].cnl[2] = 15.6954403000; data_table[26].feg[0].cl[3] = 0.9367466240; data_table[26].feg[0].cnl[3] = 10.9392410000; data_table[26].feg[0].cl[4] = 0.0097756265; data_table[26].feg[0].cnl[4] = 0.0437446816; data_table[26].feg[0].cl[5] = 0.2383785780; data_table[26].feg[0].cnl[5] = 0.5562864830; + data_table[27].feg[0].cl[0] = 1.7225463000; data_table[27].feg[0].cnl[0] = 0.7766069080; data_table[27].feg[0].cl[1] = 0.3295430440; data_table[27].feg[0].cnl[1] = 0.1022623600; data_table[27].feg[0].cl[2] = 0.6230072000; data_table[27].feg[0].cnl[2] = 19.4156207000; data_table[27].feg[0].cl[3] = 0.0094349651; data_table[27].feg[0].cnl[3] = 0.0398684596; data_table[27].feg[0].cl[4] = 0.8540635150; data_table[27].feg[0].cnl[4] = 10.4078166000; data_table[27].feg[0].cl[5] = 0.2210735150; data_table[27].feg[0].cnl[5] = 0.5108693300; + data_table[28].feg[0].cl[0] = 0.3587745310; data_table[28].feg[0].cnl[0] = 0.1061534630; data_table[28].feg[0].cl[1] = 1.7618134800; data_table[28].feg[0].cnl[1] = 1.0164099500; data_table[28].feg[0].cl[2] = 0.6369050530; data_table[28].feg[0].cnl[2] = 15.3659093000; data_table[28].feg[0].cl[3] = 0.0074493067; data_table[28].feg[0].cnl[3] = 0.0385345989; data_table[28].feg[0].cl[4] = 0.1890023470; data_table[28].feg[0].cnl[4] = 0.3984277900; data_table[28].feg[0].cl[5] = 0.2296195890; data_table[28].feg[0].cnl[5] = 0.9014198430; + data_table[29].feg[0].cl[0] = 0.5708939730; data_table[29].feg[0].cnl[0] = 0.1265346140; data_table[29].feg[0].cl[1] = 1.9890885600; data_table[29].feg[0].cnl[1] = 2.1778196500; data_table[29].feg[0].cl[2] = 0.3060605850; data_table[29].feg[0].cnl[2] = 37.8619003000; data_table[29].feg[0].cl[3] = 0.2356002230; data_table[29].feg[0].cnl[3] = 0.3670190410; data_table[29].feg[0].cl[4] = 0.3970611020; data_table[29].feg[0].cnl[4] = 0.8664195960; data_table[29].feg[0].cl[5] = 0.0068565723; data_table[29].feg[0].cnl[5] = 0.0335778823; + data_table[30].feg[0].cl[0] = 0.6255284640; data_table[30].feg[0].cnl[0] = 0.1100056500; data_table[30].feg[0].cl[1] = 2.0530290100; data_table[30].feg[0].cnl[1] = 2.4109578600; data_table[30].feg[0].cl[2] = 0.2896081200; data_table[30].feg[0].cnl[2] = 47.8685736000; data_table[30].feg[0].cl[3] = 0.2079105940; data_table[30].feg[0].cnl[3] = 0.3278072240; data_table[30].feg[0].cl[4] = 0.3450796170; data_table[30].feg[0].cnl[4] = 0.7431390610; data_table[30].feg[0].cl[5] = 0.0065563430; data_table[30].feg[0].cnl[5] = 0.0309411369; + data_table[31].feg[0].cl[0] = 0.5909526900; data_table[31].feg[0].cnl[0] = 0.1183759760; data_table[31].feg[0].cl[1] = 0.5399806600; data_table[31].feg[0].cnl[1] = 71.8937433000; data_table[31].feg[0].cl[2] = 2.0062618800; data_table[31].feg[0].cnl[2] = 1.3930488900; data_table[31].feg[0].cl[3] = 0.7497050410; data_table[31].feg[0].cnl[3] = 6.8994335000; data_table[31].feg[0].cl[4] = 0.1835813470; data_table[31].feg[0].cnl[4] = 0.3646672320; data_table[31].feg[0].cl[5] = 0.0095219074; data_table[31].feg[0].cnl[5] = 0.0269888650; + data_table[32].feg[0].cl[0] = 0.7778752180; data_table[32].feg[0].cnl[0] = 0.1507331570; data_table[32].feg[0].cl[1] = 0.5938481500; data_table[32].feg[0].cnl[1] = 142.8822090000; data_table[32].feg[0].cl[2] = 1.9591875100; data_table[32].feg[0].cnl[2] = 1.7475033900; data_table[32].feg[0].cl[3] = 0.1798802260; data_table[32].feg[0].cnl[3] = 0.3318008520; data_table[32].feg[0].cl[4] = 0.8632672220; data_table[32].feg[0].cnl[4] = 5.8549027400; data_table[32].feg[0].cl[5] = 0.0095905343; data_table[32].feg[0].cnl[5] = 0.0233777569; + data_table[33].feg[0].cl[0] = 0.9583906810; data_table[33].feg[0].cnl[0] = 0.1837755570; data_table[33].feg[0].cl[1] = 0.6038513420; data_table[33].feg[0].cnl[1] = 196.8192240000; data_table[33].feg[0].cl[2] = 1.9082893100; data_table[33].feg[0].cnl[2] = 2.1508205300; data_table[33].feg[0].cl[3] = 0.1738859560; data_table[33].feg[0].cnl[3] = 0.3000060240; data_table[33].feg[0].cl[4] = 0.9352651450; data_table[33].feg[0].cnl[4] = 4.9247121500; data_table[33].feg[0].cl[5] = 0.0086225466; data_table[33].feg[0].cnl[5] = 0.0212308108; + data_table[34].feg[0].cl[0] = 1.1413617000; data_table[34].feg[0].cnl[0] = 0.2187087100; data_table[34].feg[0].cl[1] = 0.5181187370; data_table[34].feg[0].cnl[1] = 193.9166820000; data_table[34].feg[0].cl[2] = 1.8573197500; data_table[34].feg[0].cnl[2] = 2.6575539600; data_table[34].feg[0].cl[3] = 0.1682173990; data_table[34].feg[0].cnl[3] = 0.2717199180; data_table[34].feg[0].cl[4] = 0.9757056060; data_table[34].feg[0].cnl[4] = 4.1948250000; data_table[34].feg[0].cl[5] = 0.0072418787; data_table[34].feg[0].cnl[5] = 0.0199325718; + data_table[35].feg[0].cl[0] = 0.3243869700; data_table[35].feg[0].cnl[0] = 63.1317973000; data_table[35].feg[0].cl[1] = 1.3173216300; data_table[35].feg[0].cnl[1] = 0.2547060360; data_table[35].feg[0].cl[2] = 1.7991261400; data_table[35].feg[0].cnl[2] = 3.2366839400; data_table[35].feg[0].cl[3] = 0.0042996143; data_table[35].feg[0].cnl[3] = 0.0198965610; data_table[35].feg[0].cl[4] = 1.0042943300; data_table[35].feg[0].cnl[4] = 3.6109451300; data_table[35].feg[0].cl[5] = 0.1621881970; data_table[35].feg[0].cnl[5] = 0.2455836720; + data_table[36].feg[0].cl[0] = 0.2904453510; data_table[36].feg[0].cnl[0] = 0.0368420227; data_table[36].feg[0].cl[1] = 2.4420132900; data_table[36].feg[0].cnl[1] = 1.1601333200; data_table[36].feg[0].cl[2] = 0.7694354490; data_table[36].feg[0].cnl[2] = 16.9591472000; data_table[36].feg[0].cl[3] = 1.5868700000; data_table[36].feg[0].cnl[3] = 2.5308257400; data_table[36].feg[0].cl[4] = 0.0028161759; data_table[36].feg[0].cnl[4] = 0.0188577417; data_table[36].feg[0].cl[5] = 0.1286638300; data_table[36].feg[0].cnl[5] = 0.2107539690; + data_table[37].feg[0].cl[0] = 0.0137373086; data_table[37].feg[0].cnl[0] = 0.0187469061; data_table[37].feg[0].cl[1] = 1.9754867200; data_table[37].feg[0].cnl[1] = 6.3607923000; data_table[37].feg[0].cl[2] = 1.5926102900; data_table[37].feg[0].cnl[2] = 0.2219924820; data_table[37].feg[0].cl[3] = 0.1732638820; data_table[37].feg[0].cnl[3] = 0.2016249580; data_table[37].feg[0].cl[4] = 4.6628037800; data_table[37].feg[0].cnl[4] = 25.3027803000; data_table[37].feg[0].cl[5] = 0.0016126506; data_table[37].feg[0].cnl[5] = 0.0153610568; + data_table[38].feg[0].cl[0] = 0.6753027470; data_table[38].feg[0].cnl[0] = 0.0654331847; data_table[38].feg[0].cl[1] = 0.4702867200; data_table[38].feg[0].cnl[1] = 106.1087090000; data_table[38].feg[0].cl[2] = 2.6349767700; data_table[38].feg[0].cnl[2] = 2.0664354000; data_table[38].feg[0].cl[3] = 0.1096217460; data_table[38].feg[0].cnl[3] = 0.1931319250; data_table[38].feg[0].cl[4] = 0.9603487730; data_table[38].feg[0].cnl[4] = 1.6331093800; data_table[38].feg[0].cl[5] = 0.0052892156; data_table[38].feg[0].cnl[5] = 0.0166083821; + data_table[39].feg[0].cl[0] = 2.6436550500; data_table[39].feg[0].cnl[0] = 2.2020269900; data_table[39].feg[0].cl[1] = 0.5542251470; data_table[39].feg[0].cnl[1] = 178.2601070000; data_table[39].feg[0].cl[2] = 0.7613766250; data_table[39].feg[0].cnl[2] = 0.0767218745; data_table[39].feg[0].cl[3] = 0.0060294689; data_table[39].feg[0].cnl[3] = 0.0155143296; data_table[39].feg[0].cl[4] = 0.0991630530; data_table[39].feg[0].cnl[4] = 0.1761759950; data_table[39].feg[0].cl[5] = 0.9567820200; data_table[39].feg[0].cnl[5] = 1.5433068200; + data_table[40].feg[0].cl[0] = 0.6595328750; data_table[40].feg[0].cnl[0] = 0.0866145490; data_table[40].feg[0].cl[1] = 1.8454585400; data_table[40].feg[0].cnl[1] = 5.9477439800; data_table[40].feg[0].cl[2] = 1.2558440500; data_table[40].feg[0].cnl[2] = 0.6408514750; data_table[40].feg[0].cl[3] = 0.1222534220; data_table[40].feg[0].cnl[3] = 0.1666460500; data_table[40].feg[0].cl[4] = 0.7066383280; data_table[40].feg[0].cnl[4] = 1.6285326800; data_table[40].feg[0].cl[5] = 0.0026238159; data_table[40].feg[0].cnl[5] = 0.0082625786; + data_table[41].feg[0].cl[0] = 0.6101601200; data_table[41].feg[0].cnl[0] = 0.0911628054; data_table[41].feg[0].cl[1] = 1.2654400000; data_table[41].feg[0].cnl[1] = 0.5067760250; data_table[41].feg[0].cl[2] = 1.9742876200; data_table[41].feg[0].cnl[2] = 5.8959038100; data_table[41].feg[0].cl[3] = 0.6480289620; data_table[41].feg[0].cnl[3] = 1.4663410800; data_table[41].feg[0].cl[4] = 0.0026038082; data_table[41].feg[0].cnl[4] = 0.0078433631; data_table[41].feg[0].cl[5] = 0.1138874930; data_table[41].feg[0].cnl[5] = 0.1551143400; + data_table[42].feg[0].cl[0] = 0.8551891830; data_table[42].feg[0].cnl[0] = 0.1029621510; data_table[42].feg[0].cl[1] = 1.6621964100; data_table[42].feg[0].cnl[1] = 7.6490700000; data_table[42].feg[0].cl[2] = 1.4557547500; data_table[42].feg[0].cnl[2] = 1.0163998700; data_table[42].feg[0].cl[3] = 0.1054456640; data_table[42].feg[0].cnl[3] = 0.1423033380; data_table[42].feg[0].cl[4] = 0.7716571120; data_table[42].feg[0].cnl[4] = 1.3465934900; data_table[42].feg[0].cl[5] = 0.0022099264; data_table[42].feg[0].cnl[5] = 0.0079035898; + data_table[43].feg[0].cl[0] = 0.4708470930; data_table[43].feg[0].cnl[0] = 0.0933029874; data_table[43].feg[0].cl[1] = 1.5818078100; data_table[43].feg[0].cnl[1] = 0.4528313470; data_table[43].feg[0].cl[2] = 2.0241981800; data_table[43].feg[0].cnl[2] = 7.1148902300; data_table[43].feg[0].cl[3] = 0.0019703626; data_table[43].feg[0].cnl[3] = 0.0075618160; data_table[43].feg[0].cl[4] = 0.6269126390; data_table[43].feg[0].cnl[4] = 1.2539985800; data_table[43].feg[0].cl[5] = 0.1026413200; data_table[43].feg[0].cnl[5] = 0.1337860870; + data_table[44].feg[0].cl[0] = 0.4200515530; data_table[44].feg[0].cnl[0] = 0.0938882628; data_table[44].feg[0].cl[1] = 1.7626650700; data_table[44].feg[0].cnl[1] = 0.4644416870; data_table[44].feg[0].cl[2] = 2.0273564100; data_table[44].feg[0].cnl[2] = 8.1934604600; data_table[44].feg[0].cl[3] = 0.0014548718; data_table[44].feg[0].cnl[3] = 0.0078270452; data_table[44].feg[0].cl[4] = 0.6228096000; data_table[44].feg[0].cnl[4] = 1.1719415300; data_table[44].feg[0].cl[5] = 0.0991529915; data_table[44].feg[0].cnl[5] = 0.1245328390; + data_table[45].feg[0].cl[0] = 2.1047515500; data_table[45].feg[0].cnl[0] = 8.6860647000; data_table[45].feg[0].cl[1] = 2.0388448700; data_table[45].feg[0].cnl[1] = 0.3789244490; data_table[45].feg[0].cl[2] = 0.1820672640; data_table[45].feg[0].cnl[2] = 0.1429216340; data_table[45].feg[0].cl[3] = 0.0952040948; data_table[45].feg[0].cnl[3] = 0.1171259000; data_table[45].feg[0].cl[4] = 0.5914452480; data_table[45].feg[0].cnl[4] = 1.0784380800; data_table[45].feg[0].cl[5] = 0.0011332868; data_table[45].feg[0].cnl[5] = 0.0078025209; + data_table[46].feg[0].cl[0] = 2.0798139000; data_table[46].feg[0].cnl[0] = 9.9254029700; data_table[46].feg[0].cl[1] = 0.4431707260; data_table[46].feg[0].cnl[1] = 0.1049201040; data_table[46].feg[0].cl[2] = 1.9651521500; data_table[46].feg[0].cnl[2] = 0.6401038390; data_table[46].feg[0].cl[3] = 0.5961305910; data_table[46].feg[0].cnl[3] = 0.8895947900; data_table[46].feg[0].cl[4] = 0.4780163330; data_table[46].feg[0].cnl[4] = 1.9850940700; data_table[46].feg[0].cl[5] = 0.0946458470; data_table[46].feg[0].cnl[5] = 0.1127444640; + data_table[47].feg[0].cl[0] = 1.6365754900; data_table[47].feg[0].cnl[0] = 12.4540381000; data_table[47].feg[0].cl[1] = 2.1792798900; data_table[47].feg[0].cnl[1] = 1.4513466000; data_table[47].feg[0].cl[2] = 0.7713006900; data_table[47].feg[0].cnl[2] = 0.1266957570; data_table[47].feg[0].cl[3] = 0.6641938800; data_table[47].feg[0].cnl[3] = 0.7776592020; data_table[47].feg[0].cl[4] = 0.7645632850; data_table[47].feg[0].cnl[4] = 1.6607521000; data_table[47].feg[0].cl[5] = 0.0861126689; data_table[47].feg[0].cnl[5] = 0.1057283570; + data_table[48].feg[0].cl[0] = 2.2482063200; data_table[48].feg[0].cnl[0] = 1.5191350700; data_table[48].feg[0].cl[1] = 1.6470686400; data_table[48].feg[0].cnl[1] = 13.0113424000; data_table[48].feg[0].cl[2] = 0.7886792650; data_table[48].feg[0].cnl[2] = 0.1061281840; data_table[48].feg[0].cl[3] = 0.0812579069; data_table[48].feg[0].cnl[3] = 0.0994045620; data_table[48].feg[0].cl[4] = 0.6682803460; data_table[48].feg[0].cnl[4] = 1.4974206300; data_table[48].feg[0].cl[5] = 0.6384674750; data_table[48].feg[0].cnl[5] = 0.7184226350; + data_table[49].feg[0].cl[0] = 2.1664462000; data_table[49].feg[0].cnl[0] = 11.3174909000; data_table[49].feg[0].cl[1] = 0.6886910210; data_table[49].feg[0].cnl[1] = 0.1101312850; data_table[49].feg[0].cl[2] = 1.9243175100; data_table[49].feg[0].cnl[2] = 0.6744648530; data_table[49].feg[0].cl[3] = 0.5653598880; data_table[49].feg[0].cnl[3] = 0.7335646100; data_table[49].feg[0].cl[4] = 0.9186838610; data_table[49].feg[0].cnl[4] = 10.2310312000; data_table[49].feg[0].cl[5] = 0.0780542213; data_table[49].feg[0].cnl[5] = 0.0931104308; + data_table[50].feg[0].cl[0] = 1.7366211400; data_table[50].feg[0].cnl[0] = 0.8843347190; data_table[50].feg[0].cl[1] = 0.9998713800; data_table[50].feg[0].cnl[1] = 0.1384621210; data_table[50].feg[0].cl[2] = 2.1397240900; data_table[50].feg[0].cnl[2] = 11.9666432000; data_table[50].feg[0].cl[3] = 0.5605665260; data_table[50].feg[0].cnl[3] = 0.6726728800; data_table[50].feg[0].cl[4] = 0.9937727470; data_table[50].feg[0].cnl[4] = 8.7233041100; data_table[50].feg[0].cl[5] = 0.0737374982; data_table[50].feg[0].cnl[5] = 0.0878577715; + data_table[51].feg[0].cl[0] = 2.0938388200; data_table[51].feg[0].cnl[0] = 12.6856869000; data_table[51].feg[0].cl[1] = 1.5694051900; data_table[51].feg[0].cnl[1] = 1.2123653700; data_table[51].feg[0].cl[2] = 1.3094199300; data_table[51].feg[0].cnl[2] = 0.1666332920; data_table[51].feg[0].cl[3] = 0.0698067804; data_table[51].feg[0].cnl[3] = 0.0830817576; data_table[51].feg[0].cl[4] = 1.0496953700; data_table[51].feg[0].cnl[4] = 7.4314785700; data_table[51].feg[0].cl[5] = 0.5555943540; data_table[51].feg[0].cnl[5] = 0.6174876760; + data_table[52].feg[0].cl[0] = 1.6018692500; data_table[52].feg[0].cnl[0] = 0.1950315380; data_table[52].feg[0].cl[1] = 1.9851026400; data_table[52].feg[0].cnl[1] = 13.6976183000; data_table[52].feg[0].cl[2] = 1.4822620000; data_table[52].feg[0].cnl[2] = 1.8030479500; data_table[52].feg[0].cl[3] = 0.5538071990; data_table[52].feg[0].cnl[3] = 0.5679123400; data_table[52].feg[0].cl[4] = 1.1172872200; data_table[52].feg[0].cnl[4] = 6.4087987800; data_table[52].feg[0].cl[5] = 0.0660720847; data_table[52].feg[0].cnl[5] = 0.0786615429; + data_table[53].feg[0].cl[0] = 1.6001548700; data_table[53].feg[0].cnl[0] = 2.9291335400; data_table[53].feg[0].cl[1] = 1.7164458100; data_table[53].feg[0].cnl[1] = 15.5882990000; data_table[53].feg[0].cl[2] = 1.8496835100; data_table[53].feg[0].cnl[2] = 0.2225259830; data_table[53].feg[0].cl[3] = 0.0623813648; data_table[53].feg[0].cnl[3] = 0.0745581223; data_table[53].feg[0].cl[4] = 1.2138755500; data_table[53].feg[0].cnl[4] = 5.5601327100; data_table[53].feg[0].cl[5] = 0.5540519460; data_table[53].feg[0].cnl[5] = 0.5219945210; + data_table[54].feg[0].cl[0] = 2.9523685400; data_table[54].feg[0].cnl[0] = 6.0146195200; data_table[54].feg[0].cl[1] = 0.4281057210; data_table[54].feg[0].cnl[1] = 46.4151246000; data_table[54].feg[0].cl[2] = 1.8959923300; data_table[54].feg[0].cnl[2] = 0.1801097560; data_table[54].feg[0].cl[3] = 0.0548012938; data_table[54].feg[0].cnl[3] = 0.0712799633; data_table[54].feg[0].cl[4] = 4.7083860000; data_table[54].feg[0].cnl[4] = 45.6702799000; data_table[54].feg[0].cl[5] = 0.5903567190; data_table[54].feg[0].cnl[5] = 0.4702363100; + data_table[55].feg[0].cl[0] = 3.1943424300; data_table[55].feg[0].cnl[0] = 9.2735224100; data_table[55].feg[0].cl[1] = 1.9828958600; data_table[55].feg[0].cnl[1] = 0.2287416320; data_table[55].feg[0].cl[2] = 0.1551210520; data_table[55].feg[0].cnl[2] = 0.0382000231; data_table[55].feg[0].cl[3] = 0.0673222354; data_table[55].feg[0].cnl[3] = 0.0730961745; data_table[55].feg[0].cl[4] = 4.4847421100; data_table[55].feg[0].cnl[4] = 29.5703565000; data_table[55].feg[0].cl[5] = 0.5426744140; data_table[55].feg[0].cnl[5] = 0.4086470150; + data_table[56].feg[0].cl[0] = 2.0503642500; data_table[56].feg[0].cnl[0] = 0.2203484170; data_table[56].feg[0].cl[1] = 0.1421143110; data_table[56].feg[0].cnl[1] = 0.0396438056; data_table[56].feg[0].cl[2] = 3.2353815100; data_table[56].feg[0].cnl[2] = 9.5697916900; data_table[56].feg[0].cl[3] = 0.0634683429; data_table[56].feg[0].cnl[3] = 0.0692443091; data_table[56].feg[0].cl[4] = 3.9796058600; data_table[56].feg[0].cnl[4] = 25.3178406000; data_table[56].feg[0].cl[5] = 0.5201167110; data_table[56].feg[0].cnl[5] = 0.3836140980; + data_table[57].feg[0].cl[0] = 3.2299075900; data_table[57].feg[0].cnl[0] = 9.9466013500; data_table[57].feg[0].cl[1] = 0.1576183070; data_table[57].feg[0].cnl[1] = 0.0415378676; data_table[57].feg[0].cl[2] = 2.1347783800; data_table[57].feg[0].cnl[2] = 0.2404805720; data_table[57].feg[0].cl[3] = 0.5019076090; data_table[57].feg[0].cnl[3] = 0.3662520190; data_table[57].feg[0].cl[4] = 3.8088901000; data_table[57].feg[0].cnl[4] = 24.3275968000; data_table[57].feg[0].cl[5] = 0.0596625028; data_table[57].feg[0].cnl[5] = 0.0659653503; + data_table[58].feg[0].cl[0] = 0.1581893240; data_table[58].feg[0].cnl[0] = 0.0391309056; data_table[58].feg[0].cl[1] = 3.1814199500; data_table[58].feg[0].cnl[1] = 10.4139545000; data_table[58].feg[0].cl[2] = 2.2762214000; data_table[58].feg[0].cnl[2] = 0.2816717570; data_table[58].feg[0].cl[3] = 3.9770547200; data_table[58].feg[0].cnl[3] = 26.1872978000; data_table[58].feg[0].cl[4] = 0.0558448277; data_table[58].feg[0].cnl[4] = 0.0630921695; data_table[58].feg[0].cl[5] = 0.4852079540; data_table[58].feg[0].cnl[5] = 0.3542343690; + data_table[59].feg[0].cl[0] = 0.1813794170; data_table[59].feg[0].cnl[0] = 0.0437324793; data_table[59].feg[0].cl[1] = 3.1761639600; data_table[59].feg[0].cnl[1] = 10.7842572000; data_table[59].feg[0].cl[2] = 2.3522151900; data_table[59].feg[0].cnl[2] = 0.3055718330; data_table[59].feg[0].cl[3] = 3.8312576300; data_table[59].feg[0].cnl[3] = 25.4745408000; data_table[59].feg[0].cl[4] = 0.0525889976; data_table[59].feg[0].cnl[4] = 0.0602676073; data_table[59].feg[0].cl[5] = 0.4700907420; data_table[59].feg[0].cnl[5] = 0.3390170030; + data_table[60].feg[0].cl[0] = 0.1929868110; data_table[60].feg[0].cnl[0] = 0.0437785970; data_table[60].feg[0].cl[1] = 2.4375602300; data_table[60].feg[0].cnl[1] = 0.3293369960; data_table[60].feg[0].cl[2] = 3.1724850400; data_table[60].feg[0].cnl[2] = 11.1259996000; data_table[60].feg[0].cl[3] = 3.5810541400; data_table[60].feg[0].cnl[3] = 24.6709586000; data_table[60].feg[0].cl[4] = 0.4565293940; data_table[60].feg[0].cnl[4] = 0.3249902820; data_table[60].feg[0].cl[5] = 0.0494812177; data_table[60].feg[0].cnl[5] = 0.0576553100; + data_table[61].feg[0].cl[0] = 0.2120025950; data_table[61].feg[0].cnl[0] = 0.0457703608; data_table[61].feg[0].cl[1] = 3.1689175400; data_table[61].feg[0].cnl[1] = 11.4536599000; data_table[61].feg[0].cl[2] = 2.5150349400; data_table[61].feg[0].cnl[2] = 0.3555610540; data_table[61].feg[0].cl[3] = 0.4440808450; data_table[61].feg[0].cnl[3] = 0.3119533630; data_table[61].feg[0].cl[4] = 3.3674210100; data_table[61].feg[0].cnl[4] = 24.0291435000; data_table[61].feg[0].cl[5] = 0.0465652543; data_table[61].feg[0].cnl[5] = 0.0552266819; + data_table[62].feg[0].cl[0] = 2.5935500200; data_table[62].feg[0].cnl[0] = 0.3824526120; data_table[62].feg[0].cl[1] = 3.1655752200; data_table[62].feg[0].cnl[1] = 11.7675155000; data_table[62].feg[0].cl[2] = 0.2294026520; data_table[62].feg[0].cnl[2] = 0.0476642249; data_table[62].feg[0].cl[3] = 0.4322577800; data_table[62].feg[0].cnl[3] = 0.2997198330; data_table[62].feg[0].cl[4] = 3.1726192000; data_table[62].feg[0].cnl[4] = 23.4462738000; data_table[62].feg[0].cl[5] = 0.0437958317; data_table[62].feg[0].cnl[5] = 0.0529440680; + data_table[63].feg[0].cl[0] = 3.1914493900; data_table[63].feg[0].cnl[0] = 12.0224655000; data_table[63].feg[0].cl[1] = 2.5576643100; data_table[63].feg[0].cnl[1] = 0.4083388760; data_table[63].feg[0].cl[2] = 0.3326819340; data_table[63].feg[0].cnl[2] = 0.0585819814; data_table[63].feg[0].cl[3] = 0.0414243130; data_table[63].feg[0].cnl[3] = 0.0506771477; data_table[63].feg[0].cl[4] = 2.6103672800; data_table[63].feg[0].cnl[4] = 19.9344244000; data_table[63].feg[0].cl[5] = 0.4205268630; data_table[63].feg[0].cnl[5] = 0.2856862400; + data_table[64].feg[0].cl[0] = 0.2594074620; data_table[64].feg[0].cnl[0] = 0.0504689354; data_table[64].feg[0].cl[1] = 3.1617785500; data_table[64].feg[0].cnl[1] = 12.3140183000; data_table[64].feg[0].cl[2] = 2.7509575100; data_table[64].feg[0].cnl[2] = 0.4383376260; data_table[64].feg[0].cl[3] = 2.7924768600; data_table[64].feg[0].cnl[3] = 22.3797309000; data_table[64].feg[0].cl[4] = 0.0385931001; data_table[64].feg[0].cnl[4] = 0.0487920992; data_table[64].feg[0].cl[5] = 0.4108817080; data_table[64].feg[0].cnl[5] = 0.2776228920; + data_table[65].feg[0].cl[0] = 3.1605539600; data_table[65].feg[0].cnl[0] = 12.5470414000; data_table[65].feg[0].cl[1] = 2.8275170900; data_table[65].feg[0].cnl[1] = 0.4678990940; data_table[65].feg[0].cl[2] = 0.2751402550; data_table[65].feg[0].cnl[2] = 0.0523226982; data_table[65].feg[0].cl[3] = 0.4009671600; data_table[65].feg[0].cnl[3] = 0.2676148840; data_table[65].feg[0].cl[4] = 2.6311083400; data_table[65].feg[0].cnl[4] = 21.9498166000; data_table[65].feg[0].cl[5] = 0.0361333817; data_table[65].feg[0].cnl[5] = 0.0468871497; + data_table[66].feg[0].cl[0] = 0.2886424670; data_table[66].feg[0].cnl[0] = 0.0540507687; data_table[66].feg[0].cl[1] = 2.9056729600; data_table[66].feg[0].cnl[1] = 0.4975810770; data_table[66].feg[0].cl[2] = 3.1596015900; data_table[66].feg[0].cnl[2] = 12.7599505000; data_table[66].feg[0].cl[3] = 0.3912802590; data_table[66].feg[0].cnl[3] = 0.2581518310; data_table[66].feg[0].cl[4] = 2.4859603800; data_table[66].feg[0].cnl[4] = 21.5400972000; data_table[66].feg[0].cl[5] = 0.0337664478; data_table[66].feg[0].cnl[5] = 0.0450664323; + data_table[67].feg[0].cl[0] = 3.1557321300; data_table[67].feg[0].cnl[0] = 12.9729009000; data_table[67].feg[0].cl[1] = 0.3115195600; data_table[67].feg[0].cnl[1] = 0.0581399387; data_table[67].feg[0].cl[2] = 2.9772240600; data_table[67].feg[0].cnl[2] = 0.5312133940; data_table[67].feg[0].cl[3] = 0.3815638540; data_table[67].feg[0].cnl[3] = 0.2491957760; data_table[67].feg[0].cl[4] = 2.4024753200; data_table[67].feg[0].cnl[4] = 21.3627616000; data_table[67].feg[0].cl[5] = 0.0315224214; data_table[67].feg[0].cnl[5] = 0.0433253257; + data_table[68].feg[0].cl[0] = 3.1559197000; data_table[68].feg[0].cnl[0] = 13.1232407000; data_table[68].feg[0].cl[1] = 0.3225447100; data_table[68].feg[0].cnl[1] = 0.0597223323; data_table[68].feg[0].cl[2] = 3.0556905300; data_table[68].feg[0].cnl[2] = 0.5618767730; data_table[68].feg[0].cl[3] = 0.0292845100; data_table[68].feg[0].cnl[3] = 0.0416534255; data_table[68].feg[0].cl[4] = 0.3724872050; data_table[68].feg[0].cnl[4] = 0.2408219670; data_table[68].feg[0].cl[5] = 2.2783369500; data_table[68].feg[0].cnl[5] = 21.0034185000; + data_table[69].feg[0].cl[0] = 3.1079470400; data_table[69].feg[0].cnl[0] = 0.6063478470; data_table[69].feg[0].cl[1] = 3.1409122100; data_table[69].feg[0].cnl[1] = 13.3705269000; data_table[69].feg[0].cl[2] = 0.3756604540; data_table[69].feg[0].cnl[2] = 0.0729814740; data_table[69].feg[0].cl[3] = 0.3619010970; data_table[69].feg[0].cnl[3] = 0.2326520510; data_table[69].feg[0].cl[4] = 2.4540908200; data_table[69].feg[0].cnl[4] = 21.2695209000; data_table[69].feg[0].cl[5] = 0.0272383990; data_table[69].feg[0].cnl[5] = 0.0399969597; + data_table[70].feg[0].cl[0] = 3.1144686300; data_table[70].feg[0].cnl[0] = 13.8968881000; data_table[70].feg[0].cl[1] = 0.5396343530; data_table[70].feg[0].cnl[1] = 0.0891708508; data_table[70].feg[0].cl[2] = 3.0646091500; data_table[70].feg[0].cnl[2] = 0.6799195630; data_table[70].feg[0].cl[3] = 0.0258563745; data_table[70].feg[0].cnl[3] = 0.0382808522; data_table[70].feg[0].cl[4] = 2.1398355600; data_table[70].feg[0].cnl[4] = 18.0078788000; data_table[70].feg[0].cl[5] = 0.3477882310; data_table[70].feg[0].cnl[5] = 0.2227065910; + data_table[71].feg[0].cl[0] = 3.0116689900; data_table[71].feg[0].cnl[0] = 0.7104018890; data_table[71].feg[0].cl[1] = 3.1628478800; data_table[71].feg[0].cnl[1] = 13.8262192000; data_table[71].feg[0].cl[2] = 0.6334217710; data_table[71].feg[0].cnl[2] = 0.0948486572; data_table[71].feg[0].cl[3] = 0.3414171980; data_table[71].feg[0].cnl[3] = 0.2141296780; data_table[71].feg[0].cl[4] = 1.5356601300; data_table[71].feg[0].cnl[4] = 15.5298698000; data_table[71].feg[0].cl[5] = 0.0240723773; data_table[71].feg[0].cnl[5] = 0.0367833690; + data_table[72].feg[0].cl[0] = 3.2023682100; data_table[72].feg[0].cnl[0] = 13.8446369000; data_table[72].feg[0].cl[1] = 0.8300984130; data_table[72].feg[0].cnl[1] = 0.1183815810; data_table[72].feg[0].cl[2] = 2.8655229700; data_table[72].feg[0].cnl[2] = 0.7663691180; data_table[72].feg[0].cl[3] = 0.0224813887; data_table[72].feg[0].cnl[3] = 0.0352934622; data_table[72].feg[0].cl[4] = 1.4016526300; data_table[72].feg[0].cnl[4] = 14.6148877000; data_table[72].feg[0].cl[5] = 0.3337405960; data_table[72].feg[0].cnl[5] = 0.2057044860; + data_table[73].feg[0].cl[0] = 0.9249068550; data_table[73].feg[0].cnl[0] = 0.1286633770; data_table[73].feg[0].cl[1] = 2.7555455700; data_table[73].feg[0].cnl[1] = 0.7658264790; data_table[73].feg[0].cl[2] = 3.3044006000; data_table[73].feg[0].cnl[2] = 13.4471170000; data_table[73].feg[0].cl[3] = 0.3299738620; data_table[73].feg[0].cnl[3] = 0.1982188950; data_table[73].feg[0].cl[4] = 1.0991644400; data_table[73].feg[0].cnl[4] = 13.5087534000; data_table[73].feg[0].cl[5] = 0.0206498883; data_table[73].feg[0].cnl[5] = 0.0338918459; + data_table[74].feg[0].cl[0] = 1.9695210500; data_table[74].feg[0].cnl[0] = 49.8830620000; data_table[74].feg[0].cl[1] = 1.2172661900; data_table[74].feg[0].cnl[1] = 0.1332438090; data_table[74].feg[0].cl[2] = 4.1039168500; data_table[74].feg[0].cnl[2] = 1.8439691600; data_table[74].feg[0].cl[3] = 0.0290791978; data_table[74].feg[0].cnl[3] = 0.0284192813; data_table[74].feg[0].cl[4] = 0.2306966690; data_table[74].feg[0].cnl[4] = 0.1909687840; data_table[74].feg[0].cl[5] = 0.6088402990; data_table[74].feg[0].cnl[5] = 1.3709035600; + data_table[75].feg[0].cl[0] = 2.0638586700; data_table[75].feg[0].cnl[0] = 40.5671697000; data_table[75].feg[0].cl[1] = 1.2960340600; data_table[75].feg[0].cnl[1] = 0.1465590470; data_table[75].feg[0].cl[2] = 3.9692067300; data_table[75].feg[0].cnl[2] = 1.8256159600; data_table[75].feg[0].cl[3] = 0.0269835487; data_table[75].feg[0].cnl[3] = 0.0284172045; data_table[75].feg[0].cl[4] = 0.2310839990; data_table[75].feg[0].cnl[4] = 0.1797651840; data_table[75].feg[0].cl[5] = 0.6304667740; data_table[75].feg[0].cnl[5] = 1.3891154300; + data_table[76].feg[0].cl[0] = 2.2152272600; data_table[76].feg[0].cnl[0] = 32.4464090000; data_table[76].feg[0].cl[1] = 1.3757315500; data_table[76].feg[0].cnl[1] = 0.1609200480; data_table[76].feg[0].cl[2] = 3.7824440500; data_table[76].feg[0].cnl[2] = 1.7875655300; data_table[76].feg[0].cl[3] = 0.0244643240; data_table[76].feg[0].cnl[3] = 0.0282909938; data_table[76].feg[0].cl[4] = 0.2369320160; data_table[76].feg[0].cnl[4] = 0.1706923680; data_table[76].feg[0].cl[5] = 0.6484714120; data_table[76].feg[0].cnl[5] = 1.3792839000; + data_table[77].feg[0].cl[0] = 0.9846979400; data_table[77].feg[0].cnl[0] = 0.1609108390; data_table[77].feg[0].cl[1] = 2.7398707900; data_table[77].feg[0].cnl[1] = 0.7189716670; data_table[77].feg[0].cl[2] = 3.6169671500; data_table[77].feg[0].cnl[2] = 12.9281016000; data_table[77].feg[0].cl[3] = 0.3028856020; data_table[77].feg[0].cnl[3] = 0.1701348540; data_table[77].feg[0].cl[4] = 0.2783707260; data_table[77].feg[0].cnl[4] = 1.4986270300; data_table[77].feg[0].cl[5] = 0.0152124129; data_table[77].feg[0].cnl[5] = 0.0283510822; + data_table[78].feg[0].cl[0] = 0.9612633980; data_table[78].feg[0].cnl[0] = 0.1709322770; data_table[78].feg[0].cl[1] = 3.6958103000; data_table[78].feg[0].cnl[1] = 12.9335319000; data_table[78].feg[0].cl[2] = 2.7756749100; data_table[78].feg[0].cnl[2] = 0.6899970700; data_table[78].feg[0].cl[3] = 0.2954141760; data_table[78].feg[0].cnl[3] = 0.1635255100; data_table[78].feg[0].cl[4] = 0.3114757430; data_table[78].feg[0].cnl[4] = 1.3920090100; data_table[78].feg[0].cl[5] = 0.0143237267; data_table[78].feg[0].cnl[5] = 0.0271265337; + data_table[79].feg[0].cl[0] = 1.2920049100; data_table[79].feg[0].cnl[0] = 0.1834328650; data_table[79].feg[0].cl[1] = 2.7516147800; data_table[79].feg[0].cnl[1] = 0.9423683710; data_table[79].feg[0].cl[2] = 3.4938794900; data_table[79].feg[0].cnl[2] = 14.6235654000; data_table[79].feg[0].cl[3] = 0.2773046360; data_table[79].feg[0].cnl[3] = 0.1551101440; data_table[79].feg[0].cl[4] = 0.4302328100; data_table[79].feg[0].cnl[4] = 1.2887167000; data_table[79].feg[0].cl[5] = 0.0148294351; data_table[79].feg[0].cnl[5] = 0.0261903834; + data_table[80].feg[0].cl[0] = 3.7596473000; data_table[80].feg[0].cnl[0] = 13.5041513000; data_table[80].feg[0].cl[1] = 3.2119590400; data_table[80].feg[0].cnl[1] = 0.6663309930; data_table[80].feg[0].cl[2] = 0.6477678250; data_table[80].feg[0].cnl[2] = 0.0922518234; data_table[80].feg[0].cl[3] = 0.2761232740; data_table[80].feg[0].cnl[3] = 0.1503128970; data_table[80].feg[0].cl[4] = 0.3188388100; data_table[80].feg[0].cnl[4] = 1.1256558800; data_table[80].feg[0].cl[5] = 0.0131668419; data_table[80].feg[0].cnl[5] = 0.0248879842; + data_table[81].feg[0].cl[0] = 1.0079597500; data_table[81].feg[0].cnl[0] = 0.1172684270; data_table[81].feg[0].cl[1] = 3.0979615300; data_table[81].feg[0].cnl[1] = 0.8804532350; data_table[81].feg[0].cl[2] = 3.6129686400; data_table[81].feg[0].cnl[2] = 14.7325812000; data_table[81].feg[0].cl[3] = 0.2624014760; data_table[81].feg[0].cnl[3] = 0.1434910140; data_table[81].feg[0].cl[4] = 0.4056219950; data_table[81].feg[0].cnl[4] = 1.0410350600; data_table[81].feg[0].cl[5] = 0.0131812509; data_table[81].feg[0].cnl[5] = 0.0239575415; + data_table[82].feg[0].cl[0] = 1.5982687500; data_table[82].feg[0].cnl[0] = 0.1568974710; data_table[82].feg[0].cl[1] = 4.3823392500; data_table[82].feg[0].cnl[1] = 2.4709469200; data_table[82].feg[0].cl[2] = 2.0607471900; data_table[82].feg[0].cnl[2] = 57.2438972000; data_table[82].feg[0].cl[3] = 0.1944260230; data_table[82].feg[0].cnl[3] = 0.1329791090; data_table[82].feg[0].cl[4] = 0.8227049780; data_table[82].feg[0].cnl[4] = 0.9565325280; data_table[82].feg[0].cl[5] = 0.0233226953; data_table[82].feg[0].cnl[5] = 0.0223038435; + data_table[83].feg[0].cl[0] = 1.7146322300; data_table[83].feg[0].cnl[0] = 97.9262841000; data_table[83].feg[0].cl[1] = 2.1411596000; data_table[83].feg[0].cnl[1] = 0.2101937170; data_table[83].feg[0].cl[2] = 4.3751241300; data_table[83].feg[0].cnl[2] = 3.6694881200; data_table[83].feg[0].cl[3] = 0.0216216680; data_table[83].feg[0].cnl[3] = 0.0198456144; data_table[83].feg[0].cl[4] = 0.1978438370; data_table[83].feg[0].cnl[4] = 0.1337588070; data_table[83].feg[0].cl[5] = 0.6520479200; data_table[83].feg[0].cnl[5] = 0.7804321040; + data_table[84].feg[0].cl[0] = 1.4804779400; data_table[84].feg[0].cnl[0] = 125.9439190000; data_table[84].feg[0].cl[1] = 2.0917463000; data_table[84].feg[0].cnl[1] = 0.1838030080; data_table[84].feg[0].cl[2] = 4.7524603300; data_table[84].feg[0].cnl[2] = 4.1989059600; data_table[84].feg[0].cl[3] = 0.0185643958; data_table[84].feg[0].cnl[3] = 0.0181383503; data_table[84].feg[0].cl[4] = 0.2058593750; data_table[84].feg[0].cnl[4] = 0.1330354040; data_table[84].feg[0].cl[5] = 0.7135409480; data_table[84].feg[0].cnl[5] = 0.7030319380; + data_table[85].feg[0].cl[0] = 0.6300222950; data_table[85].feg[0].cnl[0] = 0.1409097620; data_table[85].feg[0].cl[1] = 3.8096288100; data_table[85].feg[0].cnl[1] = 30.8515540000; data_table[85].feg[0].cl[2] = 3.8975606700; data_table[85].feg[0].cnl[2] = 0.6515597630; data_table[85].feg[0].cl[3] = 0.2407551000; data_table[85].feg[0].cnl[3] = 0.1088996720; data_table[85].feg[0].cl[4] = 2.6286857700; data_table[85].feg[0].cnl[4] = 6.4238326100; data_table[85].feg[0].cl[5] = 0.0314285931; data_table[85].feg[0].cnl[5] = 0.0242346699; + data_table[86].feg[0].cl[0] = 5.2328813500; data_table[86].feg[0].cnl[0] = 8.6059953600; data_table[86].feg[0].cl[1] = 2.4860420500; data_table[86].feg[0].cnl[1] = 0.3045439820; data_table[86].feg[0].cl[2] = 0.3234313540; data_table[86].feg[0].cnl[2] = 0.0387759096; data_table[86].feg[0].cl[3] = 0.2554035960; data_table[86].feg[0].cnl[3] = 0.1287177240; data_table[86].feg[0].cl[4] = 0.5536072280; data_table[86].feg[0].cnl[4] = 0.5369774520; data_table[86].feg[0].cl[5] = 0.0057527889; data_table[86].feg[0].cnl[5] = 0.0129417790; + data_table[87].feg[0].cl[0] = 1.4419268500; data_table[87].feg[0].cnl[0] = 0.1187408730; data_table[87].feg[0].cl[1] = 3.5529172500; data_table[87].feg[0].cnl[1] = 1.0173975000; data_table[87].feg[0].cl[2] = 3.9125958600; data_table[87].feg[0].cnl[2] = 63.1814783000; data_table[87].feg[0].cl[3] = 0.2161735190; data_table[87].feg[0].cnl[3] = 0.0955806441; data_table[87].feg[0].cl[4] = 3.9419160500; data_table[87].feg[0].cnl[4] = 35.0602732000; data_table[87].feg[0].cl[5] = 0.0460422605; data_table[87].feg[0].cnl[5] = 0.0220850385; + data_table[88].feg[0].cl[0] = 1.4586412700; data_table[88].feg[0].cnl[0] = 0.1077604940; data_table[88].feg[0].cl[1] = 4.1894540500; data_table[88].feg[0].cnl[1] = 88.9090649000; data_table[88].feg[0].cl[2] = 3.6586618200; data_table[88].feg[0].cnl[2] = 1.0508893100; data_table[88].feg[0].cl[3] = 0.2084792290; data_table[88].feg[0].cnl[3] = 0.0909335557; data_table[88].feg[0].cl[4] = 3.1652811700; data_table[88].feg[0].cnl[4] = 31.3297788000; data_table[88].feg[0].cl[5] = 0.0523892556; data_table[88].feg[0].cnl[5] = 0.0208807697; + data_table[89].feg[0].cl[0] = 1.1901406400; data_table[89].feg[0].cnl[0] = 0.0773468729; data_table[89].feg[0].cl[1] = 2.5538060700; data_table[89].feg[0].cnl[1] = 0.6596936810; data_table[89].feg[0].cl[2] = 4.6811018100; data_table[89].feg[0].cnl[2] = 12.8013896000; data_table[89].feg[0].cl[3] = 0.2261213030; data_table[89].feg[0].cnl[3] = 0.1086321940; data_table[89].feg[0].cl[4] = 0.3582505450; data_table[89].feg[0].cnl[4] = 0.4567656640; data_table[89].feg[0].cl[5] = 0.0078226395; data_table[89].feg[0].cnl[5] = 0.0162623474; + data_table[90].feg[0].cl[0] = 4.6853750400; data_table[90].feg[0].cnl[0] = 14.4503632000; data_table[90].feg[0].cl[1] = 2.9841370800; data_table[90].feg[0].cnl[1] = 0.5564385920; data_table[90].feg[0].cl[2] = 0.8919880610; data_table[90].feg[0].cnl[2] = 0.0669512914; data_table[90].feg[0].cl[3] = 0.2248253840; data_table[90].feg[0].cnl[3] = 0.1032353960; data_table[90].feg[0].cl[4] = 0.3044448460; data_table[90].feg[0].cnl[4] = 0.4272556470; data_table[90].feg[0].cl[5] = 0.0094816271; data_table[90].feg[0].cnl[5] = 0.0177730611; + data_table[91].feg[0].cl[0] = 4.6334360600; data_table[91].feg[0].cnl[0] = 16.3377267000; data_table[91].feg[0].cl[1] = 3.1815705600; data_table[91].feg[0].cnl[1] = 0.5695178680; data_table[91].feg[0].cl[2] = 0.8764550750; data_table[91].feg[0].cnl[2] = 0.0688860012; data_table[91].feg[0].cl[3] = 0.2216854770; data_table[91].feg[0].cnl[3] = 0.0984254550; data_table[91].feg[0].cl[4] = 0.2729171000; data_table[91].feg[0].cnl[4] = 0.4094709170; data_table[91].feg[0].cl[5] = 0.0111737298; data_table[91].feg[0].cnl[5] = 0.0186215410; + data_table[92].feg[0].cl[0] = 4.5677388800; data_table[92].feg[0].cnl[0] = 19.0992795000; data_table[92].feg[0].cl[1] = 3.4032517900; data_table[92].feg[0].cnl[1] = 0.5900996340; data_table[92].feg[0].cl[2] = 0.8618419230; data_table[92].feg[0].cnl[2] = 0.0703204851; data_table[92].feg[0].cl[3] = 0.2197288700; data_table[92].feg[0].cnl[3] = 0.0936334280; data_table[92].feg[0].cl[4] = 0.2381769030; data_table[92].feg[0].cnl[4] = 0.3935548820; data_table[92].feg[0].cl[5] = 0.0138306499; data_table[92].feg[0].cnl[5] = 0.0194437286; + data_table[93].feg[0].cl[0] = 5.4567112300; data_table[93].feg[0].cnl[0] = 10.1892720000; data_table[93].feg[0].cl[1] = 0.1116879060; data_table[93].feg[0].cnl[1] = 0.0398131313; data_table[93].feg[0].cl[2] = 3.3026034300; data_table[93].feg[0].cnl[2] = 0.3146222120; data_table[93].feg[0].cl[3] = 0.1845683190; data_table[93].feg[0].cnl[3] = 0.1042208600; data_table[93].feg[0].cl[4] = 0.4936442630; data_table[93].feg[0].cnl[4] = 0.4630805400; data_table[93].feg[0].cl[5] = 3.5748474300; data_table[93].feg[0].cnl[5] = 21.9369542000; + data_table[94].feg[0].cl[0] = 5.3832199900; data_table[94].feg[0].cnl[0] = 10.7289857000; data_table[94].feg[0].cl[1] = 0.1233432360; data_table[94].feg[0].cnl[1] = 0.0415137806; data_table[94].feg[0].cl[2] = 3.4646909000; data_table[94].feg[0].cnl[2] = 0.3393262080; data_table[94].feg[0].cl[3] = 0.1754371320; data_table[94].feg[0].cnl[3] = 0.0998932346; data_table[94].feg[0].cl[4] = 3.3980007300; data_table[94].feg[0].cnl[4] = 21.1601535000; data_table[94].feg[0].cl[5] = 0.4694595190; data_table[94].feg[0].cnl[5] = 0.4519969700; + data_table[95].feg[0].cl[0] = 5.3840237700; data_table[95].feg[0].cnl[0] = 11.1211419000; data_table[95].feg[0].cl[1] = 3.4986126400; data_table[95].feg[0].cnl[1] = 0.3567502100; data_table[95].feg[0].cl[2] = 0.1880395470; data_table[95].feg[0].cnl[2] = 0.0539853583; data_table[95].feg[0].cl[3] = 0.1691431370; data_table[95].feg[0].cnl[3] = 0.0960082633; data_table[95].feg[0].cl[4] = 3.1959501600; data_table[95].feg[0].cnl[4] = 18.0694389000; data_table[95].feg[0].cl[5] = 0.4643930590; data_table[95].feg[0].cnl[5] = 0.4363181970; + data_table[96].feg[0].cl[0] = 3.6609068800; data_table[96].feg[0].cnl[0] = 0.3844209060; data_table[96].feg[0].cl[1] = 0.2030546780; data_table[96].feg[0].cnl[1] = 0.0548547131; data_table[96].feg[0].cl[2] = 5.3069751500; data_table[96].feg[0].cnl[2] = 11.7150262000; data_table[96].feg[0].cl[3] = 0.1609340460; data_table[96].feg[0].cnl[3] = 0.0921020329; data_table[96].feg[0].cl[4] = 3.0480840100; data_table[96].feg[0].cnl[4] = 17.3525367000; data_table[96].feg[0].cl[5] = 0.4436102950; data_table[96].feg[0].cnl[5] = 0.4271323590; + data_table[97].feg[0].cl[0] = 3.9415039000; data_table[97].feg[0].cnl[0] = 0.4182467220; data_table[97].feg[0].cl[1] = 5.1691534500; data_table[97].feg[0].cnl[1] = 12.5201788000; data_table[97].feg[0].cl[2] = 0.1619410740; data_table[97].feg[0].cnl[2] = 0.0481540117; data_table[97].feg[0].cl[3] = 0.4152995610; data_table[97].feg[0].cnl[3] = 0.4249138560; data_table[97].feg[0].cl[4] = 2.9176132500; data_table[97].feg[0].cnl[4] = 19.0899693000; data_table[97].feg[0].cl[5] = 0.1514749270; data_table[97].feg[0].cnl[5] = 0.0881568925; + data_table[98].feg[0].cl[0] = 4.0978062300; data_table[98].feg[0].cnl[0] = 0.4460211450; data_table[98].feg[0].cl[1] = 5.1007939300; data_table[98].feg[0].cnl[1] = 13.1768613000; data_table[98].feg[0].cl[2] = 0.1746172890; data_table[98].feg[0].cnl[2] = 0.0502742829; data_table[98].feg[0].cl[3] = 2.7677465800; data_table[98].feg[0].cnl[3] = 18.4815393000; data_table[98].feg[0].cl[4] = 0.1444966390; data_table[98].feg[0].cnl[4] = 0.0846232592; data_table[98].feg[0].cl[5] = 0.4027721090; data_table[98].feg[0].cnl[5] = 0.4176401000; + data_table[99].feg[0].cl[0] = 4.2493482000; data_table[99].feg[0].cnl[0] = 0.4752639330; data_table[99].feg[0].cl[1] = 5.0355659400; data_table[99].feg[0].cnl[1] = 13.8570834000; data_table[99].feg[0].cl[2] = 0.1889206130; data_table[99].feg[0].cnl[2] = 0.0526975158; data_table[99].feg[0].cl[3] = 0.3943560580; data_table[99].feg[0].cnl[3] = 0.4111937510; data_table[99].feg[0].cl[4] = 2.6121310000; data_table[99].feg[0].cnl[4] = 17.8537905000; data_table[99].feg[0].cl[5] = 0.1380019270; data_table[99].feg[0].cnl[5] = 0.0812774434; + data_table[100].feg[0].cl[0] = 0.2009429310; data_table[100].feg[0].cnl[0] = 0.0548366518; data_table[100].feg[0].cl[1] = 4.4011986900; data_table[100].feg[0].cnl[1] = 0.5042484340; data_table[100].feg[0].cl[2] = 4.9725010200; data_table[100].feg[0].cnl[2] = 14.5721366000; data_table[100].feg[0].cl[3] = 2.4753059900; data_table[100].feg[0].cnl[3] = 17.2978308000; data_table[100].feg[0].cl[4] = 0.3868831970; data_table[100].feg[0].cnl[4] = 0.4050438980; data_table[100].feg[0].cl[5] = 0.1319360950; data_table[100].feg[0].cnl[5] = 0.0780821071; + data_table[101].feg[0].cl[0] = 0.2160528990; data_table[101].feg[0].cnl[0] = 0.0583584058; data_table[101].feg[0].cl[1] = 4.9110679900; data_table[101].feg[0].cnl[1] = 15.3264212000; data_table[101].feg[0].cl[2] = 4.5486287000; data_table[101].feg[0].cnl[2] = 0.5344347600; data_table[101].feg[0].cl[3] = 2.3611424900; data_table[101].feg[0].cnl[3] = 16.8164803000; data_table[101].feg[0].cl[4] = 0.1262772920; data_table[101].feg[0].cnl[4] = 0.0750304633; data_table[101].feg[0].cl[5] = 0.3813645010; data_table[101].feg[0].cnl[5] = 0.3993058520; + data_table[102].feg[0].cl[0] = 4.8673801400; data_table[102].feg[0].cnl[0] = 16.0320520000; data_table[102].feg[0].cl[1] = 0.3199744010; data_table[102].feg[0].cnl[1] = 0.0670871138; data_table[102].feg[0].cl[2] = 4.5887242500; data_table[102].feg[0].cnl[2] = 0.5770393730; data_table[102].feg[0].cl[3] = 0.1214824480; data_table[102].feg[0].cnl[3] = 0.0722275899; data_table[102].feg[0].cl[4] = 2.3163987200; data_table[102].feg[0].cnl[4] = 14.1279737000; data_table[102].feg[0].cl[5] = 0.3792581370; data_table[102].feg[0].cnl[5] = 0.3899734840; + } + + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + void Load_feg_Weickenmeier_neutral_0_12() + { + data_table[0].feg[0].cl[0] = 0.0000000000; data_table[0].feg[0].cnl[0] = 0.0000000000; data_table[0].feg[0].cl[1] = 0.0000000000; data_table[0].feg[0].cnl[1] = 0.0000000000; data_table[0].feg[0].cl[2] = 0.0000000000; data_table[0].feg[0].cnl[2] = 0.0000000000; data_table[0].feg[0].cl[3] = 0.0000000000; data_table[0].feg[0].cnl[3] = 0.0000000000; data_table[0].feg[0].cl[4] = 0.0000000000; data_table[0].feg[0].cnl[4] = 0.0000000000; data_table[0].feg[0].cl[5] = 0.0000000000; data_table[0].feg[0].cnl[5] = 0.0000000000; + data_table[1].feg[0].cl[0] = 0.5000000000; data_table[1].feg[0].cnl[0] = 2.5420000000; data_table[1].feg[0].cl[1] = 0.5000000000; data_table[1].feg[0].cnl[1] = 8.7430000000; data_table[1].feg[0].cl[2] = 0.5000000000; data_table[1].feg[0].cnl[2] = 12.6900000000; data_table[1].feg[0].cl[3] = 0.5000000000; data_table[1].feg[0].cnl[3] = 0.4371000000; data_table[1].feg[0].cl[4] = 0.5000000000; data_table[1].feg[0].cnl[4] = 5.2940000000; data_table[1].feg[0].cl[5] = 0.5000000000; data_table[1].feg[0].cnl[5] = 28.2500000000; + data_table[2].feg[0].cl[0] = 0.5000000000; data_table[2].feg[0].cnl[0] = 0.6845000000; data_table[2].feg[0].cl[1] = 0.5000000000; data_table[2].feg[0].cnl[1] = 3.0650000000; data_table[2].feg[0].cl[2] = 0.5000000000; data_table[2].feg[0].cnl[2] = 6.2400000000; data_table[2].feg[0].cl[3] = 0.5000000000; data_table[2].feg[0].cnl[3] = 126.2000000000; data_table[2].feg[0].cl[4] = 0.5000000000; data_table[2].feg[0].cnl[4] = 131.2000000000; data_table[2].feg[0].cl[5] = 0.5000000000; data_table[2].feg[0].cnl[5] = 131.8000000000; + data_table[3].feg[0].cl[0] = 0.3000000000; data_table[3].feg[0].cnl[0] = 0.5400000000; data_table[3].feg[0].cl[1] = 0.3000000000; data_table[3].feg[0].cnl[1] = 3.3880000000; data_table[3].feg[0].cl[2] = 0.3000000000; data_table[3].feg[0].cnl[2] = 55.6200000000; data_table[3].feg[0].cl[3] = 0.3000000000; data_table[3].feg[0].cnl[3] = 50.7800000000; data_table[3].feg[0].cl[4] = 0.3000000000; data_table[3].feg[0].cnl[4] = 67.0100000000; data_table[3].feg[0].cl[5] = 0.3000000000; data_table[3].feg[0].cnl[5] = 96.3700000000; + data_table[4].feg[0].cl[0] = 0.5000000000; data_table[4].feg[0].cnl[0] = 0.3314000000; data_table[4].feg[0].cl[1] = 0.5000000000; data_table[4].feg[0].cnl[1] = 2.9750000000; data_table[4].feg[0].cl[2] = 0.5000000000; data_table[4].feg[0].cnl[2] = 34.0100000000; data_table[4].feg[0].cl[3] = 0.5000000000; data_table[4].feg[0].cnl[3] = 35.9800000000; data_table[4].feg[0].cl[4] = 0.5000000000; data_table[4].feg[0].cnl[4] = 36.6800000000; data_table[4].feg[0].cl[5] = 0.5000000000; data_table[4].feg[0].cnl[5] = 60.8100000000; + data_table[5].feg[0].cl[0] = 0.5000000000; data_table[5].feg[0].cnl[0] = 0.2946000000; data_table[5].feg[0].cl[1] = 0.5000000000; data_table[5].feg[0].cnl[1] = 3.9340000000; data_table[5].feg[0].cl[2] = 0.5000000000; data_table[5].feg[0].cnl[2] = 24.9800000000; data_table[5].feg[0].cl[3] = 0.5000000000; data_table[5].feg[0].cnl[3] = 25.2800000000; data_table[5].feg[0].cl[4] = 0.5000000000; data_table[5].feg[0].cnl[4] = 25.4700000000; data_table[5].feg[0].cl[5] = 0.5000000000; data_table[5].feg[0].cnl[5] = 46.7000000000; + data_table[6].feg[0].cl[0] = 0.5000000000; data_table[6].feg[0].cnl[0] = 0.2393000000; data_table[6].feg[0].cl[1] = 0.5000000000; data_table[6].feg[0].cnl[1] = 4.9350000000; data_table[6].feg[0].cl[2] = 0.5000000000; data_table[6].feg[0].cnl[2] = 18.1200000000; data_table[6].feg[0].cl[3] = 0.5000000000; data_table[6].feg[0].cnl[3] = 15.7000000000; data_table[6].feg[0].cl[4] = 0.5000000000; data_table[6].feg[0].cnl[4] = 15.8200000000; data_table[6].feg[0].cl[5] = 0.5000000000; data_table[6].feg[0].cnl[5] = 40.2400000000; + data_table[7].feg[0].cl[0] = 0.5000000000; data_table[7].feg[0].cnl[0] = 6.3760000000; data_table[7].feg[0].cl[1] = 0.5000000000; data_table[7].feg[0].cnl[1] = 8.0370000000; data_table[7].feg[0].cl[2] = 0.5000000000; data_table[7].feg[0].cnl[2] = 27.2100000000; data_table[7].feg[0].cl[3] = 0.5000000000; data_table[7].feg[0].cnl[3] = 0.1116000000; data_table[7].feg[0].cl[4] = 0.5000000000; data_table[7].feg[0].cnl[4] = 0.3869000000; data_table[7].feg[0].cl[5] = 0.5000000000; data_table[7].feg[0].cnl[5] = 10.9000000000; + data_table[8].feg[0].cl[0] = 0.5000000000; data_table[8].feg[0].cnl[0] = 0.2180000000; data_table[8].feg[0].cl[1] = 0.5000000000; data_table[8].feg[0].cnl[1] = 6.7700000000; data_table[8].feg[0].cl[2] = 0.5000000000; data_table[8].feg[0].cnl[2] = 7.0510000000; data_table[8].feg[0].cl[3] = 0.5000000000; data_table[8].feg[0].cnl[3] = 6.6750000000; data_table[8].feg[0].cl[4] = 0.5000000000; data_table[8].feg[0].cnl[4] = 12.3800000000; data_table[8].feg[0].cl[5] = 0.5000000000; data_table[8].feg[0].cnl[5] = 28.0800000000; + data_table[9].feg[0].cl[0] = 0.5000000000; data_table[9].feg[0].cnl[0] = 0.2006000000; data_table[9].feg[0].cl[1] = 0.5000000000; data_table[9].feg[0].cnl[1] = 5.4980000000; data_table[9].feg[0].cl[2] = 0.5000000000; data_table[9].feg[0].cnl[2] = 6.2810000000; data_table[9].feg[0].cl[3] = 0.5000000000; data_table[9].feg[0].cnl[3] = 7.1920000000; data_table[9].feg[0].cl[4] = 0.5000000000; data_table[9].feg[0].cnl[4] = 7.5480000000; data_table[9].feg[0].cl[5] = 0.5000000000; data_table[9].feg[0].cnl[5] = 23.2600000000; + data_table[10].feg[0].cl[0] = 0.5000000000; data_table[10].feg[0].cnl[0] = 0.2190000000; data_table[10].feg[0].cl[1] = 0.5000000000; data_table[10].feg[0].cnl[1] = 5.3000000000; data_table[10].feg[0].cl[2] = 0.5000000000; data_table[10].feg[0].cnl[2] = 5.3190000000; data_table[10].feg[0].cl[3] = 0.5000000000; data_table[10].feg[0].cnl[3] = 5.2830000000; data_table[10].feg[0].cl[4] = 0.5000000000; data_table[10].feg[0].cnl[4] = 5.2850000000; data_table[10].feg[0].cl[5] = 0.5000000000; data_table[10].feg[0].cnl[5] = 128.2000000000; + data_table[11].feg[0].cl[0] = 0.5000000000; data_table[11].feg[0].cnl[0] = 1.9760000000; data_table[11].feg[0].cl[1] = 0.5000000000; data_table[11].feg[0].cnl[1] = 2.8090000000; data_table[11].feg[0].cl[2] = 0.5000000000; data_table[11].feg[0].cnl[2] = 16.3900000000; data_table[11].feg[0].cl[3] = 0.5000000000; data_table[11].feg[0].cnl[3] = 0.0549000000; data_table[11].feg[0].cl[4] = 0.5000000000; data_table[11].feg[0].cnl[4] = 2.0610000000; data_table[11].feg[0].cl[5] = 0.5000000000; data_table[11].feg[0].cnl[5] = 121.7000000000; + data_table[12].feg[0].cl[0] = 0.4000000000; data_table[12].feg[0].cnl[0] = 2.2970000000; data_table[12].feg[0].cl[1] = 0.4000000000; data_table[12].feg[0].cnl[1] = 2.3580000000; data_table[12].feg[0].cl[2] = 0.4000000000; data_table[12].feg[0].cnl[2] = 24.9900000000; data_table[12].feg[0].cl[3] = 0.4000000000; data_table[12].feg[0].cnl[3] = 0.0746000000; data_table[12].feg[0].cl[4] = 0.4000000000; data_table[12].feg[0].cnl[4] = 0.5595000000; data_table[12].feg[0].cl[5] = 0.4000000000; data_table[12].feg[0].cnl[5] = 128.5000000000; + data_table[13].feg[0].cl[0] = 0.5000000000; data_table[13].feg[0].cnl[0] = 1.7370000000; data_table[13].feg[0].cl[1] = 0.5000000000; data_table[13].feg[0].cnl[1] = 3.0430000000; data_table[13].feg[0].cl[2] = 0.5000000000; data_table[13].feg[0].cnl[2] = 30.5700000000; data_table[13].feg[0].cl[3] = 0.5000000000; data_table[13].feg[0].cnl[3] = 0.0507000000; data_table[13].feg[0].cl[4] = 0.5000000000; data_table[13].feg[0].cnl[4] = 0.9918000000; data_table[13].feg[0].cl[5] = 0.5000000000; data_table[13].feg[0].cnl[5] = 86.1800000000; + data_table[14].feg[0].cl[0] = 0.5000000000; data_table[14].feg[0].cnl[0] = 0.1795000000; data_table[14].feg[0].cl[1] = 0.5000000000; data_table[14].feg[0].cnl[1] = 2.6320000000; data_table[14].feg[0].cl[2] = 0.5000000000; data_table[14].feg[0].cnl[2] = 2.6760000000; data_table[14].feg[0].cl[3] = 0.5000000000; data_table[14].feg[0].cnl[3] = 34.5700000000; data_table[14].feg[0].cl[4] = 0.5000000000; data_table[14].feg[0].cnl[4] = 36.7800000000; data_table[14].feg[0].cl[5] = 0.5000000000; data_table[14].feg[0].cnl[5] = 54.0600000000; + data_table[15].feg[0].cl[0] = 0.5000000000; data_table[15].feg[0].cnl[0] = 1.0060000000; data_table[15].feg[0].cl[1] = 0.5000000000; data_table[15].feg[0].cnl[1] = 4.9040000000; data_table[15].feg[0].cl[2] = 0.5000000000; data_table[15].feg[0].cnl[2] = 31.3500000000; data_table[15].feg[0].cl[3] = 0.5000000000; data_table[15].feg[0].cnl[3] = 0.0370000000; data_table[15].feg[0].cl[4] = 0.5000000000; data_table[15].feg[0].cnl[4] = 0.9870000000; data_table[15].feg[0].cl[5] = 0.5000000000; data_table[15].feg[0].cnl[5] = 44.9400000000; + data_table[16].feg[0].cl[0] = 0.5000000000; data_table[16].feg[0].cnl[0] = 0.1846000000; data_table[16].feg[0].cl[1] = 0.5000000000; data_table[16].feg[0].cnl[1] = 1.4800000000; data_table[16].feg[0].cl[2] = 0.5000000000; data_table[16].feg[0].cnl[2] = 5.2100000000; data_table[16].feg[0].cl[3] = 0.5000000000; data_table[16].feg[0].cnl[3] = 24.7900000000; data_table[16].feg[0].cl[4] = 0.5000000000; data_table[16].feg[0].cnl[4] = 32.0600000000; data_table[16].feg[0].cl[5] = 0.5000000000; data_table[16].feg[0].cnl[5] = 39.1000000000; + data_table[17].feg[0].cl[0] = 0.5000000000; data_table[17].feg[0].cnl[0] = 0.2006000000; data_table[17].feg[0].cl[1] = 0.5000000000; data_table[17].feg[0].cnl[1] = 6.5330000000; data_table[17].feg[0].cl[2] = 0.5000000000; data_table[17].feg[0].cnl[2] = 22.7200000000; data_table[17].feg[0].cl[3] = 0.5000000000; data_table[17].feg[0].cnl[3] = 1.2000000000; data_table[17].feg[0].cl[4] = 0.5000000000; data_table[17].feg[0].cnl[4] = 1.2740000000; data_table[17].feg[0].cl[5] = 0.5000000000; data_table[17].feg[0].cnl[5] = 36.2600000000; + data_table[18].feg[0].cl[0] = 0.2000000000; data_table[18].feg[0].cnl[0] = 0.4442000000; data_table[18].feg[0].cl[1] = 0.2000000000; data_table[18].feg[0].cnl[1] = 3.3670000000; data_table[18].feg[0].cl[2] = 0.2000000000; data_table[18].feg[0].cnl[2] = 19.6300000000; data_table[18].feg[0].cl[3] = 0.2000000000; data_table[18].feg[0].cnl[3] = 0.0182000000; data_table[18].feg[0].cl[4] = 0.2000000000; data_table[18].feg[0].cnl[4] = 23.5100000000; data_table[18].feg[0].cl[5] = 0.2000000000; data_table[18].feg[0].cnl[5] = 212.9000000000; + data_table[19].feg[0].cl[0] = 0.3000000000; data_table[19].feg[0].cnl[0] = 0.1827000000; data_table[19].feg[0].cl[1] = 0.3000000000; data_table[19].feg[0].cnl[1] = 2.0660000000; data_table[19].feg[0].cl[2] = 0.3000000000; data_table[19].feg[0].cnl[2] = 16.9900000000; data_table[19].feg[0].cl[3] = 0.3000000000; data_table[19].feg[0].cnl[3] = 11.5800000000; data_table[19].feg[0].cl[4] = 0.3000000000; data_table[19].feg[0].cnl[4] = 13.9800000000; data_table[19].feg[0].cl[5] = 0.3000000000; data_table[19].feg[0].cnl[5] = 186.1000000000; + data_table[20].feg[0].cl[0] = 0.5000000000; data_table[20].feg[0].cnl[0] = 0.1425000000; data_table[20].feg[0].cl[1] = 0.5000000000; data_table[20].feg[0].cnl[1] = 1.4660000000; data_table[20].feg[0].cl[2] = 0.5000000000; data_table[20].feg[0].cnl[2] = 15.4700000000; data_table[20].feg[0].cl[3] = 0.5000000000; data_table[20].feg[0].cnl[3] = 4.2430000000; data_table[20].feg[0].cl[4] = 0.5000000000; data_table[20].feg[0].cnl[4] = 9.8040000000; data_table[20].feg[0].cl[5] = 0.5000000000; data_table[20].feg[0].cnl[5] = 121.5000000000; + data_table[21].feg[0].cl[0] = 0.5000000000; data_table[21].feg[0].cnl[0] = 0.1278000000; data_table[21].feg[0].cl[1] = 0.5000000000; data_table[21].feg[0].cnl[1] = 1.4560000000; data_table[21].feg[0].cl[2] = 0.5000000000; data_table[21].feg[0].cnl[2] = 12.1000000000; data_table[21].feg[0].cl[3] = 0.5000000000; data_table[21].feg[0].cnl[3] = 4.6170000000; data_table[21].feg[0].cl[4] = 0.5000000000; data_table[21].feg[0].cnl[4] = 11.9700000000; data_table[21].feg[0].cl[5] = 0.5000000000; data_table[21].feg[0].cnl[5] = 105.0000000000; + data_table[22].feg[0].cl[0] = 0.5000000000; data_table[22].feg[0].cnl[0] = 0.1313000000; data_table[22].feg[0].cl[1] = 0.5000000000; data_table[22].feg[0].cnl[1] = 1.3990000000; data_table[22].feg[0].cl[2] = 0.5000000000; data_table[22].feg[0].cnl[2] = 8.0080000000; data_table[22].feg[0].cl[3] = 0.5000000000; data_table[22].feg[0].cnl[3] = 7.9810000000; data_table[22].feg[0].cl[4] = 0.5000000000; data_table[22].feg[0].cnl[4] = 13.4100000000; data_table[22].feg[0].cl[5] = 0.5000000000; data_table[22].feg[0].cnl[5] = 95.3100000000; + data_table[23].feg[0].cl[0] = 0.5000000000; data_table[23].feg[0].cnl[0] = 0.1231000000; data_table[23].feg[0].cl[1] = 0.5000000000; data_table[23].feg[0].cnl[1] = 2.3840000000; data_table[23].feg[0].cl[2] = 0.5000000000; data_table[23].feg[0].cnl[2] = 9.9210000000; data_table[23].feg[0].cl[3] = 0.5000000000; data_table[23].feg[0].cnl[3] = 1.6480000000; data_table[23].feg[0].cl[4] = 0.5000000000; data_table[23].feg[0].cnl[4] = 11.0000000000; data_table[23].feg[0].cl[5] = 0.5000000000; data_table[23].feg[0].cnl[5] = 68.4600000000; + data_table[24].feg[0].cl[0] = 0.5000000000; data_table[24].feg[0].cnl[0] = 0.4817000000; data_table[24].feg[0].cl[1] = 0.5000000000; data_table[24].feg[0].cnl[1] = 3.7830000000; data_table[24].feg[0].cl[2] = 0.5000000000; data_table[24].feg[0].cnl[2] = 8.4730000000; data_table[24].feg[0].cl[3] = 0.5000000000; data_table[24].feg[0].cnl[3] = 0.0469000000; data_table[24].feg[0].cl[4] = 0.5000000000; data_table[24].feg[0].cnl[4] = 8.7450000000; data_table[24].feg[0].cl[5] = 0.5000000000; data_table[24].feg[0].cnl[5] = 77.4400000000; + data_table[25].feg[0].cl[0] = 0.5000000000; data_table[25].feg[0].cnl[0] = 0.4470000000; data_table[25].feg[0].cl[1] = 0.5000000000; data_table[25].feg[0].cnl[1] = 6.8940000000; data_table[25].feg[0].cl[2] = 0.5000000000; data_table[25].feg[0].cnl[2] = 6.9030000000; data_table[25].feg[0].cl[3] = 0.5000000000; data_table[25].feg[0].cnl[3] = 0.0569000000; data_table[25].feg[0].cl[4] = 0.5000000000; data_table[25].feg[0].cnl[4] = 3.0260000000; data_table[25].feg[0].cl[5] = 0.5000000000; data_table[25].feg[0].cnl[5] = 70.8700000000; + data_table[26].feg[0].cl[0] = 0.5000000000; data_table[26].feg[0].cnl[0] = 0.1071000000; data_table[26].feg[0].cl[1] = 0.5000000000; data_table[26].feg[0].cnl[1] = 3.6360000000; data_table[26].feg[0].cl[2] = 0.5000000000; data_table[26].feg[0].cnl[2] = 7.5580000000; data_table[26].feg[0].cl[3] = 0.5000000000; data_table[26].feg[0].cnl[3] = 1.2800000000; data_table[26].feg[0].cl[4] = 0.5000000000; data_table[26].feg[0].cnl[4] = 5.1400000000; data_table[26].feg[0].cl[5] = 0.5000000000; data_table[26].feg[0].cnl[5] = 67.1600000000; + data_table[27].feg[0].cl[0] = 0.5000000000; data_table[27].feg[0].cnl[0] = 0.1107000000; data_table[27].feg[0].cl[1] = 0.5000000000; data_table[27].feg[0].cnl[1] = 1.6190000000; data_table[27].feg[0].cl[2] = 0.5000000000; data_table[27].feg[0].cnl[2] = 6.0030000000; data_table[27].feg[0].cl[3] = 0.5000000000; data_table[27].feg[0].cnl[3] = 5.9750000000; data_table[27].feg[0].cl[4] = 0.5000000000; data_table[27].feg[0].cnl[4] = 6.0600000000; data_table[27].feg[0].cl[5] = 0.5000000000; data_table[27].feg[0].cnl[5] = 59.4100000000; + data_table[28].feg[0].cl[0] = 0.5000000000; data_table[28].feg[0].cnl[0] = 0.1129000000; data_table[28].feg[0].cl[1] = 0.5000000000; data_table[28].feg[0].cnl[1] = 1.8910000000; data_table[28].feg[0].cl[2] = 0.5000000000; data_table[28].feg[0].cnl[2] = 5.0850000000; data_table[28].feg[0].cl[3] = 0.5000000000; data_table[28].feg[0].cnl[3] = 5.0730000000; data_table[28].feg[0].cl[4] = 0.5000000000; data_table[28].feg[0].cnl[4] = 5.0990000000; data_table[28].feg[0].cl[5] = 0.5000000000; data_table[28].feg[0].cnl[5] = 46.3900000000; + data_table[29].feg[0].cl[0] = 0.5000000000; data_table[29].feg[0].cnl[0] = 0.1021000000; data_table[29].feg[0].cl[1] = 0.5000000000; data_table[29].feg[0].cnl[1] = 1.7340000000; data_table[29].feg[0].cl[2] = 0.5000000000; data_table[29].feg[0].cnl[2] = 4.7830000000; data_table[29].feg[0].cl[3] = 0.5000000000; data_table[29].feg[0].cnl[3] = 4.8070000000; data_table[29].feg[0].cl[4] = 0.5000000000; data_table[29].feg[0].cnl[4] = 5.6450000000; data_table[29].feg[0].cl[5] = 0.5000000000; data_table[29].feg[0].cnl[5] = 51.2200000000; + data_table[30].feg[0].cl[0] = 0.5000000000; data_table[30].feg[0].cnl[0] = 0.1064000000; data_table[30].feg[0].cl[1] = 0.5000000000; data_table[30].feg[0].cnl[1] = 1.5370000000; data_table[30].feg[0].cl[2] = 0.5000000000; data_table[30].feg[0].cnl[2] = 5.1380000000; data_table[30].feg[0].cl[3] = 0.5000000000; data_table[30].feg[0].cnl[3] = 4.7430000000; data_table[30].feg[0].cl[4] = 0.5000000000; data_table[30].feg[0].cnl[4] = 5.0000000000; data_table[30].feg[0].cl[5] = 0.5000000000; data_table[30].feg[0].cnl[5] = 61.4300000000; + data_table[31].feg[0].cl[0] = 0.5000000000; data_table[31].feg[0].cnl[0] = 0.0958000000; data_table[31].feg[0].cl[1] = 0.5000000000; data_table[31].feg[0].cnl[1] = 1.6770000000; data_table[31].feg[0].cl[2] = 0.5000000000; data_table[31].feg[0].cnl[2] = 4.7030000000; data_table[31].feg[0].cl[3] = 0.5000000000; data_table[31].feg[0].cnl[3] = 2.9120000000; data_table[31].feg[0].cl[4] = 0.5000000000; data_table[31].feg[0].cnl[4] = 7.8700000000; data_table[31].feg[0].cl[5] = 0.5000000000; data_table[31].feg[0].cnl[5] = 64.9400000000; + data_table[32].feg[0].cl[0] = 0.5000000000; data_table[32].feg[0].cnl[0] = 0.0943000000; data_table[32].feg[0].cl[1] = 0.5000000000; data_table[32].feg[0].cnl[1] = 2.2140000000; data_table[32].feg[0].cl[2] = 0.5000000000; data_table[32].feg[0].cnl[2] = 3.9510000000; data_table[32].feg[0].cl[3] = 0.5000000000; data_table[32].feg[0].cnl[3] = 1.5210000000; data_table[32].feg[0].cl[4] = 0.5000000000; data_table[32].feg[0].cnl[4] = 15.8100000000; data_table[32].feg[0].cl[5] = 0.5000000000; data_table[32].feg[0].cnl[5] = 52.4100000000; + data_table[33].feg[0].cl[0] = 0.5000000000; data_table[33].feg[0].cnl[0] = 0.0925000000; data_table[33].feg[0].cl[1] = 0.5000000000; data_table[33].feg[0].cnl[1] = 1.6020000000; data_table[33].feg[0].cl[2] = 0.5000000000; data_table[33].feg[0].cnl[2] = 3.0490000000; data_table[33].feg[0].cl[3] = 0.5000000000; data_table[33].feg[0].cnl[3] = 3.1850000000; data_table[33].feg[0].cl[4] = 0.5000000000; data_table[33].feg[0].cnl[4] = 18.9400000000; data_table[33].feg[0].cl[5] = 0.5000000000; data_table[33].feg[0].cnl[5] = 47.6300000000; + data_table[34].feg[0].cl[0] = 0.5000000000; data_table[34].feg[0].cnl[0] = 0.0925000000; data_table[34].feg[0].cl[1] = 0.5000000000; data_table[34].feg[0].cnl[1] = 1.7730000000; data_table[34].feg[0].cl[2] = 0.5000000000; data_table[34].feg[0].cnl[2] = 3.4810000000; data_table[34].feg[0].cl[3] = 0.5000000000; data_table[34].feg[0].cnl[3] = 1.8840000000; data_table[34].feg[0].cl[4] = 0.5000000000; data_table[34].feg[0].cnl[4] = 22.6900000000; data_table[34].feg[0].cl[5] = 0.5000000000; data_table[34].feg[0].cnl[5] = 40.6900000000; + data_table[35].feg[0].cl[0] = 0.5000000000; data_table[35].feg[0].cnl[0] = 0.4932000000; data_table[35].feg[0].cl[1] = 0.5000000000; data_table[35].feg[0].cnl[1] = 2.0830000000; data_table[35].feg[0].cl[2] = 0.5000000000; data_table[35].feg[0].cnl[2] = 11.4100000000; data_table[35].feg[0].cl[3] = 0.5000000000; data_table[35].feg[0].cnl[3] = 0.0333000000; data_table[35].feg[0].cl[4] = 0.5000000000; data_table[35].feg[0].cnl[4] = 2.0970000000; data_table[35].feg[0].cl[5] = 0.5000000000; data_table[35].feg[0].cnl[5] = 42.3800000000; + data_table[36].feg[0].cl[0] = 0.2000000000; data_table[36].feg[0].cnl[0] = 0.1580000000; data_table[36].feg[0].cl[1] = 0.2000000000; data_table[36].feg[0].cnl[1] = 1.7150000000; data_table[36].feg[0].cl[2] = 0.2000000000; data_table[36].feg[0].cnl[2] = 9.3920000000; data_table[36].feg[0].cl[3] = 0.2000000000; data_table[36].feg[0].cnl[3] = 1.6750000000; data_table[36].feg[0].cl[4] = 0.2000000000; data_table[36].feg[0].cnl[4] = 23.5900000000; data_table[36].feg[0].cl[5] = 0.2000000000; data_table[36].feg[0].cnl[5] = 152.5000000000; + data_table[37].feg[0].cl[0] = 0.3000000000; data_table[37].feg[0].cnl[0] = 0.3605000000; data_table[37].feg[0].cl[1] = 0.3000000000; data_table[37].feg[0].cnl[1] = 2.1280000000; data_table[37].feg[0].cl[2] = 0.3000000000; data_table[37].feg[0].cnl[2] = 12.4600000000; data_table[37].feg[0].cl[3] = 0.3000000000; data_table[37].feg[0].cnl[3] = 0.0153000000; data_table[37].feg[0].cl[4] = 0.3000000000; data_table[37].feg[0].cnl[4] = 2.1080000000; data_table[37].feg[0].cl[5] = 0.3000000000; data_table[37].feg[0].cnl[5] = 133.2000000000; + data_table[38].feg[0].cl[0] = 0.5000000000; data_table[38].feg[0].cnl[0] = 0.0900000000; data_table[38].feg[0].cl[1] = 0.5000000000; data_table[38].feg[0].cnl[1] = 1.4140000000; data_table[38].feg[0].cl[2] = 0.5000000000; data_table[38].feg[0].cnl[2] = 2.0530000000; data_table[38].feg[0].cl[3] = 0.5000000000; data_table[38].feg[0].cnl[3] = 10.2600000000; data_table[38].feg[0].cl[4] = 0.5000000000; data_table[38].feg[0].cnl[4] = 10.7500000000; data_table[38].feg[0].cl[5] = 0.5000000000; data_table[38].feg[0].cnl[5] = 90.6400000000; + data_table[39].feg[0].cl[0] = 0.5000000000; data_table[39].feg[0].cnl[0] = 0.1009000000; data_table[39].feg[0].cl[1] = 0.5000000000; data_table[39].feg[0].cnl[1] = 1.1540000000; data_table[39].feg[0].cl[2] = 0.5000000000; data_table[39].feg[0].cnl[2] = 2.3470000000; data_table[39].feg[0].cl[3] = 0.5000000000; data_table[39].feg[0].cnl[3] = 10.5800000000; data_table[39].feg[0].cl[4] = 0.5000000000; data_table[39].feg[0].cnl[4] = 10.9500000000; data_table[39].feg[0].cl[5] = 0.5000000000; data_table[39].feg[0].cnl[5] = 82.8200000000; + data_table[40].feg[0].cl[0] = 0.5000000000; data_table[40].feg[0].cnl[0] = 0.0924000000; data_table[40].feg[0].cl[1] = 0.5000000000; data_table[40].feg[0].cnl[1] = 1.1700000000; data_table[40].feg[0].cl[2] = 0.5000000000; data_table[40].feg[0].cnl[2] = 5.9400000000; data_table[40].feg[0].cl[3] = 0.5000000000; data_table[40].feg[0].cnl[3] = 1.3060000000; data_table[40].feg[0].cl[4] = 0.5000000000; data_table[40].feg[0].cnl[4] = 13.4300000000; data_table[40].feg[0].cl[5] = 0.5000000000; data_table[40].feg[0].cnl[5] = 66.3700000000; + data_table[41].feg[0].cl[0] = 0.5000000000; data_table[41].feg[0].cnl[0] = 0.4354000000; data_table[41].feg[0].cl[1] = 0.5000000000; data_table[41].feg[0].cnl[1] = 1.2480000000; data_table[41].feg[0].cl[2] = 0.5000000000; data_table[41].feg[0].cnl[2] = 7.4540000000; data_table[41].feg[0].cl[3] = 0.5000000000; data_table[41].feg[0].cnl[3] = 0.0354000000; data_table[41].feg[0].cl[4] = 0.5000000000; data_table[41].feg[0].cnl[4] = 9.9140000000; data_table[41].feg[0].cl[5] = 0.5000000000; data_table[41].feg[0].cnl[5] = 61.7200000000; + data_table[42].feg[0].cl[0] = 0.5000000000; data_table[42].feg[0].cnl[0] = 0.4594000000; data_table[42].feg[0].cl[1] = 0.5000000000; data_table[42].feg[0].cnl[1] = 1.1820000000; data_table[42].feg[0].cl[2] = 0.5000000000; data_table[42].feg[0].cnl[2] = 8.3170000000; data_table[42].feg[0].cl[3] = 0.5000000000; data_table[42].feg[0].cnl[3] = 0.0323000000; data_table[42].feg[0].cl[4] = 0.5000000000; data_table[42].feg[0].cnl[4] = 8.3230000000; data_table[42].feg[0].cl[5] = 0.5000000000; data_table[42].feg[0].cnl[5] = 64.9800000000; + data_table[43].feg[0].cl[0] = 0.4000000000; data_table[43].feg[0].cnl[0] = 0.0860000000; data_table[43].feg[0].cl[1] = 0.4000000000; data_table[43].feg[0].cnl[1] = 1.3960000000; data_table[43].feg[0].cl[2] = 0.4000000000; data_table[43].feg[0].cnl[2] = 11.7000000000; data_table[43].feg[0].cl[3] = 0.4000000000; data_table[43].feg[0].cnl[3] = 1.3960000000; data_table[43].feg[0].cl[4] = 0.4000000000; data_table[43].feg[0].cnl[4] = 3.4520000000; data_table[43].feg[0].cl[5] = 0.4000000000; data_table[43].feg[0].cnl[5] = 55.5600000000; + data_table[44].feg[0].cl[0] = 0.5000000000; data_table[44].feg[0].cnl[0] = 0.0921000000; data_table[44].feg[0].cl[1] = 0.5000000000; data_table[44].feg[0].cnl[1] = 1.1130000000; data_table[44].feg[0].cl[2] = 0.5000000000; data_table[44].feg[0].cnl[2] = 7.6580000000; data_table[44].feg[0].cl[3] = 0.5000000000; data_table[44].feg[0].cnl[3] = 1.1260000000; data_table[44].feg[0].cl[4] = 0.5000000000; data_table[44].feg[0].cnl[4] = 8.3250000000; data_table[44].feg[0].cl[5] = 0.5000000000; data_table[44].feg[0].cnl[5] = 48.3800000000; + data_table[45].feg[0].cl[0] = 0.5000000000; data_table[45].feg[0].cnl[0] = 0.0901000000; data_table[45].feg[0].cl[1] = 0.5000000000; data_table[45].feg[0].cnl[1] = 1.1250000000; data_table[45].feg[0].cl[2] = 0.5000000000; data_table[45].feg[0].cnl[2] = 9.6980000000; data_table[45].feg[0].cl[3] = 0.5000000000; data_table[45].feg[0].cnl[3] = 1.0850000000; data_table[45].feg[0].cl[4] = 0.5000000000; data_table[45].feg[0].cnl[4] = 5.7090000000; data_table[45].feg[0].cl[5] = 0.5000000000; data_table[45].feg[0].cnl[5] = 33.4900000000; + data_table[46].feg[0].cl[0] = 0.5000000000; data_table[46].feg[0].cnl[0] = 0.0894000000; data_table[46].feg[0].cl[1] = 0.5000000000; data_table[46].feg[0].cnl[1] = 3.1910000000; data_table[46].feg[0].cl[2] = 0.5000000000; data_table[46].feg[0].cnl[2] = 9.1000000000; data_table[46].feg[0].cl[3] = 0.5000000000; data_table[46].feg[0].cnl[3] = 0.8090000000; data_table[46].feg[0].cl[4] = 0.5000000000; data_table[46].feg[0].cnl[4] = 0.8144000000; data_table[46].feg[0].cl[5] = 0.5000000000; data_table[46].feg[0].cnl[5] = 41.3400000000; + data_table[47].feg[0].cl[0] = 0.3000000000; data_table[47].feg[0].cnl[0] = 0.2885000000; data_table[47].feg[0].cl[1] = 0.3000000000; data_table[47].feg[0].cnl[1] = 1.6130000000; data_table[47].feg[0].cl[2] = 0.3000000000; data_table[47].feg[0].cnl[2] = 8.9970000000; data_table[47].feg[0].cl[3] = 0.3000000000; data_table[47].feg[0].cnl[3] = 0.0171000000; data_table[47].feg[0].cl[4] = 0.3000000000; data_table[47].feg[0].cnl[4] = 9.4670000000; data_table[47].feg[0].cl[5] = 0.3000000000; data_table[47].feg[0].cnl[5] = 58.1300000000; + data_table[48].feg[0].cl[0] = 0.4000000000; data_table[48].feg[0].cnl[0] = 0.0895000000; data_table[48].feg[0].cl[1] = 0.4000000000; data_table[48].feg[0].cnl[1] = 1.2330000000; data_table[48].feg[0].cl[2] = 0.4000000000; data_table[48].feg[0].cnl[2] = 8.2310000000; data_table[48].feg[0].cl[3] = 0.4000000000; data_table[48].feg[0].cnl[3] = 1.2240000000; data_table[48].feg[0].cl[4] = 0.4000000000; data_table[48].feg[0].cnl[4] = 7.0620000000; data_table[48].feg[0].cl[5] = 0.4000000000; data_table[48].feg[0].cnl[5] = 59.7000000000; + data_table[49].feg[0].cl[0] = 0.6000000000; data_table[49].feg[0].cnl[0] = 0.0712000000; data_table[49].feg[0].cl[1] = 0.6000000000; data_table[49].feg[0].cnl[1] = 0.8553000000; data_table[49].feg[0].cl[2] = 0.6000000000; data_table[49].feg[0].cnl[2] = 6.4010000000; data_table[49].feg[0].cl[3] = 0.6000000000; data_table[49].feg[0].cnl[3] = 1.3360000000; data_table[49].feg[0].cl[4] = 0.6000000000; data_table[49].feg[0].cnl[4] = 6.3820000000; data_table[49].feg[0].cl[5] = 0.6000000000; data_table[49].feg[0].cnl[5] = 50.9200000000; + data_table[50].feg[0].cl[0] = 0.6000000000; data_table[50].feg[0].cnl[0] = 0.3575000000; data_table[50].feg[0].cl[1] = 0.6000000000; data_table[50].feg[0].cnl[1] = 1.3250000000; data_table[50].feg[0].cl[2] = 0.6000000000; data_table[50].feg[0].cnl[2] = 6.5170000000; data_table[50].feg[0].cl[3] = 0.6000000000; data_table[50].feg[0].cnl[3] = 0.0355000000; data_table[50].feg[0].cl[4] = 0.6000000000; data_table[50].feg[0].cnl[4] = 6.5190000000; data_table[50].feg[0].cl[5] = 0.6000000000; data_table[50].feg[0].cnl[5] = 50.8100000000; + data_table[51].feg[0].cl[0] = 0.6000000000; data_table[51].feg[0].cnl[0] = 0.5009000000; data_table[51].feg[0].cl[1] = 0.6000000000; data_table[51].feg[0].cnl[1] = 3.9530000000; data_table[51].feg[0].cl[2] = 0.6000000000; data_table[51].feg[0].cnl[2] = 7.6280000000; data_table[51].feg[0].cl[3] = 0.6000000000; data_table[51].feg[0].cnl[3] = 0.0301000000; data_table[51].feg[0].cl[4] = 0.6000000000; data_table[51].feg[0].cnl[4] = 0.5074000000; data_table[51].feg[0].cl[5] = 0.6000000000; data_table[51].feg[0].cnl[5] = 49.6300000000; + data_table[52].feg[0].cl[0] = 0.4000000000; data_table[52].feg[0].cnl[0] = 0.0843000000; data_table[52].feg[0].cl[1] = 0.4000000000; data_table[52].feg[0].cnl[1] = 1.1300000000; data_table[52].feg[0].cl[2] = 0.4000000000; data_table[52].feg[0].cnl[2] = 8.8620000000; data_table[52].feg[0].cl[3] = 0.4000000000; data_table[52].feg[0].cnl[3] = 1.1300000000; data_table[52].feg[0].cl[4] = 0.4000000000; data_table[52].feg[0].cnl[4] = 9.1320000000; data_table[52].feg[0].cl[5] = 0.4000000000; data_table[52].feg[0].cnl[5] = 56.0200000000; + data_table[53].feg[0].cl[0] = 0.4000000000; data_table[53].feg[0].cnl[0] = 0.2780000000; data_table[53].feg[0].cl[1] = 0.4000000000; data_table[53].feg[0].cnl[1] = 1.6210000000; data_table[53].feg[0].cl[2] = 0.4000000000; data_table[53].feg[0].cnl[2] = 11.4500000000; data_table[53].feg[0].cl[3] = 0.4000000000; data_table[53].feg[0].cnl[3] = 0.0203000000; data_table[53].feg[0].cl[4] = 0.4000000000; data_table[53].feg[0].cnl[4] = 3.2750000000; data_table[53].feg[0].cl[5] = 0.4000000000; data_table[53].feg[0].cnl[5] = 51.4400000000; + data_table[54].feg[0].cl[0] = 0.1000000000; data_table[54].feg[0].cnl[0] = 0.1204000000; data_table[54].feg[0].cl[1] = 0.1000000000; data_table[54].feg[0].cnl[1] = 1.5370000000; data_table[54].feg[0].cl[2] = 0.1000000000; data_table[54].feg[0].cnl[2] = 9.8160000000; data_table[54].feg[0].cl[3] = 0.1000000000; data_table[54].feg[0].cnl[3] = 41.2200000000; data_table[54].feg[0].cl[4] = 0.1000000000; data_table[54].feg[0].cnl[4] = 42.6200000000; data_table[54].feg[0].cl[5] = 0.1000000000; data_table[54].feg[0].cnl[5] = 224.3000000000; + data_table[55].feg[0].cl[0] = 0.1000000000; data_table[55].feg[0].cnl[0] = 0.1223000000; data_table[55].feg[0].cl[1] = 0.1000000000; data_table[55].feg[0].cnl[1] = 1.4490000000; data_table[55].feg[0].cl[2] = 0.1000000000; data_table[55].feg[0].cnl[2] = 9.5020000000; data_table[55].feg[0].cl[3] = 0.1000000000; data_table[55].feg[0].cnl[3] = 49.4100000000; data_table[55].feg[0].cl[4] = 0.1000000000; data_table[55].feg[0].cnl[4] = 74.9500000000; data_table[55].feg[0].cl[5] = 0.1000000000; data_table[55].feg[0].cnl[5] = 217.0000000000; + data_table[56].feg[0].cl[0] = 0.3000000000; data_table[56].feg[0].cnl[0] = 0.0893000000; data_table[56].feg[0].cl[1] = 0.3000000000; data_table[56].feg[0].cnl[1] = 1.2620000000; data_table[56].feg[0].cl[2] = 0.3000000000; data_table[56].feg[0].cnl[2] = 8.0970000000; data_table[56].feg[0].cl[3] = 0.3000000000; data_table[56].feg[0].cnl[3] = 1.2030000000; data_table[56].feg[0].cl[4] = 0.3000000000; data_table[56].feg[0].cnl[4] = 17.6600000000; data_table[56].feg[0].cl[5] = 0.3000000000; data_table[56].feg[0].cnl[5] = 116.6000000000; + data_table[57].feg[0].cl[0] = 0.3000000000; data_table[57].feg[0].cnl[0] = 0.0850000000; data_table[57].feg[0].cl[1] = 0.3000000000; data_table[57].feg[0].cnl[1] = 1.2830000000; data_table[57].feg[0].cl[2] = 0.3000000000; data_table[57].feg[0].cnl[2] = 11.2200000000; data_table[57].feg[0].cl[3] = 0.3000000000; data_table[57].feg[0].cnl[3] = 1.3270000000; data_table[57].feg[0].cl[4] = 0.3000000000; data_table[57].feg[0].cnl[4] = 4.6100000000; data_table[57].feg[0].cl[5] = 0.3000000000; data_table[57].feg[0].cnl[5] = 112.2000000000; + data_table[58].feg[0].cl[0] = 0.2000000000; data_table[58].feg[0].cnl[0] = 0.0981000000; data_table[58].feg[0].cl[1] = 0.2000000000; data_table[58].feg[0].cnl[1] = 1.5260000000; data_table[58].feg[0].cl[2] = 0.2000000000; data_table[58].feg[0].cnl[2] = 8.5900000000; data_table[58].feg[0].cl[3] = 0.2000000000; data_table[58].feg[0].cnl[3] = 1.2390000000; data_table[58].feg[0].cl[4] = 0.2000000000; data_table[58].feg[0].cnl[4] = 22.4900000000; data_table[58].feg[0].cl[5] = 0.2000000000; data_table[58].feg[0].cnl[5] = 140.0000000000; + data_table[59].feg[0].cl[0] = 0.2000000000; data_table[59].feg[0].cnl[0] = 0.0941000000; data_table[59].feg[0].cl[1] = 0.2000000000; data_table[59].feg[0].cnl[1] = 1.2660000000; data_table[59].feg[0].cl[2] = 0.2000000000; data_table[59].feg[0].cnl[2] = 5.9880000000; data_table[59].feg[0].cl[3] = 0.2000000000; data_table[59].feg[0].cnl[3] = 17.7900000000; data_table[59].feg[0].cl[4] = 0.2000000000; data_table[59].feg[0].cnl[4] = 18.1400000000; data_table[59].feg[0].cl[5] = 0.2000000000; data_table[59].feg[0].cnl[5] = 132.6000000000; + data_table[60].feg[0].cl[0] = 0.2000000000; data_table[60].feg[0].cnl[0] = 0.0945000000; data_table[60].feg[0].cl[1] = 0.2000000000; data_table[60].feg[0].cnl[1] = 1.2510000000; data_table[60].feg[0].cl[2] = 0.2000000000; data_table[60].feg[0].cnl[2] = 5.9120000000; data_table[60].feg[0].cl[3] = 0.2000000000; data_table[60].feg[0].cnl[3] = 16.2900000000; data_table[60].feg[0].cl[4] = 0.2000000000; data_table[60].feg[0].cnl[4] = 16.7300000000; data_table[60].feg[0].cl[5] = 0.2000000000; data_table[60].feg[0].cnl[5] = 127.9000000000; + data_table[61].feg[0].cl[0] = 0.2000000000; data_table[61].feg[0].cnl[0] = 0.0906000000; data_table[61].feg[0].cl[1] = 0.2000000000; data_table[61].feg[0].cnl[1] = 1.5930000000; data_table[61].feg[0].cl[2] = 0.2000000000; data_table[61].feg[0].cnl[2] = 10.6400000000; data_table[61].feg[0].cl[3] = 0.2000000000; data_table[61].feg[0].cnl[3] = 1.7890000000; data_table[61].feg[0].cl[4] = 0.2000000000; data_table[61].feg[0].cnl[4] = 2.2210000000; data_table[61].feg[0].cl[5] = 0.2000000000; data_table[61].feg[0].cnl[5] = 124.6000000000; + data_table[62].feg[0].cl[0] = 0.1000000000; data_table[62].feg[0].cnl[0] = 0.1049000000; data_table[62].feg[0].cl[1] = 0.1000000000; data_table[62].feg[0].cnl[1] = 1.5440000000; data_table[62].feg[0].cl[2] = 0.1000000000; data_table[62].feg[0].cnl[2] = 8.6520000000; data_table[62].feg[0].cl[3] = 0.1000000000; data_table[62].feg[0].cnl[3] = 7.0930000000; data_table[62].feg[0].cl[4] = 0.1000000000; data_table[62].feg[0].cnl[4] = 53.3700000000; data_table[62].feg[0].cl[5] = 0.1000000000; data_table[62].feg[0].cnl[5] = 183.7000000000; + data_table[63].feg[0].cl[0] = 0.2000000000; data_table[63].feg[0].cnl[0] = 0.0934000000; data_table[63].feg[0].cl[1] = 0.2000000000; data_table[63].feg[0].cnl[1] = 1.3870000000; data_table[63].feg[0].cl[2] = 0.2000000000; data_table[63].feg[0].cnl[2] = 7.3590000000; data_table[63].feg[0].cl[3] = 0.2000000000; data_table[63].feg[0].cnl[3] = 1.5510000000; data_table[63].feg[0].cl[4] = 0.2000000000; data_table[63].feg[0].cnl[4] = 20.8200000000; data_table[63].feg[0].cl[5] = 0.2000000000; data_table[63].feg[0].cnl[5] = 111.0000000000; + data_table[64].feg[0].cl[0] = 0.1000000000; data_table[64].feg[0].cnl[0] = 0.1019000000; data_table[64].feg[0].cl[1] = 0.1000000000; data_table[64].feg[0].cnl[1] = 1.5240000000; data_table[64].feg[0].cl[2] = 0.1000000000; data_table[64].feg[0].cnl[2] = 7.1690000000; data_table[64].feg[0].cl[3] = 0.1000000000; data_table[64].feg[0].cnl[3] = 20.8600000000; data_table[64].feg[0].cl[4] = 0.1000000000; data_table[64].feg[0].cnl[4] = 49.2900000000; data_table[64].feg[0].cl[5] = 0.1000000000; data_table[64].feg[0].cnl[5] = 166.1000000000; + data_table[65].feg[0].cl[0] = 0.2000000000; data_table[65].feg[0].cnl[0] = 0.0840000000; data_table[65].feg[0].cl[1] = 0.2000000000; data_table[65].feg[0].cnl[1] = 1.4090000000; data_table[65].feg[0].cl[2] = 0.2000000000; data_table[65].feg[0].cnl[2] = 7.1400000000; data_table[65].feg[0].cl[3] = 0.2000000000; data_table[65].feg[0].cnl[3] = 1.3480000000; data_table[65].feg[0].cl[4] = 0.2000000000; data_table[65].feg[0].cnl[4] = 11.4200000000; data_table[65].feg[0].cl[5] = 0.2000000000; data_table[65].feg[0].cnl[5] = 108.0000000000; + data_table[66].feg[0].cl[0] = 0.1000000000; data_table[66].feg[0].cnl[0] = 0.0944000000; data_table[66].feg[0].cl[1] = 0.1000000000; data_table[66].feg[0].cnl[1] = 1.6180000000; data_table[66].feg[0].cl[2] = 0.1000000000; data_table[66].feg[0].cnl[2] = 6.2710000000; data_table[66].feg[0].cl[3] = 0.1000000000; data_table[66].feg[0].cnl[3] = 40.3500000000; data_table[66].feg[0].cl[4] = 0.1000000000; data_table[66].feg[0].cnl[4] = 42.8300000000; data_table[66].feg[0].cl[5] = 0.1000000000; data_table[66].feg[0].cnl[5] = 130.6000000000; + data_table[67].feg[0].cl[0] = 0.2000000000; data_table[67].feg[0].cnl[0] = 0.0821000000; data_table[67].feg[0].cl[1] = 0.2000000000; data_table[67].feg[0].cnl[1] = 1.2510000000; data_table[67].feg[0].cl[2] = 0.2000000000; data_table[67].feg[0].cnl[2] = 4.8120000000; data_table[67].feg[0].cl[3] = 0.2000000000; data_table[67].feg[0].cnl[3] = 10.8400000000; data_table[67].feg[0].cl[4] = 0.2000000000; data_table[67].feg[0].cnl[4] = 10.9000000000; data_table[67].feg[0].cl[5] = 0.2000000000; data_table[67].feg[0].cnl[5] = 100.1000000000; + data_table[68].feg[0].cl[0] = 0.1000000000; data_table[68].feg[0].cnl[0] = 0.0966000000; data_table[68].feg[0].cl[1] = 0.1000000000; data_table[68].feg[0].cnl[1] = 1.6020000000; data_table[68].feg[0].cl[2] = 0.1000000000; data_table[68].feg[0].cnl[2] = 5.6750000000; data_table[68].feg[0].cl[3] = 0.1000000000; data_table[68].feg[0].cnl[3] = 30.5900000000; data_table[68].feg[0].cl[4] = 0.1000000000; data_table[68].feg[0].cnl[4] = 31.1300000000; data_table[68].feg[0].cl[5] = 0.1000000000; data_table[68].feg[0].cnl[5] = 138.7000000000; + data_table[69].feg[0].cl[0] = 0.1000000000; data_table[69].feg[0].cnl[0] = 0.0949000000; data_table[69].feg[0].cl[1] = 0.1000000000; data_table[69].feg[0].cnl[1] = 1.6020000000; data_table[69].feg[0].cl[2] = 0.1000000000; data_table[69].feg[0].cnl[2] = 5.4390000000; data_table[69].feg[0].cl[3] = 0.1000000000; data_table[69].feg[0].cnl[3] = 28.3100000000; data_table[69].feg[0].cl[4] = 0.1000000000; data_table[69].feg[0].cnl[4] = 29.2800000000; data_table[69].feg[0].cl[5] = 0.1000000000; data_table[69].feg[0].cnl[5] = 138.1000000000; + data_table[70].feg[0].cl[0] = 0.1000000000; data_table[70].feg[0].cnl[0] = 0.0966000000; data_table[70].feg[0].cl[1] = 0.1000000000; data_table[70].feg[0].cnl[1] = 1.5680000000; data_table[70].feg[0].cl[2] = 0.1000000000; data_table[70].feg[0].cnl[2] = 5.3220000000; data_table[70].feg[0].cl[3] = 0.1000000000; data_table[70].feg[0].cnl[3] = 34.1800000000; data_table[70].feg[0].cl[4] = 0.1000000000; data_table[70].feg[0].cnl[4] = 35.2500000000; data_table[70].feg[0].cl[5] = 0.1000000000; data_table[70].feg[0].cnl[5] = 121.4000000000; + data_table[71].feg[0].cl[0] = 0.1000000000; data_table[71].feg[0].cnl[0] = 0.0929000000; data_table[71].feg[0].cl[1] = 0.1000000000; data_table[71].feg[0].cnl[1] = 1.5550000000; data_table[71].feg[0].cl[2] = 0.1000000000; data_table[71].feg[0].cnl[2] = 5.2510000000; data_table[71].feg[0].cl[3] = 0.1000000000; data_table[71].feg[0].cnl[3] = 37.5200000000; data_table[71].feg[0].cl[4] = 0.1000000000; data_table[71].feg[0].cnl[4] = 38.8800000000; data_table[71].feg[0].cl[5] = 0.1000000000; data_table[71].feg[0].cnl[5] = 105.2000000000; + data_table[72].feg[0].cl[0] = 0.4000000000; data_table[72].feg[0].cnl[0] = 0.0630000000; data_table[72].feg[0].cl[1] = 0.4000000000; data_table[72].feg[0].cnl[1] = 0.8195000000; data_table[72].feg[0].cl[2] = 0.4000000000; data_table[72].feg[0].cnl[2] = 2.8910000000; data_table[72].feg[0].cl[3] = 0.4000000000; data_table[72].feg[0].cnl[3] = 5.5430000000; data_table[72].feg[0].cl[4] = 0.4000000000; data_table[72].feg[0].cnl[4] = 5.9810000000; data_table[72].feg[0].cl[5] = 0.4000000000; data_table[72].feg[0].cnl[5] = 54.4200000000; + data_table[73].feg[0].cl[0] = 0.2000000000; data_table[73].feg[0].cnl[0] = 0.0790000000; data_table[73].feg[0].cl[1] = 0.2000000000; data_table[73].feg[0].cnl[1] = 1.3710000000; data_table[73].feg[0].cl[2] = 0.2000000000; data_table[73].feg[0].cnl[2] = 8.2340000000; data_table[73].feg[0].cl[3] = 0.2000000000; data_table[73].feg[0].cnl[3] = 1.3830000000; data_table[73].feg[0].cl[4] = 0.2000000000; data_table[73].feg[0].cnl[4] = 1.3920000000; data_table[73].feg[0].cl[5] = 0.2000000000; data_table[73].feg[0].cnl[5] = 77.1200000000; + data_table[74].feg[0].cl[0] = 0.5000000000; data_table[74].feg[0].cnl[0] = 0.0527000000; data_table[74].feg[0].cl[1] = 0.5000000000; data_table[74].feg[0].cnl[1] = 0.9072000000; data_table[74].feg[0].cl[2] = 0.5000000000; data_table[74].feg[0].cnl[2] = 4.4380000000; data_table[74].feg[0].cl[3] = 0.5000000000; data_table[74].feg[0].cnl[3] = 0.9459000000; data_table[74].feg[0].cl[4] = 0.5000000000; data_table[74].feg[0].cnl[4] = 4.3750000000; data_table[74].feg[0].cl[5] = 0.5000000000; data_table[74].feg[0].cnl[5] = 43.9800000000; + data_table[75].feg[0].cl[0] = 0.4000000000; data_table[75].feg[0].cnl[0] = 0.2270000000; data_table[75].feg[0].cl[1] = 0.4000000000; data_table[75].feg[0].cnl[1] = 1.5700000000; data_table[75].feg[0].cl[2] = 0.4000000000; data_table[75].feg[0].cnl[2] = 6.3450000000; data_table[75].feg[0].cl[3] = 0.4000000000; data_table[75].feg[0].cnl[3] = 0.0156000000; data_table[75].feg[0].cl[4] = 0.4000000000; data_table[75].feg[0].cnl[4] = 1.6180000000; data_table[75].feg[0].cl[5] = 0.4000000000; data_table[75].feg[0].cnl[5] = 46.1600000000; + data_table[76].feg[0].cl[0] = 0.5000000000; data_table[76].feg[0].cnl[0] = 0.0506000000; data_table[76].feg[0].cl[1] = 0.5000000000; data_table[76].feg[0].cnl[1] = 0.8677000000; data_table[76].feg[0].cl[2] = 0.5000000000; data_table[76].feg[0].cnl[2] = 5.0930000000; data_table[76].feg[0].cl[3] = 0.5000000000; data_table[76].feg[0].cnl[3] = 0.8812000000; data_table[76].feg[0].cl[4] = 0.5000000000; data_table[76].feg[0].cnl[4] = 3.5690000000; data_table[76].feg[0].cl[5] = 0.5000000000; data_table[76].feg[0].cnl[5] = 39.7700000000; + data_table[77].feg[0].cl[0] = 0.5000000000; data_table[77].feg[0].cnl[0] = 0.0525000000; data_table[77].feg[0].cl[1] = 0.5000000000; data_table[77].feg[0].cnl[1] = 0.8377000000; data_table[77].feg[0].cl[2] = 0.5000000000; data_table[77].feg[0].cnl[2] = 3.9590000000; data_table[77].feg[0].cl[3] = 0.5000000000; data_table[77].feg[0].cnl[3] = 0.8152000000; data_table[77].feg[0].cl[4] = 0.5000000000; data_table[77].feg[0].cnl[4] = 6.4420000000; data_table[77].feg[0].cl[5] = 0.5000000000; data_table[77].feg[0].cnl[5] = 34.2100000000; + data_table[78].feg[0].cl[0] = 0.4000000000; data_table[78].feg[0].cnl[0] = 0.5493000000; data_table[78].feg[0].cl[1] = 0.4000000000; data_table[78].feg[0].cnl[1] = 1.7280000000; data_table[78].feg[0].cl[2] = 0.4000000000; data_table[78].feg[0].cnl[2] = 6.7200000000; data_table[78].feg[0].cl[3] = 0.4000000000; data_table[78].feg[0].cnl[3] = 0.0264000000; data_table[78].feg[0].cl[4] = 0.4000000000; data_table[78].feg[0].cnl[4] = 0.0725000000; data_table[78].feg[0].cl[5] = 0.4000000000; data_table[78].feg[0].cnl[5] = 35.4600000000; + data_table[79].feg[0].cl[0] = 0.4000000000; data_table[79].feg[0].cnl[0] = 0.2194000000; data_table[79].feg[0].cl[1] = 0.4000000000; data_table[79].feg[0].cnl[1] = 1.4160000000; data_table[79].feg[0].cl[2] = 0.4000000000; data_table[79].feg[0].cnl[2] = 6.6820000000; data_table[79].feg[0].cl[3] = 0.4000000000; data_table[79].feg[0].cnl[3] = 0.0147000000; data_table[79].feg[0].cl[4] = 0.4000000000; data_table[79].feg[0].cnl[4] = 1.5760000000; data_table[79].feg[0].cl[5] = 0.4000000000; data_table[79].feg[0].cnl[5] = 37.1600000000; + data_table[80].feg[0].cl[0] = 0.4000000000; data_table[80].feg[0].cnl[0] = 0.2246000000; data_table[80].feg[0].cl[1] = 0.4000000000; data_table[80].feg[0].cnl[1] = 1.1280000000; data_table[80].feg[0].cl[2] = 0.4000000000; data_table[80].feg[0].cnl[2] = 4.3030000000; data_table[80].feg[0].cl[3] = 0.4000000000; data_table[80].feg[0].cnl[3] = 0.0149000000; data_table[80].feg[0].cl[4] = 0.4000000000; data_table[80].feg[0].cnl[4] = 7.1560000000; data_table[80].feg[0].cl[5] = 0.4000000000; data_table[80].feg[0].cnl[5] = 43.0900000000; + data_table[81].feg[0].cl[0] = 0.3000000000; data_table[81].feg[0].cnl[0] = 0.0643000000; data_table[81].feg[0].cl[1] = 0.3000000000; data_table[81].feg[0].cnl[1] = 1.1940000000; data_table[81].feg[0].cl[2] = 0.3000000000; data_table[81].feg[0].cnl[2] = 7.3930000000; data_table[81].feg[0].cl[3] = 0.3000000000; data_table[81].feg[0].cnl[3] = 1.1420000000; data_table[81].feg[0].cl[4] = 0.3000000000; data_table[81].feg[0].cnl[4] = 1.2890000000; data_table[81].feg[0].cl[5] = 0.3000000000; data_table[81].feg[0].cnl[5] = 51.1300000000; + data_table[82].feg[0].cl[0] = 0.4000000000; data_table[82].feg[0].cnl[0] = 0.0538000000; data_table[82].feg[0].cl[1] = 0.4000000000; data_table[82].feg[0].cnl[1] = 0.8672000000; data_table[82].feg[0].cl[2] = 0.4000000000; data_table[82].feg[0].cnl[2] = 1.8750000000; data_table[82].feg[0].cl[3] = 0.4000000000; data_table[82].feg[0].cnl[3] = 7.6480000000; data_table[82].feg[0].cl[4] = 0.4000000000; data_table[82].feg[0].cnl[4] = 7.8680000000; data_table[82].feg[0].cl[5] = 0.4000000000; data_table[82].feg[0].cnl[5] = 45.6400000000; + data_table[83].feg[0].cl[0] = 0.4000000000; data_table[83].feg[0].cnl[0] = 0.5011000000; data_table[83].feg[0].cl[1] = 0.4000000000; data_table[83].feg[0].cnl[1] = 1.6380000000; data_table[83].feg[0].cl[2] = 0.4000000000; data_table[83].feg[0].cnl[2] = 6.7860000000; data_table[83].feg[0].cl[3] = 0.4000000000; data_table[83].feg[0].cnl[3] = 0.0219000000; data_table[83].feg[0].cl[4] = 0.4000000000; data_table[83].feg[0].cnl[4] = 0.0860000000; data_table[83].feg[0].cl[5] = 0.4000000000; data_table[83].feg[0].cnl[5] = 46.7300000000; + data_table[84].feg[0].cl[0] = 0.4000000000; data_table[84].feg[0].cnl[0] = 0.2232000000; data_table[84].feg[0].cl[1] = 0.4000000000; data_table[84].feg[0].cnl[1] = 1.1080000000; data_table[84].feg[0].cl[2] = 0.4000000000; data_table[84].feg[0].cnl[2] = 3.5910000000; data_table[84].feg[0].cl[3] = 0.4000000000; data_table[84].feg[0].cnl[3] = 0.0101000000; data_table[84].feg[0].cl[4] = 0.4000000000; data_table[84].feg[0].cnl[4] = 11.6400000000; data_table[84].feg[0].cl[5] = 0.4000000000; data_table[84].feg[0].cnl[5] = 45.0700000000; + data_table[85].feg[0].cl[0] = 0.4000000000; data_table[85].feg[0].cnl[0] = 0.2115000000; data_table[85].feg[0].cl[1] = 0.4000000000; data_table[85].feg[0].cnl[1] = 1.1400000000; data_table[85].feg[0].cl[2] = 0.4000000000; data_table[85].feg[0].cnl[2] = 3.4150000000; data_table[85].feg[0].cl[3] = 0.4000000000; data_table[85].feg[0].cnl[3] = 0.0119000000; data_table[85].feg[0].cl[4] = 0.4000000000; data_table[85].feg[0].cnl[4] = 13.4100000000; data_table[85].feg[0].cl[5] = 0.4000000000; data_table[85].feg[0].cnl[5] = 43.1100000000; + data_table[86].feg[0].cl[0] = 0.1000000000; data_table[86].feg[0].cnl[0] = 0.0944000000; data_table[86].feg[0].cl[1] = 0.1000000000; data_table[86].feg[0].cnl[1] = 1.0260000000; data_table[86].feg[0].cl[2] = 0.1000000000; data_table[86].feg[0].cnl[2] = 6.2550000000; data_table[86].feg[0].cl[3] = 0.1000000000; data_table[86].feg[0].cnl[3] = 32.5100000000; data_table[86].feg[0].cl[4] = 0.1000000000; data_table[86].feg[0].cnl[4] = 36.2900000000; data_table[86].feg[0].cl[5] = 0.1000000000; data_table[86].feg[0].cnl[5] = 149.1000000000; + data_table[87].feg[0].cl[0] = 0.2000000000; data_table[87].feg[0].cnl[0] = 0.0730000000; data_table[87].feg[0].cl[1] = 0.2000000000; data_table[87].feg[0].cnl[1] = 1.0180000000; data_table[87].feg[0].cl[2] = 0.2000000000; data_table[87].feg[0].cnl[2] = 5.8960000000; data_table[87].feg[0].cl[3] = 0.2000000000; data_table[87].feg[0].cnl[3] = 1.0310000000; data_table[87].feg[0].cl[4] = 0.2000000000; data_table[87].feg[0].cnl[4] = 20.3700000000; data_table[87].feg[0].cl[5] = 0.2000000000; data_table[87].feg[0].cnl[5] = 115.3000000000; + data_table[88].feg[0].cl[0] = 0.2000000000; data_table[88].feg[0].cnl[0] = 0.0752000000; data_table[88].feg[0].cl[1] = 0.2000000000; data_table[88].feg[0].cnl[1] = 0.9494000000; data_table[88].feg[0].cl[2] = 0.2000000000; data_table[88].feg[0].cnl[2] = 3.7250000000; data_table[88].feg[0].cl[3] = 0.2000000000; data_table[88].feg[0].cnl[3] = 17.5800000000; data_table[88].feg[0].cl[4] = 0.2000000000; data_table[88].feg[0].cnl[4] = 19.7500000000; data_table[88].feg[0].cl[5] = 0.2000000000; data_table[88].feg[0].cnl[5] = 109.1000000000; + data_table[89].feg[0].cl[0] = 0.3000000000; data_table[89].feg[0].cnl[0] = 0.0639000000; data_table[89].feg[0].cl[1] = 0.3000000000; data_table[89].feg[0].cnl[1] = 0.9019000000; data_table[89].feg[0].cl[2] = 0.3000000000; data_table[89].feg[0].cnl[2] = 4.6570000000; data_table[89].feg[0].cl[3] = 0.3000000000; data_table[89].feg[0].cnl[3] = 0.9025000000; data_table[89].feg[0].cl[4] = 0.3000000000; data_table[89].feg[0].cnl[4] = 15.7100000000; data_table[89].feg[0].cl[5] = 0.3000000000; data_table[89].feg[0].cnl[5] = 83.7000000000; + data_table[90].feg[0].cl[0] = 0.2000000000; data_table[90].feg[0].cnl[0] = 0.0756000000; data_table[90].feg[0].cl[1] = 0.2000000000; data_table[90].feg[0].cnl[1] = 0.8492000000; data_table[90].feg[0].cl[2] = 0.2000000000; data_table[90].feg[0].cnl[2] = 4.0100000000; data_table[90].feg[0].cl[3] = 0.2000000000; data_table[90].feg[0].cnl[3] = 16.9500000000; data_table[90].feg[0].cl[4] = 0.2000000000; data_table[90].feg[0].cnl[4] = 17.7900000000; data_table[90].feg[0].cl[5] = 0.2000000000; data_table[90].feg[0].cnl[5] = 100.2000000000; + data_table[91].feg[0].cl[0] = 0.2000000000; data_table[91].feg[0].cnl[0] = 0.0714000000; data_table[91].feg[0].cl[1] = 0.2000000000; data_table[91].feg[0].cnl[1] = 1.1490000000; data_table[91].feg[0].cl[2] = 0.2000000000; data_table[91].feg[0].cnl[2] = 9.2120000000; data_table[91].feg[0].cl[3] = 0.2000000000; data_table[91].feg[0].cnl[3] = 0.9592000000; data_table[91].feg[0].cl[4] = 0.2000000000; data_table[91].feg[0].cnl[4] = 1.2030000000; data_table[91].feg[0].cl[5] = 0.2000000000; data_table[91].feg[0].cnl[5] = 104.3000000000; + data_table[92].feg[0].cl[0] = 0.2000000000; data_table[92].feg[0].cnl[0] = 0.0692000000; data_table[92].feg[0].cl[1] = 0.2000000000; data_table[92].feg[0].cnl[1] = 0.9810000000; data_table[92].feg[0].cl[2] = 0.2000000000; data_table[92].feg[0].cnl[2] = 5.9540000000; data_table[92].feg[0].cl[3] = 0.2000000000; data_table[92].feg[0].cnl[3] = 0.9909000000; data_table[92].feg[0].cl[4] = 0.2000000000; data_table[92].feg[0].cnl[4] = 22.0600000000; data_table[92].feg[0].cl[5] = 0.2000000000; data_table[92].feg[0].cnl[5] = 90.9800000000; + data_table[93].feg[0].cl[0] = 0.2000000000; data_table[93].feg[0].cnl[0] = 0.0714000000; data_table[93].feg[0].cl[1] = 0.2000000000; data_table[93].feg[0].cnl[1] = 0.9577000000; data_table[93].feg[0].cl[2] = 0.2000000000; data_table[93].feg[0].cnl[2] = 6.1320000000; data_table[93].feg[0].cl[3] = 0.2000000000; data_table[93].feg[0].cnl[3] = 0.9744000000; data_table[93].feg[0].cl[4] = 0.2000000000; data_table[93].feg[0].cnl[4] = 15.6700000000; data_table[93].feg[0].cl[5] = 0.2000000000; data_table[93].feg[0].cnl[5] = 89.8700000000; + data_table[94].feg[0].cl[0] = 0.2000000000; data_table[94].feg[0].cnl[0] = 0.0730000000; data_table[94].feg[0].cl[1] = 0.2000000000; data_table[94].feg[0].cnl[1] = 0.9327000000; data_table[94].feg[0].cl[2] = 0.2000000000; data_table[94].feg[0].cnl[2] = 6.3480000000; data_table[94].feg[0].cl[3] = 0.2000000000; data_table[94].feg[0].cnl[3] = 0.9103000000; data_table[94].feg[0].cl[4] = 0.2000000000; data_table[94].feg[0].cnl[4] = 13.2600000000; data_table[94].feg[0].cl[5] = 0.2000000000; data_table[94].feg[0].cnl[5] = 86.8600000000; + data_table[95].feg[0].cl[0] = 0.3000000000; data_table[95].feg[0].cnl[0] = 0.0578000000; data_table[95].feg[0].cl[1] = 0.3000000000; data_table[95].feg[0].cnl[1] = 0.7227000000; data_table[95].feg[0].cl[2] = 0.3000000000; data_table[95].feg[0].cnl[2] = 3.0110000000; data_table[95].feg[0].cl[3] = 0.3000000000; data_table[95].feg[0].cnl[3] = 9.2190000000; data_table[95].feg[0].cl[4] = 0.3000000000; data_table[95].feg[0].cnl[4] = 9.5340000000; data_table[95].feg[0].cl[5] = 0.3000000000; data_table[95].feg[0].cnl[5] = 65.8700000000; + data_table[96].feg[0].cl[0] = 0.2000000000; data_table[96].feg[0].cnl[0] = 0.0709000000; data_table[96].feg[0].cl[1] = 0.2000000000; data_table[96].feg[0].cnl[1] = 0.7759000000; data_table[96].feg[0].cl[2] = 0.2000000000; data_table[96].feg[0].cnl[2] = 6.1430000000; data_table[96].feg[0].cl[3] = 0.2000000000; data_table[96].feg[0].cnl[3] = 1.7900000000; data_table[96].feg[0].cl[4] = 0.2000000000; data_table[96].feg[0].cnl[4] = 15.1200000000; data_table[96].feg[0].cl[5] = 0.2000000000; data_table[96].feg[0].cnl[5] = 83.5700000000; + data_table[97].feg[0].cl[0] = 0.3000000000; data_table[97].feg[0].cnl[0] = 0.0616000000; data_table[97].feg[0].cl[1] = 0.3000000000; data_table[97].feg[0].cnl[1] = 0.8136000000; data_table[97].feg[0].cl[2] = 0.3000000000; data_table[97].feg[0].cnl[2] = 6.5620000000; data_table[97].feg[0].cl[3] = 0.3000000000; data_table[97].feg[0].cnl[3] = 0.8381000000; data_table[97].feg[0].cl[4] = 0.3000000000; data_table[97].feg[0].cnl[4] = 4.1890000000; data_table[97].feg[0].cl[5] = 0.3000000000; data_table[97].feg[0].cnl[5] = 61.4100000000; + data_table[98].feg[0].cl[0] = 0.0000000000; data_table[98].feg[0].cnl[0] = 0.0000000000; data_table[98].feg[0].cl[1] = 0.0000000000; data_table[98].feg[0].cnl[1] = 0.0000000000; data_table[98].feg[0].cl[2] = 0.0000000000; data_table[98].feg[0].cnl[2] = 0.0000000000; data_table[98].feg[0].cl[3] = 0.0000000000; data_table[98].feg[0].cnl[3] = 0.0000000000; data_table[98].feg[0].cl[4] = 0.0000000000; data_table[98].feg[0].cnl[4] = 0.0000000000; data_table[98].feg[0].cl[5] = 0.0000000000; data_table[98].feg[0].cnl[5] = 0.0000000000; + data_table[99].feg[0].cl[0] = 0.0000000000; data_table[99].feg[0].cnl[0] = 0.0000000000; data_table[99].feg[0].cl[1] = 0.0000000000; data_table[99].feg[0].cnl[1] = 0.0000000000; data_table[99].feg[0].cl[2] = 0.0000000000; data_table[99].feg[0].cnl[2] = 0.0000000000; data_table[99].feg[0].cl[3] = 0.0000000000; data_table[99].feg[0].cnl[3] = 0.0000000000; data_table[99].feg[0].cl[4] = 0.0000000000; data_table[99].feg[0].cnl[4] = 0.0000000000; data_table[99].feg[0].cl[5] = 0.0000000000; data_table[99].feg[0].cnl[5] = 0.0000000000; + data_table[100].feg[0].cl[0] = 0.0000000000; data_table[100].feg[0].cnl[0] = 0.0000000000; data_table[100].feg[0].cl[1] = 0.0000000000; data_table[100].feg[0].cnl[1] = 0.0000000000; data_table[100].feg[0].cl[2] = 0.0000000000; data_table[100].feg[0].cnl[2] = 0.0000000000; data_table[100].feg[0].cl[3] = 0.0000000000; data_table[100].feg[0].cnl[3] = 0.0000000000; data_table[100].feg[0].cl[4] = 0.0000000000; data_table[100].feg[0].cnl[4] = 0.0000000000; data_table[100].feg[0].cl[5] = 0.0000000000; data_table[100].feg[0].cnl[5] = 0.0000000000; + data_table[101].feg[0].cl[0] = 0.0000000000; data_table[101].feg[0].cnl[0] = 0.0000000000; data_table[101].feg[0].cl[1] = 0.0000000000; data_table[101].feg[0].cnl[1] = 0.0000000000; data_table[101].feg[0].cl[2] = 0.0000000000; data_table[101].feg[0].cnl[2] = 0.0000000000; data_table[101].feg[0].cl[3] = 0.0000000000; data_table[101].feg[0].cnl[3] = 0.0000000000; data_table[101].feg[0].cl[4] = 0.0000000000; data_table[101].feg[0].cnl[4] = 0.0000000000; data_table[101].feg[0].cl[5] = 0.0000000000; data_table[101].feg[0].cnl[5] = 0.0000000000; + data_table[102].feg[0].cl[0] = 0.0000000000; data_table[102].feg[0].cnl[0] = 0.0000000000; data_table[102].feg[0].cl[1] = 0.0000000000; data_table[102].feg[0].cnl[1] = 0.0000000000; data_table[102].feg[0].cl[2] = 0.0000000000; data_table[102].feg[0].cnl[2] = 0.0000000000; data_table[102].feg[0].cl[3] = 0.0000000000; data_table[102].feg[0].cnl[3] = 0.0000000000; data_table[102].feg[0].cl[4] = 0.0000000000; data_table[102].feg[0].cnl[4] = 0.0000000000; data_table[102].feg[0].cl[5] = 0.0000000000; data_table[102].feg[0].cnl[5] = 0.0000000000; + } + + // 6: Lobato parameterization - Hydrogen functions - [0, 12] + void Load_feg_Lobato_neutral_0_12() + { + data_table[0].feg[0].cl[0] = 5.291772107783e-02; data_table[0].feg[0].cnl[0] = 2.763770717440e+00; data_table[0].feg[0].cl[1] = 5.291772107783e-02; data_table[0].feg[0].cnl[1] = 2.763770717440e+00; data_table[0].feg[0].cl[2] = 5.291772107783e-02; data_table[0].feg[0].cnl[2] = 2.763770717440e+00; data_table[0].feg[0].cl[3] = 5.291772107783e-02; data_table[0].feg[0].cnl[3] = 2.763770717440e+00; data_table[0].feg[0].cl[4] = 5.291772107783e-02; data_table[0].feg[0].cnl[4] = 2.763770717440e+00; data_table[0].feg[0].cl[5] = 0.000000000000e+00; data_table[0].feg[0].cnl[5] = 0.000000000000e+00; + data_table[1].feg[0].cl[0] = -6.598207946998e-04; data_table[1].feg[0].cnl[0] = 2.332824832085e+01; data_table[1].feg[0].cl[1] = 7.117210312090e-04; data_table[1].feg[0].cnl[1] = 1.571138854405e+01; data_table[1].feg[0].cl[2] = 8.652912786985e-02; data_table[1].feg[0].cnl[2] = 1.536482140133e+00; data_table[1].feg[0].cl[3] = 1.085231255103e-01; data_table[1].feg[0].cnl[3] = 1.049132750140e+00; data_table[1].feg[0].cl[4] = 1.389584638334e-02; data_table[1].feg[0].cnl[4] = 4.384227214906e-01; data_table[1].feg[0].cl[5] = 0.000000000000e+00; data_table[1].feg[0].cnl[5] = 0.000000000000e+00; + data_table[2].feg[0].cl[0] = -1.807352999788e+00; data_table[2].feg[0].cnl[0] = 1.196169927876e+01; data_table[2].feg[0].cl[1] = 5.170205409177e+00; data_table[2].feg[0].cnl[1] = 9.967399064528e+00; data_table[2].feg[0].cl[2] = -1.805368014034e+00; data_table[2].feg[0].cnl[2] = 6.431382442020e+00; data_table[2].feg[0].cl[3] = 7.638651418607e-02; data_table[2].feg[0].cnl[3] = 4.870256721308e-01; data_table[2].feg[0].cl[4] = 9.179090459244e-03; data_table[2].feg[0].cnl[4] = 2.112236635855e-01; data_table[2].feg[0].cl[5] = 0.000000000000e+00; data_table[2].feg[0].cnl[5] = 0.000000000000e+00; + data_table[3].feg[0].cl[0] = -1.650011428450e+00; data_table[3].feg[0].cnl[0] = 6.318482962363e+00; data_table[3].feg[0].cl[1] = 3.478474844054e+00; data_table[3].feg[0].cnl[1] = 5.717983721704e+00; data_table[3].feg[0].cl[2] = -3.497450366516e-01; data_table[3].feg[0].cnl[2] = 1.983981533223e+00; data_table[3].feg[0].cl[3] = 4.327223808732e-02; data_table[3].feg[0].cnl[3] = 2.542383113232e-01; data_table[3].feg[0].cl[4] = 4.959382960071e-03; data_table[3].feg[0].cnl[4] = 1.185871494524e-01; data_table[3].feg[0].cl[5] = 0.000000000000e+00; data_table[3].feg[0].cnl[5] = 0.000000000000e+00; + data_table[4].feg[0].cl[0] = 5.434637970245e-01; data_table[4].feg[0].cnl[0] = 4.758725154049e+00; data_table[4].feg[0].cl[1] = 9.943375413498e-01; data_table[4].feg[0].cnl[1] = 3.094110637011e+00; data_table[4].feg[0].cl[2] = -1.720216827177e-01; data_table[4].feg[0].cnl[2] = 9.666945857142e-01; data_table[4].feg[0].cl[3] = 2.787953732690e-02; data_table[4].feg[0].cnl[3] = 1.615194613399e-01; data_table[4].feg[0].cl[4] = 3.840807016439e-03; data_table[4].feg[0].cnl[4] = 7.928114138632e-02; data_table[4].feg[0].cl[5] = 0.000000000000e+00; data_table[4].feg[0].cnl[5] = 0.000000000000e+00; + data_table[5].feg[0].cl[0] = 6.829736893745e-01; data_table[5].feg[0].cnl[0] = 3.491981604158e+00; data_table[5].feg[0].cl[1] = 6.632431043459e-01; data_table[5].feg[0].cnl[1] = 1.909779371044e+00; data_table[5].feg[0].cl[2] = -1.143538015536e-01; data_table[5].feg[0].cnl[2] = 5.828594428935e-01; data_table[5].feg[0].cl[3] = 1.931977587551e-02; data_table[5].feg[0].cnl[3] = 1.120906362608e-01; data_table[5].feg[0].cl[4] = 3.167231957656e-03; data_table[5].feg[0].cnl[4] = 5.719855269582e-02; data_table[5].feg[0].cl[5] = 0.000000000000e+00; data_table[5].feg[0].cnl[5] = 0.000000000000e+00; + data_table[6].feg[0].cl[0] = 5.790202573656e-01; data_table[6].feg[0].cnl[0] = 2.648609977381e+00; data_table[6].feg[0].cl[1] = 5.889614595690e-01; data_table[6].feg[0].cnl[1] = 1.399462066106e+00; data_table[6].feg[0].cl[2] = -7.683160617318e-02; data_table[6].feg[0].cnl[2] = 3.732092216804e-01; data_table[6].feg[0].cl[3] = 1.429711777913e-02; data_table[6].feg[0].cnl[3] = 8.530120762025e-02; data_table[6].feg[0].cl[4] = 3.052771459369e-03; data_table[6].feg[0].cnl[4] = 4.428086466707e-02; data_table[6].feg[0].cl[5] = 0.000000000000e+00; data_table[6].feg[0].cnl[5] = 0.000000000000e+00; + data_table[7].feg[0].cl[0] = 5.261125701136e-01; data_table[7].feg[0].cnl[0] = 2.079265351330e+00; data_table[7].feg[0].cl[1] = 5.109028911223e-01; data_table[7].feg[0].cnl[1] = 1.048129520181e+00; data_table[7].feg[0].cl[2] = -5.690179380942e-02; data_table[7].feg[0].cnl[2] = 2.577224704813e-01; data_table[7].feg[0].cl[3] = 1.109300661291e-02; data_table[7].feg[0].cnl[3] = 6.852979260850e-02; data_table[7].feg[0].cl[4] = 2.993325960599e-03; data_table[7].feg[0].cnl[4] = 3.549862030724e-02; data_table[7].feg[0].cl[5] = 0.000000000000e+00; data_table[7].feg[0].cnl[5] = 0.000000000000e+00; + data_table[8].feg[0].cl[0] = 4.788645038502e-01; data_table[8].feg[0].cnl[0] = 1.689889754866e+00; data_table[8].feg[0].cl[1] = 4.552695091260e-01; data_table[8].feg[0].cnl[1] = 8.163825921430e-01; data_table[8].feg[0].cl[2] = -4.417062832513e-02; data_table[8].feg[0].cnl[2] = 1.857630136333e-01; data_table[8].feg[0].cl[3] = 9.091563254928e-03; data_table[8].feg[0].cnl[3] = 5.773344563066e-02; data_table[8].feg[0].cl[4] = 2.945052093955e-03; data_table[8].feg[0].cnl[4] = 2.919381111144e-02; data_table[8].feg[0].cl[5] = 0.000000000000e+00; data_table[8].feg[0].cnl[5] = 0.000000000000e+00; + data_table[9].feg[0].cl[0] = 4.360411450621e-01; data_table[9].feg[0].cnl[0] = 1.409227350817e+00; data_table[9].feg[0].cl[1] = 4.138599450963e-01; data_table[9].feg[0].cnl[1] = 6.580470753006e-01; data_table[9].feg[0].cl[2] = -3.647792823568e-02; data_table[9].feg[0].cnl[2] = 1.318704770671e-01; data_table[9].feg[0].cl[3] = 9.385476084002e-03; data_table[9].feg[0].cnl[3] = 5.548472514575e-02; data_table[9].feg[0].cl[4] = 3.141361993254e-03; data_table[9].feg[0].cnl[4] = 2.483849804973e-02; data_table[9].feg[0].cl[5] = 0.000000000000e+00; data_table[9].feg[0].cnl[5] = 0.000000000000e+00; + data_table[10].feg[0].cl[0] = 4.461007444237e+00; data_table[10].feg[0].cnl[0] = 9.707259027226e+00; data_table[10].feg[0].cl[1] = -2.619311289092e+00; data_table[10].feg[0].cnl[1] = 7.197666158078e+00; data_table[10].feg[0].cl[2] = 5.958033705019e-01; data_table[10].feg[0].cnl[2] = 5.674273314527e-01; data_table[10].feg[0].cl[3] = -5.609872877390e-02; data_table[10].feg[0].cnl[3] = 1.935729235170e-01; data_table[10].feg[0].cl[4] = 4.549203126519e-03; data_table[10].feg[0].cnl[4] = 2.306465741282e-02; data_table[10].feg[0].cl[5] = 0.000000000000e+00; data_table[10].feg[0].cnl[5] = 0.000000000000e+00; + data_table[11].feg[0].cl[0] = 5.056965905799e+00; data_table[11].feg[0].cnl[0] = 5.897923680253e+00; data_table[11].feg[0].cl[1] = -2.860536132251e+00; data_table[11].feg[0].cnl[1] = 4.241253213256e+00; data_table[11].feg[0].cl[2] = 5.146688476179e-01; data_table[11].feg[0].cnl[2] = 3.744706145656e-01; data_table[11].feg[0].cl[3] = -1.142624494895e-01; data_table[11].feg[0].cnl[3] = 1.873815955152e-01; data_table[11].feg[0].cl[4] = 3.913828324258e-03; data_table[11].feg[0].cnl[4] = 1.944751249106e-02; data_table[11].feg[0].cl[5] = 0.000000000000e+00; data_table[11].feg[0].cnl[5] = 0.000000000000e+00; + data_table[12].feg[0].cl[0] = 2.904786099285e+00; data_table[12].feg[0].cnl[0] = 6.508577332507e+00; data_table[12].feg[0].cl[1] = -3.032205903196e-01; data_table[12].feg[0].cnl[1] = 1.333702951222e+00; data_table[12].feg[0].cl[2] = 5.341791098085e-01; data_table[12].feg[0].cnl[2] = 2.712983831862e-01; data_table[12].feg[0].cl[3] = -1.961212742394e-01; data_table[12].feg[0].cnl[3] = 1.706568042018e-01; data_table[12].feg[0].cl[4] = 3.426655465978e-03; data_table[12].feg[0].cnl[4] = 1.664690826183e-02; data_table[12].feg[0].cl[5] = 0.000000000000e+00; data_table[12].feg[0].cnl[5] = 0.000000000000e+00; + data_table[13].feg[0].cl[0] = 2.921358442389e+00; data_table[13].feg[0].cnl[0] = 4.945980711274e+00; data_table[13].feg[0].cl[1] = -3.214280237771e-01; data_table[13].feg[0].cnl[1] = 8.870990766578e-01; data_table[13].feg[0].cl[2] = 8.474022627799e-01; data_table[13].feg[0].cnl[2] = 1.992810441512e-01; data_table[13].feg[0].cl[3] = -5.449947429152e-01; data_table[13].feg[0].cnl[3] = 1.627076453793e-01; data_table[13].feg[0].cl[4] = 3.012061523181e-03; data_table[13].feg[0].cnl[4] = 1.439769516961e-02; data_table[13].feg[0].cl[5] = 0.000000000000e+00; data_table[13].feg[0].cnl[5] = 0.000000000000e+00; + data_table[14].feg[0].cl[0] = 2.837426146223e+00; data_table[14].feg[0].cnl[0] = 3.707392522481e+00; data_table[14].feg[0].cl[1] = -3.796278147439e-01; data_table[14].feg[0].cnl[1] = 6.767395866138e-01; data_table[14].feg[0].cl[2] = 6.553422797629e-01; data_table[14].feg[0].cnl[2] = 1.729022763348e-01; data_table[14].feg[0].cl[3] = -3.685319057733e-01; data_table[14].feg[0].cnl[3] = 1.329388422237e-01; data_table[14].feg[0].cl[4] = 2.691294531031e-03; data_table[14].feg[0].cnl[4] = 1.260043764273e-02; data_table[14].feg[0].cl[5] = 0.000000000000e+00; data_table[14].feg[0].cnl[5] = 0.000000000000e+00; + data_table[15].feg[0].cl[0] = 2.707818764508e+00; data_table[15].feg[0].cnl[0] = 2.906651593454e+00; data_table[15].feg[0].cl[1] = -4.166315461511e-01; data_table[15].feg[0].cnl[1] = 5.058076208103e-01; data_table[15].feg[0].cl[2] = 5.146184680373e-01; data_table[15].feg[0].cnl[2] = 1.574007035130e-01; data_table[15].feg[0].cl[3] = -2.234290941523e-01; data_table[15].feg[0].cnl[3] = 1.082783542400e-01; data_table[15].feg[0].cl[4] = 2.423407758202e-03; data_table[15].feg[0].cnl[4] = 1.112442674484e-02; data_table[15].feg[0].cl[5] = 0.000000000000e+00; data_table[15].feg[0].cnl[5] = 0.000000000000e+00; + data_table[16].feg[0].cl[0] = 2.566021353326e+00; data_table[16].feg[0].cnl[0] = 2.353232106435e+00; data_table[16].feg[0].cl[1] = -4.785471011730e-01; data_table[16].feg[0].cnl[1] = 3.695843551991e-01; data_table[16].feg[0].cl[2] = 4.653976190005e-01; data_table[16].feg[0].cnl[2] = 1.534423865540e-01; data_table[16].feg[0].cl[3] = -1.235710412480e-01; data_table[16].feg[0].cnl[3] = 8.681952609634e-02; data_table[16].feg[0].cl[4] = 2.199170094442e-03; data_table[16].feg[0].cnl[4] = 9.899285961702e-03; data_table[16].feg[0].cl[5] = 0.000000000000e+00; data_table[16].feg[0].cnl[5] = 0.000000000000e+00; + data_table[17].feg[0].cl[0] = 2.425980796349e+00; data_table[17].feg[0].cnl[0] = 1.952990057609e+00; data_table[17].feg[0].cl[1] = -7.026177947527e-01; data_table[17].feg[0].cnl[1] = 2.603030874337e-01; data_table[17].feg[0].cl[2] = 6.444439386431e-01; data_table[17].feg[0].cnl[2] = 1.584358024881e-01; data_table[17].feg[0].cl[3] = -7.891602139406e-02; data_table[17].feg[0].cnl[3] = 7.085503793437e-02; data_table[17].feg[0].cl[4] = 2.009081154588e-03; data_table[17].feg[0].cnl[4] = 8.870405143324e-03; data_table[17].feg[0].cl[5] = 0.000000000000e+00; data_table[17].feg[0].cnl[5] = 0.000000000000e+00; + data_table[18].feg[0].cl[0] = 2.485912993737e+00; data_table[18].feg[0].cnl[0] = 2.450976850735e+01; data_table[18].feg[0].cl[1] = 1.914786560063e+00; data_table[18].feg[0].cnl[1] = 2.105731275399e+00; data_table[18].feg[0].cl[2] = 4.523257468324e+00; data_table[18].feg[0].cnl[2] = 5.545543558684e-02; data_table[18].feg[0].cl[3] = -4.454146252312e+00; data_table[18].feg[0].cnl[3] = 5.497591772299e-02; data_table[18].feg[0].cl[4] = 2.189230188528e-03; data_table[18].feg[0].cnl[4] = 8.338800175046e-03; data_table[18].feg[0].cl[5] = 0.000000000000e+00; data_table[18].feg[0].cnl[5] = 0.000000000000e+00; + data_table[19].feg[0].cl[0] = 3.438132731610e+00; data_table[19].feg[0].cnl[0] = 1.458451252935e+01; data_table[19].feg[0].cl[1] = 1.453864257573e+00; data_table[19].feg[0].cnl[1] = 1.658111628125e+00; data_table[19].feg[0].cl[2] = 2.231576982870e+00; data_table[19].feg[0].cnl[2] = 4.764165928423e-02; data_table[19].feg[0].cl[3] = -2.172417098642e+00; data_table[19].feg[0].cnl[3] = 4.690683153977e-02; data_table[19].feg[0].cl[4] = 2.093126590441e-03; data_table[19].feg[0].cnl[4] = 7.619449067265e-03; data_table[19].feg[0].cl[5] = 0.000000000000e+00; data_table[19].feg[0].cnl[5] = 0.000000000000e+00; + data_table[20].feg[0].cl[0] = 3.171483304275e+00; data_table[20].feg[0].cnl[0] = 1.248855957617e+01; data_table[20].feg[0].cl[1] = 1.416944704369e+00; data_table[20].feg[0].cnl[1] = 1.460547000906e+00; data_table[20].feg[0].cl[2] = 1.019963297752e+00; data_table[20].feg[0].cnl[2] = 4.046780130696e-02; data_table[20].feg[0].cl[3] = -9.705370495354e-01; data_table[20].feg[0].cnl[3] = 3.926957138514e-02; data_table[20].feg[0].cl[4] = 2.095743136919e-03; data_table[20].feg[0].cnl[4] = 7.062374073734e-03; data_table[20].feg[0].cl[5] = 0.000000000000e+00; data_table[20].feg[0].cnl[5] = 0.000000000000e+00; + data_table[21].feg[0].cl[0] = 2.912700023579e+00; data_table[21].feg[0].cnl[0] = 1.122040500589e+01; data_table[21].feg[0].cl[1] = 1.411312593605e+00; data_table[21].feg[0].cnl[1] = 1.315929465210e+00; data_table[21].feg[0].cl[2] = 4.435853205108e+00; data_table[21].feg[0].cnl[2] = 3.411607351590e-02; data_table[21].feg[0].cl[3] = -4.393975859431e+00; data_table[21].feg[0].cnl[3] = 3.391222953370e-02; data_table[21].feg[0].cl[4] = 2.110037131771e-03; data_table[21].feg[0].cnl[4] = 6.578039176085e-03; data_table[21].feg[0].cl[5] = 0.000000000000e+00; data_table[21].feg[0].cnl[5] = 0.000000000000e+00; + data_table[22].feg[0].cl[0] = 2.725200616254e+00; data_table[22].feg[0].cnl[0] = 9.922562133847e+00; data_table[22].feg[0].cl[1] = 1.360497319257e+00; data_table[22].feg[0].cnl[1] = 1.165272804360e+00; data_table[22].feg[0].cl[2] = 4.318014125581e-01; data_table[22].feg[0].cnl[2] = 3.003251626117e-02; data_table[22].feg[0].cl[3] = -3.962680689313e-01; data_table[22].feg[0].cnl[3] = 2.836667234559e-02; data_table[22].feg[0].cl[4] = 2.168720874813e-03; data_table[22].feg[0].cnl[4] = 6.171445378065e-03; data_table[22].feg[0].cl[5] = 0.000000000000e+00; data_table[22].feg[0].cnl[5] = 0.000000000000e+00; + data_table[23].feg[0].cl[0] = 1.890134056605e+00; data_table[23].feg[0].cnl[0] = 1.038543467671e+01; data_table[23].feg[0].cl[1] = 1.558721367614e+00; data_table[23].feg[0].cnl[1] = 1.140072547401e+00; data_table[23].feg[0].cl[2] = 1.325725835245e+00; data_table[23].feg[0].cnl[2] = 2.533206852666e-02; data_table[23].feg[0].cl[3] = -1.295383889297e+00; data_table[23].feg[0].cnl[3] = 2.492114616709e-02; data_table[23].feg[0].cl[4] = 2.302629798472e-03; data_table[23].feg[0].cnl[4] = 5.846747202574e-03; data_table[23].feg[0].cl[5] = 0.000000000000e+00; data_table[23].feg[0].cnl[5] = 0.000000000000e+00; + data_table[24].feg[0].cl[0] = 2.389454308099e+00; data_table[24].feg[0].cnl[0] = 8.679554632026e+00; data_table[24].feg[0].cl[1] = 1.318293216199e+00; data_table[24].feg[0].cnl[1] = 9.506916940910e-01; data_table[24].feg[0].cl[2] = 3.364468602187e-01; data_table[24].feg[0].cnl[2] = 2.225901004211e-02; data_table[24].feg[0].cl[3] = -3.109220810130e-01; data_table[24].feg[0].cnl[3] = 2.095729439190e-02; data_table[24].feg[0].cl[4] = 2.527696486204e-03; data_table[24].feg[0].cnl[4] = 5.588549400473e-03; data_table[24].feg[0].cl[5] = 0.000000000000e+00; data_table[24].feg[0].cnl[5] = 0.000000000000e+00; + data_table[25].feg[0].cl[0] = 2.281632151450e+00; data_table[25].feg[0].cnl[0] = 8.069378430777e+00; data_table[25].feg[0].cl[1] = 1.274104495231e+00; data_table[25].feg[0].cnl[1] = 8.545129353173e-01; data_table[25].feg[0].cl[2] = 1.651504241428e-01; data_table[25].feg[0].cnl[2] = 1.962009336643e-02; data_table[25].feg[0].cl[3] = -1.439119035401e-01; data_table[25].feg[0].cnl[3] = 1.745913585876e-02; data_table[25].feg[0].cl[4] = 2.924832674094e-03; data_table[25].feg[0].cnl[4] = 5.409434596089e-03; data_table[25].feg[0].cl[5] = 0.000000000000e+00; data_table[25].feg[0].cnl[5] = 0.000000000000e+00; + data_table[26].feg[0].cl[0] = 2.146415979962e+00; data_table[26].feg[0].cnl[0] = 7.625958741392e+00; data_table[26].feg[0].cl[1] = 1.257062759559e+00; data_table[26].feg[0].cnl[1] = 7.874141626337e-01; data_table[26].feg[0].cl[2] = 1.526263997700e-01; data_table[26].feg[0].cnl[2] = 1.701950713295e-02; data_table[26].feg[0].cl[3] = -1.348394567868e-01; data_table[26].feg[0].cnl[3] = 1.508741980835e-02; data_table[26].feg[0].cl[4] = 3.584317503198e-03; data_table[26].feg[0].cnl[4] = 5.299051717315e-03; data_table[26].feg[0].cl[5] = 0.000000000000e+00; data_table[26].feg[0].cnl[5] = 0.000000000000e+00; + data_table[27].feg[0].cl[0] = 2.034284901837e+00; data_table[27].feg[0].cnl[0] = 7.184258945837e+00; data_table[27].feg[0].cl[1] = 1.224448397173e+00; data_table[27].feg[0].cnl[1] = 7.169997923193e-01; data_table[27].feg[0].cl[2] = 1.856549262548e-01; data_table[27].feg[0].cnl[2] = 1.346454955189e-02; data_table[27].feg[0].cl[3] = -1.756998563211e-01; data_table[27].feg[0].cnl[3] = 1.209738462579e-02; data_table[27].feg[0].cl[4] = 8.261631316624e-03; data_table[27].feg[0].cnl[4] = 5.797487482153e-03; data_table[27].feg[0].cl[5] = 0.000000000000e+00; data_table[27].feg[0].cnl[5] = 0.000000000000e+00; + data_table[28].feg[0].cl[0] = 1.468530847248e+00; data_table[28].feg[0].cnl[0] = 7.133832365511e+00; data_table[28].feg[0].cl[1] = 1.303592647163e+00; data_table[28].feg[0].cnl[1] = 6.885880148197e-01; data_table[28].feg[0].cl[2] = 6.363376449150e-02; data_table[28].feg[0].cnl[2] = 1.340220935295e-02; data_table[28].feg[0].cl[3] = -5.626371565390e-02; data_table[28].feg[0].cnl[3] = 9.901498478554e-03; data_table[28].feg[0].cl[4] = 8.856456911193e-03; data_table[28].feg[0].cnl[4] = 5.495274889916e-03; data_table[28].feg[0].cl[5] = 0.000000000000e+00; data_table[28].feg[0].cnl[5] = 0.000000000000e+00; + data_table[29].feg[0].cl[0] = 2.141061171975e+00; data_table[29].feg[0].cnl[0] = 5.280402318068e+00; data_table[29].feg[0].cl[1] = 2.502164361704e+00; data_table[29].feg[0].cnl[1] = 2.564948614672e-01; data_table[29].feg[0].cl[2] = -3.319211861394e+00; data_table[29].feg[0].cnl[2] = 1.503836612572e-01; data_table[29].feg[0].cl[3] = 1.708852225253e+00; data_table[29].feg[0].cnl[3] = 1.166905416861e-01; data_table[29].feg[0].cl[4] = 3.841024618203e-04; data_table[29].feg[0].cnl[4] = 2.770069931941e-03; data_table[29].feg[0].cl[5] = 0.000000000000e+00; data_table[29].feg[0].cnl[5] = 0.000000000000e+00; + data_table[30].feg[0].cl[0] = 2.735134293380e+00; data_table[30].feg[0].cnl[0] = 5.920088010090e+00; data_table[30].feg[0].cl[1] = 2.455670364197e+00; data_table[30].feg[0].cnl[1] = 2.240734508902e-01; data_table[30].feg[0].cl[2] = -3.871722837838e+00; data_table[30].feg[0].cnl[2] = 1.334711195521e-01; data_table[30].feg[0].cl[3] = 2.230718492671e+00; data_table[30].feg[0].cnl[3] = 1.092475681770e-01; data_table[30].feg[0].cl[4] = 3.496875909339e-04; data_table[30].feg[0].cnl[4] = 2.579606101869e-03; data_table[30].feg[0].cl[5] = 0.000000000000e+00; data_table[30].feg[0].cnl[5] = 0.000000000000e+00; + data_table[31].feg[0].cl[0] = 2.998375774095e+00; data_table[31].feg[0].cnl[0] = 5.096437839056e+00; data_table[31].feg[0].cl[1] = 3.205420885137e+00; data_table[31].feg[0].cnl[1] = 1.763710635250e-01; data_table[31].feg[0].cl[2] = -4.058119990716e+00; data_table[31].feg[0].cnl[2] = 1.263537079937e-01; data_table[31].feg[0].cl[3] = 1.543218140035e+00; data_table[31].feg[0].cnl[3] = 9.473256565380e-02; data_table[31].feg[0].cl[4] = 3.051914119292e-04; data_table[31].feg[0].cnl[4] = 2.388763189692e-03; data_table[31].feg[0].cl[5] = 0.000000000000e+00; data_table[31].feg[0].cnl[5] = 0.000000000000e+00; + data_table[32].feg[0].cl[0] = 3.080056421378e+00; data_table[32].feg[0].cnl[0] = 4.256370135669e+00; data_table[32].feg[0].cl[1] = 3.134598461469e+00; data_table[32].feg[0].cnl[1] = 1.477140523971e-01; data_table[32].feg[0].cl[2] = -4.033699983384e+00; data_table[32].feg[0].cnl[2] = 1.095072556715e-01; data_table[32].feg[0].cl[3] = 1.485788494491e+00; data_table[32].feg[0].cnl[3] = 8.285091395989e-02; data_table[32].feg[0].cl[4] = 2.566060266361e-04; data_table[32].feg[0].cnl[4] = 2.200491757677e-03; data_table[32].feg[0].cl[5] = 0.000000000000e+00; data_table[32].feg[0].cnl[5] = 0.000000000000e+00; + data_table[33].feg[0].cl[0] = 3.102847302382e+00; data_table[33].feg[0].cnl[0] = 3.598564726720e+00; data_table[33].feg[0].cl[1] = 2.731174524981e+00; data_table[33].feg[0].cnl[1] = 1.304319816954e-01; data_table[33].feg[0].cl[2] = -3.969954988844e+00; data_table[33].feg[0].cnl[2] = 9.562394636736e-02; data_table[33].feg[0].cl[3] = 1.744746317329e+00; data_table[33].feg[0].cnl[3] = 7.634068756810e-02; data_table[33].feg[0].cl[4] = 2.368441575458e-04; data_table[33].feg[0].cnl[4] = 2.061887907813e-03; data_table[33].feg[0].cl[5] = 0.000000000000e+00; data_table[33].feg[0].cnl[5] = 0.000000000000e+00; + data_table[34].feg[0].cl[0] = 3.093497258129e+00; data_table[34].feg[0].cnl[0] = 3.099619218801e+00; data_table[34].feg[0].cl[1] = 2.774044983635e+00; data_table[34].feg[0].cnl[1] = 1.134061824866e-01; data_table[34].feg[0].cl[2] = -3.886354979745e+00; data_table[34].feg[0].cnl[2] = 8.663832349327e-02; data_table[34].feg[0].cl[3] = 1.551650463756e+00; data_table[34].feg[0].cnl[3] = 6.854036643005e-02; data_table[34].feg[0].cl[4] = 2.122742305052e-04; data_table[34].feg[0].cnl[4] = 1.924868113136e-03; data_table[34].feg[0].cl[5] = 0.000000000000e+00; data_table[34].feg[0].cnl[5] = 0.000000000000e+00; + data_table[35].feg[0].cl[0] = 3.062654111432e+00; data_table[35].feg[0].cnl[0] = 2.714305136714e+00; data_table[35].feg[0].cl[1] = 2.515541674380e+00; data_table[35].feg[0].cnl[1] = 1.010486891990e-01; data_table[35].feg[0].cl[2] = -3.794064947527e+00; data_table[35].feg[0].cnl[2] = 7.709842535612e-02; data_table[35].feg[0].cl[3] = 1.664827543148e+00; data_table[35].feg[0].cnl[3] = 6.275726417422e-02; data_table[35].feg[0].cl[4] = 1.916185682213e-04; data_table[35].feg[0].cnl[4] = 1.801289587459e-03; data_table[35].feg[0].cl[5] = 0.000000000000e+00; data_table[35].feg[0].cnl[5] = 0.000000000000e+00; + data_table[36].feg[0].cl[0] = 2.949983117627e+00; data_table[36].feg[0].cnl[0] = 2.364523241062e+01; data_table[36].feg[0].cl[1] = 2.368651437463e+00; data_table[36].feg[0].cnl[1] = 2.701688212118e+00; data_table[36].feg[0].cl[2] = 5.335572927259e-01; data_table[36].feg[0].cnl[2] = 2.793313835774e-01; data_table[36].feg[0].cl[3] = 9.176712247131e-03; data_table[36].feg[0].cnl[3] = 1.677304569876e-02; data_table[36].feg[0].cl[4] = 1.314399374960e-04; data_table[36].feg[0].cnl[4] = 1.574925169829e-03; data_table[36].feg[0].cl[5] = 0.000000000000e+00; data_table[36].feg[0].cnl[5] = 0.000000000000e+00; + data_table[37].feg[0].cl[0] = 4.241235455816e+00; data_table[37].feg[0].cnl[0] = 1.463137021307e+01; data_table[37].feg[0].cl[1] = 1.763722032677e+00; data_table[37].feg[0].cnl[1] = 2.305659127808e+00; data_table[37].feg[0].cl[2] = 5.114496412019e-01; data_table[37].feg[0].cnl[2] = 2.599925904330e-01; data_table[37].feg[0].cl[3] = 7.991466200910e-03; data_table[37].feg[0].cnl[3] = 1.466884011485e-02; data_table[37].feg[0].cl[4] = 1.014041039043e-04; data_table[37].feg[0].cnl[4] = 1.425652862963e-03; data_table[37].feg[0].cl[5] = 0.000000000000e+00; data_table[37].feg[0].cnl[5] = 0.000000000000e+00; + data_table[38].feg[0].cl[0] = 4.079636669365e+00; data_table[38].feg[0].cnl[0] = 1.218118885705e+01; data_table[38].feg[0].cl[1] = 1.777184479237e+00; data_table[38].feg[0].cnl[1] = 2.102565053886e+00; data_table[38].feg[0].cl[2] = 4.543656690947e-01; data_table[38].feg[0].cnl[2] = 2.319005324732e-01; data_table[38].feg[0].cl[3] = 6.743834665502e-03; data_table[38].feg[0].cnl[3] = 1.251526301879e-02; data_table[38].feg[0].cl[4] = 6.934763743650e-05; data_table[38].feg[0].cnl[4] = 1.253327825451e-03; data_table[38].feg[0].cl[5] = 0.000000000000e+00; data_table[38].feg[0].cnl[5] = 0.000000000000e+00; + data_table[39].feg[0].cl[0] = 3.789155411093e+00; data_table[39].feg[0].cnl[0] = 1.062914522329e+01; data_table[39].feg[0].cl[1] = 1.881078927948e+00; data_table[39].feg[0].cnl[1] = 2.002795731783e+00; data_table[39].feg[0].cl[2] = 4.066830560072e-01; data_table[39].feg[0].cnl[2] = 2.068618651311e-01; data_table[39].feg[0].cl[3] = 5.548798977761e-03; data_table[39].feg[0].cnl[3] = 1.038524420132e-02; data_table[39].feg[0].cl[4] = 3.380597303298e-05; data_table[39].feg[0].cnl[4] = 1.011819041116e-03; data_table[39].feg[0].cl[5] = 0.000000000000e+00; data_table[39].feg[0].cnl[5] = 0.000000000000e+00; + data_table[40].feg[0].cl[0] = 2.382790675111e+00; data_table[40].feg[0].cnl[0] = 1.111594850662e+01; data_table[40].feg[0].cl[1] = 2.608977555943e+00; data_table[40].feg[0].cnl[1] = 2.161507307192e+00; data_table[40].feg[0].cl[2] = 3.591552704924e-01; data_table[40].feg[0].cnl[2] = 1.829839341140e-01; data_table[40].feg[0].cl[3] = 4.569470093002e-03; data_table[40].feg[0].cnl[3] = 8.620279012938e-03; data_table[40].feg[0].cl[4] = 7.028362363305e-06; data_table[40].feg[0].cnl[4] = 6.452970292696e-04; data_table[40].feg[0].cl[5] = 0.000000000000e+00; data_table[40].feg[0].cnl[5] = 0.000000000000e+00; + data_table[41].feg[0].cl[0] = 2.099137834016e+00; data_table[41].feg[0].cnl[0] = 1.048296346698e+01; data_table[41].feg[0].cl[1] = 2.711084186853e+00; data_table[41].feg[0].cnl[1] = 2.031770881549e+00; data_table[41].feg[0].cl[2] = 3.282749545510e-01; data_table[41].feg[0].cnl[2] = 1.689467957968e-01; data_table[41].feg[0].cl[3] = 4.481651577360e-03; data_table[41].feg[0].cnl[3] = 8.659102495325e-03; data_table[41].feg[0].cl[4] = 2.137300256622e-05; data_table[41].feg[0].cnl[4] = 8.337627704780e-04; data_table[41].feg[0].cl[5] = 0.000000000000e+00; data_table[41].feg[0].cnl[5] = 0.000000000000e+00; + data_table[42].feg[0].cl[0] = 2.798815288684e+00; data_table[42].feg[0].cnl[0] = 8.903325832353e+00; data_table[42].feg[0].cl[1] = 2.315495406054e+00; data_table[42].feg[0].cnl[1] = 1.711082703938e+00; data_table[42].feg[0].cl[2] = 2.936521854080e-01; data_table[42].feg[0].cnl[2] = 1.531304123154e-01; data_table[42].feg[0].cl[3] = 4.021506040290e-03; data_table[42].feg[0].cnl[3] = 7.881537158588e-03; data_table[42].feg[0].cl[4] = 1.561381502828e-05; data_table[42].feg[0].cnl[4] = 7.401731426112e-04; data_table[42].feg[0].cl[5] = 0.000000000000e+00; data_table[42].feg[0].cnl[5] = 0.000000000000e+00; + data_table[43].feg[0].cl[0] = 1.656901947905e+00; data_table[43].feg[0].cnl[0] = 1.006749257872e+01; data_table[43].feg[0].cl[1] = 2.852635279267e+00; data_table[43].feg[0].cnl[1] = 1.753516952634e+00; data_table[43].feg[0].cl[2] = 2.630882319889e-01; data_table[43].feg[0].cnl[2] = 1.375439434014e-01; data_table[43].feg[0].cl[3] = 3.370416530862e-03; data_table[43].feg[0].cnl[3] = 6.742520105449e-03; data_table[43].feg[0].cl[4] = 4.124308787469e-06; data_table[43].feg[0].cnl[4] = 4.966391629978e-04; data_table[43].feg[0].cl[5] = 0.000000000000e+00; data_table[43].feg[0].cnl[5] = 0.000000000000e+00; + data_table[44].feg[0].cl[0] = 1.512798019316e+00; data_table[44].feg[0].cnl[0] = 9.861891560811e+00; data_table[44].feg[0].cl[1] = 2.866258747437e+00; data_table[44].feg[0].cnl[1] = 1.620481252322e+00; data_table[44].feg[0].cl[2] = 2.360230128815e-01; data_table[44].feg[0].cnl[2] = 1.251051707293e-01; data_table[44].feg[0].cl[3] = 3.070220349223e-03; data_table[44].feg[0].cnl[3] = 6.149147255418e-03; data_table[44].feg[0].cl[4] = 1.681261436276e-11; data_table[44].feg[0].cnl[4] = 9.894226825917e-06; data_table[44].feg[0].cl[5] = 0.000000000000e+00; data_table[44].feg[0].cnl[5] = 0.000000000000e+00; + data_table[45].feg[0].cl[0] = 3.600390925658e+00; data_table[45].feg[0].cnl[0] = 1.777766900138e+00; data_table[45].feg[0].cl[1] = 8.296669152435e-01; data_table[45].feg[0].cnl[1] = 4.950259367891e-02; data_table[45].feg[0].cl[2] = -1.327398314213e+00; data_table[45].feg[0].cnl[2] = 3.411306721001e-02; data_table[45].feg[0].cl[3] = 6.888815505153e-01; data_table[45].feg[0].cnl[3] = 2.815437131522e-02; data_table[45].feg[0].cl[4] = 5.892279905207e-05; data_table[45].feg[0].cnl[4] = 9.472589692928e-04; data_table[45].feg[0].cl[5] = 0.000000000000e+00; data_table[45].feg[0].cnl[5] = 0.000000000000e+00; + data_table[46].feg[0].cl[0] = 1.291211451471e+00; data_table[46].feg[0].cnl[0] = 9.842479063423e+00; data_table[46].feg[0].cl[1] = 2.845585820493e+00; data_table[46].feg[0].cnl[1] = 1.392796371595e+00; data_table[46].feg[0].cl[2] = 1.958632497752e-01; data_table[46].feg[0].cnl[2] = 1.076507878835e-01; data_table[46].feg[0].cl[3] = 2.939478261842e-03; data_table[46].feg[0].cnl[3] = 5.811139417875e-03; data_table[46].feg[0].cl[4] = 1.258664135485e-13; data_table[46].feg[0].cnl[4] = 1.865576630908e-06; data_table[46].feg[0].cl[5] = 0.000000000000e+00; data_table[46].feg[0].cnl[5] = 0.000000000000e+00; + data_table[47].feg[0].cl[0] = 1.923829541399e+00; data_table[47].feg[0].cnl[0] = 7.658787390823e+00; data_table[47].feg[0].cl[1] = 2.504683119626e+00; data_table[47].feg[0].cnl[1] = 1.237028936471e+00; data_table[47].feg[0].cl[2] = 1.848673451713e-01; data_table[47].feg[0].cnl[2] = 1.023468840505e-01; data_table[47].feg[0].cl[3] = 2.919993742015e-03; data_table[47].feg[0].cnl[3] = 5.691700041708e-03; data_table[47].feg[0].cl[4] = 6.602194436147e-11; data_table[47].feg[0].cnl[4] = 1.429796481985e-05; data_table[47].feg[0].cl[5] = 0.000000000000e+00; data_table[47].feg[0].cnl[5] = 0.000000000000e+00; + data_table[48].feg[0].cl[0] = 2.767653130082e+00; data_table[48].feg[0].cnl[0] = 8.127770566981e+00; data_table[48].feg[0].cl[1] = 2.266504950572e+00; data_table[48].feg[0].cnl[1] = 1.112551099242e+00; data_table[48].feg[0].cl[2] = 1.749609922749e-01; data_table[48].feg[0].cnl[2] = 9.754388085710e-02; data_table[48].feg[0].cl[3] = 2.880927069060e-03; data_table[48].feg[0].cnl[3] = 5.544501860424e-03; data_table[48].feg[0].cl[4] = 2.245176184313e-14; data_table[48].feg[0].cnl[4] = 1.000000000000e-06; data_table[48].feg[0].cl[5] = 0.000000000000e+00; data_table[48].feg[0].cnl[5] = 0.000000000000e+00; + data_table[49].feg[0].cl[0] = 3.255461945971e+00; data_table[49].feg[0].cnl[0] = 6.949165861385e+00; data_table[49].feg[0].cl[1] = 2.006854690705e+00; data_table[49].feg[0].cnl[1] = 9.956523106562e-01; data_table[49].feg[0].cl[2] = 1.639332619692e-01; data_table[49].feg[0].cnl[2] = 9.190385905760e-02; data_table[49].feg[0].cl[3] = 2.750101189335e-03; data_table[49].feg[0].cnl[3] = 5.299968837729e-03; data_table[49].feg[0].cl[4] = 1.588084660702e-10; data_table[49].feg[0].cnl[4] = 1.800187289546e-05; data_table[49].feg[0].cl[5] = 0.000000000000e+00; data_table[49].feg[0].cnl[5] = 0.000000000000e+00; + data_table[50].feg[0].cl[0] = 3.616597940931e+00; data_table[50].feg[0].cnl[0] = 5.732236167846e+00; data_table[50].feg[0].cl[1] = 1.719412666509e+00; data_table[50].feg[0].cnl[1] = 8.799645330194e-01; data_table[50].feg[0].cl[2] = 1.562477411339e-01; data_table[50].feg[0].cnl[2] = 8.829755113788e-02; data_table[50].feg[0].cl[3] = 2.741651415321e-03; data_table[50].feg[0].cnl[3] = 5.192244716633e-03; data_table[50].feg[0].cl[4] = 2.643849878895e-14; data_table[50].feg[0].cnl[4] = 1.000056740754e-06; data_table[50].feg[0].cl[5] = 0.000000000000e+00; data_table[50].feg[0].cnl[5] = 0.000000000000e+00; + data_table[51].feg[0].cl[0] = 3.948500628807e+00; data_table[51].feg[0].cnl[0] = 4.672763082298e+00; data_table[51].feg[0].cl[1] = 1.400040089177e+00; data_table[51].feg[0].cnl[1] = 7.513923148953e-01; data_table[51].feg[0].cl[2] = 1.439115437707e-01; data_table[51].feg[0].cnl[2] = 8.231324144488e-02; data_table[51].feg[0].cl[3] = 2.547738238993e-03; data_table[51].feg[0].cnl[3] = 4.884507367831e-03; data_table[51].feg[0].cl[4] = 6.561935737562e-12; data_table[51].feg[0].cnl[4] = 5.998278122244e-06; data_table[51].feg[0].cl[5] = 0.000000000000e+00; data_table[51].feg[0].cnl[5] = 0.000000000000e+00; + data_table[52].feg[0].cl[0] = 4.136569496020e+00; data_table[52].feg[0].cnl[0] = 4.013637853826e+00; data_table[52].feg[0].cl[1] = 1.185132281895e+00; data_table[52].feg[0].cnl[1] = 6.607679863545e-01; data_table[52].feg[0].cl[2] = 1.334595783690e-01; data_table[52].feg[0].cnl[2] = 7.684417819778e-02; data_table[52].feg[0].cl[3] = 2.338643716269e-03; data_table[52].feg[0].cnl[3] = 4.558903821153e-03; data_table[52].feg[0].cl[4] = 3.202510781627e-14; data_table[52].feg[0].cnl[4] = 1.001555370470e-06; data_table[52].feg[0].cl[5] = 0.000000000000e+00; data_table[52].feg[0].cnl[5] = 0.000000000000e+00; + data_table[53].feg[0].cl[0] = 4.266218604732e+00; data_table[53].feg[0].cnl[0] = 3.504697596599e+00; data_table[53].feg[0].cl[1] = 1.005029691758e+00; data_table[53].feg[0].cnl[1] = 5.851407565166e-01; data_table[53].feg[0].cl[2] = 1.246194375216e-01; data_table[53].feg[0].cnl[2] = 7.198187788903e-02; data_table[53].feg[0].cl[3] = 2.132265991790e-03; data_table[53].feg[0].cnl[3] = 4.234572723947e-03; data_table[53].feg[0].cl[4] = 3.511838631788e-14; data_table[53].feg[0].cnl[4] = 1.000000000000e-06; data_table[53].feg[0].cl[5] = 0.000000000000e+00; data_table[53].feg[0].cnl[5] = 0.000000000000e+00; + data_table[54].feg[0].cl[0] = 5.190940434882e+00; data_table[54].feg[0].cnl[0] = 1.664349355966e+01; data_table[54].feg[0].cl[1] = 2.841745148751e+00; data_table[54].feg[0].cnl[1] = 1.191829182197e+00; data_table[54].feg[0].cl[2] = 1.635663767305e-01; data_table[54].feg[0].cnl[2] = 7.848498222869e-02; data_table[54].feg[0].cl[3] = 1.748039528416e-03; data_table[54].feg[0].cnl[3] = 3.603430066218e-03; data_table[54].feg[0].cl[4] = 1.090291951475e-10; data_table[54].feg[0].cnl[4] = 1.341476216088e-05; data_table[54].feg[0].cl[5] = 0.000000000000e+00; data_table[54].feg[0].cnl[5] = 0.000000000000e+00; + data_table[55].feg[0].cl[0] = 6.570171258806e+00; data_table[55].feg[0].cnl[0] = 1.385610929468e+01; data_table[55].feg[0].cl[1] = 2.365684989403e+00; data_table[55].feg[0].cnl[1] = 9.860953649390e-01; data_table[55].feg[0].cl[2] = 1.442866019710e-01; data_table[55].feg[0].cnl[2] = 7.251030506732e-02; data_table[55].feg[0].cl[3] = 1.857149819325e-03; data_table[55].feg[0].cnl[3] = 3.728859863919e-03; data_table[55].feg[0].cl[4] = 4.733024042487e-12; data_table[55].feg[0].cnl[4] = 4.747189535309e-06; data_table[55].feg[0].cl[5] = 0.000000000000e+00; data_table[55].feg[0].cnl[5] = 0.000000000000e+00; + data_table[56].feg[0].cl[0] = 6.558837092513e+00; data_table[56].feg[0].cnl[0] = 1.138154017744e+01; data_table[56].feg[0].cl[1] = 2.197192669037e+00; data_table[56].feg[0].cnl[1] = 9.157361219983e-01; data_table[56].feg[0].cl[2] = 1.358248988816e-01; data_table[56].feg[0].cnl[2] = 6.802346634381e-02; data_table[56].feg[0].cl[3] = 1.645339585659e-03; data_table[56].feg[0].cnl[3] = 3.395993729765e-03; data_table[56].feg[0].cl[4] = 9.068661198337e-12; data_table[56].feg[0].cnl[4] = 5.679861398627e-06; data_table[56].feg[0].cl[5] = 0.000000000000e+00; data_table[56].feg[0].cnl[5] = 0.000000000000e+00; + data_table[57].feg[0].cl[0] = 6.323929807231e+00; data_table[57].feg[0].cnl[0] = 1.116505832155e+01; data_table[57].feg[0].cl[1] = 2.226853584534e+00; data_table[57].feg[0].cnl[1] = 8.875878162711e-01; data_table[57].feg[0].cl[2] = 1.287455969130e-01; data_table[57].feg[0].cnl[2] = 6.424775143993e-02; data_table[57].feg[0].cl[3] = 1.471011323566e-03; data_table[57].feg[0].cnl[3] = 3.107132960347e-03; data_table[57].feg[0].cl[4] = 5.205316129758e-14; data_table[57].feg[0].cnl[4] = 1.000000000000e-06; data_table[57].feg[0].cl[5] = 0.000000000000e+00; data_table[57].feg[0].cnl[5] = 0.000000000000e+00; + data_table[58].feg[0].cl[0] = 5.996921786878e+00; data_table[58].feg[0].cnl[0] = 1.266699829864e+01; data_table[58].feg[0].cl[1] = 2.357565442387e+00; data_table[58].feg[0].cnl[1] = 8.585252858745e-01; data_table[58].feg[0].cl[2] = 1.154074752833e-01; data_table[58].feg[0].cnl[2] = 5.796091591359e-02; data_table[58].feg[0].cl[3] = 1.105295435698e-03; data_table[58].feg[0].cnl[3] = 2.525105409170e-03; data_table[58].feg[0].cl[4] = 1.869462204486e-11; data_table[58].feg[0].cnl[4] = 6.626891083751e-06; data_table[58].feg[0].cl[5] = 0.000000000000e+00; data_table[58].feg[0].cnl[5] = 0.000000000000e+00; + data_table[59].feg[0].cl[0] = 5.072240962201e+00; data_table[59].feg[0].cnl[0] = 1.416698682791e+01; data_table[59].feg[0].cl[1] = 1.970039126936e+00; data_table[59].feg[0].cnl[1] = 1.990597670731e+00; data_table[59].feg[0].cl[2] = 1.132649547534e+00; data_table[59].feg[0].cnl[2] = 4.849790433014e-01; data_table[59].feg[0].cl[3] = 6.885041069236e-02; data_table[59].feg[0].cnl[3] = 3.898110046297e-02; data_table[59].feg[0].cl[4] = 2.199526364998e-04; data_table[59].feg[0].cnl[4] = 7.464571005975e-04; data_table[59].feg[0].cl[5] = 0.000000000000e+00; data_table[59].feg[0].cnl[5] = 0.000000000000e+00; + data_table[60].feg[0].cl[0] = 4.955669650183e+00; data_table[60].feg[0].cnl[0] = 1.400045016898e+01; data_table[60].feg[0].cl[1] = 1.904178583217e+00; data_table[60].feg[0].cnl[1] = 1.927650290410e+00; data_table[60].feg[0].cl[2] = 1.162107656701e+00; data_table[60].feg[0].cnl[2] = 4.772782477738e-01; data_table[60].feg[0].cl[3] = 6.632980109417e-02; data_table[60].feg[0].cnl[3] = 3.755055357828e-02; data_table[60].feg[0].cl[4] = 2.143088041065e-04; data_table[60].feg[0].cnl[4] = 7.221933906814e-04; data_table[60].feg[0].cl[5] = 0.000000000000e+00; data_table[60].feg[0].cnl[5] = 0.000000000000e+00; + data_table[61].feg[0].cl[0] = 4.851344526046e+00; data_table[61].feg[0].cnl[0] = 1.364320494775e+01; data_table[61].feg[0].cl[1] = 1.830268901176e+00; data_table[61].feg[0].cnl[1] = 1.832864734912e+00; data_table[61].feg[0].cl[2] = 1.171803387526e+00; data_table[61].feg[0].cnl[2] = 4.653877183727e-01; data_table[61].feg[0].cl[3] = 6.387443746649e-02; data_table[61].feg[0].cnl[3] = 3.619213775415e-02; data_table[61].feg[0].cl[4] = 2.087477855624e-04; data_table[61].feg[0].cnl[4] = 6.990908378726e-04; data_table[61].feg[0].cl[5] = 0.000000000000e+00; data_table[61].feg[0].cnl[5] = 0.000000000000e+00; + data_table[62].feg[0].cl[0] = 4.738602796902e+00; data_table[62].feg[0].cnl[0] = 1.334647424565e+01; data_table[62].feg[0].cl[1] = 1.803521016929e+00; data_table[62].feg[0].cnl[1] = 1.734762804901e+00; data_table[62].feg[0].cl[2] = 1.150595613348e+00; data_table[62].feg[0].cnl[2] = 4.449128398926e-01; data_table[62].feg[0].cl[3] = 6.057779012313e-02; data_table[62].feg[0].cnl[3] = 3.459771403961e-02; data_table[62].feg[0].cl[4] = 2.027826977644e-04; data_table[62].feg[0].cnl[4] = 6.769165200263e-04; data_table[62].feg[0].cl[5] = 0.000000000000e+00; data_table[62].feg[0].cnl[5] = 0.000000000000e+00; + data_table[63].feg[0].cl[0] = 4.716238753702e+00; data_table[63].feg[0].cnl[0] = 1.117212894733e+01; data_table[63].feg[0].cl[1] = 1.658631832949e+00; data_table[63].feg[0].cnl[1] = 1.844944358335e+00; data_table[63].feg[0].cl[2] = 1.205221478349e+00; data_table[63].feg[0].cnl[2] = 4.362658793004e-01; data_table[63].feg[0].cl[3] = 5.771141533917e-02; data_table[63].feg[0].cnl[3] = 3.309986499844e-02; data_table[63].feg[0].cl[4] = 1.965196604787e-04; data_table[63].feg[0].cnl[4] = 6.556770071422e-04; data_table[63].feg[0].cl[5] = 0.000000000000e+00; data_table[63].feg[0].cnl[5] = 0.000000000000e+00; + data_table[64].feg[0].cl[0] = 4.508588666409e+00; data_table[64].feg[0].cnl[0] = 1.292402663919e+01; data_table[64].feg[0].cl[1] = 1.713369231765e+00; data_table[64].feg[0].cnl[1] = 1.650227685814e+00; data_table[64].feg[0].cl[2] = 1.177241604867e+00; data_table[64].feg[0].cnl[2] = 4.211621058265e-01; data_table[64].feg[0].cl[3] = 5.560903747152e-02; data_table[64].feg[0].cnl[3] = 3.197344248625e-02; data_table[64].feg[0].cl[4] = 1.914594874646e-04; data_table[64].feg[0].cnl[4] = 6.356801777645e-04; data_table[64].feg[0].cl[5] = 0.000000000000e+00; data_table[64].feg[0].cnl[5] = 0.000000000000e+00; + data_table[65].feg[0].cl[0] = 4.396949521013e+00; data_table[65].feg[0].cnl[0] = 1.269203417363e+01; data_table[65].feg[0].cl[1] = 1.650197466569e+00; data_table[65].feg[0].cnl[1] = 1.636296904251e+00; data_table[65].feg[0].cl[2] = 1.208637277878e+00; data_table[65].feg[0].cnl[2] = 4.115274729460e-01; data_table[65].feg[0].cl[3] = 5.253066619258e-02; data_table[65].feg[0].cnl[3] = 3.043042600796e-02; data_table[65].feg[0].cl[4] = 1.850683483962e-04; data_table[65].feg[0].cnl[4] = 6.161780604303e-04; data_table[65].feg[0].cl[5] = 0.000000000000e+00; data_table[65].feg[0].cnl[5] = 0.000000000000e+00; + data_table[66].feg[0].cl[0] = 4.241694847677e+00; data_table[66].feg[0].cnl[0] = 1.261911118722e+01; data_table[66].feg[0].cl[1] = 1.680760792093e+00; data_table[66].feg[0].cnl[1] = 1.634480642481e+00; data_table[66].feg[0].cl[2] = 1.195055981189e+00; data_table[66].feg[0].cnl[2] = 3.923435868025e-01; data_table[66].feg[0].cl[3] = 4.930966653806e-02; data_table[66].feg[0].cnl[3] = 2.892483736659e-02; data_table[66].feg[0].cl[4] = 1.787125028877e-04; data_table[66].feg[0].cnl[4] = 5.975418791675e-04; data_table[66].feg[0].cl[5] = 0.000000000000e+00; data_table[66].feg[0].cnl[5] = 0.000000000000e+00; + data_table[67].feg[0].cl[0] = 4.087683802848e+00; data_table[67].feg[0].cnl[0] = 1.249267693555e+01; data_table[67].feg[0].cl[1] = 1.636977049502e+00; data_table[67].feg[0].cnl[1] = 1.653287467948e+00; data_table[67].feg[0].cl[2] = 1.235515529434e+00; data_table[67].feg[0].cnl[2] = 3.882007271675e-01; data_table[67].feg[0].cl[3] = 4.814728135789e-02; data_table[67].feg[0].cnl[3] = 2.821992151070e-02; data_table[67].feg[0].cl[4] = 1.763368580427e-04; data_table[67].feg[0].cnl[4] = 5.804414167892e-04; data_table[67].feg[0].cl[5] = 0.000000000000e+00; data_table[67].feg[0].cnl[5] = 0.000000000000e+00; + data_table[68].feg[0].cl[0] = 4.074299774907e+00; data_table[68].feg[0].cnl[0] = 1.189682973116e+01; data_table[68].feg[0].cl[1] = 1.549035563336e+00; data_table[68].feg[0].cnl[1] = 1.518122257319e+00; data_table[68].feg[0].cl[2] = 1.207860242806e+00; data_table[68].feg[0].cnl[2] = 3.731462227561e-01; data_table[68].feg[0].cl[3] = 4.663015064765e-02; data_table[68].feg[0].cnl[3] = 2.747847138939e-02; data_table[68].feg[0].cl[4] = 1.742683035876e-04; data_table[68].feg[0].cnl[4] = 5.641109067039e-04; data_table[68].feg[0].cl[5] = 0.000000000000e+00; data_table[68].feg[0].cnl[5] = 0.000000000000e+00; + data_table[69].feg[0].cl[0] = 3.994491783546e+00; data_table[69].feg[0].cnl[0] = 1.104890097615e+01; data_table[69].feg[0].cl[1] = 1.396503969404e+00; data_table[69].feg[0].cnl[1] = 1.419209658980e+00; data_table[69].feg[0].cl[2] = 1.236194180484e+00; data_table[69].feg[0].cnl[2] = 3.708063809543e-01; data_table[69].feg[0].cl[3] = 4.613765016486e-02; data_table[69].feg[0].cnl[3] = 2.701644128199e-02; data_table[69].feg[0].cl[4] = 1.724164015558e-04; data_table[69].feg[0].cnl[4] = 5.485135633366e-04; data_table[69].feg[0].cl[5] = 0.000000000000e+00; data_table[69].feg[0].cnl[5] = 0.000000000000e+00; + data_table[70].feg[0].cl[0] = 4.042533681724e+00; data_table[70].feg[0].cnl[0] = 9.270460467663e+00; data_table[70].feg[0].cl[1] = 1.268316698125e+00; data_table[70].feg[0].cnl[1] = 1.601326270981e+00; data_table[70].feg[0].cl[2] = 1.290771160405e+00; data_table[70].feg[0].cnl[2] = 3.634424507096e-01; data_table[70].feg[0].cl[3] = 4.470815108007e-02; data_table[70].feg[0].cnl[3] = 2.632521943092e-02; data_table[70].feg[0].cl[4] = 1.703086670707e-04; data_table[70].feg[0].cnl[4] = 5.334875293597e-04; data_table[70].feg[0].cl[5] = 0.000000000000e+00; data_table[70].feg[0].cnl[5] = 0.000000000000e+00; + data_table[71].feg[0].cl[0] = 3.984682678791e+00; data_table[71].feg[0].cnl[0] = 8.030076981353e+00; data_table[71].feg[0].cl[1] = 1.258524413902e+00; data_table[71].feg[0].cnl[1] = 1.584727144410e+00; data_table[71].feg[0].cl[2] = 1.236485955715e+00; data_table[71].feg[0].cnl[2] = 3.434580335946e-01; data_table[71].feg[0].cl[3] = 4.263984879087e-02; data_table[71].feg[0].cnl[3] = 2.537580469647e-02; data_table[71].feg[0].cl[4] = 1.671028017813e-04; data_table[71].feg[0].cnl[4] = 5.188343291963e-04; data_table[71].feg[0].cl[5] = 0.000000000000e+00; data_table[71].feg[0].cnl[5] = 0.000000000000e+00; + data_table[72].feg[0].cl[0] = 4.817901900524e+00; data_table[72].feg[0].cnl[0] = 5.426400271572e+00; data_table[72].feg[0].cl[1] = 1.519717440754e+00; data_table[72].feg[0].cnl[1] = 3.624940040879e-01; data_table[72].feg[0].cl[2] = 7.473079246650e-02; data_table[72].feg[0].cnl[2] = 1.269501673532e-02; data_table[72].feg[0].cl[3] = -4.358782637620e-02; data_table[72].feg[0].cnl[3] = 9.835303968311e-03; data_table[72].feg[0].cl[4] = 2.376925993528e-04; data_table[72].feg[0].cnl[4] = 5.241057252213e-04; data_table[72].feg[0].cl[5] = 0.000000000000e+00; data_table[72].feg[0].cnl[5] = 0.000000000000e+00; + data_table[73].feg[0].cl[0] = 4.774437195700e+00; data_table[73].feg[0].cnl[0] = 4.830902604138e+00; data_table[73].feg[0].cl[1] = 1.435902529044e+00; data_table[73].feg[0].cnl[1] = 3.415682858732e-01; data_table[73].feg[0].cl[2] = 6.967779522030e-02; data_table[73].feg[0].cnl[2] = 1.206224833212e-02; data_table[73].feg[0].cl[3] = -4.025316655835e-02; data_table[73].feg[0].cnl[3] = 9.263301726683e-03; data_table[73].feg[0].cl[4] = 2.356469479354e-04; data_table[73].feg[0].cnl[4] = 5.110242119502e-04; data_table[73].feg[0].cl[5] = 0.000000000000e+00; data_table[73].feg[0].cnl[5] = 0.000000000000e+00; + data_table[74].feg[0].cl[0] = 4.766686518798e+00; data_table[74].feg[0].cnl[0] = 4.306677349144e+00; data_table[74].feg[0].cl[1] = 1.338427589796e+00; data_table[74].feg[0].cnl[1] = 3.164304083801e-01; data_table[74].feg[0].cl[2] = 4.365696565125e-02; data_table[74].feg[0].cnl[2] = 1.139424638784e-02; data_table[74].feg[0].cl[3] = -1.753260675432e-02; data_table[74].feg[0].cnl[3] = 6.997060564266e-03; data_table[74].feg[0].cl[4] = 2.615319473821e-04; data_table[74].feg[0].cnl[4] = 5.051470884569e-04; data_table[74].feg[0].cl[5] = 0.000000000000e+00; data_table[74].feg[0].cnl[5] = 0.000000000000e+00; + data_table[75].feg[0].cl[0] = 4.676000312409e+00; data_table[75].feg[0].cnl[0] = 3.865557182748e+00; data_table[75].feg[0].cl[1] = 1.273344866365e+00; data_table[75].feg[0].cnl[1] = 3.028993048000e-01; data_table[75].feg[0].cl[2] = 5.409355590252e-02; data_table[75].feg[0].cnl[2] = 1.108430187698e-02; data_table[75].feg[0].cl[3] = -2.767964025732e-02; data_table[75].feg[0].cnl[3] = 7.882286252226e-03; data_table[75].feg[0].cl[4] = 2.409050891036e-04; data_table[75].feg[0].cnl[4] = 4.879082519332e-04; data_table[75].feg[0].cl[5] = 0.000000000000e+00; data_table[75].feg[0].cnl[5] = 0.000000000000e+00; + data_table[76].feg[0].cl[0] = 4.617623226181e+00; data_table[76].feg[0].cnl[0] = 3.412442820968e+00; data_table[76].feg[0].cl[1] = 1.176976436205e+00; data_table[76].feg[0].cnl[1] = 2.808615391884e-01; data_table[76].feg[0].cl[2] = 4.221910652529e-02; data_table[76].feg[0].cnl[2] = 1.041307154535e-02; data_table[76].feg[0].cl[3] = -1.808427255381e-02; data_table[76].feg[0].cnl[3] = 6.509692519465e-03; data_table[76].feg[0].cl[4] = 2.655037530051e-04; data_table[76].feg[0].cnl[4] = 4.814893695047e-04; data_table[76].feg[0].cl[5] = 0.000000000000e+00; data_table[76].feg[0].cnl[5] = 0.000000000000e+00; + data_table[77].feg[0].cl[0] = 4.297575590751e+00; data_table[77].feg[0].cnl[0] = 2.806366885349e+00; data_table[77].feg[0].cl[1] = 1.082376077985e+00; data_table[77].feg[0].cnl[1] = 2.631812747251e-01; data_table[77].feg[0].cl[2] = 3.997378475454e-02; data_table[77].feg[0].cnl[2] = 1.007519901883e-02; data_table[77].feg[0].cl[3] = -1.669384357940e-02; data_table[77].feg[0].cnl[3] = 6.149755341311e-03; data_table[77].feg[0].cl[4] = 2.683899648674e-04; data_table[77].feg[0].cnl[4] = 4.706255960743e-04; data_table[77].feg[0].cl[5] = 0.000000000000e+00; data_table[77].feg[0].cnl[5] = 0.000000000000e+00; + data_table[78].feg[0].cl[0] = 4.319253070395e+00; data_table[78].feg[0].cnl[0] = 2.430804640247e+00; data_table[78].feg[0].cl[1] = 9.361407976022e-01; data_table[78].feg[0].cnl[1] = 2.326073755862e-01; data_table[78].feg[0].cl[2] = 7.588030908582e-02; data_table[78].feg[0].cnl[2] = 8.257084212608e-03; data_table[78].feg[0].cl[3] = -5.503761562648e-02; data_table[78].feg[0].cnl[3] = 6.877684796876e-03; data_table[78].feg[0].cl[4] = 2.634385321135e-04; data_table[78].feg[0].cnl[4] = 4.587717445328e-04; data_table[78].feg[0].cl[5] = 0.000000000000e+00; data_table[78].feg[0].cnl[5] = 0.000000000000e+00; + data_table[79].feg[0].cl[0] = 1.685762695137e+00; data_table[79].feg[0].cnl[0] = 5.699443864462e+00; data_table[79].feg[0].cl[1] = 3.048868823223e+00; data_table[79].feg[0].cnl[1] = 1.538051399135e+00; data_table[79].feg[0].cl[2] = 7.029763988130e-01; data_table[79].feg[0].cnl[2] = 1.934650027769e-01; data_table[79].feg[0].cl[3] = 2.326700329799e-02; data_table[79].feg[0].cnl[3] = 1.608026793360e-02; data_table[79].feg[0].cl[4] = 1.250795337370e-04; data_table[79].feg[0].cnl[4] = 4.167058863466e-04; data_table[79].feg[0].cl[5] = 0.000000000000e+00; data_table[79].feg[0].cnl[5] = 0.000000000000e+00; + data_table[80].feg[0].cl[0] = 2.828978370248e+00; data_table[80].feg[0].cnl[0] = 8.513830179204e+00; data_table[80].feg[0].cl[1] = 2.881925073356e+00; data_table[80].feg[0].cnl[1] = 1.332948750181e+00; data_table[80].feg[0].cl[2] = 6.298422694932e-01; data_table[80].feg[0].cnl[2] = 1.772467356348e-01; data_table[80].feg[0].cl[3] = 2.113600361384e-02; data_table[80].feg[0].cnl[3] = 1.493800717596e-02; data_table[80].feg[0].cl[4] = 1.182832853609e-04; data_table[80].feg[0].cnl[4] = 4.054040056495e-04; data_table[80].feg[0].cl[5] = 0.000000000000e+00; data_table[80].feg[0].cnl[5] = 0.000000000000e+00; + data_table[81].feg[0].cl[0] = 3.410340859295e+00; data_table[81].feg[0].cnl[0] = 6.738247028041e+00; data_table[81].feg[0].cl[1] = 2.487288720979e+00; data_table[81].feg[0].cnl[1] = 1.185221394897e+00; data_table[81].feg[0].cl[2] = 6.024932571690e-01; data_table[81].feg[0].cnl[2] = 1.694306049981e-01; data_table[81].feg[0].cl[3] = 1.976567414282e-02; data_table[81].feg[0].cnl[3] = 1.404902485888e-02; data_table[81].feg[0].cl[4] = 1.114884158005e-04; data_table[81].feg[0].cnl[4] = 3.944501643171e-04; data_table[81].feg[0].cl[5] = 0.000000000000e+00; data_table[81].feg[0].cnl[5] = 0.000000000000e+00; + data_table[82].feg[0].cl[0] = 3.888919287457e+00; data_table[82].feg[0].cnl[0] = 5.184823019984e+00; data_table[82].feg[0].cl[1] = 2.010985450052e+00; data_table[82].feg[0].cnl[1] = 1.042316727779e+00; data_table[82].feg[0].cl[2] = 5.910876080376e-01; data_table[82].feg[0].cnl[2] = 1.651423478571e-01; data_table[82].feg[0].cl[3] = 1.890167442523e-02; data_table[82].feg[0].cnl[3] = 1.339208996724e-02; data_table[82].feg[0].cl[4] = 1.059800257370e-04; data_table[82].feg[0].cnl[4] = 3.841135706125e-04; data_table[82].feg[0].cl[5] = 0.000000000000e+00; data_table[82].feg[0].cnl[5] = 0.000000000000e+00; + data_table[83].feg[0].cl[0] = 3.895470428731e+00; data_table[83].feg[0].cnl[0] = 3.771404146309e+00; data_table[83].feg[0].cl[1] = 1.622709537429e+00; data_table[83].feg[0].cnl[1] = 9.810595863021e-01; data_table[83].feg[0].cl[2] = 5.947573595513e-01; data_table[83].feg[0].cnl[2] = 1.612894773037e-01; data_table[83].feg[0].cl[3] = 1.746595684824e-02; data_table[83].feg[0].cnl[3] = 1.240544459433e-02; data_table[83].feg[0].cl[4] = 9.671744024565e-05; data_table[83].feg[0].cnl[4] = 3.729452600179e-04; data_table[83].feg[0].cl[5] = 0.000000000000e+00; data_table[83].feg[0].cnl[5] = 0.000000000000e+00; + data_table[84].feg[0].cl[0] = 4.772690328171e+00; data_table[84].feg[0].cnl[0] = 4.062706726401e+00; data_table[84].feg[0].cl[1] = 1.384048085551e+00; data_table[84].feg[0].cnl[1] = 8.149198933100e-01; data_table[84].feg[0].cl[2] = 5.504642853228e-01; data_table[84].feg[0].cnl[2] = 1.520919680403e-01; data_table[84].feg[0].cl[3] = 1.620711203298e-02; data_table[84].feg[0].cnl[3] = 1.160703684042e-02; data_table[84].feg[0].cl[4] = 9.018892176023e-05; data_table[84].feg[0].cnl[4] = 3.626421650928e-04; data_table[84].feg[0].cl[5] = 0.000000000000e+00; data_table[84].feg[0].cnl[5] = 0.000000000000e+00; + data_table[85].feg[0].cl[0] = 5.121588284998e+00; data_table[85].feg[0].cnl[0] = 3.564768992576e+00; data_table[85].feg[0].cl[1] = 1.065311970337e+00; data_table[85].feg[0].cnl[1] = 6.945489117785e-01; data_table[85].feg[0].cl[2] = 5.333451761011e-01; data_table[85].feg[0].cnl[2] = 1.468296828139e-01; data_table[85].feg[0].cl[3] = 1.517123066434e-02; data_table[85].feg[0].cnl[3] = 1.088525725670e-02; data_table[85].feg[0].cl[4] = 8.333789972382e-05; data_table[85].feg[0].cnl[4] = 3.523966050259e-04; data_table[85].feg[0].cl[5] = 0.000000000000e+00; data_table[85].feg[0].cnl[5] = 0.000000000000e+00; + data_table[86].feg[0].cl[0] = 4.326300506863e+00; data_table[86].feg[0].cnl[0] = 1.598464225924e+01; data_table[86].feg[0].cl[1] = 3.927685983348e+00; data_table[86].feg[0].cnl[1] = 1.785016789169e+00; data_table[86].feg[0].cl[2] = 6.817081940053e-01; data_table[86].feg[0].cnl[2] = 1.631874713912e-01; data_table[86].feg[0].cl[3] = 1.572388032955e-02; data_table[86].feg[0].cnl[3] = 1.088933530078e-02; data_table[86].feg[0].cl[4] = 8.143545562484e-05; data_table[86].feg[0].cnl[4] = 3.443767774590e-04; data_table[86].feg[0].cl[5] = 0.000000000000e+00; data_table[86].feg[0].cnl[5] = 0.000000000000e+00; + data_table[87].feg[0].cl[0] = 6.206606028573e+00; data_table[87].feg[0].cnl[0] = 1.312206218351e+01; data_table[87].feg[0].cl[1] = 3.158572113291e+00; data_table[87].feg[0].cnl[1] = 1.359507039642e+00; data_table[87].feg[0].cl[2] = 5.763788069594e-01; data_table[87].feg[0].cnl[2] = 1.425271037182e-01; data_table[87].feg[0].cl[3] = 1.287606664376e-02; data_table[87].feg[0].cnl[3] = 9.318402543442e-03; data_table[87].feg[0].cl[4] = 6.698453367208e-05; data_table[87].feg[0].cnl[4] = 3.307005301731e-04; data_table[87].feg[0].cl[5] = 0.000000000000e+00; data_table[87].feg[0].cnl[5] = 0.000000000000e+00; + data_table[88].feg[0].cl[0] = 6.904795469039e+00; data_table[88].feg[0].cnl[0] = 1.093977295526e+01; data_table[88].feg[0].cl[1] = 2.791640980424e+00; data_table[88].feg[0].cnl[1] = 1.205162050086e+00; data_table[88].feg[0].cl[2] = 5.394488841112e-01; data_table[88].feg[0].cnl[2] = 1.340293069461e-01; data_table[88].feg[0].cl[3] = 1.155875654381e-02; data_table[88].feg[0].cnl[3] = 8.424990860991e-03; data_table[88].feg[0].cl[4] = 5.590988205797e-05; data_table[88].feg[0].cnl[4] = 3.176743009512e-04; data_table[88].feg[0].cl[5] = 0.000000000000e+00; data_table[88].feg[0].cnl[5] = 0.000000000000e+00; + data_table[89].feg[0].cl[0] = 7.108608985958e+00; data_table[89].feg[0].cnl[0] = 8.936472275737e+00; data_table[89].feg[0].cl[1] = 2.468518228417e+00; data_table[89].feg[0].cnl[1] = 1.074932025413e+00; data_table[89].feg[0].cl[2] = 5.068648952366e-01; data_table[89].feg[0].cnl[2] = 1.264470423469e-01; data_table[89].feg[0].cl[3] = 1.046185831411e-02; data_table[89].feg[0].cnl[3] = 7.668062648681e-03; data_table[89].feg[0].cl[4] = 4.603207245220e-05; data_table[89].feg[0].cnl[4] = 3.041243360628e-04; data_table[89].feg[0].cl[5] = 0.000000000000e+00; data_table[89].feg[0].cnl[5] = 0.000000000000e+00; + data_table[90].feg[0].cl[0] = 6.265118991091e+00; data_table[90].feg[0].cnl[0] = 1.013987934922e+01; data_table[90].feg[0].cl[1] = 2.997883072507e+00; data_table[90].feg[0].cnl[1] = 1.174043143373e+00; data_table[90].feg[0].cl[2] = 4.871287920782e-01; data_table[90].feg[0].cnl[2] = 1.193071834458e-01; data_table[90].feg[0].cl[3] = 8.844055245587e-03; data_table[90].feg[0].cnl[3] = 6.475339055316e-03; data_table[90].feg[0].cl[4] = 2.508908042739e-05; data_table[90].feg[0].cnl[4] = 2.735135302295e-04; data_table[90].feg[0].cl[5] = 0.000000000000e+00; data_table[90].feg[0].cnl[5] = 0.000000000000e+00; + data_table[91].feg[0].cl[0] = 6.002970274769e+00; data_table[91].feg[0].cnl[0] = 9.825086413018e+00; data_table[91].feg[0].cl[1] = 3.068445619847e+00; data_table[91].feg[0].cnl[1] = 1.135512631855e+00; data_table[91].feg[0].cl[2] = 4.555780347632e-01; data_table[91].feg[0].cnl[2] = 1.113666249326e-01; data_table[91].feg[0].cl[3] = 7.503868907966e-03; data_table[91].feg[0].cnl[3] = 5.398534942030e-03; data_table[91].feg[0].cl[4] = 2.201729737597e-06; data_table[91].feg[0].cnl[4] = 1.622502547230e-04; data_table[91].feg[0].cl[5] = 0.000000000000e+00; data_table[91].feg[0].cnl[5] = 0.000000000000e+00; + data_table[92].feg[0].cl[0] = 5.776246099937e+00; data_table[92].feg[0].cnl[0] = 9.627666105822e+00; data_table[92].feg[0].cl[1] = 3.137669947153e+00; data_table[92].feg[0].cnl[1] = 1.105431535799e+00; data_table[92].feg[0].cl[2] = 4.311200585167e-01; data_table[92].feg[0].cnl[2] = 1.055575226249e-01; data_table[92].feg[0].cl[3] = 6.963860955603e-03; data_table[92].feg[0].cnl[3] = 5.046086894603e-03; data_table[92].feg[0].cl[4] = 3.342636320371e-08; data_table[92].feg[0].cnl[4] = 4.945724792708e-05; data_table[92].feg[0].cl[5] = 0.000000000000e+00; data_table[92].feg[0].cnl[5] = 0.000000000000e+00; + data_table[93].feg[0].cl[0] = 5.114441086159e+00; data_table[93].feg[0].cnl[0] = 1.110961902164e+01; data_table[93].feg[0].cl[1] = 3.505295669439e+00; data_table[93].feg[0].cnl[1] = 1.141789662453e+00; data_table[93].feg[0].cl[2] = 4.160774022955e-01; data_table[93].feg[0].cnl[2] = 1.015949971146e-01; data_table[93].feg[0].cl[3] = 6.685840916280e-03; data_table[93].feg[0].cnl[3] = 4.868898995445e-03; data_table[93].feg[0].cl[4] = 1.190788405432e-09; data_table[93].feg[0].cnl[4] = 1.725005671512e-05; data_table[93].feg[0].cl[5] = 0.000000000000e+00; data_table[93].feg[0].cnl[5] = 0.000000000000e+00; + data_table[94].feg[0].cl[0] = 4.928379432669e+00; data_table[94].feg[0].cnl[0] = 1.094873051522e+01; data_table[94].feg[0].cl[1] = 3.532165584477e+00; data_table[94].feg[0].cnl[1] = 1.099697230044e+00; data_table[94].feg[0].cl[2] = 3.936063503053e-01; data_table[94].feg[0].cnl[2] = 9.662556321866e-02; data_table[94].feg[0].cl[3] = 6.348631807030e-03; data_table[94].feg[0].cnl[3] = 4.671056132769e-03; data_table[94].feg[0].cl[4] = 7.282240817667e-10; data_table[94].feg[0].cnl[4] = 1.446137126888e-05; data_table[94].feg[0].cl[5] = 0.000000000000e+00; data_table[94].feg[0].cnl[5] = 0.000000000000e+00; + data_table[95].feg[0].cl[0] = 5.194007987831e+00; data_table[95].feg[0].cnl[0] = 9.045839152597e+00; data_table[95].feg[0].cl[1] = 3.236455236583e+00; data_table[95].feg[0].cnl[1] = 9.895966606816e-01; data_table[95].feg[0].cl[2] = 3.626720076528e-01; data_table[95].feg[0].cnl[2] = 9.035552827339e-02; data_table[95].feg[0].cl[3] = 5.864767558415e-03; data_table[95].feg[0].cnl[3] = 4.403009455041e-03; data_table[95].feg[0].cl[4] = 4.186081279040e-10; data_table[95].feg[0].cnl[4] = 1.182689042828e-05; data_table[95].feg[0].cl[5] = 0.000000000000e+00; data_table[95].feg[0].cnl[5] = 0.000000000000e+00; + data_table[96].feg[0].cl[0] = 5.062674964788e+00; data_table[96].feg[0].cnl[0] = 8.942161813774e+00; data_table[96].feg[0].cl[1] = 3.251994776161e+00; data_table[96].feg[0].cnl[1] = 9.519372069789e-01; data_table[96].feg[0].cl[2] = 3.423070976390e-01; data_table[96].feg[0].cnl[2] = 8.581899834632e-02; data_table[96].feg[0].cl[3] = 5.523161420640e-03; data_table[96].feg[0].cnl[3] = 4.199464398228e-03; data_table[96].feg[0].cl[4] = 2.320587774719e-13; data_table[96].feg[0].cnl[4] = 1.003320766129e-06; data_table[96].feg[0].cl[5] = 0.000000000000e+00; data_table[96].feg[0].cnl[5] = 0.000000000000e+00; + data_table[97].feg[0].cl[0] = 4.459033865939e+00; data_table[97].feg[0].cnl[0] = 1.035332827659e+01; data_table[97].feg[0].cl[1] = 3.540957137520e+00; data_table[97].feg[0].cnl[1] = 9.740623966592e-01; data_table[97].feg[0].cl[2] = 3.335691264893e-01; data_table[97].feg[0].cnl[2] = 8.347403612471e-02; data_table[97].feg[0].cl[3] = 5.439870086607e-03; data_table[97].feg[0].cnl[3] = 4.121177065070e-03; data_table[97].feg[0].cl[4] = 2.399504795464e-13; data_table[97].feg[0].cnl[4] = 1.000000000000e-06; data_table[97].feg[0].cl[5] = 0.000000000000e+00; data_table[97].feg[0].cnl[5] = 0.000000000000e+00; + data_table[98].feg[0].cl[0] = 4.360442820372e+00; data_table[98].feg[0].cnl[0] = 1.003183148831e+01; data_table[98].feg[0].cl[1] = 3.511473670570e+00; data_table[98].feg[0].cnl[1] = 9.187495133185e-01; data_table[98].feg[0].cl[2] = 3.027297662978e-01; data_table[98].feg[0].cnl[2] = 7.561230629461e-02; data_table[98].feg[0].cl[3] = 4.556929533227e-03; data_table[98].feg[0].cnl[3] = 2.324924961379e-03; data_table[98].feg[0].cl[4] = -7.031867827314e-04; data_table[98].feg[0].cnl[4] = 9.468127404760e-04; data_table[98].feg[0].cl[5] = 0.000000000000e+00; data_table[98].feg[0].cnl[5] = 0.000000000000e+00; + data_table[99].feg[0].cl[0] = 4.223354382825e+00; data_table[99].feg[0].cnl[0] = 9.822572452935e+00; data_table[99].feg[0].cl[1] = 3.497909486848e+00; data_table[99].feg[0].cnl[1] = 8.851991604703e-01; data_table[99].feg[0].cl[2] = 2.890667681101e-01; data_table[99].feg[0].cnl[2] = 7.262699608308e-02; data_table[99].feg[0].cl[3] = 1.086385321320e-01; data_table[99].feg[0].cnl[3] = 1.616074855132e-03; data_table[99].feg[0].cl[4] = -1.049691699837e-01; data_table[99].feg[0].cnl[4] = 1.590155088388e-03; data_table[99].feg[0].cl[5] = 0.000000000000e+00; data_table[99].feg[0].cnl[5] = 0.000000000000e+00; + data_table[100].feg[0].cl[0] = 4.105093096117e+00; data_table[100].feg[0].cnl[0] = 9.604366132224e+00; data_table[100].feg[0].cl[1] = 3.478902121090e+00; data_table[100].feg[0].cnl[1] = 8.506197530668e-01; data_table[100].feg[0].cl[2] = 2.739290417276e-01; data_table[100].feg[0].cnl[2] = 6.947173969610e-02; data_table[100].feg[0].cl[3] = 5.465078212511e-01; data_table[100].feg[0].cnl[3] = 1.567207693675e-03; data_table[100].feg[0].cl[4] = -5.429320802213e-01; data_table[100].feg[0].cnl[4] = 1.562369978280e-03; data_table[100].feg[0].cl[5] = 0.000000000000e+00; data_table[100].feg[0].cnl[5] = 0.000000000000e+00; + data_table[101].feg[0].cl[0] = 3.978174422541e+00; data_table[101].feg[0].cnl[0] = 9.322844061694e+00; data_table[101].feg[0].cl[1] = 3.455845623349e+00; data_table[101].feg[0].cnl[1] = 8.190918007908e-01; data_table[101].feg[0].cl[2] = 2.609732707382e-01; data_table[101].feg[0].cnl[2] = 6.674448990551e-02; data_table[101].feg[0].cl[3] = 1.448317747385e-02; data_table[101].feg[0].cnl[3] = 1.633126678336e-03; data_table[101].feg[0].cl[4] = -1.097649403824e-02; data_table[101].feg[0].cnl[4] = 1.433092520468e-03; data_table[101].feg[0].cl[5] = 0.000000000000e+00; data_table[101].feg[0].cnl[5] = 0.000000000000e+00; + data_table[102].feg[0].cl[0] = 4.472319512080e+00; data_table[102].feg[0].cnl[0] = 8.221771154610e+00; data_table[102].feg[0].cl[1] = 3.204128540727e+00; data_table[102].feg[0].cnl[1] = 7.452706498861e-01; data_table[102].feg[0].cl[2] = 2.387265503153e-01; data_table[102].feg[0].cnl[2] = 6.242119838316e-02; data_table[102].feg[0].cl[3] = 2.697110402440e-02; data_table[102].feg[0].cnl[3] = 1.514952131673e-03; data_table[102].feg[0].cl[4] = -2.364570714437e-02; data_table[102].feg[0].cnl[4] = 1.423557559439e-03; data_table[102].feg[0].cl[5] = 0.000000000000e+00; data_table[102].feg[0].cnl[5] = 0.000000000000e+00; + } + + // 7: Peng et al. parameterization for Ions- 5 Gaussians - [0, 4] + void Load_feg_Peng_ion_0_4() + { + data_table[0].feg[1].cl[0]= 0.1400000000; data_table[0].feg[1].cnl[0]= 0.9840000000; data_table[0].feg[1].cl[1]= 0.6490000000; data_table[0].feg[1].cnl[1]= 8.6700000000; data_table[0].feg[1].cl[2]= 1.3700000000; data_table[0].feg[1].cnl[2]= 38.9000000000; data_table[0].feg[1].cl[3]= 0.3370000000; data_table[0].feg[1].cnl[3]= 111.0000000000; data_table[0].feg[1].cl[4]= 0.7870000000; data_table[0].feg[1].cnl[4]= 166.0000000000; + data_table[2].feg[2].cl[0]= 0.0046000000; data_table[2].feg[2].cnl[0]= 0.0358000000; data_table[2].feg[2].cl[1]= 0.0165000000; data_table[2].feg[2].cnl[1]= 0.2390000000; data_table[2].feg[2].cl[2]= 0.0435000000; data_table[2].feg[2].cnl[2]= 0.8790000000; data_table[2].feg[2].cl[3]= 0.0649000000; data_table[2].feg[2].cnl[3]= 2.6400000000; data_table[2].feg[2].cl[4]= 0.0270000000; data_table[2].feg[2].cnl[4]= 7.0900000000; + data_table[3].feg[4].cl[0]= 0.0034000000; data_table[3].feg[4].cnl[0]= 0.0267000000; data_table[3].feg[4].cl[1]= 0.0103000000; data_table[3].feg[4].cnl[1]= 0.1620000000; data_table[3].feg[4].cl[2]= 0.0233000000; data_table[3].feg[4].cnl[2]= 0.5310000000; data_table[3].feg[4].cl[3]= 0.0325000000; data_table[3].feg[4].cnl[3]= 1.4800000000; data_table[3].feg[4].cl[4]= 0.0120000000; data_table[3].feg[4].cnl[4]= 3.8800000000; + data_table[7].feg[1].cl[0]= 0.2050000000; data_table[7].feg[1].cnl[0]= 0.3970000000; data_table[7].feg[1].cl[1]= 0.6280000000; data_table[7].feg[1].cnl[1]= 2.6400000000; data_table[7].feg[1].cl[2]= 1.1700000000; data_table[7].feg[1].cnl[2]= 8.8000000000; data_table[7].feg[1].cl[3]= 1.0300000000; data_table[7].feg[1].cnl[3]= 27.1000000000; data_table[7].feg[1].cl[4]= 0.2900000000; data_table[7].feg[1].cnl[4]= 91.8000000000; + data_table[7].feg[3].cl[0]= 0.0421000000; data_table[7].feg[3].cnl[0]= 0.0609000000; data_table[7].feg[3].cl[1]= 0.2100000000; data_table[7].feg[3].cnl[1]= 0.5590000000; data_table[7].feg[3].cl[2]= 0.8520000000; data_table[7].feg[3].cnl[2]= 2.9600000000; data_table[7].feg[3].cl[3]= 1.8200000000; data_table[7].feg[3].cnl[3]= 11.5000000000; data_table[7].feg[3].cl[4]= 1.1700000000; data_table[7].feg[3].cnl[4]= 37.7000000000; + data_table[8].feg[1].cl[0]= 0.1340000000; data_table[8].feg[1].cnl[0]= 0.2280000000; data_table[8].feg[1].cl[1]= 0.3910000000; data_table[8].feg[1].cnl[1]= 1.4700000000; data_table[8].feg[1].cl[2]= 0.8140000000; data_table[8].feg[1].cnl[2]= 4.6800000000; data_table[8].feg[1].cl[3]= 0.9280000000; data_table[8].feg[1].cnl[3]= 13.2000000000; data_table[8].feg[1].cl[4]= 0.3470000000; data_table[8].feg[1].cnl[4]= 36.0000000000; + data_table[10].feg[2].cl[0]= 0.0256000000; data_table[10].feg[2].cnl[0]= 0.0397000000; data_table[10].feg[2].cl[1]= 0.0919000000; data_table[10].feg[2].cnl[1]= 0.2870000000; data_table[10].feg[2].cl[2]= 0.2970000000; data_table[10].feg[2].cnl[2]= 1.1800000000; data_table[10].feg[2].cl[3]= 0.5140000000; data_table[10].feg[2].cnl[3]= 3.7500000000; data_table[10].feg[2].cl[4]= 0.1990000000; data_table[10].feg[2].cnl[4]= 10.8000000000; + data_table[11].feg[4].cl[0]= 0.0210000000; data_table[11].feg[4].cnl[0]= 0.0331000000; data_table[11].feg[4].cl[1]= 0.0672000000; data_table[11].feg[4].cnl[1]= 0.2220000000; data_table[11].feg[4].cl[2]= 0.1980000000; data_table[11].feg[4].cnl[2]= 0.8380000000; data_table[11].feg[4].cl[3]= 0.3680000000; data_table[11].feg[4].cnl[3]= 2.4800000000; data_table[11].feg[4].cl[4]= 0.1740000000; data_table[11].feg[4].cnl[4]= 6.7500000000; + data_table[12].feg[6].cl[0]= 0.0192000000; data_table[12].feg[6].cnl[0]= 0.0306000000; data_table[12].feg[6].cl[1]= 0.0579000000; data_table[12].feg[6].cnl[1]= 0.1980000000; data_table[12].feg[6].cl[2]= 0.1630000000; data_table[12].feg[6].cnl[2]= 0.7130000000; data_table[12].feg[6].cl[3]= 0.2840000000; data_table[12].feg[6].cnl[3]= 2.0400000000; data_table[12].feg[6].cl[4]= 0.1140000000; data_table[12].feg[6].cnl[4]= 5.2500000000; + data_table[13].feg[8].cl[0]= 0.1920000000; data_table[13].feg[8].cnl[0]= 0.3590000000; data_table[13].feg[8].cl[1]= 0.2890000000; data_table[13].feg[8].cnl[1]= 1.9600000000; data_table[13].feg[8].cl[2]= 0.1000000000; data_table[13].feg[8].cnl[2]= 9.3400000000; data_table[13].feg[8].cl[3]=-0.0728000000; data_table[13].feg[8].cnl[3]= 11.1000000000; data_table[13].feg[8].cl[4]= 0.0012000000; data_table[13].feg[8].cnl[4]= 13.4000000000; + data_table[16].feg[1].cl[0]= 0.2650000000; data_table[16].feg[1].cnl[0]= 0.2520000000; data_table[16].feg[1].cl[1]= 0.5960000000; data_table[16].feg[1].cnl[1]= 1.5600000000; data_table[16].feg[1].cl[2]= 1.6000000000; data_table[16].feg[1].cnl[2]= 6.2100000000; data_table[16].feg[1].cl[3]= 2.6900000000; data_table[16].feg[1].cnl[3]= 17.8000000000; data_table[16].feg[1].cl[4]= 1.2300000000; data_table[16].feg[1].cnl[4]= 47.8000000000; + data_table[18].feg[2].cl[0]= 0.1990000000; data_table[18].feg[2].cnl[0]= 0.1920000000; data_table[18].feg[2].cl[1]= 0.3960000000; data_table[18].feg[2].cnl[1]= 1.1000000000; data_table[18].feg[2].cl[2]= 0.9280000000; data_table[18].feg[2].cnl[2]= 3.9100000000; data_table[18].feg[2].cl[3]= 1.4500000000; data_table[18].feg[2].cnl[3]= 9.7500000000; data_table[18].feg[2].cl[4]= 0.4500000000; data_table[18].feg[2].cnl[4]= 23.4000000000; + data_table[19].feg[4].cl[0]= 0.1640000000; data_table[19].feg[4].cnl[0]= 0.1570000000; data_table[19].feg[4].cl[1]= 0.3270000000; data_table[19].feg[4].cnl[1]= 0.8940000000; data_table[19].feg[4].cl[2]= 0.7430000000; data_table[19].feg[4].cnl[2]= 3.1500000000; data_table[19].feg[4].cl[3]= 1.1600000000; data_table[19].feg[4].cnl[3]= 7.6700000000; data_table[19].feg[4].cl[4]= 0.3070000000; data_table[19].feg[4].cnl[4]= 17.7000000000; + data_table[20].feg[6].cl[0]= 0.1630000000; data_table[20].feg[6].cnl[0]= 0.1570000000; data_table[20].feg[6].cl[1]= 0.3070000000; data_table[20].feg[6].cnl[1]= 0.8990000000; data_table[20].feg[6].cl[2]= 0.7160000000; data_table[20].feg[6].cnl[2]= 3.0600000000; data_table[20].feg[6].cl[3]= 0.8800000000; data_table[20].feg[6].cnl[3]= 7.0500000000; data_table[20].feg[6].cl[4]= 0.1390000000; data_table[20].feg[6].cnl[4]= 16.1000000000; + data_table[21].feg[4].cl[0]= 0.3990000000; data_table[21].feg[4].cnl[0]= 0.3760000000; data_table[21].feg[4].cl[1]= 1.0400000000; data_table[21].feg[4].cnl[1]= 2.7400000000; data_table[21].feg[4].cl[2]= 1.2100000000; data_table[21].feg[4].cnl[2]= 8.1000000000; data_table[21].feg[4].cl[3]=-0.0797000000; data_table[21].feg[4].cnl[3]= 14.2000000000; data_table[21].feg[4].cl[4]= 0.3520000000; data_table[21].feg[4].cnl[4]= 23.2000000000; + data_table[21].feg[6].cl[0]= 0.3640000000; data_table[21].feg[6].cnl[0]= 0.3640000000; data_table[21].feg[6].cl[1]= 0.9190000000; data_table[21].feg[6].cnl[1]= 2.6700000000; data_table[21].feg[6].cl[2]= 1.3500000000; data_table[21].feg[6].cnl[2]= 8.1800000000; data_table[21].feg[6].cl[3]=-0.9330000000; data_table[21].feg[6].cnl[3]= 11.8000000000; data_table[21].feg[6].cl[4]= 0.5890000000; data_table[21].feg[6].cnl[4]= 14.9000000000; + data_table[21].feg[8].cl[0]= 0.1160000000; data_table[21].feg[8].cnl[0]= 0.1080000000; data_table[21].feg[8].cl[1]= 0.2560000000; data_table[21].feg[8].cnl[1]= 0.6550000000; data_table[21].feg[8].cl[2]= 0.5650000000; data_table[21].feg[8].cnl[2]= 2.3800000000; data_table[21].feg[8].cl[3]= 0.7720000000; data_table[21].feg[8].cnl[3]= 5.5100000000; data_table[21].feg[8].cl[4]= 0.1320000000; data_table[21].feg[8].cnl[4]= 12.3000000000; + data_table[22].feg[4].cl[0]= 0.3170000000; data_table[22].feg[4].cnl[0]= 0.2690000000; data_table[22].feg[4].cl[1]= 0.9390000000; data_table[22].feg[4].cnl[1]= 2.0900000000; data_table[22].feg[4].cl[2]= 1.4900000000; data_table[22].feg[4].cnl[2]= 7.2200000000; data_table[22].feg[4].cl[3]=-1.3100000000; data_table[22].feg[4].cnl[3]= 15.2000000000; data_table[22].feg[4].cl[4]= 1.4700000000; data_table[22].feg[4].cnl[4]= 17.6000000000; + data_table[22].feg[6].cl[0]= 0.3410000000; data_table[22].feg[6].cnl[0]= 0.3210000000; data_table[22].feg[6].cl[1]= 0.8050000000; data_table[22].feg[6].cnl[1]= 2.2300000000; data_table[22].feg[6].cl[2]= 0.9420000000; data_table[22].feg[6].cnl[2]= 5.9900000000; data_table[22].feg[6].cl[3]= 0.0783000000; data_table[22].feg[6].cnl[3]= 13.4000000000; data_table[22].feg[6].cl[4]= 0.1560000000; data_table[22].feg[6].cnl[4]= 16.9000000000; + data_table[22].feg[10].cl[0]= 0.0367000000; data_table[22].feg[10].cnl[0]= 0.0330000000; data_table[22].feg[10].cl[1]= 0.1240000000; data_table[22].feg[10].cnl[1]= 0.2220000000; data_table[22].feg[10].cl[2]= 0.2440000000; data_table[22].feg[10].cnl[2]= 0.8240000000; data_table[22].feg[10].cl[3]= 0.7230000000; data_table[22].feg[10].cnl[3]= 2.8000000000; data_table[22].feg[10].cl[4]= 0.4350000000; data_table[22].feg[10].cnl[4]= 6.7000000000; + data_table[23].feg[4].cl[0]= 0.2370000000; data_table[23].feg[4].cnl[0]= 0.1770000000; data_table[23].feg[4].cl[1]= 0.6340000000; data_table[23].feg[4].cnl[1]= 1.3500000000; data_table[23].feg[4].cl[2]= 1.2300000000; data_table[23].feg[4].cnl[2]= 4.3000000000; data_table[23].feg[4].cl[3]= 0.7130000000; data_table[23].feg[4].cnl[3]= 12.2000000000; data_table[23].feg[4].cl[4]= 0.0859000000; data_table[23].feg[4].cnl[4]= 39.0000000000; + data_table[23].feg[6].cl[0]= 0.3930000000; data_table[23].feg[6].cnl[0]= 0.3590000000; data_table[23].feg[6].cl[1]= 1.0500000000; data_table[23].feg[6].cnl[1]= 2.5700000000; data_table[23].feg[6].cl[2]= 1.6200000000; data_table[23].feg[6].cnl[2]= 8.6800000000; data_table[23].feg[6].cl[3]=-1.1500000000; data_table[23].feg[6].cnl[3]= 11.0000000000; data_table[23].feg[6].cl[4]= 0.4070000000; data_table[23].feg[6].cnl[4]= 15.8000000000; + data_table[23].feg[8].cl[0]= 0.1320000000; data_table[23].feg[8].cnl[0]= 0.1090000000; data_table[23].feg[8].cl[1]= 0.2920000000; data_table[23].feg[8].cnl[1]= 0.6950000000; data_table[23].feg[8].cl[2]= 0.7030000000; data_table[23].feg[8].cnl[2]= 2.3900000000; data_table[23].feg[8].cl[3]= 0.6920000000; data_table[23].feg[8].cnl[3]= 5.6500000000; data_table[23].feg[8].cl[4]= 0.0959000000; data_table[23].feg[8].cnl[4]= 14.7000000000; + data_table[24].feg[4].cl[0]= 0.0576000000; data_table[24].feg[4].cnl[0]= 0.0398000000; data_table[24].feg[4].cl[1]= 0.2100000000; data_table[24].feg[4].cnl[1]= 0.2840000000; data_table[24].feg[4].cl[2]= 0.6040000000; data_table[24].feg[4].cnl[2]= 1.2900000000; data_table[24].feg[4].cl[3]= 1.3200000000; data_table[24].feg[4].cnl[3]= 4.2300000000; data_table[24].feg[4].cl[4]= 0.6590000000; data_table[24].feg[4].cnl[4]= 14.5000000000; + data_table[24].feg[6].cl[0]= 0.1160000000; data_table[24].feg[6].cnl[0]= 0.0117000000; data_table[24].feg[6].cl[1]= 0.5230000000; data_table[24].feg[6].cnl[1]= 0.8760000000; data_table[24].feg[6].cl[2]= 0.8810000000; data_table[24].feg[6].cnl[2]= 3.0600000000; data_table[24].feg[6].cl[3]= 0.5890000000; data_table[24].feg[6].cnl[3]= 6.4400000000; data_table[24].feg[6].cl[4]= 0.2140000000; data_table[24].feg[6].cnl[4]= 14.3000000000; + data_table[24].feg[8].cl[0]= 0.3810000000; data_table[24].feg[8].cnl[0]= 0.3540000000; data_table[24].feg[8].cl[1]= 1.8300000000; data_table[24].feg[8].cnl[1]= 2.7200000000; data_table[24].feg[8].cl[2]=-1.3300000000; data_table[24].feg[8].cnl[2]= 3.4700000000; data_table[24].feg[8].cl[3]= 0.9950000000; data_table[24].feg[8].cnl[3]= 5.4700000000; data_table[24].feg[8].cl[4]= 0.0618000000; data_table[24].feg[8].cnl[4]= 16.1000000000; + data_table[25].feg[4].cl[0]= 0.3070000000; data_table[25].feg[4].cnl[0]= 0.2300000000; data_table[25].feg[4].cl[1]= 0.8380000000; data_table[25].feg[4].cnl[1]= 1.6200000000; data_table[25].feg[4].cl[2]= 1.1100000000; data_table[25].feg[4].cnl[2]= 4.8700000000; data_table[25].feg[4].cl[3]= 0.2800000000; data_table[25].feg[4].cnl[3]= 10.7000000000; data_table[25].feg[4].cl[4]= 0.2770000000; data_table[25].feg[4].cnl[4]= 19.2000000000; + data_table[25].feg[6].cl[0]= 0.1980000000; data_table[25].feg[6].cnl[0]= 0.1540000000; data_table[25].feg[6].cl[1]= 0.3870000000; data_table[25].feg[6].cnl[1]= 0.8930000000; data_table[25].feg[6].cl[2]= 0.8890000000; data_table[25].feg[6].cnl[2]= 2.6200000000; data_table[25].feg[6].cl[3]= 0.7090000000; data_table[25].feg[6].cnl[3]= 6.6500000000; data_table[25].feg[6].cl[4]= 0.1170000000; data_table[25].feg[6].cnl[4]= 18.0000000000; + data_table[26].feg[4].cl[0]= 0.2130000000; data_table[26].feg[4].cnl[0]= 0.1480000000; data_table[26].feg[4].cl[1]= 0.4880000000; data_table[26].feg[4].cnl[1]= 0.9390000000; data_table[26].feg[4].cl[2]= 0.9980000000; data_table[26].feg[4].cnl[2]= 2.7800000000; data_table[26].feg[4].cl[3]= 0.8280000000; data_table[26].feg[4].cnl[3]= 7.3100000000; data_table[26].feg[4].cl[4]= 0.2300000000; data_table[26].feg[4].cnl[4]= 20.7000000000; + data_table[26].feg[6].cl[0]= 0.3310000000; data_table[26].feg[6].cnl[0]= 0.2670000000; data_table[26].feg[6].cl[1]= 0.4870000000; data_table[26].feg[6].cnl[1]= 1.4100000000; data_table[26].feg[6].cl[2]= 0.7290000000; data_table[26].feg[6].cnl[2]= 2.8900000000; data_table[26].feg[6].cl[3]= 0.6080000000; data_table[26].feg[6].cnl[3]= 6.4500000000; data_table[26].feg[6].cl[4]= 0.1310000000; data_table[26].feg[6].cnl[4]= 15.8000000000; + data_table[27].feg[4].cl[0]= 0.3380000000; data_table[27].feg[4].cnl[0]= 0.2370000000; data_table[27].feg[4].cl[1]= 0.9820000000; data_table[27].feg[4].cnl[1]= 1.6700000000; data_table[27].feg[4].cl[2]= 1.3200000000; data_table[27].feg[4].cnl[2]= 5.7300000000; data_table[27].feg[4].cl[3]=-3.5600000000; data_table[27].feg[4].cnl[3]= 11.4000000000; data_table[27].feg[4].cl[4]= 3.6200000000; data_table[27].feg[4].cnl[4]= 12.1000000000; + data_table[27].feg[6].cl[0]= 0.3470000000; data_table[27].feg[6].cnl[0]= 0.2600000000; data_table[27].feg[6].cl[1]= 0.8770000000; data_table[27].feg[6].cnl[1]= 1.7100000000; data_table[27].feg[6].cl[2]= 0.7900000000; data_table[27].feg[6].cnl[2]= 4.7500000000; data_table[27].feg[6].cl[3]= 0.0538000000; data_table[27].feg[6].cnl[3]= 7.5100000000; data_table[27].feg[6].cl[4]= 0.1920000000; data_table[27].feg[6].cnl[4]= 13.0000000000; + data_table[28].feg[2].cl[0]= 0.3120000000; data_table[28].feg[2].cnl[0]= 0.2010000000; data_table[28].feg[2].cl[1]= 0.8120000000; data_table[28].feg[2].cnl[1]= 1.3100000000; data_table[28].feg[2].cl[2]= 1.1100000000; data_table[28].feg[2].cnl[2]= 3.8000000000; data_table[28].feg[2].cl[3]= 0.7940000000; data_table[28].feg[2].cnl[3]= 10.5000000000; data_table[28].feg[2].cl[4]= 0.2570000000; data_table[28].feg[2].cnl[4]= 28.2000000000; + data_table[28].feg[4].cl[0]= 0.2240000000; data_table[28].feg[4].cnl[0]= 0.1450000000; data_table[28].feg[4].cl[1]= 0.5440000000; data_table[28].feg[4].cnl[1]= 0.9330000000; data_table[28].feg[4].cl[2]= 0.9700000000; data_table[28].feg[4].cnl[2]= 2.6900000000; data_table[28].feg[4].cl[3]= 0.7270000000; data_table[28].feg[4].cnl[3]= 7.1100000000; data_table[28].feg[4].cl[4]= 0.1820000000; data_table[28].feg[4].cnl[4]= 19.4000000000; + data_table[29].feg[4].cl[0]= 0.2520000000; data_table[29].feg[4].cnl[0]= 0.1610000000; data_table[29].feg[4].cl[1]= 0.6000000000; data_table[29].feg[4].cnl[1]= 1.0100000000; data_table[29].feg[4].cl[2]= 0.9170000000; data_table[29].feg[4].cnl[2]= 2.7600000000; data_table[29].feg[4].cl[3]= 0.6630000000; data_table[29].feg[4].cnl[3]= 7.0800000000; data_table[29].feg[4].cl[4]= 0.1610000000; data_table[29].feg[4].cnl[4]= 19.0000000000; + data_table[30].feg[6].cl[0]= 0.3910000000; data_table[30].feg[6].cnl[0]= 0.2640000000; data_table[30].feg[6].cl[1]= 0.9470000000; data_table[30].feg[6].cnl[1]= 1.6500000000; data_table[30].feg[6].cl[2]= 0.6900000000; data_table[30].feg[6].cnl[2]= 4.8200000000; data_table[30].feg[6].cl[3]= 0.0709000000; data_table[30].feg[6].cnl[3]= 10.7000000000; data_table[30].feg[6].cl[4]= 0.0653000000; data_table[30].feg[6].cnl[4]= 15.2000000000; + data_table[31].feg[8].cl[0]= 0.3460000000; data_table[31].feg[8].cnl[0]= 0.2320000000; data_table[31].feg[8].cl[1]= 0.8300000000; data_table[31].feg[8].cnl[1]= 1.4500000000; data_table[31].feg[8].cl[2]= 0.5990000000; data_table[31].feg[8].cnl[2]= 4.0800000000; data_table[31].feg[8].cl[3]= 0.0949000000; data_table[31].feg[8].cnl[3]= 13.2000000000; data_table[31].feg[8].cl[4]=-0.0217000000; data_table[31].feg[8].cnl[4]= 29.5000000000; + data_table[34].feg[1].cl[0]= 0.1250000000; data_table[34].feg[1].cnl[0]= 0.0530000000; data_table[34].feg[1].cl[1]= 0.5630000000; data_table[34].feg[1].cnl[1]= 0.4690000000; data_table[34].feg[1].cl[2]= 1.4300000000; data_table[34].feg[1].cnl[2]= 2.1500000000; data_table[34].feg[1].cl[3]= 3.5200000000; data_table[34].feg[1].cnl[3]= 11.1000000000; data_table[34].feg[1].cl[4]= 3.2200000000; data_table[34].feg[1].cnl[4]= 38.9000000000; + data_table[36].feg[2].cl[0]= 0.3680000000; data_table[36].feg[2].cnl[0]= 0.1870000000; data_table[36].feg[2].cl[1]= 0.8840000000; data_table[36].feg[2].cnl[1]= 1.1200000000; data_table[36].feg[2].cl[2]= 1.1400000000; data_table[36].feg[2].cnl[2]= 3.9800000000; data_table[36].feg[2].cl[3]= 2.2600000000; data_table[36].feg[2].cnl[3]= 10.9000000000; data_table[36].feg[2].cl[4]= 0.8810000000; data_table[36].feg[2].cnl[4]= 26.6000000000; + data_table[37].feg[4].cl[0]= 0.3460000000; data_table[37].feg[4].cnl[0]= 0.1760000000; data_table[37].feg[4].cl[1]= 0.8040000000; data_table[37].feg[4].cnl[1]= 1.0400000000; data_table[37].feg[4].cl[2]= 0.9880000000; data_table[37].feg[4].cnl[2]= 3.5900000000; data_table[37].feg[4].cl[3]= 1.8900000000; data_table[37].feg[4].cnl[3]= 9.3200000000; data_table[37].feg[4].cl[4]= 0.6090000000; data_table[37].feg[4].cnl[4]= 21.4000000000; + data_table[38].feg[6].cl[0]= 0.4650000000; data_table[38].feg[6].cnl[0]= 0.2400000000; data_table[38].feg[6].cl[1]= 0.9230000000; data_table[38].feg[6].cnl[1]= 1.4300000000; data_table[38].feg[6].cl[2]= 2.4100000000; data_table[38].feg[6].cnl[2]= 6.4500000000; data_table[38].feg[6].cl[3]=-2.3100000000; data_table[38].feg[6].cnl[3]= 9.9700000000; data_table[38].feg[6].cl[4]= 2.4800000000; data_table[38].feg[6].cnl[4]= 12.2000000000; + data_table[39].feg[8].cl[0]= 0.2340000000; data_table[39].feg[8].cnl[0]= 0.1130000000; data_table[39].feg[8].cl[1]= 0.6420000000; data_table[39].feg[8].cnl[1]= 0.7360000000; data_table[39].feg[8].cl[2]= 0.7470000000; data_table[39].feg[8].cnl[2]= 2.5400000000; data_table[39].feg[8].cl[3]= 1.4700000000; data_table[39].feg[8].cnl[3]= 6.7200000000; data_table[39].feg[8].cl[4]= 0.3770000000; data_table[39].feg[8].cnl[4]= 14.7000000000; + data_table[40].feg[6].cl[0]= 0.3770000000; data_table[40].feg[6].cnl[0]= 0.1840000000; data_table[40].feg[6].cl[1]= 0.7490000000; data_table[40].feg[6].cnl[1]= 1.0200000000; data_table[40].feg[6].cl[2]= 1.2900000000; data_table[40].feg[6].cnl[2]= 3.8000000000; data_table[40].feg[6].cl[3]= 1.6100000000; data_table[40].feg[6].cnl[3]= 9.4400000000; data_table[40].feg[6].cl[4]= 0.4810000000; data_table[40].feg[6].cnl[4]= 25.7000000000; + data_table[40].feg[10].cl[0]= 0.0828000000; data_table[40].feg[10].cnl[0]= 0.0369000000; data_table[40].feg[10].cl[1]= 0.2710000000; data_table[40].feg[10].cnl[1]= 0.2610000000; data_table[40].feg[10].cl[2]= 0.6540000000; data_table[40].feg[10].cnl[2]= 0.9570000000; data_table[40].feg[10].cl[3]= 1.2400000000; data_table[40].feg[10].cnl[3]= 3.9400000000; data_table[40].feg[10].cl[4]= 0.8290000000; data_table[40].feg[10].cnl[4]= 9.4400000000; + data_table[41].feg[6].cl[0]= 0.4010000000; data_table[41].feg[6].cnl[0]= 0.1910000000; data_table[41].feg[6].cl[1]= 0.7560000000; data_table[41].feg[6].cnl[1]= 1.0600000000; data_table[41].feg[6].cl[2]= 1.3800000000; data_table[41].feg[6].cnl[2]= 3.8400000000; data_table[41].feg[6].cl[3]= 1.5800000000; data_table[41].feg[6].cnl[3]= 9.3800000000; data_table[41].feg[6].cl[4]= 0.4970000000; data_table[41].feg[6].cnl[4]= 24.6000000000; + data_table[41].feg[10].cl[0]= 0.4790000000; data_table[41].feg[10].cnl[0]= 0.2410000000; data_table[41].feg[10].cl[1]= 0.8460000000; data_table[41].feg[10].cnl[1]= 1.4600000000; data_table[41].feg[10].cl[2]= 15.6000000000; data_table[41].feg[10].cnl[2]= 6.7900000000; data_table[41].feg[10].cl[3]=-15.2000000000; data_table[41].feg[10].cnl[3]= 7.1300000000; data_table[41].feg[10].cl[4]= 1.6000000000; data_table[41].feg[10].cnl[4]= 10.4000000000; + data_table[41].feg[12].cl[0]= 0.2030000000; data_table[41].feg[12].cnl[0]= 0.0971000000; data_table[41].feg[12].cl[1]= 0.5670000000; data_table[41].feg[12].cnl[1]= 0.6470000000; data_table[41].feg[12].cl[2]= 0.6460000000; data_table[41].feg[12].cnl[2]= 2.2800000000; data_table[41].feg[12].cl[3]= 1.1600000000; data_table[41].feg[12].cnl[3]= 5.6100000000; data_table[41].feg[12].cl[4]= 0.1710000000; data_table[41].feg[12].cnl[4]= 12.4000000000; + data_table[43].feg[6].cl[0]= 0.4280000000; data_table[43].feg[6].cnl[0]= 0.1910000000; data_table[43].feg[6].cl[1]= 0.7730000000; data_table[43].feg[6].cnl[1]= 1.0900000000; data_table[43].feg[6].cl[2]= 1.5500000000; data_table[43].feg[6].cnl[2]= 3.8200000000; data_table[43].feg[6].cl[3]= 1.4600000000; data_table[43].feg[6].cnl[3]= 9.0800000000; data_table[43].feg[6].cl[4]= 0.4860000000; data_table[43].feg[6].cnl[4]= 21.7000000000; + data_table[43].feg[8].cl[0]= 0.2820000000; data_table[43].feg[8].cnl[0]= 0.1250000000; data_table[43].feg[8].cl[1]= 0.6530000000; data_table[43].feg[8].cnl[1]= 0.7530000000; data_table[43].feg[8].cl[2]= 1.1400000000; data_table[43].feg[8].cnl[2]= 2.8500000000; data_table[43].feg[8].cl[3]= 1.5300000000; data_table[43].feg[8].cnl[3]= 7.0100000000; data_table[43].feg[8].cl[4]= 0.4180000000; data_table[43].feg[8].cnl[4]= 17.5000000000; + data_table[44].feg[6].cl[0]= 0.3520000000; data_table[44].feg[6].cnl[0]= 0.1510000000; data_table[44].feg[6].cl[1]= 0.7230000000; data_table[44].feg[6].cnl[1]= 0.8780000000; data_table[44].feg[6].cl[2]= 1.5000000000; data_table[44].feg[6].cnl[2]= 3.2800000000; data_table[44].feg[6].cl[3]= 1.6300000000; data_table[44].feg[6].cnl[3]= 8.1600000000; data_table[44].feg[6].cl[4]= 0.4990000000; data_table[44].feg[6].cnl[4]= 20.7000000000; + data_table[44].feg[8].cl[0]= 0.3970000000; data_table[44].feg[8].cnl[0]= 0.1770000000; data_table[44].feg[8].cl[1]= 0.7250000000; data_table[44].feg[8].cnl[1]= 1.0100000000; data_table[44].feg[8].cl[2]= 1.5100000000; data_table[44].feg[8].cnl[2]= 3.6200000000; data_table[44].feg[8].cl[3]= 1.1900000000; data_table[44].feg[8].cnl[3]= 8.5600000000; data_table[44].feg[8].cl[4]= 0.2510000000; data_table[44].feg[8].cnl[4]= 18.9000000000; + data_table[45].feg[4].cl[0]= 0.9350000000; data_table[45].feg[4].cnl[0]= 0.3930000000; data_table[45].feg[4].cl[1]= 3.1100000000; data_table[45].feg[4].cnl[1]= 4.0600000000; data_table[45].feg[4].cl[2]= 24.6000000000; data_table[45].feg[4].cnl[2]= 43.1000000000; data_table[45].feg[4].cl[3]=-43.6000000000; data_table[45].feg[4].cnl[3]= 54.0000000000; data_table[45].feg[4].cl[4]= 21.1000000000; data_table[45].feg[4].cnl[4]= 69.8000000000; + data_table[45].feg[8].cl[0]= 0.3480000000; data_table[45].feg[8].cnl[0]= 0.1510000000; data_table[45].feg[8].cl[1]= 0.6400000000; data_table[45].feg[8].cnl[1]= 0.8320000000; data_table[45].feg[8].cl[2]= 1.2200000000; data_table[45].feg[8].cnl[2]= 2.8500000000; data_table[45].feg[8].cl[3]= 1.4500000000; data_table[45].feg[8].cnl[3]= 6.5900000000; data_table[45].feg[8].cl[4]= 0.4270000000; data_table[45].feg[8].cnl[4]= 15.6000000000; + data_table[46].feg[2].cl[0]= 0.5030000000; data_table[46].feg[2].cnl[0]= 0.1990000000; data_table[46].feg[2].cl[1]= 0.9400000000; data_table[46].feg[2].cnl[1]= 1.1900000000; data_table[46].feg[2].cl[2]= 2.1700000000; data_table[46].feg[2].cnl[2]= 4.0500000000; data_table[46].feg[2].cl[3]= 1.9900000000; data_table[46].feg[2].cnl[3]= 11.3000000000; data_table[46].feg[2].cl[4]= 0.7260000000; data_table[46].feg[2].cnl[4]= 32.4000000000; + data_table[46].feg[4].cl[0]= 0.4310000000; data_table[46].feg[4].cnl[0]= 0.1750000000; data_table[46].feg[4].cl[1]= 0.7560000000; data_table[46].feg[4].cnl[1]= 0.9790000000; data_table[46].feg[4].cl[2]= 1.7200000000; data_table[46].feg[4].cnl[2]= 3.3000000000; data_table[46].feg[4].cl[3]= 1.7800000000; data_table[46].feg[4].cnl[3]= 8.2400000000; data_table[46].feg[4].cl[4]= 0.5260000000; data_table[46].feg[4].cnl[4]= 21.4000000000; + data_table[47].feg[4].cl[0]= 0.4250000000; data_table[47].feg[4].cnl[0]= 0.1680000000; data_table[47].feg[4].cl[1]= 0.7450000000; data_table[47].feg[4].cnl[1]= 0.9440000000; data_table[47].feg[4].cl[2]= 1.7300000000; data_table[47].feg[4].cnl[2]= 3.1400000000; data_table[47].feg[4].cl[3]= 1.7400000000; data_table[47].feg[4].cnl[3]= 7.8400000000; data_table[47].feg[4].cl[4]= 0.4870000000; data_table[47].feg[4].cnl[4]= 20.4000000000; + data_table[48].feg[6].cl[0]= 0.4170000000; data_table[48].feg[6].cnl[0]= 0.1640000000; data_table[48].feg[6].cl[1]= 0.7550000000; data_table[48].feg[6].cnl[1]= 0.9600000000; data_table[48].feg[6].cl[2]= 1.5900000000; data_table[48].feg[6].cnl[2]= 3.0800000000; data_table[48].feg[6].cl[3]= 1.3600000000; data_table[48].feg[6].cnl[3]= 7.0300000000; data_table[48].feg[6].cl[4]= 0.4510000000; data_table[48].feg[6].cnl[4]= 16.1000000000; + data_table[49].feg[4].cl[0]= 0.7970000000; data_table[49].feg[4].cnl[0]= 0.3170000000; data_table[49].feg[4].cl[1]= 2.1300000000; data_table[49].feg[4].cnl[1]= 2.5100000000; data_table[49].feg[4].cl[2]= 2.1500000000; data_table[49].feg[4].cnl[2]= 9.0400000000; data_table[49].feg[4].cl[3]=-1.6400000000; data_table[49].feg[4].cnl[3]= 24.2000000000; data_table[49].feg[4].cl[4]= 2.7200000000; data_table[49].feg[4].cnl[4]= 26.4000000000; + data_table[49].feg[8].cl[0]= 0.2610000000; data_table[49].feg[8].cnl[0]= 0.0957000000; data_table[49].feg[8].cl[1]= 0.6420000000; data_table[49].feg[8].cnl[1]= 0.6250000000; data_table[49].feg[8].cl[2]= 1.5300000000; data_table[49].feg[8].cnl[2]= 2.5100000000; data_table[49].feg[8].cl[3]= 1.3600000000; data_table[49].feg[8].cnl[3]= 6.3100000000; data_table[49].feg[8].cl[4]= 0.1770000000; data_table[49].feg[8].cnl[4]= 15.9000000000; + data_table[50].feg[6].cl[0]= 0.5520000000; data_table[50].feg[6].cnl[0]= 0.2120000000; data_table[50].feg[6].cl[1]= 1.1400000000; data_table[50].feg[6].cnl[1]= 1.4200000000; data_table[50].feg[6].cl[2]= 1.8700000000; data_table[50].feg[6].cnl[2]= 4.2100000000; data_table[50].feg[6].cl[3]= 1.3600000000; data_table[50].feg[6].cnl[3]= 12.5000000000; data_table[50].feg[6].cl[4]= 0.4140000000; data_table[50].feg[6].cnl[4]= 29.0000000000; + data_table[50].feg[10].cl[0]= 0.3770000000; data_table[50].feg[10].cnl[0]= 0.1510000000; data_table[50].feg[10].cl[1]= 0.5880000000; data_table[50].feg[10].cnl[1]= 0.8120000000; data_table[50].feg[10].cl[2]= 1.2200000000; data_table[50].feg[10].cnl[2]= 2.4000000000; data_table[50].feg[10].cl[3]= 1.1800000000; data_table[50].feg[10].cnl[3]= 5.2700000000; data_table[50].feg[10].cl[4]= 0.2440000000; data_table[50].feg[10].cnl[4]= 11.9000000000; + data_table[52].feg[1].cl[0]= 0.9010000000; data_table[52].feg[1].cnl[0]= 0.3120000000; data_table[52].feg[1].cl[1]= 2.8000000000; data_table[52].feg[1].cnl[1]= 2.5900000000; data_table[52].feg[1].cl[2]= 5.6100000000; data_table[52].feg[1].cnl[2]= 14.1000000000; data_table[52].feg[1].cl[3]=-8.6900000000; data_table[52].feg[1].cnl[3]= 34.4000000000; data_table[52].feg[1].cl[4]= 12.6000000000; data_table[52].feg[1].cnl[4]= 39.5000000000; + data_table[54].feg[2].cl[0]= 0.5870000000; data_table[54].feg[2].cnl[0]= 0.2000000000; data_table[54].feg[2].cl[1]= 1.4000000000; data_table[54].feg[2].cnl[1]= 1.3800000000; data_table[54].feg[2].cl[2]= 1.8700000000; data_table[54].feg[2].cnl[2]= 4.1200000000; data_table[54].feg[2].cl[3]= 3.4800000000; data_table[54].feg[2].cnl[3]= 13.0000000000; data_table[54].feg[2].cl[4]= 1.6700000000; data_table[54].feg[2].cnl[4]= 31.8000000000; + data_table[55].feg[4].cl[0]= 0.7330000000; data_table[55].feg[4].cnl[0]= 0.2580000000; data_table[55].feg[4].cl[1]= 2.0500000000; data_table[55].feg[4].cnl[1]= 1.9600000000; data_table[55].feg[4].cl[2]= 23.0000000000; data_table[55].feg[4].cnl[2]= 11.8000000000; data_table[55].feg[4].cl[3]=-152.0000000000; data_table[55].feg[4].cnl[3]= 14.4000000000; data_table[55].feg[4].cl[4]= 134.0000000000; data_table[55].feg[4].cnl[4]= 14.9000000000; + data_table[56].feg[6].cl[0]= 0.4930000000; data_table[56].feg[6].cnl[0]= 0.1670000000; data_table[56].feg[6].cl[1]= 1.1000000000; data_table[56].feg[6].cnl[1]= 1.1100000000; data_table[56].feg[6].cl[2]= 1.5000000000; data_table[56].feg[6].cnl[2]= 3.1100000000; data_table[56].feg[6].cl[3]= 2.7000000000; data_table[56].feg[6].cnl[3]= 9.6100000000; data_table[56].feg[6].cl[4]= 1.0800000000; data_table[56].feg[6].cnl[4]= 21.2000000000; + data_table[57].feg[6].cl[0]= 0.5600000000; data_table[57].feg[6].cnl[0]= 0.1900000000; data_table[57].feg[6].cl[1]= 1.3500000000; data_table[57].feg[6].cnl[1]= 1.3000000000; data_table[57].feg[6].cl[2]= 1.5900000000; data_table[57].feg[6].cnl[2]= 3.9300000000; data_table[57].feg[6].cl[3]= 2.6300000000; data_table[57].feg[6].cnl[3]= 10.7000000000; data_table[57].feg[6].cl[4]= 0.7060000000; data_table[57].feg[6].cnl[4]= 23.8000000000; + data_table[57].feg[8].cl[0]= 0.4830000000; data_table[57].feg[8].cnl[0]= 0.1650000000; data_table[57].feg[8].cl[1]= 1.0900000000; data_table[57].feg[8].cnl[1]= 1.1000000000; data_table[57].feg[8].cl[2]= 1.3400000000; data_table[57].feg[8].cnl[2]= 3.0200000000; data_table[57].feg[8].cl[3]= 2.4500000000; data_table[57].feg[8].cnl[3]= 8.8500000000; data_table[57].feg[8].cl[4]= 0.7970000000; data_table[57].feg[8].cnl[4]= 18.8000000000; + data_table[58].feg[6].cl[0]= 0.6630000000; data_table[58].feg[6].cnl[0]= 0.2260000000; data_table[58].feg[6].cl[1]= 1.7300000000; data_table[58].feg[6].cnl[1]= 1.6100000000; data_table[58].feg[6].cl[2]= 2.3500000000; data_table[58].feg[6].cnl[2]= 6.3300000000; data_table[58].feg[6].cl[3]= 0.3510000000; data_table[58].feg[6].cnl[3]= 11.0000000000; data_table[58].feg[6].cl[4]= 1.5900000000; data_table[58].feg[6].cnl[4]= 16.9000000000; + data_table[58].feg[8].cl[0]= 0.5210000000; data_table[58].feg[8].cnl[0]= 0.1770000000; data_table[58].feg[8].cl[1]= 1.1900000000; data_table[58].feg[8].cnl[1]= 1.1700000000; data_table[58].feg[8].cl[2]= 1.3300000000; data_table[58].feg[8].cnl[2]= 3.2800000000; data_table[58].feg[8].cl[3]= 2.3600000000; data_table[58].feg[8].cnl[3]= 8.9400000000; data_table[58].feg[8].cl[4]= 0.6900000000; data_table[58].feg[8].cnl[4]= 19.3000000000; + data_table[59].feg[6].cl[0]= 0.5010000000; data_table[59].feg[6].cnl[0]= 0.1620000000; data_table[59].feg[6].cl[1]= 1.1800000000; data_table[59].feg[6].cnl[1]= 1.0800000000; data_table[59].feg[6].cl[2]= 1.4500000000; data_table[59].feg[6].cnl[2]= 3.0600000000; data_table[59].feg[6].cl[3]= 2.5300000000; data_table[59].feg[6].cnl[3]= 8.8000000000; data_table[59].feg[6].cl[4]= 0.9200000000; data_table[59].feg[6].cnl[4]= 19.6000000000; + data_table[60].feg[6].cl[0]= 0.4960000000; data_table[60].feg[6].cnl[0]= 0.1560000000; data_table[60].feg[6].cl[1]= 1.2000000000; data_table[60].feg[6].cnl[1]= 1.0500000000; data_table[60].feg[6].cl[2]= 1.4700000000; data_table[60].feg[6].cnl[2]= 3.0700000000; data_table[60].feg[6].cl[3]= 2.4300000000; data_table[60].feg[6].cnl[3]= 8.5600000000; data_table[60].feg[6].cl[4]= 0.9430000000; data_table[60].feg[6].cnl[4]= 19.2000000000; + data_table[61].feg[6].cl[0]= 0.5180000000; data_table[61].feg[6].cnl[0]= 0.1630000000; data_table[61].feg[6].cl[1]= 1.2400000000; data_table[61].feg[6].cnl[1]= 1.0800000000; data_table[61].feg[6].cl[2]= 1.4300000000; data_table[61].feg[6].cnl[2]= 3.1100000000; data_table[61].feg[6].cl[3]= 2.4000000000; data_table[61].feg[6].cnl[3]= 8.5200000000; data_table[61].feg[6].cl[4]= 0.7810000000; data_table[61].feg[6].cnl[4]= 19.1000000000; + data_table[62].feg[4].cl[0]= 0.6130000000; data_table[62].feg[4].cnl[0]= 0.1900000000; data_table[62].feg[4].cl[1]= 1.5300000000; data_table[62].feg[4].cnl[1]= 1.2700000000; data_table[62].feg[4].cl[2]= 1.8400000000; data_table[62].feg[4].cnl[2]= 4.1800000000; data_table[62].feg[4].cl[3]= 2.4600000000; data_table[62].feg[4].cnl[3]= 10.7000000000; data_table[62].feg[4].cl[4]= 0.7140000000; data_table[62].feg[4].cnl[4]= 26.2000000000; + data_table[62].feg[6].cl[0]= 0.4960000000; data_table[62].feg[6].cnl[0]= 0.1520000000; data_table[62].feg[6].cl[1]= 1.2100000000; data_table[62].feg[6].cnl[1]= 1.0100000000; data_table[62].feg[6].cl[2]= 1.4500000000; data_table[62].feg[6].cnl[2]= 2.9500000000; data_table[62].feg[6].cl[3]= 2.3600000000; data_table[62].feg[6].cnl[3]= 8.1800000000; data_table[62].feg[6].cl[4]= 0.7740000000; data_table[62].feg[6].cnl[4]= 18.5000000000; + data_table[63].feg[6].cl[0]= 0.4900000000; data_table[63].feg[6].cnl[0]= 0.1480000000; data_table[63].feg[6].cl[1]= 1.1900000000; data_table[63].feg[6].cnl[1]= 0.9740000000; data_table[63].feg[6].cl[2]= 1.4200000000; data_table[63].feg[6].cnl[2]= 2.8100000000; data_table[63].feg[6].cl[3]= 2.3000000000; data_table[63].feg[6].cnl[3]= 7.7800000000; data_table[63].feg[6].cl[4]= 0.7950000000; data_table[63].feg[6].cnl[4]= 17.7000000000; + data_table[64].feg[6].cl[0]= 0.5030000000; data_table[64].feg[6].cnl[0]= 0.1500000000; data_table[64].feg[6].cl[1]= 1.2200000000; data_table[64].feg[6].cnl[1]= 0.9820000000; data_table[64].feg[6].cl[2]= 1.4200000000; data_table[64].feg[6].cnl[2]= 2.8600000000; data_table[64].feg[6].cl[3]= 2.2400000000; data_table[64].feg[6].cnl[3]= 7.7700000000; data_table[64].feg[6].cl[4]= 0.7100000000; data_table[64].feg[6].cnl[4]= 17.7000000000; + data_table[65].feg[6].cl[0]= 0.5030000000; data_table[65].feg[6].cnl[0]= 0.1480000000; data_table[65].feg[6].cl[1]= 1.2400000000; data_table[65].feg[6].cnl[1]= 0.9700000000; data_table[65].feg[6].cl[2]= 1.4400000000; data_table[65].feg[6].cnl[2]= 2.8800000000; data_table[65].feg[6].cl[3]= 2.1700000000; data_table[65].feg[6].cnl[3]= 7.7300000000; data_table[65].feg[6].cl[4]= 0.6430000000; data_table[65].feg[6].cnl[4]= 17.6000000000; + data_table[66].feg[6].cl[0]= 0.4560000000; data_table[66].feg[6].cnl[0]= 0.1290000000; data_table[66].feg[6].cl[1]= 1.1700000000; data_table[66].feg[6].cnl[1]= 0.8690000000; data_table[66].feg[6].cl[2]= 1.4300000000; data_table[66].feg[6].cnl[2]= 2.6100000000; data_table[66].feg[6].cl[3]= 2.1500000000; data_table[66].feg[6].cnl[3]= 7.2400000000; data_table[66].feg[6].cl[4]= 0.6920000000; data_table[66].feg[6].cnl[4]= 16.7000000000; + data_table[67].feg[6].cl[0]= 0.5220000000; data_table[67].feg[6].cnl[0]= 0.1500000000; data_table[67].feg[6].cl[1]= 1.2800000000; data_table[67].feg[6].cnl[1]= 0.9640000000; data_table[67].feg[6].cl[2]= 1.4600000000; data_table[67].feg[6].cnl[2]= 2.9300000000; data_table[67].feg[6].cl[3]= 2.0500000000; data_table[67].feg[6].cnl[3]= 7.7200000000; data_table[67].feg[6].cl[4]= 0.5080000000; data_table[67].feg[6].cnl[4]= 17.8000000000; + data_table[68].feg[6].cl[0]= 0.4750000000; data_table[68].feg[6].cnl[0]= 0.1320000000; data_table[68].feg[6].cl[1]= 1.2000000000; data_table[68].feg[6].cnl[1]= 0.8640000000; data_table[68].feg[6].cl[2]= 1.4200000000; data_table[68].feg[6].cnl[2]= 2.6000000000; data_table[68].feg[6].cl[3]= 2.0500000000; data_table[68].feg[6].cnl[3]= 7.0900000000; data_table[68].feg[6].cl[4]= 0.5840000000; data_table[68].feg[6].cnl[4]= 16.6000000000; + data_table[69].feg[4].cl[0]= 0.5080000000; data_table[69].feg[4].cnl[0]= 0.1360000000; data_table[69].feg[4].cl[1]= 1.3700000000; data_table[69].feg[4].cnl[1]= 0.9220000000; data_table[69].feg[4].cl[2]= 1.7600000000; data_table[69].feg[4].cnl[2]= 3.1200000000; data_table[69].feg[4].cl[3]= 2.2300000000; data_table[69].feg[4].cnl[3]= 8.7200000000; data_table[69].feg[4].cl[4]= 0.5840000000; data_table[69].feg[4].cnl[4]= 23.7000000000; + data_table[69].feg[6].cl[0]= 0.4980000000; data_table[69].feg[6].cnl[0]= 0.1380000000; data_table[69].feg[6].cl[1]= 1.2200000000; data_table[69].feg[6].cnl[1]= 0.8810000000; data_table[69].feg[6].cl[2]= 1.3900000000; data_table[69].feg[6].cnl[2]= 2.6300000000; data_table[69].feg[6].cl[3]= 1.9700000000; data_table[69].feg[6].cnl[3]= 6.9900000000; data_table[69].feg[6].cl[4]= 0.5590000000; data_table[69].feg[6].cnl[4]= 16.3000000000; + data_table[70].feg[6].cl[0]= 0.4830000000; data_table[70].feg[6].cnl[0]= 0.1310000000; data_table[70].feg[6].cl[1]= 1.2100000000; data_table[70].feg[6].cnl[1]= 0.8450000000; data_table[70].feg[6].cl[2]= 1.4100000000; data_table[70].feg[6].cnl[2]= 2.5700000000; data_table[70].feg[6].cl[3]= 1.9400000000; data_table[70].feg[6].cnl[3]= 6.8800000000; data_table[70].feg[6].cl[4]= 0.5220000000; data_table[70].feg[6].cnl[4]= 16.2000000000; + data_table[71].feg[8].cl[0]= 0.5220000000; data_table[71].feg[8].cnl[0]= 0.1450000000; data_table[71].feg[8].cl[1]= 1.2200000000; data_table[71].feg[8].cnl[1]= 0.8960000000; data_table[71].feg[8].cl[2]= 1.3700000000; data_table[71].feg[8].cnl[2]= 2.7400000000; data_table[71].feg[8].cl[3]= 1.6800000000; data_table[71].feg[8].cnl[3]= 6.9100000000; data_table[71].feg[8].cl[4]= 0.3120000000; data_table[71].feg[8].cnl[4]= 16.1000000000; + data_table[72].feg[10].cl[0]= 0.5690000000; data_table[72].feg[10].cnl[0]= 0.1610000000; data_table[72].feg[10].cl[1]= 1.2600000000; data_table[72].feg[10].cnl[1]= 0.9720000000; data_table[72].feg[10].cl[2]= 0.9790000000; data_table[72].feg[10].cnl[2]= 2.7600000000; data_table[72].feg[10].cl[3]= 1.2900000000; data_table[72].feg[10].cnl[3]= 5.4000000000; data_table[72].feg[10].cl[4]= 0.5510000000; data_table[72].feg[10].cnl[4]= 10.9000000000; + data_table[73].feg[12].cl[0]= 0.1810000000; data_table[73].feg[12].cnl[0]= 0.0118000000; data_table[73].feg[12].cl[1]= 0.8730000000; data_table[73].feg[12].cnl[1]= 0.4420000000; data_table[73].feg[12].cl[2]= 1.1800000000; data_table[73].feg[12].cnl[2]= 1.5200000000; data_table[73].feg[12].cl[3]= 1.4800000000; data_table[73].feg[12].cnl[3]= 4.3500000000; data_table[73].feg[12].cl[4]= 0.5620000000; data_table[73].feg[12].cnl[4]= 9.4200000000; + data_table[75].feg[8].cl[0]= 0.5860000000; data_table[75].feg[8].cnl[0]= 0.1550000000; data_table[75].feg[8].cl[1]= 1.3100000000; data_table[75].feg[8].cnl[1]= 0.9380000000; data_table[75].feg[8].cl[2]= 1.6300000000; data_table[75].feg[8].cnl[2]= 3.1900000000; data_table[75].feg[8].cl[3]= 1.7100000000; data_table[75].feg[8].cnl[3]= 7.8400000000; data_table[75].feg[8].cl[4]= 0.5400000000; data_table[75].feg[8].cnl[4]= 19.3000000000; + data_table[76].feg[6].cl[0]= 0.6920000000; data_table[76].feg[6].cnl[0]= 0.1820000000; data_table[76].feg[6].cl[1]= 1.3700000000; data_table[76].feg[6].cnl[1]= 1.0400000000; data_table[76].feg[6].cl[2]= 1.8000000000; data_table[76].feg[6].cnl[2]= 3.4700000000; data_table[76].feg[6].cl[3]= 1.9700000000; data_table[76].feg[6].cnl[3]= 8.5100000000; data_table[76].feg[6].cl[4]= 0.8040000000; data_table[76].feg[6].cnl[4]= 21.2000000000; + data_table[76].feg[8].cl[0]= 0.6530000000; data_table[76].feg[8].cnl[0]= 0.1740000000; data_table[76].feg[8].cl[1]= 1.2900000000; data_table[76].feg[8].cnl[1]= 0.9920000000; data_table[76].feg[8].cl[2]= 1.5000000000; data_table[76].feg[8].cnl[2]= 3.1400000000; data_table[76].feg[8].cl[3]= 1.7400000000; data_table[76].feg[8].cnl[3]= 7.2200000000; data_table[76].feg[8].cl[4]= 0.6830000000; data_table[76].feg[8].cnl[4]= 17.2000000000; + data_table[77].feg[4].cl[0]= 0.8720000000; data_table[77].feg[4].cnl[0]= 0.2230000000; data_table[77].feg[4].cl[1]= 1.6800000000; data_table[77].feg[4].cnl[1]= 1.3500000000; data_table[77].feg[4].cl[2]= 2.6300000000; data_table[77].feg[4].cnl[2]= 4.9900000000; data_table[77].feg[4].cl[3]= 1.9300000000; data_table[77].feg[4].cnl[3]= 13.6000000000; data_table[77].feg[4].cl[4]= 0.4750000000; data_table[77].feg[4].cnl[4]= 33.0000000000; + data_table[77].feg[8].cl[0]= 0.5500000000; data_table[77].feg[8].cnl[0]= 0.1420000000; data_table[77].feg[8].cl[1]= 1.2100000000; data_table[77].feg[8].cnl[1]= 0.8330000000; data_table[77].feg[8].cl[2]= 1.6200000000; data_table[77].feg[8].cnl[2]= 2.8100000000; data_table[77].feg[8].cl[3]= 1.9500000000; data_table[77].feg[8].cnl[3]= 7.2100000000; data_table[77].feg[8].cl[4]= 0.6100000000; data_table[77].feg[8].cnl[4]= 17.7000000000; + data_table[78].feg[2].cl[0]= 0.8110000000; data_table[78].feg[2].cnl[0]= 0.2010000000; data_table[78].feg[2].cl[1]= 1.5700000000; data_table[78].feg[2].cnl[1]= 1.1800000000; data_table[78].feg[2].cl[2]= 2.6300000000; data_table[78].feg[2].cnl[2]= 4.2500000000; data_table[78].feg[2].cl[3]= 2.6800000000; data_table[78].feg[2].cnl[3]= 12.1000000000; data_table[78].feg[2].cl[4]= 0.9980000000; data_table[78].feg[2].cnl[4]= 34.4000000000; + data_table[78].feg[6].cl[0]= 0.7220000000; data_table[78].feg[6].cnl[0]= 0.1840000000; data_table[78].feg[6].cl[1]= 1.3900000000; data_table[78].feg[6].cnl[1]= 1.0600000000; data_table[78].feg[6].cl[2]= 1.9400000000; data_table[78].feg[6].cnl[2]= 3.5800000000; data_table[78].feg[6].cl[3]= 1.9400000000; data_table[78].feg[6].cnl[3]= 8.5600000000; data_table[78].feg[6].cl[4]= 0.6990000000; data_table[78].feg[6].cnl[4]= 20.4000000000; + data_table[79].feg[2].cl[0]= 0.7960000000; data_table[79].feg[2].cnl[0]= 0.1940000000; data_table[79].feg[2].cl[1]= 1.5600000000; data_table[79].feg[2].cnl[1]= 1.1400000000; data_table[79].feg[2].cl[2]= 2.7200000000; data_table[79].feg[2].cnl[2]= 4.2100000000; data_table[79].feg[2].cl[3]= 2.7600000000; data_table[79].feg[2].cnl[3]= 12.4000000000; data_table[79].feg[2].cl[4]= 1.1800000000; data_table[79].feg[2].cnl[4]= 36.2000000000; + data_table[79].feg[4].cl[0]= 0.7730000000; data_table[79].feg[4].cnl[0]= 0.1910000000; data_table[79].feg[4].cl[1]= 1.4900000000; data_table[79].feg[4].cnl[1]= 1.1200000000; data_table[79].feg[4].cl[2]= 2.4500000000; data_table[79].feg[4].cnl[2]= 4.0000000000; data_table[79].feg[4].cl[3]= 2.2300000000; data_table[79].feg[4].cnl[3]= 10.8000000000; data_table[79].feg[4].cl[4]= 0.5700000000; data_table[79].feg[4].cnl[4]= 27.6000000000; + data_table[80].feg[2].cl[0]= 0.8200000000; data_table[80].feg[2].cnl[0]= 0.1970000000; data_table[80].feg[2].cl[1]= 1.5700000000; data_table[80].feg[2].cnl[1]= 1.1600000000; data_table[80].feg[2].cl[2]= 2.7800000000; data_table[80].feg[2].cnl[2]= 4.2300000000; data_table[80].feg[2].cl[3]= 2.8200000000; data_table[80].feg[2].cnl[3]= 12.7000000000; data_table[80].feg[2].cl[4]= 1.3100000000; data_table[80].feg[2].cnl[4]= 35.7000000000; + data_table[80].feg[6].cl[0]= 0.8360000000; data_table[80].feg[6].cnl[0]= 0.2080000000; data_table[80].feg[6].cl[1]= 1.4300000000; data_table[80].feg[6].cnl[1]= 1.2000000000; data_table[80].feg[6].cl[2]= 0.3940000000; data_table[80].feg[6].cnl[2]= 2.5700000000; data_table[80].feg[6].cl[3]= 2.5100000000; data_table[80].feg[6].cnl[3]= 4.8600000000; data_table[80].feg[6].cl[4]= 1.5000000000; data_table[80].feg[6].cnl[4]= 13.5000000000; + data_table[81].feg[4].cl[0]= 0.7550000000; data_table[81].feg[4].cnl[0]= 0.1810000000; data_table[81].feg[4].cl[1]= 1.4400000000; data_table[81].feg[4].cnl[1]= 1.0500000000; data_table[81].feg[4].cl[2]= 2.4800000000; data_table[81].feg[4].cnl[2]= 3.7500000000; data_table[81].feg[4].cl[3]= 2.4500000000; data_table[81].feg[4].cnl[3]= 10.6000000000; data_table[81].feg[4].cl[4]= 1.0300000000; data_table[81].feg[4].cnl[4]= 27.9000000000; + data_table[81].feg[8].cl[0]= 0.5830000000; data_table[81].feg[8].cnl[0]= 0.1440000000; data_table[81].feg[8].cl[1]= 1.1400000000; data_table[81].feg[8].cnl[1]= 0.7960000000; data_table[81].feg[8].cl[2]= 1.6000000000; data_table[81].feg[8].cnl[2]= 2.5800000000; data_table[81].feg[8].cl[3]= 2.0600000000; data_table[81].feg[8].cnl[3]= 6.2200000000; data_table[81].feg[8].cl[4]= 0.6620000000; data_table[81].feg[8].cnl[4]= 14.8000000000; + data_table[82].feg[6].cl[0]= 0.7080000000; data_table[82].feg[6].cnl[0]= 0.1700000000; data_table[82].feg[6].cl[1]= 1.3500000000; data_table[82].feg[6].cnl[1]= 0.9810000000; data_table[82].feg[6].cl[2]= 2.2800000000; data_table[82].feg[6].cnl[2]= 3.4400000000; data_table[82].feg[6].cl[3]= 2.1800000000; data_table[82].feg[6].cnl[3]= 9.4100000000; data_table[82].feg[6].cl[4]= 0.7970000000; data_table[82].feg[6].cnl[4]= 23.7000000000; + data_table[82].feg[10].cl[0]= 0.6540000000; data_table[82].feg[10].cnl[0]= 0.1620000000; data_table[82].feg[10].cl[1]= 1.1800000000; data_table[82].feg[10].cnl[1]= 0.9050000000; data_table[82].feg[10].cl[2]= 1.2500000000; data_table[82].feg[10].cnl[2]= 2.6800000000; data_table[82].feg[10].cl[3]= 1.6600000000; data_table[82].feg[10].cnl[3]= 5.1400000000; data_table[82].feg[10].cl[4]= 0.7780000000; data_table[82].feg[10].cnl[4]= 11.2000000000; + data_table[87].feg[4].cl[0]= 0.9110000000; data_table[87].feg[4].cnl[0]= 0.2040000000; data_table[87].feg[4].cl[1]= 1.6500000000; data_table[87].feg[4].cnl[1]= 1.2600000000; data_table[87].feg[4].cl[2]= 2.5300000000; data_table[87].feg[4].cnl[2]= 4.0300000000; data_table[87].feg[4].cl[3]= 3.6200000000; data_table[87].feg[4].cnl[3]= 12.6000000000; data_table[87].feg[4].cl[4]= 1.5800000000; data_table[87].feg[4].cnl[4]= 30.0000000000; + data_table[88].feg[6].cl[0]= 0.9150000000; data_table[88].feg[6].cnl[0]= 0.2050000000; data_table[88].feg[6].cl[1]= 1.6400000000; data_table[88].feg[6].cnl[1]= 1.2800000000; data_table[88].feg[6].cl[2]= 2.2600000000; data_table[88].feg[6].cnl[2]= 3.9200000000; data_table[88].feg[6].cl[3]= 3.1800000000; data_table[88].feg[6].cnl[3]= 11.3000000000; data_table[88].feg[6].cl[4]= 1.2500000000; data_table[88].feg[6].cnl[4]= 25.1000000000; + data_table[91].feg[6].cl[0]= 1.1400000000; data_table[91].feg[6].cnl[0]= 0.2500000000; data_table[91].feg[6].cl[1]= 2.4800000000; data_table[91].feg[6].cnl[1]= 1.8400000000; data_table[91].feg[6].cl[2]= 3.6100000000; data_table[91].feg[6].cnl[2]= 7.3900000000; data_table[91].feg[6].cl[3]= 1.1300000000; data_table[91].feg[6].cnl[3]= 18.0000000000; data_table[91].feg[6].cl[4]= 0.9000000000; data_table[91].feg[6].cnl[4]= 22.7000000000; + data_table[91].feg[8].cl[0]= 1.0900000000; data_table[91].feg[8].cnl[0]= 0.2430000000; data_table[91].feg[8].cl[1]= 2.3200000000; data_table[91].feg[8].cnl[1]= 1.7500000000; data_table[91].feg[8].cl[2]= 12.0000000000; data_table[91].feg[8].cnl[2]= 7.7900000000; data_table[91].feg[8].cl[3]=-9.1100000000; data_table[91].feg[8].cnl[3]= 8.3100000000; data_table[91].feg[8].cl[4]= 2.1500000000; data_table[91].feg[8].cnl[4]= 16.5000000000; + data_table[91].feg[12].cl[0]= 0.6870000000; data_table[91].feg[12].cnl[0]= 0.1540000000; data_table[91].feg[12].cl[1]= 1.1400000000; data_table[91].feg[12].cnl[1]= 0.8610000000; data_table[91].feg[12].cl[2]= 1.8300000000; data_table[91].feg[12].cnl[2]= 2.5800000000; data_table[91].feg[12].cl[3]= 2.5300000000; data_table[91].feg[12].cnl[3]= 7.7000000000; data_table[91].feg[12].cl[4]= 0.9570000000; data_table[91].feg[12].cnl[4]= 15.9000000000; + } + + // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + template + void set_Doyle_Peng_neutral_coef(const int &Z, TPP_Coef &feg, TPP_Coef &fxg, TPP_Coef &Pr, TPP_Coef &Vr, TPP_Coef &VR) + { + int iZ = Z-1; + + for(auto j = 0; j < 5; j++) + { + auto cl = data_table[iZ].feg[0].cl[j]; + auto cnl = (isZero(cl))?0.0:data_table[iZ].feg[0].cnl[j]/4.0; + + if(nonZero(cl, cnl)) + { + feg.cl[j] = cl; + feg.cnl[j] = cnl; + + fxg.cl[j] = c_2Pi2a0*cl; + fxg.cnl[j] = cnl; + + Pr.cl[j] = 0.5*c_2Pi2a0*cl*pow(c_Pi/cnl, 3.5); + Pr.cnl[j] = c_Pi2/cnl; + + Vr.cl[j] = c_Potf*cl*pow(c_Pi/cnl, 1.5); + Vr.cnl[j] = c_Pi2/cnl; + + VR.cl[j] = c_Potf*c_Pi*cl/cnl; + VR.cnl[j] = c_Pi2/cnl; + } + } + } + + // 4: Kirkland parameterization - 3 Yukawa + 3 Gaussians - [0, 12] + template + void set_Kirkland_neutral_coef(const int &Z, TPP_Coef &feg, TPP_Coef &fxg, TPP_Coef &Pr, TPP_Coef &Vr, TPP_Coef &VR) + { + int iZ = Z-1; + + for(auto j = 0; j < 3; j++) + { + auto cl = data_table[iZ].feg[0].cl[j]; + auto cnl = (isZero(cl))?0.0:data_table[iZ].feg[0].cnl[j]; + + if(nonZero(cl, cnl)) + { + feg.cl[j] = cl; + feg.cnl[j] = cnl; + + fxg.cl[j] = c_2Pi2a0*cl; + fxg.cnl[j] = cnl; + + Pr.cl[j] = c_2Pi2a0*c_Pi*cl*cnl; + Pr.cnl[j] = c_2Pi*sqrt(cnl); + + Vr.cl[j] = c_Potf*c_Pi*cl; + Vr.cnl[j] = c_2Pi*sqrt(cnl); + + VR.cl[j] = c_Potf*c_2Pi*cl; + VR.cnl[j] = c_2Pi*sqrt(cnl); + } + } + + for(auto j = 3; j < 6; j++) + { + auto cl = data_table[iZ].feg[0].cl[j]; + auto cnl = (isZero(cl))?0.0:data_table[iZ].feg[0].cnl[j]; + + if(nonZero(cl, cnl)) + { + feg.cl[j] = cl; + feg.cnl[j] = cnl; + + fxg.cl[j] = c_2Pi2a0*cl; + fxg.cnl[j] = cnl; + + Pr.cl[j] = 0.5*c_2Pi2a0*cl*pow(c_Pi/cnl, 3.5); + Pr.cnl[j] = c_Pi2/cnl; + + Vr.cl[j] = c_Potf*cl*pow(c_Pi/cnl, 1.5); + Vr.cnl[j] = c_Pi2/cnl; + + VR.cl[j] = c_Potf*c_Pi*cl/cnl; + VR.cnl[j] = c_Pi2/cnl; + } + } + } + + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + template + void set_Weickenmeier_neutral_coef(const int &Z, TPP_Coef &feg, TPP_Coef &fxg, TPP_Coef &Pr, TPP_Coef &Vr, TPP_Coef &VR) + { + int iZ = Z-1; + + for(auto j = 0; j < 6; j++) + { + // 1.0/c_2Pi2a0 = 4.0*0.0239336609991378 + auto cl = Z/(c_2Pi2a0*3.0*(1.0+data_table[iZ].feg[0].cl[j])); + cl *= (j>= 3)?data_table[iZ].feg[0].cl[j]:1; + auto cnl = (isZero(cl))?0.0:data_table[iZ].feg[0].cnl[j]/4.0; + cl = (isZero(cnl))?0.0:cl; + + if(nonZero(cl, cnl)) + { + feg.cl[j] = cl; + feg.cnl[j] = cnl; + + fxg.cl[j] = c_2Pi2a0*cl; + fxg.cnl[j] = cnl; + + Pr.cl[j] = c_2Pi2a0*cl*pow(c_Pi/cnl, 1.5); + Pr.cnl[j] = c_Pi2/cnl; + + Vr.cl[j] = c_Potf*c_Pi*cl; + Vr.cnl[j] = c_Pi/sqrt(cnl); + + // there is not analytic expression for the projected potential + VR.cl[j] = Vr.cl[j]; + VR.cnl[j] = Vr.cnl[j]; + } + } + } + + // 6: Lobato parameterization - Hydrogen functions - [0, 12] + template + void set_Lobato_neutral_coef(const int &Z, TPP_Coef &feg, TPP_Coef &fxg, TPP_Coef &Pr, TPP_Coef &Vr, TPP_Coef &VR) + { + int iZ = Z-1; + + for(auto j = 0; j < 6; j++) + { + auto cl = data_table[iZ].feg[0].cl[j]; + auto cnl = (isZero(cl))?0.0:data_table[iZ].feg[0].cnl[j]; + + if(nonZero(cl, cnl)) + { + feg.cl[j] = cl; + feg.cnl[j] = cnl; + + fxg.cl[j] = c_2Pi2a0*cl/cnl; + fxg.cnl[j] = cnl; + + Pr.cl[j] = c_2Pi2a0*c_Pi2*cl/pow(cnl, 2.5); + Pr.cnl[j] = c_2Pi/sqrt(cnl); + + Vr.cl[j] = c_Potf*c_Pi2*cl/pow(cnl, 1.5); + Vr.cnl[j] = c_2Pi/sqrt(cnl); + + VR.cl[j] = 2.0*c_Potf*c_Pi2*cl/pow(cnl, 1.5); + VR.cnl[j] = c_2Pi/sqrt(cnl); + } + } + } + + // Peng et al. parameterization for ions - 5 Gaussians - [0, 4] + template + void set_Peng_ions_coef(const int &Z, const int &charge, TPP_Coef &feg, TPP_Coef &fxg, TPP_Coef &Pr, TPP_Coef &Vr, TPP_Coef &VR) + { + using T = Value_type; + + int iZ = Z-1; + int icharge = (charge>= 0)?(2*charge):(-2*charge-1); + + for(auto j = 0; j < 5; j++) + { + auto cl = data_table[iZ].feg[icharge].cl[j]; + auto cnl = (isZero(cl))?0.0:data_table[iZ].feg[icharge].cnl[j]/4.0; + + if(nonZero(cl, cnl)) + { + feg.cl[j] = cl; + feg.cnl[j] = cnl; + + fxg.cl[j] = c_2Pi2a0*cl; + fxg.cnl[j] = cnl; + + Pr.cl[j] = 0.5*c_2Pi2a0*cl*pow(c_Pi/cnl, 3.5); + Pr.cnl[j] = c_Pi2/cnl; + + Vr.cl[j] = c_Potf*cl*pow(c_Pi/cnl, 1.5); + Vr.cnl[j] = c_Pi2/cnl; + + VR.cl[j] = c_Potf*c_Pi*cl/cnl; + VR.cnl[j] = c_Pi2/cnl; + } + } + + // 1/g2 + if(nonZero(feg.cl[0])) + { + int j = 5; + T r0 = 2.0; + auto cl = charge/c_2Pi2a0; + auto cnl = pow(c_2Pi*r0, -2); + + feg.cl[j] = cl; + feg.cnl[j] = cnl; + + fxg.cl[j] = c_2Pi2a0*cl; + fxg.cnl[j] = cnl; + + Pr.cl[j] = c_2Pi2a0*c_Pi*cl*cnl; + Pr.cnl[j] = c_2Pi*sqrt(cnl); + + Vr.cl[j] = c_Potf*c_Pi*cl; + Vr.cnl[j] = c_2Pi*sqrt(cnl); + + VR.cl[j] = c_Potf*c_2Pi*cl; + VR.cnl[j] = c_2Pi*sqrt(cnl); + } + } + + // get Coefficients + template + void get_atom_coef(int Z, double Vrl, int nR, double R_min, TAtom_Type &atom_type) + { + using T = Value_type; + + for(auto i = 0; i < c_feg.size(); i++) + { + c_feg[i].fill(0); + c_fxg[i].fill(0); + c_Pr[i].fill(0); + c_Vr[i].fill(0); + c_VR[i].fill(0); + } + + if(static_cast(potential_type) <= 3) + { + // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + set_Doyle_Peng_neutral_coef(Z, c_feg[0], c_fxg[0], c_Pr[0], c_Vr[0], c_VR[0]); + } + else if(potential_type == ePT_Kirkland_0_12) + { + // 4: Kirkland parameterization - 3 Yukawa + 3 Gaussians - [0, 12] + set_Kirkland_neutral_coef(Z, c_feg[0], c_fxg[0], c_Pr[0], c_Vr[0], c_VR[0]); + } + else if(potential_type == ePT_Weickenmeier_0_12) + { + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + set_Weickenmeier_neutral_coef(Z, c_feg[0], c_fxg[0], c_Pr[0], c_Vr[0], c_VR[0]); + } + else if(potential_type == ePT_Lobato_0_12) + { + // 6: Lobato parameterization - Hydrogen functions - [0, 12] + set_Lobato_neutral_coef(Z, c_feg[0], c_fxg[0], c_Pr[0], c_Vr[0], c_VR[0]); + } + + auto from_idx_to_charge = [](const int &i)->int{return ((i%2 == 0)?1:-1)*((i+1)/2); }; + + // Peng et al. parameterizationfor ions - 5 Gaussians - [0, 4] + int ncoef = 1; + for(auto i = 1; i < c_feg.size(); i++) + { + auto charge = from_idx_to_charge(i); + set_Peng_ions_coef(Z, charge, c_feg[i], c_fxg[i], c_Pr[i], c_Vr[i], c_VR[i]); + ncoef += (nonZero(c_feg[i].cl[0]))?1:0; + } + + // copy all coefficients + atom_type.coef.resize(ncoef); + int icoef = 0; + for(auto i = 0; i < c_feg.size(); i++) + { + if((i == 0) || nonZero(c_feg[i].cl[0])) + { + auto &coef = atom_type.coef[icoef++]; + coef.charge = from_idx_to_charge(i); + + coef.feg.assign(c_feg[i]); + coef.fxg.assign(c_fxg[i]); + coef.Pr.assign(c_Pr[i]); + coef.Vr.assign(c_Vr[i]); + coef.VR.assign(c_VR[i]); + + coef.R_min = R_min; + c_atom_cal.Set_Atom_Type(potential_type, coef.charge, &atom_type); + coef.R_max = (coef.charge == 0)?c_atom_cal.AtomicRadius_Cutoff(3, Vrl):atom_type.coef[0].R_max; + if(isZero(coef.R_max)) + { + coef.R_max = 1.75*atom_type.ra_e; + } + + coef.R_tap = 0.85*coef.R_max; + coef.tap_cf = c_i2Pi/(coef.R2_max()-coef.R2_tap()); + + // R and R2 + coef.R.resize(nR); + coef.R2.resize(nR); + T dlnr = log(coef.R_max/coef.R_min)/T(nR-1); + for(auto iR = 0; iR < nR; iR++) + { + coef.R[iR] = coef.R_min*exp(iR*dlnr); + coef.R2[iR] = pow(coef.R[iR], 2); + } + + Vector VR(nR); + Vector dVR(nR); + + c_atom_cal.Set_Atom_Type(potential_type, coef.charge, &atom_type); + c_atom_cal.VR_dVR(nR, coef.R.data(), VR.data(), dVR.data()); + + auto x_tap = coef.R2_tap(); + auto tap_cf = coef.tap_cf; + coef.ciVR.resize(nR); + for(auto iR = 0; iR < nR; iR++) + { + auto x = coef.R2[iR]; + auto y = VR[iR]; + auto dy = 0.5*dVR[iR]/coef.R[iR]; + host_device_detail::apply_tapering(x_tap, tap_cf, x, y, dy); + + coef.ciVR.c0[iR] = y; + coef.ciVR.c1[iR] = dy; + } + + for(auto iR = 0; iR < nR-1; iR++) + { + T idR = 1.0/(coef.R2[iR+1]-coef.R2[iR]); + T V = coef.ciVR.c0[iR]; + T Vn = coef.ciVR.c0[iR+1]; + T dV = coef.ciVR.c1[iR]; + T dVn = coef.ciVR.c1[iR+1]; + T m = (Vn-V)*idR; + T n = dV+dVn; + coef.ciVR.c2[iR] = (3.0*m-n-dV)*idR; + coef.ciVR.c3[iR] = (n-2.0*m)*idR*idR; + } + } + } + } + + ePotential_Type potential_type; + Vector data_table; + + Vector, e_host> c_feg; + Vector, e_host> c_fxg; + Vector, e_host> c_Pr; + Vector, e_host> c_Vr; + Vector, e_host> c_VR; + + Atom_Cal c_atom_cal; + Atom_Type c_atom_type; + }; + +} // namespace mt +#endif \ No newline at end of file diff --git a/src - Copy (2)/atomic_data_mt.cuh b/src - Copy (2)/atomic_data_mt.cuh new file mode 100755 index 00000000..80d3210b --- /dev/null +++ b/src - Copy (2)/atomic_data_mt.cuh @@ -0,0 +1,2857 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ATOMIC_DATA_MT_H + #define ATOMIC_DATA_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "const_enum_mt.cuh" + #include "cgpu_fcns_gen.cuh" + #include "intrpl_coef.cuh" + + namespace mt + { + /************************* atomic coefficients ***********************/ + template + class Atomic_Coef + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + eAtomic_Pot_Parm_Typ atomic_pot_parm_typ; // feg parameterization + dt_int32 Z; // atomic number + dt_int32 charge; // charge + + mutable LNL_Coef feg; // electron scattering factor coefficients + mutable LNL_Coef fxg; // x-ray scattering factor coefficients + mutable LNL_Coef pr; // electron density coefficients + mutable LNL_Coef vr; // potential coefficients + mutable LNL_Coef vzp; // projected potential coefficients + + /************************************* constructors ************************************/ + Atomic_Coef():atomic_pot_parm_typ(eappt_lobato_0_12), Z(0), charge(0) {} + + Atomic_Coef(const size_type& new_size): Atomic_Coef() + { + resize(new_size); + } + + Atomic_Coef(const size_type& new_size, const T& value): Atomic_Coef() + { + resize(new_size, value); + } + + /* copy constructor */ + Atomic_Coef(const Atomic_Coef& atomic_coef): Atomic_Coef() + { + *this = atomic_coef; + } + + /* converting constructor */ + template + Atomic_Coef(const Atomic_Coef& atomic_coef) + { + *this = atomic_coef; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Atomic_Coef& operator=(const Atomic_Coef& atomic_coef) + { + this->assign(atomic_coef); + + return *this; + } + + /* converting assignment operator */ + template + Atomic_Coef& operator=(const Atomic_Coef& atomic_coef) + { + this->assign(atomic_coef); + + return *this; + } + + template + void assign(const Atomic_Coef& atomic_coef) + { + atomic_pot_parm_typ = atomic_coef.atomic_pot_parm_typ; + Z = atomic_coef.Z; + charge = atomic_coef.charge; + + feg.assign(atomic_coef.feg); + fxg.assign(atomic_coef.fxg); + pr.assign(atomic_coef.pr); + vr.assign(atomic_coef.vr); + vzp.assign(atomic_coef.vzp); + } + + void fill(const T& val) + { + feg.fill(val); + fxg.fill(val); + pr.fill(val); + vr.fill(val); + vzp.fill(val); + } + + size_type size() const + { + return size_type(feg.size()); + } + + template + ST size() const + { + return static_cast(feg.size()); + } + + void clear() + { + atomic_pot_parm_typ = eappt_lobato_0_12; + Z = 0; + charge = 0; + + feg.clear(); + fxg.clear(); + pr.clear(); + vr.clear(); + vzp.clear(); + } + + void resize(const size_type& new_size) + { + feg.resize(new_size); + fxg.resize(new_size); + pr.resize(new_size); + vr.resize(new_size); + vzp.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + feg.resize(new_size, value); + fxg.resize(new_size, value); + pr.resize(new_size, value); + vr.resize(new_size, value); + vzp.resize(new_size, value); + } + + void shrink_to_fit() + { + feg.shrink_to_fit(); + fxg.shrink_to_fit(); + pr.shrink_to_fit(); + vr.shrink_to_fit(); + vzp.shrink_to_fit(); + } + + T Z_diff() + { + return T(Z - charge); + } + }; + + template + using Atomic_Coef_cpu = Atomic_Coef; + + template + using Atomic_Coef_gpu = Atomic_Coef; + + /*************************** atomic info *****************************/ + template + class Atomic_Info + { + public: + using value_type = T; + using size_type = dt_int32; + + std::string name; // atom name + dt_int32 Z; // atomic number + dt_int32 A; // mass number + T m; // atomic mass + T rn; // experimental nuclear radius (Angs.) + T ra; // experimental atomic radius (Angs.) + + mutable Vctr_cpu eels_maj_edg; // major eels edges + mutable Vctr_cpu eels_min_edg; // minor eels edges + mutable Vctr_cpu> coef; // atomic coefficients + + /************************************* constructors ************************************/ + Atomic_Info(): name(""), Z(0), A(0), m(0), rn(0), ra(0){} + + Atomic_Info(const std::string& name, const dt_int32& Z, const dt_int32& A, const T& m, + const T& rn, const T& ra): name(name), Z(Z), A(A), m(m), rn(rn), ra(ra) {} + + Atomic_Info(const std::string& name, const dt_int32& Z, const dt_int32& A, const T& m, + const T& rn, const T& ra, const dt_init_list_f64& eels_maj_edg, const dt_init_list_f64& eels_min_edg): Atomic_Info(name, Z, A, m, rn, ra) + { + this->eels_maj_edg.assign(eels_maj_edg.begin(), eels_maj_edg.end()); + this->eels_min_edg.assign(eels_min_edg.begin(), eels_min_edg.end()); + } + + /* copy constructor */ + Atomic_Info(const Atomic_Info& atomic_info) + { + *this = atomic_info; + } + + /* converting constructor */ + template + Atomic_Info(const Atomic_Info& atomic_info) + { + *this = atomic_info; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Atomic_Info& operator=(const Atomic_Info& atomic_info) + { + if (this != &atomic_info) + { + this->assign(atomic_info); + } + + return *this; + } + + /* converting assignment operator */ + template + Atomic_Info& operator=(const Atomic_Info& atomic_info) + { + this->assign(atomic_info); + + return *this; + } + + template + void assign(const Atomic_Info& atomic_info) + { + name = atomic_info.name; + Z = atomic_info.Z; + A = atomic_info.A; + m = T(atomic_info.m); + rn = T(atomic_info.rn); + ra = T(atomic_info.ra); + + eels_maj_edg.assign(atomic_info.eels_maj_edg); + eels_min_edg.assign(atomic_info.eels_min_edg); + + coef.resize(atomic_info.coef.size()); + for(auto ik = 0; ik < atomic_info.coef.size(); ik++) + { + coef[ik].assign(atomic_info.coef[ik]); + } + + } + + template + void add_atomic_coef(const Atomic_Coef_cpu& atomic_coef) + { + if (atomic_coef.size()==0) + { + return; + } + coef.resize(coef.size()+1); + coef.back() = atomic_coef; + } + + T Z_r() + { + return T(Z); + } + + int mass_number() const + { + return A; + } + + T atomic_mass() const + { + return m; + } + + T nuclear_radius() const + { + return rn; + } + + T atomic_radius() const + { + return ra; + } + + T nuclear_radius_cal() const + { + return 1.2e-05*pow(T(A), T(1.0/3.0)); + } + }; + + template + using Atomic_Info_cpu = Atomic_Info; + + template + using Atomic_Info_gpu = Atomic_Info; + + /**************************** atomic data ****************************/ + class Atomic_Data{ + public: + using T = double; + using value_type = T; + using size_type = dt_int32; + static const eDev device = edev_cpu; + + Atomic_Data() {} + + Atomic_Data(const dt_int32& Z) + { + atomic_info = operator()(Z); + } + + Atomic_Data(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, dt_int32 charge=0) + { + atomic_info = operator()(Z, atomic_pot_parm_typ, charge); + } + + Atomic_Data(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const Vctr_int32_cpu& charge) + { + atomic_info = operator()(Z, atomic_pot_parm_typ, charge); + } + + // conversion operator + operator Atomic_Info_cpu() const + { + return atomic_info; + } + + // conversion operator + operator Atomic_Info_cpu() const + { + return atomic_info; + } + + // get atomic info + Atomic_Info_cpu operator()(const dt_int32& Z) + { + return operator()(Z, eappt_lobato_0_12); + } + + // get atomic info + Atomic_Info_cpu operator()(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, dt_int32 charge=0) + { + auto atomic_info = load_atomic_info_1(Z); + + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_doyle_neutral_0_4(Z)); + } + break; + case eappt_peng_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_4(Z)); + } + break; + case eappt_peng_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_12(Z)); + } + break; + case eappt_kirkland_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_kirkland_neutral_0_12(Z)); + } + break; + case eappt_weickenmeier_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_weickenmeier_neutral_0_12(Z)); + } + break; + case eappt_lobato_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_lobato_neutral_0_12(Z)); + } + break; + case eappt_peng_ion_0_4: + { + auto atomic_coef = atomic_coef_peng_ion_0_4(Z, charge); + + if (atomic_coef.size()==0) + { + atomic_coef = atomic_coef_peng_neutral_0_4(Z); + } + + atomic_info.add_atomic_coef(atomic_coef); + } + break; + } + + return atomic_info; + } + + // get atomic info + Atomic_Info_cpu operator()(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const Vctr_int32_cpu& charge) + { + auto atomic_info = load_atomic_info_1(Z); + + for(auto ik=0; ik < charge.size(); ik++) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_doyle_neutral_0_4(Z)); + } + break; + case eappt_peng_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_4(Z)); + } + break; + case eappt_peng_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_12(Z)); + } + break; + case eappt_kirkland_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_kirkland_neutral_0_12(Z)); + } + break; + case eappt_weickenmeier_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_weickenmeier_neutral_0_12(Z)); + } + break; + case eappt_lobato_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_lobato_neutral_0_12(Z)); + } + break; + case eappt_peng_ion_0_4: + { + auto atomic_coef = atomic_coef_peng_ion_0_4(Z, charge[ik]); + + if (atomic_coef.size()==0) + { + atomic_coef = atomic_coef_peng_neutral_0_4(Z); + } + + atomic_info.add_atomic_coef(atomic_coef); + } + break; + } + } + + return atomic_info; + } + + private: + Atomic_Info_cpu atomic_info; + + /***************************************************************************************/ + // load atomic info + Atomic_Info_cpu load_atomic_info_1(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {"H", 1, 1, 1.0080e+00, 8.7770e-06, 7.9000e-01, {13.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 2: + return {"He", 2, 4, 4.0026e+00, 1.6753e-05, 4.9000e-01, {22.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 3: + return {"Li", 3, 7, 6.9410e+00, 2.4173e-05, 2.0500e+00, {55.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 4: + return {"Be", 4, 9, 9.0122e+00, 2.5180e-05, 1.4000e+00, {111.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 5: + return {"B", 5, 11, 1.0811e+01, 2.4060e-05, 1.1700e+00, {188.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 6: + return {"C", 6, 12, 1.2011e+01, 2.4702e-05, 9.1000e-01, {284.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 7: + return {"N", 7, 14, 1.4007e+01, 2.5582e-05, 7.5000e-01, {401.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 8: + return {"O", 8, 16, 1.5999e+01, 2.6991e-05, 6.5000e-01, {532.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 9: + return {"F", 9, 19, 1.8998e+01, 2.8976e-05, 5.7000e-01, {685.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 10: + return {"Ne", 10, 20, 2.0180e+01, 3.0058e-05, 5.1000e-01, {867.00, 18.00, 0.00, 0.00, 0.00}, {45.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 11: + return {"Na", 11, 23, 2.2990e+01, 2.9935e-05, 2.2300e+00, {1072.00, 31.00, 0.00, 0.00, 0.00}, {63.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 12: + return {"Mg", 12, 24, 2.4305e+01, 3.0570e-05, 1.7200e+00, {1305.00, 51.00, 0.00, 0.00, 0.00}, {89.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 13: + return {"Al", 13, 27, 2.6982e+01, 3.0610e-05, 1.6200e+00, {1560.00, 73.00, 0.00, 0.00, 0.00}, {118.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 14: + return {"Si", 14, 28, 2.8085e+01, 3.1224e-05, 1.4400e+00, {1839.00, 99.00, 0.00, 0.00, 0.00}, {149.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 15: + return {"P", 15, 31, 3.0974e+01, 3.1889e-05, 1.2300e+00, {2146.00, 132.00, 0.00, 0.00, 0.00}, {189.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 16: + return {"S", 16, 32, 3.2066e+01, 3.2847e-05, 1.0900e+00, {2472.00, 165.00, 0.00, 0.00, 0.00}, {229.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 17: + return {"Cl", 17, 35, 3.5453e+01, 3.3654e-05, 9.7000e-01, {2822.00, 200.00, 0.00, 0.00, 0.00}, {270.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 18: + return {"Ar", 18, 40, 3.9948e+01, 3.4276e-05, 8.8000e-01, {3203.00, 245.00, 12.00, 0.00, 0.00}, {320.00, 25.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 19: + return {"K", 19, 39, 3.9098e+01, 3.4350e-05, 2.7700e+00, {3607.00, 296.00, 294.00, 18.00, 0.00}, {377.00, 34.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 20: + return {"Ca", 20, 40, 4.0078e+01, 3.4777e-05, 2.2300e+00, {4038.00, 350.00, 346.00, 25.00, 0.00}, {438.00, 44.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 21: + return {"Sc", 21, 45, 4.4956e+01, 3.5460e-05, 2.0900e+00, {4493.00, 407.00, 402.00, 32.00, 0.00}, {500.00, 54.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 22: + return {"Ti", 22, 48, 4.7880e+01, 3.5922e-05, 2.0000e+00, {4966.00, 462.00, 456.00, 35.00, 0.00}, {564.00, 60.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 23: + return {"V", 23, 51, 5.0941e+01, 3.6002e-05, 1.9200e+00, {521.00, 513.00, 38.00, 0.00, 0.00}, {628.00, 66.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 24: + return {"Cr", 24, 52, 5.1996e+01, 3.6452e-05, 1.8500e+00, {584.00, 575.00, 42.00, 0.00, 0.00}, {695.00, 74.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 25: + return {"Mn", 25, 55, 5.4938e+01, 3.7057e-05, 1.7900e+00, {651.00, 640.00, 49.00, 0.00, 0.00}, {769.00, 84.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 26: + return {"Fe", 26, 56, 5.5847e+01, 3.7384e-05, 1.7200e+00, {721.00, 708.00, 54.00, 0.00, 0.00}, {846.00, 93.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 27: + return {"Co", 27, 59, 5.8933e+01, 3.7875e-05, 1.6700e+00, {794.00, 779.00, 60.00, 0.00, 0.00}, {926.00, 101.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 28: + return {"Ni", 28, 58, 5.8693e+01, 3.7757e-05, 1.6200e+00, {872.00, 855.00, 68.00, 0.00, 0.00}, {1008.00, 112.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 29: + return {"Cu", 29, 63, 6.3456e+01, 3.8823e-05, 1.5700e+00, {951.00, 931.00, 74.00, 0.00, 0.00}, {1096.00, 120.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 30: + return {"Zn", 30, 64, 6.5390e+01, 3.9279e-05, 1.5300e+00, {1043.00, 1020.00, 0.00, 0.00, 0.00}, {1194.00, 136.00, 87.00, 0.00, 0.00, 0.00, 0.00}}; + case 31: + return {"Ga", 31, 69, 6.9723e+01, 3.9973e-05, 1.8100e+00, {1142.00, 1115.00, 0.00, 0.00, 0.00}, {1298.00, 158.00, 103.00, 0.00, 0.00, 0.00, 0.00}}; + case 32: + return {"Ge", 32, 74, 7.2610e+01, 4.0742e-05, 1.5200e+00, {1248.00, 1217.00, 29.00, 0.00, 0.00}, {1414.00, 180.00, 121.00, 0.00, 0.00, 0.00, 0.00}}; + case 33: + return {"As", 33, 75, 7.4922e+01, 4.0968e-05, 1.3300e+00, {1359.00, 1323.00, 41.00, 0.00, 0.00}, {1526.00, 203.00, 140.00, 0.00, 0.00, 0.00, 0.00}}; + case 34: + return {"Se", 34, 80, 7.8960e+01, 4.1400e-05, 1.2200e+00, {1476.00, 1436.00, 57.00, 0.00, 0.00}, {1654.00, 231.00, 162.00, 0.00, 0.00, 0.00, 0.00}}; + case 35: + return {"Br", 35, 79, 7.9904e+01, 4.1629e-05, 1.1200e+00, {1596.00, 1150.00, 69.00, 0.00, 0.00}, {1782.00, 256.00, 181.00, 0.00, 0.00, 0.00, 0.00}}; + case 36: + return {"Kr", 36, 84, 8.3800e+01, 4.1883e-05, 1.0300e+00, {1727.00, 1675.00, 89.00, 11.00, 0.00}, {1921.00, 289.00, 214.00, 24.00, 0.00, 0.00, 0.00}}; + case 37: + return {"Rb", 37, 85, 8.5468e+01, 4.2037e-05, 2.9800e+00, {1864.00, 1804.00, 110.00, 14.00, 0.00}, {2065.00, 322.00, 247.00, 238.00, 29.00, 0.00, 0.00}}; + case 38: + return {"Sr", 38, 88, 8.7620e+01, 4.2246e-05, 2.4500e+00, {2007.00, 1940.00, 133.00, 20.00, 0.00}, {2216.00, 357.00, 280.00, 269.00, 38.00, 0.00, 0.00}}; + case 39: + return {"Y", 39, 89, 8.8906e+01, 4.2438e-05, 2.2700e+00, {2155.00, 2080.00, 157.00, 26.00, 0.00}, {2372.00, 394.00, 312.00, 300.00, 45.00, 0.00, 0.00}}; + case 40: + return {"Zr", 40, 90, 9.1224e+01, 4.2690e-05, 2.1600e+00, {2307.00, 2222.00, 180.00, 29.00, 0.00}, {2532.00, 430.00, 344.00, 330.00, 51.00, 0.00, 0.00}}; + case 41: + return {"Nb", 41, 93, 9.2906e+01, 4.3240e-05, 2.0800e+00, {2465.00, 2371.00, 205.00, 34.00, 0.00}, {2698.00, 468.00, 378.00, 363.00, 58.00, 0.00, 0.00}}; + case 42: + return {"Mo", 42, 98, 9.5940e+01, 4.4090e-05, 2.0100e+00, {2625.00, 2520.00, 227.00, 35.00, 0.00}, {2865.00, 505.00, 410.00, 392.00, 62.00, 0.00, 0.00}}; + case 43: + return {"Tc", 43, 98, 9.8000e+01, 4.4130e-05, 1.9500e+00, {2793.00, 2677.00, 253.00, 39.00, 0.00}, {3042.00, 544.00, 445.00, 425.00, 68.00, 0.00, 0.00}}; + case 44: + return {"Ru", 44, 102, 1.0107e+02, 4.4811e-05, 1.8900e+00, {2967.00, 2838.00, 279.00, 43.00, 0.00}, {3224.00, 585.00, 483.00, 461.00, 75.00, 0.00, 0.00}}; + case 45: + return {"Rh", 45, 103, 1.0291e+02, 4.4945e-05, 1.8300e+00, {3146.00, 3004.00, 307.00, 48.00, 0.00}, {3412.00, 627.00, 521.00, 496.00, 81.00, 0.00, 0.00}}; + case 46: + return {"Pd", 46, 106, 1.0642e+02, 4.5324e-05, 1.7900e+00, {3330.00, 3173.00, 335.00, 51.00, 0.00}, {3604.00, 670.00, 559.00, 531.00, 86.00, 0.00, 0.00}}; + case 47: + return {"Ag", 47, 107, 1.0787e+02, 4.5464e-05, 1.7500e+00, {3524.00, 3351.00, 367.00, 0.00, 0.00}, {3806.00, 717.00, 602.00, 571.00, 95.00, 56.00, 0.00}}; + case 48: + return {"Cd", 48, 114, 1.1241e+02, 4.6068e-05, 1.7100e+00, {3727.00, 3538.00, 404.00, 0.00, 0.00}, {4018.00, 770.00, 651.00, 616.00, 108.00, 67.00, 0.00}}; + case 49: + return {"In", 49, 115, 1.1482e+02, 4.6155e-05, 2.0000e+00, {3938.00, 3730.00, 443.00, 0.00, 0.00}, {4237.00, 826.00, 702.00, 664.00, 122.00, 77.00, 0.00}}; + case 50: + return {"Sn", 50, 120, 1.1871e+02, 4.6525e-05, 1.7200e+00, {4156.00, 3929.00, 485.00, 24.00, 0.00}, {4465.00, 884.00, 756.00, 714.00, 136.00, 89.00, 0.00}}; + case 51: + return {"Sb", 51, 121, 1.2176e+02, 4.6802e-05, 1.5300e+00, {4380.00, 4132.00, 528.00, 31.00, 0.00}, {944.00, 812.00, 766.00, 152.00, 98.00, 0.00, 0.00}}; + case 52: + return {"Te", 52, 130, 1.2760e+02, 4.7420e-05, 1.4200e+00, {4612.00, 4341.00, 40.00, 572.00, 0.00}, {1006.00, 870.00, 819.00, 168.00, 110.00, 0.00, 0.00}}; + case 53: + return {"I", 53, 127, 1.2690e+02, 4.7500e-05, 1.3200e+00, {4852.00, 4557.00, 619.00, 50.00, 0.00}, {1072.00, 930.00, 875.00, 186.00, 123.00, 0.00, 0.00}}; + case 54: + return {"Xe", 54, 132, 1.3129e+02, 4.7850e-05, 1.2400e+00, {4782.00, 672.00, 63.00, 0.00, 0.00}, {1145.00, 999.00, 937.00, 208.00, 147.00, 0.00, 0.00}}; + case 55: + return {"Cs", 55, 133, 1.3291e+02, 4.8040e-05, 3.3400e+00, {740.00, 726.00, 76.00, 0.00, 0.00}, {1217.00, 1065.00, 998.00, 231.00, 162.00, 0.00, 0.00}}; + case 56: + return {"Ba", 56, 138, 1.3733e+02, 4.8370e-05, 2.7600e+00, {796.00, 781.00, 90.00, 15.00, 0.00}, {1293.00, 1137.00, 1062.00, 253.00, 180.00, 0.00, 0.00}}; + case 57: + return {"La", 57, 139, 1.3891e+02, 4.8549e-05, 2.7400e+00, {849.00, 832.00, 99.00, 14.00, 0.00}, {1361.00, 1204.00, 1123.00, 270.00, 191.00, 0.00, 0.00}}; + case 58: + return {"Ce", 58, 140, 1.4012e+02, 4.8773e-05, 2.7000e+00, {901.00, 883.00, 110.00, 20.00, 0.00}, {1435.00, 1273.00, 1185.00, 290.00, 207.00, 0.00, 0.00}}; + case 59: + return {"Pr", 59, 141, 1.4091e+02, 4.8919e-05, 2.6700e+00, {951.00, 931.00, 113.00, 22.00, 0.00}, {1511.00, 1337.00, 1242.00, 305.00, 218.00, 0.00, 0.00}}; + case 60: + return {"Nd", 60, 142, 1.4424e+02, 4.9115e-05, 2.6400e+00, {1000.00, 978.00, 118.00, 21.00, 0.00}, {1575.00, 1403.00, 1297.00, 315.00, 225.00, 0.00, 0.00}}; + case 61: + return {"Pm", 61, 145, 1.4500e+02, 4.9530e-05, 2.6200e+00, {1052.00, 1027.00, 120.00, 24.00, 0.00}, {1649.00, 1471.00, 1357.00, 331.00, 236.00, 0.00, 0.00}}; + case 62: + return {"Sm", 62, 152, 1.5036e+02, 5.0823e-05, 2.5900e+00, {1106.00, 1080.00, 129.00, 21.00, 0.00}, {1723.00, 1541.00, 1420.00, 346.00, 247.00, 0.00, 0.00}}; + case 63: + return {"Eu", 63, 153, 1.5197e+02, 5.1093e-05, 2.5600e+00, {1161.00, 1131.00, 133.00, 22.00, 0.00}, {1800.00, 1614.00, 1481.00, 360.00, 257.00, 0.00, 0.00}}; + case 64: + return {"Gd", 64, 158, 1.5725e+02, 5.1578e-05, 2.5400e+00, {1217.00, 1185.00, 140.00, 20.00, 0.00}, {1881.00, 1688.00, 1544.00, 376.00, 271.00, 0.00, 0.00}}; + case 65: + return {"Tb", 65, 159, 1.5893e+02, 5.0600e-05, 2.5100e+00, {1275.00, 1241.00, 147.00, 25.00, 0.00}, {1967.00, 1768.00, 1611.00, 398.00, 285.00, 0.00, 0.00}}; + case 66: + return {"Dy", 66, 164, 1.6250e+02, 5.2240e-05, 2.4900e+00, {1332.00, 1295.00, 154.00, 26.00, 0.00}, {2047.00, 1842.00, 1676.00, 416.00, 293.00, 0.00, 0.00}}; + case 67: + return {"Ho", 67, 165, 1.6493e+02, 5.2022e-05, 2.4700e+00, {1391.00, 1351.00, 161.00, 20.00, 0.00}, {2128.00, 1923.00, 1741.00, 436.00, 307.00, 51.00, 0.00}}; + case 68: + return {"Er", 68, 166, 1.6726e+02, 5.2527e-05, 2.4500e+00, {1453.00, 1409.00, 168.00, 29.00, 0.00}, {2206.00, 2006.00, 1812.00, 449.00, 320.00, 60.00, 0.00}}; + case 69: + return {"Tm", 69, 169, 1.6893e+02, 5.2256e-05, 2.4200e+00, {1515.00, 1468.00, 180.00, 32.00, 0.00}, {2307.00, 2090.00, 1884.00, 472.00, 337.00, 53.00, 0.00}}; + case 70: + return {"Yb", 70, 174, 1.7304e+02, 5.3105e-05, 2.4000e+00, {1576.00, 1528.00, 185.00, 24.00, 0.00}, {2398.00, 2173.00, 1950.00, 487.00, 343.00, 54.00, 0.00}}; + case 71: + return {"Lu", 71, 175, 1.7497e+02, 5.3700e-05, 2.2500e+00, {1639.00, 1588.00, 195.00, 28.00, 0.00}, {2491.00, 2263.00, 2024.00, 506.00, 359.00, 57.00, 0.00}}; + case 72: + return {"Hf", 72, 180, 1.7849e+02, 5.3482e-05, 2.1600e+00, {1716.00, 1662.00, 31.00, 0.00, 0.00}, {2601.00, 2365.00, 2108.00, 538.00, 380.00, 214.00, 65.00}}; + case 73: + return {"Ta", 73, 181, 1.8095e+02, 5.3507e-05, 2.0900e+00, {1793.00, 1735.00, 36.00, 0.00, 0.00}, {2708.00, 2469.00, 2194.00, 565.00, 404.00, 229.00, 71.00}}; + case 74: + return {"W", 74, 184, 1.8385e+02, 5.3646e-05, 2.0200e+00, {1872.00, 1809.00, 36.00, 0.00, 0.00}, {2820.00, 2575.00, 2281.00, 595.00, 425.00, 245.00, 77.00}}; + case 75: + return {"Re", 75, 187, 1.8621e+02, 5.3697e-05, 1.9700e+00, {1949.00, 1883.00, 35.00, 0.00, 0.00}, {2932.00, 2682.00, 2367.00, 625.00, 444.00, 260.00, 83.00}}; + case 76: + return {"Os", 76, 192, 1.9020e+02, 5.4122e-05, 1.9200e+00, {2031.00, 1960.00, 45.00, 0.00, 0.00}, {2792.00, 2457.00, 654.00, 468.00, 273.00, 46.00, 84.00}}; + case 77: + return {"Ir", 77, 193, 1.9222e+02, 5.4020e-05, 1.8700e+00, {2116.00, 2040.00, 50.00, 0.00, 0.00}, {2909.00, 2551.00, 690.00, 494.00, 295.00, 60.00, 95.00}}; + case 78: + return {"Pt", 78, 195, 1.9508e+02, 5.4250e-05, 1.8300e+00, {2202.00, 2122.00, 52.00, 0.00, 0.00}, {3026.00, 2645.00, 722.00, 519.00, 313.00, 102.00, 71.00}}; + case 79: + return {"Au", 79, 197, 1.9697e+02, 5.4379e-05, 1.7900e+00, {2291.00, 2206.00, 54.00, 0.00, 0.00}, {3148.00, 2743.00, 759.00, 545.00, 334.00, 108.00, 83.00}}; + case 80: + return {"Hg", 80, 202, 2.0059e+02, 5.4637e-05, 1.7600e+00, {2385.00, 2295.00, 58.00, 0.00, 0.00}, {3278.00, 2847.00, 800.00, 571.00, 360.00, 120.00, 98.00}}; + case 81: + return {"Tl", 81, 205, 2.0438e+02, 5.4757e-05, 2.0800e+00, {2485.00, 2389.00, 75.00, 0.00, 0.00}, {3416.00, 2957.00, 845.00, 609.00, 386.00, 136.00, 118.00}}; + case 82: + return {"Pb", 82, 208, 2.0720e+02, 5.5010e-05, 1.8100e+00, {2586.00, 2484.00, 86.00, 19.00, 0.00}, {3554.00, 3066.00, 894.00, 644.00, 413.00, 147.00, 138.00}}; + case 83: + return {"Bi", 83, 209, 2.0898e+02, 5.5210e-05, 1.6300e+00, {2688.00, 2580.00, 93.00, 24.00, 0.00}, {3696.00, 3177.00, 938.00, 679.00, 440.00, 159.00, 157.00}}; + case 84: + return {"Po", 84, 209, 2.0900e+02, 5.5262e-05, 1.5300e+00, {3491.00, 3332.00, 0.00, 0.00, 0.00}, {4046.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 85: + return {"At", 85, 210, 2.1000e+02, 5.5310e-05, 1.4300e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 86: + return {"Rn", 86, 222, 2.2200e+02, 5.6547e-05, 1.3400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 87: + return {"Fr", 87, 223, 2.2300e+02, 5.6584e-05, 2.7000e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 88: + return {"Ra", 88, 226, 2.2603e+02, 5.6840e-05, 2.2300e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 89: + return {"Ac", 89, 227, 2.2700e+02, 5.7120e-05, 1.8800e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 90: + return {"Th", 90, 232, 2.3204e+02, 5.7800e-05, 1.8000e+00, {3491.00, 3332.00, 344.00, 335.00, 88.00}, {4046.00, 1329.00, 967.00, 714.00, 676.00, 290.00, 182.00}}; + case 91: + return {"Pa", 91, 231, 2.3104e+02, 5.7660e-05, 1.6100e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 92: + return {"U", 92, 238, 2.3803e+02, 5.8571e-05, 1.3800e+00, {3728.00, 3552.00, 391.00, 381.00, 96.00}, {4303.00, 1441.00, 1045.00, 780.00, 738.00, 324.00, 195.00}}; + case 93: + return {"Np", 93, 237, 2.3705e+02, 5.8410e-05, 1.3000e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 94: + return {"Pu", 94, 244, 2.4400e+02, 5.8948e-05, 1.5100e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 95: + return {"Am", 95, 243, 2.4300e+02, 5.9042e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 96: + return {"Cm", 96, 247, 2.4700e+02, 5.9630e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 97: + return {"Bk", 97, 247, 2.4700e+02, 5.9300e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 98: + return {"Cf", 98, 251, 2.5100e+02, 6.0200e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 99: + return {"Es", 99, 252, 2.5200e+02, 6.0340e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 100: + return {"Fm", 100, 257, 2.5700e+02, 6.1070e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 101: + return {"Md", 101, 258, 2.5800e+02, 6.1220e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 102: + return {"No", 102, 259, 2.5900e+02, 6.1370e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 103: + return {"Lr", 103, 262, 2.6000e+02, 6.1820e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + } + return {}; + } + + // 1: doyle and Turner parameterization - 4 Gaussians - [0, 4] + LNL_Coef_cpu load_feg_doyle_neutral_0_4(const dt_int32& Z) + { + switch(Z) + { + case 2: + return {{9.0600e-02, 1.8140e-01, 1.0950e-01, 3.6200e-02}, {1.8183e+01, 6.2109e+00, 1.8026e+00, 2.8440e-01}}; + case 3: + return {{1.6108e+00, 1.2460e+00, 3.2570e-01, 9.8600e-02}, {1.0764e+02, 3.0480e+01, 4.5331e+00, 4.9510e-01}}; + case 4: + return {{1.2498e+00, 1.3335e+00, 3.6030e-01, 1.0550e-01}, {6.0804e+01, 1.8591e+01, 3.6534e+00, 4.1570e-01}}; + case 5: + return {{9.4460e-01, 1.3120e+00, 4.1880e-01, 1.1590e-01}, {4.6444e+01, 1.4178e+01, 3.2228e+00, 3.7670e-01}}; + case 6: + return {{7.3070e-01, 1.1951e+00, 4.5630e-01, 1.2470e-01}, {3.6995e+01, 1.1297e+01, 2.8139e+00, 3.4560e-01}}; + case 7: + return {{5.7170e-01, 1.0425e+00, 4.6470e-01, 1.3110e-01}, {2.8846e+01, 9.0542e+00, 2.4213e+00, 3.1670e-01}}; + case 8: + return {{4.5400e-01, 9.1730e-01, 4.7190e-01, 1.3840e-01}, {2.3780e+01, 7.6220e+00, 2.1440e+00, 2.9590e-01}}; + case 9: + return {{3.6860e-01, 8.1090e-01, 4.7510e-01, 1.4590e-01}, {2.0239e+01, 6.6093e+00, 1.9310e+00, 2.7930e-01}}; + case 10: + return {{3.0250e-01, 7.2020e-01, 4.7510e-01, 1.5340e-01}, {1.7639e+01, 5.8604e+00, 1.7623e+00, 2.6560e-01}}; + case 11: + return {{2.2406e+00, 1.3326e+00, 9.0700e-01, 2.8630e-01}, {1.0800e+02, 2.4505e+01, 3.3914e+00, 4.3460e-01}}; + case 12: + return {{2.2692e+00, 1.8025e+00, 8.3940e-01, 2.8920e-01}, {7.3670e+01, 2.0175e+01, 3.0131e+00, 4.0460e-01}}; + case 13: + return {{2.2756e+00, 2.4280e+00, 8.5780e-01, 3.2660e-01}, {7.2322e+01, 1.9773e+01, 3.0799e+00, 4.0760e-01}}; + case 14: + return {{2.1293e+00, 2.5333e+00, 8.3490e-01, 3.2160e-01}, {5.7775e+01, 1.6476e+01, 2.6796e+00, 3.8600e-01}}; + case 15: + return {{1.8882e+00, 2.4685e+00, 8.0460e-01, 3.2040e-01}, {4.4876e+01, 1.3538e+01, 2.6424e+00, 3.6030e-01}}; + case 16: + return {{1.6591e+00, 2.3863e+00, 7.8990e-01, 3.2080e-01}, {3.6650e+01, 1.1488e+01, 2.4686e+00, 3.4030e-01}}; + case 17: + return {{1.4524e+00, 2.2926e+00, 7.8740e-01, 3.2170e-01}, {3.0935e+01, 9.9798e+00, 2.3336e+00, 3.2280e-01}}; + case 18: + return {{1.2736e+00, 2.1894e+00, 7.9270e-01, 3.2250e-01}, {2.6682e+01, 8.8130e+00, 2.2186e+00, 3.0710e-01}}; + case 19: + return {{3.9507e+00, 2.5452e+00, 1.9795e+00, 4.0170e-01}, {1.3707e+02, 2.2402e+01, 4.5319e+00, 4.3400e-01}}; + case 20: + return {{4.4696e+00, 2.9703e+00, 1.9696e+00, 4.8180e-01}, {9.9523e+01, 2.2696e+01, 4.1954e+00, 4.1650e-01}}; + case 21: + return {{3.9659e+00, 2.9169e+00, 1.9254e+00, 4.8020e-01}, {3.8960e+01, 2.0606e+01, 3.8557e+00, 3.9880e-01}}; + case 22: + return {{3.5653e+00, 2.8181e+00, 1.8930e+00, 4.8250e-01}, {8.1982e+01, 1.9049e+01, 3.5904e+00, 3.8550e-01}}; + case 23: + return {{3.2449e+00, 2.6978e+00, 1.8597e+00, 4.8640e-01}, {7.6379e+01, 1.7726e+01, 3.3632e+00, 3.7430e-01}}; + case 24: + return {{2.3066e+00, 2.3339e+00, 1.8226e+00, 4.9010e-01}, {7.8405e+01, 1.5785e+01, 3.1566e+00, 3.6360e-01}}; + case 25: + return {{2.7467e+00, 2.4556e+00, 1.7923e+00, 4.9840e-01}, {6.7786e+01, 1.5674e+01, 2.9998e+00, 3.5690e-01}}; + case 26: + return {{2.5440e+00, 2.3434e+00, 1.7588e+00, 5.0620e-01}, {6.4424e+01, 1.4531e+01, 2.8539e+00, 3.5020e-01}}; + case 27: + return {{2.3668e+00, 2.2361e+00, 1.7243e+00, 5.1480e-01}, {6.1431e+01, 1.4179e+01, 2.7247e+00, 3.4420e-01}}; + case 28: + return {{2.2104e+00, 2.1342e+00, 1.6891e+00, 5.2380e-01}, {5.8727e+01, 1.3553e+01, 2.6094e+00, 3.3880e-01}}; + case 29: + return {{1.5792e+00, 1.8197e+00, 1.6576e+00, 5.3230e-01}, {6.2940e+01, 1.2453e+01, 2.5042e+00, 3.3310e-01}}; + case 30: + return {{1.9418e+00, 1.9501e+00, 1.6192e+00, 5.4340e-01}, {5.4162e+01, 1.2518e+01, 2.4164e+00, 3.2950e-01}}; + case 31: + return {{2.3205e+00, 2.4955e+00, 1.6879e+00, 5.9920e-01}, {6.5602e+01, 1.5458e+01, 2.5806e+00, 3.5100e-01}}; + case 32: + return {{2.4467e+00, 2.7015e+00, 1.6157e+00, 6.0090e-01}, {5.5893e+01, 1.4393e+01, 2.4461e+00, 3.4150e-01}}; + case 33: + return {{2.3989e+00, 2.7898e+00, 1.5288e+00, 5.9360e-01}, {4.5718e+01, 3.2817e+01, 2.2799e+00, 3.2770e-01}}; + case 34: + return {{2.2980e+00, 2.8541e+00, 1.4555e+00, 5.8950e-01}, {3.8830e+01, 1.1536e+01, 2.1463e+00, 3.1630e-01}}; + case 35: + return {{2.1659e+00, 2.9037e+00, 1.3951e+00, 5.8860e-01}, {3.3899e+01, 1.0500e+01, 2.0413e+00, 3.0700e-01}}; + case 36: + return {{2.0338e+00, 2.9271e+00, 1.3425e+00, 5.8880e-01}, {2.9999e+01, 9.5977e+00, 1.9520e+00, 2.9860e-01}}; + case 37: + return {{4.7760e+00, 3.8588e+00, 2.2339e+00, 8.6830e-01}, {1.4078e+02, 1.8991e+01, 3.7010e+00, 4.1940e-01}}; + case 38: + return {{5.8478e+00, 4.0026e+00, 2.3420e+00, 8.7950e-01}, {1.0497e+02, 1.9367e+01, 3.7368e+00, 4.1420e-01}}; + case 42: + return {{3.1199e+00, 3.9061e+00, 2.3615e+00, 8.5040e-01}, {7.2464e+01, 1.4642e+01, 3.2370e+00, 3.6620e-01}}; + case 47: + return {{2.0355e+00, 3.2716e+00, 2.5105e+00, 8.3720e-01}, {6.1497e+01, 1.1324e+01, 2.8456e+00, 3.2710e-01}}; + case 48: + return {{2.5737e+00, 3.2536e+00, 2.5468e+00, 8.3790e-01}, {5.5675e+01, 1.1838e+01, 2.7842e+00, 3.2170e-01}}; + case 49: + return {{3.1528e+00, 3.5565e+00, 2.8180e+00, 8.8420e-01}, {6.6649e+01, 1.4449e+01, 2.9758e+00, 3.3450e-01}}; + case 50: + return {{3.4495e+00, 3.7349e+00, 2.7779e+00, 8.7860e-01}, {5.9104e+01, 1.4179e+01, 2.8548e+00, 3.2700e-01}}; + case 51: + return {{3.5644e+00, 3.8437e+00, 2.6366e+00, 8.6380e-01}, {5.0487e+01, 1.3316e+01, 2.6909e+00, 3.1610e-01}}; + case 53: + return {{3.4728e+00, 4.0602e+00, 2.5215e+00, 8.3980e-01}, {3.9441e+01, 1.1816e+01, 2.4148e+00, 2.9760e-01}}; + case 54: + return {{3.3656e+00, 4.1468e+00, 2.4430e+00, 8.2930e-01}, {3.5509e+01, 1.1117e+01, 2.2940e+00, 2.8920e-01}}; + case 55: + return {{6.0620e+00, 5.9861e+00, 3.3033e+00, 1.0958e+00}, {1.5583e+02, 1.9695e+01, 3.3354e+00, 3.7930e-01}}; + case 56: + return {{7.8212e+00, 6.0040e+00, 3.2803e+00, 1.1030e+00}, {1.1766e+02, 1.8778e+01, 3.2634e+00, 3.7600e-01}}; + case 57: + return {{6.2661e+00, 4.8440e+00, 3.2023e+00, 1.2009e+00}, {1.0030e+02, 1.6066e+01, 2.9803e+00, 3.6740e-01}}; + case 79: + return {{2.3880e+00, 4.2259e+00, 2.6886e+00, 1.2551e+00}, {4.2866e+01, 9.7430e+00, 2.2641e+00, 3.0670e-01}}; + case 80: + return {{2.6817e+00, 4.2414e+00, 2.7549e+00, 1.2706e+00}, {4.2822e+01, 9.8557e+00, 2.2951e+00, 3.0670e-01}}; + case 82: + return {{3.5099e+00, 4.5523e+00, 3.1539e+00, 1.3591e+00}, {5.2914e+01, 1.1884e+01, 2.5713e+00, 3.2050e-01}}; + case 83: + return {{3.8412e+00, 4.6784e+00, 3.1924e+00, 1.3625e+00}, {5.0261e+01, 1.1999e+01, 2.5598e+00, 3.1770e-01}}; + case 86: + return {{4.0779e+00, 4.9778e+00, 3.0955e+00, 1.3259e+00}, {2.8406e+01, 1.1020e+01, 2.3549e+00, 2.9910e-01}}; + case 92: + return {{6.7668e+00, 6.7287e+00, 4.0135e+00, 1.5607e+00}, {8.5951e+01, 1.5642e+01, 2.9364e+00, 3.3480e-01}}; + } + + return {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}}; + } + + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + LNL_Coef_cpu load_feg_peng_neutral_0_4(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{3.490000e-02, 1.201000e-01, 1.970000e-01, 5.730000e-02, 1.195000e-01}, {5.347000e-01, 3.586700e+00, 1.234710e+01, 1.895250e+01, 3.862690e+01}}; + case 2: + return {{3.170000e-02, 8.380000e-02, 1.526000e-01, 1.334000e-01, 1.640000e-02}, {2.507000e-01, 1.475100e+00, 4.493800e+00, 1.266460e+01, 3.116530e+01}}; + case 3: + return {{7.500000e-02, 2.249000e-01, 5.548000e-01, 1.495400e+00, 9.354000e-01}, {3.864000e-01, 2.938300e+00, 1.538290e+01, 5.355450e+01, 1.387337e+02}}; + case 4: + return {{7.800000e-02, 2.210000e-01, 6.740000e-01, 1.386700e+00, 6.925000e-01}, {3.131000e-01, 2.238100e+00, 1.015170e+01, 3.090610e+01, 7.832730e+01}}; + case 5: + return {{9.090000e-02, 2.551000e-01, 7.738000e-01, 1.213600e+00, 4.606000e-01}, {2.995000e-01, 2.115500e+00, 8.381600e+00, 2.412920e+01, 6.313140e+01}}; + case 6: + return {{8.930000e-02, 2.563000e-01, 7.570000e-01, 1.048700e+00, 3.575000e-01}, {2.465000e-01, 1.710000e+00, 6.409400e+00, 1.861130e+01, 5.025230e+01}}; + case 7: + return {{1.022000e-01, 3.219000e-01, 7.982000e-01, 8.197000e-01, 1.715000e-01}, {2.451000e-01, 1.748100e+00, 6.192500e+00, 1.738940e+01, 4.814310e+01}}; + case 8: + return {{9.740000e-02, 2.921000e-01, 6.910000e-01, 6.990000e-01, 2.039000e-01}, {2.067000e-01, 1.381500e+00, 4.694300e+00, 1.271050e+01, 3.247260e+01}}; + case 9: + return {{1.083000e-01, 3.175000e-01, 6.487000e-01, 5.846000e-01, 1.421000e-01}, {2.057000e-01, 1.343900e+00, 4.278800e+00, 1.139320e+01, 2.878810e+01}}; + case 10: + return {{1.269000e-01, 3.535000e-01, 5.582000e-01, 4.674000e-01, 1.460000e-01}, {2.200000e-01, 1.377900e+00, 4.020300e+00, 9.493400e+00, 2.312780e+01}}; + case 11: + return {{2.142000e-01, 6.853000e-01, 7.692000e-01, 1.658900e+00, 1.448200e+00}, {3.334000e-01, 2.344600e+00, 1.008300e+01, 4.830370e+01, 1.382700e+02}}; + case 12: + return {{2.314000e-01, 6.866000e-01, 9.677000e-01, 2.188200e+00, 1.133900e+00}, {3.278000e-01, 2.272000e+00, 1.092410e+01, 3.928980e+01, 1.019748e+02}}; + case 13: + return {{2.390000e-01, 6.573000e-01, 1.201100e+00, 2.558600e+00, 1.231200e+00}, {3.138000e-01, 2.106300e+00, 1.041630e+01, 3.445520e+01, 9.853440e+01}}; + case 14: + return {{2.519000e-01, 6.372000e-01, 1.379500e+00, 2.508200e+00, 1.050000e+00}, {3.075000e-01, 2.017400e+00, 9.674600e+00, 2.937440e+01, 8.047320e+01}}; + case 15: + return {{2.548000e-01, 6.106000e-01, 1.454100e+00, 2.320400e+00, 8.477000e-01}, {2.908000e-01, 1.874000e+00, 8.517600e+00, 2.434340e+01, 6.329960e+01}}; + case 16: + return {{2.497000e-01, 5.628000e-01, 1.389900e+00, 2.186500e+00, 7.715000e-01}, {2.681000e-01, 1.671100e+00, 7.026700e+00, 1.953770e+01, 5.038880e+01}}; + case 17: + return {{2.443000e-01, 5.397000e-01, 1.391900e+00, 2.019700e+00, 6.621000e-01}, {2.468000e-01, 1.524200e+00, 6.153700e+00, 1.666870e+01, 4.230860e+01}}; + case 18: + return {{2.385000e-01, 5.017000e-01, 1.342800e+00, 1.889900e+00, 6.079000e-01}, {2.289000e-01, 1.369400e+00, 5.256100e+00, 1.409280e+01, 3.553610e+01}}; + case 19: + return {{4.115000e-01, 1.403100e+00, 2.278400e+00, 2.674200e+00, 2.216200e+00}, {3.703000e-01, 3.387400e+00, 1.310290e+01, 6.895920e+01, 1.944329e+02}}; + case 20: + return {{4.054000e-01, 1.388000e+00, 2.160200e+00, 3.753200e+00, 2.206300e+00}, {3.499000e-01, 3.099100e+00, 1.196080e+01, 5.393530e+01, 1.423892e+02}}; + case 21: + return {{3.787000e-01, 1.218100e+00, 2.059400e+00, 3.261800e+00, 2.387000e+00}, {3.133000e-01, 2.585600e+00, 9.581300e+00, 4.176880e+01, 1.167282e+02}}; + case 22: + return {{3.825000e-01, 1.259800e+00, 2.000800e+00, 3.061700e+00, 2.069400e+00}, {3.040000e-01, 2.486300e+00, 9.278300e+00, 3.907510e+01, 1.094583e+02}}; + case 23: + return {{3.876000e-01, 1.275000e+00, 1.910900e+00, 2.831400e+00, 1.897900e+00}, {2.967000e-01, 2.378000e+00, 8.798100e+00, 3.595280e+01, 1.017201e+02}}; + case 24: + return {{4.046000e-01, 1.369600e+00, 1.894100e+00, 2.080000e+00, 1.219600e+00}, {2.986000e-01, 2.395800e+00, 9.140600e+00, 3.747010e+01, 1.137121e+02}}; + case 25: + return {{3.796000e-01, 1.209400e+00, 1.781500e+00, 2.542000e+00, 1.593700e+00}, {2.699000e-01, 2.045500e+00, 7.472600e+00, 3.106040e+01, 9.156220e+01}}; + case 26: + return {{3.946000e-01, 1.272500e+00, 1.703100e+00, 2.314000e+00, 1.479500e+00}, {2.717000e-01, 2.044300e+00, 7.600700e+00, 2.997140e+01, 8.622650e+01}}; + case 27: + return {{4.118000e-01, 1.316100e+00, 1.649300e+00, 2.193000e+00, 1.283000e+00}, {2.742000e-01, 2.037200e+00, 7.720500e+00, 2.996800e+01, 8.493830e+01}}; + case 28: + return {{3.860000e-01, 1.176500e+00, 1.545100e+00, 2.073000e+00, 1.381400e+00}, {2.478000e-01, 1.766000e+00, 6.310700e+00, 2.522040e+01, 7.431460e+01}}; + case 29: + return {{4.314000e-01, 1.320800e+00, 1.523600e+00, 1.467100e+00, 8.562000e-01}, {2.694000e-01, 1.922300e+00, 7.347400e+00, 2.898920e+01, 9.062460e+01}}; + case 30: + return {{4.288000e-01, 1.264600e+00, 1.447200e+00, 1.829400e+00, 1.093400e+00}, {2.593000e-01, 1.799800e+00, 6.750000e+00, 2.558600e+01, 7.352840e+01}}; + case 31: + return {{4.818000e-01, 1.403200e+00, 1.656100e+00, 2.460500e+00, 1.105400e+00}, {2.825000e-01, 1.978500e+00, 8.754600e+00, 3.252380e+01, 9.855230e+01}}; + case 32: + return {{4.655000e-01, 1.301400e+00, 1.608800e+00, 2.699800e+00, 1.300300e+00}, {2.647000e-01, 1.792600e+00, 7.607100e+00, 2.655410e+01, 7.752380e+01}}; + case 33: + return {{4.517000e-01, 1.222900e+00, 1.585200e+00, 2.795800e+00, 1.263800e+00}, {2.493000e-01, 1.643600e+00, 6.815400e+00, 2.236810e+01, 6.203900e+01}}; + case 34: + return {{4.477000e-01, 1.167800e+00, 1.584300e+00, 2.808700e+00, 1.195600e+00}, {2.405000e-01, 1.544200e+00, 6.323100e+00, 1.946100e+01, 5.202330e+01}}; + case 35: + return {{4.798000e-01, 1.194800e+00, 1.869500e+00, 2.695300e+00, 8.203000e-01}, {2.504000e-01, 1.596300e+00, 6.965300e+00, 1.984920e+01, 5.032330e+01}}; + case 36: + return {{4.546000e-01, 1.099300e+00, 1.769600e+00, 2.706800e+00, 8.672000e-01}, {2.309000e-01, 1.427900e+00, 5.944900e+00, 1.667520e+01, 4.222430e+01}}; + case 37: + return {{1.016000e+00, 2.852800e+00, 3.546600e+00, -7.780400e+00, 1.211480e+01}, {4.853000e-01, 5.092500e+00, 2.578510e+01, 1.304515e+02, 1.386775e+02}}; + case 38: + return {{6.703000e-01, 1.492600e+00, 3.336800e+00, 4.460000e+00, 3.150100e+00}, {3.190000e-01, 2.228700e+00, 1.035040e+01, 5.232910e+01, 1.512216e+02}}; + case 39: + return {{6.894000e-01, 1.547400e+00, 3.245000e+00, 4.212600e+00, 2.976400e+00}, {3.189000e-01, 2.290400e+00, 1.000620e+01, 4.407710e+01, 1.250120e+02}}; + case 40: + return {{6.719000e-01, 1.468400e+00, 3.166800e+00, 3.955700e+00, 2.892000e+00}, {3.036000e-01, 2.124900e+00, 8.923600e+00, 3.684580e+01, 1.082049e+02}}; + case 41: + return {{6.123000e-01, 1.267700e+00, 3.034800e+00, 3.384100e+00, 2.368300e+00}, {2.709000e-01, 1.768300e+00, 7.248900e+00, 2.794650e+01, 9.856240e+01}}; + case 42: + return {{6.773000e-01, 1.479800e+00, 3.178800e+00, 3.082400e+00, 1.838400e+00}, {2.920000e-01, 2.060600e+00, 8.112900e+00, 3.053360e+01, 1.000658e+02}}; + case 43: + return {{7.082000e-01, 1.639200e+00, 3.199300e+00, 3.432700e+00, 1.871100e+00}, {2.976000e-01, 2.210600e+00, 8.524600e+00, 3.314560e+01, 9.663770e+01}}; + case 44: + return {{6.735000e-01, 1.493400e+00, 3.096600e+00, 2.725400e+00, 1.559700e+00}, {2.773000e-01, 1.971600e+00, 7.324900e+00, 2.668910e+01, 9.055810e+01}}; + case 45: + return {{6.413000e-01, 1.369000e+00, 2.985400e+00, 2.695200e+00, 1.543300e+00}, {2.580000e-01, 1.772100e+00, 6.385400e+00, 2.325490e+01, 8.515170e+01}}; + case 46: + return {{5.904000e-01, 1.177500e+00, 2.651900e+00, 2.287500e+00, 8.689000e-01}, {2.324000e-01, 1.501900e+00, 5.159100e+00, 1.554280e+01, 4.682130e+01}}; + case 47: + return {{6.377000e-01, 1.379000e+00, 2.829400e+00, 2.363100e+00, 1.455300e+00}, {2.466000e-01, 1.697400e+00, 5.765600e+00, 2.009430e+01, 7.673720e+01}}; + case 48: + return {{6.364000e-01, 1.424700e+00, 2.780200e+00, 2.597300e+00, 1.788600e+00}, {2.407000e-01, 1.682300e+00, 5.658800e+00, 2.072190e+01, 6.911090e+01}}; + case 49: + return {{6.768000e-01, 1.658900e+00, 2.774000e+00, 3.183500e+00, 2.132600e+00}, {2.522000e-01, 1.854500e+00, 6.293600e+00, 2.514570e+01, 8.454480e+01}}; + case 50: + return {{7.224000e-01, 1.961000e+00, 2.716100e+00, 3.560300e+00, 1.897200e+00}, {2.651000e-01, 2.060400e+00, 7.301100e+00, 2.754930e+01, 8.133490e+01}}; + case 51: + return {{7.106000e-01, 1.924700e+00, 2.614900e+00, 3.832200e+00, 1.889900e+00}, {2.562000e-01, 1.964600e+00, 6.885200e+00, 2.476480e+01, 6.891680e+01}}; + case 52: + return {{6.947000e-01, 1.869000e+00, 2.535600e+00, 4.001300e+00, 1.895500e+00}, {2.459000e-01, 1.854200e+00, 6.441100e+00, 2.217300e+01, 5.922060e+01}}; + case 53: + return {{7.047000e-01, 1.948400e+00, 2.594000e+00, 4.152600e+00, 1.505700e+00}, {2.455000e-01, 1.863800e+00, 6.763900e+00, 2.180070e+01, 5.643950e+01}}; + case 54: + return {{6.737000e-01, 1.790800e+00, 2.412900e+00, 4.210000e+00, 1.705800e+00}, {2.305000e-01, 1.689000e+00, 5.821800e+00, 1.839280e+01, 4.724960e+01}}; + case 55: + return {{1.270400e+00, 3.801800e+00, 5.661800e+00, 9.205000e-01, 4.810500e+00}, {4.356000e-01, 4.205800e+00, 2.343420e+01, 1.367783e+02, 1.717561e+02}}; + case 56: + return {{9.049000e-01, 2.607600e+00, 4.849800e+00, 5.160300e+00, 4.738800e+00}, {3.066000e-01, 2.436300e+00, 1.218210e+01, 5.461350e+01, 1.619978e+02}}; + case 57: + return {{8.405000e-01, 2.386300e+00, 4.613900e+00, 5.151400e+00, 4.794900e+00}, {2.791000e-01, 2.141000e+00, 1.034000e+01, 4.191480e+01, 1.320204e+02}}; + case 58: + return {{8.551000e-01, 2.391500e+00, 4.577200e+00, 5.027800e+00, 4.511800e+00}, {2.805000e-01, 2.120000e+00, 1.018080e+01, 4.206330e+01, 1.309893e+02}}; + case 59: + return {{9.096000e-01, 2.531300e+00, 4.526600e+00, 4.637600e+00, 4.369000e+00}, {2.939000e-01, 2.247100e+00, 1.082660e+01, 4.888420e+01, 1.476020e+02}}; + case 60: + return {{8.807000e-01, 2.418300e+00, 4.444800e+00, 4.685800e+00, 4.172500e+00}, {2.802000e-01, 2.083600e+00, 1.003570e+01, 4.745060e+01, 1.469976e+02}}; + case 61: + return {{9.471000e-01, 2.546300e+00, 4.352300e+00, 4.478900e+00, 3.908000e+00}, {2.977000e-01, 2.227600e+00, 1.057620e+01, 4.936190e+01, 1.453580e+02}}; + case 62: + return {{9.699000e-01, 2.583700e+00, 4.277800e+00, 4.457500e+00, 3.598500e+00}, {3.003000e-01, 2.244700e+00, 1.064870e+01, 5.079940e+01, 1.464179e+02}}; + case 63: + return {{8.694000e-01, 2.241300e+00, 3.919600e+00, 3.969400e+00, 4.549800e+00}, {2.653000e-01, 1.859000e+00, 8.399800e+00, 3.673970e+01, 1.257089e+02}}; + case 64: + return {{9.673000e-01, 2.470200e+00, 4.114800e+00, 4.497200e+00, 3.209900e+00}, {2.909000e-01, 2.101400e+00, 9.706700e+00, 4.342700e+01, 1.259474e+02}}; + case 65: + return {{9.325000e-01, 2.367300e+00, 3.879100e+00, 3.967400e+00, 3.799600e+00}, {2.761000e-01, 1.951100e+00, 8.929600e+00, 4.159370e+01, 1.310122e+02}}; + case 66: + return {{9.505000e-01, 2.370500e+00, 3.821800e+00, 4.047100e+00, 3.445100e+00}, {2.773000e-01, 1.946900e+00, 8.886200e+00, 4.309380e+01, 1.331396e+02}}; + case 67: + return {{9.248000e-01, 2.242800e+00, 3.618200e+00, 3.791000e+00, 3.791200e+00}, {2.660000e-01, 1.818300e+00, 7.965500e+00, 3.311290e+01, 1.018139e+02}}; + case 68: + return {{1.037300e+00, 2.482400e+00, 3.655800e+00, 3.892500e+00, 3.005600e+00}, {2.944000e-01, 2.079700e+00, 9.415600e+00, 4.580560e+01, 1.327720e+02}}; + case 69: + return {{1.007500e+00, 2.378700e+00, 3.544000e+00, 3.693200e+00, 3.175900e+00}, {2.816000e-01, 1.948600e+00, 8.716200e+00, 4.184200e+01, 1.250320e+02}}; + case 70: + return {{1.034700e+00, 2.391100e+00, 3.461900e+00, 3.655600e+00, 3.005200e+00}, {2.855000e-01, 1.967900e+00, 8.761900e+00, 4.233040e+01, 1.256499e+02}}; + case 71: + return {{9.927000e-01, 2.243600e+00, 3.355400e+00, 3.781300e+00, 3.099400e+00}, {2.701000e-01, 1.807300e+00, 7.811200e+00, 3.448490e+01, 1.033526e+02}}; + case 72: + return {{1.029500e+00, 2.291100e+00, 3.411000e+00, 3.949700e+00, 2.492500e+00}, {2.761000e-01, 1.862500e+00, 8.096100e+00, 3.427120e+01, 9.852950e+01}}; + case 73: + return {{1.019000e+00, 2.229100e+00, 3.409700e+00, 3.925200e+00, 2.267900e+00}, {2.694000e-01, 1.796200e+00, 7.694400e+00, 3.109420e+01, 9.110890e+01}}; + case 74: + return {{9.853000e-01, 2.116700e+00, 3.357000e+00, 3.798100e+00, 2.279800e+00}, {2.569000e-01, 1.674500e+00, 7.009800e+00, 2.692340e+01, 8.139100e+01}}; + case 75: + return {{9.914000e-01, 2.085800e+00, 3.453100e+00, 3.881200e+00, 1.852600e+00}, {2.548000e-01, 1.651800e+00, 6.884500e+00, 2.672340e+01, 8.172150e+01}}; + case 76: + return {{9.813000e-01, 2.032200e+00, 3.366500e+00, 3.623500e+00, 1.974100e+00}, {2.487000e-01, 1.597300e+00, 6.473700e+00, 2.328170e+01, 7.092540e+01}}; + case 77: + return {{1.019400e+00, 2.064500e+00, 3.442500e+00, 3.491400e+00, 1.697600e+00}, {2.554000e-01, 1.647500e+00, 6.596600e+00, 2.322690e+01, 7.002720e+01}}; + case 78: + return {{9.148000e-01, 1.809600e+00, 3.213400e+00, 3.295300e+00, 1.575400e+00}, {2.263000e-01, 1.381300e+00, 5.324300e+00, 1.759870e+01, 6.001710e+01}}; + case 79: + return {{9.674000e-01, 1.891600e+00, 3.399300e+00, 3.052400e+00, 1.260700e+00}, {2.358000e-01, 1.471200e+00, 5.675800e+00, 1.871190e+01, 6.152860e+01}}; + case 80: + return {{1.003300e+00, 1.946900e+00, 3.439600e+00, 3.154800e+00, 1.418000e+00}, {2.413000e-01, 1.529800e+00, 5.800900e+00, 1.945200e+01, 6.057530e+01}}; + case 81: + return {{1.068900e+00, 2.103800e+00, 3.603900e+00, 3.492700e+00, 1.828300e+00}, {2.540000e-01, 1.671500e+00, 6.350900e+00, 2.315310e+01, 7.870990e+01}}; + case 82: + return {{1.089100e+00, 2.186700e+00, 3.616000e+00, 3.803100e+00, 1.899400e+00}, {2.552000e-01, 1.717400e+00, 6.513100e+00, 2.391700e+01, 7.470390e+01}}; + case 83: + return {{1.100700e+00, 2.230600e+00, 3.568900e+00, 4.154900e+00, 2.038200e+00}, {2.546000e-01, 1.735100e+00, 6.494800e+00, 2.364640e+01, 7.037800e+01}}; + case 84: + return {{1.156800e+00, 2.435300e+00, 3.645900e+00, 4.406400e+00, 1.717900e+00}, {2.648000e-01, 1.878600e+00, 7.174900e+00, 2.517660e+01, 6.928210e+01}}; + case 85: + return {{1.090900e+00, 2.197600e+00, 3.383100e+00, 4.670000e+00, 2.127700e+00}, {2.466000e-01, 1.670700e+00, 6.019700e+00, 2.076570e+01, 5.726630e+01}}; + case 86: + return {{1.075600e+00, 2.163000e+00, 3.317800e+00, 4.885200e+00, 2.048900e+00}, {2.402000e-01, 1.616900e+00, 5.764400e+00, 1.945680e+01, 5.250090e+01}}; + case 87: + return {{1.428200e+00, 3.508100e+00, 5.676700e+00, 4.196400e+00, 3.894600e+00}, {3.183000e-01, 2.688900e+00, 1.348160e+01, 5.438660e+01, 2.008321e+02}}; + case 88: + return {{1.312700e+00, 3.124300e+00, 5.298800e+00, 5.389100e+00, 5.413300e+00}, {2.887000e-01, 2.289700e+00, 1.082760e+01, 4.353890e+01, 1.456109e+02}}; + case 89: + return {{1.312800e+00, 3.102100e+00, 5.338500e+00, 5.961100e+00, 4.756200e+00}, {2.861000e-01, 2.250900e+00, 1.052870e+01, 4.177960e+01, 1.282973e+02}}; + case 90: + return {{1.255300e+00, 2.917800e+00, 5.086200e+00, 6.120600e+00, 4.712200e+00}, {2.701000e-01, 2.063600e+00, 9.305100e+00, 3.459770e+01, 1.079200e+02}}; + case 91: + return {{1.321800e+00, 3.144400e+00, 5.437100e+00, 5.644400e+00, 4.010700e+00}, {2.827000e-01, 2.225000e+00, 1.024540e+01, 4.111620e+01, 1.244449e+02}}; + case 92: + return {{1.338200e+00, 3.204300e+00, 5.455800e+00, 5.483900e+00, 3.634200e+00}, {2.838000e-01, 2.245200e+00, 1.025190e+01, 4.172510e+01, 1.249023e+02}}; + case 93: + return {{1.519300e+00, 4.005300e+00, 6.532700e+00, -1.402000e-01, 6.748900e+00}, {3.213000e-01, 2.820600e+00, 1.488780e+01, 6.891030e+01, 8.172570e+01}}; + case 94: + return {{1.351700e+00, 3.293700e+00, 5.321300e+00, 4.646600e+00, 3.571400e+00}, {2.813000e-01, 2.241800e+00, 9.995200e+00, 4.279390e+01, 1.321739e+02}}; + case 95: + return {{1.213500e+00, 2.796200e+00, 4.754500e+00, 4.573100e+00, 4.478600e+00}, {2.483000e-01, 1.843700e+00, 7.542100e+00, 2.938410e+01, 1.124579e+02}}; + case 96: + return {{1.293700e+00, 3.110000e+00, 5.039300e+00, 4.754600e+00, 3.503100e+00}, {2.638000e-01, 2.034100e+00, 8.710100e+00, 3.529920e+01, 1.094972e+02}}; + case 97: + return {{1.291500e+00, 3.102300e+00, 4.930900e+00, 4.600900e+00, 3.466100e+00}, {2.611000e-01, 2.002300e+00, 8.437700e+00, 3.415590e+01, 1.058911e+02}}; + case 98: + return {{1.208900e+00, 2.739100e+00, 4.348200e+00, 4.004700e+00, 4.649700e+00}, {2.421000e-01, 1.748700e+00, 6.726200e+00, 2.321530e+01, 8.031080e+01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + LNL_Coef_cpu load_feg_peng_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{8.800000e-03, 4.490000e-02, 1.481000e-01, 2.356000e-01, 9.140000e-02}, {1.152000e-01, 1.086700e+00, 4.975500e+00, 1.655910e+01, 4.327430e+01}}; + case 2: + return {{8.400000e-03, 4.430000e-02, 1.314000e-01, 1.671000e-01, 6.660000e-02}, {5.960000e-02, 5.360000e-01, 2.427400e+00, 7.785200e+00, 2.031260e+01}}; + case 3: + return {{4.780000e-02, 2.048000e-01, 5.253000e-01, 1.522500e+00, 9.853000e-01}, {2.258000e-01, 2.103200e+00, 1.293490e+01, 5.075010e+01, 1.366280e+02}}; + case 4: + return {{4.230000e-02, 1.874000e-01, 6.019000e-01, 1.431100e+00, 7.891000e-01}, {1.445000e-01, 1.418000e+00, 8.116500e+00, 2.797050e+01, 7.486840e+01}}; + case 5: + return {{4.360000e-02, 1.898000e-01, 6.788000e-01, 1.327300e+00, 5.544000e-01}, {1.207000e-01, 1.159500e+00, 6.247400e+00, 2.104600e+01, 5.936190e+01}}; + case 6: + return {{4.890000e-02, 2.091000e-01, 7.537000e-01, 1.142000e+00, 3.555000e-01}, {1.140000e-01, 1.082500e+00, 5.428100e+00, 1.788110e+01, 5.113410e+01}}; + case 7: + return {{2.670000e-02, 1.328000e-01, 5.301000e-01, 1.102000e+00, 4.215000e-01}, {5.410000e-02, 5.165000e-01, 2.820700e+00, 1.062970e+01, 3.437640e+01}}; + case 8: + return {{3.650000e-02, 1.729000e-01, 5.805000e-01, 8.814000e-01, 3.121000e-01}, {6.520000e-02, 6.184000e-01, 2.944900e+00, 9.629800e+00, 2.821940e+01}}; + case 9: + return {{3.820000e-02, 1.822000e-01, 5.972000e-01, 7.707000e-01, 2.130000e-01}, {6.130000e-02, 5.753000e-01, 2.685800e+00, 8.821400e+00, 2.566680e+01}}; + case 10: + return {{3.800000e-02, 1.785000e-01, 5.494000e-01, 6.942000e-01, 1.918000e-01}, {5.540000e-02, 5.087000e-01, 2.263900e+00, 7.331600e+00, 2.169120e+01}}; + case 11: + return {{1.260000e-01, 6.442000e-01, 8.893000e-01, 1.819700e+00, 1.298800e+00}, {1.684000e-01, 1.715000e+00, 8.838600e+00, 5.082650e+01, 1.472073e+02}}; + case 12: + return {{1.130000e-01, 5.575000e-01, 9.046000e-01, 2.158000e+00, 1.473500e+00}, {1.356000e-01, 1.357900e+00, 6.925500e+00, 3.231650e+01, 9.211380e+01}}; + case 13: + return {{1.165000e-01, 5.504000e-01, 1.017900e+00, 2.629500e+00, 1.571100e+00}, {1.295000e-01, 1.261900e+00, 6.824200e+00, 2.845770e+01, 8.847500e+01}}; + case 14: + return {{5.670000e-02, 3.365000e-01, 8.104000e-01, 2.496000e+00, 2.118600e+00}, {5.820000e-02, 6.155000e-01, 3.252200e+00, 1.679290e+01, 5.767670e+01}}; + case 15: + return {{1.005000e-01, 4.615000e-01, 1.066300e+00, 2.585400e+00, 1.272500e+00}, {9.770000e-02, 9.084000e-01, 4.965400e+00, 1.854710e+01, 5.436480e+01}}; + case 16: + return {{9.150000e-02, 4.312000e-01, 1.084700e+00, 2.467100e+00, 1.085200e+00}, {8.380000e-02, 7.788000e-01, 4.346200e+00, 1.558460e+01, 4.463650e+01}}; + case 17: + return {{7.990000e-02, 3.891000e-01, 1.003700e+00, 2.333200e+00, 1.050700e+00}, {6.940000e-02, 6.443000e-01, 3.535100e+00, 1.250580e+01, 3.586330e+01}}; + case 18: + return {{1.044000e-01, 4.551000e-01, 1.423200e+00, 2.153300e+00, 4.459000e-01}, {8.530000e-02, 7.701000e-01, 4.468400e+00, 1.458640e+01, 4.124740e+01}}; + case 19: + return {{2.149000e-01, 8.703000e-01, 2.499900e+00, 2.359100e+00, 3.031800e+00}, {1.660000e-01, 1.690600e+00, 8.744700e+00, 4.678250e+01, 1.656923e+02}}; + case 20: + return {{2.355000e-01, 9.916000e-01, 2.395900e+00, 3.725200e+00, 2.564700e+00}, {1.742000e-01, 1.832900e+00, 8.840700e+00, 4.745830e+01, 1.349613e+02}}; + case 21: + return {{4.636000e-01, 2.080200e+00, 2.900300e+00, 1.419300e+00, 2.432300e+00}, {3.682000e-01, 4.031200e+00, 2.264930e+01, 7.182000e+01, 1.033691e+02}}; + case 22: + return {{2.123000e-01, 8.960000e-01, 2.176500e+00, 3.043600e+00, 2.443900e+00}, {1.399000e-01, 1.456800e+00, 6.753400e+00, 3.311680e+01, 1.018238e+02}}; + case 23: + return {{2.369000e-01, 1.077400e+00, 2.189400e+00, 3.082500e+00, 1.719000e+00}, {1.505000e-01, 1.639200e+00, 7.569100e+00, 3.687410e+01, 1.078517e+02}}; + case 24: + return {{1.970000e-01, 8.228000e-01, 2.020000e+00, 2.171700e+00, 1.751600e+00}, {1.197000e-01, 1.198500e+00, 5.409700e+00, 2.523610e+01, 9.442900e+01}}; + case 25: + return {{1.943000e-01, 8.190000e-01, 1.929600e+00, 2.496800e+00, 2.062500e+00}, {1.135000e-01, 1.131300e+00, 5.034100e+00, 2.417980e+01, 8.055980e+01}}; + case 26: + return {{1.929000e-01, 8.239000e-01, 1.868900e+00, 2.369400e+00, 1.906000e+00}, {1.087000e-01, 1.080600e+00, 4.763700e+00, 2.285000e+01, 7.673090e+01}}; + case 27: + return {{2.186000e-01, 9.861000e-01, 1.854000e+00, 2.325800e+00, 1.468500e+00}, {1.182000e-01, 1.230000e+00, 5.417700e+00, 2.576020e+01, 8.085420e+01}}; + case 28: + return {{2.313000e-01, 1.065700e+00, 1.822900e+00, 2.260900e+00, 1.188300e+00}, {1.210000e-01, 1.269100e+00, 5.687000e+00, 2.709170e+01, 8.302850e+01}}; + case 29: + return {{3.501000e-01, 1.655800e+00, 1.958200e+00, 2.134000e-01, 1.410900e+00}, {1.867000e-01, 1.991700e+00, 1.133960e+01, 5.326190e+01, 6.325200e+01}}; + case 30: + return {{1.780000e-01, 8.096000e-01, 1.674400e+00, 1.949900e+00, 1.449500e+00}, {8.760000e-02, 8.650000e-01, 3.861200e+00, 1.887260e+01, 6.470160e+01}}; + case 31: + return {{2.135000e-01, 9.768000e-01, 1.666900e+00, 2.566200e+00, 1.679000e+00}, {1.020000e-01, 1.021900e+00, 4.627500e+00, 2.287420e+01, 8.015350e+01}}; + case 32: + return {{2.135000e-01, 9.761000e-01, 1.655500e+00, 2.893800e+00, 1.635600e+00}, {9.890000e-02, 9.845000e-01, 4.552700e+00, 2.155630e+01, 7.039030e+01}}; + case 33: + return {{2.059000e-01, 9.518000e-01, 1.637200e+00, 3.049000e+00, 1.475600e+00}, {9.260000e-02, 9.182000e-01, 4.329100e+00, 1.929960e+01, 5.893290e+01}}; + case 34: + return {{1.574000e-01, 7.614000e-01, 1.483400e+00, 3.001600e+00, 1.797800e+00}, {6.860000e-02, 6.808000e-01, 3.116300e+00, 1.434580e+01, 4.404550e+01}}; + case 35: + return {{1.899000e-01, 8.983000e-01, 1.635800e+00, 3.184500e+00, 1.151800e+00}, {8.100000e-02, 7.957000e-01, 3.905400e+00, 1.577010e+01, 4.561240e+01}}; + case 36: + return {{1.742000e-01, 8.447000e-01, 1.594400e+00, 3.150700e+00, 1.133800e+00}, {7.230000e-02, 7.123000e-01, 3.519200e+00, 1.377240e+01, 3.911480e+01}}; + case 37: + return {{3.781000e-01, 1.490400e+00, 3.575300e+00, 3.003100e+00, 3.327200e+00}, {1.557000e-01, 1.534700e+00, 9.994700e+00, 5.142510e+01, 1.859828e+02}}; + case 38: + return {{3.723000e-01, 1.459800e+00, 3.512400e+00, 4.461200e+00, 3.303100e+00}, {1.480000e-01, 1.464300e+00, 9.232000e+00, 4.988070e+01, 1.480937e+02}}; + case 39: + return {{3.234000e-01, 1.273700e+00, 3.211500e+00, 4.056300e+00, 3.796200e+00}, {1.244000e-01, 1.194800e+00, 7.275600e+00, 3.414300e+01, 1.112079e+02}}; + case 40: + return {{2.997000e-01, 1.187900e+00, 3.107500e+00, 3.974000e+00, 3.576900e+00}, {1.121000e-01, 1.063800e+00, 6.389100e+00, 2.870810e+01, 9.742890e+01}}; + case 41: + return {{1.680000e-01, 9.370000e-01, 2.730000e+00, 3.815000e+00, 3.005300e+00}, {5.970000e-02, 6.524000e-01, 4.431700e+00, 1.955400e+01, 8.550110e+01}}; + case 42: + return {{3.069000e-01, 1.171400e+00, 3.229300e+00, 3.425400e+00, 2.122400e+00}, {1.101000e-01, 1.022200e+00, 5.961300e+00, 2.519650e+01, 9.358310e+01}}; + case 43: + return {{2.928000e-01, 1.126700e+00, 3.167500e+00, 3.661900e+00, 2.594200e+00}, {1.020000e-01, 9.481000e-01, 5.471300e+00, 2.381530e+01, 8.289910e+01}}; + case 44: + return {{2.604000e-01, 1.044200e+00, 3.076100e+00, 3.217500e+00, 1.944800e+00}, {8.870000e-02, 8.240000e-01, 4.827800e+00, 1.989770e+01, 8.045660e+01}}; + case 45: + return {{2.713000e-01, 1.055600e+00, 3.141600e+00, 3.045100e+00, 1.717900e+00}, {9.070000e-02, 8.324000e-01, 4.770200e+00, 1.978620e+01, 8.025400e+01}}; + case 46: + return {{2.003000e-01, 8.779000e-01, 2.613500e+00, 2.859400e+00, 1.025800e+00}, {6.590000e-02, 6.111000e-01, 3.556300e+00, 1.276380e+01, 4.442830e+01}}; + case 47: + return {{2.739000e-01, 1.050300e+00, 3.156400e+00, 2.754300e+00, 1.432800e+00}, {8.810000e-02, 8.028000e-01, 4.445100e+00, 1.870110e+01, 7.926330e+01}}; + case 48: + return {{3.072000e-01, 1.130300e+00, 3.204600e+00, 2.932900e+00, 1.656000e+00}, {9.660000e-02, 8.856000e-01, 4.627300e+00, 2.067890e+01, 7.347230e+01}}; + case 49: + return {{3.564000e-01, 1.301100e+00, 3.242400e+00, 3.483900e+00, 2.045900e+00}, {1.091000e-01, 1.045200e+00, 5.090000e+00, 2.465780e+01, 8.805130e+01}}; + case 50: + return {{2.966000e-01, 1.115700e+00, 3.097300e+00, 3.815600e+00, 2.528100e+00}, {8.960000e-02, 8.268000e-01, 4.224200e+00, 2.069000e+01, 7.133990e+01}}; + case 51: + return {{2.725000e-01, 1.065100e+00, 2.994000e+00, 4.069700e+00, 2.568200e+00}, {8.090000e-02, 7.488000e-01, 3.871000e+00, 1.888000e+01, 6.064990e+01}}; + case 52: + return {{2.422000e-01, 9.692000e-01, 2.811400e+00, 4.150900e+00, 2.816100e+00}, {7.080000e-02, 6.472000e-01, 3.360900e+00, 1.607520e+01, 5.017240e+01}}; + case 53: + return {{2.617000e-01, 1.032500e+00, 2.809700e+00, 4.480900e+00, 2.319000e+00}, {7.490000e-02, 6.914000e-01, 3.463400e+00, 1.636030e+01, 4.825220e+01}}; + case 54: + return {{2.334000e-01, 9.496000e-01, 2.638100e+00, 4.468000e+00, 2.502000e+00}, {6.550000e-02, 6.050000e-01, 3.038900e+00, 1.408090e+01, 4.100050e+01}}; + case 55: + return {{5.713000e-01, 2.486600e+00, 4.979500e+00, 4.019800e+00, 4.440300e+00}, {1.626000e-01, 1.821300e+00, 1.110490e+01, 4.905680e+01, 2.029987e+02}}; + case 56: + return {{5.229000e-01, 2.287400e+00, 4.724300e+00, 5.080700e+00, 5.638900e+00}, {1.434000e-01, 1.601900e+00, 9.451100e+00, 4.276850e+01, 1.484969e+02}}; + case 57: + return {{5.461000e-01, 2.385600e+00, 5.065300e+00, 5.760100e+00, 4.046300e+00}, {1.479000e-01, 1.655200e+00, 1.000590e+01, 4.732450e+01, 1.458464e+02}}; + case 58: + return {{2.227000e-01, 1.076000e+00, 2.948200e+00, 5.849600e+00, 7.183400e+00}, {5.710000e-02, 5.946000e-01, 3.202200e+00, 1.642530e+01, 9.570300e+01}}; + case 59: + return {{5.237000e-01, 2.291300e+00, 4.616100e+00, 4.723300e+00, 4.817300e+00}, {1.360000e-01, 1.506800e+00, 8.821300e+00, 4.195360e+01, 1.412424e+02}}; + case 60: + return {{5.368000e-01, 2.330100e+00, 4.605800e+00, 4.662100e+00, 4.462200e+00}, {1.378000e-01, 1.514000e+00, 8.871900e+00, 4.359670e+01, 1.418065e+02}}; + case 61: + return {{5.232000e-01, 2.262700e+00, 4.455200e+00, 4.478700e+00, 4.507300e+00}, {1.317000e-01, 1.433600e+00, 8.308700e+00, 4.060100e+01, 1.359196e+02}}; + case 62: + return {{5.162000e-01, 2.230200e+00, 4.344900e+00, 4.359800e+00, 4.429200e+00}, {1.279000e-01, 1.381100e+00, 7.962900e+00, 3.912130e+01, 1.327846e+02}}; + case 63: + return {{5.272000e-01, 2.284400e+00, 4.336100e+00, 4.317800e+00, 4.090800e+00}, {1.285000e-01, 1.394300e+00, 8.108100e+00, 4.096310e+01, 1.341233e+02}}; + case 64: + return {{9.664000e-01, 3.405200e+00, 5.080300e+00, 1.499100e+00, 4.252800e+00}, {2.641000e-01, 2.658600e+00, 1.622130e+01, 8.020600e+01, 9.253590e+01}}; + case 65: + return {{5.110000e-01, 2.157000e+00, 4.030800e+00, 3.993600e+00, 4.246600e+00}, {1.210000e-01, 1.270400e+00, 7.136800e+00, 3.503540e+01, 1.235062e+02}}; + case 66: + return {{4.974000e-01, 2.109700e+00, 3.890600e+00, 3.810000e+00, 4.308400e+00}, {1.157000e-01, 1.210800e+00, 6.737700e+00, 3.241500e+01, 1.169225e+02}}; + case 67: + return {{4.679000e-01, 1.969300e+00, 3.719100e+00, 3.963200e+00, 4.243200e+00}, {1.069000e-01, 1.099400e+00, 5.976900e+00, 2.714910e+01, 9.631190e+01}}; + case 68: + return {{5.034000e-01, 2.108800e+00, 3.823200e+00, 3.729900e+00, 3.896300e+00}, {1.141000e-01, 1.176900e+00, 6.608700e+00, 3.343320e+01, 1.164913e+02}}; + case 69: + return {{4.839000e-01, 2.026200e+00, 3.685100e+00, 3.587400e+00, 4.003700e+00}, {1.081000e-01, 1.101200e+00, 6.111400e+00, 3.037280e+01, 1.105988e+02}}; + case 70: + return {{5.221000e-01, 2.169500e+00, 3.756700e+00, 3.668500e+00, 3.427400e+00}, {1.148000e-01, 1.186000e+00, 6.752000e+00, 3.568070e+01, 1.180692e+02}}; + case 71: + return {{4.680000e-01, 1.946600e+00, 3.542800e+00, 3.849000e+00, 3.659400e+00}, {1.015000e-01, 1.019500e+00, 5.605800e+00, 2.748990e+01, 9.528460e+01}}; + case 72: + return {{4.048000e-01, 1.737000e+00, 3.339900e+00, 3.944800e+00, 3.729300e+00}, {8.680000e-02, 8.585000e-01, 4.637800e+00, 2.169000e+01, 8.024080e+01}}; + case 73: + return {{3.835000e-01, 1.674700e+00, 3.298600e+00, 4.046200e+00, 3.430300e+00}, {8.100000e-02, 8.020000e-01, 4.354500e+00, 1.996440e+01, 7.363370e+01}}; + case 74: + return {{3.661000e-01, 1.619100e+00, 3.245500e+00, 4.085600e+00, 3.206400e+00}, {7.610000e-02, 7.543000e-01, 4.095200e+00, 1.828860e+01, 6.809670e+01}}; + case 75: + return {{3.933000e-01, 1.697300e+00, 3.420200e+00, 4.127400e+00, 2.615800e+00}, {8.060000e-02, 7.972000e-01, 4.423700e+00, 1.956920e+01, 6.874770e+01}}; + case 76: + return {{3.854000e-01, 1.655500e+00, 3.412900e+00, 4.111100e+00, 2.410600e+00}, {7.870000e-02, 7.638000e-01, 4.244100e+00, 1.837000e+01, 6.510710e+01}}; + case 77: + return {{3.510000e-01, 1.562000e+00, 3.294600e+00, 4.061500e+00, 2.438200e+00}, {7.060000e-02, 6.904000e-01, 3.826600e+00, 1.608120e+01, 5.876380e+01}}; + case 78: + return {{3.083000e-01, 1.415800e+00, 2.966200e+00, 3.934900e+00, 2.170900e+00}, {6.090000e-02, 5.993000e-01, 3.192100e+00, 1.252850e+01, 4.976750e+01}}; + case 79: + return {{3.055000e-01, 1.394500e+00, 2.961700e+00, 3.899000e+00, 2.002600e+00}, {5.960000e-02, 5.827000e-01, 3.103500e+00, 1.196930e+01, 4.791060e+01}}; + case 80: + return {{3.593000e-01, 1.573600e+00, 3.523700e+00, 3.810900e+00, 1.695300e+00}, {6.940000e-02, 6.758000e-01, 3.845700e+00, 1.562030e+01, 5.666140e+01}}; + case 81: + return {{3.511000e-01, 1.548900e+00, 3.567600e+00, 4.090000e+00, 2.525100e+00}, {6.720000e-02, 6.522000e-01, 3.742000e+00, 1.597910e+01, 6.513540e+01}}; + case 82: + return {{3.540000e-01, 1.545300e+00, 3.597500e+00, 4.315200e+00, 2.774300e+00}, {6.680000e-02, 6.465000e-01, 3.696800e+00, 1.620560e+01, 6.149090e+01}}; + case 83: + return {{3.530000e-01, 1.525800e+00, 3.581500e+00, 4.553200e+00, 3.071400e+00}, {6.610000e-02, 6.324000e-01, 3.590600e+00, 1.599620e+01, 5.757600e+01}}; + case 84: + return {{3.673000e-01, 1.577200e+00, 3.707900e+00, 4.858200e+00, 2.844000e+00}, {6.780000e-02, 6.527000e-01, 3.739600e+00, 1.706680e+01, 5.597890e+01}}; + case 85: + return {{3.547000e-01, 1.520600e+00, 3.562100e+00, 5.018400e+00, 3.007500e+00}, {6.490000e-02, 6.188000e-01, 3.469600e+00, 1.560900e+01, 4.948180e+01}}; + case 86: + return {{4.586000e-01, 1.778100e+00, 3.987700e+00, 5.727300e+00, 1.546000e+00}, {8.310000e-02, 7.840000e-01, 4.359900e+00, 2.001280e+01, 6.215350e+01}}; + case 87: + return {{8.282000e-01, 2.994100e+00, 5.659700e+00, 4.929200e+00, 4.288900e+00}, {1.515000e-01, 1.616300e+00, 9.775200e+00, 4.284800e+01, 1.907366e+02}}; + case 88: + return {{1.412900e+00, 4.426900e+00, 7.046000e+00, -1.057300e+00, 8.643000e+00}, {2.921000e-01, 3.138100e+00, 1.967670e+01, 1.020436e+02, 1.139798e+02}}; + case 89: + return {{7.169000e-01, 2.571000e+00, 5.179100e+00, 6.348400e+00, 5.647400e+00}, {1.263000e-01, 1.290000e+00, 7.368600e+00, 3.244900e+01, 1.180558e+02}}; + case 90: + return {{6.958000e-01, 2.493600e+00, 5.126900e+00, 6.698800e+00, 5.079900e+00}, {1.211000e-01, 1.224700e+00, 6.939800e+00, 3.009910e+01, 1.051960e+02}}; + case 91: + return {{1.250200e+00, 4.228400e+00, 7.048900e+00, 1.139000e+00, 5.822200e+00}, {2.415000e-01, 2.644200e+00, 1.633130e+01, 7.357570e+01, 9.194010e+01}}; + case 92: + return {{6.410000e-01, 2.264300e+00, 4.871300e+00, 5.928700e+00, 5.393500e+00}, {1.097000e-01, 1.064400e+00, 5.790700e+00, 2.502610e+01, 1.013899e+02}}; + case 93: + return {{6.938000e-01, 2.465200e+00, 5.122700e+00, 5.596500e+00, 4.854300e+00}, {1.171000e-01, 1.175700e+00, 6.405300e+00, 2.752170e+01, 1.030482e+02}}; + case 94: + return {{6.902000e-01, 2.450900e+00, 5.128400e+00, 5.033900e+00, 4.857500e+00}, {1.153000e-01, 1.154500e+00, 6.229100e+00, 2.707410e+01, 1.113150e+02}}; + case 95: + return {{7.577000e-01, 2.726400e+00, 5.418400e+00, 4.819800e+00, 4.101300e+00}, {1.257000e-01, 1.304400e+00, 7.103500e+00, 3.246490e+01, 1.188647e+02}}; + case 96: + return {{7.567000e-01, 2.756500e+00, 5.436400e+00, 5.191800e+00, 3.564300e+00}, {1.239000e-01, 1.297900e+00, 7.079800e+00, 3.278710e+01, 1.101512e+02}}; + case 97: + return {{7.492000e-01, 2.726700e+00, 5.352100e+00, 5.036900e+00, 3.532100e+00}, {1.217000e-01, 1.265100e+00, 6.810100e+00, 3.160880e+01, 1.064853e+02}}; + case 98: + return {{8.100000e-01, 3.000100e+00, 5.463500e+00, 4.175600e+00, 3.506600e+00}, {1.310000e-01, 1.403800e+00, 7.605700e+00, 3.401860e+01, 9.052260e+01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 4: Kirkland parameterization - 3 yukawa + 3 Gaussians - [0, 12] + LNL_Coef_cpu load_feg_kirkland_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{4.20298320e-03, 6.27762505e-02, 3.00907347e-02, 6.77756695e-02, 3.56609240e-03, 2.76135815e-02}, {2.25350888e-01, 2.25366950e-01, 2.25331756e-01, 4.38854001e+00, 4.03884823e-01, 1.44490166e+00}}; + case 2: + return {{1.87544000e-05, 4.10595800e-04, 1.96300059e-01, 8.36015740e-03, 2.95102022e-02, 4.65900000e-07}, {2.12427997e-01, 3.32212279e-01, 5.17325152e-01, 3.66668239e-01, 1.37171827e+00, 3.75768025e+04}}; + case 3: + return {{7.45843816e-02, 7.15382250e-02, 1.45315229e-01, 1.12125769e+00, 2.51736530e-03, 3.58434971e-01}, {8.81151424e-01, 4.59142904e-02, 8.81301714e-01, 1.88483665e+01, 1.59189995e-01, 6.12371000e+00}}; + case 4: + return {{6.11642897e-02, 1.25755034e-01, 2.00831548e-01, 7.87242876e-01, 1.58847850e-03, 2.73962031e-01}, {9.90182132e-02, 9.90272412e-02, 1.87392509e+00, 9.32794929e+00, 8.91900236e-02, 3.20687658e+00}}; + case 5: + return {{1.25716066e-01, 1.73314452e-01, 1.84774811e-01, 1.95250221e-01, 5.29642075e-01, 1.08230500e-03}, {1.48258830e-01, 1.48257216e-01, 3.34227311e+00, 1.97339463e+00, 5.70035553e+00, 5.64857237e-02}}; + case 6: + return {{2.12080767e-01, 1.99811865e-01, 1.68254385e-01, 1.42048360e-01, 3.63830672e-01, 8.35012000e-04}, {2.08605417e-01, 2.08610186e-01, 5.57870773e+00, 1.33311887e+00, 3.80800263e+00, 4.03982620e-02}}; + case 7: + return {{5.33015554e-01, 5.29008883e-02, 9.24159648e-02, 2.61799101e-01, 8.80262100e-04, 1.10166555e-01}, {2.90952515e-01, 1.03547896e+01, 1.03540028e+01, 2.76252723e+00, 3.47681236e-02, 9.93421736e-01}}; + case 8: + return {{3.39969204e-01, 3.07570172e-01, 1.30369072e-01, 8.83326058e-02, 1.96586700e-01, 9.96220000e-04}, {3.81570280e-01, 3.81571436e-01, 1.91919745e+01, 7.60635525e-01, 2.07401094e+00, 3.03266869e-02}}; + case 9: + return {{2.30560593e-01, 5.26889648e-01, 1.24346755e-01, 1.24616890e-03, 7.20452555e-02, 1.53075777e-01}, {4.80754213e-01, 4.80763895e-01, 3.95306720e+01, 2.62181803e-02, 5.92495593e-01, 1.59127671e+00}}; + case 10: + return {{4.08371771e-01, 4.54418858e-01, 1.44564923e-01, 5.91531395e-02, 1.24003718e-01, 1.64986040e-03}, {5.88228627e-01, 5.88288655e-01, 1.21246013e+02, 4.63963540e-01, 1.23413025e+00, 2.05869217e-02}}; + case 11: + return {{1.36471662e-01, 7.70677865e-01, 1.56862014e-01, 9.96821513e-01, 3.80304670e-02, 1.27685089e-01}, {4.99965301e-02, 8.81899664e-01, 1.61768579e+01, 2.00132610e+01, 2.60516254e-01, 6.99559329e-01}}; + case 12: + return {{3.04384121e-01, 7.56270563e-01, 1.01164809e-01, 3.45203403e-02, 9.71751327e-01, 1.20593012e-01}, {8.42014377e-02, 1.64065598e+00, 2.97142975e+01, 2.16596094e-01, 1.21236852e+01, 5.60865838e-01}}; + case 13: + return {{7.77419424e-01, 5.78312036e-02, 4.26386499e-01, 1.13407220e-01, 7.90114035e-01, 3.23293496e-02}, {2.71058227e+00, 7.17532098e+01, 9.13331555e-02, 4.48867451e-01, 8.66366718e+00, 1.78503463e-01}}; + case 14: + return {{1.06543892e+00, 1.20143691e-01, 1.80915263e-01, 1.12065620e+00, 3.05452816e-02, 1.59963502e+00}, {1.04118455e+00, 6.87113368e+01, 8.87533926e-02, 3.70062619e+00, 2.14097897e-01, 9.99096638e+00}}; + case 15: + return {{1.05284447e+00, 2.99440284e-01, 1.17460748e-01, 9.60643452e-01, 2.63555748e-02, 1.38059330e+00}, {1.31962590e+00, 1.28460520e-01, 1.02190163e+02, 2.87477555e+00, 1.82076844e-01, 7.49165526e+00}}; + case 16: + return {{1.01646916e+00, 4.41766748e-01, 1.21503863e-01, 8.27966670e-01, 2.33022533e-02, 1.18302846e+00}, {1.69181965e+00, 1.74180288e-01, 1.67011091e+02, 2.30342810e+00, 1.56954150e-01, 5.85782891e+00}}; + case 17: + return {{9.44221116e-01, 4.37322049e-01, 2.54547926e-01, 5.47763323e-02, 8.00087488e-01, 1.07488641e-02}, {2.40052374e-01, 9.30510439e+00, 9.30486346e+00, 1.68655688e-01, 2.97849774e+00, 6.84240646e-02}}; + case 18: + return {{1.06983288e+00, 4.24631786e-01, 2.43897949e-01, 4.79446296e-02, 7.64958952e-01, 8.23128430e-03}, {2.87791022e-01, 1.24156957e+01, 1.24158868e+01, 1.36979796e-01, 2.43940729e+00, 5.27258749e-02}}; + case 19: + return {{6.92717865e-01, 9.65161085e-01, 1.48466588e-01, 2.64645027e-02, 1.80883768e+00, 5.43900018e-01}, {7.10849990e+00, 3.57532901e-01, 3.93763275e-02, 1.03591321e-01, 3.22845199e+01, 1.67791374e+00}}; + case 20: + return {{3.66902871e-01, 8.66378999e-01, 6.67203300e-01, 4.87743636e-01, 1.82406314e+00, 2.20248453e-02}, {6.14274129e-02, 5.70881727e-01, 7.82965639e+00, 1.32531318e+00, 2.10056032e+01, 9.11853450e-02}}; + case 21: + return {{3.78871777e-01, 9.00022505e-01, 7.15288914e-01, 1.88640973e-02, 4.07945949e-01, 1.61786540e+00}, {6.98910162e-02, 5.21061541e-01, 7.87707920e+00, 8.17512708e-02, 1.11141388e+00, 1.80840759e+01}}; + case 22: + return {{3.62383267e-01, 9.84232966e-01, 7.41715642e-01, 3.62555269e-01, 1.49159390e+00, 1.61659509e-02}, {7.54707114e-02, 4.97757309e-01, 8.17659391e+00, 9.55524906e-01, 1.62221677e+01, 7.33140839e-02}}; + case 23: + return {{3.52961378e-01, 7.46791014e-01, 1.08364068e+00, 1.39013610e+00, 3.31273356e-01, 1.40422612e-02}, {8.19204103e-02, 8.81189511e+00, 5.10646075e-01, 1.48901841e+01, 8.38543079e-01, 6.57432678e-02}}; + case 24: + return {{1.34348379e+00, 5.07040328e-01, 4.26358955e-01, 1.17241826e-02, 5.11966516e-01, 3.38285828e-01}, {1.25814353e+00, 1.15042811e+01, 8.53660389e-02, 6.00177061e-02, 1.53772451e+00, 6.62418319e-01}}; + case 25: + return {{3.26697613e-01, 7.17297000e-01, 1.33212464e+00, 2.80801702e-01, 1.15499241e+00, 1.11984488e-02}, {8.88813083e-02, 1.11300198e+01, 5.82141104e-01, 6.71583145e-01, 1.26825395e+01, 5.32334467e-02}}; + case 26: + return {{3.13454847e-01, 6.89290016e-01, 1.47141531e+00, 1.03298688e+00, 2.58280285e-01, 1.03460690e-02}, {8.99325756e-02, 1.30366038e+01, 6.33345291e-01, 1.16783425e+01, 6.09116446e-01, 4.81610627e-02}}; + case 27: + return {{3.15878278e-01, 1.60139005e+00, 6.56394338e-01, 9.36746624e-01, 9.77562650e-03, 2.38378578e-01}, {9.46683246e-02, 6.99436449e-01, 1.56954403e+01, 1.09392410e+01, 4.37446816e-02, 5.56286483e-01}}; + case 28: + return {{1.72254630e+00, 3.29543044e-01, 6.23007200e-01, 9.43496510e-03, 8.54063515e-01, 2.21073515e-01}, {7.76606908e-01, 1.02262360e-01, 1.94156207e+01, 3.98684596e-02, 1.04078166e+01, 5.10869330e-01}}; + case 29: + return {{3.58774531e-01, 1.76181348e+00, 6.36905053e-01, 7.44930670e-03, 1.89002347e-01, 2.29619589e-01}, {1.06153463e-01, 1.01640995e+00, 1.53659093e+01, 3.85345989e-02, 3.98427790e-01, 9.01419843e-01}}; + case 30: + return {{5.70893973e-01, 1.98908856e+00, 3.06060585e-01, 2.35600223e-01, 3.97061102e-01, 6.85657230e-03}, {1.26534614e-01, 2.17781965e+00, 3.78619003e+01, 3.67019041e-01, 8.66419596e-01, 3.35778823e-02}}; + case 31: + return {{6.25528464e-01, 2.05302901e+00, 2.89608120e-01, 2.07910594e-01, 3.45079617e-01, 6.55634300e-03}, {1.10005650e-01, 2.41095786e+00, 4.78685736e+01, 3.27807224e-01, 7.43139061e-01, 3.09411369e-02}}; + case 32: + return {{5.90952690e-01, 5.39980660e-01, 2.00626188e+00, 7.49705041e-01, 1.83581347e-01, 9.52190740e-03}, {1.18375976e-01, 7.18937433e+01, 1.39304889e+00, 6.89943350e+00, 3.64667232e-01, 2.69888650e-02}}; + case 33: + return {{7.77875218e-01, 5.93848150e-01, 1.95918751e+00, 1.79880226e-01, 8.63267222e-01, 9.59053430e-03}, {1.50733157e-01, 1.42882209e+02, 1.74750339e+00, 3.31800852e-01, 5.85490274e+00, 2.33777569e-02}}; + case 34: + return {{9.58390681e-01, 6.03851342e-01, 1.90828931e+00, 1.73885956e-01, 9.35265145e-01, 8.62254660e-03}, {1.83775557e-01, 1.96819224e+02, 2.15082053e+00, 3.00006024e-01, 4.92471215e+00, 2.12308108e-02}}; + case 35: + return {{1.14136170e+00, 5.18118737e-01, 1.85731975e+00, 1.68217399e-01, 9.75705606e-01, 7.24187870e-03}, {2.18708710e-01, 1.93916682e+02, 2.65755396e+00, 2.71719918e-01, 4.19482500e+00, 1.99325718e-02}}; + case 36: + return {{3.24386970e-01, 1.31732163e+00, 1.79912614e+00, 4.29961430e-03, 1.00429433e+00, 1.62188197e-01}, {6.31317973e+01, 2.54706036e-01, 3.23668394e+00, 1.98965610e-02, 3.61094513e+00, 2.45583672e-01}}; + case 37: + return {{2.90445351e-01, 2.44201329e+00, 7.69435449e-01, 1.58687000e+00, 2.81617590e-03, 1.28663830e-01}, {3.68420227e-02, 1.16013332e+00, 1.69591472e+01, 2.53082574e+00, 1.88577417e-02, 2.10753969e-01}}; + case 38: + return {{1.37373086e-02, 1.97548672e+00, 1.59261029e+00, 1.73263882e-01, 4.66280378e+00, 1.61265060e-03}, {1.87469061e-02, 6.36079230e+00, 2.21992482e-01, 2.01624958e-01, 2.53027803e+01, 1.53610568e-02}}; + case 39: + return {{6.75302747e-01, 4.70286720e-01, 2.63497677e+00, 1.09621746e-01, 9.60348773e-01, 5.28921560e-03}, {6.54331847e-02, 1.06108709e+02, 2.06643540e+00, 1.93131925e-01, 1.63310938e+00, 1.66083821e-02}}; + case 40: + return {{2.64365505e+00, 5.54225147e-01, 7.61376625e-01, 6.02946890e-03, 9.91630530e-02, 9.56782020e-01}, {2.20202699e+00, 1.78260107e+02, 7.67218745e-02, 1.55143296e-02, 1.76175995e-01, 1.54330682e+00}}; + case 41: + return {{6.59532875e-01, 1.84545854e+00, 1.25584405e+00, 1.22253422e-01, 7.06638328e-01, 2.62381590e-03}, {8.66145490e-02, 5.94774398e+00, 6.40851475e-01, 1.66646050e-01, 1.62853268e+00, 8.26257860e-03}}; + case 42: + return {{6.10160120e-01, 1.26544000e+00, 1.97428762e+00, 6.48028962e-01, 2.60380820e-03, 1.13887493e-01}, {9.11628054e-02, 5.06776025e-01, 5.89590381e+00, 1.46634108e+00, 7.84336310e-03, 1.55114340e-01}}; + case 43: + return {{8.55189183e-01, 1.66219641e+00, 1.45575475e+00, 1.05445664e-01, 7.71657112e-01, 2.20992640e-03}, {1.02962151e-01, 7.64907000e+00, 1.01639987e+00, 1.42303338e-01, 1.34659349e+00, 7.90358980e-03}}; + case 44: + return {{4.70847093e-01, 1.58180781e+00, 2.02419818e+00, 1.97036260e-03, 6.26912639e-01, 1.02641320e-01}, {9.33029874e-02, 4.52831347e-01, 7.11489023e+00, 7.56181600e-03, 1.25399858e+00, 1.33786087e-01}}; + case 45: + return {{4.20051553e-01, 1.76266507e+00, 2.02735641e+00, 1.45487180e-03, 6.22809600e-01, 9.91529915e-02}, {9.38882628e-02, 4.64441687e-01, 8.19346046e+00, 7.82704520e-03, 1.17194153e+00, 1.24532839e-01}}; + case 46: + return {{2.10475155e+00, 2.03884487e+00, 1.82067264e-01, 9.52040948e-02, 5.91445248e-01, 1.13328680e-03}, {8.68606470e+00, 3.78924449e-01, 1.42921634e-01, 1.17125900e-01, 1.07843808e+00, 7.80252090e-03}}; + case 47: + return {{2.07981390e+00, 4.43170726e-01, 1.96515215e+00, 5.96130591e-01, 4.78016333e-01, 9.46458470e-02}, {9.92540297e+00, 1.04920104e-01, 6.40103839e-01, 8.89594790e-01, 1.98509407e+00, 1.12744464e-01}}; + case 48: + return {{1.63657549e+00, 2.17927989e+00, 7.71300690e-01, 6.64193880e-01, 7.64563285e-01, 8.61126689e-02}, {1.24540381e+01, 1.45134660e+00, 1.26695757e-01, 7.77659202e-01, 1.66075210e+00, 1.05728357e-01}}; + case 49: + return {{2.24820632e+00, 1.64706864e+00, 7.88679265e-01, 8.12579069e-02, 6.68280346e-01, 6.38467475e-01}, {1.51913507e+00, 1.30113424e+01, 1.06128184e-01, 9.94045620e-02, 1.49742063e+00, 7.18422635e-01}}; + case 50: + return {{2.16644620e+00, 6.88691021e-01, 1.92431751e+00, 5.65359888e-01, 9.18683861e-01, 7.80542213e-02}, {1.13174909e+01, 1.10131285e-01, 6.74464853e-01, 7.33564610e-01, 1.02310312e+01, 9.31104308e-02}}; + case 51: + return {{1.73662114e+00, 9.99871380e-01, 2.13972409e+00, 5.60566526e-01, 9.93772747e-01, 7.37374982e-02}, {8.84334719e-01, 1.38462121e-01, 1.19666432e+01, 6.72672880e-01, 8.72330411e+00, 8.78577715e-02}}; + case 52: + return {{2.09383882e+00, 1.56940519e+00, 1.30941993e+00, 6.98067804e-02, 1.04969537e+00, 5.55594354e-01}, {1.26856869e+01, 1.21236537e+00, 1.66633292e-01, 8.30817576e-02, 7.43147857e+00, 6.17487676e-01}}; + case 53: + return {{1.60186925e+00, 1.98510264e+00, 1.48226200e+00, 5.53807199e-01, 1.11728722e+00, 6.60720847e-02}, {1.95031538e-01, 1.36976183e+01, 1.80304795e+00, 5.67912340e-01, 6.40879878e+00, 7.86615429e-02}}; + case 54: + return {{1.60015487e+00, 1.71644581e+00, 1.84968351e+00, 6.23813648e-02, 1.21387555e+00, 5.54051946e-01}, {2.92913354e+00, 1.55882990e+01, 2.22525983e-01, 7.45581223e-02, 5.56013271e+00, 5.21994521e-01}}; + case 55: + return {{2.95236854e+00, 4.28105721e-01, 1.89599233e+00, 5.48012938e-02, 4.70838600e+00, 5.90356719e-01}, {6.01461952e+00, 4.64151246e+01, 1.80109756e-01, 7.12799633e-02, 4.56702799e+01, 4.70236310e-01}}; + case 56: + return {{3.19434243e+00, 1.98289586e+00, 1.55121052e-01, 6.73222354e-02, 4.48474211e+00, 5.42674414e-01}, {9.27352241e+00, 2.28741632e-01, 3.82000231e-02, 7.30961745e-02, 2.95703565e+01, 4.08647015e-01}}; + case 57: + return {{2.05036425e+00, 1.42114311e-01, 3.23538151e+00, 6.34683429e-02, 3.97960586e+00, 5.20116711e-01}, {2.20348417e-01, 3.96438056e-02, 9.56979169e+00, 6.92443091e-02, 2.53178406e+01, 3.83614098e-01}}; + case 58: + return {{3.22990759e+00, 1.57618307e-01, 2.13477838e+00, 5.01907609e-01, 3.80889010e+00, 5.96625028e-02}, {9.94660135e+00, 4.15378676e-02, 2.40480572e-01, 3.66252019e-01, 2.43275968e+01, 6.59653503e-02}}; + case 59: + return {{1.58189324e-01, 3.18141995e+00, 2.27622140e+00, 3.97705472e+00, 5.58448277e-02, 4.85207954e-01}, {3.91309056e-02, 1.04139545e+01, 2.81671757e-01, 2.61872978e+01, 6.30921695e-02, 3.54234369e-01}}; + case 60: + return {{1.81379417e-01, 3.17616396e+00, 2.35221519e+00, 3.83125763e+00, 5.25889976e-02, 4.70090742e-01}, {4.37324793e-02, 1.07842572e+01, 3.05571833e-01, 2.54745408e+01, 6.02676073e-02, 3.39017003e-01}}; + case 61: + return {{1.92986811e-01, 2.43756023e+00, 3.17248504e+00, 3.58105414e+00, 4.56529394e-01, 4.94812177e-02}, {4.37785970e-02, 3.29336996e-01, 1.11259996e+01, 2.46709586e+01, 3.24990282e-01, 5.76553100e-02}}; + case 62: + return {{2.12002595e-01, 3.16891754e+00, 2.51503494e+00, 4.44080845e-01, 3.36742101e+00, 4.65652543e-02}, {4.57703608e-02, 1.14536599e+01, 3.55561054e-01, 3.11953363e-01, 2.40291435e+01, 5.52266819e-02}}; + case 63: + return {{2.59355002e+00, 3.16557522e+00, 2.29402652e-01, 4.32257780e-01, 3.17261920e+00, 4.37958317e-02}, {3.82452612e-01, 1.17675155e+01, 4.76642249e-02, 2.99719833e-01, 2.34462738e+01, 5.29440680e-02}}; + case 64: + return {{3.19144939e+00, 2.55766431e+00, 3.32681934e-01, 4.14243130e-02, 2.61036728e+00, 4.20526863e-01}, {1.20224655e+01, 4.08338876e-01, 5.85819814e-02, 5.06771477e-02, 1.99344244e+01, 2.85686240e-01}}; + case 65: + return {{2.59407462e-01, 3.16177855e+00, 2.75095751e+00, 2.79247686e+00, 3.85931001e-02, 4.10881708e-01}, {5.04689354e-02, 1.23140183e+01, 4.38337626e-01, 2.23797309e+01, 4.87920992e-02, 2.77622892e-01}}; + case 66: + return {{3.16055396e+00, 2.82751709e+00, 2.75140255e-01, 4.00967160e-01, 2.63110834e+00, 3.61333817e-02}, {1.25470414e+01, 4.67899094e-01, 5.23226982e-02, 2.67614884e-01, 2.19498166e+01, 4.68871497e-02}}; + case 67: + return {{2.88642467e-01, 2.90567296e+00, 3.15960159e+00, 3.91280259e-01, 2.48596038e+00, 3.37664478e-02}, {5.40507687e-02, 4.97581077e-01, 1.27599505e+01, 2.58151831e-01, 2.15400972e+01, 4.50664323e-02}}; + case 68: + return {{3.15573213e+00, 3.11519560e-01, 2.97722406e+00, 3.81563854e-01, 2.40247532e+00, 3.15224214e-02}, {1.29729009e+01, 5.81399387e-02, 5.31213394e-01, 2.49195776e-01, 2.13627616e+01, 4.33253257e-02}}; + case 69: + return {{3.15591970e+00, 3.22544710e-01, 3.05569053e+00, 2.92845100e-02, 3.72487205e-01, 2.27833695e+00}, {1.31232407e+01, 5.97223323e-02, 5.61876773e-01, 4.16534255e-02, 2.40821967e-01, 2.10034185e+01}}; + case 70: + return {{3.10794704e+00, 3.14091221e+00, 3.75660454e-01, 3.61901097e-01, 2.45409082e+00, 2.72383990e-02}, {6.06347847e-01, 1.33705269e+01, 7.29814740e-02, 2.32652051e-01, 2.12695209e+01, 3.99969597e-02}}; + case 71: + return {{3.11446863e+00, 5.39634353e-01, 3.06460915e+00, 2.58563745e-02, 2.13983556e+00, 3.47788231e-01}, {1.38968881e+01, 8.91708508e-02, 6.79919563e-01, 3.82808522e-02, 1.80078788e+01, 2.22706591e-01}}; + case 72: + return {{3.01166899e+00, 3.16284788e+00, 6.33421771e-01, 3.41417198e-01, 1.53566013e+00, 2.40723773e-02}, {7.10401889e-01, 1.38262192e+01, 9.48486572e-02, 2.14129678e-01, 1.55298698e+01, 3.67833690e-02}}; + case 73: + return {{3.20236821e+00, 8.30098413e-01, 2.86552297e+00, 2.24813887e-02, 1.40165263e+00, 3.33740596e-01}, {1.38446369e+01, 1.18381581e-01, 7.66369118e-01, 3.52934622e-02, 1.46148877e+01, 2.05704486e-01}}; + case 74: + return {{9.24906855e-01, 2.75554557e+00, 3.30440060e+00, 3.29973862e-01, 1.09916444e+00, 2.06498883e-02}, {1.28663377e-01, 7.65826479e-01, 1.34471170e+01, 1.98218895e-01, 1.35087534e+01, 3.38918459e-02}}; + case 75: + return {{1.96952105e+00, 1.21726619e+00, 4.10391685e+00, 2.90791978e-02, 2.30696669e-01, 6.08840299e-01}, {4.98830620e+01, 1.33243809e-01, 1.84396916e+00, 2.84192813e-02, 1.90968784e-01, 1.37090356e+00}}; + case 76: + return {{2.06385867e+00, 1.29603406e+00, 3.96920673e+00, 2.69835487e-02, 2.31083999e-01, 6.30466774e-01}, {4.05671697e+01, 1.46559047e-01, 1.82561596e+00, 2.84172045e-02, 1.79765184e-01, 1.38911543e+00}}; + case 77: + return {{2.21522726e+00, 1.37573155e+00, 3.78244405e+00, 2.44643240e-02, 2.36932016e-01, 6.48471412e-01}, {3.24464090e+01, 1.60920048e-01, 1.78756553e+00, 2.82909938e-02, 1.70692368e-01, 1.37928390e+00}}; + case 78: + return {{9.84697940e-01, 2.73987079e+00, 3.61696715e+00, 3.02885602e-01, 2.78370726e-01, 1.52124129e-02}, {1.60910839e-01, 7.18971667e-01, 1.29281016e+01, 1.70134854e-01, 1.49862703e+00, 2.83510822e-02}}; + case 79: + return {{9.61263398e-01, 3.69581030e+00, 2.77567491e+00, 2.95414176e-01, 3.11475743e-01, 1.43237267e-02}, {1.70932277e-01, 1.29335319e+01, 6.89997070e-01, 1.63525510e-01, 1.39200901e+00, 2.71265337e-02}}; + case 80: + return {{1.29200491e+00, 2.75161478e+00, 3.49387949e+00, 2.77304636e-01, 4.30232810e-01, 1.48294351e-02}, {1.83432865e-01, 9.42368371e-01, 1.46235654e+01, 1.55110144e-01, 1.28871670e+00, 2.61903834e-02}}; + case 81: + return {{3.75964730e+00, 3.21195904e+00, 6.47767825e-01, 2.76123274e-01, 3.18838810e-01, 1.31668419e-02}, {1.35041513e+01, 6.66330993e-01, 9.22518234e-02, 1.50312897e-01, 1.12565588e+00, 2.48879842e-02}}; + case 82: + return {{1.00795975e+00, 3.09796153e+00, 3.61296864e+00, 2.62401476e-01, 4.05621995e-01, 1.31812509e-02}, {1.17268427e-01, 8.80453235e-01, 1.47325812e+01, 1.43491014e-01, 1.04103506e+00, 2.39575415e-02}}; + case 83: + return {{1.59826875e+00, 4.38233925e+00, 2.06074719e+00, 1.94426023e-01, 8.22704978e-01, 2.33226953e-02}, {1.56897471e-01, 2.47094692e+00, 5.72438972e+01, 1.32979109e-01, 9.56532528e-01, 2.23038435e-02}}; + case 84: + return {{1.71463223e+00, 2.14115960e+00, 4.37512413e+00, 2.16216680e-02, 1.97843837e-01, 6.52047920e-01}, {9.79262841e+01, 2.10193717e-01, 3.66948812e+00, 1.98456144e-02, 1.33758807e-01, 7.80432104e-01}}; + case 85: + return {{1.48047794e+00, 2.09174630e+00, 4.75246033e+00, 1.85643958e-02, 2.05859375e-01, 7.13540948e-01}, {1.25943919e+02, 1.83803008e-01, 4.19890596e+00, 1.81383503e-02, 1.33035404e-01, 7.03031938e-01}}; + case 86: + return {{6.30022295e-01, 3.80962881e+00, 3.89756067e+00, 2.40755100e-01, 2.62868577e+00, 3.14285931e-02}, {1.40909762e-01, 3.08515540e+01, 6.51559763e-01, 1.08899672e-01, 6.42383261e+00, 2.42346699e-02}}; + case 87: + return {{5.23288135e+00, 2.48604205e+00, 3.23431354e-01, 2.55403596e-01, 5.53607228e-01, 5.75278890e-03}, {8.60599536e+00, 3.04543982e-01, 3.87759096e-02, 1.28717724e-01, 5.36977452e-01, 1.29417790e-02}}; + case 88: + return {{1.44192685e+00, 3.55291725e+00, 3.91259586e+00, 2.16173519e-01, 3.94191605e+00, 4.60422605e-02}, {1.18740873e-01, 1.01739750e+00, 6.31814783e+01, 9.55806441e-02, 3.50602732e+01, 2.20850385e-02}}; + case 89: + return {{1.45864127e+00, 4.18945405e+00, 3.65866182e+00, 2.08479229e-01, 3.16528117e+00, 5.23892556e-02}, {1.07760494e-01, 8.89090649e+01, 1.05088931e+00, 9.09335557e-02, 3.13297788e+01, 2.08807697e-02}}; + case 90: + return {{1.19014064e+00, 2.55380607e+00, 4.68110181e+00, 2.26121303e-01, 3.58250545e-01, 7.82263950e-03}, {7.73468729e-02, 6.59693681e-01, 1.28013896e+01, 1.08632194e-01, 4.56765664e-01, 1.62623474e-02}}; + case 91: + return {{4.68537504e+00, 2.98413708e+00, 8.91988061e-01, 2.24825384e-01, 3.04444846e-01, 9.48162710e-03}, {1.44503632e+01, 5.56438592e-01, 6.69512914e-02, 1.03235396e-01, 4.27255647e-01, 1.77730611e-02}}; + case 92: + return {{4.63343606e+00, 3.18157056e+00, 8.76455075e-01, 2.21685477e-01, 2.72917100e-01, 1.11737298e-02}, {1.63377267e+01, 5.69517868e-01, 6.88860012e-02, 9.84254550e-02, 4.09470917e-01, 1.86215410e-02}}; + case 93: + return {{4.56773888e+00, 3.40325179e+00, 8.61841923e-01, 2.19728870e-01, 2.38176903e-01, 1.38306499e-02}, {1.90992795e+01, 5.90099634e-01, 7.03204851e-02, 9.36334280e-02, 3.93554882e-01, 1.94437286e-02}}; + case 94: + return {{5.45671123e+00, 1.11687906e-01, 3.30260343e+00, 1.84568319e-01, 4.93644263e-01, 3.57484743e+00}, {1.01892720e+01, 3.98131313e-02, 3.14622212e-01, 1.04220860e-01, 4.63080540e-01, 2.19369542e+01}}; + case 95: + return {{5.38321999e+00, 1.23343236e-01, 3.46469090e+00, 1.75437132e-01, 3.39800073e+00, 4.69459519e-01}, {1.07289857e+01, 4.15137806e-02, 3.39326208e-01, 9.98932346e-02, 2.11601535e+01, 4.51996970e-01}}; + case 96: + return {{5.38402377e+00, 3.49861264e+00, 1.88039547e-01, 1.69143137e-01, 3.19595016e+00, 4.64393059e-01}, {1.11211419e+01, 3.56750210e-01, 5.39853583e-02, 9.60082633e-02, 1.80694389e+01, 4.36318197e-01}}; + case 97: + return {{3.66090688e+00, 2.03054678e-01, 5.30697515e+00, 1.60934046e-01, 3.04808401e+00, 4.43610295e-01}, {3.84420906e-01, 5.48547131e-02, 1.17150262e+01, 9.21020329e-02, 1.73525367e+01, 4.27132359e-01}}; + case 98: + return {{3.94150390e+00, 5.16915345e+00, 1.61941074e-01, 4.15299561e-01, 2.91761325e+00, 1.51474927e-01}, {4.18246722e-01, 1.25201788e+01, 4.81540117e-02, 4.24913856e-01, 1.90899693e+01, 8.81568925e-02}}; + case 99: + return {{4.09780623e+00, 5.10079393e+00, 1.74617289e-01, 2.76774658e+00, 1.44496639e-01, 4.02772109e-01}, {4.46021145e-01, 1.31768613e+01, 5.02742829e-02, 1.84815393e+01, 8.46232592e-02, 4.17640100e-01}}; + case 100: + return {{4.24934820e+00, 5.03556594e+00, 1.88920613e-01, 3.94356058e-01, 2.61213100e+00, 1.38001927e-01}, {4.75263933e-01, 1.38570834e+01, 5.26975158e-02, 4.11193751e-01, 1.78537905e+01, 8.12774434e-02}}; + case 101: + return {{2.00942931e-01, 4.40119869e+00, 4.97250102e+00, 2.47530599e+00, 3.86883197e-01, 1.31936095e-01}, {5.48366518e-02, 5.04248434e-01, 1.45721366e+01, 1.72978308e+01, 4.05043898e-01, 7.80821071e-02}}; + case 102: + return {{2.16052899e-01, 4.91106799e+00, 4.54862870e+00, 2.36114249e+00, 1.26277292e-01, 3.81364501e-01}, {5.83584058e-02, 1.53264212e+01, 5.34434760e-01, 1.68164803e+01, 7.50304633e-02, 3.99305852e-01}}; + case 103: + return {{4.86738014e+00, 3.19974401e-01, 4.58872425e+00, 1.21482448e-01, 2.31639872e+00, 3.79258137e-01}, {1.60320520e+01, 6.70871138e-02, 5.77039373e-01, 7.22275899e-02, 1.41279737e+01, 3.89973484e-01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + LNL_Coef_cpu load_feg_weickenmeier_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 2: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.542e+00, 8.743e+00, 1.269e+01, 4.371e-01, 5.294e+00, 2.825e+01}}; + case 3: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {6.845e-01, 3.065e+00, 6.240e+00, 1.262e+02, 1.312e+02, 1.318e+02}}; + case 4: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {5.400e-01, 3.388e+00, 5.562e+01, 5.078e+01, 6.701e+01, 9.637e+01}}; + case 5: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {3.314e-01, 2.975e+00, 3.401e+01, 3.598e+01, 3.668e+01, 6.081e+01}}; + case 6: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.946e-01, 3.934e+00, 2.498e+01, 2.528e+01, 2.547e+01, 4.670e+01}}; + case 7: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.393e-01, 4.935e+00, 1.812e+01, 1.570e+01, 1.582e+01, 4.024e+01}}; + case 8: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {6.376e+00, 8.037e+00, 2.721e+01, 1.116e-01, 3.869e-01, 1.090e+01}}; + case 9: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.180e-01, 6.770e+00, 7.051e+00, 6.675e+00, 1.238e+01, 2.808e+01}}; + case 10: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.006e-01, 5.498e+00, 6.281e+00, 7.192e+00, 7.548e+00, 2.326e+01}}; + case 11: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.190e-01, 5.300e+00, 5.319e+00, 5.283e+00, 5.285e+00, 1.282e+02}}; + case 12: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.976e+00, 2.809e+00, 1.639e+01, 5.490e-02, 2.061e+00, 1.217e+02}}; + case 13: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.297e+00, 2.358e+00, 2.499e+01, 7.460e-02, 5.595e-01, 1.285e+02}}; + case 14: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.737e+00, 3.043e+00, 3.057e+01, 5.070e-02, 9.918e-01, 8.618e+01}}; + case 15: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.795e-01, 2.632e+00, 2.676e+00, 3.457e+01, 3.678e+01, 5.406e+01}}; + case 16: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.006e+00, 4.904e+00, 3.135e+01, 3.700e-02, 9.870e-01, 4.494e+01}}; + case 17: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.846e-01, 1.480e+00, 5.210e+00, 2.479e+01, 3.206e+01, 3.910e+01}}; + case 18: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.006e-01, 6.533e+00, 2.272e+01, 1.200e+00, 1.274e+00, 3.626e+01}}; + case 19: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {4.442e-01, 3.367e+00, 1.963e+01, 1.820e-02, 2.351e+01, 2.129e+02}}; + case 20: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {1.827e-01, 2.066e+00, 1.699e+01, 1.158e+01, 1.398e+01, 1.861e+02}}; + case 21: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.425e-01, 1.466e+00, 1.547e+01, 4.243e+00, 9.804e+00, 1.215e+02}}; + case 22: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.278e-01, 1.456e+00, 1.210e+01, 4.617e+00, 1.197e+01, 1.050e+02}}; + case 23: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.313e-01, 1.399e+00, 8.008e+00, 7.981e+00, 1.341e+01, 9.531e+01}}; + case 24: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.231e-01, 2.384e+00, 9.921e+00, 1.648e+00, 1.100e+01, 6.846e+01}}; + case 25: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.817e-01, 3.783e+00, 8.473e+00, 4.690e-02, 8.745e+00, 7.744e+01}}; + case 26: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.470e-01, 6.894e+00, 6.903e+00, 5.690e-02, 3.026e+00, 7.087e+01}}; + case 27: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.071e-01, 3.636e+00, 7.558e+00, 1.280e+00, 5.140e+00, 6.716e+01}}; + case 28: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.107e-01, 1.619e+00, 6.003e+00, 5.975e+00, 6.060e+00, 5.941e+01}}; + case 29: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.129e-01, 1.891e+00, 5.085e+00, 5.073e+00, 5.099e+00, 4.639e+01}}; + case 30: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.021e-01, 1.734e+00, 4.783e+00, 4.807e+00, 5.645e+00, 5.122e+01}}; + case 31: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.064e-01, 1.537e+00, 5.138e+00, 4.743e+00, 5.000e+00, 6.143e+01}}; + case 32: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.580e-02, 1.677e+00, 4.703e+00, 2.912e+00, 7.870e+00, 6.494e+01}}; + case 33: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.430e-02, 2.214e+00, 3.951e+00, 1.521e+00, 1.581e+01, 5.241e+01}}; + case 34: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.250e-02, 1.602e+00, 3.049e+00, 3.185e+00, 1.894e+01, 4.763e+01}}; + case 35: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.250e-02, 1.773e+00, 3.481e+00, 1.884e+00, 2.269e+01, 4.069e+01}}; + case 36: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.932e-01, 2.083e+00, 1.141e+01, 3.330e-02, 2.097e+00, 4.238e+01}}; + case 37: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {1.580e-01, 1.715e+00, 9.392e+00, 1.675e+00, 2.359e+01, 1.525e+02}}; + case 38: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {3.605e-01, 2.128e+00, 1.246e+01, 1.530e-02, 2.108e+00, 1.332e+02}}; + case 39: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.000e-02, 1.414e+00, 2.053e+00, 1.026e+01, 1.075e+01, 9.064e+01}}; + case 40: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.009e-01, 1.154e+00, 2.347e+00, 1.058e+01, 1.095e+01, 8.282e+01}}; + case 41: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.240e-02, 1.170e+00, 5.940e+00, 1.306e+00, 1.343e+01, 6.637e+01}}; + case 42: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.354e-01, 1.248e+00, 7.454e+00, 3.540e-02, 9.914e+00, 6.172e+01}}; + case 43: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.594e-01, 1.182e+00, 8.317e+00, 3.230e-02, 8.323e+00, 6.498e+01}}; + case 44: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {8.600e-02, 1.396e+00, 1.170e+01, 1.396e+00, 3.452e+00, 5.556e+01}}; + case 45: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.210e-02, 1.113e+00, 7.658e+00, 1.126e+00, 8.325e+00, 4.838e+01}}; + case 46: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.010e-02, 1.125e+00, 9.698e+00, 1.085e+00, 5.709e+00, 3.349e+01}}; + case 47: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {8.940e-02, 3.191e+00, 9.100e+00, 8.090e-01, 8.144e-01, 4.134e+01}}; + case 48: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {2.885e-01, 1.613e+00, 8.997e+00, 1.710e-02, 9.467e+00, 5.813e+01}}; + case 49: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {8.950e-02, 1.233e+00, 8.231e+00, 1.224e+00, 7.062e+00, 5.970e+01}}; + case 50: + return {{6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01}, {7.120e-02, 8.553e-01, 6.401e+00, 1.336e+00, 6.382e+00, 5.092e+01}}; + case 51: + return {{6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01}, {3.575e-01, 1.325e+00, 6.517e+00, 3.550e-02, 6.519e+00, 5.081e+01}}; + case 52: + return {{6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01}, {5.009e-01, 3.953e+00, 7.628e+00, 3.010e-02, 5.074e-01, 4.963e+01}}; + case 53: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {8.430e-02, 1.130e+00, 8.862e+00, 1.130e+00, 9.132e+00, 5.602e+01}}; + case 54: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.780e-01, 1.621e+00, 1.145e+01, 2.030e-02, 3.275e+00, 5.144e+01}}; + case 55: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.204e-01, 1.537e+00, 9.816e+00, 4.122e+01, 4.262e+01, 2.243e+02}}; + case 56: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.223e-01, 1.449e+00, 9.502e+00, 4.941e+01, 7.495e+01, 2.170e+02}}; + case 57: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {8.930e-02, 1.262e+00, 8.097e+00, 1.203e+00, 1.766e+01, 1.166e+02}}; + case 58: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {8.500e-02, 1.283e+00, 1.122e+01, 1.327e+00, 4.610e+00, 1.122e+02}}; + case 59: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.810e-02, 1.526e+00, 8.590e+00, 1.239e+00, 2.249e+01, 1.400e+02}}; + case 60: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.410e-02, 1.266e+00, 5.988e+00, 1.779e+01, 1.814e+01, 1.326e+02}}; + case 61: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.450e-02, 1.251e+00, 5.912e+00, 1.629e+01, 1.673e+01, 1.279e+02}}; + case 62: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.060e-02, 1.593e+00, 1.064e+01, 1.789e+00, 2.221e+00, 1.246e+02}}; + case 63: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.049e-01, 1.544e+00, 8.652e+00, 7.093e+00, 5.337e+01, 1.837e+02}}; + case 64: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.340e-02, 1.387e+00, 7.359e+00, 1.551e+00, 2.082e+01, 1.110e+02}}; + case 65: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.019e-01, 1.524e+00, 7.169e+00, 2.086e+01, 4.929e+01, 1.661e+02}}; + case 66: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {8.400e-02, 1.409e+00, 7.140e+00, 1.348e+00, 1.142e+01, 1.080e+02}}; + case 67: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.440e-02, 1.618e+00, 6.271e+00, 4.035e+01, 4.283e+01, 1.306e+02}}; + case 68: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {8.210e-02, 1.251e+00, 4.812e+00, 1.084e+01, 1.090e+01, 1.001e+02}}; + case 69: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.660e-02, 1.602e+00, 5.675e+00, 3.059e+01, 3.113e+01, 1.387e+02}}; + case 70: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.490e-02, 1.602e+00, 5.439e+00, 2.831e+01, 2.928e+01, 1.381e+02}}; + case 71: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.660e-02, 1.568e+00, 5.322e+00, 3.418e+01, 3.525e+01, 1.214e+02}}; + case 72: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.290e-02, 1.555e+00, 5.251e+00, 3.752e+01, 3.888e+01, 1.052e+02}}; + case 73: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {6.300e-02, 8.195e-01, 2.891e+00, 5.543e+00, 5.981e+00, 5.442e+01}}; + case 74: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.900e-02, 1.371e+00, 8.234e+00, 1.383e+00, 1.392e+00, 7.712e+01}}; + case 75: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {5.270e-02, 9.072e-01, 4.438e+00, 9.459e-01, 4.375e+00, 4.398e+01}}; + case 76: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.270e-01, 1.570e+00, 6.345e+00, 1.560e-02, 1.618e+00, 4.616e+01}}; + case 77: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {5.060e-02, 8.677e-01, 5.093e+00, 8.812e-01, 3.569e+00, 3.977e+01}}; + case 78: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {5.250e-02, 8.377e-01, 3.959e+00, 8.152e-01, 6.442e+00, 3.421e+01}}; + case 79: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {5.493e-01, 1.728e+00, 6.720e+00, 2.640e-02, 7.250e-02, 3.546e+01}}; + case 80: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.194e-01, 1.416e+00, 6.682e+00, 1.470e-02, 1.576e+00, 3.716e+01}}; + case 81: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.246e-01, 1.128e+00, 4.303e+00, 1.490e-02, 7.156e+00, 4.309e+01}}; + case 82: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {6.430e-02, 1.194e+00, 7.393e+00, 1.142e+00, 1.289e+00, 5.113e+01}}; + case 83: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {5.380e-02, 8.672e-01, 1.875e+00, 7.648e+00, 7.868e+00, 4.564e+01}}; + case 84: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {5.011e-01, 1.638e+00, 6.786e+00, 2.190e-02, 8.600e-02, 4.673e+01}}; + case 85: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.232e-01, 1.108e+00, 3.591e+00, 1.010e-02, 1.164e+01, 4.507e+01}}; + case 86: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.115e-01, 1.140e+00, 3.415e+00, 1.190e-02, 1.341e+01, 4.311e+01}}; + case 87: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.440e-02, 1.026e+00, 6.255e+00, 3.251e+01, 3.629e+01, 1.491e+02}}; + case 88: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.300e-02, 1.018e+00, 5.896e+00, 1.031e+00, 2.037e+01, 1.153e+02}}; + case 89: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.520e-02, 9.494e-01, 3.725e+00, 1.758e+01, 1.975e+01, 1.091e+02}}; + case 90: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {6.390e-02, 9.019e-01, 4.657e+00, 9.025e-01, 1.571e+01, 8.370e+01}}; + case 91: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.560e-02, 8.492e-01, 4.010e+00, 1.695e+01, 1.779e+01, 1.002e+02}}; + case 92: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.140e-02, 1.149e+00, 9.212e+00, 9.592e-01, 1.203e+00, 1.043e+02}}; + case 93: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {6.920e-02, 9.810e-01, 5.954e+00, 9.909e-01, 2.206e+01, 9.098e+01}}; + case 94: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.140e-02, 9.577e-01, 6.132e+00, 9.744e-01, 1.567e+01, 8.987e+01}}; + case 95: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.300e-02, 9.327e-01, 6.348e+00, 9.103e-01, 1.326e+01, 8.686e+01}}; + case 96: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {5.780e-02, 7.227e-01, 3.011e+00, 9.219e+00, 9.534e+00, 6.587e+01}}; + case 97: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.090e-02, 7.759e-01, 6.143e+00, 1.790e+00, 1.512e+01, 8.357e+01}}; + case 98: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {6.160e-02, 8.136e-01, 6.562e+00, 8.381e-01, 4.189e+00, 6.141e+01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 6: Lobato parameterization - Hydrogen functions - [0, 12] + LNL_Coef_cpu load_feg_lobato_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{5.29176831e-02, 5.29176831e-02, 5.29176831e-02, 5.29176831e-02, 5.29176831e-02}, {2.76376891e+00, 2.76376891e+00, 2.76376891e+00, 2.76376891e+00, 2.76376891e+00}}; + case 2: + return {{1.01746701e-01, 9.49040428e-02, -4.11936715e-02, 5.35294712e-02, 1.34533102e-05}, {1.49190903e+00, 1.01103199e+00, 4.90177989e-01, 4.72138286e-01, 2.12409496e-01}}; + case 3: + return {{6.19087696e-01, 1.72226405e+00, -7.92180777e-01, 8.37330297e-02, 1.01449499e-02}, {1.05523100e+01, 9.23192024e+00, 4.76025486e+00, 5.19986629e-01, 2.14180499e-01}}; + case 4: + return {{1.07960296e+00, 7.13181376e-01, -3.91357690e-01, 1.06852397e-01, 1.86710991e-02}, {6.00019121e+00, 4.10317707e+00, 1.37123895e+00, 5.52847624e-01, 1.53891206e-01}}; + case 5: + return {{1.31485796e+00, 2.52792597e-01, -2.02927098e-01, 2.92299408e-02, 3.54602700e-03}, {3.94681811e+00, 1.91365397e+00, 9.58502173e-01, 1.62817106e-01, 7.77361393e-02}}; + case 6: + return {{7.39281714e-01, 7.50964522e-01, -2.54863292e-01, 1.76229905e-02, 1.34442805e-03}, {3.47855496e+00, 1.63563204e+00, 8.30155313e-01, 9.63626578e-02, 5.00164293e-02}}; + case 7: + return {{3.26442391e-01, 8.36000979e-01, -7.21398070e-02, 1.31275300e-02, 5.07714599e-03}, {3.17208099e+00, 1.59607995e+00, 3.68962586e-01, 9.75946933e-02, 4.86027598e-02}}; + case 8: + return {{7.85341978e-01, 2.52642393e-01, -5.85432090e-02, 1.27868997e-02, 1.97321596e-03}, {1.78015697e+00, 8.17416310e-01, 2.44515404e-01, 6.56605288e-02, 3.27121913e-02}}; + case 9: + return {{6.07230484e-01, 4.81327087e-01, -1.94196299e-01, 7.56342197e-03, 7.61223928e-05}, {1.58934402e+00, 5.77747822e-01, 3.46372694e-01, 3.73525992e-02, 1.65033191e-02}}; + case 10: + return {{6.13327866e-05, 4.95682299e-01, 8.31292927e-01, -5.06411910e-01, 5.32641588e-03}, {1.25770597e+01, 1.38210797e+00, 4.62477595e-01, 3.64122301e-01, 2.77422108e-02}}; + case 11: + return {{2.38567805e+00, -5.41312218e-01, 5.80007017e-01, -4.31193784e-02, 4.69793798e-03}, {1.17757797e+01, 5.18739605e+00, 5.75649977e-01, 1.69096500e-01, 2.32259594e-02}}; + case 12: + return {{2.48242688e+00, -4.73447889e-01, 8.96034002e-01, -3.08043092e-01, 3.78086301e-03}, {7.48703098e+00, 1.11762202e+00, 3.95489693e-01, 2.52319604e-01, 1.92819294e-02}}; + case 13: + return {{2.84625793e+00, -5.46510279e-01, 7.44476914e-01, -1.04492702e-01, 3.32048093e-03}, {6.67600107e+00, 7.45036721e-01, 3.77064496e-01, 1.67518005e-01, 1.65107101e-02}}; + case 14: + return {{2.85535312e+00, -4.35813814e-01, 6.98928118e-01, -2.16126293e-01, 3.03548202e-03}, {5.05003214e+00, 5.29675722e-01, 2.47670904e-01, 1.50627494e-01, 1.44170700e-02}}; + case 15: + return {{2.83505607e+00, -2.85362303e-01, 2.51688510e-01, -5.73274195e-02, 3.27281700e-03}, {3.81684399e+00, 1.01348305e+00, 1.71625093e-01, 7.74765834e-02, 1.31826401e-02}}; + case 16: + return {{2.71400809e+00, -3.41581792e-01, 2.40847498e-01, -3.09837908e-02, 2.47210590e-03}, {2.95212793e+00, 6.79380417e-01, 1.75853401e-01, 6.52635694e-02, 1.12200603e-02}}; + case 17: + return {{2.53558207e+00, -1.92675203e-01, 1.20515399e-01, -3.50671113e-02, 3.20018711e-03}, {2.74467707e+00, 2.44560409e+00, 9.37200710e-02, 4.38743904e-02, 1.08148400e-02}}; + case 18: + return {{2.39861608e+00, -6.07183397e-01, 5.24528027e-01, -2.69268993e-02, 1.87984400e-03}, {2.05899811e+00, 3.09629112e-01, 1.89788997e-01, 5.85227199e-02, 8.71843286e-03}}; + case 19: + return {{2.46684504e+00, 1.92999494e+00, 1.54350102e-01, -8.12437236e-02, 2.15101591e-03}, {2.41689091e+01, 2.15578604e+00, 6.77528828e-02, 4.73528206e-02, 8.29782058e-03}}; + case 20: + return {{3.55370402e+00, 1.34050202e+00, 6.76007420e-02, -1.39076998e-02, 5.67091210e-03}, {1.34759798e+01, 1.55728805e+00, 6.80236369e-02, 1.71041396e-02, 9.30336956e-03}}; + case 21: + return {{3.44377804e+00, 1.13595498e+00, 6.00283407e-02, 1.71150803e-03, -1.41223101e-03}, {1.11026001e+01, 1.23438895e+00, 8.91299099e-02, 2.11031688e-03, 2.00439896e-03}}; + case 22: + return {{2.24129701e+00, 2.07236791e+00, 9.29673165e-02, -4.03135009e-02, 2.26346403e-03}, {1.70091000e+01, 1.85258400e+00, 4.71124090e-02, 2.76718698e-02, 6.66805590e-03}}; + case 23: + return {{2.92555189e+00, 1.16348600e+00, 4.43377793e-02, -1.35539500e-02, 4.69834497e-03}, {9.08362007e+00, 1.00832999e+00, 4.14920002e-02, 1.35524096e-02, 7.13791978e-03}}; + case 24: + return {{1.64590800e+00, 1.80008602e+00, 5.35616912e-02, -2.09835991e-02, 4.11470514e-03}, {1.21226702e+01, 1.31736004e+00, 3.45182195e-02, 1.51794404e-02, 6.56798482e-03}}; + case 25: + return {{2.39974809e+00, 1.31345499e+00, 5.21507002e-02, -4.50833105e-02, 1.73789803e-02}, {8.79271221e+00, 9.28560615e-01, 2.16320492e-02, 1.14173004e-02, 7.73268519e-03}}; + case 26: + return {{1.84187496e+00, 1.69585705e+00, 4.24552783e-02, 2.01590403e-04, -1.46712104e-04}, {1.19059095e+01, 1.14025199e+00, 5.56822792e-02, 4.73777589e-04, 4.29703505e-04}}; + case 27: + return {{2.13464499e+00, 1.70659602e+00, -5.68710923e-01, 1.51593298e-01, 5.05861302e-04}, {8.62808323e+00, 5.93899727e-01, 2.49489203e-01, 9.49204788e-02, 3.46111390e-03}}; + case 28: + return {{2.31999111e+00, 1.31185806e+00, -6.97869778e-01, 3.42176288e-01, 4.83954413e-04}, {5.89068222e+00, 4.14797008e-01, 1.55506194e-01, 9.88660678e-02, 3.21499701e-03}}; + case 29: + return {{1.23546398e+00, 1.54618704e+00, 2.77369693e-02, -1.17329899e-02, 4.77816490e-03}, {1.07732496e+01, 8.05693388e-01, 2.23376006e-02, 7.92775396e-03, 4.88925213e-03}}; + case 30: + return {{1.99225104e+00, 1.36421597e+00, -5.34584999e-01, 2.10798606e-01, 3.86487402e-04}, {5.84002686e+00, 4.15746897e-01, 1.55540794e-01, 8.27629790e-02, 2.77534500e-03}}; + case 31: + return {{2.66632009e+00, 1.94698906e+00, -1.18554604e+00, 1.21890597e-01, 3.09190800e-04}, {6.34141302e+00, 2.78902292e-01, 1.83026701e-01, 6.34498373e-02, 2.52509094e-03}}; + case 32: + return {{3.44351792e+00, -1.13572204e+00, 1.36060297e+00, 2.05168296e-02, 2.72685196e-04}, {4.83926678e+00, 1.60483098e+00, 5.87697089e-01, 3.27054188e-02, 2.32771295e-03}}; + case 33: + return {{3.23248005e+00, -1.32028103e+00, 1.74037302e+00, 1.42622404e-02, 1.96056702e-04}, {4.26419592e+00, 9.00477171e-01, 5.46430409e-01, 2.42819097e-02, 2.06261105e-03}}; + case 34: + return {{3.63524103e+00, -2.07056499e+00, 2.03258395e+00, 1.16819199e-02, 1.22890197e-04}, {3.28155088e+00, 8.77488911e-01, 5.28532326e-01, 1.97308101e-02, 1.78012101e-03}}; + case 35: + return {{3.69151306e+00, -1.79441595e+00, 1.62838995e+00, 7.51289679e-03, 5.47963391e-05}, {2.62788510e+00, 7.07726896e-01, 4.17159408e-01, 1.39476703e-02, 1.39450806e-03}}; + case 36: + return {{3.31220102e+00, -5.70945084e-01, 6.97833002e-01, 9.94181167e-03, 1.29992593e-04}, {2.61677909e+00, 9.20762420e-01, 3.22337389e-01, 1.78531203e-02, 1.64635398e-03}}; + case 37: + return {{2.98498106e+00, 2.36873889e+00, 5.00381887e-01, 7.34424405e-03, 4.27639898e-05}, {2.40395908e+01, 2.55953598e+00, 2.63484299e-01, 1.31538603e-02, 1.21721299e-03}}; + case 38: + return {{4.12212515e+00, 1.92479300e+00, 4.70577389e-01, 7.04240007e-03, 3.69832087e-05}, {1.62667599e+01, 2.20284200e+00, 2.45777294e-01, 1.25011001e-02, 1.12981803e-03}}; + case 39: + return {{3.74598193e+00, 2.12386703e+00, 4.42405105e-01, 5.74155105e-03, 1.75479108e-05}, {1.34013996e+01, 2.35688090e+00, 2.22515702e-01, 1.05318800e-02, 8.94146215e-04}}; + case 40: + return {{3.38130689e+00, 2.25415707e+00, 4.40226912e-01, 6.77093910e-03, 6.23684973e-05}, {1.21639204e+01, 2.35530710e+00, 2.21562207e-01, 1.22107305e-02, 1.17974204e-03}}; + case 41: + return {{2.17703199e+00, 2.78299403e+00, 3.90569508e-01, 4.67265584e-03, 6.22945709e-06}, {1.11494303e+01, 2.41581297e+00, 1.92431599e-01, 8.68258812e-03, 6.24530192e-04}}; + case 42: + return {{1.67860794e+00, 3.11303711e+00, 3.46704096e-01, 4.59088618e-03, 9.16880344e-06}, {1.36886101e+01, 2.27832890e+00, 1.75135896e-01, 8.52385256e-03, 6.70720416e-04}}; + case 43: + return {{2.88291001e+00, 2.22659802e+00, 2.98569113e-01, 4.29125316e-03, 9.66334756e-06}, {8.43309307e+00, 1.69386697e+00, 1.55848294e-01, 8.09361599e-03, 6.57025608e-04}}; + case 44: + return {{1.31261802e+00, 3.17361403e+00, 2.85882711e-01, 3.99975199e-03, 8.73038971e-06}, {1.25337400e+01, 1.96410704e+00, 1.46394894e-01, 7.61754299e-03, 6.17400685e-04}}; + case 45: + return {{1.44103205e+00, 2.94216609e+00, 2.32040107e-01, 3.09590693e-03, 2.05679089e-06}, {1.03466597e+01, 1.64708400e+00, 1.23005100e-01, 6.30735699e-03, 3.96098098e-04}}; + case 46: + return {{2.02130705e-01, 3.35615706e+00, 2.30525196e-01, 3.56838107e-03, 4.97298106e-06}, {1.69279804e+01, 1.69309103e+00, 1.22913197e-01, 6.80784881e-03, 4.96210472e-04}}; + case 47: + return {{1.21013403e+00, 2.92162895e+00, 1.98055595e-01, 3.18102399e-03, 8.53895926e-06}, {1.01067600e+01, 1.43554401e+00, 1.08165003e-01, 6.40084315e-03, 5.55367384e-04}}; + case 48: + return {{1.60705805e+00, 2.81508899e+00, 1.91956207e-01, 2.63145100e-03, 1.84189503e-06}, {9.29942894e+00, 1.37371194e+00, 1.02014497e-01, 5.39610581e-03, 3.47371009e-04}}; + case 49: + return {{2.70126796e+00, 2.29345989e+00, 2.16367900e-01, 3.69811291e-03, 1.95252096e-06}, {8.33631229e+00, 1.19331098e+00, 1.16310202e-01, 6.37960806e-03, 3.49309004e-04}}; + case 50: + return {{2.87292099e+00, 2.40417600e+00, 1.57168493e-01, 1.89157098e-03, 7.62896207e-06}, {8.46732521e+00, 1.12822700e+00, 8.41042623e-02, 4.36692312e-03, 4.75006207e-04}}; + case 51: + return {{3.50419807e+00, 1.83627403e+00, 1.50732994e-01, 3.59381200e-03, 1.05334497e-04}, {5.89424086e+00, 9.22941923e-01, 8.61572027e-02, 8.35711230e-03, 8.86740920e-04}}; + case 52: + return {{3.21798110e+00, 2.05408001e+00, 2.15190396e-01, 2.72924802e-03, 2.24804194e-06}, {5.26334810e+00, 1.19520295e+00, 1.02286197e-01, 5.08707995e-03, 3.28804512e-04}}; + case 53: + return {{4.13265181e+00, 1.18767595e+00, 1.35713801e-01, 1.50258699e-03, 1.33380800e-05}, {3.71807408e+00, 7.28209019e-01, 7.14013129e-02, 3.71678802e-03, 5.00523078e-04}}; + case 54: + return {{3.51788712e+00, 1.66314995e+00, 2.16246501e-01, 2.76901806e-03, 8.36265008e-06}, {3.94756007e+00, 1.07487500e+00, 1.00129701e-01, 5.00469515e-03, 4.41977201e-04}}; + case 55: + return {{3.81201100e+00, 3.07259011e+00, 1.22549701e+00, 8.76324698e-02, 2.59851106e-04}, {2.28876896e+01, 3.35200000e+00, 5.80402970e-01, 4.92655188e-02, 8.89977906e-04}}; + case 56: + return {{6.35506678e+00, 1.69075298e+00, 9.57290590e-01, 7.86023363e-02, 2.44261813e-04}, {1.39797802e+01, 1.68795502e+00, 5.12502193e-01, 4.48691696e-02, 8.56465078e-04}}; + case 57: + return {{4.28002501e+00, 3.07966208e+00, 1.45083499e+00, 8.27694386e-02, 2.41575995e-04}, {1.66275997e+01, 4.31141520e+00, 6.13337815e-01, 4.52826284e-02, 8.27733311e-04}}; + case 58: + return {{5.13602400e+00, 2.43740010e+00, 1.03740597e+00, 6.99751526e-02, 2.29697005e-04}, {1.42508097e+01, 2.43046999e+00, 4.76604193e-01, 4.05691713e-02, 7.97950372e-04}}; + case 59: + return {{5.35353422e+00, 2.12939692e+00, 9.15245771e-01, 7.25957975e-02, 2.31387705e-04}, {1.41875095e+01, 1.81712794e+00, 4.47230697e-01, 4.14027907e-02, 7.73125212e-04}}; + case 60: + return {{5.32854700e+00, 1.72848594e+00, 1.11297500e+00, 7.37465993e-02, 2.25470707e-04}, {1.31087599e+01, 1.74724901e+00, 4.96911108e-01, 4.08121310e-02, 7.47739687e-04}}; + case 61: + return {{4.36711407e+00, 1.98772097e+00, 1.65877998e+00, 7.46220574e-02, 2.23465599e-04}, {1.53489799e+01, 3.45163202e+00, 5.88005126e-01, 4.03418690e-02, 7.24034617e-04}}; + case 62: + return {{5.13235712e+00, 1.91035604e+00, 8.09289694e-01, 6.53573796e-02, 2.11307895e-04}, {1.30506601e+01, 1.27198803e+00, 4.12205100e-01, 3.68197896e-02, 6.99623721e-04}}; + case 63: + return {{4.25057316e+00, 2.08642793e+00, 1.35467899e+00, 6.16801083e-02, 2.06875600e-04}, {1.51125002e+01, 2.45922089e+00, 4.77150202e-01, 3.51009294e-02, 6.77573611e-04}}; + case 64: + return {{4.78696299e+00, 1.37942696e+00, 1.41249299e+00, 5.88963702e-02, 1.96196401e-04}, {1.08546200e+01, 2.08167791e+00, 4.78227913e-01, 3.32649015e-02, 6.55558892e-04}}; + case 65: + return {{4.72020006e+00, 1.16532505e+00, 1.50215197e+00, 6.71210736e-02, 2.09402002e-04}, {1.22190304e+01, 1.67899096e+00, 5.07295787e-01, 3.62123288e-02, 6.38881815e-04}}; + case 66: + return {{4.22459507e+00, 1.57796502e+00, 1.44352305e+00, 6.22941405e-02, 1.98618902e-04}, {1.33922796e+01, 2.03565693e+00, 4.68585610e-01, 3.41081098e-02, 6.18939695e-04}}; + case 67: + return {{3.68242311e+00, 1.69007802e+00, 1.73174500e+00, 6.26287907e-02, 1.94016204e-04}, {1.36538200e+01, 3.38136411e+00, 5.00155091e-01, 3.36822011e-02, 6.00808591e-04}}; + case 68: + return {{3.65319490e+00, 1.80632806e+00, 1.50050402e+00, 4.83703911e-02, 1.80868403e-04}, {1.33160105e+01, 2.66234398e+00, 4.23525512e-01, 2.84032505e-02, 5.81026427e-04}}; + case 69: + return {{2.81324100e+00, 2.29724407e+00, 1.71350300e+00, 5.38761392e-02, 1.82238698e-04}, {1.63576298e+01, 3.92391706e+00, 4.60097700e-01, 2.98996102e-02, 5.65685797e-04}}; + case 70: + return {{3.86458898e+00, 1.25103104e+00, 1.50890696e+00, 4.87409793e-02, 1.76625705e-04}, {1.09293900e+01, 2.05829406e+00, 4.10406888e-01, 2.79810801e-02, 5.49290911e-04}}; + case 71: + return {{2.78422499e+00, 2.18659902e+00, 1.62505805e+00, 5.04949987e-02, 1.76768895e-04}, {1.05224104e+01, 4.15039682e+00, 4.16781306e-01, 2.84288507e-02, 5.34839579e-04}}; + case 72: + return {{1.82888401e+00, 3.08626103e+00, 1.56239796e+00, 4.50708307e-02, 1.67344595e-04}, {1.09088402e+01, 4.48407412e+00, 3.92598897e-01, 2.59789601e-02, 5.18937595e-04}}; + case 73: + return {{1.34293997e+00, 3.54547095e+00, 1.43781698e+00, 4.28609811e-02, 1.62209704e-04}, {1.22230902e+01, 3.98015690e+00, 3.64430696e-01, 2.49023698e-02, 5.04579220e-04}}; + case 74: + return {{1.11627996e+00, 3.81305695e+00, 1.27436197e+00, 3.69497910e-02, 1.52609398e-04}, {1.21982803e+01, 3.51693296e+00, 3.22148204e-01, 2.25107409e-02, 4.89797501e-04}}; + case 75: + return {{1.15703595e+00, 3.75507998e+00, 1.18611205e+00, 3.35603990e-02, 1.41277094e-04}, {1.14396601e+01, 3.10535192e+00, 3.00034910e-01, 2.07285509e-02, 4.75228589e-04}}; + case 76: + return {{2.95070696e+00, 1.99730504e+00, 9.92647886e-01, 3.54575291e-02, 1.46259103e-04}, {5.83780003e+00, 1.72655404e+00, 2.71308392e-01, 2.16202103e-02, 4.64655401e-04}}; + case 77: + return {{3.32513905e+00, 1.52911794e+00, 9.36988473e-01, 2.82717198e-02, 1.28554704e-04}, {4.62521505e+00, 1.43798900e+00, 2.50209898e-01, 1.81400497e-02, 4.49112791e-04}}; + case 78: + return {{4.98159796e-01, 4.03055811e+00, 8.52239490e-01, 2.27640904e-02, 1.15693001e-04}, {1.65708504e+01, 2.17498207e+00, 2.20648602e-01, 1.56411994e-02, 4.34708607e-04}}; + case 79: + return {{8.70827496e-01, 3.66290498e+00, 7.21173406e-01, 2.25834902e-02, 1.15950199e-04}, {8.26474285e+00, 1.76541495e+00, 1.96660295e-01, 1.56456195e-02, 4.24816913e-04}}; + case 80: + return {{2.23930812e+00, 2.49683499e+00, 7.04915404e-01, 2.09938809e-02, 9.59475219e-05}, {4.66368914e+00, 1.36597097e+00, 1.94375604e-01, 1.40903797e-02, 4.09117813e-04}}; + case 81: + return {{2.71713591e+00, 2.91902208e+00, 7.08489776e-01, 1.79738607e-02, 8.45634204e-05}, {8.71158314e+00, 1.45481896e+00, 1.87859505e-01, 1.23882899e-02, 3.94706090e-04}}; + case 82: + return {{3.29438901e+00, 2.66650391e+00, 5.41207910e-01, 1.59845799e-02, 9.09762530e-05}, {7.26526308e+00, 1.15847301e+00, 1.53856993e-01, 1.19057801e-02, 3.87974986e-04}}; + case 83: + return {{2.90801311e+00, 2.94222403e+00, 6.40052676e-01, 1.98365692e-02, 1.03154103e-04}, {7.08211708e+00, 1.40495801e+00, 1.71940193e-01, 1.36806397e-02, 3.83776205e-04}}; + case 84: + return {{4.17358112e+00, 1.43807697e+00, 5.06418884e-01, 1.17866602e-02, 3.70279995e-05}, {3.63485503e+00, 7.84012079e-01, 1.42200202e-01, 8.50070175e-03, 3.35267512e-04}}; + case 85: + return {{4.40665388e+00, 1.68819594e+00, 6.11086190e-01, 1.74588896e-02, 8.35977771e-05}, {4.43530703e+00, 9.95206296e-01, 1.63246498e-01, 1.18547501e-02, 3.61005805e-04}}; + case 86: + return {{4.44254780e+00, 1.57980704e+00, 7.00253785e-01, 1.36486702e-02, 5.30898506e-05}, {3.88471198e+00, 1.23543596e+00, 1.67034298e-01, 9.34090279e-03, 3.36916302e-04}}; + case 87: + return {{4.44422293e+00, 3.84529591e+00, 6.47594690e-01, 1.57298408e-02, 8.11556311e-05}, {1.55769997e+01, 1.69413495e+00, 1.57903805e-01, 1.09456200e-02, 3.44481290e-04}}; + case 88: + return {{5.84577084e+00, 3.43635201e+00, 6.62875414e-01, 1.30639505e-02, 4.20832803e-05}, {1.44227695e+01, 1.58868802e+00, 1.56904906e-01, 8.72127432e-03, 3.15123296e-04}}; + case 89: + return {{6.56823683e+00, 3.08116007e+00, 5.87002397e-01, 1.18503897e-02, 3.66903696e-05}, {1.23099003e+01, 1.34582400e+00, 1.42942101e-01, 8.05882178e-03, 3.02906294e-04}}; + case 90: + return {{6.75877714e+00, 2.74244094e+00, 5.82863986e-01, 1.08115301e-02, 1.49991101e-05}, {9.66876411e+00, 1.26876402e+00, 1.39298707e-01, 7.15679117e-03, 2.59494089e-04}}; + case 91: + return {{6.37304688e+00, 2.82305002e+00, 5.40732384e-01, 1.19372196e-02, 5.09942292e-05}, {9.53488636e+00, 1.19764698e+00, 1.32480398e-01, 8.31615925e-03, 3.02768894e-04}}; + case 92: + return {{6.01751184e+00, 3.00574708e+00, 5.04366279e-01, 9.93358810e-03, 1.37084398e-05}, {9.77997780e+00, 1.16927600e+00, 1.23806901e-01, 6.66506588e-03, 2.45529693e-04}}; + case 93: + return {{5.20271587e+00, 3.61388612e+00, 5.22116423e-01, 8.51191860e-03, 1.63058994e-05}, {1.04132996e+01, 1.40175903e+00, 1.19989701e-01, 6.06458494e-03, 2.46154610e-04}}; + case 94: + return {{4.97225809e+00, 3.62590599e+00, 4.27345693e-01, 8.12398084e-03, 1.48722102e-05}, {1.17354097e+01, 1.18188906e+00, 1.05401397e-01, 5.83548006e-03, 2.37660599e-04}}; + case 95: + return {{4.50712395e+00, 3.90453696e+00, 4.45498198e-01, 7.97858369e-03, 8.28391057e-06}, {1.28308401e+01, 1.25748503e+00, 1.06835604e-01, 5.59567707e-03, 2.09513906e-04}}; + case 96: + return {{4.95550919e+00, 3.46335196e+00, 3.79075289e-01, 5.84759377e-03, 2.35737807e-05}, {9.56314087e+00, 1.07623196e+00, 9.16181728e-02, 4.78272792e-03, 2.42163704e-04}}; + case 97: + return {{4.87071705e+00, 3.45333791e+00, 3.44667703e-01, 6.47798879e-03, 1.13584201e-05}, {9.75995636e+00, 9.98554826e-01, 8.70402008e-02, 4.92938887e-03, 2.12656101e-04}}; + case 98: + return {{4.32416010e+00, 3.69497395e+00, 3.30316305e-01, 5.58224786e-03, 7.66277208e-06}, {1.12858105e+01, 1.00380003e+00, 8.26271027e-02, 4.33693221e-03, 1.90465493e-04}}; + case 99: + return {{3.96653795e+00, 3.86160207e+00, 3.56552094e-01, 7.00159417e-03, 2.81896791e-05}, {1.22629700e+01, 1.04874003e+00, 8.83088931e-02, 5.31629194e-03, 2.38887806e-04}}; + case 100: + return {{4.27992916e+00, 3.45720100e+00, 2.69533694e-01, 4.48193215e-03, 1.74949400e-05}, {9.27273178e+00, 8.65246892e-01, 6.92421496e-02, 3.92412720e-03, 2.13503794e-04}}; + case 101: + return {{3.94026089e+00, 3.62439609e+00, 2.89608896e-01, 6.40732795e-03, 3.19458813e-05}, {1.02414103e+01, 8.98189783e-01, 7.49766305e-02, 5.15825208e-03, 2.35140804e-04}}; + case 102: + return {{3.96523499e+00, 3.38761902e+00, 3.31892401e-01, 5.65199787e-03, 7.42224984e-06}, {8.30294800e+00, 8.89315307e-01, 8.13126490e-02, 4.15963400e-03, 1.77448994e-04}}; + case 103: + return {{4.46439791e+00, 3.20867705e+00, 2.26712495e-01, 4.08070907e-03, -1.60853798e-03}, {7.96693707e+00, 7.42235303e-01, 5.82330413e-02, 1.39190501e-03, 8.74621095e-04}}; + } + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 10: Peng et al. parameterization for Ions- 5 Gaussians - [0, 4] + LNL_Coef_cpu load_feg_peng_ion_0_4(const dt_int32& Z, const dt_int32& charge) + { + switch(Z) + { + case 1: + { + switch(charge) + { + case -1: + return {{1.400e-01, 6.490e-01, 1.370e+00, 3.370e-01, 7.870e-01}, {9.840e-01, 8.670e+00, 3.890e+01, 1.110e+02, 1.660e+02}}; + } + } + break; + case 3: + { + switch(charge) + { + case 1: + return {{4.600e-03, 1.650e-02, 4.350e-02, 6.490e-02, 2.700e-02}, {3.580e-02, 2.390e-01, 8.790e-01, 2.640e+00, 7.090e+00}}; + } + } + break; + case 4: + { + switch(charge) + { + case 2: + return {{3.400e-03, 1.030e-02, 2.330e-02, 3.250e-02, 1.200e-02}, {2.670e-02, 1.620e-01, 5.310e-01, 1.480e+00, 3.880e+00}}; + } + } + break; + case 8: + { + switch(charge) + { + case -1: + return {{2.050e-01, 6.280e-01, 1.170e+00, 1.030e+00, 2.900e-01}, {3.970e-01, 2.640e+00, 8.800e+00, 2.710e+01, 9.180e+01}}; + case -2: + return {{4.210e-02, 2.100e-01, 8.520e-01, 1.820e+00, 1.170e+00}, {6.090e-02, 5.590e-01, 2.960e+00, 1.150e+01, 3.770e+01}}; + } + } + break; + case 9: + { + switch(charge) + { + case -1: + return {{1.340e-01, 3.910e-01, 8.140e-01, 9.280e-01, 3.470e-01}, {2.280e-01, 1.470e+00, 4.680e+00, 1.320e+01, 3.600e+01}}; + } + } + break; + case 11: + { + switch(charge) + { + case 1: + return {{2.560e-02, 9.190e-02, 2.970e-01, 5.140e-01, 1.990e-01}, {3.970e-02, 2.870e-01, 1.180e+00, 3.750e+00, 1.080e+01}}; + } + } + break; + case 12: + { + switch(charge) + { + case 2: + return {{2.100e-02, 6.720e-02, 1.980e-01, 3.680e-01, 1.740e-01}, {3.310e-02, 2.220e-01, 8.380e-01, 2.480e+00, 6.750e+00}}; + } + } + break; + case 13: + { + switch(charge) + { + case 3: + return {{1.920e-02, 5.790e-02, 1.630e-01, 2.840e-01, 1.140e-01}, {3.060e-02, 1.980e-01, 7.130e-01, 2.040e+00, 5.250e+00}}; + } + } + break; + case 14: + { + switch(charge) + { + case 4: + return {{1.920e-01, 2.890e-01, 1.000e-01, -7.280e-02, 1.200e-03}, {3.590e-01, 1.960e+00, 9.340e+00, 1.110e+01, 1.340e+01}}; + } + } + break; + case 17: + { + switch(charge) + { + case -1: + return {{2.650e-01, 5.960e-01, 1.600e+00, 2.690e+00, 1.230e+00}, {2.520e-01, 1.560e+00, 6.210e+00, 1.780e+01, 4.780e+01}}; + } + } + break; + case 19: + { + switch(charge) + { + case 1: + return {{1.990e-01, 3.960e-01, 9.280e-01, 1.450e+00, 4.500e-01}, {1.920e-01, 1.100e+00, 3.910e+00, 9.750e+00, 2.340e+01}}; + } + } + break; + case 20: + { + switch(charge) + { + case 2: + return {{1.640e-01, 3.270e-01, 7.430e-01, 1.160e+00, 3.070e-01}, {1.570e-01, 8.940e-01, 3.150e+00, 7.670e+00, 1.770e+01}}; + } + } + break; + case 21: + { + switch(charge) + { + case 3: + return {{1.630e-01, 3.070e-01, 7.160e-01, 8.800e-01, 1.390e-01}, {1.570e-01, 8.990e-01, 3.060e+00, 7.050e+00, 1.610e+01}}; + } + } + break; + case 22: + { + switch(charge) + { + case 2: + return {{3.990e-01, 1.040e+00, 1.210e+00, -7.970e-02, 3.520e-01}, {3.760e-01, 2.740e+00, 8.100e+00, 1.420e+01, 2.320e+01}}; + case 3: + return {{3.640e-01, 9.190e-01, 1.350e+00, -9.330e-01, 5.890e-01}, {3.640e-01, 2.670e+00, 8.180e+00, 1.180e+01, 1.490e+01}}; + case 4: + return {{1.160e-01, 2.560e-01, 5.650e-01, 7.720e-01, 1.320e-01}, {1.080e-01, 6.550e-01, 2.380e+00, 5.510e+00, 1.230e+01}}; + } + } + break; + case 23: + { + switch(charge) + { + case 2: + return {{3.170e-01, 9.390e-01, 1.490e+00, -1.310e+00, 1.470e+00}, {2.690e-01, 2.090e+00, 7.220e+00, 1.520e+01, 1.760e+01}}; + case 3: + return {{3.410e-01, 8.050e-01, 9.420e-01, 7.830e-02, 1.560e-01}, {3.210e-01, 2.230e+00, 5.990e+00, 1.340e+01, 1.690e+01}}; + case 5: + return {{3.670e-02, 1.240e-01, 2.440e-01, 7.230e-01, 4.350e-01}, {3.300e-02, 2.220e-01, 8.240e-01, 2.800e+00, 6.700e+00}}; + } + } + break; + case 24: + { + switch(charge) + { + case 2: + return {{2.370e-01, 6.340e-01, 1.230e+00, 7.130e-01, 8.590e-02}, {1.770e-01, 1.350e+00, 4.300e+00, 1.220e+01, 3.900e+01}}; + case 3: + return {{3.930e-01, 1.050e+00, 1.620e+00, -1.150e+00, 4.070e-01}, {3.590e-01, 2.570e+00, 8.680e+00, 1.100e+01, 1.580e+01}}; + case 4: + return {{1.320e-01, 2.920e-01, 7.030e-01, 6.920e-01, 9.590e-02}, {1.090e-01, 6.950e-01, 2.390e+00, 5.650e+00, 1.470e+01}}; + } + } + break; + case 25: + { + switch(charge) + { + case 2: + return {{5.760e-02, 2.100e-01, 6.040e-01, 1.320e+00, 6.590e-01}, {3.980e-02, 2.840e-01, 1.290e+00, 4.230e+00, 1.450e+01}}; + case 3: + return {{1.160e-01, 5.230e-01, 8.810e-01, 5.890e-01, 2.140e-01}, {1.170e-02, 8.760e-01, 3.060e+00, 6.440e+00, 1.430e+01}}; + case 4: + return {{3.810e-01, 1.830e+00, -1.330e+00, 9.950e-01, 6.180e-02}, {3.540e-01, 2.720e+00, 3.470e+00, 5.470e+00, 1.610e+01}}; + } + } + break; + case 26: + { + switch(charge) + { + case 2: + return {{3.070e-01, 8.380e-01, 1.110e+00, 2.800e-01, 2.770e-01}, {2.300e-01, 1.620e+00, 4.870e+00, 1.070e+01, 1.920e+01}}; + case 3: + return {{1.980e-01, 3.870e-01, 8.890e-01, 7.090e-01, 1.170e-01}, {1.540e-01, 8.930e-01, 2.620e+00, 6.650e+00, 1.800e+01}}; + } + } + break; + case 27: + { + switch(charge) + { + case 2: + return {{2.130e-01, 4.880e-01, 9.980e-01, 8.280e-01, 2.300e-01}, {1.480e-01, 9.390e-01, 2.780e+00, 7.310e+00, 2.070e+01}}; + case 3: + return {{3.310e-01, 4.870e-01, 7.290e-01, 6.080e-01, 1.310e-01}, {2.670e-01, 1.410e+00, 2.890e+00, 6.450e+00, 1.580e+01}}; + } + } + break; + case 28: + { + switch(charge) + { + case 2: + return {{3.380e-01, 9.820e-01, 1.320e+00, -3.560e+00, 3.620e+00}, {2.370e-01, 1.670e+00, 5.730e+00, 1.140e+01, 1.210e+01}}; + case 3: + return {{3.470e-01, 8.770e-01, 7.900e-01, 5.380e-02, 1.920e-01}, {2.600e-01, 1.710e+00, 4.750e+00, 7.510e+00, 1.300e+01}}; + } + } + break; + case 29: + { + switch(charge) + { + case 1: + return {{3.120e-01, 8.120e-01, 1.110e+00, 7.940e-01, 2.570e-01}, {2.010e-01, 1.310e+00, 3.800e+00, 1.050e+01, 2.820e+01}}; + case 2: + return {{2.240e-01, 5.440e-01, 9.700e-01, 7.270e-01, 1.820e-01}, {1.450e-01, 9.330e-01, 2.690e+00, 7.110e+00, 1.940e+01}}; + } + } + break; + case 30: + { + switch(charge) + { + case 2: + return {{2.520e-01, 6.000e-01, 9.170e-01, 6.630e-01, 1.610e-01}, {1.610e-01, 1.010e+00, 2.760e+00, 7.080e+00, 1.900e+01}}; + } + } + break; + case 31: + { + switch(charge) + { + case 3: + return {{3.910e-01, 9.470e-01, 6.900e-01, 7.090e-02, 6.530e-02}, {2.640e-01, 1.650e+00, 4.820e+00, 1.070e+01, 1.520e+01}}; + } + } + break; + case 32: + { + switch(charge) + { + case 4: + return {{3.460e-01, 8.300e-01, 5.990e-01, 9.490e-02, -2.170e-02}, {2.320e-01, 1.450e+00, 4.080e+00, 1.320e+01, 2.950e+01}}; + } + } + break; + case 35: + { + switch(charge) + { + case -1: + return {{1.250e-01, 5.630e-01, 1.430e+00, 3.520e+00, 3.220e+00}, {5.300e-02, 4.690e-01, 2.150e+00, 1.110e+01, 3.890e+01}}; + } + } + break; + case 37: + { + switch(charge) + { + case 1: + return {{3.680e-01, 8.840e-01, 1.140e+00, 2.260e+00, 8.810e-01}, {1.870e-01, 1.120e+00, 3.980e+00, 1.090e+01, 2.660e+01}}; + } + } + break; + case 38: + { + switch(charge) + { + case 2: + return {{3.460e-01, 8.040e-01, 9.880e-01, 1.890e+00, 6.090e-01}, {1.760e-01, 1.040e+00, 3.590e+00, 9.320e+00, 2.140e+01}}; + } + } + break; + case 39: + { + switch(charge) + { + case 3: + return {{4.650e-01, 9.230e-01, 2.410e+00, -2.310e+00, 2.480e+00}, {2.400e-01, 1.430e+00, 6.450e+00, 9.970e+00, 1.220e+01}}; + } + } + break; + case 40: + { + switch(charge) + { + case 4: + return {{2.340e-01, 6.420e-01, 7.470e-01, 1.470e+00, 3.770e-01}, {1.130e-01, 7.360e-01, 2.540e+00, 6.720e+00, 1.470e+01}}; + } + } + break; + case 41: + { + switch(charge) + { + case 3: + return {{3.770e-01, 7.490e-01, 1.290e+00, 1.610e+00, 4.810e-01}, {1.840e-01, 1.020e+00, 3.800e+00, 9.440e+00, 2.570e+01}}; + case 5: + return {{8.280e-02, 2.710e-01, 6.540e-01, 1.240e+00, 8.290e-01}, {3.690e-02, 2.610e-01, 9.570e-01, 3.940e+00, 9.440e+00}}; + } + } + break; + case 42: + { + switch(charge) + { + case 3: + return {{4.010e-01, 7.560e-01, 1.380e+00, 1.580e+00, 4.970e-01}, {1.910e-01, 1.060e+00, 3.840e+00, 9.380e+00, 2.460e+01}}; + case 5: + return {{4.790e-01, 8.460e-01, 1.560e+01, -1.520e+01, 1.600e+00}, {2.410e-01, 1.460e+00, 6.790e+00, 7.130e+00, 1.040e+01}}; + case 6: + return {{2.030e-01, 5.670e-01, 6.460e-01, 1.160e+00, 1.710e-01}, {9.710e-02, 6.470e-01, 2.280e+00, 5.610e+00, 1.240e+01}}; + } + } + break; + case 44: + { + switch(charge) + { + case 3: + return {{4.280e-01, 7.730e-01, 1.550e+00, 1.460e+00, 4.860e-01}, {1.910e-01, 1.090e+00, 3.820e+00, 9.080e+00, 2.170e+01}}; + case 4: + return {{2.820e-01, 6.530e-01, 1.140e+00, 1.530e+00, 4.180e-01}, {1.250e-01, 7.530e-01, 2.850e+00, 7.010e+00, 1.750e+01}}; + } + } + break; + case 45: + { + switch(charge) + { + case 3: + return {{3.520e-01, 7.230e-01, 1.500e+00, 1.630e+00, 4.990e-01}, {1.510e-01, 8.780e-01, 3.280e+00, 8.160e+00, 2.070e+01}}; + case 4: + return {{3.970e-01, 7.250e-01, 1.510e+00, 1.190e+00, 2.510e-01}, {1.770e-01, 1.010e+00, 3.620e+00, 8.560e+00, 1.890e+01}}; + } + } + break; + case 46: + { + switch(charge) + { + case 2: + return {{9.350e-01, 3.110e+00, 2.460e+01, -4.360e+01, 2.110e+01}, {3.930e-01, 4.060e+00, 4.310e+01, 5.400e+01, 6.980e+01}}; + case 4: + return {{3.480e-01, 6.400e-01, 1.220e+00, 1.450e+00, 4.270e-01}, {1.510e-01, 8.320e-01, 2.850e+00, 6.590e+00, 1.560e+01}}; + } + } + break; + case 47: + { + switch(charge) + { + case 1: + return {{5.030e-01, 9.400e-01, 2.170e+00, 1.990e+00, 7.260e-01}, {1.990e-01, 1.190e+00, 4.050e+00, 1.130e+01, 3.240e+01}}; + case 2: + return {{4.310e-01, 7.560e-01, 1.720e+00, 1.780e+00, 5.260e-01}, {1.750e-01, 9.790e-01, 3.300e+00, 8.240e+00, 2.140e+01}}; + } + } + break; + case 48: + { + switch(charge) + { + case 2: + return {{4.250e-01, 7.450e-01, 1.730e+00, 1.740e+00, 4.870e-01}, {1.680e-01, 9.440e-01, 3.140e+00, 7.840e+00, 2.040e+01}}; + } + } + break; + case 49: + { + switch(charge) + { + case 3: + return {{4.170e-01, 7.550e-01, 1.590e+00, 1.360e+00, 4.510e-01}, {1.640e-01, 9.600e-01, 3.080e+00, 7.030e+00, 1.610e+01}}; + } + } + break; + case 50: + { + switch(charge) + { + case 2: + return {{7.970e-01, 2.130e+00, 2.150e+00, -1.640e+00, 2.720e+00}, {3.170e-01, 2.510e+00, 9.040e+00, 2.420e+01, 2.640e+01}}; + case 4: + return {{2.610e-01, 6.420e-01, 1.530e+00, 1.360e+00, 1.770e-01}, {9.570e-02, 6.250e-01, 2.510e+00, 6.310e+00, 1.590e+01}}; + } + } + break; + case 51: + { + switch(charge) + { + case 3: + return {{5.520e-01, 1.140e+00, 1.870e+00, 1.360e+00, 4.140e-01}, {2.120e-01, 1.420e+00, 4.210e+00, 1.250e+01, 2.900e+01}}; + case 5: + return {{3.770e-01, 5.880e-01, 1.220e+00, 1.180e+00, 2.440e-01}, {1.510e-01, 8.120e-01, 2.400e+00, 5.270e+00, 1.190e+01}}; + } + } + break; + case 53: + { + switch(charge) + { + case -1: + return {{9.010e-01, 2.800e+00, 5.610e+00, -8.690e+00, 1.260e+01}, {3.120e-01, 2.590e+00, 1.410e+01, 3.440e+01, 3.950e+01}}; + } + } + break; + case 55: + { + switch(charge) + { + case 1: + return {{5.870e-01, 1.400e+00, 1.870e+00, 3.480e+00, 1.670e+00}, {2.000e-01, 1.380e+00, 4.120e+00, 1.300e+01, 3.180e+01}}; + } + } + break; + case 56: + { + switch(charge) + { + case 2: + return {{7.330e-01, 2.050e+00, 2.300e+01, -1.520e+02, 1.340e+02}, {2.580e-01, 1.960e+00, 1.180e+01, 1.440e+01, 1.490e+01}}; + } + } + break; + case 57: + { + switch(charge) + { + case 3: + return {{4.930e-01, 1.100e+00, 1.500e+00, 2.700e+00, 1.080e+00}, {1.670e-01, 1.110e+00, 3.110e+00, 9.610e+00, 2.120e+01}}; + } + } + break; + case 58: + { + switch(charge) + { + case 3: + return {{5.600e-01, 1.350e+00, 1.590e+00, 2.630e+00, 7.060e-01}, {1.900e-01, 1.300e+00, 3.930e+00, 1.070e+01, 2.380e+01}}; + case 4: + return {{4.830e-01, 1.090e+00, 1.340e+00, 2.450e+00, 7.970e-01}, {1.650e-01, 1.100e+00, 3.020e+00, 8.850e+00, 1.880e+01}}; + } + } + break; + case 59: + { + switch(charge) + { + case 3: + return {{6.630e-01, 1.730e+00, 2.350e+00, 3.510e-01, 1.590e+00}, {2.260e-01, 1.610e+00, 6.330e+00, 1.100e+01, 1.690e+01}}; + case 4: + return {{5.210e-01, 1.190e+00, 1.330e+00, 2.360e+00, 6.900e-01}, {1.770e-01, 1.170e+00, 3.280e+00, 8.940e+00, 1.930e+01}}; + } + } + break; + case 60: + { + switch(charge) + { + case 3: + return {{5.010e-01, 1.180e+00, 1.450e+00, 2.530e+00, 9.200e-01}, {1.620e-01, 1.080e+00, 3.060e+00, 8.800e+00, 1.960e+01}}; + } + } + break; + case 61: + { + switch(charge) + { + case 3: + return {{4.960e-01, 1.200e+00, 1.470e+00, 2.430e+00, 9.430e-01}, {1.560e-01, 1.050e+00, 3.070e+00, 8.560e+00, 1.920e+01}}; + } + } + break; + case 62: + { + switch(charge) + { + case 3: + return {{5.180e-01, 1.240e+00, 1.430e+00, 2.400e+00, 7.810e-01}, {1.630e-01, 1.080e+00, 3.110e+00, 8.520e+00, 1.910e+01}}; + } + } + break; + case 63: + { + switch(charge) + { + case 2: + return {{6.130e-01, 1.530e+00, 1.840e+00, 2.460e+00, 7.140e-01}, {1.900e-01, 1.270e+00, 4.180e+00, 1.070e+01, 2.620e+01}}; + case 3: + return {{4.960e-01, 1.210e+00, 1.450e+00, 2.360e+00, 7.740e-01}, {1.520e-01, 1.010e+00, 2.950e+00, 8.180e+00, 1.850e+01}}; + } + } + break; + case 64: + { + switch(charge) + { + case 3: + return {{4.900e-01, 1.190e+00, 1.420e+00, 2.300e+00, 7.950e-01}, {1.480e-01, 9.740e-01, 2.810e+00, 7.780e+00, 1.770e+01}}; + } + } + break; + case 65: + { + switch(charge) + { + case 3: + return {{5.030e-01, 1.220e+00, 1.420e+00, 2.240e+00, 7.100e-01}, {1.500e-01, 9.820e-01, 2.860e+00, 7.770e+00, 1.770e+01}}; + } + } + break; + case 66: + { + switch(charge) + { + case 3: + return {{5.030e-01, 1.240e+00, 1.440e+00, 2.170e+00, 6.430e-01}, {1.480e-01, 9.700e-01, 2.880e+00, 7.730e+00, 1.760e+01}}; + } + } + break; + case 67: + { + switch(charge) + { + case 3: + return {{4.560e-01, 1.170e+00, 1.430e+00, 2.150e+00, 6.920e-01}, {1.290e-01, 8.690e-01, 2.610e+00, 7.240e+00, 1.670e+01}}; + } + } + break; + case 68: + { + switch(charge) + { + case 3: + return {{5.220e-01, 1.280e+00, 1.460e+00, 2.050e+00, 5.080e-01}, {1.500e-01, 9.640e-01, 2.930e+00, 7.720e+00, 1.780e+01}}; + } + } + break; + case 69: + { + switch(charge) + { + case 3: + return {{4.750e-01, 1.200e+00, 1.420e+00, 2.050e+00, 5.840e-01}, {1.320e-01, 8.640e-01, 2.600e+00, 7.090e+00, 1.660e+01}}; + } + } + break; + case 70: + { + switch(charge) + { + case 2: + return {{5.080e-01, 1.370e+00, 1.760e+00, 2.230e+00, 5.840e-01}, {1.360e-01, 9.220e-01, 3.120e+00, 8.720e+00, 2.370e+01}}; + case 3: + return {{4.980e-01, 1.220e+00, 1.390e+00, 1.970e+00, 5.590e-01}, {1.380e-01, 8.810e-01, 2.630e+00, 6.990e+00, 1.630e+01}}; + } + } + break; + case 71: + { + switch(charge) + { + case 3: + return {{4.830e-01, 1.210e+00, 1.410e+00, 1.940e+00, 5.220e-01}, {1.310e-01, 8.450e-01, 2.570e+00, 6.880e+00, 1.620e+01}}; + } + } + break; + case 72: + { + switch(charge) + { + case 4: + return {{5.220e-01, 1.220e+00, 1.370e+00, 1.680e+00, 3.120e-01}, {1.450e-01, 8.960e-01, 2.740e+00, 6.910e+00, 1.610e+01}}; + } + } + break; + case 73: + { + switch(charge) + { + case 5: + return {{5.690e-01, 1.260e+00, 9.790e-01, 1.290e+00, 5.510e-01}, {1.610e-01, 9.720e-01, 2.760e+00, 5.400e+00, 1.090e+01}}; + } + } + break; + case 74: + { + switch(charge) + { + case 6: + return {{1.810e-01, 8.730e-01, 1.180e+00, 1.480e+00, 5.620e-01}, {1.180e-02, 4.420e-01, 1.520e+00, 4.350e+00, 9.420e+00}}; + } + } + break; + case 76: + { + switch(charge) + { + case 4: + return {{5.860e-01, 1.310e+00, 1.630e+00, 1.710e+00, 5.400e-01}, {1.550e-01, 9.380e-01, 3.190e+00, 7.840e+00, 1.930e+01}}; + } + } + break; + case 77: + { + switch(charge) + { + case 3: + return {{6.920e-01, 1.370e+00, 1.800e+00, 1.970e+00, 8.040e-01}, {1.820e-01, 1.040e+00, 3.470e+00, 8.510e+00, 2.120e+01}}; + case 4: + return {{6.530e-01, 1.290e+00, 1.500e+00, 1.740e+00, 6.830e-01}, {1.740e-01, 9.920e-01, 3.140e+00, 7.220e+00, 1.720e+01}}; + } + } + break; + case 78: + { + switch(charge) + { + case 2: + return {{8.720e-01, 1.680e+00, 2.630e+00, 1.930e+00, 4.750e-01}, {2.230e-01, 1.350e+00, 4.990e+00, 1.360e+01, 3.300e+01}}; + case 4: + return {{5.500e-01, 1.210e+00, 1.620e+00, 1.950e+00, 6.100e-01}, {1.420e-01, 8.330e-01, 2.810e+00, 7.210e+00, 1.770e+01}}; + } + } + break; + case 79: + { + switch(charge) + { + case 1: + return {{8.110e-01, 1.570e+00, 2.630e+00, 2.680e+00, 9.980e-01}, {2.010e-01, 1.180e+00, 4.250e+00, 1.210e+01, 3.440e+01}}; + case 3: + return {{7.220e-01, 1.390e+00, 1.940e+00, 1.940e+00, 6.990e-01}, {1.840e-01, 1.060e+00, 3.580e+00, 8.560e+00, 2.040e+01}}; + } + } + break; + case 80: + { + switch(charge) + { + case 1: + return {{7.960e-01, 1.560e+00, 2.720e+00, 2.760e+00, 1.180e+00}, {1.940e-01, 1.140e+00, 4.210e+00, 1.240e+01, 3.620e+01}}; + case 2: + return {{7.730e-01, 1.490e+00, 2.450e+00, 2.230e+00, 5.700e-01}, {1.910e-01, 1.120e+00, 4.000e+00, 1.080e+01, 2.760e+01}}; + } + } + break; + case 81: + { + switch(charge) + { + case 1: + return {{8.200e-01, 1.570e+00, 2.780e+00, 2.820e+00, 1.310e+00}, {1.970e-01, 1.160e+00, 4.230e+00, 1.270e+01, 3.570e+01}}; + case 3: + return {{8.360e-01, 1.430e+00, 3.940e-01, 2.510e+00, 1.500e+00}, {2.080e-01, 1.200e+00, 2.570e+00, 4.860e+00, 1.350e+01}}; + } + } + break; + case 82: + { + switch(charge) + { + case 2: + return {{7.550e-01, 1.440e+00, 2.480e+00, 2.450e+00, 1.030e+00}, {1.810e-01, 1.050e+00, 3.750e+00, 1.060e+01, 2.790e+01}}; + case 4: + return {{5.830e-01, 1.140e+00, 1.600e+00, 2.060e+00, 6.620e-01}, {1.440e-01, 7.960e-01, 2.580e+00, 6.220e+00, 1.480e+01}}; + } + } + break; + case 83: + { + switch(charge) + { + case 3: + return {{7.080e-01, 1.350e+00, 2.280e+00, 2.180e+00, 7.970e-01}, {1.700e-01, 9.810e-01, 3.440e+00, 9.410e+00, 2.370e+01}}; + case 5: + return {{6.540e-01, 1.180e+00, 1.250e+00, 1.660e+00, 7.780e-01}, {1.620e-01, 9.050e-01, 2.680e+00, 5.140e+00, 1.120e+01}}; + } + } + break; + case 88: + { + switch(charge) + { + case 2: + return {{9.110e-01, 1.650e+00, 2.530e+00, 3.620e+00, 1.580e+00}, {2.040e-01, 1.260e+00, 4.030e+00, 1.260e+01, 3.000e+01}}; + } + } + break; + case 89: + { + switch(charge) + { + case 3: + return {{9.150e-01, 1.640e+00, 2.260e+00, 3.180e+00, 1.250e+00}, {2.050e-01, 1.280e+00, 3.920e+00, 1.130e+01, 2.510e+01}}; + } + } + break; + case 92: + { + switch(charge) + { + case 3: + return {{1.140e+00, 2.480e+00, 3.610e+00, 1.130e+00, 9.000e-01}, {2.500e-01, 1.840e+00, 7.390e+00, 1.800e+01, 2.270e+01}}; + case 4: + return {{1.090e+00, 2.320e+00, 1.200e+01, -9.110e+00, 2.150e+00}, {2.430e-01, 1.750e+00, 7.790e+00, 8.310e+00, 1.650e+01}}; + case 6: + return {{6.870e-01, 1.140e+00, 1.830e+00, 2.530e+00, 9.570e-01}, {1.540e-01, 8.610e-01, 2.580e+00, 7.700e+00, 1.590e+01}}; + } + } + break; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + /***************************************************************************************/ + Atomic_Coef_cpu atomic_coef_gaussian(const LNL_Coef_cpu& feg) + { + Atomic_Coef_cpu atomic_coef(feg.size(), T(0)); + + for(auto ik = 0; ik < feg.size(); ik++) + { + auto cl = feg.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(0):feg.cnl[ik]/T(4); + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = T(0.5)*c_2Pi2a0*cl*pow(c_pi/cnl, T(3.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_pi*cl/cnl; + atomic_coef.vzp.cnl[ik] = c_pi2/cnl; + } + } + + return atomic_coef; + } + + // 1: doyle and Turner parameterization - 4 Gaussians - [0, 4] + Atomic_Coef_cpu atomic_coef_doyle_neutral_0_4(const dt_int32& Z) + { + auto feg_coef = load_feg_doyle_neutral_0_4(Z); + + auto atomic_coef = atomic_coef_gaussian(feg_coef); + atomic_coef.atomic_pot_parm_typ = eappt_doyle_0_4; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + return atomic_coef; + } + + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + Atomic_Coef_cpu atomic_coef_peng_neutral_0_4(const dt_int32& Z) + { + auto feg_coef = load_feg_peng_neutral_0_4(Z); + + auto atomic_coef = atomic_coef_gaussian(feg_coef); + + atomic_coef.atomic_pot_parm_typ = eappt_peng_0_4; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + return atomic_coef; + } + + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + Atomic_Coef_cpu atomic_coef_peng_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_peng_neutral_0_12(Z); + + if (feg_coef.size()==0) + { + return {}; + } + + auto atomic_coef = atomic_coef_gaussian(feg_coef); + atomic_coef.atomic_pot_parm_typ = eappt_peng_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + return atomic_coef; + } + + // 4: Kirkland parameterization - 3 yukawa + 3 Gaussians - [0, 12] + Atomic_Coef_cpu atomic_coef_kirkland_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_kirkland_neutral_0_12(Z); + + Atomic_Coef_cpu atomic_coef(feg_coef.size(), T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_kirkland_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + for(auto ik = 0; ik < 3; ik++) + { + auto cl = feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?0.0:feg_coef.cnl[ik]; + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*c_pi*cl*cnl; + atomic_coef.pr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi*cl; + atomic_coef.vr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_2pi*cl; + atomic_coef.vzp.cnl[ik] = c_2pi*::sqrt(cnl); + } + } + + for(auto ik = 3; ik < 6; ik++) + { + auto cl = feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(0):feg_coef.cnl[ik]; + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = T(0.5)*c_2Pi2a0*cl*pow(c_pi/cnl, T(3.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_pi*cl/cnl; + atomic_coef.vzp.cnl[ik] = c_pi2/cnl; + } + } + + return atomic_coef; + } + + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + Atomic_Coef_cpu atomic_coef_weickenmeier_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_weickenmeier_neutral_0_12(Z); + + Atomic_Coef_cpu atomic_coef(feg_coef.size(), T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_weickenmeier_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + for(auto ik = 0; ik < 6; ik++) + { + // 1.0/c_2Pi2a0 = 4.0*0.0239336609991378 + auto cl = Z/(c_2Pi2a0*T(3)*(T(1)+feg_coef.cl[ik])); + cl *= (ik>= 3)?feg_coef.cl[ik]:T(1); + + auto cnl = (fcn_is_zero(cl))?0.0:feg_coef.cnl[ik]/T(4); + cl = (fcn_is_zero(cnl))?T(0):cl; + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi*cl; + atomic_coef.vr.cnl[ik] = c_pi/::sqrt(cnl); + + // there is not analytic expression for the projected potential + atomic_coef.vzp.cl[ik] = atomic_coef.vr.cl[ik]; + atomic_coef.vzp.cnl[ik] = atomic_coef.vr.cnl[ik]; + } + } + + return atomic_coef; + } + + // 6: Lobato parameterization - Hydrogen functions - [0, 12] + Atomic_Coef_cpu atomic_coef_lobato_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_lobato_neutral_0_12(Z); + + Atomic_Coef_cpu atomic_coef(feg_coef.size(), T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_lobato_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + for(auto ik = 0; ik < 5; ik++) + { + auto cl = (fcn_is_zero(feg_coef.cl[ik]))?T(0):feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(1):feg_coef.cnl[ik]; + + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl/cnl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*c_pi2*cl/pow(cnl, T(2.5)); + atomic_coef.pr.cnl[ik] = c_2pi/::sqrt(cnl); + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi2*cl/pow(cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_2pi/::sqrt(cnl); + + atomic_coef.vzp.cl[ik] = 2.0*c_pot_factor*c_pi2*cl/pow(cnl, T(1.5)); + atomic_coef.vzp.cnl[ik] = c_2pi/::sqrt(cnl); + } + + return atomic_coef; + } + + // 10: Peng et al. parameterization for ions - 5 Gaussians - [0, 4] + Atomic_Coef_cpu atomic_coef_peng_ion_0_4(const dt_int32& Z, const dt_int32& charge) + { + auto feg_coef = load_feg_peng_ion_0_4(Z, charge); + + if (fcn_is_zero(feg_coef.cl[0])) + { + return atomic_coef_peng_neutral_0_4(Z); + } + + Atomic_Coef_cpu atomic_coef(feg_coef.size()+1, T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_peng_ion_0_4; + atomic_coef.Z = Z; + atomic_coef.charge = charge; + + for(auto ik = 0; ik < 5; ik++) + { + auto cl = feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(0):feg_coef.cnl[ik]/T(4); + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = T(0.5)*c_2Pi2a0*cl*pow(c_pi/cnl, T(3.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_pi*cl/cnl; + atomic_coef.vzp.cnl[ik] = c_pi2/cnl; + } + } + + // 1/g2 + if (fcn_is_nzero(feg_coef.cl[0])) + { + dt_int32 ik = 5; + T r0 = 2.0; + auto cl = charge/c_2Pi2a0; + auto cnl = pow(c_2pi*r0, -2); + + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*c_pi*cl*cnl; + atomic_coef.pr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi*cl; + atomic_coef.vr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_2pi*cl; + atomic_coef.vzp.cnl[ik] = c_2pi*::sqrt(cnl); + } + + return atomic_coef; + } + }; + + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/atomic_fcns_mt.cuh b/src - Copy (2)/atomic_fcns_mt.cuh new file mode 100755 index 00000000..465eb0a0 --- /dev/null +++ b/src - Copy (2)/atomic_fcns_mt.cuh @@ -0,0 +1,512 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ATOMIC_FCNS_MT_H + #define ATOMIC_FCNS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "type_traits_mt.cuh" + #include "intrpl_coef.cuh" + #include "quad_data.cuh" + #include "cgpu_vctr.cuh" + #include "atomic_data_mt.cuh" + #include "cgpu_detail_mt.cuh" + #include "cpu_fcns_mt.hpp" + + #ifdef __CUDACC__ + #include "gpu_fcns_mt.cuh" + #endif + + namespace mt + { + #define SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pfcn, ...) \ + switch(atomic_pot_parm_typ) \ + { \ + case eappt_doyle_0_4: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_peng_0_4: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_peng_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_kirkland_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_weickenmeier_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_lobato_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_peng_ion_0_4: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + } + + /************************************** feg ********************************************/ + template + void fcn_feg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const pLNL_Coef& coef, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_feg, g, coef, y); + } + + template + void fcn_feg_dfeg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_feg_dfeg, g, coef, y, dy); + } + + /*************************************** fxg *******************************************/ + template + void fcn_fxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const T& Z, const pLNL_Coef& coef, pVctr_32& y) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + } + } + + template + void fcn_fxg_dfxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const T& Z, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + } + } + + /*************************************** pr ********************************************/ + template + void fcn_pr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_pr, r, coef, y); + } + + template + void fcn_pr_dpr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_pr_dpr, r, coef, y, dy); + } + + /**************************************** vr *******************************************/ + template + void fcn_vr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vr, r, coef, y); + } + + template + void fcn_vr_dvr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vr_dvr, r, coef, y, dy); + } + + /************************************** vz *********************************************/ + template + void fcn_vz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const T& z_0, const T& z_e, const pLNL_Coef& coef, const pQuad_Coef_1d& quad, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vz, r, z_0, z_e, coef, quad, y); + } + + template + void fcn_vz_dvz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const T& z_0, const T& z_e, const pLNL_Coef& coef, const pQuad_Coef_1d& quad, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vz_dvz, r, z_0, z_e, coef, quad, y, dy); + } + + /************************************* vzp *********************************************/ + template + void fcn_vzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pQuad_Coef_1d* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, *pquad, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + } + } + + template + void fcn_vzp_dvzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy, pQuad_Coef_1d* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, *pquad, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + } + } + + /***************************************************************************************/ + /********************************** atomic fcns ****************************************/ + /***************************************************************************************/ + template + class Atomic_Fcns + { + public: + using value_type = T; + + Atomic_Fcns(): pcoef(nullptr) + { + Quad_Data quad_data; + quad_data(eqt_tanh_sinh_int_n1_p1, c_nqz, quad_a_b); // 1: eqt_tanh_sinh_int_n1_p1 -> int_-1^1 f(x) dx + quad_data(eqt_exp_sinh_int_0_pinfty, c_nqz, quad_0_infty); // 2: eqt_exp_sinh_int_0_pinfty -> int_0^infty f(x) dx + + pquad_a_b = quad_a_b; + pquad_0_infty = quad_0_infty; + } + + Atomic_Fcns(Atomic_Coef_cpu& coef): Atomic_Fcns() + { + set_atomic_coef(coef); + } + + void set_atomic_coef(Atomic_Coef_cpu& coef) + { + pcoef = &coef; + } + + /***************************************************************************************/ + T feg(const T& g) + { + return fcn_feg(pcoef->atomic_pot_parm_typ, g, pcoef->feg); + } + + void feg_dfeg(const T& g, T& y, T& dy) + { + fcn_feg_dfeg(pcoef->atomic_pot_parm_typ, g, pcoef->feg, y, dy); + } + + void feg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y) + { + fcn_feg(pcoef->atomic_pot_parm_typ, g, pcoef->feg, y); + } + + void feg_dfeg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_feg_dfeg(pcoef->atomic_pot_parm_typ, g, pcoef->feg, y, dy); + } + + /***************************************************************************************/ + T fxg(const T& g) + { + return fcn_fxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg); + } + + void fxg_dfxg(const T& g, T& y, T& dy) + { + fcn_fxg_dfxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg, y, dy); + } + + void fxg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y) + { + fcn_fxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg, y); + } + + void fxg_dfxg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_fxg_dfxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg, y, dy); + } + + /***************************************************************************************/ + T pr(const T& r) + { + return fcn_pr(pcoef->atomic_pot_parm_typ, r, pcoef->pr); + } + + void pr_dpr(const T& r, T& y, T& dy) + { + fcn_pr_dpr(pcoef->atomic_pot_parm_typ, r, pcoef->pr, y, dy); + } + + void pr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_pr(pcoef->atomic_pot_parm_typ, r, pcoef->pr, y); + } + + void pr_dpr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_pr_dpr(pcoef->atomic_pot_parm_typ, r, pcoef->pr, y, dy); + } + + /***************************************************************************************/ + T vr(const T& r) + { + return fcn_vr(pcoef->atomic_pot_parm_typ, r, pcoef->vr); + } + + void vr_dvr(const T& r, T& y, T& dy) + { + fcn_vr_dvr(pcoef->atomic_pot_parm_typ, r, pcoef->vr, y, dy); + } + + void vr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_vr(pcoef->atomic_pot_parm_typ, r, pcoef->vr, y); + } + + void vr_dvr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_vr_dvr(pcoef->atomic_pot_parm_typ, r, pcoef->vr, y, dy); + } + + /***************************************************************************************/ + T vz(const T& z_0, const T& z_e, const T& r) + { + return fcn_vz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b); + } + + void vz_dvz(const T& z_0, const T& z_e, const T& r, T& y, T& dy) + { + fcn_vz_dvz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b, y, dy); + } + + void vz(const T& z_0, const T& z_e, const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_vz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b, y); + } + + void vz_dvz(const T& z_0, const T& z_e, const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_vz_dvz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b, y, dy); + } + + /***************************************************************************************/ + T vzp(const T& r) + { + return fcn_vzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, &pquad_0_infty); + } + + void vzp_dvzp(const T& r, T& y, T& dy) + { + fcn_vzp_dvzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, y, dy, &pquad_0_infty); + } + + void vzp(const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_vzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, y, &pquad_0_infty); + } + + void vzp_dvzp(const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_vzp_dvzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, y, dy, &pquad_0_infty); + } + + /***************************************************************************************/ + T atomic_radius_rms(const dt_int32& dim) + { + if (fcn_is_zero(pcoef->vr.cl[0])) + { + return T(0); + } + + auto fcn = [&](const T& r) { return (dim == 3)?vr(r):vzp(r); }; + + KS vr_sum = T(0); + KS vr2_sum = T(0); + for(auto ik = 0; ik < quad_0_infty.size(); ik++) + { + const auto r_ik = quad_0_infty.x[ik]; + const auto vr_ik = quad_0_infty.w[ik]*fcn(r_ik)*pow(r_ik, dim-1); + vr_sum += vr_ik; + vr2_sum += vr_ik*r_ik*r_ik; + } + + return ::sqrt(vr2_sum/vr_sum); + } + + T atomic_radius_cutoff(const dt_int32& dim, const T& vr_lim) + { + if (fcn_is_zero(pcoef->vr.cl[0]) || fabs(vr_lim)<1e-8) + { + return T(0); + } + + auto fcn = [&](const T& r) { return ((dim == 3)?vr(r):vzp(r))-vr_lim; }; + + const T r_min = 1e-5; + const T r_max = 25.0; + + return fcn_fd_root(r_min, r_max, 1e-8, 200, fcn); + } + + private: + Atomic_Coef_cpu* pcoef; + + Quad_Coef_1d_cpu quad_a_b; + Quad_Coef_1d_cpu quad_0_infty; + pQuad_Coef_1d_cpu pquad_a_b; + pQuad_Coef_1d_cpu pquad_0_infty; + }; + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/atomic_vib.hpp b/src - Copy (2)/atomic_vib.hpp new file mode 100755 index 00000000..d66dc760 --- /dev/null +++ b/src - Copy (2)/atomic_vib.hpp @@ -0,0 +1,129 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ATOMIC_VIB_H + #define ATOMIC_VIB_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "r_3d.cuh" + + namespace mt + { + /**************** atomic vibration model parameters ******************/ + class Atomic_Vib + { + public: + eAtomic_Vib_Mod model; // 1: Still atom model, 2: Absorptive potential model, 3: Frozen phonon model + dt_bool coh_contrib; // true, false + dt_int32 dist; // 1: Gaussian (Phonon distribution) + dt_int32 seed; // random seed (frozen phonon) + dt_bool sgl_conf; // single configuration: true, false + dt_int32 nconf; // if single phonon configuration == true then phonon configuration if not number of frozen phonon configurations + R_3d dim; // atomic vibration dimension (x, y, z) + + dt_int32 iconf_0; // initial configuration + dt_int32 iconf_e; // final configuration + + Atomic_Vib(): model(eavm_still_atom), coh_contrib(false), sgl_conf(false), dist(1), seed(300183), + nconf(1), iconf_0(1), iconf_e(1), dim{true, true, false}{} + + void assign(Atomic_Vib& atomic_vib) + { + if (this != &atomic_vib) + { + model = atomic_vib.model; + coh_contrib = atomic_vib.coh_contrib; + sgl_conf = atomic_vib.sgl_conf; + dist = atomic_vib.dist; + seed = atomic_vib.seed; + nconf = atomic_vib.nconf; + iconf_0 = atomic_vib.iconf_0; + dim = atomic_vib.dim; + } + } + + void set_in_data(const eAtomic_Vib_Mod& model, const dt_bool& coh_contrib, const dt_bool& sgl_conf, const dt_int32& dist, + const dt_int32& seed, const dt_int32& nconf, const dt_int32& iconf_0, const R_3d& dim) + { + this->model = model; + this->coh_contrib = coh_contrib; + this->sgl_conf = sgl_conf; + this->dist = dist; + this->seed = seed; + this->nconf = nconf; + this->iconf_0 = iconf_0; + this->dim = dim; + + set_dep_var(); + } + + void set_dep_var() + { + seed = max(1, seed); + + if (is_avm_frozen_phonon()) + { + nconf = max(1, nconf); + iconf_0 = (sgl_conf)?nconf:1; + iconf_e = nconf; + } + else + { + iconf_0 = iconf_e = nconf = 1; + } + } + + Atomic_Vib& operator=(Atomic_Vib& atomic_vib) + { + assign(atomic_vib); + return *this; + } + + dt_bool is_avm_still_atom() const + { + return mt::is_avm_still_atom(model); + } + + dt_bool is_avm_absorptive_pot() const + { + return mt::is_avm_absorptive_pot(model); + } + + dt_bool is_avm_frozen_phonon() const + { + return mt::is_avm_frozen_phonon(model); + } + + dt_bool is_avm_frozen_phonon_sgl_conf() const + { + return mt::is_avm_frozen_phonon_sgl_conf(model, sgl_conf); + } + + dt_int32 number_conf() + { + return (nconf-iconf_0+1); + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/beam_pos_2d.hpp b/src - Copy (2)/beam_pos_2d.hpp new file mode 100755 index 00000000..7d445697 --- /dev/null +++ b/src - Copy (2)/beam_pos_2d.hpp @@ -0,0 +1,162 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef BEAM_POS_2D_H + #define BEAM_POS_2D_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + #include + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_fcns_gen.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "particles.cuh" + #include "types.cuh" + + namespace mt + { + template + struct Beam_Pos_2d + { + Vctr idx; // index + Vctr, edev_cpu> p; // xy-position + + Beam_Pos_2d() {} + + Beam_Pos_2d(dt_int32 new_size) { resize(new_size); } + + template + void set_in_data(const TVctr& x) + { + dt_int32 n = x.cols; + resize(n); + for(auto ik = 0; ik(x(0, ik), x(1, ik)); + } + } + + template + void set_in_data(const TVctr& x, const TVctr& y) + { + dt_int32 n = min(x.size(), y.size()); + resize(n); + for(auto ik = 0; ik(x[ik], y[ik]); + } + } + + typename Vctr, edev_cpu>::iterator begin() const + { + return p.begin(); + } + + typename Vctr, edev_cpu>::iterator end() const + { + return p.end(); + } + + dt_int32 size() const { return idx.size(); } + + void resize(dt_int32 new_size) + { + idx.resize(new_size); + p.resize(new_size); + } + + void init() + { + thrust::fill(idx.begin(), idx.end(), 0); + thrust::fill(p.begin(), p.end(), R_2d()); + } + + void clear() + { + idx.clear(); + p.clear(); + } + + void shrink_to_fit() + { + idx.shrink_to_fit(); + p.shrink_to_fit(); + } + + void clear_shrink_to_fit() + { + clear(); + shrink_to_fit(); + } + + Vctr x() + { + Vctr x; + x.reserve(p.size()); + for(auto ik = 0; ik y() + { + Vctr y; + y.reserve(p.size()); + for(auto ik = 0; ik + void assign(TBeam_Pos_2d &beam_pos) + { + resize(beam_pos.size()); + thrust::copy(beam_pos.idx.begin(), beam_pos.idx.end(), idx.begin()); + thrust::copy(beam_pos.p.begin(), beam_pos.p.end(), p.begin()); + } + + template + Beam_Pos_2d& operator=(const TBeam_Pos_2d &beam_pos) + { + assign(beam_pos); + return *this; + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/blas.cuh b/src - Copy (2)/blas.cuh new file mode 100755 index 00000000..28314eb3 --- /dev/null +++ b/src - Copy (2)/blas.cuh @@ -0,0 +1,145 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef BLAS_H + #define BLAS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + + #include + #include + #include + + namespace blass + { + template + struct GEAM; + + template + struct GEAM + { + public: + using value_type = T; + using TVctr_c = mt::Vctr; + + const mt::eDev device; + + GEAM(): device(mt::edev_cpu) {} + }; + + template + struct GEAM + { + public: + using value_type = T; + using TVctr = mt::Vctr; + + const mt::eDev device; + + GEAM(): device(mt::edev_gpu) + { + cublasCreate(&handle); + } + + ~GEAM() + { + cublasDestroy(handle); + } + + void operator()(mt::eOP trsa, mt::eOP trsb, dt_int32 m, dt_int32 n, T alpha, TVctr& A, T beta, TVctr& B, TVctr& C) + { + cublasOperation_t transa = op_2_cbop(trsa); + cublasOperation_t transb = op_2_cbop(trsb); + + geam(handle, transa, transb, m, n, alpha, A, m, beta, B, m, C, m); + } + + private: + + cublasOperation_t op_2_cbop(mt::eOP op) + { + return static_cast(static_cast(op)-1); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_float32 alpha, mt::Vctr& A, dt_int32 lda, dt_float32 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + dt_float32 *ralpha = reinterpret_cast(&alpha); + dt_float32 *rbeta = reinterpret_cast(&beta); + + dt_float32 *rA = reinterpret_cast(A.data()); + dt_float32 *rB = reinterpret_cast(B.data()); + dt_float32 *rC = reinterpret_cast(C.data()); + + auto result = cublasSgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_float64 alpha, mt::Vctr& A, dt_int32 lda, dt_float64 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + dt_float64 *ralpha = reinterpret_cast(&alpha); + dt_float64 *rbeta = reinterpret_cast(&beta); + + dt_float64 *rA = reinterpret_cast(A.data()); + dt_float64 *rB = reinterpret_cast(B.data()); + dt_float64 *rC = reinterpret_cast(C.data()); + + cublasDgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_cfloat32 alpha, mt::Vctr& A, dt_int32 lda, dt_cfloat32 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + cuComplex *ralpha = reinterpret_cast(&alpha); + cuComplex *rbeta = reinterpret_cast(&beta); + + cuComplex *rA = reinterpret_cast(A.data()); + cuComplex *rB = reinterpret_cast(B.data()); + cuComplex *rC = reinterpret_cast(C.data()); + + cublasCgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_cfloat64 alpha, mt::Vctr& A, dt_int32 lda, dt_cfloat64 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + cuDoubleComplex *ralpha = reinterpret_cast(&alpha); + cuDoubleComplex *rbeta = reinterpret_cast(&beta); + + cuDoubleComplex *rA = reinterpret_cast(A.data()); + cuDoubleComplex *rB = reinterpret_cast(B.data()); + cuDoubleComplex *rC = reinterpret_cast(C.data()); + + cublasZgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + cublasHandle_t handle; + }; + } // namespace blas + +#endif \ No newline at end of file diff --git a/src - Copy (2)/border.cuh b/src - Copy (2)/border.cuh new file mode 100755 index 00000000..cc7106fa --- /dev/null +++ b/src - Copy (2)/border.cuh @@ -0,0 +1,798 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef BORDER_H + #define BORDER_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "math.cuh" + #include "const_enum.cuh" + #include "cgpu_fcns_gen.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "cgpu_vctr.cuh" + + /***************************************************************************************/ + /******************************** rectangular border ***********************************/ + /***************************************************************************************/ + namespace mt + { + template class Border_Rect_xd; + + template + using iBorder_Rect_xd = Border_Rect_xd; + + /* 1d */ + template + using Border_Rect_1d = Border_Rect_xd; + + using iBorder_Rect_1d = Border_Rect_xd; + + using iBorder_Rect_1d_64 = Border_Rect_xd; + + /* 2d */ + template + using Border_Rect_2d = Border_Rect_xd; + + using iBorder_Rect_2d = Border_Rect_xd; + + using iBorder_Rect_2d_64 = Border_Rect_xd; + + /* 3d */ + template + using Border_Rect_3d = Border_Rect_xd; + + using iBorder_Rect_3d = Border_Rect_xd; + + using iBorder_Rect_3d_64 = Border_Rect_xd; + } + + /* template specialization 1d */ + namespace mt + { + template + class Border_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T bx_0; // initial x position + T bx_e; // final x position + + /************************************* constructors ************************************/ + CGPU_EXEC + Border_Rect_xd(): bx_0(0), bx_e(0) {} + + Border_Rect_xd(const T& bx_0, const T& bx_e) + { + set_in_data(bx_0, bx_e); + } + + template + Border_Rect_xd(const dt_init_list& list) + { + set_in_data(list); + } + + template + Border_Rect_xd(const Vctr_cpu& vctr) + { + set_in_data(vctr); + } + + /* copy constructor */ + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /* converting constructor */ + template + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + bx_0 = border.bx_0; + bx_e = border.bx_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + bx_0 = T(border.bx_0); + bx_e = T(border.bx_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Border_Rect_xd& border) + { + *this = border; + } + + /***************************************************************************************/ + template + void set_in_data(const U& bx_0, const U& bx_e) + { + this->bx_0 = bx_0; + this->bx_e = bx_e; + } + + template + void set_in_data(const dt_init_list& list) + { + auto ptr = list.begin(); + + bx_0 = T(ptr[0]); + bx_e = T(ptr[1]); + } + + template + void set_in_data(const Vctr_cpu& vctr) + { + if (vctr.size_32()==1) + { + set_in_data({vctr[0], vctr[0]}); + } + else + { + set_in_data({vctr[0], vctr[1]}); + } + } + + CGPU_EXEC + void clear() + { + bx_0 = T(0); + bx_e = T(0); + } + + CGPU_EXEC + T bx_sum() const + { + return bx_0 + bx_e; + } + + CGPU_EXEC + T bx_min() const + { + return fcn_min(bx_0, bx_e); + } + + CGPU_EXEC + T bx_max() const + { + return fcn_max(bx_0, bx_e); + } + CGPU_EXEC + T bs_x(const T& bs_x_i) const + { + return fcn_max(bs_x_i - bx_sum(), T(0)); + } + + CGPU_EXEC + T bs(const T& bs_i) const + { + return bs_x(bs_i); + } + + CGPU_EXEC + T bs_min(const T& bs) const + { + return bs(bs); + } + + CGPU_EXEC + T bs_max(const T& bs) const + { + return bs(bs); + } + + CGPU_EXEC + T bs_x_h(const T& bs_x) const + { + return this->bs_x(bs_x)/T(2); + } + + CGPU_EXEC + T bs_h(const T& bs) const + { + return bs_x_h(bs); + } + + CGPU_EXEC + T rx_c(const T& bs_x) const + { + return bx_0 + bs_x_h(bs_x); + } + + CGPU_EXEC + T r_c(const T& bs) const + { + return rx_c(bs); + } + + CGPU_EXEC + T radius_x(const T& bs_x) const + { + return bs_x_h(bs_x); + } + + CGPU_EXEC + T radius(const T& bs) const + { + return radius_x(bs); + } + + CGPU_EXEC + T radius_x_p(const T& bs_x, const T& p) const + { + return (T(1)-p)*radius_x(bs_x); + } + + CGPU_EXEC + T radius_p(const T& bs, const T& p) const + { + return radius_x_p(bs, p); + } + + void set_by_sft(const T& bs, const T& dr) + { + bx_0 = fcn_set_bound(dr, T(0), bs); + bx_e = fcn_set_bound(bs - dr, T(0), bs); + } + + void sft_bdr(const T& bs, const T& dr) + { + bx_0 = fcn_set_bound(bx_0 + dr, T(0), bs); + bx_e = fcn_set_bound(bx_e - dr, T(0), bs); + } + }; + } + + /* template specialization 2d */ + namespace mt + { + template + class Border_Rect_xd: public Border_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T by_0; // initial y position + T by_e; // final y position + + /************************************* constructors ************************************/ + CGPU_EXEC + Border_Rect_xd(): Border_Rect_xd(), by_0(0), by_e(0) {} + + Border_Rect_xd(const T& bx_0, const T& bx_e, const T& by_0, const T& by_e) + { + set_in_data(bx_0, bx_e, by_0, by_e); + } + + template + Border_Rect_xd(const dt_init_list& list) + { + set_in_data(list); + } + + template + Border_Rect_xd(const Vctr_cpu& vctr) + { + set_in_data(vctr); + } + + /* copy constructor */ + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /* converting constructor */ + template + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + by_0 = border.by_0; + by_e = border.by_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + by_0 = T(border.by_0); + by_e = T(border.by_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Border_Rect_xd& border) + { + *this = border; + } + + /***************************************************************************************/ + template + void set_in_data(const U& bx_0, const U& bx_e, const U& by_0, const U& by_e) + { + Border_Rect_xd::set_in_data(bx_0, bx_e); + + this->by_0 = by_0; + this->by_e = by_e; + } + + template + void set_in_data(const dt_init_list& list) + { + auto ptr = list.begin(); + + Border_Rect_xd::set_in_data({ptr[0], ptr[1]}); + + by_0 = T(ptr[2]); + by_e = T(ptr[3]); + } + + template + void set_in_data(const Vctr_cpu& vctr) + { + const auto shape = vctr.shape(); + + if (shape[0]==1) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[0], vctr[0], vctr[0]}); + else if (shape[1]<3) + set_in_data({vctr[0], vctr[0], vctr[1], vctr[1]}); + else if (shape[1]<4) + set_in_data({vctr[0], vctr[1], vctr[2], T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3]}); + } + else if (shape[0]==2) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[1], T(0), T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3]}); + } + } + + CGPU_EXEC + void clear() + { + Border_Rect_xd::clear(); + + by_0 = T(0); + by_e = T(0); + } + + CGPU_EXEC + T by_sum() const + { + return by_0 + by_e; + } + + CGPU_EXEC + T by_min() const + { + return fcn_min(by_0, by_e); + } + + CGPU_EXEC + T by_max() const + { + return fcn_max(by_0, by_e); + } + CGPU_EXEC + T bs_y(const T& bs_y_i) const + { + return fcn_max(bs_y_i - by_sum(), T(0)); + } + + CGPU_EXEC + R_2d bs(const R_2d& bs_i) const + { + return {this->bs_x(bs_i.x), bs_y(bs_i.y)}; + } + + CGPU_EXEC + T bs_min(const R_2d& bs) const + { + return fmin(bs(bs)); + } + + CGPU_EXEC + T bs_max(const R_2d& bs) const + { + return fmax(bs(bs)); + } + + CGPU_EXEC + T bs_y_h(const T& bs_y) const + { + return this->bs_y(bs_y)/T(2); + } + + CGPU_EXEC + R_2d bs_h(const R_2d& bs) const + { + return {this->bs_x_h(bs.x), bs_y_h(bs.y)}; + } + + CGPU_EXEC + T ry_c(const T& bs_y) const + { + return by_0 + bs_y_h(bs_y); + } + + CGPU_EXEC + R_2d r_c(const R_2d& bs) const + { + return {this->rx_c(bs.x), ry_c(bs.y)}; + } + + CGPU_EXEC + T radius_y(const T& bs_y) const + { + return bs_y_h(bs_y); + } + + CGPU_EXEC + R_2d radius(const R_2d& bs) const + { + return {this->radius_x(bs.x), radius_y(bs.y)}; + } + + CGPU_EXEC + T radius_y_p(const T& bs_y, const T& p) const + { + return (T(1)-p)*radius_y(bs_y); + } + + CGPU_EXEC + R_2d radius_p(const R_2d& bs, const T& p) const + { + return {this->radius_x_p(bs.x, p), radius_y_p(bs.y, p)}; + } + + void set_by_sft(const R_2d& bs, const R_2d& dr) + { + Border_Rect_xd::set_by_sft(bs.x, dr.x); + + by_0 = fcn_set_bound(dr.y, T(0), bs.y); + by_e = fcn_set_bound(bs.y - dr.y, T(0), bs.y); + } + + void sft_bdr(const R_2d& bs, const R_2d& dr) + { + Border_Rect_xd::sft_bdr(bs.x, dr.x); + + by_0 = fcn_set_bound(by_0 + dr.y, T(0), bs.y); + by_e = fcn_set_bound(by_e - dr.y, T(0), bs.y); + } + }; + } + + /* template specialization 3d */ + namespace mt + { + template + class Border_Rect_xd: public Border_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T bz_0; // initial z position + T bz_e; // final z position + + /************************************* constructors ************************************/ + CGPU_EXEC + Border_Rect_xd(): Border_Rect_xd(), bz_0(0), bz_e(0) {} + + Border_Rect_xd(const T& bx_0, const T& bx_e, const T& by_0, const T& by_e, const T& bz_0, const T& bz_e) + { + set_in_data(bx_0, bx_e, by_0, by_e, bz_0, bz_e); + } + + template + Border_Rect_xd(const dt_init_list& list) + { + set_in_data(list); + } + + template + Border_Rect_xd(const Vctr_cpu& vctr) + { + set_in_data(vctr); + } + + /* copy constructor */ + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /* converting constructor */ + template + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + bz_0 = border.bz_0; + bz_e = border.bz_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + bz_0 = T(border.bz_0); + bz_e = T(border.bz_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Border_Rect_xd& border) + { + *this = border; + } + + /***************************************************************************************/ + template + void set_in_data(const U& bx_0, const U& bx_e, const U& by_0, const U& by_e, const U& bz_0, const U& bz_e) + { + Border_Rect_xd::set_in_data(bx_0, bx_e, by_0, by_e); + + this->bz_0 = bz_0; + this->bz_e = bz_e; + } + + template + void set_in_data(const dt_init_list& list) + { + auto ptr = list.begin(); + + Border_Rect_xd::set_in_data({ptr[0], ptr[1], ptr[2], ptr[3]}); + + bz_0 = T(ptr[4]); + bz_e = T(ptr[5]); + } + + template + void set_in_data(const Vctr_cpu& vctr) + { + const auto shape = vctr.shape(); + + if (shape[0]==1) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[0], vctr[0], vctr[0], T(0), T(0)}); + else if (shape[1]<3) + set_in_data({vctr[0], vctr[0], vctr[1], vctr[1], T(0), T(0)}); + else if (shape[1]<4) + set_in_data({vctr[0], vctr[0], vctr[1], vctr[1], vctr[2], vctr[2]}); + else if (shape[1]<5) + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], T(0), T(0)}); + else if (shape[1]<6) + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], vctr[4], T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], vctr[4], vctr[5]}); + } + else if (shape[0]==2) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[1], T(0), T(0), T(0), T(0)}); + else if (shape[1]<3) + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], T(0), T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], vctr[4], vctr[5]}); + } + } + + CGPU_EXEC + void clear() + { + Border_Rect_xd::clear(); + + bz_0 = T(0); + bz_e = T(0); + } + + CGPU_EXEC + T bz_sum() const + { + return bz_0 + bz_e; + } + + CGPU_EXEC + T bz_min() const + { + return fcn_min(bz_0, bz_e); + } + + CGPU_EXEC + T bz_max() const + { + return fcn_max(bz_0, bz_e); + } + CGPU_EXEC + T bs_z(const T& bs_z_i) const + { + return fcn_max(bs_z_i - bz_sum(), T(0)); + } + + CGPU_EXEC + R_3d bs(const R_3d& bs_i) const + { + return {this->bs_x(bs_i.x), this->bs_y(bs_i.y), bs_z(bs_i.z)}; + } + + CGPU_EXEC + T bs_min(const R_3d& bs) const + { + return fmin(bs(bs)); + } + + CGPU_EXEC + T bs_max(const R_3d& bs) const + { + return fmax(bs(bs)); + } + + CGPU_EXEC + T bs_z_h(const T& bs_z) const + { + return this->bs_z(bs_z)/T(2); + } + + CGPU_EXEC + R_3d bs_h(const R_3d& bs) const + { + return {this->bs_x_h(bs.x), this->bs_y_h(bs.y), bs_z_h(bs.z)}; + } + + CGPU_EXEC + T rz_c(const T& bs_z) const + { + return bz_0 + bs_z_h(bs_z); + } + + CGPU_EXEC + R_3d r_c(const R_3d& bs) const + { + return {this->rx_c(bs.x), this->ry_c(bs.y), rz_c(bs.z)}; + } + + CGPU_EXEC + T radius_z(const T& bs_z) const + { + return bs_z_h(bs_z); + } + + CGPU_EXEC + R_3d radius(const R_3d& bs) const + { + return {this->radius_x(bs.x), this->radius_y(bs.y), radius_z(bs.z)}; + } + + CGPU_EXEC + T radius_z_p(const T& bs_z, const T& p) const + { + return (T(1)-p)*radius_z(bs_z); + } + + CGPU_EXEC + R_3d radius_p(const R_3d& bs, const T& p) const + { + return {this->radius_x_p(bs.x, p), this->radius_y_p(bs.y, p), radius_z_p(bs.z, p)}; + } + + void set_by_sft(const R_3d& bs, const R_3d& dr) + { + Border_Rect_xd::set_bz_sft({bs.x, bs.y}, {dr.x, dr.y}); + + bz_0 = fcn_set_bound(dr.z, T(0), bs.z); + bz_e = fcn_set_bound(bs.z - dr.z, T(0), bs.z); + } + + void sft_bdr(const R_3d& bs, const R_3d& dr) + { + Border_Rect_xd::sft_bdr({bs.x, bs.y}, {dr.x, dr.y}); + + bz_0 = fcn_set_bound(bz_0 + dr.z, T(0), bs.z); + bz_e = fcn_set_bound(bz_e - dr.z, T(0), bs.z); + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/box_occ.hpp b/src - Copy (2)/box_occ.hpp new file mode 100755 index 00000000..6821b65f --- /dev/null +++ b/src - Copy (2)/box_occ.hpp @@ -0,0 +1,665 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef BOX_OCC_H + #define BOX_OCC_H + + #include "cgpu_fcns_gen.cuh" + #include "math.cuh" + #include "r_3d.cuh" + #include "types.cuh" + #include "particles.cuh" + #include "cgpu_stream.cuh" + + namespace mt + { + template + class Box_Occ_3d + { + public: + Box_Occ_3d(): d2_min(), a_min(), r_0(), nx(), ny(), nz(){}; + + Box_Occ_3d(T d_min, R_3d bs, R_3d r_0 = R_3d()) + { + set_in_data(d_min, bs, r_0); + } + + void set_in_data(T d_min, R_3d bs, R_3d r_0 = R_3d()) + { + d2_min = ::square(d_min); + a_min = d_min/mt::c_3i2; + this->r_0 = r_0; + + nx = fcn_cceil(bs.x/a_min); + ny = fcn_cceil(bs.y/a_min); + nz = fcn_cceil(bs.z/a_min); + + occ.clear(); + occ.shrink_to_fit(); + occ.resize({ny, nx, nz}, -1); + } + + void set(R_3d r, const dt_int32& val) + { + r = (r-r_0)/a_min; + + const auto ix = fcn_cfloor(r.x); + const auto iy = fcn_cfloor(r.y); + const auto iz = fcn_cfloor(r.z); + + occ(iy, ix, iz) = val; + } + + template + dt_bool check_r_min(const TPtc_3d& atoms, R_3d r) + { + const auto r_idx = (r-r_0)/a_min; + + const auto ix_m = fcn_cfloor(r_idx.x); + const auto iy_m = fcn_cfloor(r_idx.y); + const auto iz_m = fcn_cfloor(r_idx.z); + + const auto bb_bound = fcn_chk_bound(ix_m, 0, nx) && fcn_chk_bound(iy_m, 0, ny) && fcn_chk_bound(iz_m, 0, nz); + + if (bb_bound && (occ(iy_m, ix_m, iz_m) > -1)) + { + return false; + } + + const auto ax = range_loop_pbc(ix_m, nx); + const auto ay = range_loop_pbc(iy_m, ny); + const auto az = range_loop(iz_m, nz); + + for(auto iz: az) + { + for(auto ix: ax) + { + for(auto iy: ay) + { + auto iatom = occ(iy, ix, iz); + if (iatom>-1) + { + auto d2 = atoms.norm_2_pbc_xy(iatom, r); + if (d2 r_0; + + Vctr_cpu occ; + private: + T a_min; + T d2_min; + dt_int32 nx; + dt_int32 ny; + dt_int32 nz; + + Vctr_std range_loop(const dt_int32& k, const dt_int32& n_k) + { + if (k==0) + { + return {k, k+1, k+2}; + } + else if (k==1) + { + return {k-1, k, k+1, k+2}; + } + else if (k==n_k-1) + { + return {k-2, k-1, k}; + } + else if (k==n_k-2) + { + return {k-2, k-1, k, k+1}; + } + else + { + return {k-2, k-1, k, k+1, k+2}; + } + } + + Vctr_std range_loop_pbc(const dt_int32& k, const dt_int32& n_k) + { + if (k==0) + { + return {n_k-2, n_k-1, k, k+1, k+2}; + } + else if (k==1) + { + return {n_k-1, k-1, k, k+1, k+2}; + } + else if (k==n_k-1) + { + return {k-2, k-1, k, 0, 1}; + } + else if (k==n_k-2) + { + return {k-2, k-1, k, k+1, 0}; + } + else + { + return {k-2, k-1, k, k+1, k+2}; + } + } + }; + + template + class Neigh_2d + { + public: + using value_type = T; + using size_type = dt_uint64; + + Neigh_2d() {}; + + template + Neigh_2d(Stream& stream, TVctr& x_i, TVctr& y_i, Value_type r_neigh_i) + { + operator()(stream, x_i, y_i, r_neigh_i); + } + + size_type size() const {return neigh.size(); }; + + Vctr_std& operator[](const dt_int32 i){ return neigh[i]; } + + const Vctr_std& operator[](const dt_int32 i) const { return neigh[i]; } + + template + void operator()(Stream& stream, TVctr& x_i, TVctr& y_i, Value_type r_neigh_i) + { + const dt_int32 n_neigh = 16; + r_neigh = r_neigh_i; + + T bs_x; + x = sft_vector(x_i, bs_x); + dt_int32 nx = static_cast(::ceil(bs_x/r_neigh)); + + T bs_y; + y = sft_vector(y_i, bs_y); + dt_int32 ny = static_cast(::ceil(bs_y/r_neigh)); + + // reserve memory + Vctr_std> neigh_grid(nx*ny); + for(auto i=0; i(::floor(x[i]/r_neigh)); + dt_int32 iy = static_cast(::floor(y[i]/r_neigh)); + neigh_grid[ix*ny+iy].push_back(i); + }; + + auto get_neighbors_sort = [&](T x_i, T y_i, T radius)->Vctr_std + { + Vctr_std vd_neigh; + vd_neigh.reserve(n_neigh); + + Vctr_std r2d_neigh; + r2d_neigh.reserve(n_neigh); + + T radius2 = radius*radius; + + dt_int32 ix_i = static_cast(::floor(x_i/r_neigh)); + dt_int32 iy_i = static_cast(::floor(y_i/r_neigh)); + dt_int32 ix_0 = max(0, ix_i-1); + dt_int32 ix_e = min(nx, ix_i+2); + dt_int32 iy_0 = max(0, iy_i-1); + dt_int32 iy_e = min(ny, iy_i+2); + + for(auto ix=ix_0; ix& v = neigh_grid[ix*ny+iy]; + for(auto iv=0; iv1) + { + auto first = thrust::make_zip_iterator(thrust::make_tuple(r2d_neigh.begin(), vd_neigh.begin())); + auto last = thrust::make_zip_iterator(thrust::make_tuple(r2d_neigh.end(), vd_neigh.end())); + thrust::sort(first, last); + } + + vd_neigh.shrink_to_fit(); + return vd_neigh; + }; + + // get neighbors + neigh.resize(x.size()); + + auto thr_neighbors_sort = [&](const iThread_Rect_2d& range) + { + for(auto i=range.ind_0; i1) + { + dt_int32 idx = neigh[i][1]; + auto rx = x[idx]-x[i]; + auto ry = y[idx]-y[i]; + r_min += sqrt(rx*rx+ry*ry); + cr_min++; + } + } + r_min /= cr_min; + + T r_neigh_n = ::fmax(2*r_min, 1.25*r_neigh); + // correct outliers + for(auto i=0; id_max(i)) + // { + // neigh[i] = get_neighbors_sort(x[i], y[i], r_neigh_n); + // } + // } + // }; + + // stream.set_n_stream_act(x.size()); + // stream.set_grid(x.size(), 1); + // stream.exec(thr_neighbors_sort_n); + } + + template + void delete_points(TVctr& x_i, TVctr& y_i, TGrid& grid_i) + { + const dt_int32 n_neigh = 16; + T r_neigh = 1.6*grid_i.dR_min(); + + T bs_x; + x = sft_vector(x_i, bs_x); + dt_int32 nx = static_cast(::ceil(bs_x/r_neigh)); + + T bs_y; + y = sft_vector(y_i, bs_y); + dt_int32 ny = static_cast(::ceil(bs_y/r_neigh)); + + // reserve memory + Vctr_std> neigh_grid(nx*ny); + for(auto i=0; i(::floor(x[i]/r_neigh)); + dt_int32 iy = static_cast(::floor(y[i]/r_neigh)); + neigh_grid[ix*ny+iy].push_back(i); + }; + + auto get_neighbors = [&](T x_i, T y_i, T radius)->Vctr_std + { + Vctr_std vd_neigh; + vd_neigh.reserve(n_neigh); + + T radius2 = radius*radius; + + dt_int32 ix_i = static_cast(::floor(x_i/r_neigh)); + dt_int32 iy_i = static_cast(::floor(y_i/r_neigh)); + dt_int32 ix_0 = max(0, ix_i-1); + dt_int32 ix_e = min(nx, ix_i+2); + dt_int32 iy_0 = max(0, iy_i-1); + dt_int32 iy_e = min(ny, iy_i+2); + + for(auto ix=ix_0; ix& v = neigh_grid[ix*ny+iy]; + for(auto iv=0; iv bb(x.size(), true); + + TVctr x_o; + x_o.reserve(x.size()); + + TVctr y_o; + y_o.reserve(y.size()); + + for(auto i=0; i1) + { + rx = 0; + ry = 0; + for(auto j=0; j0) + { + bb[idx] = false; + } + } + rx /= neigh.size(); + ry /= neigh.size(); + } + x_o.push_back(rx); + y_o.push_back(ry); + } + } + x_i = x_o; + y_i = y_o; + } + + dt_int32 size(const dt_int32& idx) + { + if (idx>=neigh.size()) + { + return 1; + } + + return neigh[idx].size(); + } + + T d_min(const dt_int32& idx) + { + T d = r_neigh; + if (idx>=neigh.size()) + { + return d; + } + + if (neigh[idx].size()>1) + { + dt_int32 i = neigh[idx][1]; + auto rx = x[i]-x[idx]; + auto ry = y[i]-y[idx]; + d = sqrt(rx*rx+ry*ry); + } + return d; + } + + T d_max(const dt_int32& idx) + { + T d = r_neigh; + if (idx>=neigh.size()) + { + return d; + } + + if (neigh[idx].size()>1) + { + dt_int32 i = neigh[idx].back(); + auto rx = x[i]-x[idx]; + auto ry = y[i]-y[idx]; + d = sqrt(rx*rx+ry*ry); + } + return d; + } + + template + T radius_min(const dt_int32& idx, TGrid& grid_2d, TVctr& Im) + { + T r_min = 2.0*grid_2d.dR_min(); + if (idx>=neigh.size()) + { + return r_min; + } + + auto interp2 = [](const R_2d& p, TGrid& grid_2d, TVctr& Im)->T + { + auto ix = grid_2d.rx_2_irx_bfds(p.x); + auto iy = grid_2d.ry_2_iry_bfds(p.y); + + T f11 = Im[grid_2d.sub_2_ind(ix, iy)]; + T f12 = Im[grid_2d.sub_2_ind(ix, iy+1)]; + T f21 = Im[grid_2d.sub_2_ind(ix+1, iy)]; + T f22 = Im[grid_2d.sub_2_ind(ix+1, iy+1)]; + + T x1 = grid_2d.rx(ix); + T x2 = grid_2d.rx(ix+1); + T y1 = grid_2d.ry(iy); + T y2 = grid_2d.ry(iy+1); + + T dx1 = p.x-x1; + T dx2 = x2-p.x; + T dy1 = p.y-y1; + T dy2 = y2-p.y; + + T f = (dx2*(f11*dy2 + f12*dy1)+dx1*(f21*dy2 + f22*dy1))/((x2-x1)*(y2-y1)); + return f; + + }; + + if (neigh[idx].size()>1) + { + dt_int32 i = neigh[idx][1]; + R_2d p1(x[idx], y[idx]); + R_2d p2(x[i], y[i]); + R_2d p12 = R_2d(x[i], y[i])-p1; + auto u = normalize(p12); + + T r = p12.norm(); + T dr = 0.75*grid_2d.dR_min(); + dt_int32 nr = static_cast(::ceil(r/dr+0.5)); + dr = r/nr; + + T f_min = Im[grid_2d.rv_2_ir_bfds(p1.x, p1.y)]; + for(auto ir=1; irf) + { + f_min = f; + r_min = d; + } + } + r_min = ::fmax(r_min, 0.5*r); + } + return r_min; + } + + template + TVctr radius_min(Stream& stream, TGrid& grid_2d, TVctr& Im) + { + TVctr radius(x.size()); + + auto thr_radius_min = [&](const iThread_Rect_2d& range) + { + for(auto idx=range.ind_0; idx + TVctr select(const dt_int32& idx, TVctr& x, Value_type x_sf=0, Value_type x_sc=1) + { + TVctr v; + if (idx>=neigh.size()) + { + return v; + } + + Vctr_std& neigh_i = neigh[idx]; + v.reserve(neigh_i.size()); + + for(const auto &in:neigh_i) + { + v.push_back((x[in]-x_sf)/x_sc); + } + return v; + } + + //template + //Ptc_gauss_2d> select(const dt_int32& idx, TVctr& a, TVctr& sigma, TVctr& x, TVctr& y) + //{ + // Ptc_gauss_2d> atom; + // if (idx>=neigh.size()) + // { + // return atom; + // } + + // Vctr_std& neigh_i = neigh[idx]; + // atom.reserve(neigh_i.size()); + + // for(const auto &in:neigh_i) + // { + // atom.push_back(x[in], y[in], a[in], sigma[in]); + // } + // return atom; + //} + + template + T min_val(const dt_int32& idx, TVctr& x) + { + T x_min = 0; + if (idx>=neigh.size()) + { + return x_min; + } + + Vctr_std& neigh_i = neigh[idx]; + + x_min = neigh_i[0]; + for(const auto &in:neigh_i) + { + x_min = ::fmin(x_min, x[in]); + } + + return x_min; + } + + template + T mean_val(const dt_int32& idx, TVctr& x) + { + T x_mean = 0; + if (idx>=neigh.size()) + { + return x_mean; + } + + Vctr_std& neigh_i = neigh[idx]; + + for(const auto &in:neigh_i) + { + x_mean += x[in]; + } + x_mean /= neigh_i.size(); + + return x_mean; + } + private: + Vctr_std x; + Vctr_std y; + Vctr_std> neigh; + T r_neigh; + + template + Vctr_std sft_vector(TVctr& x_i, T& l_m) + { + T d_e = 1e-03; + auto x_minmax = fcn_minmax_element(x_i.begin(), x_i.end()); + T x_min = *(x_minmax.first)-d_e; + l_m = (*(x_minmax.second)+d_e-x_min); + + Vctr_std x; + x.reserve(x_i.size()); + + for(auto i=0; i + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CB_SPL_INTRPL_H + #define CB_SPL_INTRPL_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + + #include "type_traits_gen.cuh" + #include "intrpl_coef.cuh" + + namespace mt + { + // Cubic spline interpolation + template + class Cb_spl_Intrpl + { + public: + Cb_spl_Intrpl(){} + + Cb_spl_Intrpl(const pVctr_cpu_64& x, const pVctr_cpu_64& y) + { + set_points(x, y); + } + + void set_points(const pVctr_cpu_64& x, const pVctr_cpu_64& y) + { + dt_int32 n = static_cast(x.size()); + + m_x.assign(x.begin(), x.end()); + m_c0.assign(y.begin(), y.end()); + m_c1.resize(n); + m_c2.resize(n); + m_c3.resize(n); + + Vctr m_h(n); + Vctr cl(n); + Vctr m_mu(n); + Vctr m_z(n); + + n--; + + for(auto ik = 0; ik < n; ik++) + { + m_h[ik] = m_x[ik+1]-m_x[ik]; + } + + cl[0] = 1; + m_mu[0] = 0; + m_z[0] = 0; + + for(auto ik = 1; ik < n; ik++) + { + cl[ik] = T(2)*(m_x[ik+1]-m_x[ik-1])-m_h[ik-1]*m_mu[ik-1]; + m_mu[ik] = m_h[ik]/cl[ik]; + const auto alpha = T(3)*(m_c0[ik+1]-m_c0[ik])/m_h[ik]-T(3)*(m_c0[ik]-m_c0[ik-1])/m_h[ik-1]; + m_z[ik] = (alpha-m_h[ik-1]*m_z[ik-1])/cl[ik]; + } + + cl[n] = 1; + m_z[n] = 0; + m_c2[n] = 0; + + for(auto ik =n-1; ik >= 0; ik--) + { + m_c2[ik] = m_z[ik] - m_mu[ik]*m_c2[ik+1]; + m_c1[ik] = (m_c0[ik+1]-m_c0[ik])/m_h[ik]-m_h[ik]*(m_c2[ik+1]+2*m_c2[ik])/3; + m_c3[ik] = (m_c2[ik+1]-m_c2[ik])/(T(3)*m_h[ik]); + } + } + + T operator() (T x) const + { + // find the closest point m_x[idx] < m_x, idx = 0 even if m_x& x, pVctr_cpu_64& y) + { + for(auto ik = 0; ikoperator()(x[ik]); + } + } + + void get_coef_poly3(Poly_Coef_3d& ci_coef) + { + ci_coef.c0.assign(m_c0.begin(), m_c0.end()); + ci_coef.c1.assign(m_c1.begin(), m_c1.end()); + ci_coef.c2.assign(m_c2.begin(), m_c2.end()); + ci_coef.c3.assign(m_c3.begin(), m_c3.end()); + } + + template + void eval_radial_function(const TGrid& grid_2d, Value_type x, Value_type y, TVctr& V) + { + using X = Value_type; + + X r_max = x_max(); + X fr_max = (*this)(r_max); + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + X r = grid_2d.r2(ix, iy, x, y); + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + V[ixy] = (r < r_max)?(*this)(r):fr_max; + } + } + } + + T x_min() const + { + return m_x.front(); + } + + T x_max() const + { + return m_x.back(); + } + + private: + // interpolation parameters + // f(x) = c3*(x-x_i)^3 + c2*(x-x_i)^2 + c1*(x-x_i) + c0 + Vctr m_x; + Vctr m_c0; + Vctr m_c1; + Vctr m_c2; + Vctr m_c3; + }; + } + +#endif diff --git a/src - Copy (2)/cgpu_classes.cuh b/src - Copy (2)/cgpu_classes.cuh new file mode 100755 index 00000000..9b7e3cc9 --- /dev/null +++ b/src - Copy (2)/cgpu_classes.cuh @@ -0,0 +1,4130 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_CLASSES_H + #define CGPU_CLASSES_H + + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + //#include "eval_fit_gaussians.hpp" + #include "cgpu_rand.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + #include "in_classes.cuh" + #include "cgpu_fcns.cuh" + #include "cpu_fcns.hpp" + #include "particles.cuh" + + #ifdef __CUDACC__ + #include "gpu_fcns.cuh" + #endif + + namespace mt + { + /********************************* Gaussian Conv ***************************************/ + template + class Gauss_Cv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Cv_1d():fft_1d(nullptr) {} + + Gauss_Cv_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, TVctr_c& Im) + { + fcn_fftsft_1d(grid_1d, Im); + fft_1d->forward(Im); + + gauss_cv_1d(sigma_r, Im); + + fft_1d->inverse(Im); + fcn_fftsft_1d(grid_1d, Im); + } + + void operator()(T sigma_r, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_1d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + cgpu_detail::gauss_cv_1d, TVctr_c>(ix, grid_1d, alpha, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_1d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_1d.d_grid_blk(); + gpu_detail::gauss_cv_1d, typename TVctr_c::value_type><<>>(grid_1d, alpha, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Cv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Cv_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Cv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVctr_c& Im) + { + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, Im); + + fft_2d->inverse(Im); + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vctr gauss_vector_1d(T alpha) + { + TVctr_r fg; + fg.reserve(grid_2d.ny); + + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_sft(iy))/grid_2d.ny_r(); + fg.push_back(v); + } + return fg; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_2d_bc(T sigma_r, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_ew_mult_mx_vctr_col, TVctr_r, TVctr_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_2d_bc(T sigma_r, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha); + TVctr_r fg = fg_h; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_ew_mult_mx_vctr_col, typename TVctr_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Cv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Cv_2d():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Cv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVctr_c& Im) + { + if (fcn_is_zero(sigma_r)) + { + return; + } + + fcn_fftsft_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d(sigma_r, Im); + + fft_2d->inverse(Im); + fcn_fftsft_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVctr_r &Im) + { + if (fcn_is_zero(sigma_r)) + { + return; + } + + Im_c.assign(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_2d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::gauss_cv_2d, TVctr_c>, grid_2d, alpha, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_2d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::gauss_cv_2d, typename TVctr_c::value_type><<>>(grid_2d, alpha, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + + TVctr_c Im_c; + }; + + /********************************* Gaussian Deconv *************************************/ + template + class Gauss_Dcv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Dcv_1d():fft_1d(nullptr) {} + + Gauss_Dcv_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, T PSNR, TVctr_c& Im) + { + fcn_fftsft_1d(grid_1d, Im); + fft_1d->forward(Im); + + gauss_dcv_1d(sigma_r, PSNR, Im); + + fft_1d->inverse(Im); + fcn_fftsft_1d(grid_1d, Im); + } + + void operator()(T sigma_r, T PSNR, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_dcv_1d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + cgpu_detail::gauss_dcv_1d, TVctr_c>(ix, grid_1d, alpha, PSNR, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_dcv_1d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_1d.d_grid_blk(); + gpu_detail::gauss_dcv_1d, typename TVctr_c::value_type><<>>(grid_1d, alpha, PSNR, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Dcv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Dcv_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Dcv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVctr_c& Im) + { + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vctr gauss_vector_1d(T alpha, T PSNR) + { + TVctr_r fg; + fg.reserve(grid_2d.ny); + + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_sft(iy)); + fg.push_back(v/((v*v+PSNR)*grid_2d.ny_r())); + } + return fg; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_2d_bc(T sigma_r, T PSNR, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha, PSNR); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_ew_mult_mx_vctr_col, TVctr_r, TVctr_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_2d_bc(T sigma_r, T PSNR, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha, PSNR); + TVctr_r fg = fg_h; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_ew_mult_mx_vctr_col, typename TVctr_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Dcv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Dcv_2d():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Dcv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVctr_c& Im) + { + fcn_fftsft_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_dcv_2d(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fcn_fftsft_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_dcv_2d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::gauss_dcv_2d, TVctr_c>, grid_2d, alpha, PSNR, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_dcv_2d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::gauss_dcv_2d, typename TVctr_c::value_type><<>>(grid_2d, alpha, PSNR, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /******************************* affine transformations ********************************/ + template + class Sd_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Sd_2d(): stream(nullptr) {} + + Sd_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + bg_opt = bg_opt_i; + bg = bg_i; + } + + void generate_dx_dy(T ds_x, T phi_x, T ds_y, T phi_y, dt_int32 seed, TVctr& dx_o, TVctr& dy_o) + { + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + gen.seed(seed); + rand_n.reset(); + + dx_o = generate_ds(ds_x, phi_x); + dy_o = generate_ds(ds_y, phi_y); + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& dx, TVctr& dy, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::sd_2d, TVctr>, grid_2d, mx_i, dx, dy, bg, mx_o); + + return bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& dx, TVctr& dy, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::sd_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, dx, dy, bg, mx_o); + + return bg; + } + #endif + + protected: + std::mt19937_64 gen; + std::normal_distribution rand_n; + + Grid_2d grid_2d; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + Vctr generate_ds(T ds, T phi) + { + Vctr ds_v; + ds_v.reserve(grid_2d.ny); + + T a = ds*rand_n(gen); + ds_v.push_back(a/::sqrt(1.0-phi*phi)); + for(auto iy = 1; iy < grid_2d.ny; iy++) + { + T a = ds*rand_n(gen); + ds_v.push_back(phi*ds_v.back() + a); + } + return ds_v; + } + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + template + class Sd_nr_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Sd_nr_2d(): stream(nullptr) {} + + Sd_nr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + bg_opt = bg_opt_i; + bg = bg_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, TVctr& mx_o) + { + preprocessing(mx_i, ds_x_i, ds_y_i, parm); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::sd_nr_2d, TVctr, SPar>, grid_2d, mx_i, parm, mx_o); + + return parm.bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, TVctr& mx_o) + { + // preprocessing(ds_x_i, ds_y_i, parm); + // auto d_grid_blk = grid_2d.d_grid_blk(); + // gpu_detail::sd_nr_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, ds_x_i, ds_y_i, mx_o); + + return parm.bg; + } + + #endif + + protected: + struct SPar + { + eFil_Sel_Typ bg_opt; + T bg; + TVctr dx; + TVctr dy; + TVctr ry_s; + Vctr iy; + } parm; + + struct sort_by_first + { + template + CGPU_EXEC + dt_bool operator()(const Ttuple1 &t1, const Ttuple2 &t2) + { + return thrust::get<0>(t1) < thrust::get<0>(t2); + } + }; + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, SPar &parm) + { + // calculate background + parm.bg_opt = bg_opt; + parm.bg = get_bg(mx_i); + + parm.dx = ds_x_i; + parm.dy = ds_y_i; + parm.ry_s.resize(parm.dy.size()); + parm.iy.resize(parm.dy.size()); + + for(auto ik = 0; ik < parm.dy.size(); ik++) + { + parm.ry_s[ik] = grid_2d.ry(ik) + parm.dy[ik]; + parm.iy[ik] = ik; + } + + auto first = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.begin(), parm.iy.begin())); + auto last = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.end(), parm.iy.end())); + + thrust::sort(first, last, sort_by_first()); + } + + /**********************Device**********************/ + // not working yet + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, SPar &parm) + { + // calculate background + parm.bg_opt = bg_opt; + parm.bg = get_bg(mx_i); + + parm.dx = ds_x_i; + parm.dy = ds_y_i; + parm.ry_s.resize(parm.dy.size()); + parm.iy.resize(parm.dy.size()); + + for(auto ik = 0; ik < parm.dy.size(); ik++) + { + parm.ry_s[ik] = grid_2d.ry(ik) + parm.dy[ik]; + parm.iy[ik] = ik; + } + + auto first = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.begin(), parm.iy.begin())); + auto last = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.end(), parm.iy.end())); + + thrust::sort(first, last, sort_by_first()); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + template + class Data_Aug_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Data_Aug_2d():stream(nullptr) {} + + Data_Aug_2d(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, T theta, R_2d p0, T sx, T sy, R_2d ps, T sim, + dt_int32 nx_o, dt_int32 ny_o, TVctr& mx_o) + { + // calculate maximum + auto M_max = *thrust::max_element(mx_i.begin(), mx_i.end()); + + // calculate background + auto g_max = grid_2d.gx_back(); + auto g_min = 0.9*g_max; + // T bg = fcn_int_det_ring(*stream, grid_2d, g_min, g_max, mx_i); + + T bg = 0.6*fcn_mean(*stream, mx_i); + + T rx_0 = p0.x*sx-(nx_o/2)*grid_2d.drx; + T ry_0 = p0.y*sy-(ny_o/2)*grid_2d.dry; + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + grid_2d_o.set_r_0(rx_0, ry_0); + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::rot_sca_sft_2d, TVctr>, grid_2d, mx_i, theta, p0, sx, sy, ps, bg, grid_2d_o, mx_o); + + normalized_data(mx_o, M_max); + + // add Poisson noise + mx_o = fcn_add_poiss_nois(*stream, mx_o, sim, -1); + + M_max = *thrust::max_element(mx_o.begin(), mx_o.end()); + normalized_data(mx_o, M_max); + } + + protected: + void normalized_data(TVctr& M, T M_max) + { + std::for_each(M.begin(), M.end(), [M_max](T& v){ v = (v>0)?v/M_max:0; }); + } + + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Interp_rn_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Interp_rn_2d(): stream(nullptr) {} + + Interp_rn_2d(Stream *stream_i, Grid_2d& grid_2d_i, Grid_2d& grid_2d_o, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, grid_2d_o, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, Grid_2d& grid_2d_o, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + grid_2d_mo = grid_2d_o; + bg_opt = bg_opt_i; + bg = bg_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& Rx_i, TVctr& Ry_i, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + stream->set_n_stream_act(grid_2d_mo.nx); + stream->set_grid(grid_2d_mo.nx, grid_2d_mo.ny); + stream->exec_2d(cgpu_detail::intrpl_rg_2d, TVctr>, grid_2d, mx_i, Rx_i, Ry_i, grid_2d_mo, bg, mx_o); + + return bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& Rx_i, TVctr& Ry_i, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + auto d_grid_blk = grid_2d_mo.d_grid_blk(); + gpu_detail::intrpl_rg_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, Rx_i, Ry_i, grid_2d_mo, bg, mx_o); + + return bg; + } + #endif + + protected: + Grid_2d grid_2d; + Grid_2d grid_2d_mo; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + template + class Rs_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Rs_2d(): stream(nullptr) {} + + Rs_2d(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, T sxy, TVctr& mx_o) + { + if (fcn_is_equal(sxy, T(1))) + { + mx_o = mx_i; + } + + dt_int32 nx_o = fcn_sc_size_c(grid_2d.nx, sxy); + dt_int32 ny_o = fcn_sc_size_c(grid_2d.ny, sxy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::sc_2d, TVctr>, grid_2d, mx_i, sxy, grid_2d_o, mx_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, T sxy, TVctr& mx_o) + { + if (fcn_is_equal(sxy, T(1))) + { + mx_o = mx_i; + } + + dt_int32 nx_o = max(dt_int32(::floor(grid_2d.nx*sxy)), 1); + dt_int32 ny_o = max(dt_int32(::floor(grid_2d.ny*sxy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + auto d_grid_blk = grid_2d_o.d_grid_blk(); + gpu_detail::sc_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, sxy, grid_2d_o, mx_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Rot_Sca_sft_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Rot_Sca_sft_2d():stream(nullptr) {} + + Rot_Sca_sft_2d(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, T theta, R_2d p0, T sx, T sy, R_2d ps, TVctr& mx_o) + { + // calculate background + T bg = fcn_mean(*stream, mx_i); + + dt_int32 nx_o = fcn_sc_size_c(grid_2d.nx, sx); + dt_int32 ny_o = fcn_sc_size_c(grid_2d.ny, sy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::rot_sca_sft_2d, TVctr>, grid_2d, mx_i, theta, p0, sx, sy, ps, bg, grid_2d_o, mx_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, T theta, R_2d p0, T sx, T sy, R_2d ps, TVctr& mx_o) + { + // calculate background + T bg = fcn_mean(*stream, mx_i); + + dt_int32 nx_o = max(dt_int32(::floor(grid_2d.nx*sx)), 1); + dt_int32 ny_o = max(dt_int32(::floor(grid_2d.ny*sy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + auto d_grid_blk = grid_2d_o.d_grid_blk(); + gpu_detail::rot_sca_sft_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, theta, p0, sx, sy, ps, bg, grid_2d_o, mx_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + /************************************ Gradient ******************************************/ + template + class Gradient + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Gradient(): stream(nullptr) {} + + Gradient(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& dM_x, TVctr& dM_y) + { + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::gradient, TVctr>, grid_2d, mx_i, dM_x, dM_y); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& dM_x, TVctr& dM_y) + { + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::gradient, typename TVctr::value_type><<>>(grid_2d, mx_i, dM_x, dM_y); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + /***************************** 2d affine transformation *********************************/ + template + class AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + AT_2d(): stream(nullptr) {} + + AT_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + bg_opt = bg_opt_i; + bg = bg_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, Mx_2x2 A, R_2d txy, TVctr& mx_o) + { + if (fcn_is_zero(txy) && is_I2x2(A)) + { + mx_o = mx_i; + } + + // calculate background + T bg = get_bg(mx_i); + + A = inv(A); + txy = T(-1)*A*txy; + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::at_2d, TVctr>, grid_2d, mx_i, A, txy, bg, mx_o); + + return bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, Mx_2x2 A, R_2d txy, TVctr& mx_o) + { + if (fcn_is_zero(txy) && is_I2x2(A)) + { + mx_o = mx_i; + } + + // calculate background + T bg = get_bg(mx_i); + + A = inv(A); + txy = T(-1)*A*txy; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::at_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, A, txy, bg, mx_o); + + return bg; + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + /************************************ translation **************************************/ + template + class Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_2d(): AT_2d() {} + + Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = 1.0; + A(2, 1) = 0; + A(1, 2) = 0; + A(2, 2) = 1.0; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + + }; + + /***************************************************************************************/ + template + class Rot_Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Rot_Tr_2d(): AT_2d() {} + + Rot_Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T theta, R_2d pr, R_2d txy, TVctr& mx_o) + { + auto A = fcn_rot_mx_2d(theta); + txy = pr - A*(pr-txy); + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + template + class Tr_Rot_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_Rot_2d(): AT_2d() {} + + Tr_Rot_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T theta, R_2d pr, R_2d txy, TVctr& mx_o) + { + auto A = fcn_rot_mx_2d(theta); + txy = pr - A*pr + txy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + /************************************** scy_shx_tr *************************************/ + template + class Scy_Shx_Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Scy_Shx_Tr_2d(): AT_2d() {} + + Scy_Shx_Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T shx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = 1; + A(2, 1) = 0; + A(1, 2) = shx; + A(2, 2) = scy; + + txy = A*txy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + template + class Tr_Scy_Shx_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_Scy_Shx_2d(): AT_2d() {} + + Tr_Scy_Shx_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T shx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = 1; + A(2, 1) = 0; + A(1, 2) = shx; + A(2, 2) = scy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + /************************************ scy_scx_tr ***************************************/ + template + class Scy_Scx_Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Scy_Scx_Tr_2d(): AT_2d() {} + + Scy_Scx_Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T scx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = scx; + A(2, 1) = 0; + A(1, 2) = 0; + A(2, 2) = scy; + + txy = A*txy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + template + class Tr_Scy_Scx_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_Scy_Scx_2d(): AT_2d() {} + + Tr_Scy_Scx_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T scx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = scx; + A(2, 1) = 0; + A(1, 2) = 0; + A(2, 2) = scy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + /************************************* shift *******************************************/ + template + class Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Sft_1d():fft_1d(nullptr) {} + + Sft_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx); + } + + void operator()(T xs, TVctr_c& Im) + { + fcn_fftsft_1d(grid_1d, Im); + fft_1d->forward(Im); + fcn_exp_g_factor_1d(grid_1d, -c_2pi*xs, Im, Im); + fft_1d->inverse(Im); + fcn_fftsft_1d(grid_1d, Im); + } + + void operator()(T xs, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + T Im_min = fcn_min_element(Im); + + this->operator()(xs, Im_c); + fcn_assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_1d->cleanup(); + } + + protected: + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Sft_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T alpha, TVctr_r ys, TVctr_c& Im) + { + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + fcn_exp_g_factor_2d_bc(*stream, grid_2d, -c_2pi*alpha, ys, Im, Im); + fft_2d->inverse(Im); + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + } + + void operator()(T alpha, TVctr_r ys, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + T Im_min = fcn_min_element(Im); + + this->operator()(alpha, ys, Im_c); + fcn_assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Sft_2d():stream(nullptr), fft_2d(nullptr) {} + + Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(R_2d p, TVctr_c& Im) + { + fcn_fftsft_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + fcn_exp_g_factor_2d(*stream, grid_2d, T(-c_2pi)*p, Im, Im); + fft_2d->inverse(Im); + fcn_fftsft_2d(*stream, grid_2d, Im); + } + + void operator()(R_2d p, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + T Im_min = fcn_min_element(Im); + + this->operator()(p, Im_c); + fcn_assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /******************************** phase correlation ************************************/ + template + class Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Pcf_1d(): fft_1d(nullptr) {} + + Pcf_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + + PN_Fact pn; + + dt_int32 nx = pn(2*grid_1d.nx-1, edst_greater_than); + + grid_1d_e.set_in_data(nx, grid_1d.drx*nx); + + M_r_c.resize(grid_1d_e.nx); + M_s_c.resize(grid_1d_e.nx); + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + fft_1d_e.create_plan_1d(grid_1d_e.nx, 1); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_1d bd, dt_bool b_pv, TVctr_r& mx_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVctr_c& pcf = M_s_c; + + // shift matrix + fcn_fftsft_1d(grid_1d_e, M_r_c); + fcn_fftsft_1d(grid_1d_e, M_s_c); + + // fft_1d_e + fft_1d_e.forward(M_r_c); + fft_1d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + + fft_1d_e.inverse(pcf); + + // shift pcf + fcn_fftsft_1d(grid_1d_e, pcf); + + dt_int32 ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + this->fcn_assign_real(pcf, ix_s, mx_o, b_pv); + } + + void cleanup() + { + fft_1d->destroy_plan(); + fft_1d_e.cleanup(); + } + + protected: + + void fcn_assign_real(TVctr_c& mx_i, dt_int32 ix_s, TVctr_r& mx_o, dt_bool b_pos = false) + { + auto first = mx_i.begin() + ix_s; + auto last = first + grid_1d.nx; + + if (b_pos) + { + thrust::transform(first, last, mx_o.begin(), cgpu_fctr::assign_max_real(0)); + } + else + { + thrust::transform(first, last, mx_o.begin(), cgpu_fctr::assign_real()); + } + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Wd_Butwth_1d bw_1d(bd, bd.radius_p(p), 32); + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + cgpu_detail::fcn_rs_pcf_1d_dp(ix, ix_s, grid_1d, bw_1d, mx_i, mx_o); + } + } + + template + enable_if_edev_cpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_1d gs_1d(0, sigma_g); + + for(auto ix = 0; ix < grid_1d_e.nx; ix++) + { + cgpu_detail::fcn_fs_pcf_1d_dp(ix, grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + } + + /*************************************** device ****************************************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Wd_Butwth_1d bw_1d(bd, bd.radius_p(p), 32); + + auto d_grid_blk = grid_1d.d_grid_blk(); + gpu_detail::fcn_rs_pcf_1d_dp, typename TVctr_c::value_type><<>>(ix_s, grid_1d, bw_1d, mx_i, mx_o); + } + + template + enable_if_edev_gpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_1d gs_1d(0, sigma_g); + + auto d_grid_blk = grid_1d_e.d_grid_blk(); + gpu_detail::fcn_fs_pcf_1d_dp, typename TVctr_c::value_type><<>>(grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + #endif + + TVctr_c M_r_c; + TVctr_c M_s_c; + + FFT *fft_1d; + Grid_1d grid_1d; + + private: + FFT fft_1d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Pcf_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Pcf_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + grid_1d.set_in_data(grid_2d.ny, grid_2d.bs_y); + + PN_Fact pn; + + dt_int32 ny = pn(2*grid_2d.ny-1, edst_greater_than); + + grid_2d_e.set_in_data(grid_2d.nx, ny, grid_2d.bs_x, grid_2d.dry*ny); + grid_1d_e.set_in_data(grid_2d_e.ny, grid_2d_e.bs_y); + + M_r_c.resize(grid_2d_e.size()); + M_s_c.resize(grid_2d_e.size()); + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d_e.create_plan_1d_batch(grid_2d_e.ny, grid_2d_e.nx, stream->size()); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_1d bd, dt_bool b_pv, TVctr_r& mx_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVctr_c& pcf = M_s_c; + + // shift matrix + fcn_fftsft_bc_2d(*stream, grid_2d_e, M_r_c); + fcn_fftsft_bc_2d(*stream, grid_2d_e, M_s_c); + + // fft_2d + fft_2d_e.forward(M_r_c); + fft_2d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + fft_2d_e.inverse(pcf); + + // shift pcf + fcn_fftsft_bc_2d(*stream, grid_2d_e, pcf); + + dt_int32 iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + this->fcn_assign_real(pcf, iy_s, mx_o, b_pv); + } + + void cleanup() + { + fft_2d->destroy_plan(); + fft_2d_e.cleanup(); + } + + protected: + + TVctr_r gauss_vector_1d(Grid_1d& grid_1d, T sigma_g, dt_bool b_norm = false) + { + Wd_Gauss_1d gs_1d(0, sigma_g); + + TVctr_r fg; + fg.reserve(grid_1d.nx); + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + T g2 = grid_1d.g2_sft(ix); + T v = gs_1d(g2); + fg.push_back(v); + } + return fg; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh = fcn_wd_butwth_1d(grid_1d, bd.radius_p(p), 32, false, bd); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::pcf_2d_bc_pp, TVctr_r, TVctr_c>, iy_s, grid_2d, grid_2d_e, mx_i, fh, mx_o); + } + + template + enable_if_edev_cpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + auto fg = gauss_vector_1d(grid_1d_e, sigma_g); + + stream->set_n_stream_act(grid_2d_e.nx); + stream->set_grid(grid_2d_e.nx, grid_2d_e.ny); + stream->exec_2d(cgpu_detail::pcf_2d_bc_gaussian, TVctr_r, TVctr_c>, grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_edev_cpu + fcn_assign_real(TVctr_c& mx_i, dt_int32 iy_s, TVctr_r& mx_o, dt_bool b_pos = false) + { + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + dt_int32 ixy_i = grid_2d_e.sub_2_ind(ix, iy+iy_s); + dt_int32 ixy_o = grid_2d.sub_2_ind(ix, iy); + auto v = mx_i[ixy_i].real(); + mx_o[ixy_o] = (!b_pos || (v>0))?v:0; + } + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh_h = fcn_wd_butwth_1d>(grid_1d, bd.radius_p(p), 32, false, bd); + TVctr_r fh = fh_h; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::pcf_2d_bc_pp, typename TVctr_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, mx_i, fh, mx_o); + } + + template + enable_if_edev_gpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + auto fg_h = gauss_vector_1d(grid_1d_e, sigma_g); + TVctr_r fg = fg_h; + + auto d_grid_blk = grid_2d_e.d_grid_blk(); + gpu_detail::pcf_2d_bc_gaussian, typename TVctr_c::value_type><<>>(grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_edev_gpu + fcn_assign_real(TVctr_c& mx_i, dt_int32 iy_s, TVctr_r& mx_o, dt_bool b_pos = false) + { + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::pcf_2d_bc_assign_real, typename TVctr_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, mx_i, mx_o, b_pos); + } + #endif + + Vctr M_r_c; + Vctr M_s_c; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + Grid_1d grid_1d; + + private: + FFT fft_2d_e; + Grid_2d grid_2d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Pcf_2d():stream(nullptr), fft_2d(nullptr) {} + + Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + + af_tr.set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + + M_r_c.resize(grid_2d.size()); + M_s_c.resize(grid_2d.size()); + pcf_r.resize(grid_2d.size()); + + Fit_Ellipt_Gauss_2d.init_variables(grid_2d, 1.0); + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_2d bd, TVctr_r &pcf_o) + { + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + // shift matrix + fcn_fftsft_2d(*stream, grid_2d, M_r_c); + fcn_fftsft_2d(*stream, grid_2d, M_s_c); + + // fft_2d + fft_2d->forward(M_r_c); + fft_2d->forward(M_s_c); + + TVctr_c& pcf_c = M_s_c; + pcf_g(M_r_c, M_s_c, sigma_g, pcf_c); + fft_2d->inverse(pcf_c); + + // shift pcf + fcn_fftsft_2d(*stream, grid_2d, pcf_c); + + fcn_assign_real(pcf_c, pcf_o); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, Region _Rect_2d bd, TVctr_r &pcf_o) + { + auto &M_s_t = pcf_r; + af_tr(M_s, A, txy, M_s_t); + this->operator()(M_r, M_s_t, p, sigma_g, bd, pcf_o); + } + + T chi_2(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_2d bd) + { + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + // shift matrix + fcn_fftsft_2d(*stream, grid_2d, M_r_c); + fcn_fftsft_2d(*stream, grid_2d, M_s_c); + + // fft_2d + fft_2d->forward(M_r_c); + fft_2d->forward(M_s_c); + + TVctr_c& pcf_c = M_s_c; + pcf_g(M_r_c, M_s_c, sigma_g, pcf_c); + fft_2d->inverse(pcf_c); + + return mt::fcn_mean_abs_real(pcf_c); + } + + T chi_2(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, Region _Rect_2d bd) + { + auto &M_s_t = pcf_r; + af_tr(M_s, A, txy, M_s_t); + return this->chi_2(M_r, M_s_t, p, sigma_g, bd); + } + + T chi_2(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, Vctr& coef) + { + // pcf + this->operator()(M_r, M_s, A, txy, p, sigma_g, bd, this->pcf_r); + + // get coefficients + coef = fit_coef(this->pcf_r, txy, sigma_g, radius); + + return mt::fcn_mean_abs(this->pcf_r); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + + Vctr fit_coef(TVctr_r &pcf_r, R_2d txy, T sigma_g, T radius) + { + // get maximum position + R_2d r_c = Fit_Ellipt_Gauss_2d.fd_max_peak_pos(pcf_r); + + // fitting + T sigma_r = 1.0/(c_2pi*sigma_g); + auto coef = Fit_Ellipt_Gauss_2d.fit(pcf_r, r_c, sigma_r, radius); + coef[0] = txy.x + this->grid_2d.bs_x_h(); + coef[1] = txy.y + this->grid_2d.bs_y_h(); + + return coef; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_2d& bd, TVctr_c& mx_o) + { + Wd_Butwth_2d bw_2d(bd, bd.radius_p(p), 16); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_rs_pcf_2d_dp, TVctr_r, TVctr_c>, grid_2d, bw_2d, mx_i, mx_o); + } + + template + enable_if_edev_cpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_2d gs_2d(R_2d(), sigma_g); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_fs_pcf_2d_dp, TVctr_c>, grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_2d& bd, TVctr_c& mx_o) + { + Wd_Butwth_2d bw_2d(bd, bd.radius_p(p), 16); + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_rs_pcf_2d_dp, typename TVctr_c::value_type><<>>(grid_2d, bw_2d, mx_i, mx_o); + } + + template + enable_if_edev_gpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_2d gs_2d(R_2d(), sigma_g); + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_fs_pcf_2d_dp, typename TVctr_c::value_type><<< d_grid_blk.grid, d_grid_blk.blk >>>(grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + #endif + + Fit_Ellipt_Gauss_2d Fit_Ellipt_Gauss_2d; + + TVctr_c M_r_c; + TVctr_c M_s_c; + TVctr_r pcf_r; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + + AT_2d af_tr; + }; + + /*********************************** find shift ****************************************/ + template + class Fd_Sft_1d: public Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Sft_1d(): Pcf_1d() {} + + Fd_Sft_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i): Pcf_1d() + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + Pcf_1d::set_in_data(fft_1d_i, grid_1d_i); + sft_1d.set_in_data(fft_1d_i, grid_1d_i); + } + + T operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, T dx, + Region _Rect_1d bd, dt_int32 nit_pcf) + { + T sigma_r = 1.0/(c_2pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.drx, 0.9*sigma_r); + + TVctr_r M = M_s; + TVctr_r pcf(M.size()); + + if (fcn_is_nzero(dx)) + { + sft_1d(dx, M); + } + + for(auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); + + // get maximum position + T x_c = cgpu_detail::fd_max_peak_pos(this->grid_1d, pcf); + + if (it==nit_pcf-1) + { + x_c = fit_max_pos_1d(this->grid_1d, pcf, x_c, sigma_r, radius); + } + + T dx_t = -(x_c - this->grid_1d.bs_x_h()); + + if (it sft_1d; + }; + + template + class Fd_Sft_2d_BC: public Pcf_2d_BC + { + public: + using TB = std::pair; + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using TVctr_rh = Vctr; + using TVctr_ch = Vctr; + + Fd_Sft_2d_BC(): Pcf_2d_BC() {} + + Fd_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): Pcf_2d_BC() + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + Pcf_2d_BC::set_in_data(stream_i, fft_2d_i, grid_2d_i); + gauss_cv_2d_bc.set_in_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d_bc.set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + TVctr_rh operator()(TVctr_r &M_r_i, TVctr_r &M_s_i, T p, T sigma_g, TVctr_rh dx, + Region _Rect_2d bd_2d, dt_int32 nit_pcf) + { + T sigma_r = 1.0/(c_2pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.drx, 0.9*sigma_r); + Region _Rect_1d bd_1d(bd_2d.bs_y, bd_2d.yb_0, bd_2d.yb_e); + Peaks peaks(this->grid_1d, &bd_1d); + + TVctr_r M_r = M_r_i; + TVctr_r M_s = M_s_i; + TVctr_r pcf(M_r.size()); + + // Gaussian filter + gauss_cv_2d_bc(sigma_r, M_r); + gauss_cv_2d_bc(sigma_r, M_s); + + const dt_int32 ix_0 = this->grid_2d.rx_2_irx_cds(bd_2d.x_0()); + const dt_int32 ix_e = this->grid_2d.rx_2_irx_fds(bd_2d.x_e()); + + dt_bool dx_s = false; + for(auto ix = 0; ixgrid_1d.nx, T(0)); + + for(auto it=0; it::operator()(M_r, M_s, p, sigma_g, bd_1d, false, pcf); + + // get maximum distance + T d_max = (it==0)?peaks.get_d_max_0(ix_0, ix_e, pcf):peaks.get_d_max(ix_0, ix_e, dx_t); + d_max = ::fmax(sigma_r, d_max); + + for(auto ix=ix_0; ixgrid_1d.nx, pcf.begin()+(ix+1)*this->grid_1d.nx); + + auto py = peaks.find(ix, M_r, M_s, y, d_max); + if (it==nit_pcf-1) + { + py = fit_max_pos_1d(this->grid_1d, y, py, sigma_r, radius); + } + dx_t[ix] = -(py - this->grid_1d.bs_x_h()); + dx[ix] += dx_t[ix]; + } + + // shift by column + if (it gauss_cv_2d_bc; + Sft_2d_BC sft_2d_bc; + + private: + struct Peaks + { + public: + using TVctr_ih = Vctr; + + Peaks(): y_c(0), bd_1d(nullptr) {} + + Peaks(Grid_1d& grid_1d_i, Region _Rect_1d *bd_1d_i) + { + set_in_data(grid_1d_i, bd_1d_i); + } + + inline + void set_in_data(Grid_1d& grid_1d_i, Region _Rect_1d *bd_1d_i) + { + grid_1d = grid_1d_i; + bd_1d = bd_1d_i; + fft_1d.create_plan_1d(grid_1d.nx, 1); + sft_1d.set_in_data(&fft_1d, grid_1d); + + ix_pk.resize(grid_1d.nx); + x_pk.resize(grid_1d.nx); + y_pk.resize(grid_1d.nx); + } + + T get_d_max_0(dt_int32 ix_0, dt_int32 ix_e, TVctr_r &pcf) + { + T x_c = grid_1d.bs_x_h(); + TVctr_rh dx; + dx.reserve(grid_1d.nx); + + for(auto ix=ix_0; ixdx_max); }); + dx.resize(std::distance(dx.begin(), it)); + + T dx_std = ::sqrt(fcn_variance(dx)); + T d_max = fcn_max_element(dx) + 2*dx_std; + + return ::fmax(10*grid_1d.drx, d_max); + } + + T get_d_max(dt_int32 ix_0, dt_int32 ix_e, TVctr_rh &dx) + { + TVctr_rh dx_h(dx.begin()+ix_0, dx.begin()+ix_e); + return ::fmax(10*grid_1d.drx, 3*::sqrt(fcn_variance(dx_h))); + } + + T find(dt_int32 icol, TVctr_r &M_r, TVctr_r &M_s, TVctr_rh &y, T d_max) + { + const T x_c = grid_1d.bs_x_h(); + y_c = y[grid_1d.nx_h]; + + // find peaks + fd_peaks(y); + + // remove peaks + remove_peaks(x_c-d_max, x_c+d_max); + + // return if x_pk is empty + if (empty()) + { + return x_c; + } + + // return if there is only one element + if (size() == 1) + { + return x_pk.front(); + } + + const dt_int32 ix_max = idx_y_max(); + const dt_int32 ix_clt = idx_x_clt(); + + // return if closest position is equal to maximum intensity position + // and the maximum intensity is greater than the second maximum intensity + if (fabs(x_pk[ix_max]-x_pk[ix_clt])<1) + { + T y_thr = 0.61*y_pk[ix_max]; + for(auto ix = 0; ix grid_1d; + Region _Rect_1d *bd_1d; + + FFT fft_1d; + Sft_1d sft_1d; + + T y_c; + + dt_bool empty() const + { + return ix_pk.empty(); + } + + dt_int32 size() const + { + return ix_pk.size(); + } + + dt_int32 idx_y_max() const + { + dt_int32 idx_max = (std::max_element(y_pk.begin(), y_pk.end())-y_pk.begin()); + + return idx_max; + } + + dt_int32 idx_x_clt() const + { + T x_c = grid_1d.bs_x_h(); + + dt_int32 idx_clt = 0; + if (x_pk.size()>1) + { + idx_clt = std::min_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)1) + { + idx_clt = std::max_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)y_thr) + { + if ((y[ix-1] bd_l = *bd_1d; + bd_l.xb_0 = max(bd_l.xb_0, d_fht); + bd_l.xb_e = max(bd_l.xb_e, d_fht); + + // get indexes + const dt_int32 ix_0 = grid_1d.rx_2_irx_cds(bd_l.x_0()); + const dt_int32 ix_e = grid_1d.rx_2_irx_fds(bd_l.x_e()); + + // get reference data + TVctr_rh yr_b(M_r.begin()+(icol-1)*grid_1d.nx, M_r.begin()+icol*grid_1d.nx); + TVctr_rh yr(M_r.begin()+icol*grid_1d.nx, M_r.begin()+(icol+1)*grid_1d.nx); + TVctr_rh yr_n(M_r.begin()+(icol+1)*grid_1d.nx, M_r.begin()+(icol+2)*grid_1d.nx); + + // get shifted data + TVctr_rh ys_0(M_s.begin()+icol*grid_1d.nx, M_s.begin()+(icol+1)*grid_1d.nx); + + TVctr_rh chi2_pk(size()); + + for(auto ix_pk=0; ix_pk + class Fd_Sft_2d: public Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Sft_2d(): Pcf_2d() {} + + Fd_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): Pcf_2d() + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + Pcf_2d::set_in_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d.set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + R_2d operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, R_2d dr, + Region _Rect_2d bd, dt_int32 nit_pcf) + { + T sigma_r = 1.0/(c_2pi*sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 0.9*sigma_r); + + TVctr_r M = M_s; + TVctr_r pcf(M.size()); + + if (fcn_is_nzero(dr)) + { + sft_2d(dr, M); + } + + for(auto it=0; it::operator()(M_r, M, p, sigma_g, bd, pcf); + + // get maximum position + R_2d r_c = this->Fit_Ellipt_Gauss_2d.fd_max_peak_pos(pcf); + + if (it==nit_pcf-1) + { + r_c = this->Fit_Ellipt_Gauss_2d.fit_peak_pos(pcf, r_c, sigma_r, radius); + } + + R_2d dr_t = -(r_c - this->grid_2d.bs_h()); + + if (it sft_2d; + }; + + template + class Fd_Tr_2d: public Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Tr_2d(): Pcf_2d(), b_fit(true) {} + + Fd_Tr_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, + eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0, dt_bool b_fit_i = true): + Pcf_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i), b_fit(b_fit_i) {} + + R_2d operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius_f, Region _Rect_2d bd, dt_int32 nit_pcf) + { + T sigma_r = fcn_sigma_r_2_sigma_g(sigma_g); + radius_f = fcn_set_bound(radius_f, 3*this->grid_2d.dR_min(), sigma_r); + + for(auto it=0; it::operator()(M_r, M_s, A, txy, p, sigma_g, bd, this->pcf_r); + + // get maximum position + R_2d r_c = this->Fit_Ellipt_Gauss_2d.fd_max_peak_pos(this->pcf_r); + + if ((it==nit_pcf-1) & b_fit) + { + r_c = this->Fit_Ellipt_Gauss_2d.fit_peak_pos(this->pcf_r, r_c, sigma_r, radius_f); + } + + txy += -(r_c - this->grid_2d.bs_h()); + } + + return txy; + } + protected: + dt_bool b_fit; + }; + + /******************************** Corrrect shift ***************************************/ + template + class Crt_Sft_1d: public Fd_Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Crt_Sft_1d(): Fd_Sft_1d() {} + + Crt_Sft_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i): + Fd_Sft_1d(fft_1d_i, grid_1d_i) {} + + T operator()(TVctr_r &M_r_i, TVctr_r &M_s_io, T p, T sigma_g, + Region _Rect_1d bd, dt_int32 nit_pcf) + { + T dx = 0; + dx = Fd_Sft_1d::operator()(M_r_i, M_s_io, p, sigma_g, dx, bd, nit_pcf); + this->sft_1d(dx, M_s_io); + + return dx; + } + }; + + template + class Crt_Sft_2d_BC: public Fd_Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using TVctr_rh = Vctr; + using TVctr_ch = Vctr; + + Crt_Sft_2d_BC(): Fd_Sft_2d_BC() {} + + Crt_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): + Fd_Sft_2d_BC(stream_i, fft_2d_i, grid_2d_i) {} + + TVctr_rh operator()(TVctr_r &M_r_i, TVctr_r &M_s_io, T p, T sigma_g, + Region _Rect_2d bd, dt_int32 nit_pcf) + { + TVctr_rh dr(this->grid_2d.ny, T(0)); + dr = Fd_Sft_2d_BC::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d_bc(1, dr, M_s_io); + + return dr; + } + }; + + template + class Crt_Sft_2d: public Fd_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Crt_Sft_2d(): Fd_Sft_2d() {} + + Crt_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): + Fd_Sft_2d(stream_i, fft_2d_i, grid_2d_i) {} + + R_2d operator()(TVctr_r &M_r_i, TVctr_r &M_s_io, T p, T sigma_g, + Region _Rect_2d bd, dt_int32 nit_pcf) + { + R_2d dr(0, 0); + dr = Fd_Sft_2d::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d(dr, M_s_io); + + return dr; + } + }; + + template + class Crt_Tr_2d: public Fd_Tr_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Crt_Tr_2d(): Fd_Tr_2d() {} + + Crt_Tr_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, + eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0, dt_bool b_fit_i = true): + Fd_Tr_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i, b_fit_i) {} + + R_2d operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_pcf, TVctr_r& mx_o) + { + txy = Fd_Tr_2d::operator()(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + this->af_tr(M_s, A, txy, mx_o); + + return txy; + } + }; + + /*********************************** calculate Chi^2 ***********************************/ + template + class Scy_Shx + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Scy_Shx():stream(nullptr) {} + + Scy_Shx(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + template + enable_if_edev_cpu + operator()(TVctr& mx_i, R_2d af, TVctr& mx_o) + { + if (fcn_is_zero(af.x) && fcn_is_equal(af.y, T(1))) + { + mx_o = mx_i; + } + + TVctr M_o_t; + TVctr *pM_o = &mx_o; + + if (mx_i.data() == mx_o.data()) + { + M_o_t.resize(mx_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = fcn_mean(*stream, mx_i); + + Grid_2d grid_2d_o = grid_2d; + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::shx_scy, TVctr>, grid_2d, mx_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (mx_i.data() == mx_o.data()) + { + mx_o.assign(pM_o->begin(), pM_o->end()); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, R_2d af, TVctr& mx_o) + { + if (fcn_is_zero(af.x) && fcn_is_equal(af.y, T(1))) + { + mx_o = mx_i; + } + + TVctr M_o_t; + TVctr *pM_o = &mx_o; + + if (mx_i.data() == mx_o.data()) + { + M_o_t.resize(mx_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = fcn_mean(*stream, mx_i); + + Grid_2d grid_2d_o = grid_2d; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::shx_scy, typename TVctr::value_type><<>>(grid_2d, mx_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (mx_i.data() == mx_o.data()) + { + mx_o.assign(pM_o->begin(), pM_o->end()); + } + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Chi2_Pcf_Sft_Scy_Shx_2d: public Crt_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Chi2_Pcf_Sft_Scy_Shx_2d(): Crt_Sft_2d() {} + + Chi2_Pcf_Sft_Scy_Shx_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): Crt_Sft_2d() + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + Crt_Sft_2d::set_in_data(stream_i, fft_2d_i, grid_2d_i); + shx_scy.set_in_data(this->stream, this->grid_2d); + } + + T operator()(TVctr_r &M_r_i, TVctr_r &M_s_i, T p, T sigma_g, + R_2d af, Region _Rect_2d bd, dt_int32 nit_pcf, R_2d& ds) + { + TVctr_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVctr_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, pcf); + + // cost function + return fcn_mean(*(this->stream), pcf); + } + + T operator()(TVctr_r &M_r_i, TVctr_r &M_s_i, T p, T sigma_g, + R_2d af, Region _Rect_2d bd, dt_int32 nit_pcf, R_2d& ds, Vctr& coef) + { + TVctr_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVctr_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, pcf); + + // cost function + auto chi2 = fcn_mean(*(this->stream), pcf); + + // get maximum position + R_2d r_c = this->Fit_Ellipt_Gauss_2d.fd_max_peak_pos(pcf); + + // fitting + T sigma_r = mt::fcn_sigma_r_2_sigma_g(sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 1.5*sigma_r); + coef = this->Fit_Ellipt_Gauss_2d.fit(pcf, r_c, sigma_r, radius); + coef[0] = ds.x + this->grid_2d.bs_x_h(); + coef[1] = ds.y + this->grid_2d.bs_y_h(); + + return chi2; + } + + protected: + Scy_Shx shx_scy; + }; + + template + class Chi2_Pcf_2d: public Fd_Tr_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Chi2_Pcf_2d(): Fd_Tr_2d() {} + + Chi2_Pcf_2d(Stream *stream_i, FFT *fft_2d_i, + Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0): + Fd_Tr_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i) {} + + T operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, Region _Rect_2d bd) + { + return this->chi_2(M_r, M_s, p, sigma_g, bd); + } + + T operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, Region _Rect_2d bd) + { + return this->chi_2(M_r, M_s, A, txy, p, sigma_g, bd); + } + + T operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, Vctr& coef) + { + return this->chi_2(M_r, M_s, A, txy, p, sigma_g, radius, bd, coef); + } + + R_2d find_txy(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_pcf) + { + return Fd_Tr_2d::operator()(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + } + }; + + template + class Fd_Sft_Scy_Shx_2d: public Chi2_Pcf_Sft_Scy_Shx_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Sft_Scy_Shx_2d():Chi2_Pcf_Sft_Scy_Shx_2d(), nit_pcf(2) {} + + Fd_Sft_Scy_Shx_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): + Chi2_Pcf_Sft_Scy_Shx_2d(stream_i, fft_2d_i, grid_2d_i), nit_pcf(2) {} + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Vctr, edev_cpu>& spx, Region _Rect_2d bd, dt_int32 nit_nm) + { + dt_int32 ic = 1; + + T d_pix_min = this->grid_2d.dg_min(); + T d_min = 0.05*d_pix_min; + T alpha = 1.0; + T beta = 0.5; + T gamma = 2.0; + + for(auto it=0; it ds_r(0, 0); + auto chi2_r = chi2_pcf(M_r, M_s, p, sigma_g, x_r, bd, nit_pcf, ds_r); + + if (chi2_r ds_e(0, 0); + auto chi2_e = chi2_pcf(M_r, M_s, p, sigma_g, x_e, bd, nit_pcf, ds_e); + if (chi2_e(x_e, ds_e, chi2_e); + } + else + { + spx[2] = Atp_1(x_r, ds_r, chi2_r); + } + } + else if (chi2_r(x_r, ds_r, chi2_r); + } + else if (chi2_r ds_rc(0, 0); + auto chi2_rc = chi2_pcf(M_r, M_s, p, sigma_g, x_rc, bd, nit_pcf, ds_rc); + if (chi2_rc(x_rc, ds_rc, chi2_rc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + else + { + auto x_wc = x_m + beta*(x_w-x_m); + R_2d ds_wc(0, 0); + auto chi2_wc = chi2_pcf(M_r, M_s, p, sigma_g, x_wc, bd, nit_pcf, ds_wc); + if (chi2_wc(x_wc, ds_wc, chi2_wc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + } + + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d& af, Region _Rect_2d bd, R_2d& tr, dt_int32 nit_nm) + { + auto spx = set_simplex(M_r, M_s, p, sigma_g, af, tr, bd, nit_nm); + this->operator()(M_r, M_s, p, sigma_g, spx, bd, nit_nm); + + af = spx[0].f; + tr = spx[0].tr; + + // // shear and scaling + // shx_scy(M_s, af, M_s); + // // correct shift + // tr = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, tr, bd, nit_pcf); + } + + protected: + R_2d x_af(const R_2d& af, const R_2d& r) + { + return R_2d(r.x+af.x*r.y, af.y*r.y); + } + + R_2d x_iaf(const R_2d& af, const R_2d& r) + { + return R_2d(r.x-af.x*r.y/af.y, r.y/af.y); + } + + Vctr, edev_cpu> set_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d x_0, R_2d ds_0, Region _Rect_2d& bd, dt_int32 nit_nm) + { + // global shift + if (fcn_is_zero(ds_0)) + { + ds_0 = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds_0, bd, nit_pcf); + // bd.fcn_repl_bdr(ds_0); + } + + TVctr_r M_s_t = M_s; + this->sft_2d(x_iaf(x_0, ds_0), M_s_t); + + // determine coefficients + Vctr coef(6); + chi2_pcf(M_r, M_s_t, p, sigma_g, x_0, bd, nit_pcf, ds_0, coef); + + // calculate dd0 + T ff = coef[4]/coef[3]; + ff = (ff<1)?1/ff:ff; + ff = ::fmax(1.05, ff); + + T dd0 = ::sqrt(1.354e-04*pow(ff-1, 2)+6.622e-4*(ff-1)); + dd0 = ::fmax(dd0, this->grid_2d.dg_min()); + + T sin_t = sin(coef[5]); + T cos_t = cos(coef[5]); + + T sigma_x = pow(cos_t/coef[3], 2)+pow(sin_t/coef[4], 2); + sigma_x = ::sqrt(1/sigma_x); + + T sigma_y = pow(sin_t/coef[3], 2)+pow(cos_t/coef[4], 2); + sigma_y = ::sqrt(1/sigma_y); + + T theta = atan2(sigma_y, sigma_x); + + R_2d u(dd0*cos(theta), dd0*sin(theta)); + R_2d v(-u.y, u.x); + + // set simplex + Vctr, edev_cpu> spx(3); + + spx[0].f = x_0; + spx[0].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[0].f, bd, nit_pcf, spx[0].tr); + + spx[1].f = x_0+u; + spx[1].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[1].f, bd, nit_pcf, spx[1].tr); + + spx[2].f = x_0+v; + spx[2].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[2].f, bd, nit_pcf, spx[2].tr); + + // sort simplex + sort(spx); + + return spx; + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d af, Region _Rect_2d& bd, dt_int32 nit_pcf, R_2d& tr) + { + return Chi2_Pcf_Sft_Scy_Shx_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, tr); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d af, Region _Rect_2d& bd, dt_int32 nit_pcf, R_2d& tr, Vctr& coef) + { + return Chi2_Pcf_Sft_Scy_Shx_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, tr, coef); + } + + void sort(Vctr, edev_cpu>& spx) + { + std::sort(spx.begin(), spx.end(), [](const Atp_1& x, const Atp_1& y){ return x.chi2, edev_cpu>& spx) + { + auto r0 = spx[0].f; + + R_2d dr = spx[1].f - r0; + T d_max = dr.norm(); + for(auto i=2; i dr = spx[i].f - r0; + d_max = ::fmax(d_max, dr.norm()); + } + return d_max; + } + + T min_length(Vctr, edev_cpu>& spx) + { + auto r0 = spx[0].f; + R_2d dr = spx[1].f - r0; + T d_min = dr.norm(); + for(auto i=2; i dr = spx[i].f - r0; + d_min = ::fmin(d_min, dr.norm()); + } + return d_min; + } + + R_2d best_centroid(Vctr, edev_cpu>& spx) + { + R_2d r_c(0, 0); + for(auto i=0; i, edev_cpu>& spx, Region _Rect_2d& bd, dt_int32 nit_pcf) + { + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.norm(); + auto mp13 = p13.norm(); + auto mp_max = ::fmax(mp12, mp13); + + T theta = angle(p12, p13); + + T theta_min = 10; + T theta_0 = theta_min*c_pi/180; + T theta_e = c_pi-theta_min*c_pi/180; + + dt_bool b_m = (mp12theta_e)||b_m) + { + if (b_m && (mp12(-u.y, u.x); + R_2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[1] = Atp_1(x_o, ds_o, chi2_o); + } + else + { + T m = max_length(spx); + auto u = p12/norm(p12); + auto x_o = spx[0].f + mp_max*R_2d(-u.y, u.x); + R_2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[2] = Atp_1(x_o, ds_o, chi2_o); + } + + sort(spx); + } + } + + void contract_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Vctr, edev_cpu>& spx, Region _Rect_2d& bd, dt_int32 nit_pcf) + { + T ff = 0.5; + + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.norm(); + auto mp13 = p13.norm(); + + if (mp12(-u.y, u.x); + R_2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[2] = Atp_1(x_c, ds_c, chi2_c); + } + else + { + auto u = p13/mp13; + auto x_c = spx[0].f + ff*mp12*R_2d(-u.y, u.x); + R_2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[1] = Atp_1(x_c, ds_c, chi2_c); + } + + sort(spx); + } + + dt_int32 nit_pcf; + }; + + template + class Fd_Tr_Scy_Shx_2d:public Chi2_Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Tr_Scy_Shx_2d(): Chi2_Pcf_2d(), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5) {} + + Fd_Tr_Scy_Shx_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0): + Chi2_Pcf_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5) {} + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T& scy, T& shx, R_2d& txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_nm) + { + Simplex spx = spx_0(M_r, M_s, scy, shx, txy, p, sigma_g, radius, bd); + + dt_int32 ic = 1; + + T d_pix_min = this->grid_2d.dg_min(); + T d_min = 0.05*d_pix_min; + + for(auto it = 0; it(x_r, t_r, chi2_r); + } + else + { + auto x_e = x_m + c_e*(x_r - x_m); + auto t_e = find_txy(M_r, M_s, x_e, t_b, p, sigma_g, radius, bd); + auto chi2_e = chi2_pcf(M_r, M_s, x_e, t_e, p, sigma_g, bd); + + spx[2] = (chi2_e(x_e, t_e, chi2_e):Atp_1(x_r, t_r, chi2_r); + } + } + else + { + if (chi2_r(x_r, t_r, chi2_r); + } + + auto x_c = x_m + c_c*(x_r - x_m); + auto t_c = find_txy(M_r, M_s, x_c, t_b, p, sigma_g, radius, bd); + auto chi2_c = chi2_pcf(M_r, M_s, x_c, t_c, p, sigma_g, bd); + + if (chi2_c(x_c, t_c, chi2_c); + } + else + { + shrink_simplex(M_r, M_s, p, sigma_g, radius, bd, spx); + } + } + + spx.sort(); + } + + shx = spx[0].f.x; + scy = spx[0].f.y; + txy = spx[0].tr; + } + + protected: + const dt_int32 nit_pcf; + + const T c_r; + const T c_e; + const T c_c; + const T c_s; + + struct Simplex + { + Simplex() {} + + Simplex(dt_int32 new_size) + { + resize(new_size); + } + + dt_int32 size() const + { + return m_spx.size(); + } + + void resize(dt_int32 new_size) + { + m_spx.resize(new_size); + } + + Atp_1& operator[](const dt_int32 idx) { return m_spx[idx]; } + + const Atp_1& operator[](const dt_int32 idx) const { return m_spx[idx]; } + + void sort() + { + std::sort(m_spx.begin(), m_spx.end(), [](const Atp_1& x, const Atp_1& y) { return x.chi2 < y.chi2; }); + } + + T max_length() + { + auto f0 = m_spx[0].f; + R_2d dr = m_spx[1].f - f0; + T d_max = dr.norm(); + for(auto ik = 2; ik < m_spx.size(); ik++) + { + R_2d dr = m_spx[ik].f - f0; + d_max = ::fmax(d_max, dr.norm()); + } + return d_max; + } + + T min_length() + { + auto f0 = m_spx[0].f; + R_2d dr = m_spx[1].f - f0; + T d_min = dr.norm(); + for(auto ik = 2; ik < m_spx.size(); ik++) + { + R_2d dr = m_spx[ik].f - f0; + d_min = ::fmin(d_min, dr.norm()); + } + return d_min; + } + + R_2d centroid() + { + R_2d r_c(0, 0); + dt_int32 n_spx = m_spx.size()-1; + for(auto ik = 0; ik, edev_cpu> m_spx; + }; + + R_2d find_txy(TVctr_r &M_r, TVctr_r &M_s, R_2d f, R_2d txy, T p, T sigma_g, T radius, Region _Rect_2d& bd) + { + Mx_2x2 A(1, 0, f.x, f.y); + return Chi2_Pcf_2d::find_txy(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, R_2d f, R_2d txy, T p, T sigma_g, Region _Rect_2d& bd) + { + Mx_2x2 A(1, 0, f.x, f.y); + return Chi2_Pcf_2d::operator()(M_r, M_s, A, txy, p, sigma_g, bd); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, R_2d f, R_2d txy, T p, T sigma_g, T radius, + Region _Rect_2d& bd, Vctr& coef) + { + Mx_2x2 A(1, 0, f.x, f.y); + return Chi2_Pcf_2d::operator()(M_r, M_s, A, txy, p, sigma_g, radius, bd, coef); + } + + Simplex spx_0(TVctr_r &M_r, TVctr_r &M_s, T scy, T shx, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd) + { + // global shift + Vctr coef(6); + + auto x_0 = R_2d(shx, scy); + auto t_0 = find_txy(M_r, M_s, x_0, txy, p, sigma_g, radius, bd); + auto chi2_0 = chi2_pcf(M_r, M_s, x_0, t_0, p, sigma_g, radius, bd, coef); + + // bd.fcn_repl_bdr(t_0); + + // calculate dd0 + T ff = coef[4]/coef[3]; + ff = (ff<1)?1/ff:ff; + ff = ::fmax(1.05, ff); + + T dd0 = ::sqrt(1.354e-04*pow(ff - 1, 2) + 6.622e-4*(ff - 1)); + dd0 = ::fmax(dd0, this->grid_2d.dg_min()); + + T sin_t = sin(coef[5]); + T cos_t = cos(coef[5]); + + T sigma_x = pow(cos_t/coef[3], 2) + pow(sin_t/coef[4], 2); + sigma_x = ::sqrt(1/sigma_x); + + T sigma_y = pow(sin_t/coef[3], 2) + pow(cos_t/coef[4], 2); + sigma_y = ::sqrt(1/sigma_y); + + T theta = atan2(sigma_y, sigma_x); + + R_2d u(dd0*cos(theta), dd0*sin(theta)); + R_2d v(-u.y, u.x); + + // set simplex + Simplex spx(3); + + spx[0].f = x_0; + spx[0].tr = t_0; + spx[0].chi2 = chi2_0; + + spx[1].f = x_0 + u; + spx[1].tr = find_txy(M_r, M_s, spx[1].f, t_0, p, sigma_g, radius, bd); + spx[1].chi2 = chi2_pcf(M_r, M_s, spx[1].f, spx[1].tr, p, sigma_g, bd); + + spx[2].f = x_0 + v; + spx[2].tr = find_txy(M_r, M_s, spx[2].f, t_0, p, sigma_g, radius, bd); + spx[2].chi2 = chi2_pcf(M_r, M_s, spx[2].f, spx[2].tr, p, sigma_g, bd); + + spx.sort(); + + return spx; + } + + void orthogonal_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, T radius, + Region _Rect_2d& bd, Simplex &spx) + { + auto x_b = spx[0].f; + auto t_b = spx[0].tr; + + auto p12 = spx[1].f - x_b; + auto p13 = spx[2].f - x_b; + auto mp12 = p12.norm(); + auto mp13 = p13.norm(); + auto mp_max = ::fmax(mp12, mp13); + + T theta = angle(p12, p13); + + T theta_min = 10; + T theta_0 = theta_min*c_pi/180; + T theta_e = c_pi - theta_min*c_pi/180; + + dt_bool b_m = (mp12theta_e) || b_m) + { + if (b_m && (mp12(-u.y, u.x); + auto t_o = find_txy(M_r, M_s, x_o, t_b, p, sigma_g, radius, bd); + auto chi2_o = chi2_pcf(M_r, M_s, x_o, t_o, p, sigma_g, bd); + + spx[1] = Atp_1(x_o, t_o, chi2_o); + } + else + { + auto u = normalize(p12); + auto x_o = x_b + mp_max*R_2d(-u.y, u.x); + auto t_o = find_txy(M_r, M_s, x_o, t_b, p, sigma_g, radius, bd); + auto chi2_o = chi2_pcf(M_r, M_s, x_o, t_o, p, sigma_g, bd); + + spx[2] = Atp_1(x_o, t_o, chi2_o); + } + + spx.sort(); + } + } + + void shrink_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, T radius, + Region _Rect_2d& bd, Simplex &spx) + { + auto x_b = spx[0].f; + auto t_b = spx[0].tr; + for(auto ik = 1; ik < spx.size(); ik++) + { + auto x_s = x_b + c_s*(spx[ik].f-x_b); + auto t_s = find_txy(M_r, M_s, x_s, t_b, p, sigma_g, radius, bd); + auto chi2_s = chi2_pcf(M_r, M_s, x_s, t_s, p, sigma_g, bd); + + spx[ik] = Atp_1(x_s, t_s, chi2_s); + } + } + }; + + template + class Fd_Tr_Rot_2d:public Chi2_Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Tr_Rot_2d(): Chi2_Pcf_2d(), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5), p_c(0, 0) {} + + Fd_Tr_Rot_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0): + Chi2_Pcf_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5), p_c(grid_2d_i.rx_c(), grid_2d_i.ry_c()) {} + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T& theta, R_2d& txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_nm) + { + Simplex spx = spx_0(M_r, M_s, theta, txy, p, sigma_g, radius, bd); + + T d_min = 0.025*c_deg_2_rad; + + for(auto it = 0; it(x_r, t_r, chi2_r); + } + else + { + auto x_e = x_m + c_e*(x_r - x_m); + auto t_e = find_txy(M_r, M_s, x_e, t_b, p, sigma_g, radius, bd); + auto chi2_e = chi2_pcf(M_r, M_s, x_e, t_e, p, sigma_g, bd); + + spx[1] = (chi2_e(x_e, t_e, chi2_e):Atp_2(x_r, t_r, chi2_r); + } + } + else + { + if (chi2_r(x_r, t_r, chi2_r); + } + + auto x_c = x_m + c_c*(x_r - x_m); + auto t_c = find_txy(M_r, M_s, x_c, t_b, p, sigma_g, radius, bd); + auto chi2_c = chi2_pcf(M_r, M_s, x_c, t_c, p, sigma_g, bd); + + if (chi2_c(x_c, t_c, chi2_c); + } + } + + spx.sort(); + } + + theta = spx[0].theta; + txy = spx[0].tr; + } + + protected: + const dt_int32 nit_pcf; + + const T c_r; + const T c_e; + const T c_c; + const T c_s; + const R_2d p_c; + + struct Simplex + { + Simplex() {} + + Simplex(dt_int32 new_size) + { + resize(new_size); + } + + dt_int32 size() const + { + return m_spx.size(); + } + + void resize(dt_int32 new_size) + { + m_spx.resize(new_size); + } + + Atp_2& operator[](const dt_int32 idx) { return m_spx[idx]; } + + const Atp_2& operator[](const dt_int32 idx) const { return m_spx[idx]; } + + void sort() + { + std::sort(m_spx.begin(), m_spx.end(), [](const Atp_2& x, const Atp_2& y) { return x.chi2 < y.chi2; }); + } + + T max_length() + { + return ::fabs(m_spx[1].theta - m_spx[0].theta); + } + + T min_length() + { + return ::fabs(m_spx[1].theta - m_spx[0].theta); + } + + T centroid() + { + return m_spx[0].theta; + } + + private: + Vctr, edev_cpu> m_spx; + }; + + R_2d find_txy(TVctr_r &M_r, TVctr_r &M_s, T theta, R_2d txy, T p, T sigma_g, T radius, Region _Rect_2d& bd) + { + auto A = fcn_rot_mx_2d(theta); + txy = p_c - A*p_c + txy; + + return Chi2_Pcf_2d::find_txy(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, T theta, R_2d txy, T p, T sigma_g, Region _Rect_2d& bd) + { + auto A = mt::fcn_rot_mx_2d(theta); + txy = p_c - A*p_c + txy; + + return Chi2_Pcf_2d::operator()(M_r, M_s, A, txy, p, sigma_g, bd); + } + + Simplex spx_0(TVctr_r &M_r, TVctr_r &M_s, T theta, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd) + { + auto x_0 = theta; + auto t_0 = find_txy(M_r, M_s, x_0, txy, p, sigma_g, radius, bd); + auto chi2_0 = chi2_pcf(M_r, M_s, x_0, t_0, p, sigma_g, bd); + + // set simplex + Simplex spx(2); + + spx[0].theta = x_0; + spx[0].tr = t_0; + spx[0].chi2 = chi2_0; + + spx[1].theta = x_0 + 1.0*c_deg_2_rad; + spx[1].tr = find_txy(M_r, M_s, spx[1].theta, t_0, p, sigma_g, radius, bd); + spx[1].chi2 = chi2_pcf(M_r, M_s, spx[1].theta, spx[1].tr, p, sigma_g, bd); + spx.sort(); + + return spx; + } + }; + + /********************************* calculate d_phi *************************************/ + template + class Opt_Flow + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Opt_Flow(): stream(nullptr) {} + + Opt_Flow(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + + intrpl_rg_2d.set_in_data(stream, grid_2d, grid_2d); + + gauss_cv_2d.set_in_data(stream, fft_2d_i, grid_2d); + + v_x.resize(grid_2d.size()); + v_y.resize(grid_2d.size()); + + Rx.resize(grid_2d.size()); + Ry.resize(grid_2d.size()); + M.resize(grid_2d.size()); + + } + + void operator()(TVctr& M_s, TVctr& M_m, T alpha, T sigma, dt_int32 n_iter, TVctr& v_xt, TVctr& v_yt) + { + // create rectangular grid + set_regular_grid(Rx, Ry); + + // set initial optical flow + v_x = v_xt; + v_y = v_yt; + + for(auto iter = 0; iter < n_iter; iter++) + { + // create new grid + mt::add(*stream, v_x, Rx); + mt::add(*stream, v_y, Ry); + + // resample distored image in a new grid + intrpl_rg_2d(M_m, Rx, Ry, M); + + // calculate optical flow + fcn_opt_flow(M_s, M, alpha, v_x, v_y); + + // regularization based on convolution + if (fcn_is_nzero(sigma)) + { + gauss_cv_2d(sigma, v_x); + gauss_cv_2d(sigma, v_y); + } + + // add optical flow + mt::add(*stream, v_x, v_xt); + mt::add(*stream, v_y, v_yt); + + } + } + + void set_fft_plan() + { + gauss_cv_2d.set_fft_plan(); + } + + void cleanup() + { + gauss_cv_2d.cleanup(); + } + + protected: + + void set_regular_grid(TVctr& Rx, TVctr& Ry) + { + Vctr Rx_h; + Vctr Ry_h; + + Rx_h.reserve(grid_2d.size()); + Ry_h.reserve(grid_2d.size()); + + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + Rx_h.push_back(grid_2d.rx(ix)); + Ry_h.push_back(grid_2d.ry(iy)); + } + } + + thrust::copy(Rx_h.begin(), Rx_h.end(), Rx.begin()); + thrust::copy(Ry_h.begin(), Ry_h.end(), Ry.begin()); + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + fcn_opt_flow(TVctr& M_s, TVctr& M_m, T alpha, TVctr& v_x, TVctr& v_y) + { + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_opt_flow, TVctr>, grid_2d, M_s, M_m, alpha, v_x, v_y); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + fcn_opt_flow(TVctr& M_s, TVctr& M_m, T alpha, TVctr& v_x, TVctr& v_y) + { + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_opt_flow, typename TVctr::value_type><<>>(grid_2d, M_s, M_m, alpha, v_x, v_y); + } + #endif + + Stream *stream; + Grid_2d grid_2d; + + Interp_rn_2d intrpl_rg_2d; + Gauss_Cv_2d gauss_cv_2d; + + TVctr v_x; + TVctr v_y; + + TVctr Rx; + TVctr Ry; + TVctr M; + }; + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cgpu_detail.cuh b/src - Copy (2)/cgpu_detail.cuh new file mode 100755 index 00000000..894862b9 --- /dev/null +++ b/src - Copy (2)/cgpu_detail.cuh @@ -0,0 +1,1535 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_DETAIL_H + #define CGPU_DETAIL_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "grid.cuh" + #include "cgpu_vctr.cuh" + #include "kahan_sum.cuh" + #include "cgpu_fcns_gen.cuh" + #include "fcns_wd.cuh" + #include "igrid.cuh" + #include "grid.cuh" + + #include + + namespace mt + { + /* functors */ + namespace cgpu_fctr + { + template + struct assign_real + { + template + CGPU_EXEC + T operator()(const U& x) const { return x.real(); } + }; + + template + struct assign_max_real + { + const T v_lim; + const T val; + assign_max_real(const T& v_lim, const T& val): v_lim(v_lim), val(val) {} + + CGPU_EXEC + T operator()(const complex& x) const + { + auto x_r = T(x.real()); + return (x_r>=v_lim)?x_r:val; + } + }; + + template + struct assign_abs_real + { + CGPU_EXEC + T operator()(const complex& x) const { return ::abs(x.real()); } + }; + + template + struct assign_abs + { + template + CGPU_EXEC + T operator()(const U& x) const { return ::abs(x); } + }; + + template + struct scale + { + const T w; + scale(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return w*x; } + }; + + template + struct norm_2 + { + template + CGPU_EXEC + T operator()(const U& x) const { return ::norm_2(x); } + }; + + template + struct scale_norm_2 + { + const T w; + scale_norm_2(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return w*::norm_2(x); } + }; + + template + struct add + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return lhs + rhs; } + }; + + template + struct sub + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return lhs - rhs; } + }; + + template + struct add_scale + { + const T w; + add_scale(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w*lhs + rhs; } + }; + + template + struct add_scale_i + { + const T w1; + const T w2; + add_scale_i(T w1, T w2): w1(w1), w2(w2) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w1*lhs + w2*rhs; } + }; + + template + struct add_norm_2 + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return ::norm_2(lhs) + rhs; } + }; + + template + struct add_norm_2_i + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return ::norm_2(lhs) + ::norm_2(rhs); } + }; + + template + struct add_scale_norm_2 + { + const T w; + add_scale_norm_2(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w*::norm_2(lhs) + rhs; } + }; + + template + struct add_scale_norm_2_i + { + const T w1; + const T w2; + add_scale_norm_2_i(T w1, T w2): w1(w1), w2(w2) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w1*::norm_2(lhs) + w2*::norm_2(rhs); } + }; + + template + struct mult + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return lhs*rhs; } + }; + + template + struct norm_2_sft + { + const T x_sft; + norm_2_sft(T x_sft): x_sft(x_sft) {} + + template + CGPU_EXEC + Tr operator()(const U& x) const { return ::norm_2(x-x_sft); } + }; + + template + struct abs_sft + { + const T x_sft; + abs_sft(T x_sft): x_sft(x_sft) {} + + template + CGPU_EXEC + Tr operator()(const U& x) const { return ::fabs(x-x_sft); } + }; + + template + struct div_sft + { + const T x_sft; + const T x_div; + div_sft(T x_sft, T x_div): x_sft(x_sft), x_div(x_div){} + + template + CGPU_EXEC + T operator()(const U& x) const { return (x-x_sft)/x_div; } + }; + + template + struct less + { + CGPU_EXEC + bool operator()(const T &lhs, const T &rhs) const + { + return lhs < rhs; + } + }; + + template + struct less_soa + { + template + bool operator()(const TTuple1& lhs, const TTuple2& rhs) + { + return thrust::get(lhs) < thrust::get(rhs); + } + }; + + template + struct closest_element + { + const T m_val; + + closest_element(T val): m_val(val) {} + + dt_bool operator()(const T& a, const T& b) + { + const T da = 1e-4; + return fabs(a-m_val-da) + struct binarize + { + const T thr; + binarize(T thr): thr(thr) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return (x + struct threshold_max + { + const T thr; + + threshold_max(T thr): thr(thr) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return fcn_max(thr, x); } + }; + + template + struct threshold_min + { + const T thr; + + threshold_min(T thr): thr(thr) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return fcn_min(thr, x); } + }; + + template + struct anscombe_fwd + { + const T xs; + anscombe_fwd(): xs(T(3.0/8.0)) {} + + template + CGPU_EXEC + T operator()(const U& x) const + { + return fcn_max(T(0), T(2)*::sqrt(x+xs)); + } + }; + + template + struct anscombe_inv + { + const T a; + const T b; + const T c; + const T d; + const T e; + anscombe_inv(): a(T(1.0/4.0)), b(T(::sqrt(3.0/2.0)/4.0)), + c(T(-11.0/8.0)), d(T(5.0*::sqrt(3.0/2.0)/8)), e(T(-1.0/8.0)) {} + + template + CGPU_EXEC + T operator()(const U& x) const + { + if (fcn_is_zero(x)) + { + return fcn_max(T(0), a*x+e); + } + else + { + const T ix = T(1)/x; + return fcn_max(T(0), a*x*x+e+ix*(b+ix*(c+ix*d))); + } + } + }; + + template + struct rad_dist_ind_by_div + { + T r_0; + T dr; + dt_int32 ix_min; + dt_int32 ix_max; + + rad_dist_ind_by_div(T r_0, T dr, dt_int32 ix_min, dt_int32 ix_max): r_0(r_0), dr(dr), ix_min(ix_min), ix_max(ix_max) {} + + CGPU_EXEC + dt_int32 operator()(const T& r) const + { + return fcn_bcfloor((r-r_0)/dr, ix_min, ix_max); + } + }; + + template + struct rad_dist_ind_by_srch + { + T* rv; + dt_int32 ix_min; + dt_int32 ix_max; + + rad_dist_ind_by_srch(T* rv, dt_int32 ix_min, dt_int32 ix_max): rv(rv), ix_min(ix_min), ix_max(ix_max) {} + + CGPU_EXEC + dt_int32 operator()(const T& r) const + { + return fcn_r_2_ir_by_vctr(rv, r, ix_min, ix_max); + } + }; + + } // namespace fctr + + template + void synchronize_every(const dt_int32& i_sync, const dt_int32& n_sync) + { + + } + + template <> + void synchronize_every(const dt_int32& i_sync, const dt_int32& n_sync) + { + #ifdef __CUDACC__ + if (i_sync % n_sync == 0) + { + cudaDeviceSynchronize(); + } + #endif + } + + template + auto fcn_mkzipiter_begin(Args&... args) + { + return thrust::make_zip_iterator(thrust::make_tuple(std::begin(args)...)); + } + + template + auto fcn_mkzipiter_end(Args&... args) + { + return thrust::make_zip_iterator(thrust::make_tuple(std::end(args)...)); + } + + /* unrolled binary search */ + namespace cgpu_detail + { + template + CGPU_EXEC_INL + dt_int32 fcn_unrolled_binary_search_256(const T& x, Ctpr xv) + { + dt_int32 i_0 = 0; + dt_int32 i_e = 255; + + dt_int32 im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 128 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 64 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 32 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 16 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 8 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 4 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 2 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 1 + + return i_0; + } + + template + CGPU_EXEC_INL + dt_int32 fcn_unrolled_binary_search_128(const T& x, Ctpr xv) + { + dt_int32 i_0 = 0; + dt_int32 i_e = 127; + + dt_int32 im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 64 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 32 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 16 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 8 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 4 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 2 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 1 + + return i_0; + } + + template + CGPU_EXEC_INL + dt_int32 fcn_unrolled_binary_search_64(const T& x, Ctpr xv) + { + dt_int32 i_0 = 0; + dt_int32 i_e = 63; + + dt_int32 im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 32 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 16 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 8 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 4 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 2 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 1 + + return i_0; + } + } + + /* add - assign - crop - norm_2 - fftsft */ + namespace cgpu_detail + { + /***************************************************************************************/ + /**************** Shift zero-frequency component to center of spectrum *****************/ + /***************************************************************************************/ + /* shift matrix respect to nx_h */ + template + CGPU_EXEC_INL + void fcn_fftsft_1d(const dt_int32& ix, const iGrid_1d& igrid, T* mx_io) + { + const auto ix_sft = igrid.sub_2_ind(igrid.nx_h+ix); + thrust::swap(mx_io[ix], mx_io[ix_sft]); + } + + /* shift matrix respect to ny_h */ + template + CGPU_EXEC_INL + void fcn_fftsft_bc_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_io) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + const auto ixy_sft = igrid.sub_2_ind(ix, igrid.ny_h+iy); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_io) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, T* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + } + + /* shift 3d matrix respect to (nx_h, ny_h, nz_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_3d(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const iGrid_3d& igrid, T* mx_io) + { + auto ixy = igrid.sub_2_ind(ix, iy, iz); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(ix, iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, iy, iz); + ixy_sft = igrid.sub_2_ind(ix, igrid.ny_h+iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + } + + /* shift 3d matrix respect to (nx_h, ny_h, nz_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_3d(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const iGrid_3d& igrid, T* mx_i, T* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy, iz); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(ix, iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, iy, iz); + ixy_sft = igrid.sub_2_ind(ix, igrid.ny_h+iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const T& w, T* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + mx_o[ixy] += w*mx_i[ixy_sft]; + mx_o[ixy_sft] += w*mx_i[ixy]; + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + mx_o[ixy] += w*mx_i[ixy_sft]; + mx_o[ixy_sft] += w*mx_i[ixy]; + } + + /* add, scale, square and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_norm_2_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const U& w, U* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + mx_o[ixy] += w*::norm_2(mx_i[ixy_sft]); + mx_o[ixy_sft] += w*::norm_2(mx_i[ixy]); + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + mx_o[ixy] += w*::norm_2(mx_i[ixy_sft]); + mx_o[ixy_sft] += w*::norm_2(mx_i[ixy]); + } + + /***************************************************************************************/ + /* Assign and crop */ + template + CGPU_EXEC_INL + void fcn_assign_crop_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, T* mx_o) + { + if (iregion.chk_bound(ix, iy)) + { + mx_o[iregion.sub_2_ind(ix, iy)] = mx_i[igrid.sub_2_ind(ix, iy)]; + } + } + + /* assign, crop and shift */ + template + CGPU_EXEC_INL + void fcn_assign_crop_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, T* mx_o) + { + auto ix_i = ix; + auto iy_i = iy; + + auto ix_s = igrid.nx_h+ix; + auto iy_s = igrid.ny_h+iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] = mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] = mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + + /***************************************************************************************/ + ix_i = ix; + iy_i = igrid.ny_h+iy; + + ix_s = igrid.nx_h+ix; + iy_s = iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] = mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] = mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + } + + /* add, scale, crop and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_crop_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, const T& w, T* mx_o) + { + auto ix_i = ix; + auto iy_i = iy; + + auto ix_s = igrid.nx_h+ix; + auto iy_s = igrid.ny_h+iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + + /***************************************************************************************/ + ix_i = ix; + iy_i = igrid.ny_h+iy; + + ix_s = igrid.nx_h+ix; + iy_s = iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + } + + /* add, scale, square, crop and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_norm_2_crop_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, const U& w, U* mx_o) + { + auto ix_i = ix; + auto iy_i = iy; + + auto ix_s = igrid.nx_h+ix; + auto iy_s = igrid.ny_h+iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_s, iy_s)]); + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_i, iy_i)]); + } + + /***************************************************************************************/ + ix_i = ix; + iy_i = igrid.ny_h+iy; + + ix_s = igrid.nx_h+ix; + iy_s = iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_s, iy_s)]); + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_i, iy_i)]); + } + } + } + + /* transpose - element wise matrix op vector */ + namespace cgpu_detail + { + /* transpose */ + template + CGPU_EXEC_INL + void fcn_trs_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr mx_o) + { + mx_o[igrid.sub_2_ind_by_d2(ix, iy)] = mx_i[igrid.sub_2_ind(ix, iy)]; + } + + /***************************************************************************************/ + /* element wise addition: matrix + vector row */ + template + CGPU_EXEC_INL + void fcn_ew_add_mx_vctr_row(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] += vctr[ix]; + } + + /* element wise addition: matrix + vector col */ + template + CGPU_EXEC_INL + void fcn_ew_add_mx_vctr_col(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] += vctr[iy]; + } + + /***************************************************************************************/ + /* element wise subtraction: matrix - vector row */ + template + CGPU_EXEC_INL + void fcn_ew_sub_mx_vctr_row(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] -= vctr[ix]; + } + + /* element wise subtraction: matrix - vector col */ + template + CGPU_EXEC_INL + void fcn_ew_sub_mx_vctr_col(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] -= vctr[iy]; + } + + /***************************************************************************************/ + /* element wise multiplication matrix X vector row */ + template + CGPU_EXEC_INL + void fcn_ew_mult_mx_vctr_row(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] *= vctr[ix]; + } + + /* element wise multiplication matrix X vector col */ + template + CGPU_EXEC_INL + void fcn_ew_mult_mx_vctr_col(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] *= vctr[iy]; + } + } + + /* aperture functions */ + namespace cgpu_detail + { + template + CGPU_EXEC_INL + void fcn_fermi_aperture(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_cut, const T& alpha, const T& w, U* mx_io) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto g2 = grid.g2_sft(ix, iy); + + mx_io[ixy] *= w*fcn_fermi_lpf(alpha, g2_cut, g2); + } + + template + CGPU_EXEC_INL + void fcn_hard_aperture(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_cut, const T& w, U* mx_io) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto g2 = grid.g2_sft(ix, iy); + + mx_io[ixy] = ((g2 <= g2_cut))?(w*mx_io[ixy]):T(0); + } + } + + /* phase shifts real space*/ + namespace cgpu_detail + { + // phase factor 1d + template + CGPU_EXEC_INL + void fcn_rs_exp_factor_1d(const dt_int32& ix, const Grid_1d& grid, + complex* psi_i, const T& gx, const T& w, complex* psi_o) + { + const auto rx = grid.rx_sft(ix)-grid.rx_c(); + psi_o[ix] = w*psi_i[ix]*euler(gx*rx); + } + + // phase factor 2d by col + template + CGPU_EXEC_INL + void fcn_rs_exp_factor_2d_bc(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const T& alpha, Ctpr gy, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto ry = grid.ry_sft(iy)-grid.ry_c(); + psi_o[ixy] = w*psi_i[ixy]*euler(alpha*gy[ix]*ry); + } + + // phase factor 2d + template + CGPU_EXEC_INL + void fcn_rs_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto rv = grid.rv_sft(ix, iy)-grid.rv_c(); + psi_o[ixy] = w*psi_i[ixy]*euler(g*rv); + } + + // phase factor 2d multipositions + template + CGPU_EXEC_INL + void fcn_rs_mul_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, R_2d* g, const dt_int32& n_g, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto rv = grid.rv_sft(ix, iy)-grid.rv_c(); + + complex exp_sum = 0; + for(auto ig=0; ig + CGPU_EXEC_INL + void fcn_fs_exp_factor_1d(const dt_int32& ix, const Grid_1d& grid, + complex* psi_i, const T& rx, const T& w, complex* psi_o) + { + const auto gx = grid.gx_sft(ix); + psi_o[ix] = w*psi_i[ix]*euler(rx*gx); + } + + template + CGPU_EXEC_INL + void fcn_fs_exp_factor_2d_bc(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const T& alpha, T* ry, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gy = grid.gy_sft(iy); + psi_o[ixy] = w*psi_i[ixy]*euler(alpha*ry[ix]*gy); + } + + template + CGPU_EXEC_INL + void fcn_fs_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& r, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gv = grid.gv_sft(ix, iy); + psi_o[ixy] = w*psi_i[ixy]*euler(r*gv); + } + + template + CGPU_EXEC_INL + void fcn_fs_mul_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, R_2d* r, const dt_int32& n_r, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gv = grid.gv_sft(ix, iy); + + complex exp_sum = 0; + for(auto ir=0; ir + CGPU_EXEC_INL + T fcn_grad_x(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + + if (ix == 0) + { + const auto ixy_f = igrid.sub_2_ind(ix+1, iy); + + return mx_i[ixy_f]-mx_i[ixy]; + } + else if (ix == igrid.nx-1) + { + const auto ixy_b = igrid.sub_2_ind(ix-1, iy); + + return mx_i[ixy]-mx_i[ixy_b]; + } + else + { + const auto ixy_b = igrid.sub_2_ind(ix-1, iy); + const auto ixy_f = igrid.sub_2_ind(ix+1, iy); + + return (mx_i[ixy_f]-mx_i[ixy_b])/T(2); + } + } + + template + CGPU_EXEC_INL + void fcn_grad_x(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr mx_o) + { + mx_o[igrid.sub_2_ind(ix, iy)] = fcn_grad_x(ix, iy, igrid, mx_i); + } + + /***************************************************************************************/ + template + CGPU_EXEC_INL + T fcn_grad_y(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + + if (iy == 0) + { + const auto ixy_f = igrid.sub_2_ind(ix, iy+1); + + return mx_i[ixy_f]-mx_i[ixy]; + } + else if (iy == igrid.ny-1) + { + const auto ixy_b = igrid.sub_2_ind(ix, iy-1); + + return mx_i[ixy]-mx_i[ixy_b]; + } + else + { + const auto ixy_b = igrid.sub_2_ind(ix, iy-1); + const auto ixy_f = igrid.sub_2_ind(ix, iy+1); + + return (mx_i[ixy_f]-mx_i[ixy_b])/T(2); + } + } + + template + CGPU_EXEC_INL + void fcn_grad_y(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr mx_o) + { + mx_o[igrid.sub_2_ind(ix, iy)] = fcn_grad_y(ix, iy, igrid, mx_i); + } + + /***************************************************************************************/ + //template + //CGPU_EXEC_INL + //R_2d fcn_grad(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i) + //{ + // return {fcn_grad_x(ix, iy, igrid, mx_i), fcn_grad_y(ix, iy, igrid, mx_i)}; + //} + + template + CGPU_EXEC_INL + void fcn_grad(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr dm_x, Tpr dm_y) + { + fcn_grad_x(ix, iy, igrid, mx_i, dm_x); + fcn_grad_y(ix, iy, igrid, mx_i, dm_y); + } + } + + /* function multiplication fourier space */ + namespace cgpu_detail + { + #define FCN_MULT_FS_FCN_CGPU(POW, DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_mult_fs_fcn_g##POW##_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, const T& w, Tpr mx_io) \ + { \ + const auto fg = fcn(grid.g##POW##_sft(IDX_ND(DIM))); \ + mx_io[grid.sub_2_ind(IDX_ND(DIM))] *= w*fg; \ + } + + FCN_MULT_FS_FCN_CGPU(, 1); // fcn_mult_fs_fcn_g_1d + FCN_MULT_FS_FCN_CGPU(, 2); // fcn_mult_fs_fcn_g_2d + FCN_MULT_FS_FCN_CGPU(, 3); // fcn_mult_fs_fcn_g_3d + + FCN_MULT_FS_FCN_CGPU(2, 1); // fcn_mult_fs_fcn_g2_1d + FCN_MULT_FS_FCN_CGPU(2, 2); // fcn_mult_fs_fcn_g2_2d + FCN_MULT_FS_FCN_CGPU(2, 3); // fcn_mult_fs_fcn_g2_3d + } + + /* deconvolution */ + namespace cgpu_detail + { + #define FCN_DCV_FS_FCN_CGPU(POW, DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_dcv_fs_fcn_g##POW##_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, const T& psnr, const T& w, Tpr mx_io) \ + { \ + const auto fg = fcn(grid.g##POW##_sft(IDX_ND(DIM))); \ + mx_io[grid.sub_2_ind(IDX_ND(DIM))] *= w*fg/(fg*fg+psnr); \ + } + + FCN_DCV_FS_FCN_CGPU(, 1); // fcn_dcv_fs_fcn_g_1d + FCN_DCV_FS_FCN_CGPU(, 2); // fcn_dcv_fs_fcn_g_2d + FCN_DCV_FS_FCN_CGPU(, 3); // fcn_dcv_fs_fcn_g_3d + + FCN_DCV_FS_FCN_CGPU(2, 1); // fcn_dcv_fs_fcn_g2_1d + FCN_DCV_FS_FCN_CGPU(2, 2); // fcn_dcv_fs_fcn_g2_2d + FCN_DCV_FS_FCN_CGPU(2, 3); // fcn_dcv_fs_fcn_g2_3d + } + + /* window functions */ + namespace cgpu_detail + { + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_xd(const dt_int32& ix, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix)] = fcn.eval_r2(grid.r2(ix, fcn.r)); + //} + // + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_xd(const dt_int32& ix, const dt_int32& iy, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy)] = fcn.eval_r2(grid.r2(ix, iy, fcn.r)); + //} + + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_xd(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy, iz)] = fcn.eval_r2(grid.r2(ix, iy, iz, fcn.r)); + //} + + ///***************************************************************************************/ + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_sft_xd(const dt_int32& ix, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix)] = fcn.eval_r2(grid.r2_sft(ix, fcn.r)); + //} + // + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_sft_xd(const dt_int32& ix, const dt_int32& iy, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy)] = fcn.eval_r2(grid.r2_sft(ix, iy, fcn.r)); + //} + + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_sft_xd(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy, iz)] = fcn.eval_r2(grid.r2_sft(ix, iy, iz, fcn.r)); + //} + + #define FCN_WD_FCN_CGPU(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_wd_fcn_r2_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, Tpr mx_o) \ + { \ + mx_o[grid.sub_2_ind(IDX_ND(DIM))] = fcn.eval_r2(grid.r2(IDX_ND(DIM), fcn.r)); \ + } + + FCN_WD_FCN_CGPU(1); // fcn_wd_fcn_r2_1d + FCN_WD_FCN_CGPU(2); // fcn_wd_fcn_r2_2d + FCN_WD_FCN_CGPU(3); // fcn_wd_fcn_r2_3d + + #define FCN_WD_FCN_SFT_CGPU(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_wd_fcn_r2_sft_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, Tpr mx_o) \ + { \ + mx_o[grid.sub_2_ind(IDX_ND(DIM))] = fcn.eval_r2(grid.r2_sft(IDX_ND(DIM), fcn.r)); \ + } + + FCN_WD_FCN_SFT_CGPU(1); // fcn_wd_fcn_r2_sft_1d + FCN_WD_FCN_SFT_CGPU(2); // fcn_wd_fcn_r2_sft_2d + FCN_WD_FCN_SFT_CGPU(3); // fcn_wd_fcn_r2_sft_3d + } + + /* phase correlation */ + namespace cgpu_detail + { + /****************** pcf data processing real space *******************/ + #define FCN_RS_PCF_XD_DP(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_rs_pcf_##DIM##d_dp(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + Ctpr mx_i, const TFcn& wd, const T& w, Tpr mx_o) \ + { \ + const auto ind_0 = grid.sub_2_ind(IDX_ND(DIM)); \ + const auto ind_n = grid.sub_2_ind_bd(IDX_ND(DIM)+1); \ + mx_o[ind_0] = w*(mx_i[ind_n]-mx_i[ind_0])*wd(grid.r2(IDX_ND(DIM), wd.r_c)); \ + } + + FCN_RS_PCF_XD_DP(1); // fcn_rs_pcf_1d_dp + FCN_RS_PCF_XD_DP(2); // fcn_rs_pcf_2d_dp + FCN_RS_PCF_XD_DP(3); // fcn_rs_pcf_3d_dp + + /**************** mx_o data processing fourier space ******************/ + #define FCN_FS_PCF_XD_DP(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_fs_pcf_##DIM##d_dp(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + Ctpr mx_1i, Ctpr mx_2i, const TFcn& wd, const T& w, Tpr mx_o) \ + { \ + const auto ind_0 = grid.sub_2_ind(IDX_ND(DIM)); \ + auto z = conj(mx_1i[ind_0])*mx_2i[ind_0]; \ + mx_o[ind_0] = polar(wd(grid.g2_sft(IDX_ND(DIM))), arg(z)); \ + } + + FCN_FS_PCF_XD_DP(1); // fcn_fs_pcf_1d_dp + FCN_FS_PCF_XD_DP(2); // fcn_fs_pcf_2d_dp + FCN_FS_PCF_XD_DP(3); // fcn_fs_pcf_3d_dp + } + + /* optical flow */ + namespace cgpu_detail + { + // https:// en.wikipedia.org/wiki/Optical_flow + template + CGPU_EXEC_INL + void fcn_opt_flow(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_s, Ctpr mx_m, + const T& alpha, Tpr dphi_x, Tpr dphi_y) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + + const auto sm = mx_m[ixy]-mx_s[ixy]; + const auto alpha_sm_2 = ::square(alpha*sm); + + auto dmx_s = fcn_grad(ix, iy, igrid, mx_s); + auto dmx_m = fcn_grad(ix, iy, igrid, mx_m); + + const auto dphi = -sm*(dmx_s/(dmx_s.norm_2() + alpha_sm_2) + dmx_s/(dmx_m.norm_2() + alpha_sm_2)); + + if (isfinite(dphi.x) && isfinite(dphi.y)) + { + dphi_y[ixy] = dphi.x; + dphi_x[ixy] = dphi.y; + } + else + { + dphi_y[ixy] = T(0); + dphi_x[ixy] = T(0); + } + } + } + + /* interpolation poly3 */ + namespace cgpu_detail + { + // calculate interpolation coefficients from its value and derivative + template + CGPU_EXEC_INL + void fcn_vd_2_coef_poly3(const T& dx_ij, const T& y_i, const T& y_j, const T& t_i, const T& t_j, T& c2, T& c3) + { + const auto m_i = (y_j-y_i)/dx_ij; + const auto n_i = t_i + t_j - T(2)*m_i; + + c2 = (m_i-t_i-n_i)/dx_ij; + c3 = n_i/(dx_ij*dx_ij); + } + + // eval polynomial of order 3 + template + CGPU_EXEC_INL + T fcn_eval_poly3(const T& x, Ctpr xv, Ctpr c0, Ctpr c1, Ctpr c2, Ctpr c3) + { + const auto ix = fcn_unrolled_binary_search_128(x, xv); + const auto dx = x - xv[ix]; + + return c0[ix] + (c1[ix] +(c2[ix] + c3[ix]*dx)*dx)*dx; + } + } + + /* bilinear interpolation */ + namespace cgpu_detail + { + /* regular grid bilinear interpolation */ + // https:// en.wikipedia.org/wiki/Bilinear_interpolation + template + CGPU_EXEC_INL + T fcn_intrpl_bl_rg_2d(const R_2d& p, const Grid_2d& grid_i, Tpr mx_i) + { + const auto ix = fcn_set_bound(grid_i.rx_2_irx_fds(p.x), 0, grid_i.nx-2); + const auto iy = fcn_set_bound(grid_i.ry_2_iry_fds(p.y), 0, grid_i.ny-2); + + const auto f11 = mx_i[grid_i.sub_2_ind(ix, iy)]; + const auto f12 = mx_i[grid_i.sub_2_ind(ix, iy+1)]; + const auto f21 = mx_i[grid_i.sub_2_ind(ix+1, iy)]; + const auto f22 = mx_i[grid_i.sub_2_ind(ix+1, iy+1)]; + + const auto x1 = grid_i.rx(ix); + const auto x2 = grid_i.rx(ix+1); + const auto y1 = grid_i.ry(iy); + const auto y2 = grid_i.ry(iy+1); + + const auto dx1 = (p.x-x1)/(x2-x1); + const auto dx2 = (x2-p.x)/(x2-x1); + const auto dy1 = (p.y-y1)/(y2-y1); + const auto dy2 = (y2-p.y)/(y2-y1); + + return dx2*(f11*dy2 + f12*dy1)+dx1*(f21*dy2 + f22*dy1); + }; + + template + CGPU_EXEC_INL + void fcn_intrpl_bl_rg_2d(const dt_int32& ixy, const Grid_2d& grid_i, Ctpr mx_i, + Ctpr vrx, Ctpr vry, const T& bg, Tpr mx_o) + { + R_2d p(vrx[ixy], vry[ixy]); + mx_o[ixy] = (grid_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid_i, mx_i):bg; + }; + + /***************************************************************************************/ + /* non regular grid bilinear interpolation */ + // https:// www.codesd.com/item/bilinear-interpolation-with-non-aligned-entry-points.html + template + CGPU_EXEC_INL + T fcn_intrpl_bl_nrg_2d(const R_2d& p, const R_3d& p1, + const R_3d& p2, const R_3d& p3, const R_3d& p4) + { + const auto a = -p1.x + p3.x; + const auto b = -p1.x + p2.x; + const auto c = p1.x - p2.x - p3.x + p4.x; + const auto d = p.x - p1.x; + const auto e = -p1.y + p3.y; + const auto f = -p1.y + p2.y; + const auto g = p1.y - p2.y - p3.y + p4.y; + const auto h = p.y - p1.y; + + const auto c_x = ::sqrt(T(-4)*(c*e - a*g)*(d*f - b*h) + ::square(b*e - a*f + d*g - c*h)); + const auto c_y = T(2)*(c*e - a*g); + const auto c_z = T(2)*(c*f - b*g); + + T alpha = -(b*e - a*f + d*g - c*h + c_x)/c_y; + T beta = (b*e - a*f - d*g + c*h + c_x)/c_z; + + if ((alpha < T(0)) || (alpha > T(1)) || (beta < T(0)) || (beta > T(1))) + { + alpha = (-b*e + a*f - d*g + c*h + c_x)/c_y; + beta = -(-b*e + a*f + d*g - c*h + c_x)/c_z; + } + + return (T(1) - alpha)*((T(1) - beta)*p1.z + beta*p2.z) + alpha*((T(1) - beta)*p3.z + beta*p4.z); + }; + + template + CGPU_EXEC_INL + void fcn_intrpl_bl_nrg_2d(const dt_int32& ixy, Ctpr vrx_i, Ctpr vry_i, Ctprmx_i, + Ctpr vrx, Ctpr vry, const T& bg, Tpr mx_o) + { + R_2d p(vrx[ixy], vry[ixy]); + // neighboring search algorithm: check out tessellation or MD find neighbors + R_3d p1; + R_3d p2; + R_3d p3; + R_3d p4; + + // how to check out bound for non regular grid? + // mx_o[ixy] = (grid_2d_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, p1, p2, p3, p4, mx_i):bg; + }; + } + + namespace cgpu_detail + { + /* distort regular grid */ + template + CGPU_EXEC_INL + void fcn_distort_mx_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, Ctpr mx, + Ctpr dvx, Ctpr dvy, const T& bg, Tpr mx_o) + { + const R_2d p(grid.rx(ix)+dvx[iy], grid.ry(iy)+dvy[iy]); + mx_o[grid.sub_2_ind(ix, iy)] = (grid.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid, mx):bg; + }; + + /* scan distortion */ + template + CGPU_EXEC_INL + void fcn_sd_nr_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, Ctpr mx, + TPar &parm, Tpr mx_o) + { + const auto ixy = grid.sub_2nd(ix, iy); + const auto ny = grid.ny-2; + const auto nx = grid.nx-2; + + const R_2d p(grid.rx(ix), grid.ry(iy)); + + const auto iy_s1 = fcn_r_2r_b_by_vctr(parm.ry_s, p.y, 0, ny); + const auto iy_s2 = iy_s1 + 1; + + if ((iy_s1 < 0)||(iy_s2 > ny)) + { + mx_o[ixy] = (parm.bg_opt == efst_same_in)?mx[ixy]:parm.bg; + return; + } + + const auto iy_k1 = parm.iy[iy_s1]; + const auto ix_k1 = grid.rx_2rx_fds(p.x - parm.dx[iy_k1]); + const auto iy_k2 = parm.iy[iy_s2]; + const auto ix_k2 = grid.rx_2rx_fds(p.x - parm.dx[iy_k2]); + + if ((ix_k1 < 0)||(ix_k1 > nx)||(ix_k2 < 0)||(ix_k2 > nx)) + { + mx_o[ixy] = (parm.bg_opt == efst_same_in)?mx[ixy]:parm.bg; + return; + } + + const R_3d p1(grid.rx(ix_k1) + parm.dx[iy_k1], parm.ry_s[iy_s1], mx[grid.sub_2nd(ix_k1, iy_k1)]); + const R_3d p4(grid.rx(ix_k1+1) + parm.dx[iy_k1], parm.ry_s[iy_s1], mx[grid.sub_2nd(ix_k1+1, iy_k1)]); + const R_3d p2(grid.rx(ix_k2) + parm.dx[iy_k2], parm.ry_s[iy_s2], mx[grid.sub_2nd(ix_k2, iy_k2)]); + const R_3d p3(grid.rx(ix_k2+1) + parm.dx[iy_k2], parm.ry_s[iy_s2], mx[grid.sub_2nd(ix_k2+1, iy_k2)]); + + /* this must work */ + // mx_o[ixy] = fcn_intrpl_bl_nrg_2d(p, p1, p2, p3, p4, grid); + + auto u = p2-p1; + auto v = p4-p1; + p = p - p1; + T m = v.x*u.y-v.y*u.x; + T alpha = (u.y*p.x-u.x*p.y)/m; + T beta = (-v.y*p.x+v.x*p.y)/m; + + mx_o[ixy] = beta*(alpha*p3.z + (1-alpha)*p2.z) + (1-beta)*(alpha*p4.z + (1-alpha)*p1.z); + }; + + // /* find peak maximum 1d */ + // template + // CGPU_EXEC_INL + // T fd_max_peak_pos(const Grid_1d& grid, Ctpr M) + // { + // const dt_int32 ix_max = thrust::distance(M.begin(), thrust::max_element(M.begin(), M.end())); + + // return grid.rx(ix_max); + // }; + + // /* find peak maximum 2d */ + // template + // CGPU_EXEC FORCE_INLINE + // R_2d fd_max_peak_pos(const Grid_2d& grid, CtprM) + // { + // const dt_int32 ixy_max = thrust::distance(M.begin(), thrust::max_element(M.begin(), M.end())); + // const dt_int32 ix_max, iy_max; + // grid.ind_2_sub(ixy_max, ix_max, iy_max); + + // return {grid.rx(ix_max), grid.ry(iy_max)}; + // }; + + // template + // CGPU_EXEC_INL + // R_2d af_iscale(const R_2d& p, const T& fxy) + // { + // return p/fxy; + // } + + // template + // CGPU_EXEC_INL + // void sc_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid_2d_i, TVctr& mx_i, + // const T& fxy, const Grid_2d& grid_2d_o, TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid_2d_o.rx(ix), grid_2d_o.ry(iy)); + // p = af_iscale(p, fxy); + + // mx_o[grid_2d_o.sub_2_ind(ix, iy)] = fcn_intrpl_bl_rg_2d(p, grid_2d_i, mx_i); + // } + + // template + // CGPU_EXEC_INL + // R_2d af_irot_sca_sft(const T& theta, const R_2d& p0, const T& fx, const T& fy, const R_2d& ps, R_2d p) + // { + // T sin_t, cos_t; + // sincos(theta, &sin_t, &cos_t); + // p.x = (p.x-ps.x)/fx; + // p.y = (p.y-ps.y)/fy; + // p -= p0; + // p = R_2d(cos_t*p.x+sin_t*p.y, -sin_t*p.x+cos_t*p.y); + // p += p0; + // return p; + // } + + // template + // CGPU_EXEC_INL + // void rot_sca_sft_2d(const dt_int32& ix, const dt_int32& iy, const TGrid& grid_2d_i, TVctr& mx_i, + // const T& theta, const R_2d& p0, const T& fx, const T& fy, + // const R_2d& ps, const T& bg, const TGrid& grid_2d_o, TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid_2d_o.rx(ix), grid_2d_o.ry(iy)); + // p = af_irot_sca_sft(theta, p0, fx, fy, ps, p); + + // mx_o[grid_2d_o.sub_2_ind(ix, iy)] = (grid_2d_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid_2d_i, mx_i):bg; + // }; + + // template + // CGPU_EXEC_INL + // void at_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, TVctr& mx_i, + // const Mx_2x2& A, const R_2d& txy, const T& bg, + // TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid.rx(ix), grid.ry(iy)); + // p = A*p+txy; + + // mx_o[grid.sub_2_ind(ix, iy)] = (grid.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid, mx_i):bg; + // }; + + // template + // CGPU_EXEC_INL + // R_2d af_shx_scy(const R_2d& p, const T& a, const T& b) + // { + // return R_2d(p.x+a*p.y, b*p.y); + // } + + // template + // CGPU_EXEC_INL + // void shx_scy(const dt_int32& ix, const dt_int32& iy, const TGrid& grid_2d_i, TVctr& mx_i, + // const T& fx, const T& fy, const T& bg, + // const TGrid& grid_2d_o, TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid_2d_o.rx(ix), grid_2d_o.ry(iy)); + // p = af_shx_scy(p, fx, fy); + + // mx_o[grid_2d_o.sub_2_ind(ix, iy)] = (grid_2d_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid_2d_i, mx_i):bg; + // }; + + + // template + // CGPU_EXEC_INL + // void dilate(const dt_int32& ix_i, const dt_int32& iy_i, TVctr& Im_i, TVctr& Im_o) + // { + // dt_int32 ix_0 = max(ix_i+nk0, 0); + // dt_int32 ix_e = min(ix_i+nke, nx_i); + + // dt_int32 iy_0 = max(iy_i+nk0, 0); + // dt_int32 iy_e = min(iy_i+nke, ny_i); + + // for(auto ix = ix_0; ix < ix_e; ix++) + // { + // for(auto iy = iy_0; iy < iy_e; iy++) + // { + // if (Im_i[ix*ny_i+iy]>0.5) + // { + // Im_o[ix_i*ny_i+iy_i] = 1; + // return; + // } + // } + // } + // Im_o[ix_i*ny_i+iy_i] = 0; + // } + } // cgpu_detail + } + +#endif diff --git a/src - Copy (2)/cgpu_detail_mt.cuh b/src - Copy (2)/cgpu_detail_mt.cuh new file mode 100755 index 00000000..e87831d4 --- /dev/null +++ b/src - Copy (2)/cgpu_detail_mt.cuh @@ -0,0 +1,1811 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_DETAIL_MT_H + #define CGPU_DETAIL_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "type_traits_mt.cuh" + #include "lens.cuh" + #include "energy_loss.cuh" + #include "cgpu_detail.cuh" + + /* pointer to atomic functions */ + namespace mt + { + template + using pFcn_clnl_3_1 = T (*)(const T&, Ctpr, Ctpr); + + template + using pFcn_clnl_3_2 = void (*)(const T&, Ctpr, Ctpr, T&, T&); + + /***************************************************************************************/ + template + using pFcn_clnl_4_1 = T (*)(const T&, const T&, Ctpr, Ctpr); + + template + using pFcn_clnl_4_2 = void (*)(const T&, const T&, Ctpr, Ctpr, T&, T&); + + /***************************************************************************************/ + template + using pFcn_clnl_6_1 = T (*)(const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr); + + template + using pFcn_clnl_6_2 = void (*)(const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr, T&, T&); + + /***************************************************************************************/ + template + using pFcn_clnl_8_1 = T (*)(const T&, const T&, const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr); + + template + using pFcn_clnl_8_2 = void (*)(const T&, const T&, const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr, T&, T&); + } + + /* atomic functions */ + namespace mt + { + namespace cgpu_detail_mt + { + template + CGPU_EXEC_INL + T fcn_spt_exp_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_exp_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_gauss_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_gauss_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_lorentzian_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_lorentzian_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_yukawa_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T ix = T(1)/x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_yukawa_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T ix = T(1)/x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_pr_gauss_feg_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_pr_gauss_feg_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_int_fx_x0_xe(const T& x, const T& x_0, const T& x_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + const T a = 0.5*(x_e-x_0); + const T b = 0.5*(x_e+x_0); + T s = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + void fcn_int_fx_x0_xe(const T& x, const T& x_0, const T& x_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s1, T& s2, pFcn_clnl_3_2 fcn) + { + const T a = 0.5*(x_e-x_0); + const T b = 0.5*(x_e+x_0); + s1 = s2 = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + T fcn_int_fx_x0_pinfty(const T& x, const T& x_0, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + T s = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + void fcn_int_fx_x0_pinfty(const T& x, const T& x_0, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s1, T& s2, pFcn_clnl_3_2 fcn) + { + s1 = s2 = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + T fcn_int_vz_z0_ze(const T& r, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + const dt_bool split = (z_0<0) && (0 + CGPU_EXEC_INL + void fcn_int_vz_dvz_z0_ze( const T& r, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s, T& ds, pFcn_clnl_3_2 fcn) + { + dt_bool split = (z_0<0) && (0 + CGPU_EXEC_INL + T fcn_int_vz_ninfty_pinfty(const T& r, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + const T r2 = r*r; + T s = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + void fcn_int_vz_dvz_ninfty_pinfty(const T& r, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s, T& ds, pFcn_clnl_3_2 fcn) + { + const T r2 = r*r; + s = ds = 0; + + for(auto ik = 0; ik \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + if (Dev==edev_cpu) \ + pfcn = fcn_##cnam; \ + else \ + cudaMemcpyFromSymbol(&pfcn, pgpu_fcn_##cnam, sizeof(pFcn)); \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + + #define pFCN_TEMPLATE_AF_SPEC(cnam, TpFcn, ppt) \ + template \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + if (Dev==edev_cpu) \ + pfcn = fcn_##cnam; \ + else \ + cudaMemcpyFromSymbol(&pfcn, pgpu_fcn_##cnam##_spec, sizeof(pFcn)); \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + #else + #define pFCN_TEMPLATE_AF(cnam, TpFcn) \ + template \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + pfcn = fcn_##cnam; \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + + #define pFCN_TEMPLATE_AF_SPEC(cnam, TpFcn, ppt) \ + template \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + pfcn = fcn_##cnam; \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + #endif + + /***************************************************************************************/ + /*************************************** feg *******************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_lorentzian_v(x, 0, 3, cl, cnl) + fcn_spt_gauss_v(x, 3, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_lorentzian_vd(x, 0, 3, cl, cnl, y, dy); + fcn_spt_gauss_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + const T x2 = x*x; + + T y = 0; + + if (fcn_is_zero(x)) + { + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*cnl[ik]; + } + + } + else + { + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*(T(1)-exp(-cnl[ik]*x2)); + } + y = y/x2; + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T x2 = x*x; + + y = dy = 0; + + if (fcn_is_zero(x)) + { + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*cnl[ik]; + } + } + else + { + for(auto ik = 0; ik <6; ik++) + { + const auto t = exp(-cnl[ik]*x2); + y += cl[ik]*(T(1)-t); + dy += cl[ik]*(T(1)-(T(1)+cnl[ik]*x2)*t); + } + y = y/x2; + dy = T(-2)*dy/(x*x2); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + const T x2 = x*x; + + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1) + cnl[ik]*x2); + y += cl[ik]*t*(t + T(1)); + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T x2 = x*x; + + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1) + cnl[ik]*x2); + y += cl[ik]*t*(t + T(1)); + dy += T(-2)*x*cl[ik]*cnl[ik]*t*t*(T(2)*t + T(1)); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + auto y = fcn_spt_gauss_v(x, 0, 5, cl, cnl); + y += cl[5]/(cnl[5] + x*x); + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + const auto t = T(1)/(cnl[5] + x*x); + const auto yt = cl[5]*t; + y += yt; + dy += T(-2)*x*yt*t; + } + + /***************************************************************************************/ + template + using pFcn_feg1 = pFcn_clnl_3_1; + + #ifdef __CUDACC__ + template + GPU_EXEC pFcn_feg1 pgpu_fcn_feg = fcn_feg; + #endif + + pFCN_TEMPLATE_AF(feg, pFcn_feg1); + + /***************************************************************************************/ + template + using pFcn_feg2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_feg2 pgpu_fcn_feg_dfeg = fcn_feg_dfeg; + + pFCN_TEMPLATE_AF(feg_dfeg , pFcn_feg2); + + /***************************************************************************************/ + /***************************************** fxg *****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_fxg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_fxg_dfxg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_fxg(const T& x, Ctpr cl, Ctpr cnl) + { + const T x2 = x*x; + + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1)+cnl[ik]*x2); + y += cl[ik]*t*t; + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_fxg_dfxg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T x2 = x*x; + + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1)+cnl[ik]*x2); + const auto yt = cl[ik]*t*t; + y += yt; + dy += cnl[ik]*yt*t; + } + dy = T(-4)*x*dy; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + /***************************************************************************************/ + template + using pFcn_fxg1 = pFcn_clnl_4_1; + + template + GPU_EXEC pFcn_fxg1 pgpu_fcn_fxg = fcn_fxg; + + pFCN_TEMPLATE_AF(fxg, pFcn_fxg1); + + template + GPU_EXEC pFcn_clnl_3_1 pgpu_fcn_fxg_spec = fcn_fxg; + + pFCN_TEMPLATE_AF_SPEC(fxg, pFcn_clnl_3_1, eappt_weickenmeier_0_12); + + pFCN_TEMPLATE_AF_SPEC(fxg, pFcn_clnl_3_1, eappt_lobato_0_12); + + /***************************************************************************************/ + template + using pFcn_fxg2 = pFcn_clnl_4_2; + + template + GPU_EXEC pFcn_fxg2 pgpu_fcn_fxg_dfxg = fcn_fxg_dfxg; + + pFCN_TEMPLATE_AF(fxg_dfxg, pFcn_fxg2); + + template + GPU_EXEC pFcn_clnl_3_2 pgpu_fcn_fxg_dfxg_spec = fcn_fxg_dfxg; + + pFCN_TEMPLATE_AF_SPEC(fxg_dfxg, pFcn_clnl_3_2, eappt_weickenmeier_0_12); + + pFCN_TEMPLATE_AF_SPEC(fxg_dfxg, pFcn_clnl_3_2, eappt_lobato_0_12); + + /***************************************************************************************/ + /****************************************** pr *****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_pr_gauss_feg_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_pr_gauss_feg_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_yukawa_v(x, 0, 3, cl, cnl) + fcn_spt_pr_gauss_feg_v(x, 3, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_yukawa_vd(x, 0, 3, cl, cnl, y, dy); + fcn_spt_pr_gauss_feg_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_exp_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_exp_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_pr_gauss_feg_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 5, cl, cnl, y, dy); + } + + /***************************************************************************************/ + template + using pFcn_pr1 = pFcn_clnl_3_1; + + template + GPU_EXEC pFcn_pr1 pgpu_fcn_pr = fcn_pr; + + pFCN_TEMPLATE_AF(pr, pFcn_pr1); + + /***************************************************************************************/ + template + using pFcn_pr2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_pr2 pgpu_fcn_pr_dpr = fcn_pr_dpr; + + pFCN_TEMPLATE_AF(pr_dpr , pFcn_pr2); + + /***************************************************************************************/ + /***************************************** vr ******************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_yukawa_v(x, 0, 3, cl, cnl) + fcn_spt_gauss_v(x, 3, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_yukawa_vd(x, 0, 3, cl, cnl, y, dy); + fcn_spt_gauss_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + const T ix = T(1)/x; + + T y = 0; + + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*erfc(cnl[ik]*x)*ix; + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T c_pii2 = 1.772453850905516027298; + const T ix = T(1)/x; + const T x2 = x*x; + + y = dy = 0; + + for(auto ik = 0; ik <6; ik++) + { + const auto yt = cl[ik]*erfc(cnl[ik]*x)*ix; + y += yt; + dy += (T(-2)*cl[ik]*cnl[ik]*exp(-cnl[ik]*cnl[ik]*x2)/c_pii2-yt)*ix; + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + const T ix = T(1)/x; + + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + y += cl[ik]*exp(-cnl[ik]*x)*ix*(T(2)/cnl[ik] + x); + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T ix = T(1)/x; + + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto yt = cl[ik]*exp(-cnl[ik]*x)*ix; + const auto icnl = T(1)/cnl[ik]; + y += yt*(T(2)*icnl + x); + dy += -yt*(T(2)*icnl*ix + T(2) + cnl[ik]*x); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + auto y = fcn_spt_gauss_v(x, 0, 5, cl, cnl); + y += cl[5]*exp(-cnl[5]*x)/x; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + const auto ix = T(1)/x; + const auto yt = cl[5]*exp(-cnl[5]*x)*ix; + y += yt; + dy += -(cnl[5]+ ix)*yt; + } + + /***************************************************************************************/ + template + using pFcn_vr1 = pFcn_clnl_3_1; + + template + GPU_EXEC pFcn_vr1 pgpu_fcn_vr = fcn_vr; + + pFCN_TEMPLATE_AF(vr, pFcn_vr1); + + /***************************************************************************************/ + template + using pFcn_vr2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_vr2 pgpu_fcn_vr_dvr = fcn_vr_dvr; + + pFCN_TEMPLATE_AF(vr_dvr , pFcn_vr2); + + /***************************************************************************************/ + /***************************************** vz ******************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + T fcn_vz(const T& x, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw) + { + return fcn_int_vz_z0_ze(x, z_0, z_e, cl, cnl, n_q, qx, qw, fcn_vr); + } + + template + CGPU_EXEC_INL + void fcn_vz_dvz(const T& x, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& y, T& dy) + { + fcn_int_vz_dvz_z0_ze(x, z_0, z_e, cl, cnl, n_q, qx, qw, y, dy, fcn_vr_dvr); + } + + /***************************************************************************************/ + template + using pFcn_vz1 = pFcn_clnl_8_1; + + template + GPU_EXEC pFcn_vz1 pgpu_fcn_vz = fcn_vz; + + pFCN_TEMPLATE_AF(vz, pFcn_vz1); + + /***************************************************************************************/ + template + using pFcn_vz2 = pFcn_clnl_8_2; + + template + GPU_EXEC pFcn_vz2 pgpu_fcn_vz_dvz = fcn_vz_dvz; + + pFCN_TEMPLATE_AF(vz_dvz , pFcn_vz2); + + /***************************************************************************************/ + /****************************************** vzp *****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + T y = 0; + + for(auto ik = 0; ik <3; ik++) + { + y += cl[ik]*bessel_k0(cnl[ik]*x); + } + + y += fcn_spt_gauss_v(x, 3, 6, cl, cnl); + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + y = dy = 0; + + for(auto ik = 0; ik <3; ik++) + { + y += cl[ik]*bessel_k0(cnl[ik]*x); + dy += -cl[ik]*cnl[ik]*bessel_k1(cnl[ik]*x); + } + + fcn_spt_gauss_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw) + { + return fcn_int_vz_ninfty_pinfty(x, cl, cnl, n_q, qx, qw, fcn_vr); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& y, T& dy) + { + fcn_int_vz_dvz_ninfty_pinfty(x, cl, cnl, n_q, qx, qw, y, dy, fcn_vr_dvr); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + y += cl[ik]*(T(2)*bessel_k0(cnl[ik]*x)/cnl[ik] + x*bessel_k1(cnl[ik]*x)); + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto k0 = bessel_k0(cnl[ik]*x); + const auto k1 = bessel_k1(cnl[ik]*x); + y += cl[ik]*(T(2)*k0/cnl[ik] + x*k1); + dy += -cl[ik]*(cnl[ik]*x*k0 + T(2)*k1); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + auto y = fcn_spt_gauss_v(x, 0, 5, cl, cnl); + y += cl[5]*bessel_k0(cnl[5]*x); + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + y += cl[5]*bessel_k0(cnl[5]*x); + dy += -cl[5]*cnl[5]*bessel_k1(cnl[5]*x); + } + + /***************************************************************************************/ + template + using pFcn_vzp1 = pFcn_clnl_3_1; + + template + GPU_EXEC pFcn_vzp1 pgpu_fcn_vzp = fcn_vzp; + + pFCN_TEMPLATE_AF(vzp, pFcn_vzp1); + + template + GPU_EXEC pFcn_clnl_6_1 pgpu_fcn_vzp_spec = fcn_vzp; + + pFCN_TEMPLATE_AF_SPEC(vzp, pFcn_clnl_6_1, eappt_weickenmeier_0_12); + + /***************************************************************************************/ + template + using pFcn_vzp2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_vzp2 pgpu_fcn_vzp_dvzp = fcn_vzp_dvzp; + + pFCN_TEMPLATE_AF(vzp_dvzp, pFcn_vzp2); + + template + GPU_EXEC pFcn_clnl_6_2 pgpu_fcn_vzp_dvzp_spec = fcn_vzp_dvzp; + + pFCN_TEMPLATE_AF_SPEC(vzp_dvzp, pFcn_clnl_6_2, eappt_weickenmeier_0_12); + } + } + + /* detector integration */ + namespace mt + { + namespace cgpu_detail_mt + { + /* integration over a detector ring */ + template + CGPU_EXEC_INL + void fcn_int_det_ring(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_min, const T& g2_max, Ctpr mx_i, KS& sum) + { + const auto g2 = grid.g2_sft(ix, iy); + if (mt::fcn_chk_bound(g2, g2_min, g2_max)) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += mx_i[ixy]; + } + } + + /* norm_2 integration over a detector ring */ + template + CGPU_EXEC_INL + void fcn_int_det_ring_norm_2(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_min, const T& g2_max, Ctpr mx_i, KS>& sum) + { + const auto g2 = grid.g2_sft(ix, iy); + if (mt::fcn_chk_bound(g2, g2_min, g2_max)) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += ::norm_2(mx_i[ixy]); + } + } + + /* integration over a detector with sensitivity */ + template + CGPU_EXEC_INL + void fcn_int_det_sen(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + Ctpr sen_i, Ctpr mx_i, KS& sum) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += sen_i[ixy]*mx_i[ixy]; + } + + /* norm_2 integration over a detector with sensitivity */ + template + CGPU_EXEC_INL + void fcn_int_det_sen_norm_2(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + Ctpr> sen_i, Ctpr mx_i, KS>& sum) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += sen_i[ixy]*::norm_2(mx_i[ixy]); + } + } + } + + /* wave propagation */ + namespace mt + { + namespace cgpu_detail_mt + { + /* propagate */ + template + CGPU_EXEC_INL + void fcn_fs_propagate(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g_0, const T& w_g2, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto theta = w_g2*grid.g2_sft(ix, iy, g_0); + + psi_o[ixy] = w*psi_i[ixy]*euler(theta); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + CGPU_EXEC_INL + void fcn_fs_propagate_bw_f(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g_0, const T& w_g2, const T& g2_cut, const T& alpha, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto theta = w_g2*grid.g2_sft(ix, iy, g_0); + const auto m = w*fcn_fermi_lpf(alpha, g2_cut, grid.g2_sft(ix, iy)); // bandwith limit does not mater if it includes till illumination + psi_o[ixy] = m*psi_i[ixy]*euler(theta); + } + + /* propagate and bandwith limit using a hard aperture */ + template + CGPU_EXEC_INL + void fcn_fs_propagate_bw_h(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g_0, const T& w_g2, const T& g2_cut, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto theta = w_g2*grid.g2_sft(ix, iy, g_0); + const auto m = ((grid.g2_sft(ix, iy) <= g2_cut))?w:T(0); // bandwith limit does not mater if it includes till illumination + psi_o[ixy] = m*psi_i[ixy]*euler(theta); + } + } + } + + /* probe - ctf - pctf */ + namespace mt + { + namespace cgpu_detail_mt + { + /* create probe */ + template + CGPU_EXEC_INL + complex fcn_fs_exp_i_chi(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const Lens& lens, + const R_2d& R, const R_2d& gu) + { + const auto gx = grid.gx_sft(ix) + gu.x; + const auto gy = grid.gy_sft(iy) + gu.y; + const auto g2 = gx*gx + gy*gy; + + complex v = 0; + + if (fcn_chk_bound(g2, lens.g2_inner, lens.g2_outer)) + { + const auto g4 = g2*g2; + const auto g6 = g4*g2; + const auto chi = R.x*gx + R.y*gy + lens.eval_c_10(g2) + lens.eval_c_30(g4) + lens.eval_c_50(g6); + + if (bb_phi) + { + const auto g =::sqrt(g2); + const auto g3 = g2*g; + const auto g5 = g4*g; + const auto phi = atan2(gy, gx); + chi += lens.eval_m(phi) + lens.eval_c_12(g2, phi); + chi += lens.eval_c_21_c_23(g3, phi) + lens.eval_c_32_c_34(g4, phi); + chi += lens.eval_c_41_c_43_c_45(g5, phi) + lens.eval_c_52_c_54_c_56(g6, phi); + } + + v = euler(chi); + } + + return v; + } + + /* create probe */ + template + CGPU_EXEC_INL + void fcn_fs_probe(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const Lens& lens, + const R_2d& r, const R_2d& gu, complex* psi_o) + { + const auto v = fcn_fs_exp_i_chi(ix, iy, grid, lens, r, gu); + + const auto ixy = grid.sub_2_ind(ix, iy); + psi_o[ixy] = v; + } + + /* apply coherent transfer function */ + template + CGPU_EXEC_INL + void fcn_fs_apply_ctf(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, complex* psi_i, + const Lens& lens, const R_2d& gu, complex* psi_o) + { + const auto v = fcn_fs_exp_i_chi(ix, iy, grid, lens, R_2d(), gu); + + const auto ixy = grid.sub_2_ind(ix, iy); + psi_o[ixy] = v*psi_i[ixy]; + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + CGPU_EXEC_INL + void fcn_fs_apply_pctf(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, complex* psi_i, + const Lens& lens, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto g2 = grid.g2_sft(ix, iy); + + if (fcn_chk_bound(g2, lens.g2_inner, lens.g2_outer)) + { + const auto c_pi = T(3.141592653589793238463); + + const auto chi = lens.eval_c_10(g2) + lens.eval_c_30(g2*g2); + const auto c_u = c_pi*lens.spt_inc_theta_c*lens.tp_inc_iehwgd; + const auto u = T(1) + T(2)*c_u*c_u*g2; + + const auto c_tp = c_pi*lens.tp_inc_iehwgd*lens.lambda*g2; + const auto tp_inc = T(0.5)*c_tp*c_tp*g2*g2; + + const auto c_spt = c_pi*lens.spt_inc_iehwgd*(lens.c_30*lens.lambda_2*g2-lens.c_10); + const auto spt_inc = c_spt*c_spt*g2; + + const auto st_inc = exp(-(spt_inc + tp_inc)/u); // sqrt(u); + + psi_o[ixy] = psi_i[ixy]*polar(st_inc, chi); + } + else + { + psi_o[ixy] = T(0); + } + } + } + } + + /* transmission function */ + namespace mt + { + namespace cgpu_detail_mt + { + template + CGPU_EXEC_INL + void fcn_trans_fcn(const dt_int32& ix, const iGrid_1d& igrid, Ctpr* vzp_i, const T& w, complex* tfcn_o) + { + const auto ind = igrid.sub_2_ind(ix); + + if (esim == eesim_weak_phase_object) + { + tfcn_o[ind] =complex(T(1), w*vzp_i[ind]); + } + else + { + tfcn_o[ind] =euler(w*vzp_i[ind]); + } + } + } + } + + /* eels */ + namespace mt + { + namespace cgpu_detail_mt + { + template + CGPU_EXEC_INL + void fcn_eels_lorentz_norm_factor(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& gc2, const T& ge2, KS& sum) + { + const auto g2 = grid.g2_sft(ix, iy); + if (g2 < gc2) + { + sum += T(1)/(g2 + ge2); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_xyz(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const EELS& eels, Tpr> w_x, Tpr> w_y, Tpr> w_z) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_x[ixy] = gx*lorentz*pos; + w_y[ixy] = gy*lorentz*pos; + w_z[ixy] = eels.ge*lorentz*pos; + } + else + { + w_x[ixy] = complex(0); + w_y[ixy] = complex(0); + w_z[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_x(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_x) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_x[ixy] = gx*lorentz*pos; + } + else + { + w_x[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_y(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_y) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_y[ixy] = gy*lorentz*pos; + } + else + { + w_y[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_z(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_z) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_z[ixy] = eels.ge*lorentz*pos; + } + else + { + w_z[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_mn1(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_mn1) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto c_i2i2 = T(0.70710678118654746); + + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = c_i2i2*eels.factor/(g2 + eels.ge2); + w_mn1[ixy] = complex(gx, -gy)*lorentz*pos; + } + else + { + w_mn1[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_mp1(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_mp1) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto c_i2i2 = T(0.70710678118654746); + + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = c_i2i2*eels.factor/(g2 + eels.ge2); + w_mp1[ixy] = complex(gx, gy)*lorentz*pos; + } + else + { + w_mp1[ixy] = complex(0); + } + } + } + } + +#endif diff --git a/src - Copy (2)/cgpu_fcns.cuh b/src - Copy (2)/cgpu_fcns.cuh new file mode 100755 index 00000000..09e89fa4 --- /dev/null +++ b/src - Copy (2)/cgpu_fcns.cuh @@ -0,0 +1,89 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_FCNS_H + #define CGPU_FCNS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_vctr.cuh" + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + namespace mt + { + // snr using squared difference + template + Value_type_r fcn_snr_ma2(TVctr& mx_i, TVctr& M_r) + { + using T = Value_type; + + auto ma1_r = fcn_variance(M_r); + + TVctr M_n(mx_i.size()); + for(auto ik = 0; ik + Value_type_r fcn_snr_ma1(TVctr& mx_i, TVctr& M_r) + { + using T = Value_type; + + auto ma1_r = fcn_moment_1a(M_r); + + TVctr M_n(mx_i.size()); + for(auto ik = 0; ik + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_FCNS_GEN_H + #define CGPU_FCNS_GEN_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + + #include "macros.cuh" + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + + /********************************* simple functions ************************************/ + /********** static member function are not supported for the cuda compiler *************/ + /***************************************************************************************/ + //template + //CGPU_EXEC + //T fill_nzero(const T& r) // for R_2d and R_3d compatibility + //{ + // return r; + //} + + + /* is equal */ + namespace mt + { + template + CGPU_EXEC_INL + dt_bool fcn_is_equal(const T& a, const T& b) + { + return a == b; + } + + template <> + CGPU_EXEC_INL + dt_bool fcn_is_equal(const dt_int32& a, const dt_int32& b) + { + return a == b; + } + + template <> + CGPU_EXEC_INL + dt_bool fcn_is_equal(const dt_float32 &a, const dt_float32 &b) + { + const dt_float32 eps_abs = 1e-5f; + const dt_float32 eps_rel = 1e-4f; + + // check if the numbers are really close -- needed when comparing numbers near zero. + dt_float32 diff = fabs(a - b); + if (diff <= eps_abs) + return true; + + // otherwise fall back to Knuth's algorithm + return diff <= ((fabs(a) + CGPU_EXEC_INL + dt_bool fcn_is_equal(const dt_float64 &a, const dt_float64 &b) + { + const dt_float64 eps_abs = 1e-13; + const dt_float64 eps_rel = 1e-8; + + // check if the numbers are really close -- needed when comparing numbers near zero. + dt_float64 diff = fabs(a - b); + if (diff <= eps_abs) + return true; + + // otherwise fall back to Knuth's algorithm + return diff <= ((fabs(a) + CGPU_EXEC_INL + dt_bool fcn_is_zero(const T& x) + { + return fcn_is_equal(x, T(0)); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_zero(const T& x, const TArg&... arg) + { + return fcn_is_zero(x) && fcn_is_zero(arg...); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_nzero(const T& x) + { + return !fcn_is_equal(x, T(0)); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_nzero(const T& x, const TArg&... arg) + { + return fcn_is_nzero(x) && fcn_is_nzero(arg...); + } + } + + /* is one */ + namespace mt + { + template + CGPU_EXEC_INL + dt_bool fcn_is_one(const T& x) + { + return fcn_is_equal(x, T(1)); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_one(const T& x, const TArg&... arg) + { + return fcn_is_one(x) && fcn_is_one(arg...); + } + } + + /* if else zero */ + namespace mt + { + template + CGPU_EXEC + T fcn_set_zero_eps(const T& x) + { + return (fcn_is_zero(x))?T(0):x; + } + + template + CGPU_EXEC + T fcn_ifzero(const T& x, const T& x_t, const T& x_f) + { + return (fcn_is_zero(x))?x_t:x_f; + } + + template + CGPU_EXEC + T fcn_ifnzero(const T& x, const T& x_t, const T& x_f) + { + return (fcn_is_nzero(x))?x_t:x_f; + } + } + + /* div/min/max */ + namespace mt + { + template + CGPU_EXEC + T fcn_div(const T& x, const U& y) + { + return (fcn_is_zero(y))?T(0):x/static_cast(y); + } + + template + CGPU_EXEC + T fcn_min(const T& x, const T& y) + { + return (x + CGPU_EXEC + T fcn_max(const T& x, const T& y) + { + return (x>y)?x:y; + } + } + + /* check bounds */ + namespace mt + { + template + CGPU_EXEC + dt_bool fcn_chk_bound(const T& x, const T& x_min, const T& x_max) + { + return (x_min <= x) && (x < x_max); + } + + // template + // CGPU_EXEC + // dt_bool fcn_chk_bound(const T& x, const T& x_min, const T& x_max, const TArg&... arg) + // { + // return fcn_chk_bound(x, x_min, x_max) && fcn_chk_bound(x, arg...); + // } + + template + CGPU_EXEC + dt_bool fcn_chk_bound_eps(const T& x, const T& x_min, const T& x_max) + { + const T eps = epsilon_abs(); + return (x_min - eps <= x) && (x < x_max + eps); + } + + template + CGPU_EXEC + dt_bool fcn_chk_bound_eps(const T& x, const T& x_min, const T& x_max, const TArg&... arg) + { + return fcn_chk_bound_eps(x, x_min, x_max) && fcn_chk_bound_eps(arg...); + } + } + + /* set bounds */ + namespace mt + { + template + CGPU_EXEC + enable_if_float + fcn_set_bound(const T& x, const T& x_min, const T& x_max) + { + return ::fmax(x_min, ::fmin(x_max, x)); + } + + template + CGPU_EXEC + enable_if_int + fcn_set_bound(const T& x, const T& x_min, const T& x_max) + { + return (x<=x_min)?x_min:(x>=x_max)?x_max:x; + } + } + + /* locate index: floor/ceil/pbc */ + namespace mt + { + // ! apply periodic boundary conditions to index + template + CGPU_EXEC + ST fcn_ind_pbc(const ST& ix, const ST& nx) + { + return ix - static_cast(::floor(T(ix)/T(nx)))*nx; + } + + // ! cast floor + template + CGPU_EXEC + ST fcn_cfloor(const T& x) + { + return static_cast(::floor(x)); + } + + // ! cast ceil + template + CGPU_EXEC + ST fcn_cceil(const T& x) + { + return static_cast(::ceil(x)); + } + + // ! bound cast floor + template + CGPU_EXEC + U fcn_bcfloor(const T& x, const U& ix_min, const U& ix_max) + { + return fcn_set_bound(fcn_cfloor(x), ix_min, ix_max); + } + + // ! bound cast ceil + template + CGPU_EXEC + U fcn_bcceil(const T& x, const U& ix_min, const U& ix_max) + { + return fcn_set_bound(fcn_cceil(x), ix_min, ix_max); + } + + // get index and distance + template + CGPU_EXEC + void fcn_get_idx_0_idx_n(const T& x, const T& x_max, const T& dx, const dt_bool& pbc, const ST& nx, ST& ix_0, ST& ix_n) + { + ix_0 = fcn_cfloor((x - x_max)/dx); + auto ix_e = fcn_cceil((x + x_max)/dx); + + if (!pbc) + { + ix_0 = fcn_set_bound(ix_0, ST(0), nx); + ix_e = fcn_set_bound(ix_e, ST(0), nx); + } + + ix_n = (ix_0 == ix_e)?ST(0):(ix_e - ix_0 + 1); + } + } + + /* index search */ + namespace mt + { + template + CGPU_EXEC + dt_int32 fcn_r_2_ir_b_by_fcn(TFcn fcn, const T& x, dt_int32 ix_min, dt_int32 ix_max) + { + do + { + const dt_int32 ix_m = (ix_min + ix_max) >> 1; // divide by 2 + + if (x <= fcn(ix_m)) + ix_max = ix_m; + else + ix_min = ix_m; + } while ((ix_max - ix_min) > 1); + + if (x >= fcn(ix_max)) + return ix_max; + else + return ix_min; + } + + template + CGPU_EXEC + dt_int32 fcn_r_2_ir_by_vctr(T* xv, const T& x, dt_int32 ix_min, dt_int32 ix_max) + { + do { + const dt_int32 ix_m = (ix_min + ix_max) >> 1; // divide by 2 + + if (x <= xv[ix_m]) + ix_max = ix_m; + else + ix_min = ix_m; + } while ((ix_max - ix_min) > 1); + + if (x >= xv[ix_max]) + return ix_max; + else + return ix_min; + } + + template + CGPU_EXEC + dt_int32 fcn_r_2_ir_b_by_vctr(T* xv, const T& x, dt_int32 ix_min, dt_int32 ix_max) + { + if (x > xv[ix_max]) + return -2; + else if (x < x[ix_min]) + return -1; + + return fcn_r_2_ir_by_vctr(xv, x, ix_min, ix_max); + } + } + + /* find root */ + namespace mt + { + template + CGPU_EXEC + T fcn_fd_root(T x_0, T x_e, const T& Tol, const dt_int32& it_max, TFcn fcn) + { + dt_int32 it = 0; + T x, fx, fx_e = fcn(x_e); + + do + { + x = 0.5*(x_0 + x_e); + fx = fcn(x); + + if (fx*fx_e<0) + { + x_0 = x; + } + else + { + x_e = x; + fx_e = fx; + } + it++; + } while ((::fabs(fx)>Tol) && (it < it_max)); + + return x; + } + } + + /* point 2 line 2d*/ + namespace mt + { + // ax + by + c = 0 + // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line + + // distance from point to line + template + CGPU_EXEC + T fcn_pt_2_ln_dist(const T& a, const T& b, const T& c, const T& x0, const T& y0) + { + return ::fabs(a*x0 + b*y0 + c)/::sqrt(a*a + b*b); + } + + // calculate intersection from point to line + template + CGPU_EXEC + void fcn_pt_2_ln_intxn_2d(const T& a, const T& b, const T& c, const T& x0, const T& y0, const T& x, const T& y) + { + auto m = ::sqrt(a*a + b*b); + + x = (b*(b*x0-a*y0)-a*c)/m; + y = -(a*(b*x0-a*y0)-b*c)/m; + } + } + + /* length of curve */ + namespace mt + { + template + CGPU_EXEC + T fcn_get_len_crv(dt_int32 ix_0, dt_int32 ix_e, Ctpr x, Ctpr y) + { + T ln = 0; + for(auto ik = ix_0; ik < ix_e-1; ik++) + { + const T dx = x[ik + 1] - x[ik]; + const T dy = y[ik + 1] - y[ik]; + ln = ln + ::sqrt(dx*dx + dy*dy); + } + + return ln; + } + + template + CGPU_EXEC + T fcn_get_len_crv(dt_int32 ix_0, dt_int32 ix_e, Ctpr x, Ctpr y, const T& ln_max, dt_int32& iln) + { + T ln = 0; + + if (ix_0 < ix_e) + { + iln = ix_e; + for(auto ik = ix_0; ik < ix_e-1; ik++) + { + const T dx = x[ik + 1] - x[ik]; + const T dy = y[ik + 1] - y[ik]; + ln = ln + ::sqrt(dx*dx + dy*dy); + if ((ln_max > 0) && (ln >= ln_max)) + { + iln = ik; + break; + } + } + } + else + { + iln = ix_e; + for(auto ik = ix_0; ik > ix_e; ik--) + { + const T dx = x[ik] - x[ik-1]; + const T dy = y[ik] - y[ik-1]; + ln = ln + ::sqrt(dx*dx + dy*dy); + if ((ln_max > 0) && (ln >= ln_max)) + { + iln = ik; + break; + } + } + } + + return ln; + } + + // get index to maximum distance + template + CGPU_EXEC + T fcn_get_max_crv_2_ln_dist(const T& x_1, const T& y_1, const T& x_2, const T& y_2, dt_int32 ix_0, dt_int32 ix_e, Tpr x, Tpr y, dt_int32& ind_max) + { + const T m = ::sqrt(::square(x_2 - x_1) + ::square(y_2 - y_1)); + const T a = (y_2 - y_1)/m; + const T b = -(x_2 - x_1)/m; + const T c = (x_2*y_1 - y_2*x_1)/m; + + T d_max = 0; + ind_max = 0; + for(auto ik = ix_0; ik < ix_e; ik++) + { + const T d = ::fabs(a*x[ik] + b*y[ik] + c); + if (d > d_max) + { + d_max = d; + ind_max = ik; + } + } + + return d_max; + } + } + + /* Kahan summation algorithm*/ + namespace mt + { + // https:// en.wikipedia.org/wiki/Kahan_summation_algorithm + template + CGPU_EXEC + void fcn_kh_sum(T& sum, T val, T& error) + { + val = val - error; + const auto t = sum + val; + error = (t-sum) - val; + sum = t; + } + } + + /* tapering/cosine */ + namespace mt + { + // ! calculate fermi low-pass filter alpha parameter + template + CGPU_EXEC + T fcn_coef_tap(const T& r_tap, const T& r_max) + { + // y = cos(coef_tap*(x-x_tap)) + const auto c_i2pi = T(1.570796326794896619231); // pi/2 + return (fcn_is_equal(r_tap, r_max))?T(0):c_i2pi/(r_max - r_tap); + } + + // ! calculate fermi low-pass filter alpha parameter + template + CGPU_EXEC + T fcn_fermi_lpf_alpha(const T& r_cut, const T& dr_0=T(0.25), const T& fr_0=T(1e-02)) + { + // y = 1/(1+exp(alpha*(x^2-x_c^2))) + return log(T(1)/fr_0-T(1))/(::square(r_cut+dr_0)-::square(r_cut)); + } + + // ! fermi low-pass filter value + template + CGPU_EXEC + T fcn_fermi_lpf(const T& alpha, const T& gl2_max, const T& g2) + { + // y = 1/(1+exp(alpha*(x^2-x_c^2))) + return T(1)/(T(1) + ::exp(alpha*(g2 - gl2_max))); + } + + // ! cosine tapering + template + CGPU_EXEC + T fcn_cos_tap(const T& x_tap, const T& coef_tap, const T& x) + { + return (x + CGPU_EXEC + void fcn_apply_cos_tap(const T& x_tap, const T& coef_tap, const T& x, T& y, T& dy) + { + if (x_tap FFT ->exp(2*pi^2*sigma_r^2*g^2) + template + CGPU_EXEC + T fcn_sigma_r_2_sigma_g(const T& sigma_g) + { + return T(1)/(T(6.283185307179586476925)*sigma_g); + } + + // ! plane wave exponential factor + template + CGPU_EXEC + T fcn_n_2pi_sft(const T& x, const T& x_c) + { + return -T(6.283185307179586476925)*(x-x_c); + } + + // in: E_0(keV), Output: lambda (electron wave): Angs + // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 + template + CGPU_EXEC + T fcn_lambda(const T& E_0) + { + const auto emass = T(510.99906); + const auto hc = T(12.3984244); + + return hc/::sqrt(E_0*(T(2)*emass + E_0)); + } + + // in: E_0(keV), Output: gamma(relativistic factor): unitless + // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 + template + CGPU_EXEC + T fcn_gamma(const T& E_0) + { + const auto emass = T(510.99906); + + return T(1) + E_0/emass; + } + + // in: E_0(keV), Output: sigma (Interaction parameter): radians/(kV - Angs) + // E. J. Kirkland - Advanced computing in electron microscopy page: 79 + template + CGPU_EXEC + T fcn_elec_interact_parm_kva(const T& E_0) + { + const auto c_2pi = T(6.283185307179586476925); + const auto emass = T(510.99906); + T x = (emass + E_0)/(T(2)*emass + E_0); + + return c_2pi*x/(fcn_lambda(E_0)*E_0); + } + + // in: E_0(keV), Theta, Output: sigma = gamma*lambda/c_pot_factor: radians/(V - Angs), where c_pot_factor = 47.877645145863056 + // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13, 79, 120 + + template + CGPU_EXEC + T fcn_transf_exp_factor(const T& E_0, const T& theta) + { + return T(1e-3)*fcn_elec_interact_parm_kva(E_0)/::cos(theta); + } + + // reciprocal Angs to radians + // in: theta(mrad), E_0(keV), Output: Angs^-1 + template + CGPU_EXEC + T fcn_rangs_2_rad(const T& E_0, const T& rAngs) + { + return ::asin(rAngs*fcn_lambda(E_0)); + } + + // in: theta(mrad), E_0(keV), Output: Angs^-1 + template + CGPU_EXEC + T fcn_rad_2_rangs(const T& E_0, const T& theta) + { + return ::sin(theta)/fcn_lambda(E_0); + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // hwhm: Half width at half maximum + // sigma: standard deviation + template + CGPU_EXEC + T fcn_hwhm_2_sigma(const T& v) + { + const auto c_hwhm_2_sigma = T(0.84932180028801907); // hwhm to sigma 1/(sqrt(2*log(2))) + + return v*c_hwhm_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // fwhm: Full width at half maximum + // sigma: standard deviation + template + CGPU_EXEC + T fcn_fwhm_2_sigma(const T& v) + { + const auto c_fwhm_2_sigma = T(0.42466090014400953); // fwhm to sigma 1/(2*sqrt(2*log(2))) + + return v*c_fwhm_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // iehwgd: e^-1 half-width value of the Gaussian distribution + // sigma: standard deviation + template + CGPU_EXEC + T fcn_iehwgd_2_sigma(const T& v) + { + const auto c_iehwgd_2_sigma = T(0.70710678118654746); // iehwgd to sigma 1/sqrt(2) + + return v*c_iehwgd_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // sigma: standard deviation + template + CGPU_EXEC + T fcn_rad_2_sigma(const T& E_0, const T& theta) + { + const auto q0 = fcn_rad_2_rangs(E_0, theta); + return fcn_iehwgd_2_sigma(q0); + } + + // E. J. Kirkland - Advanced computing in electron microscopy page: 33 + template + CGPU_EXEC + T fcn_scherzer_defocus(const T& E_0, const T& c_30, T n=1.0) + { + n = ::fmax(n, 1); + const auto lambda = fcn_lambda(E_0); + + return -::copysign(::sqrt((T(2)*n-T(0.5))*::fabs(c_30)*lambda), c_30); + } + + // E. J. Kirkland - Advanced computing in electron microscopy page: 33 + template + CGPU_EXEC + T fcn_scherzer_aperture(const T& E_0, const T& c_30, T n=1.0) + { + n = ::fmax(n, 1); + const auto lambda = fcn_lambda(E_0); + return ::pow(T(4)*(T(2)*n-T(0.5))*lambda/::fabs(c_30), T(0.25)); + } + + // E. J. Kirkland - Advanced computing in electron microscopy page: 33 + template + CGPU_EXEC + void fcn_scherzer_conditions(const T& E_0, const T& c_30, T& defocus, T& aperture) + { + defocus = fcn_scherzer_defocus(E_0, c_30); + + aperture = fcn_scherzer_aperture(E_0, c_30); + } + } + + namespace mt + { + // ceil - scale size + template + CGPU_EXEC + dt_int32 fcn_sc_size_c(const dt_int32& n, T factor) + { + return max(dt_int32(::ceil(n*factor)), 1); + } + + // ! next power of 2 + CGPU_EXEC + dt_uint64 fcn_next_pow2(dt_uint32 x) + { + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return ++x; + } + + // from bytes to mb + template + CGPU_EXEC + dt_float64 fcn_size_mb(const dt_int64& n) + { + return static_cast(n*sizeof(T)/dt_float64(c_bytes_2_mb)); + } + + // select background option + template + T fcn_select_bg(const eFil_Sel_Typ& bg_opt, const T& v_min, const T& v_max, const T& v_mean, T bg =0) + { + T bg_r = 0; + + switch (bg_opt) + { + case efst_min: + bg_r = v_min; + break; + case efst_max: + bg_r = v_max; + break; + case efst_mean: + bg_r = v_mean; + break; + case efst_min_mean: + bg_r = (v_mean + v_min)/T(2); + break; + case efst_max_mean: + bg_r = (v_mean + v_max)/T(2); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + + template + dt_init_list fcn_read_col(T* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + switch(n_c) + { + case 1: + { + return {T(v[ip + 0*n_r])}; + } + case 2: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r])}; + } + case 3: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r])}; + } + case 4: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r])}; + } + case 5: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r])}; + } + case 6: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r])}; + } + case 7: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r])}; + } + case 8: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r]), T(v[ip + 7*n_r])}; + } + case 9: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r]), T(v[ip + 7*n_r]), T(v[ip + 8*n_r])}; + } + case 10: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r]), T(v[ip + 7*n_r]), T(v[ip + 8*n_r]), T(v[ip + 9*n_r])}; + } + } + } + + } + + /* strings */ + namespace mt + { + static inline + std::vector fcn_str_split(const std::string& s, char delimiter) + { + std::vector string_elems; + std::istringstream tokenStream(s); + std::string token; + + while (std::getline(tokenStream, token, delimiter)) + { + string_elems.push_back(token); + } + return string_elems; + } + + // to lowercase (in place) + static inline + void fcn_str_2_lower_ip(std::string& str) + { + std::for_each(str.begin(), str.end(), [](auto &v){ v = tolower(v); }); + } + + // to lowercase + static inline + std::string fcn_str_2_lower(std::string str) + { + fcn_str_2_lower_ip(str); + return str; + } + + // to uppercase (in place) + static inline + void fcn_str_2_upper_ip(std::string& str) + { + std::for_each(str.begin(), str.end(), [](auto &v){ v = toupper(v); }); + } + + // to uppercase + static inline + std::string fcn_str_2_upper(std::string str) + { + fcn_str_2_upper_ip(str); + return str; + } + + // trim from start (in place) + static inline + void fcn_str_ltrim_ip(std::string &s) { + s.erase(s.begin(), std::find_if (s.begin(), s.end(), [](dt_int32 ch) + { + return !std::isspace(ch); + })); + } + + // trim from start + static inline + std::string fcn_str_ltrim(std::string s) + { + fcn_str_ltrim_ip(s); + return s; + } + + // trim from end (in place) + static inline + void fcn_str_rtrim_ip(std::string &s) + { + s.erase(std::find_if(s.rbegin(), s.rend(), [](dt_int32 ch) + { + return !std::isspace(ch); + }).base(), s.end()); + } + + // trim from end + static inline + std::string fcn_rtrim(std::string s) + { + fcn_str_rtrim_ip(s); + return s; + } + + // trim from both ends (in place) + static inline + void fcn_str_trim_ip_ip(std::string &s) + { + fcn_str_ltrim_ip(s); + fcn_str_rtrim_ip(s); + } + + // trim from both ends + static inline + std::string fcn_str_trim(std::string s) + { + fcn_str_trim_ip_ip(s); + return s; + } + + // Compare string + static inline + dt_bool fcn_str_cmp(const std::string &s1, const std::string &s2) + { + return (s1.find(s2) != std::string::npos); + } + + void fcn_str_rem_char_not_of(std::string &str, std::string chars) + { + str.erase(remove_if (str.begin(), str.end(), [chars](const auto& v){ return std::all_of(chars.begin(), chars.end(), [v](const auto& a){return a != v; }); }), str.end() ); + } + + void fcn_str_rem_char_of(std::string &str, std::string chars) + { + str.erase(remove_if (str.begin(), str.end(), [chars](const auto& v){ return std::any_of(chars.begin(), chars.end(), [v](const auto& a){return a == v; }); }), str.end() ); + } + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cgpu_fft.cuh b/src - Copy (2)/cgpu_fft.cuh new file mode 100755 index 00000000..cecfe545 --- /dev/null +++ b/src - Copy (2)/cgpu_fft.cuh @@ -0,0 +1,671 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_FFT_H + #define CGPU_FFT_H + + #include + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + #include "macros.cuh" + #include "const_enum.cuh" + #include "math.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_stream.cuh" + + /* cpu fourier transform */ + namespace mt + { + template class FFT; + + template <> + class FFT + { + public: + using value_type = dt_float32; + static const eDev device = edev_cpu; + + using TVctr_c = Vctr, edev_cpu>; + + FFT(): plan_forward(nullptr), plan_backward(nullptr) + { + fftwf_init_threads(); + } + + FFT(const dt_int32& s0, Stream_cpu* pstream = nullptr): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_1d(s0, n_thread); + } + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_cpu* pstream = nullptr): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_2d(s0, s1, n_thread); + } + + ~FFT() + { + destroy_plan(); + } + + void cleanup() + { + destroy_plan(); + + fftwf_cleanup_threads(); + } + + void destroy_plan() + { + if (plan_backward == nullptr) + { + return; + } + + fftwf_destroy_plan(plan_forward); + fftwf_destroy_plan(plan_backward); + + plan_backward = plan_forward = nullptr; + } + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_1d.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0); + + auto pdata = M.data_cast(); + + plan_forward = fftwf_plan_dft_1d(s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_dft_1d(s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_1d.wisdom"); + } + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_1d_batch.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_many = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_1d_batch.wisdom"); + } + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_2d.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + plan_forward = fftwf_plan_dft_2d(s1, s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_dft_2d(s1, s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d.wisdom"); + } + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread=1) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_2d_batch.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1*s2); + + auto pdata = M.data_cast(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_many = s2; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d_batch.wisdom"); + } + + void forward(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftwf_execute_dft(plan_forward, pdata, pdata); + } + + void inverse(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftwf_execute_dft(plan_backward, pdata, pdata); + } + + void forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + forward(mx_o); + } + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + inverse(mx_o); + } + private: + fftwf_plan plan_forward; + fftwf_plan plan_backward; + }; + + template <> + class FFT + { + public: + using value_type = dt_float64; + static const eDev device = edev_cpu; + + using TVctr_c = Vctr, edev_cpu>; + + FFT(): plan_forward(nullptr), plan_backward(nullptr) + { + fftw_init_threads(); + } + + FFT(const dt_int32& s0, Stream_cpu* pstream = nullptr): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_1d(s0, n_thread); + } + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_cpu* pstream = nullptr): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_2d(s0, s1, n_thread); + } + + ~FFT() + { + destroy_plan(); + } + + void cleanup() + { + destroy_plan(); + + fftw_cleanup_threads(); + } + + void destroy_plan() + { + if (plan_backward == nullptr) + { + return; + } + + fftw_destroy_plan(plan_forward); + fftw_destroy_plan(plan_backward); + + plan_backward = plan_forward = nullptr; + } + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1) + { + destroy_plan(); + + fftw_import_wisdom_from_filename("fftw_1d.wisdom"); + + fftw_plan_with_nthreads(n_thread); + + TVctr_c M(s0); + + auto pdata = M.data_cast(); + + plan_forward = fftw_plan_dft_1d(s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_dft_1d(s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftw_export_wisdom_to_filename("fftw_1d.wisdom"); + } + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + fftw_import_wisdom_from_filename("fftw_1d_batch.wisdom"); + + fftw_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_many = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftw_export_wisdom_to_filename("fftw_1d_batch.wisdom"); + } + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + fftw_import_wisdom_from_filename("fftw_2d.wisdom"); + + fftw_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + plan_forward = fftw_plan_dft_2d(s1, s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_dft_2d(s1, s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftw_export_wisdom_to_filename("fftw_2d.wisdom"); + } + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread=1) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftw_2d_batch.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1*s2); + + auto pdata = M.data_cast(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_many = s2; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d_batch.wisdom"); + } + + void forward(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftw_execute_dft(plan_forward, pdata, pdata); + } + + void inverse(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftw_execute_dft(plan_backward, pdata, pdata); + } + + void forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + forward(mx_o); + } + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + inverse(mx_o); + } + private: + fftw_plan plan_forward; + fftw_plan plan_backward; + }; + } + + /* gpu fourier transform */ + namespace mt + { + #ifdef __CUDACC__ + template <> + class FFT + { + public: + using value_type = dt_float32; + static const eDev device = edev_gpu; + + using TVctr_c = Vctr, edev_gpu>; + + FFT(): plan_forward(0), plan_backward(0) {} + + FFT(const dt_int32& s0, Stream_gpu* pstream = nullptr): FFT() + { + create_plan_1d(s0); + } + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_gpu* pstream = nullptr): FFT() + { + create_plan_2d(s0, s1); + } + + ~FFT() + { + destroy_plan(); + } + + void cleanup() + { + destroy_plan(); + } + + void destroy_plan() + { + if (plan_backward == 0) + { + return; + } + + cudaDeviceSynchronize(); + + cufftDestroy(plan_forward); + plan_backward = plan_forward = 0; + } + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1) + { + destroy_plan(); + + cufftPlan1d(&plan_forward, s0, CUFFT_C2C, 1); + + plan_backward = plan_forward; + } + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_many = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, how_many); + + plan_backward = plan_forward; + } + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + // https:// docs.nvidia.com/cuda/cufft/index.html + cufftPlan2d(&plan_forward, s1, s0, CUFFT_C2C); + + plan_backward = plan_forward; + } + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& nz, dt_int32 n_thread=1) + { + destroy_plan(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_many = nz; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, how_many); + + plan_backward = plan_forward; + } + + void set_stream(cudaStream_t &stream) + { + cufftSetStream(plan_forward, stream); + } + + void forward(TVctr_c& mx) + { + forward(mx, mx); + } + + void inverse(TVctr_c& mx) + { + inverse(mx, mx); + } + + void forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecC2C(plan_forward, pdata_i, pdata_o, CUFFT_FORWARD); + } + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecC2C(plan_backward, pdata_i, pdata_o, CUFFT_INVERSE); + } + private: + cufftHandle plan_forward; + cufftHandle plan_backward; + }; + + template <> + class FFT + { + public: + using value_type = dt_float64; + static const eDev device = edev_gpu; + + using TVctr_c = Vctr, edev_gpu>; + + FFT(): plan_forward(0), plan_backward(0) {} + + FFT(const dt_int32& s0, Stream_gpu* pstream = nullptr): FFT() + { + create_plan_1d(s0); + } + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_gpu* pstream = nullptr): FFT() + { + create_plan_2d(s0, s1); + } + + ~FFT() + { + destroy_plan(); + } + + void cleanup() + { + destroy_plan(); + } + + void destroy_plan() + { + if (plan_backward == 0) + { + return; + } + + cudaDeviceSynchronize(); + + cufftDestroy(plan_forward); + plan_backward = plan_forward = 0; + } + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1) + { + destroy_plan(); + + cufftPlan1d(&plan_forward, s0, CUFFT_Z2Z, 1); + + plan_backward = plan_forward; + } + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_mas0 = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_Z2Z, how_mas0); + + plan_backward = plan_forward; + } + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1) + { + destroy_plan(); + + // https:// docs.nvidia.com/cuda/cufft/index.html + cufftPlan2d(&plan_forward, s1, s0, CUFFT_Z2Z); + + plan_backward = plan_forward; + } + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread=1) + { + destroy_plan(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_mas0 = s2; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_Z2Z, how_mas0); + + plan_backward = plan_forward; + } + + void forward(TVctr_c& mx) + { + forward(mx, mx); + } + + void inverse(TVctr_c& mx) + { + inverse(mx, mx); + } + + void forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecZ2Z(plan_forward, pdata_i, pdata_o, CUFFT_FORWARD); + } + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecZ2Z(plan_backward, pdata_i, pdata_o, CUFFT_INVERSE); + } + private: + cufftHandle plan_forward; + cufftHandle plan_backward; + }; + #endif + } + + /* derive classes */ + namespace mt + { + /***************************************************************************************/ + /************************************ alias ********************************************/ + /***************************************************************************************/ + template + using FFT_cpu = FFT; + + template + using FFT_gpu = FFT; + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cgpu_info.cuh b/src - Copy (2)/cgpu_info.cuh new file mode 100755 index 00000000..62e96ba6 --- /dev/null +++ b/src - Copy (2)/cgpu_info.cuh @@ -0,0 +1,420 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_INFO_H + #define CGPU_INFO_H + + #ifdef _WIN32 + #include + + #elif defined __APPLE__ + #include + #include + #include + #include + #include + + #else + #include + #include + #include + #endif + + #include + #include + #include + #include + #include + + #include "const_enum.cuh" + #include "cgpu_vctr.cuh" + + #ifdef __CUDACC__ + #include + #include + #endif + + namespace mt + { + class Cpu_Info + { + public: + dt_int32 n_proc; // number of cores + dt_int32 n_threads; // number of threads + dt_float64 tot_mem; // size in Mb + dt_float64 free_mem; // size in Mb + + Cpu_Info(): n_proc(0), n_threads(0), + tot_mem(0), free_mem(0) {} + }; + + class Gpu_Info + { + public: + dt_int32 id; // gpu id + std::string name; // gpu name + dt_int32 comp_cap; // compute capability + dt_float64 tot_mem; // size in Mb + dt_float64 free_mem; // size in Mb + + Gpu_Info(): id(0), name(""), comp_cap(0), + tot_mem(0), free_mem(0) {} + }; + + /* device info */ + namespace dev_info + { + void cpu_tot_free_mem(dt_float64 &tot, dt_float64 &free) + { + const dt_float64 s_bytes_2_mb(c_bytes_2_mb); + + #if defined(_WIN32) + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + GlobalMemoryStatusEx(&status); + free = static_cast(status.ullAvailPhys)/s_bytes_2_mb; + tot = static_cast(status.ullTotalPhys)/s_bytes_2_mb; + + #elif defined(__APPLE__) + dt_int32 mib[2]; + mib[0] = CTL_HW; + mib[1] = HW_MEMSIZE; + uint64_t physicalMem = 0; + dt_uint64 returnSize = sizeof(physicalMem); + sysctl(mib, 2, &physicalMem, &returnSize, NULL, 0); + tot = returnSize/s_bytes_2_mb; + + task_t targetTask = mach_task_self(); + struct task_basic_info ti; + mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT; + task_info(targetTask, TASK_BASIC_INFO_64, (task_info_t) &ti, &count); + free = ti.resident_size/s_bytes_2_mb; + + #else // linux + struct sysinfo memInfo; + sysinfo (&memInfo); + long long totalPhysMem = memInfo.totalram; + totalPhysMem *= memInfo.mem_unit; + long long physMemFree = memInfo.freeram; + physMemFree *= memInfo.mem_unit; + free = static_cast(physMemFree)/s_bytes_2_mb; // check if division by 1MB = 1048576 is necessary + tot = static_cast(totalPhysMem)/s_bytes_2_mb; // check if division by 1MB = 1048576 is necessary + #endif + } + + dt_float64 cpu_free_mem() + { + dt_float64 tot, free; + cpu_tot_free_mem(tot, free); + return free; + } + + dt_float64 cpu_tot_mem() + { + dt_float64 tot, free; + cpu_tot_free_mem(tot, free); + return tot; + } + + Cpu_Info cpu_info() + { + Cpu_Info info; + + #ifdef _WIN32 + SYSTEM_INFO siSysInfo; + GetSystemInfo(&siSysInfo); + info.n_proc = siSysInfo.dwNumberOfProcessors; + + #elif defined(__APPLE__) + dt_int32 count = 0; + dt_uint64 count_len = sizeof(count); + sysctlbyname("hw.logicalcpu", &count, &count_len, NULL, 0); + info.n_proc = count; + + #else // linux + info.n_proc = sysconf(_SC_NPROCESSORS_ONLN); + + #endif + + info.n_threads = std::thread::hardware_concurrency(); + cpu_tot_free_mem(info.tot_mem, info.free_mem); + + return info; + } + + #ifdef __CUDACC__ + void gpu_tot_free_mem(dt_float64 &tot, dt_float64 &free, dt_int32 idx = 0) + { + dt_float64 s_bytes_2_mb(c_bytes_2_mb); + + tot = free = 0; + #ifdef __CUDACC__ + dt_uint64 free_t, tot_t; + if (cudaSuccess == cudaMemGetInfo(&free_t, &tot_t)) + { + free = static_cast(free_t)/s_bytes_2_mb; + tot = static_cast(tot_t)/s_bytes_2_mb; + } + #endif + } + + dt_float64 gpu_free_mem() + { + dt_float64 tot, free; + gpu_tot_free_mem(tot, free); + return tot; + } + + dt_float64 gpu_tot_mem() + { + dt_float64 tot=0, free=0; + gpu_tot_free_mem(tot, free); + return free; + } + + dt_bool is_gpu_avbl() + { + dt_bool is_available = false; + try + { + dt_int32 device_count = 0; + cudaError_t error_id = cudaGetDeviceCount(&device_count); + + is_available = !((error_id != cudaSuccess)||(device_count == 0)); + } + catch(...) + { + is_available = false; + } + + return is_available; + } + + dt_int32 gpu_n_avbl() + { + dt_int32 device_count = 0; + cudaError_t error_id = cudaGetDeviceCount(&device_count); + + return (error_id != cudaSuccess)?0:device_count; + } + + std::vector gpu_info() + { + std::vector info; + + if (!is_gpu_avbl()) + { + return info; + } + + dt_int32 device_count = 0; + cudaGetDeviceCount(&device_count); + + info.resize(device_count); + for(auto idev = 0; idev < device_count; idev++) + { + cudaDeviceProp cuda_device_prop; + cudaGetDeviceProperties(&cuda_device_prop, idev); + + info[idev].id = idev; + info[idev].name = cuda_device_prop.name; + info[idev].comp_cap = 10*cuda_device_prop.major+cuda_device_prop.minor; + gpu_tot_free_mem(info[idev].tot_mem, info[idev].free_mem); + } + + // auto compare_fn = [](const Gpu_Info &a, const Gpu_Info &b)->dt_bool + // { + // return a.comp_cap > b.comp_cap; + // }; + // std::sort(info.begin(), info.end(), compare_fn); + + return info; + } + #endif + } + + /******************************* device configuration **********************************/ + class System_Config + { + public: + ePrecision precision; + eDev device; // eprc_float32 = 1, eprc_float64 = 2 + dt_int32 cpu_n_proc; // number of Cores CPU + dt_int32 cpu_n_thread; // number of threads + + Vctr_cpu gpu_device; // gpu devices + dt_int32 gpu_n_stream; // number of streams + + dt_int32 gpu_n_avbl; // number of selected gpus + dt_int32 n_stream; // number of streams + dt_int32 idx_0; // parameter position + + System_Config(): precision(eprc_float64), device(edev_cpu), cpu_n_proc(1), + cpu_n_thread(1), gpu_n_stream(1), gpu_n_avbl(0), n_stream(1), idx_0(0) {}; + + System_Config(const System_Config &system_config) + { + *this = system_config; + } + + System_Config& operator=(const System_Config &system_config) + { + precision = system_config.precision; + device = system_config.device; + cpu_n_proc = system_config.cpu_n_proc; + cpu_n_thread = system_config.cpu_n_thread; + gpu_device = system_config.gpu_device; + gpu_n_stream = system_config.gpu_n_stream; + n_stream = system_config.n_stream; + idx_0 = system_config.idx_0; + gpu_n_avbl = system_config.gpu_n_avbl; + + return *this; + } + + void set_dep_var() + { + // check precision + if (!(is_float32() || is_float64())) + { + precision = eprc_float32; + } + + // check cpu or gpu + if (!(is_cpu() || is_gpu())) + { + device = edev_cpu; + } + if (is_gpu()) + { + #ifdef __CUDACC__ + if (!dev_info::is_gpu_avbl()) + { + device = edev_cpu; + gpu_n_avbl = 0; + } + else + { + cpu_n_thread = 1; + gpu_n_avbl = dev_info::gpu_n_avbl(); + for(auto gpu_ind=0; gpu_ind + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_RAND_H + #define CGPU_RAND_H + + #include + + #include "macros.cuh" + #include "const_enum.cuh" + #include "math.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_stream.cuh" + + #ifdef __CUDACC__ + #include + #include + #endif + + /* traits */ + namespace mt + { + template + using enable_if_dist_p = typename std::enable_if::type; + + template + using enable_ifn_dist_p = typename std::enable_if::type; + + template + using Dist_type = typename std::conditional, + typename std::conditional, \ + typename std::conditional, T>::type>::type>::type; + } + + /* distribution type */ + namespace mt + { + template class Rnd_Dist; + + template + class Rnd_Dist + { + public: + using value_type = T; + + void set_seed(const dt_uint64& seed) + { + gen.seed(seed); + rnd.reset(); + } + + void reset_rnd() + { + rnd.reset(); + } + + T operator()(const T& x) + { + return x*rnd(gen); + } + + T operator()(const T& x, const T& sft) + { + return this->operator()(x) + sft; + } + private: + std::mt19937_64 gen; + Dist_type rnd; + }; + + template + class Rnd_Dist + { + public: + using value_type = T; + + void set_seed(const dt_uint64& seed) + { + gen.seed(seed); + rnd.reset(); + } + + void reset_rnd() + { + rnd.reset(); + } + + T operator()(const T& x) + { + rnd.param(Dist_type::param_type(x)); + + return T(rnd(gen)); + } + + T operator()(const T& x, const T& sft) + { + return this->operator()(x) + sft; + } + + private: + std::mt19937_64 gen; + Dist_type rnd; + }; + } + + /* distribution */ + namespace mt + { + class Gen_seed + { + public: + dt_uint64 m_seed; // seed + + Gen_seed(dt_uint64 seed=300183): m_seed(seed), rand_u(1) + { + set_seed(seed); + } + + dt_uint64 seed_1d(dt_uint64 seed, dt_int32 n_iter=1) + { + set_seed(seed); + + return iseed(n_iter); + } + + R_2d seed_2d(dt_uint64 seed, dt_int32 n_iter=1) + { + set_seed(seed); + + return {iseed(n_iter), iseed(n_iter)}; + } + + R_3d seed_3d(dt_uint64 seed, dt_int32 n_iter=1) + { + set_seed(seed); + + return {iseed(n_iter), iseed(n_iter), iseed(n_iter)}; + } + + dt_uint64 operator()() + { + return rand_u(gen_u); + } + + Vctr_uint64_cpu operator()(const dt_int32& n_spl) + { + Vctr_uint64_cpu vctr; + vctr.reserve(n_spl); + for(auto ik=0; ik rand_u; + }; + + template class Rand_xd; + + /* uniform distribution */ + template + using Randu_1d_cpu = Rand_xd; + + template + using Randu_2d_cpu = Rand_xd; + + template + using Randu_3d_cpu = Rand_xd; + + /* normal distribution */ + template + using Randn_1d_cpu = Rand_xd; + + template + using Randn_2d_cpu = Rand_xd; + + template + using Randn_3d_cpu = Rand_xd; + + /* poisson distribution */ + template + using Randp_1d_cpu = Rand_xd; + + template + using Randp_2d_cpu = Rand_xd; + + template + using Randp_3d_cpu = Rand_xd; + } + + /* 1d distribution */ + namespace mt + { + template + class Rand_xd: public Gen_seed + { + public: + using value_type = T; + + static const eDev device = edev_cpu; + + T m_sc; // scaling + T m_sft; // shift + + Rand_xd(dt_uint64 seed=300183, dt_int32 n_iter=1): Gen_seed(seed), m_sc{1}, m_sft{0} + { + set_seed(seed, n_iter); + } + + void set_in_data(const dt_uint64& seed, const T& sc, const T& sft, dt_int32 n_iter=1) + { + set_seed(seed, n_iter); + set_sc_sft(sc, sft); + } + + void set_seed(dt_uint64 seed, dt_int32 n_iter=1) + { + auto gen_seed = this->seed_1d(seed, n_iter); + + rnd.set_seed(gen_seed); + } + + void set_sc_sft(const T& sc, const T& sft) + { + m_sc = sc; + m_sft = sft; + } + + T operator()() + { + return rnd(m_sc, m_sft); + } + + T operator()(const T& sc) + { + return rnd(sc); + } + + T operator()(const T& sc, const T& sft) + { + return rnd(sc, sft); + } + + private: + Rnd_Dist rnd; + }; + } + + /* 2d distribution */ + namespace mt + { + template + class Rand_xd: public Gen_seed + { + public: + using value_type = T; + + static const eDev device = edev_cpu; + + R_2d m_sc; // scaling + R_2d m_sft; // shift + R_2d m_b_dim; // active dimensions + + Rand_xd(dt_uint64 seed=300183, dt_int32 n_iter=1): Gen_seed(seed), + m_sc{1, 1}, m_b_dim{true, true} + { + set_seed(seed, n_iter); + } + + void set_in_data(const dt_uint64& seed, const R_2d& sc, const R_2d& sft, dt_int32 n_iter=1) + { + set_seed(seed, n_iter); + set_sc_sft(sc, sft); + } + + void set_seed(dt_uint64 seed, dt_int32 n_iter=1) + { + auto gen_seed = this->seed_2d(seed, n_iter); + + rnd_x.set_seed(gen_seed.x); + rnd_y.set_seed(gen_seed.y); + } + + void set_sc_sft(const R_2d& sc, const R_2d& sft) + { + m_sc = sc; + m_sft = sft; + } + + void set_act_dim(const R_2d& b_dim) + { + m_b_dim = b_dim; + } + + R_2d operator()() + { + return this->operator()(m_sc, m_sft); + } + + R_2d operator()(const R_2d& sc) + { + return gen_rnd(sc); + } + + R_2d operator()(const R_2d& sc, const R_2d& sft) + { + return gen_rnd(sc, sft); + } + + private: + R_2d gen_rnd(const R_2d& sc) + { + return {(m_b_dim.x)?(rnd_x(sc.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y)):T(0)}; + } + + R_2d gen_rnd(const R_2d& sc, const R_2d& sft) + { + return {(m_b_dim.x)?(rnd_x(sc.x, sft.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y, sft.y)):T(0)}; + } + + Rnd_Dist rnd_x; + Rnd_Dist rnd_y; + }; + } + + /* 3d distribution */ + namespace mt + { + template + class Rand_xd: public Gen_seed + { + public: + using value_type = T; + + static const eDev device = edev_cpu; + + R_3d m_sc; // scaling + R_3d m_sft; // shift + R_3d m_b_dim; // active dimensions + + Rand_xd(dt_uint64 seed=300183, dt_int32 n_iter=1): Gen_seed(seed), + m_sc{1, 1, 1}, m_sft{0, 0, 0}, m_b_dim{true, true, true} + { + set_seed(seed, n_iter); + } + + void set_in_data(const dt_uint64& seed, const R_3d& sc, const R_3d& sft, dt_int32 n_iter=1) + { + set_seed(seed, n_iter); + set_sc_sft(sc, sft); + } + + void set_seed(dt_uint64 seed, dt_int32 n_iter=1) + { + auto gen_seed = this->seed_3d(seed, n_iter); + + rnd_x.set_seed(gen_seed.x); + rnd_y.set_seed(gen_seed.y); + rnd_z.set_seed(gen_seed.z); + } + + void set_sc_sft(const R_3d& sc, const R_3d& sft) + { + m_sc = sc; + m_sft = sft; + } + + void set_act_dim(const R_3d& b_dim) + { + m_b_dim = b_dim; + } + + R_3d operator()() + { + return this->operator()(m_sc, m_sft); + } + + R_3d operator()(const R_3d& sc) + { + return gen_rnd(sc); + } + + R_3d operator()(const R_3d& sc, const R_3d& sft) + { + return gen_rnd(sc, sft); + } + + private: + R_3d gen_rnd(const R_3d& sc) + { + return {(m_b_dim.x)?(rnd_x(sc.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y)):T(0), (m_b_dim.z)?(rnd_z(sc.z)):T(0)}; + } + + R_3d gen_rnd(const R_3d& sc, const R_3d& sft) + { + return {(m_b_dim.x)?(rnd_x(sc.x, sft.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y, sft.y)):T(0), (m_b_dim.z)?(rnd_z(sc.z, sft.z)):T(0)}; + } + + Rnd_Dist rnd_x; + Rnd_Dist rnd_y; + Rnd_Dist rnd_z; + }; + } + + /* fcns */ + namespace mt + { + // add uniform noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_unif_nois(TVctr_i& mx_i, Value_type sc, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto seed = seed_i; + + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + Gen_seed gen_seed(seed); + Vctr_uint64_cpu vctr_seed = gen_seed((pstream==nullptr)?1:pstream->size()); + + const T a = -sc; + const T b = T(2)*sc; + + auto thr_add_nois = [a, b, &mx_i, &vctr_seed, &mx_o](const iThread_Rect_1d& range) + { + Randu_1d_cpu rnd(vctr_seed[range.istm]); + + for(auto ind = range.ind_0; ind < range.ind_e; ind++) + { + mx_o[ind] = rnd(b, T(mx_i[ind]) + a); + } + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_nois); + }; + + // add gaussian noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_gauss_nois(TVctr_i& mx_i, Value_type sigma, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto seed = seed_i; + + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + Gen_seed gen_seed(seed); + Vctr_uint64_cpu vctr_seed = gen_seed((pstream==nullptr)?1:pstream->size()); + + auto thr_add_nois = [sigma, &mx_i, &vctr_seed, &mx_o](const iThread_Rect_1d& range) + { + Randn_1d_cpu rnd(vctr_seed[range.istm]); + + for(auto ind = range.ind_0; ind < range.ind_e; ind++) + { + mx_o[ind] = rnd(sigma, T(mx_i[ind])); + } + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_nois); + }; + + + // add poisson noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_poiss_nois(TVctr_i& mx_i, double sc_i, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto seed = seed_i; + auto sc = T(sc_i); + + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + Gen_seed gen_seed(seed); + Vctr_uint64_cpu vctr_seed = gen_seed((pstream==nullptr)?1:pstream->size()); + + auto thr_add_nois = [sc, &mx_i, &vctr_seed, &mx_o](const iThread_Rect_1d& range) + { + Randp_1d_cpu rnd(vctr_seed[range.istm]); + + for(auto ind = range.ind_0; ind < range.ind_e; ind++) + { + mx_o[ind] = rnd(T(mx_i[ind])*sc); + } + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_nois); + }; + + //// add Poisson noise + //template + //TVctr add_poiss_nois_by_SNR(Stream& stream, TVctr& Im_i, + // Value_type SNR_i, Value_type& scl_o) + //{ + // using T = Value_type; + + // auto get_SNR = [](Stream& stream, TVctr& Im, T Im_std, T scf)->T + // { + // T x_mean = 0; + // T x_var = 0; + // auto thr_SNR = [&](const iThread_Rect_2d& range) + // { + // std::mt19937_64 gen; + // std::poisson_distribution rand; + + // T x_mean_partial = 0; + // T x_var_partial = 0; + // for(auto ixy = range.ind_0; ixy < range.ind_e; ixy++) + // { + // auto x0 = scf*Im[ixy]; + // rand.param(std::poisson_distribution::param_type(x0)); + // auto xn = rand(gen)-x0; + // x_mean_partial += xn; + // x_var_partial += xn*xn; + // } + + // stream.stream_mutex.lock(); + // x_mean += x_mean_partial; + // x_var += x_var_partial; + // stream.stream_mutex.unlock(); + // }; + + // stream.set_n_stream_act(Im.size()); + // stream.set_grid(1, Im.size()); + // stream.exec(thr_SNR); + + // x_mean /= Im.size(); + // x_var = x_var/Im.size()-x_mean*x_mean; + + // return scf*Im_std/sqrt(x_var); + // }; + + // auto Im_i_std = sqrt(fcn_variance(stream, Im_i)); + + // T SNR_k = get_SNR(stream, Im_i, Im_i_std, 1); + + // T k_0 = 1; + // T k_e = 1; + + // if (SNR_k= SNR_i); + // k_e = 2*k_0; + // } + + + // // bisection method + // dt_int32 ic = 0; + // do + // { + // scl_o = 0.5*(k_0 + k_e); + // auto SNR_k = get_SNR(stream, Im_i, Im_i_std, scl_o); + + // if (SNR_k < SNR_i) + // { + // k_0 = scl_o; + // } + // else + // { + // k_e = scl_o; + // } + // ic++; + // } while ((fabs(SNR_i-SNR_k)>0.1) && (ic<10)); + + // // add Poisson noise + // return fcn_add_poiss_nois(stream, Im_i, scl_o); + //} + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cgpu_spt_ptc.cuh b/src - Copy (2)/cgpu_spt_ptc.cuh new file mode 100755 index 00000000..e5c7d1a8 --- /dev/null +++ b/src - Copy (2)/cgpu_spt_ptc.cuh @@ -0,0 +1,274 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_SPT_PTC_H + #define CGPU_SPT_PTC_H +#include + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_stream.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + #include "in_classes.cuh" + //#include "cgpu_fcns.cuh" + //#include "cpu_fcns.hpp" + #include "particles.cuh" + + #ifdef __CUDACC__ + #include "gpu_fcns.cuh" + #endif + + /* gpu detail */ + namespace mt + { + namespace gpu_detail + { + template + __global__ void fcn_ptc_s_fcn_eval(Grid_2d grid_2d, pVctr_gpu_32> ptc, pVctr_gpu_32 mx_o) + { + const auto fcn_ptc = ptc.m_data[blockIdx.x]; + + dt_int32 ix_t = threadIdx.y; + while (ix_t < fcn_ptc.nx) + { + const dt_int32 ix = fcn_ptc.ix_0 + ix_t; + + dt_int32 iy_t = threadIdx.x; + while (iy_t < fcn_ptc.ny) + { + const dt_int32 iy = fcn_ptc.iy_0 + iy_t; + const auto r2 = grid_2d.r2(ix, iy, fcn_ptc.r); + + if (r2 < fcn_ptc.r_max_2) + { + const auto ixy = grid_2d.sub_2_ind_pbc(ix, iy); + atomicAdd(&(mx_o.m_data[ixy]), fcn_ptc.eval_r2(r2)); + } + + iy_t += blockDim.x; + } + ix_t += blockDim.y; + } + } + } + } + + /* cpu detail */ + namespace mt + { + namespace cpu_detail + { + template + void fcn_ptc_s_fcn_eval(Stream& stream, Grid_2d& grid_2d, Ptc_s_fcn_xd& fcn_ptc, Vctr_cpu& mx_o) + { + for (auto ix_0 = 0; ix_0 < fcn_ptc.nx; ix_0++) + { + + for (auto iy_0 = 0; iy_0 < fcn_ptc.ny; iy_0++) + { + const dt_int32 ix = ix_0 + fcn_ptc.ix_0; + const dt_int32 iy = iy_0 + fcn_ptc.iy_0; + + const auto r2 = grid_2d.r2(ix, iy, fcn_ptc.r); + if (r2 < fcn_ptc.r_max_2) + { + const auto ixy = grid_2d.sub_2_ind_pbc(ix, iy); + mx_o[ixy] += fcn_ptc.eval_r2(r2); + } + } + } + } + } + } + + /***************************************************************************************/ + /********************************** superposition **************************************/ + /***************************************************************************************/ + namespace mt + { + template class Spt_Ptc_xd; + + template + using Spt_gauss_2d = Spt_Ptc_xd; + } + + /* template specialization cpu */ + namespace mt + { + template + class Spt_Ptc_xd + { + public: + using T_r = T; + using size_type = dt_uint64; + static const eDev device = edev_cpu; + + using TVctr_r = Vctr; + using Vctr_Ptc_dev = Vctr, edev_cpu>; + using Stream_dev = Stream; + + Spt_Ptc_xd(): in_spt_ptc(nullptr), stream(nullptr), n_ptc_blk(512) {} + + Spt_Ptc_xd(In_Spt_Ptc_xd *in_spt_ptc, Stream_dev *stream): n_ptc_blk(512) + { + set_in_data(in_spt_ptc, stream); + } + + void set_in_data(In_Spt_Ptc_xd *in_spt_ptc, Stream_dev *stream) + { + this->in_spt_ptc = in_spt_ptc; + this->stream = stream; + + n_ptc_blk = stream->size(); + ptc_sp.resize(n_ptc_blk); + } + + void operator()(TVctr_r &mx_io) + { + auto thr_gauss_eval = [](Stream_cpu& stream, Grid_2d& grid, Vctr_Ptc_dev& ptc_sp, TVctr_r& mx_o) + { + if (stream.n_stream_act<= 0) + { + return; + } + + for(auto istm = 0; istm < stream.n_stream_act-1; istm++) + { + stream[istm] = std::thread(cpu_detail::fcn_ptc_s_fcn_eval, std::ref(stream), std::ref(grid), std::ref(ptc_sp[istm]), std::ref(mx_o)); + } + + cpu_detail::fcn_ptc_s_fcn_eval(stream, grid, ptc_sp[stream.n_stream_act-1], mx_o); + + stream.synchronize(); + }; + + mx_io.fill(0); + + stream->set_grid(in_spt_ptc->grid.shape()); + + const dt_int32 iptc_0 = 0; + const dt_int32 iptc_e = in_spt_ptc->ptc.size()-1; + + dt_int32 iptc = iptc_0; + while (iptc <= iptc_e) + { + dt_int32 n_ptc = min(n_ptc_blk, iptc_e-iptc+1); + stream->set_n_stream_act(n_ptc); + set_ptc_s_fcn(iptc, n_ptc, ptc_sp); + + thr_gauss_eval(*stream, in_spt_ptc->grid, ptc_sp, mx_io); + + iptc += n_ptc; + } + } + + In_Spt_Ptc_xd *in_spt_ptc; + Stream_dev *stream; + private: + dt_int32 n_ptc_blk; + + void set_ptc_s_fcn(dt_int32 iptc, dt_int32 n_ptc_blk, Vctr_Ptc_dev& ptc_sp) + { + for(auto istm = 0; istm < n_ptc_blk; istm++) + { + ptc_sp[istm] = in_spt_ptc->ptc_s_fcn(iptc++, 0.85); + } + } + + Vctr_Ptc_dev ptc_sp; + }; + } + + /* template specialization gpu */ + namespace mt + { + template + class Spt_Ptc_xd + { + public: + using T_r = T; + using size_type = dt_uint64; + static const eDev device = edev_cpu; + + using TVctr_r = Vctr; + using Vctr_Ptc_cpu = Vctr, edev_cpu>; + using Vctr_Ptc_dev = Vctr, edev_gpu>; + using Stream_dev = Stream; + + Spt_Ptc_xd(): in_spt_ptc(nullptr), stream(nullptr), n_ptc_blk(512) {} + + Spt_Ptc_xd(In_Spt_Ptc_xd*in_spt_ptc, Stream_dev *stream): n_ptc_blk(512) + { + set_in_data(in_spt_ptc, stream); + } + + void set_in_data(In_Spt_Ptc_xd *in_spt_ptc, Stream_dev *stream) + { + this->in_spt_ptc = in_spt_ptc; + this->stream = stream; + + n_ptc_blk = 512; + ptc_sp_cpu.resize(n_ptc_blk); + ptc_sp.resize(n_ptc_blk); + } + + void operator()(TVctr_r &mx_io) + { + mx_io.fill(0); + + const dt_int32 iptc_0 = 0; + const dt_int32 iptc_e = in_spt_ptc->ptc.size_32()-1; + + dt_int32 iptc = iptc_0; + while (iptc <= iptc_e) + { + dt_int32 n_ptc = min(n_ptc_blk, iptc_e-iptc+1); + set_ptc_s_fcn(iptc, n_ptc, ptc_sp); + + gpu_detail::fcn_ptc_s_fcn_eval<<>>(in_spt_ptc->grid, ptc_sp.ptr_32(), mx_io.ptr_32()); + + iptc += n_ptc; + } + } + + In_Spt_Ptc_xd *in_spt_ptc; + Stream_dev *stream; + private: + dt_int32 n_ptc_blk; + + void set_ptc_s_fcn(dt_int32 iptc, dt_int32 n_ptc_blk, Vctr_Ptc_dev& ptc_sp) + { + for(auto istm = 0; istm < n_ptc_blk; istm++) + { + ptc_sp_cpu[istm] = in_spt_ptc->ptc_s_fcn(iptc++, 0.85); + } + ptc_sp = ptc_sp_cpu; + } + + Vctr_Ptc_cpu ptc_sp_cpu; + Vctr_Ptc_dev ptc_sp; + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cgpu_stream.cuh b/src - Copy (2)/cgpu_stream.cuh new file mode 100755 index 00000000..2468896b --- /dev/null +++ b/src - Copy (2)/cgpu_stream.cuh @@ -0,0 +1,863 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_STREAM_H + #define CGPU_STREAM_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + + #ifdef __CUDACC__ + #include + #include + #endif + + #include "const_enum.cuh" + #include "kahan_sum.cuh" + #include "ithread_rect.cuh" + + /***************************************************************************************/ + /***************************** stream template declaration *****************************/ + /***************************************************************************************/ + namespace mt + { + template class Stream; + + using Stream_cpu = Stream; + + #ifdef __CUDACC__ + using Stream_gpu = Stream; + #endif + } + + /***************************************************************************************/ + /************************************* cpu stream **************************************/ + /***************************************************************************************/ + namespace mt + { + template <> + class Stream + { + public: + static const eDev device = edev_cpu; + + std::mutex stream_mutex; + + Stream(): shape(), n_stream(0), n_stream_act(0), stream(nullptr) {} + + Stream(const dt_int32& n_stream): Stream() + { + resize(n_stream); + } + + Stream(const dt_int32& n_stream, const dt_shape& shape): Stream() + { + resize(n_stream); + set_grid(shape); + } + + ~Stream(){ + cleanup(); + n_stream = n_stream_act = 0; + } + + dt_int32 size() const + { + return n_stream; + } + + dt_bool is_single_thread() const + { + return n_stream < 2; + } + + void resize(const dt_int32& n_stream) + { + cleanup(); + + this->n_stream = (n_stream<1)?1:n_stream; + + if (this->n_stream > 1) + { + stream = new std::thread[this->n_stream-1]; + } + + set_n_stream_act(size()); + } + + std::thread& operator[](const dt_int32& iy) + { + return stream[iy]; + } + + const std::thread& operator[](const dt_int32& iy) const + { + return stream[iy]; + } + + void synchronize() + { + cleanup(); + + if (n_stream > 1) + { + stream = new std::thread[n_stream-1]; + } + } + + void set_n_stream_act(const dt_int32& n_stream_act) + { + this->n_stream_act = (n_stream_act<0)?0:min(size(), n_stream_act); + } + + void set_grid(const dt_shape& shape) + { + this->shape = shape; + } + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(nx); + } + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx); + } + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx, nz); + } + + template + enable_if_edim_1> + get_ithread_rect_xd(dt_int32 istm=0) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + ithread_rect.ix_0 = istm*qsiz; + ithread_rect.ix_e = (istm+1)*qsiz; + + if (istm == n_stream_act-1) + { + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + ithread_rect.ix_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_2> + get_ithread_rect_xd(dt_int32 istm=0) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnx = shape[1]/n_stream_act; + ithread_rect.ix_0 = istm*qnx; + ithread_rect.ix_e = (istm+1)*qnx; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.ix_e += (shape[1] - qnx*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_3> + get_ithread_rect_xd(dt_int32 istm=0) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnz = shape[2]/n_stream_act; + ithread_rect.iz_0 = istm*qnz; + ithread_rect.iz_e = (istm+1)*qnz; + ithread_rect.ix_0 = 0; + ithread_rect.ix_e = shape[1]; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.iz_e += (shape[2] - qsiz*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + + /***************************************************************************************/ + template + enable_if_edim_1 + exec_xd_krn(const dt_int32& nx, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx); + + if (n_stream_act < 1) + { + return; + } + + auto thr_fcn = [&](const iThread_Rect_xd& ithread) + { + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + fcn(ind, arg...); + } + }; + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(thr_fcn, std::move(get_ithread_rect_xd(istm))); + } + + thr_fcn(std::move(get_ithread_rect_xd(n_stream_act-1))); + + synchronize(); + } + + template + enable_if_edim_2 + exec_xd_krn(const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx, ny); + + if (n_stream_act < 1) + { + return; + } + + auto thr_fcn = [&](const iThread_Rect_xd& ithread) + { + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, arg...); + } + } + }; + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(thr_fcn, std::move(get_ithread_rect_xd(istm))); + } + + thr_fcn(std::move(get_ithread_rect_xd(n_stream_act-1))); + + synchronize(); + } + + template + enable_if_edim_3 + exec_xd_krn(const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nz), nx, ny, nz); + + if (n_stream_act < 1) + { + return; + } + + auto thr_fcn = [&](const iThread_Rect_xd& ithread) + { + for(auto iz = ithread.iz_0; iz < ithread.iz_e; iz++) + { + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, iz, arg...); + } + } + } + }; + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(thr_fcn, std::move(get_ithread_rect_xd(istm))); + } + + thr_fcn(std::move(get_ithread_rect_xd(n_stream_act-1))); + + synchronize(); + } + + /***************************************************************************************/ + template + enable_if_edim_1 + exec_xd_fcn(const dt_int32& nx, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx); + + if (n_stream_act < 1) + { + return; + } + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(fcn, get_ithread_rect_xd(istm), std::ref(arg)...)); + } + + fcn(get_ithread_rect_xd(n_stream_act-1), std::ref(arg)...); + + synchronize(); + } + + template + enable_if_edim_2 + exec_xd_fcn(const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx, ny); + + if (n_stream_act < 1) + { + return; + } + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(fcn, get_ithread_rect_xd(istm), std::ref(arg)...)); + } + + fcn(get_ithread_rect_xd(n_stream_act-1), std::ref(arg)...); + + synchronize(); + } + + template + enable_if_edim_3 + exec_xd_fcn(const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nz), nx, ny, nz); + + if (n_stream_act < 1) + { + return; + } + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(fcn, get_ithread_rect_xd(istm), std::ref(arg)...)); + } + + fcn(get_ithread_rect_xd(n_stream_act-1), std::ref(arg)...); + + synchronize(); + } + + void cleanup() + { + if ((n_stream <= 0) || (stream==nullptr)) + { + return; + } + + for(auto i = 0; i < n_stream-1; i++) + { + if (stream[i].joinable()) + { + stream[i].join(); + } + } + + delete [] stream; + stream = nullptr; + }; + + dt_int32 n_stream_act; + private: + dt_shape shape; + + dt_int32 n_stream; + std::thread *stream; + }; + } + + /***************************************************************************************/ + /************************************ gpu stream ***************************************/ + /***************************************************************************************/ + namespace mt + { + #ifdef __CUDACC__ + template <> + class Stream + { + public: + static const eDev device = edev_gpu; + + Stream(): shape(), n_stream(0), n_stream_act(0) {} + + Stream(const dt_int32& n_stream): Stream() + { + resize(n_stream); + } + + Stream(const dt_int32& n_stream, const dt_shape& shape): Stream() + { + resize(n_stream); + set_grid(shape); + } + + ~Stream() + { + cleanup(); + n_stream = n_stream_act = 0; + } + + dt_int32 size() const + { + return static_cast(stream.size()); + } + + void resize(const dt_int32& n_stream) + { + this->n_stream = max(1, n_stream); + + cleanup(); + + stream.resize(this->n_stream); + + for(auto i = 0; i < this->n_stream; i++) + { + cudaStreamCreate(&(stream[i])); + } + + set_n_stream_act(size()); + } + + cudaStream_t& operator[](const dt_int32& iy) + { + return stream[iy]; + } + + const cudaStream_t& operator[](const dt_int32& iy) const + { + return stream[iy]; + } + + void synchronize() + { + cudaDeviceSynchronize(); + } + + void set_n_stream_act(const dt_int32& n_stream_act) + { + this->n_stream_act = (n_stream_act<0)?0:min(size(), n_stream_act); + } + + void set_grid(const dt_shape& shape) + { + this->shape = shape; + } + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(nx); + } + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx); + } + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx, nz); + } + + template + enable_if_edim_1> + get_ithread_rect_xd(dt_int32 istm=0) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + ithread_rect.ix_0 = istm*qsiz; + ithread_rect.ix_e = (istm+1)*qsiz; + + if (istm == n_stream_act-1) + { + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + ithread_rect.ix_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_2> + get_ithread_rect_xd(dt_int32 istm=0) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnx = shape[1]/n_stream_act; + ithread_rect.ix_0 = istm*qnx; + ithread_rect.ix_e = (istm+1)*qnx; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.ix_e += (shape[1] - qnx*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_3> + get_ithread_rect_xd(dt_int32 istm=0) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnz = shape[2]/n_stream_act; + ithread_rect.iz_0 = istm*qnz; + ithread_rect.iz_e = (istm+1)*qnz; + ithread_rect.ix_0 = 0; + ithread_rect.ix_e = shape[1]; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.iz_e += (shape[2] - qsiz*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + void cleanup() + { + if (stream.empty()) + { + return; + } + + cudaDeviceSynchronize(); + + for(auto istm = 0; istm < stream.size(); istm++) + { + cudaStreamDestroy(stream[istm]); + } + + stream.clear(); + } + + dt_int32 n_stream_act; + + private: + dt_shape shape; + + dt_int32 n_stream; + std::vector stream; + }; + #endif + } + + /* stream functions */ + namespace mt + { + dt_bool fcn_is_single_thread(Stream_cpu* pstream) + { + return (pstream == nullptr)?true:pstream->is_single_thread(); + } + } + + /* kernel execution functions */ + namespace mt + { + template + enable_if_edim_1 + fcn_stream_exec_xd_krn(Stream_cpu* pstream, const dt_int32& nx, TFcn& fcn, TArgs&& ...arg) + { + if (pstream == nullptr) + { + Stream_cpu stream(1); + stream.exec_xd_krn(nx, fcn, arg...); + } + else + { + pstream->exec_xd_krn(nx, fcn, arg...); + } + } + + template + enable_if_edim_2 + fcn_stream_exec_xd_krn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs&& ...arg) + { + if (pstream == nullptr) + { + Stream_cpu stream(1); + stream.exec_xd_krn(nx, ny, fcn, arg...); + } + else + { + pstream->exec_xd_krn(nx, ny, fcn, arg...); + } + } + + template + enable_if_edim_3 + fcn_stream_exec_xd_krn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs&& ...arg) + { + if (pstream == nullptr) + { + Stream_cpu stream(1); + stream.exec_xd_krn(nx, ny, nz, fcn, arg...); + } + else + { + pstream->exec_xd_krn(nx, ny, nz, fcn, arg...); + } + } + } + + /* kernel reduction execution functions */ + namespace mt + { + template + enable_if_edim_1 + fcn_stream_exec_xd_krn_reduce(Stream_cpu* pstream, const dt_int32& nx, TOp&& fcn_op, T v_0, TFcn& fcn, TArgs&& ...arg) + { + auto thr_fcn = [](const iThread_Rect_xd& ithread, TFcn& fcn, TArgs&& ...arg, std::vector& vctr) + { + KS v_part = vctr[ithread.istm]; + + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + fcn(ind, arg..., v_part); + } + + vctr[ithread.istm] = v_part; + }; + + T v_tot = v_0; + + if (fcn_is_single_thread(pstream)) + { + std::vector vctr(1, v_0); + thr_fcn(iThread_Rect_xd(nx), fcn, arg..., vctr); + v_tot = vctr[0]; + } + else + { + std::vector vctr(pstream->size(), v_0); + pstream->exec_xd_fcn(nx, thr_fcn, fcn, arg..., vctr); + + // run remainder operations + for(auto ik=0; ik + enable_if_edim_2 + fcn_stream_exec_xd_krn_reduce(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, TOp&& fcn_op, T v_0, TFcn& fcn, TArgs&& ...arg) + { + auto thr_fcn = [](const iThread_Rect_xd& ithread, TFcn& fcn, TArgs&& ...arg, std::vector& vctr) + { + KS v_part = vctr[ithread.istm]; + + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, arg..., v_part); + } + } + + vctr[ithread.istm] = v_part; + }; + + T v_tot = v_0; + + if (fcn_is_single_thread(pstream)) + { + std::vector vctr(1, v_0); + thr_fcn(iThread_Rect_xd(nx, ny), fcn, arg..., vctr); + v_tot = vctr[0]; + } + else + { + std::vector vctr(pstream->size(), v_0); + pstream->exec_xd_fcn(nx, ny, thr_fcn, fcn, arg..., vctr); + + // run remainder operations + for(auto ik=0; ik + enable_if_edim_3 + fcn_stream_exec_xd_krn_reduce(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TOp&& fcn_op, T v_0, TFcn& fcn, TArgs&& ...arg) + { + auto thr_fcn = [](const iThread_Rect_xd& ithread, TFcn& fcn, TArgs&& ...arg, std::vector& vctr) + { + KS v_part = vctr[ithread.istm]; + + for(auto iz = ithread.iz_0; iz < ithread.iz_e; iz++) + { + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, iz, arg..., v_part); + } + } + } + + vctr[ithread.istm] = v_part; + }; + + T v_tot = v_0; + + if (fcn_is_single_thread(pstream)) + { + std::vector vctr(1, v_0); + thr_fcn(iThread_Rect_xd(nx, ny, nz), fcn, arg..., vctr); + v_tot = vctr[0]; + } + else + { + std::vector vctr(pstream->size(), v_0); + pstream->exec_xd_fcn(nx, ny, nz, thr_fcn, fcn, arg..., vctr); + + // run remainder operations + for(auto ik=0; ik + enable_if_edim_1 + fcn_stream_exec_xd_fcn(Stream_cpu* pstream, const dt_int32& nx, TFcn& fcn, TArgs&& ...arg) + { + if (fcn_is_single_thread(pstream)) + { + fcn(iThread_Rect_xd(nx), std::ref(arg)...); + } + else + { + pstream->exec_xd_fcn(nx, fcn, arg...); + } + } + + template + enable_if_edim_2 + fcn_stream_exec_xd_fcn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs&& ...arg) + { + if (fcn_is_single_thread(pstream)) + { + fcn(iThread_Rect_xd(nx, ny), std::ref(arg)...); + } + else + { + pstream->exec_xd_fcn(nx, ny, fcn, arg...); + } + } + + template + enable_if_edim_3 + fcn_stream_exec_xd_fcn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs&& ...arg) + { + if (fcn_is_single_thread(pstream)) + { + fcn(iThread_Rect_xd(nx, ny, nz), std::ref(arg)...); + } + else + { + pstream->exec_xd_fcn(nx, ny, nz, fcn, arg...); + } + } + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cgpu_vctr.cuh b/src - Copy (2)/cgpu_vctr.cuh new file mode 100755 index 00000000..a2c7b88a --- /dev/null +++ b/src - Copy (2)/cgpu_vctr.cuh @@ -0,0 +1,3119 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is destroy software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_VCTR_H + #define CGPU_VCTR_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "macros.cuh" + #include "const_enum.cuh" + #include "type_traits_gen.cuh" + #include "memcpy.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "mx_2x2.cuh" + #include "mx_3x3.cuh" + #include "igrid.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #include + #include + #endif + + /* vector copy */ + namespace mt + { + template class Vctr; + + // (dst, src): cpu -> cpu + template + void vctr_cpy(Vctr& vctr_cpu_dst, const Vctr& vctr_cpu_src, Ts* pvctr_cpu_jk = nullptr) + { + memcpy_cpu_cpu(vctr_cpu_dst.data(), vctr_cpu_src.data(), vctr_cpu_src.size(), pvctr_cpu_jk); + } + + #ifdef __CUDACC__ + // (dst, src): gpu -> cpu + template + void vctr_cpy(Vctr& vctr_cpu_dst, const Vctr& vctr_gpu_src, Ts* pvctr_cpu_jk = nullptr) + { + memcpy_gpu_cpu(vctr_cpu_dst.data(), vctr_gpu_src.data(), vctr_gpu_src.size(), pvctr_cpu_jk); + } + + // (dst, src): cpu -> gpu + template + void vctr_cpy(Vctr& vctr_gpu_dst, const Vctr& vctr_cpu_src, Td* pvctr_cpu_jk = nullptr) + { + memcpy_cpu_gpu(vctr_gpu_dst.data(), vctr_cpu_src.data(), vctr_cpu_src.size(), pvctr_cpu_jk); + } + + // (dst, src): gpu -> gpu + template + void vctr_cpy(Vctr& vctr_gpu_dst, const Vctr& vctr_gpu_src, Td* pvctr_cpu_jk = nullptr) + { + memcpy_gpu_gpu(vctr_gpu_dst.data(), vctr_gpu_src.data(), vctr_gpu_src.size(), pvctr_cpu_jk); + } + #endif + } + + /* macro grid-block */ + namespace mt + { + #define FCNS_GPU_GRID_BLK_VCTR \ + dim3 d_blk_size() \ + { \ + return fcn_cdb_size(); \ + } \ + \ + dim3 d_grid_size(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + auto grid = fcn_cdg_size(m_size); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_blk_1d() \ + { \ + return fcn_cdb_1d(); \ + } \ + \ + dim3 d_grid_1d(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + auto grid = fcn_cdg_1d(m_s0); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_1d(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + return D_Grid_Blk(d_grid_1d(d_grid_max), d_blk_1d()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_1d_h(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + auto grid = fcn_cdg_1d(m_s0/2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_1d_h(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + return D_Grid_Blk(d_grid_1d_h(d_grid_max), d_blk_1d()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_blk_2d() \ + { \ + return fcn_cdb_2d(); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_2d(const dim3 d_grid_max = dim3(64, 64, 0)) \ + { \ + auto grid = fcn_cdg_2d(m_s0, m_s1); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_2d(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + return D_Grid_Blk(d_grid_2d(d_grid_max), d_blk_2d()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_2d_h(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + auto grid = fcn_cdg_2d(m_s0/2, m_s1/2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_2d_h(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + return D_Grid_Blk(d_grid_2d_h(d_grid_max), d_blk_2d()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_blk_3d() \ + { \ + return fcn_cdb_3d(); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_3d(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + auto grid = fcn_cdg_3d(m_s0, m_s1, m_s2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_3d(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + return D_Grid_Blk(d_grid_3d(d_grid_max), d_blk_3d()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_3d_h(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + auto grid = fcn_cdg_3d(m_s0/2, m_s1/2, m_s2/2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + return D_Grid_Blk(d_grid_3d_h(d_grid_max), d_blk_3d()); \ + } + } + + /* vector pointer */ + namespace mt + { + template + class pVctr + { + public: + using value_type = T; + using size_type = ST; + static const eDev device = Dev; + + T* m_data; + ST m_s0; + ST m_s1; + ST m_s2; + ST m_s3; + ST m_size; + + ST m_pitch_s1; + ST m_pitch_s2; + ST m_pitch_s3; + + /************************************* constructors ************************************/ + CGPU_EXEC + pVctr(): m_data(nullptr), m_s0(0), m_s1(1), m_s2(1), m_s3(1), + m_size(0) + { + set_picth(); + } + + CPU_EXEC + pVctr(T* data, dt_shape_64 shape): m_data(data), + m_s0(ST(shape[0])), m_s1(ST(shape[1])), + m_s2(ST(shape[2])), m_s3(ST(shape[3])), m_size(shape_size()) + { + set_picth(); + } + + CGPU_EXEC + pVctr(T* data, ST s0): m_data(data), + m_s0(s0), m_s1(1), m_s2(1), m_s3(1), m_size(shape_size()) + { + set_picth(); + } + + CGPU_EXEC + pVctr(T* data, ST s0, ST s1): m_data(data), + m_s0(s0), m_s1(s1), m_s2(1), m_s3(1), m_size(shape_size()) + { + set_picth(); + } + + CGPU_EXEC + pVctr(T* data, ST s0, ST s1, ST s2): m_data(data), + m_s0(s0), m_s1(s1), m_s2(s2), m_s3(1), m_size(shape_size()) + { + set_picth(); + } + + CGPU_EXEC + pVctr(T* data, ST s0, ST s1, ST s2, ST s3): m_data(data), + m_s0(s0), m_s1(s1), m_s2(s2), m_s3(s3), m_size(shape_size()) + { + set_picth(); + } + + /************************** constructors *****************************/ + /* copy constructor */ + CGPU_EXEC + pVctr(const pVctr& pvctr) + { + *this = pvctr; + } + + /* Move constructor */ + CGPU_EXEC + pVctr(pVctr&& pvctr) + { + *this = std::move(pvctr); + } + + // ! Converting constructor + template + CPU_EXEC + explicit pVctr(const pVctr& pvctr) + { + *this = pvctr; + } + + // ! constructor from Vctr + CPU_EXEC + explicit pVctr(const Vctr& vctr) + { + *this = vctr; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pVctr& operator=(const pVctr& pvctr) + { + if (this != &pvctr) + { + m_data = pvctr.m_data; + m_s0 = pvctr.m_s0; + m_s1 = pvctr.m_s1; + m_s2 = pvctr.m_s2; + m_s3 = pvctr.m_s3; + m_size = pvctr.m_size; + m_pitch_s1 = pvctr.m_pitch_s1; + m_pitch_s2 = pvctr.m_pitch_s2; + m_pitch_s3 = pvctr.m_pitch_s3; + } + + return *this; + } + + /* Move assignment operator */ + CGPU_EXEC + pVctr& operator=(pVctr&& pvctr) + { + if (this != &pvctr) + { + m_data = pvctr.m_data; + m_s0 = pvctr.m_s0; + m_s1 = pvctr.m_s1; + m_s2 = pvctr.m_s2; + m_s3 = pvctr.m_s3; + m_size = pvctr.m_size; + m_pitch_s1 = pvctr.m_pitch_s1; + m_pitch_s2 = pvctr.m_pitch_s2; + m_pitch_s3 = pvctr.m_pitch_s3; + + pvctr.m_data = nullptr; + pvctr.m_s0 = 0; + pvctr.m_s1 = 0; + pvctr.m_s2 = 0; + pvctr.m_s3 = 0; + pvctr.m_size = 0; + pvctr.m_pitch_s1 = 0; + pvctr.m_pitch_s2 = 0; + pvctr.m_pitch_s3 = 0; + } + + return *this; + } + + // ! Converting assignment operator + template + CPU_EXEC + pVctr& operator=(const pVctr& pvctr) + { + m_data = pvctr.m_data; + m_s0 = ST(pvctr.m_s0); + m_s1 = ST(pvctr.m_s1); + m_s2 = ST(pvctr.m_s2); + m_s3 = ST(pvctr.m_s3); + m_size = ST(pvctr.m_size); + m_pitch_s1 = ST(pvctr.m_pitch_s1); + m_pitch_s2 = ST(pvctr.m_pitch_s2); + m_pitch_s3 = ST(pvctr.m_pitch_s3); + + return *this; + } + + // ! Assignment operator: Vctr -> pVctr + CPU_EXEC + pVctr& operator=(const Vctr& vctr) + { + m_data = vctr.m_data; + m_s0 = ST(vctr.m_s0); + m_s1 = ST(vctr.m_s1); + m_s2 = ST(vctr.m_s2); + m_s3 = ST(vctr.m_s3); + m_size = ST(vctr.m_size); + m_pitch_s1 = ST(vctr.m_pitch_s1); + m_pitch_s2 = ST(vctr.m_pitch_s2); + m_pitch_s3 = ST(vctr.m_pitch_s3); + + return *this; + } + + /**************** user define conversion operators *******************/ + pVctr ptr_32() const + { + return pVctr(*this); + } + + pVctr ptr_64() const + { + return pVctr(*this); + } + + operator pVctr>() const + { + return pVctr>(*this); + } + + CGPU_EXEC + ST s0() const + { + return m_s0; + } + + CGPU_EXEC + ST s1() const + { + return m_s1; + } + + CGPU_EXEC + ST s2() const + { + return m_s2; + } + + CGPU_EXEC + ST s3() const + { + return m_s3; + } + + CGPU_EXEC + dt_int32 s0_32() const + { + return static_cast(m_s0); + } + + CGPU_EXEC + dt_int32 s1_32() const + { + return static_cast(m_s1); + } + + CGPU_EXEC + dt_int32 s2_32() const + { + return static_cast(m_s2); + } + + CGPU_EXEC + dt_int32 s3_32() const + { + return static_cast(m_s3); + } + + CGPU_EXEC + dt_int64 s0_64() const + { + return static_cast(m_s0); + } + + CGPU_EXEC + dt_int64 s1_64() const + { + return static_cast(m_s1); + } + + CGPU_EXEC + dt_int64 s2_64() const + { + return static_cast(m_s2); + } + + CGPU_EXEC + dt_int64 s3_64() const + { + return static_cast(m_s3); + } + + CGPU_EXEC + ST s0h() const + { + return m_s0/ST(2); + } + + CGPU_EXEC + ST s1h() const + { + return m_s1/ST(2); + } + + CGPU_EXEC + ST s2h() const + { + return m_s2/ST(2); + } + + CGPU_EXEC + ST s3h() const + { + return m_s3/ST(2); + } + + dt_shape_st shape() const + { + return {m_s0, m_s1, m_s2, m_s3}; + } + + dt_shape_st shape_2d_trs() const + { + return {m_s1, m_s0, m_s2, m_s3}; + } + + CGPU_EXEC + ST shape_size() const + { + return m_s0*max(m_s1, ST(1))*max(m_s2, ST(1))*max(m_s3, ST(1)); + } + + CGPU_EXEC + ST pitch_s1() const + { + return m_pitch_s1; + } + + CGPU_EXEC + ST pitch_s2() const + { + return m_pitch_s2; + } + + CGPU_EXEC + ST pitch_s3() const + { + return m_pitch_s3; + } + + CGPU_EXEC + ST size() const + { + return m_size; + } + + CGPU_EXEC + dt_int32 size_32() const + { + return static_cast(m_size); + } + + CGPU_EXEC + dt_int64 size_64() const + { + return static_cast(m_size); + } + + iGrid_1d igrid_1d() const + { + return {size_32()}; + } + + iGrid_2d igrid_2d() const + { + return {s1_32(), s0_32()}; + } + + iGrid_2d igrid_3d() const + { + return {s1_32(), s0_32(), s2_32()}; + } + + iGrid_1d_64 igrid_1d_64() const + { + return {size_64()}; + } + + iGrid_2d_64 igrid_2d_64() const + { + return {s1_64(), s0_64()}; + } + + iGrid_2d_64 igrid_3d_64() const + { + return {s1_64(), s0_64(), s2_64()}; + } + + CGPU_EXEC + dt_bool empty() const + { + return m_size == 0; + } + + CGPU_EXEC + dt_bool is_1d() const + { + return (m_s0 == 1) || (m_s1 == 1); + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0) const + { + return ix_0; + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0, const ST& ix_1) const + { + return ix_0 + m_s0*ix_1; + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0, const ST& ix_1, const ST& ix_2) const + { + return ix_0 + m_s0*(ix_1 + m_s1*ix_2); + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) const + { + return ix_0 + m_s0*(ix_1 + m_s1*(ix_2 + m_s2*ix_3)); + } + + CGPU_EXEC + T& operator[](const ST& iy) + { + return m_data[iy]; + } + + CGPU_EXEC + const T& operator[](const ST& iy) const + { + return m_data[iy]; + } + + CGPU_EXEC + T& operator()(const ST& iy) + { + return m_data[iy]; + } + + CGPU_EXEC + const T& operator()(const ST& iy) const + { + return m_data[iy]; + } + + CGPU_EXEC + T& operator()(const ST& ix_0, const ST& ix_1) + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + CGPU_EXEC + const T& operator()(const ST& ix_0, const ST& ix_1) const + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + CGPU_EXEC + T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + CGPU_EXEC + const T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + CGPU_EXEC + T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + CGPU_EXEC + const T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + CGPU_EXEC + T* begin() + { + return m_data; + } + + CGPU_EXEC + const T* begin() const + { + return m_data; + } + + CGPU_EXEC + T* end() + { + return m_data + m_size; + } + + CGPU_EXEC + const T* end() const + { + return m_data + m_size; + } + + CGPU_EXEC + T* data() + { + return m_data; + } + + CGPU_EXEC + const T* data() const + { + return m_data; + } + + template + U data_cast() + { + return reinterpret_cast(m_data); + } + + template + const U data_cast() const + { + return reinterpret_cast(m_data); + } + + CGPU_EXEC + T front() const + { + return m_data[0]; + } + + CGPU_EXEC + T back() const + { + return m_data[m_size-1]; + } + + #ifdef __CUDACC__ + FCNS_GPU_GRID_BLK_VCTR; + #endif + + private: + + CGPU_EXEC + void set_picth() + { + m_pitch_s1 = m_s0*sizeof(T); + m_pitch_s2 = m_pitch_s1*m_s1; + m_pitch_s3 = m_pitch_s2*m_s2; + } + }; + + template + using pVctr_32 = pVctr; + + template + using pVctr_64 = pVctr; + + template + using pVctr_cpu_32 = pVctr; + + template + using pVctr_cpu_64 = pVctr; + + template + using pVctr_gpu_32 = pVctr; + + template + using pVctr_gpu_64 = pVctr; + } + + /* cpu vector */ + namespace mt + { + template + class Vctr + { + public: + using value_type = T; + using size_type = dt_int64; + static const eDev device = edev_cpu; + + mutable T* m_data; + size_type m_s0; + size_type m_s1; + size_type m_s2; + size_type m_s3; + size_type m_size; + size_type m_capacity; + + size_type m_pitch_s1; + size_type m_pitch_s2; + size_type m_pitch_s3; + + /************************************* constructors ************************************/ + explicit Vctr(): m_data(nullptr), m_s0(0), m_s1(1), m_s2(1), m_s3(1), + m_size(shape_size()), m_capacity(0) + { + set_picth(); + } + + Vctr(const dt_init_list_f64& data): Vctr() + { + assign(data.begin(), data.end()); + } + + Vctr(size_type s0): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1) }); + } + + Vctr(size_type s0, const T& value): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1) }, value); + } + + explicit Vctr(const dt_shape_st& shape): Vctr() + { + resize(shape); + } + + explicit Vctr(const dt_shape_st& shape, const T& value): Vctr() + { + resize(shape, value); + } + + /* copy constructor */ + Vctr(const Vctr& vctr): Vctr() + { + *this = vctr; + } + + /* Move constructor */ + Vctr(Vctr&& vctr): Vctr() + { + *this = std::move(vctr); + } + + /* converting constructor */ + template + Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + Vctr(U* first, U* last): Vctr() + { + assign(first, last); + } + + template > + Vctr(U *p, dt_int64 n_p, dt_int64 icol=0): Vctr() + { + set_pos_from_cpu_ptr(p, n_p, icol); + } + + template + Vctr(const std::vector& vctr): Vctr() + { + assign(vctr); + } + + // from cpu pVctr to Vctr + template + Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } + + #ifdef __CUDACC__ + template + Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + Vctr(const thrust::host_vector& vctr): Vctr() + { + assign(vctr); + } + + template + Vctr(const thrust::device_vector& vctr): Vctr() + { + assign(vctr); + } + + // from gpu pVctr to Vctr + template + Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } + #endif + ~Vctr() + { + destroy(); + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Vctr& operator=(const Vctr& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + delete[] m_data; + + m_data = new T[vctr.m_capacity]; + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size()); + + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + } + + return *this; + } + + /* Move assignment operator */ + Vctr& operator=(Vctr&& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + delete[] m_data; + + m_data = vctr.m_data; + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s2 = vctr.m_s2; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + + vctr.m_data = nullptr; + vctr.m_s0 = 0; + vctr.m_s1 = 0; + vctr.m_s2 = 0; + vctr.m_s3 = 0; + vctr.m_size = 0; + vctr.m_capacity = 0; + vctr.m_pitch_s1 = 0; + vctr.m_pitch_s2 = 0; + vctr.m_pitch_s3 = 0; + } + + return *this; + } + + /* converting assignment operator */ + template + Vctr& operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + Vctr& operator=(const std::vector& vctr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size()); + + return *this; + } + + #ifdef __CUDACC__ + template + Vctr& operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + Vctr& operator=(const thrust::host_vector& vctr) + { + assign(vctr); + + return *this; + } + + template + Vctr& operator=(const thrust::device_vector& vctr) + { + assign(vctr); + + return *this; + } + #endif + + template + void assign(const Vctr& vctr, U* pvctr_cpu = nullptr) + { + if ((void*)this != (void*)&vctr) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + } + + template + void assign(U* first, U* last) + { + if ((void*)m_data != (void*)first) + { + auto m_size_i = std::distance(first, last); + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, first, m_size); + } + } + } + + // from cpu pVctr to Vctr + template + void assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_cpu_cpu(m_data, pvctr.data(), m_size); + } + + #ifdef __CUDACC__ + template + void assign(const thrust::device_ptr& first, const thrust::device_ptr& last, U* pvctr_cpu = nullptr) + { + auto m_size_i = thrust::distance(first, last); + + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_cpu(m_data, (U*)first.get(), m_size, pvctr_cpu); + } + } + + // from gpu pVctr to Vctr + template + void assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_gpu_cpu(m_data, pvctr.data(), m_size); + } + #endif + + template + void assign(const std::vector& vctr, U* pvctr_cpu = nullptr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + + #ifdef __CUDACC__ + template + void assign(const Vctr& vctr, U* pvctr_cpu = nullptr) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + + template + void assign(const thrust::host_vector& vctr, U* pvctr_cpu = nullptr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + + template + void assign(const thrust::device_vector& vctr, U* pvctr_cpu = nullptr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_cpu(m_data, (U*)vctr.data().get(), vctr.size(), pvctr_cpu); + } + #endif + /**************** user define conversion operators *******************/ + pVctr_cpu_32 ptr_32() const + { + return pVctr_cpu_32(*this); + } + + pVctr_cpu_64 ptr_64() const + { + return pVctr_cpu_64(*this); + } + + operator pVctr_cpu_32() const + { + return pVctr_cpu_32(*this); + } + + operator pVctr_cpu_64() const + { + return pVctr_cpu_64(*this); + } + + // ! user define conversion + operator std::vector() const + { + std::vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion in which T is the complemented precision + template > + operator std::vector() const + { + std::vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + #ifdef __CUDACC__ + // ! user define conversion to output type std::vector> + template > + operator std::vector>() const + { + std::vector> vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion to output type std::vector> + template > + operator std::vector>() const + { + std::vector>vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + // ! user define conversion + operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion in which T is the complemented precision + template > + operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion to output type thrust::host_vector> + template > + operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion to output type thrust::host_vector> + template > + operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + // ! user define conversion + operator thrust::device_vector() const + { + thrust::device_vector vctr(m_size); + memcpy_cpu_gpu((T*)vctr.data().get(), m_data, m_size); + + return vctr; + } + + // ! user define conversion in which T is the complemented precision + template > + operator thrust::device_vector() const + { + thrust::device_vector vctr(m_size); + memcpy_cpu_gpu((U*)vctr.data().get(), m_data, m_size); + + return vctr; + } + #endif + /***************************************************************************************/ + template + void cpy_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_cpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + void cpy_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_cpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + #ifdef __CUDACC__ + template + void cpy_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_cpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + void cpy_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_cpu_gpu(first, m_data, n_data, pvctr_cpu); + } + #endif + + /***************************************************************************************/ + template > + void cpy_real_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_real_cpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_real_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_real_cpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + #ifdef __CUDACC__ + template > + void cpy_real_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_real_cpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_real_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_real_cpu_gpu(first, m_data, n_data, pvctr_cpu); + } + #endif + + /***************************************************************************************/ + template > + void cpy_imag_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_imag_cpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_imag_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_imag_cpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + #ifdef __CUDACC__ + template > + void cpy_imag_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_imag_cpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_imag_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_imag_cpu_gpu(first, m_data, n_data, pvctr_cpu); + } + #endif + + /***************************************************************************************/ + template > + void set_pos_from_cpu_ptr(U *p, size_type n_p, dt_int64 icol=0) + { + resize({n_p}); + + memcpy_pos_cpu_cpu(m_data, p, size(), icol); + } + + template > + void cpy_pos_to_cpu_ptr(U *p, size_type icol=0) + { + memcpy_pos_cpu_cpu(p, m_data, size(), icol); + } + + /***************************************************************************************/ + void resize(const dt_shape_st& shape) + { + this->allocate(shape); + } + + void resize(const dt_shape_st& shape, const T& value) + { + auto m_size_t = m_size; + this->allocate(shape); + std::fill(this->begin()+m_size_t, this->end(), value); + } + + void reserve(const dt_shape_st& shape) + { + this->allocate(shape, true); + } + + void shrink_to_fit() + { + if (m_size < m_capacity) + { + if (m_size > 0) + { + // ! allocate memory and transfer data + T* data_tmp = new T[m_size]; + memcpy_cpu_cpu(data_tmp, m_data, m_size); + delete[] m_data; + + m_data = data_tmp; + data_tmp = nullptr; + } + else + { + delete[] m_data; + m_data = nullptr; + } + + m_capacity = m_size; + + if (shape().dim()==2) + { + if (m_s1==1) + m_s0 = m_size; + + if (m_s0==1) + m_s1 = m_size; + } + } + } + + template + void push_back(const U& val) + { + if (m_size >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_type(1), 2*m_size); + else + shape[1] *= size_type(2); + } + else + { + shape[2] *= size_type(2); + } + } + else + { + shape[3] *= size_type(2); + } + + this->allocate(shape, true); + } + + m_data[m_size++] = T(val); + } + + template + void push_back(const Vctr& vctr) + { + const size_type size_new = m_size + vctr.size(); + + if (size_new >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_new, 2*shape[0]); + else + shape[1] = max(size_new/shape[0], 2*shape[1]); + } + else + { + shape[2] = max(size_new/(shape[0]*shape[1]), 2*shape[2]); + } + } + else + { + shape[3] = max(size_new/(shape[0]*shape[1]*shape[2]), 2*shape[3]); + } + + this->allocate(shape, true); + } + + memcpy_cpu_cpu(m_data + m_size, vctr.data(), vctr.size()); + + m_size = size_new; + } + + void pop_back() + { + if (m_size >= 1) + { + m_size--; + } + } + + void fill(T val) + { + std::fill(this->begin(), this->end(), val); + } + + /***************************************************************************************/ + size_type s0() const + { + return m_s0; + } + + size_type s1() const + { + return m_s1; + } + + size_type s2() const + { + return m_s2; + } + + size_type s3() const + { + return m_s2; + } + + dt_int32 s0_32() const + { + return static_cast(m_s0); + } + + dt_int32 s1_32() const + { + return static_cast(m_s1); + } + + dt_int32 s2_32() const + { + return static_cast(m_s2); + } + + dt_int32 s3_32() const + { + return static_cast(m_s3); + } + + dt_int64 s0_64() const + { + return static_cast(m_s0); + } + + dt_int64 s1_64() const + { + return static_cast(m_s1); + } + + dt_int64 s2_64() const + { + return static_cast(m_s2); + } + + dt_int64 s3_64() const + { + return static_cast(m_s3); + } + + size_type s0h() const + { + return m_s0/size_type(2); + } + + size_type s1h() const + { + return m_s1/size_type(2); + } + + size_type s2h() const + { + return m_s2/size_type(2); + } + + size_type s3h() const + { + return m_s3/size_type(2); + } + + dt_shape_st shape() const + { + return {m_s0, m_s1, m_s2, m_s3}; + } + + dt_shape_st shape_2d_trs() const + { + return {m_s1, m_s0, m_s2, m_s3}; + } + + size_type shape_size() const + { + return m_s0*max(m_s1, size_type(1))*max(m_s2, size_type(1))*max(m_s3, size_type(1)); + } + + size_type pitch_s1() const + { + return m_pitch_s1; + } + + size_type pitch_s2() const + { + return m_pitch_s2; + } + + size_type pitch_s3() const + { + return m_pitch_s3; + } + + size_type size() const + { + return m_size; + } + + dt_int32 size_32() const + { + return static_cast(m_size); + } + + dt_int64 size_64() const + { + return static_cast(m_size); + } + + iGrid_1d igrid_1d() const + { + return {size_32()}; + } + + iGrid_2d igrid_2d() const + { + return {s1_32(), s0_32()}; + } + + iGrid_2d igrid_3d() const + { + return {s1_32(), s0_32(), s2_32()}; + } + + iGrid_1d_64 igrid_1d_64() const + { + return {size_64()}; + } + + iGrid_2d_64 igrid_2d_64() const + { + return {s1_64(), s0_64()}; + } + + iGrid_2d_64 igrid_3d_64() const + { + return {s1_64(), s0_64(), s2_64()}; + } + + size_type capacity() const + { + return m_capacity; + } + + dt_bool empty() const + { + return m_size == 0; + } + + dt_bool is_1d() const + { + return (m_s0 == 1) || (m_s1 == 1); + } + + void clear() + { + m_size = 0; + } + + void clear_shrink_to_fit() + { + destroy(); + } + + size_type sub_2_ind(const size_type& ix_0) const + { + return ix_0; + } + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1) const + { + return ix_0 + m_s0*ix_1; + } + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + { + return ix_0 + m_s0*(ix_1 + m_s1*ix_2); + } + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + { + return ix_0 + m_s0*(ix_1 + m_s1*(ix_2 + m_s2*ix_3)); + } + + T& operator[](const size_type& iy) + { + return m_data[iy]; + } + + const T& operator[](const size_type& iy) const + { + return m_data[iy]; + } + + T& operator()(const size_type& iy) + { + return m_data[iy]; + } + + const T& operator()(const size_type& iy) const + { + return m_data[iy]; + } + + T& operator()(const size_type& ix_0, const size_type& ix_1) + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + const T& operator()(const size_type& ix_0, const size_type& ix_1) const + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + T* begin() + { + return m_data; + } + + const T* begin() const + { + return m_data; + } + + T* end() + { + return m_data + m_size; + } + + const T* end() const + { + return m_data + m_size; + } + + T* data() + { + return m_data; + } + + const T* data() const + { + return m_data; + } + + template + U data_cast() + { + return reinterpret_cast(m_data); + } + + template + const U data_cast() const + { + return reinterpret_cast(m_data); + } + + T& front() + { + return m_data[0]; + } + + const T& front() const + { + return m_data[0]; + } + + T& back() + { + return m_data[m_size-1]; + } + + const T& back() const + { + return m_data[m_size-1]; + } + + // set shape + void set_shape(const dt_shape_st& shape) + { + m_s0 = max(shape[0], size_type(0)); + m_s1 = max(shape[1], size_type(1)); + m_s2 = max(shape[2], size_type(1)); + m_s3 = max(shape[3], size_type(1)); + + set_picth(); + } + + void trs_shape_2d() + { + set_shape({m_s1, m_s0, m_s2, m_s3}); + } + + template + void set_shape(const Vctr& vctr, dt_bool bb_size = true) + { + this->set_shape(vctr.shape(), bb_size); + } + + #ifdef __CUDACC__ + FCNS_GPU_GRID_BLK_VCTR; + #endif + + private: + + void set_picth() + { + m_pitch_s1 = m_s0*sizeof(T); + m_pitch_s2 = m_pitch_s1*m_s1; + m_pitch_s3 = m_pitch_s2*m_s2; + } + + void set_capacity(size_type size_r) + { + m_capacity = max(m_capacity, size_r); + } + + void set_shape_cstr(dt_shape_st& shape) + { + shape[0] = max(shape[0], size_type(0)); + shape[1] = max(shape[1], size_type(1)); + shape[2] = max(shape[2], size_type(1)); + shape[3] = max(shape[3], size_type(1)); + } + + // reallocate and copy memory + void allocate(dt_shape_st shape, dt_bool bb_reserve=false) + { + set_shape_cstr(shape); + + auto size_r = shape[0]*shape[1]*shape[2]*shape[3]; + + if (size_r == 0) + { + return; + } + + if (m_size == 0) + { + if (m_data != nullptr) + { + delete[] m_data; + } + + m_data = new T[size_r]; + } + else if (size_r>m_capacity) + { + // ! allocate memory and transfer data + T* data_tmp = new T[size_r]; + memcpy_cpu_cpu(data_tmp, m_data, m_size); + + if (m_data != nullptr) + { + delete[] m_data; + } + + m_data = data_tmp; + data_tmp = nullptr; + } + + this->set_shape(shape); + if (!bb_reserve) + { + m_size = size_r; + } + this->set_capacity(size_r); + } + + // destroy memory on the device + void init() + { + m_data = nullptr; + m_s0 = 0; m_s1 = m_s2 = m_s3 = 1; + m_pitch_s1 = m_pitch_s2 = m_pitch_s3 = 0; + m_size = 0; + m_capacity = 0; + } + + // destroy memory on the device + void destroy() + { + if (m_data != 0) + { + delete[] m_data; + } + + init(); + } + + }; + } + + /* gpu vector */ + namespace mt + { + #ifdef __CUDACC__ + template + class Vctr + { + public: + using value_type = T; + using size_type = dt_int64; + static const eDev device = edev_gpu; + + mutable T* m_data; + size_type m_s0; + size_type m_s1; + size_type m_s2; + size_type m_s3; + size_type m_size; + size_type m_capacity; + + size_type m_pitch_s1; + size_type m_pitch_s2; + size_type m_pitch_s3; + + /************************************* constructors ************************************/ + explicit Vctr(): m_data(nullptr), m_s0(0), m_s1(1), m_s2(1), m_s3(1), + m_size(shape_size()), m_capacity(0) + { + set_picth(); + } + + Vctr(const dt_init_list_f64& data): Vctr() + { + assign(data.begin(), data.end()); + } + + Vctr(size_type s0): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1) }); + } + + Vctr(size_type s0, const T& value): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1)}, value); + } + + explicit Vctr(const dt_shape_st& shape): Vctr() + { + resize(shape); + } + + explicit Vctr(const dt_shape_st& shape, const T& value): Vctr() + { + resize(shape, value); + } + + /* copy constructor */ + Vctr(const Vctr& vctr): Vctr() + { + *this = vctr; + } + + /* Move constructor */ + Vctr(Vctr&& vctr): Vctr() + { + *this = std::move(vctr); + } + + /* converting constructor */ + template + Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + Vctr(U* first, U* last): Vctr() + { + assign(first, last); + } + + template > + Vctr(U *p, dt_int64 n_p, size_type icol=0): Vctr() + { + set_pos_from_cpu_ptr(p, n_p, icol); + } + + template + Vctr(const std::vector& vctr): Vctr() + { + assign(vctr); + } + + // from gpu pVctr to Vctr + template + Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } + + // from cpu pVctr to Vctr + template + Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } + + template + Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + Vctr(const thrust::host_vector& vctr): Vctr() + { + assign(vctr); + } + + template + Vctr(const thrust::device_vector& vctr): Vctr() + { + assign(vctr); + } + + ~Vctr() + { + destroy(); + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Vctr& operator=(const Vctr& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + fcn_cuda_free(m_data); + + fcn_cuda_malloc(m_data, vctr.m_capacity); + + memcpy_gpu_gpu(m_data, vctr.data(), vctr.size()); + + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s2 = vctr.m_s2; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + } + + return *this; + } + + /* Move assignment operator */ + Vctr& operator=(Vctr&& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + fcn_cuda_free(m_data); + + m_data = vctr.m_data; + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s2 = vctr.m_s2; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + + vctr.m_data = nullptr; + vctr.m_s0 = 0; + vctr.m_s1 = 0; + vctr.m_s2 = 0; + vctr.m_s3 = 0; + vctr.m_size = 0; + vctr.m_capacity = 0; + vctr.m_pitch_s1 = 0; + vctr.m_pitch_s2 = 0; + vctr.m_pitch_s3 = 0; + } + + return *this; + } + + /* converting assignment operator */ + template + Vctr& operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + Vctr& operator=(const std::vector& vctr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, vctr.data(), vctr.size()); + + return *this; + } + + template + Vctr& operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + Vctr& operator=(const thrust::host_vector& vctr) + { + assign(vctr); + + return *this; + } + + template + Vctr& operator=(const thrust::device_vector& vctr) + { + assign(vctr); + + return *this; + } + + template + void assign(const Vctr& vctr, T* pvctr_cpu = nullptr) + { + if ((void*)this != (void*)&vctr) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + } + + template + void assign(U* first, U* last) + { + if ((void*)m_data != (void*)first) + { + auto m_size_i = std::distance(first, last); + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, first, m_size); + } + } + } + + // from gpu pVctr to Vctr + template + void assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_gpu_gpu(m_data, pvctr.data(), m_size); + } + + template + void assign(const thrust::device_ptr& first, const thrust::device_ptr& last, T* pvctr_cpu = nullptr) + { + auto m_size_i = thrust::distance(first, last); + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_gpu(m_data, (U*)first.get(), m_size, pvctr_cpu); + } + } + + // from cpu pVctr to Vctr + template + void assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_cpu_gpu(m_data, pvctr.data(), m_size); + } + + template + void assign(const std::vector& vctr, T* pvctr_cpu = nullptr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + + template + void assign(const Vctr& vctr, T* pvctr_cpu = nullptr) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + + template + void assign(const thrust::host_vector& vctr, T* pvctr_cpu = nullptr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + + template + void assign(const thrust::device_vector& vctr, T* pvctr_cpu = nullptr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_gpu(m_data, (T*)vctr.data().get(), vctr.size(), pvctr_cpu); + } + + /**************** user define conversion operators *******************/ + pVctr_gpu_32 ptr_32() const + { + + return pVctr_gpu_32(*this); + } + + pVctr_gpu_64 ptr_64() const + { + + return pVctr_gpu_64(*this); + } + + // ! user define conversion for pointer Vctr + operator pVctr_gpu_32() const + { + return pVctr_gpu_32(*this); + } + + operator pVctr_gpu_64() const + { + return pVctr_gpu_64(*this); + } + + // ! user define conversion + operator std::vector() const + { + std::vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion in which T is the complemented precision + template > + operator std::vector() const + { + std::vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion to output type std::vector> + template > + operator std::vector>() const + { + std::vector> vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + return vctr; + } + + // ! user define conversion to output type std::vector> + template > + operator std::vector>() const + { + std::vector>vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + return vctr; + } + + // ! user define conversion + operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion in which T is the complemented precision + template > + operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion to output type thrust::host_vector> + template > + operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + // ! user define conversion to output type thrust::host_vector> + template > + operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + // ! user define conversion + operator thrust::device_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_gpu((T*)vctr.data().get(), m_data, m_size); + return vctr; + } + + // ! user define conversion in which T is the complemented precision + template > + operator thrust::device_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_gpu((U*)vctr.data().get(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + template + void cpy_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_gpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + void cpy_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_gpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + template + void cpy_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_gpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + void cpy_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr) + { + auto n_data = thrust::distance(first, last); + memcpy_gpu_gpu(first, m_data, n_data, pvctr_cpu); + } + + /***************************************************************************************/ + template > + void cpy_real_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_real_gpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_real_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_real_gpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_real_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_real_gpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_real_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_real_gpu_gpu(first, m_data, n_data, pvctr_cpu); + } + + /***************************************************************************************/ + template > + void cpy_imag_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_imag_gpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_imag_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_imag_gpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_imag_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr) + { + n_data = std::min(m_size, n_data); + memcpy_imag_gpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template > + void cpy_imag_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr) + { + auto n_data = std::distance(first, last); + memcpy_imag_gpu_gpu(first, m_data, n_data, pvctr_cpu); + } + + /***************************************************************************************/ + template > + void set_pos_from_cpu_ptr(U *p, size_type n_p, dt_int64 icol=0) + { + resize({n_p}); + + memcpy_pos_cpu_gpu(m_data, p, size(), icol); + } + + template > + void cpy_pos_to_cpu_ptr(U *p, size_type icol=0) + { + memcpy_pos_gpu_cpu(p, m_data, size(), icol); + } + + /***************************************************************************************/ + void resize(const dt_shape_st& shape) + { + this->allocate(shape); + } + + void resize(const dt_shape_st& shape, const T& value) + { + auto m_size_t = m_size; + this->allocate(shape); + thrust::fill(this->begin()+m_size_t, this->end(), value); + } + + void reserve(const dt_shape_st& shape) + { + this->allocate(shape, true); + } + + void shrink_to_fit() + { + if (m_size < m_capacity) + { + if (m_size > 0) + { + // ! allocate memory and transfer data + T* data_tmp = nullptr; + fcn_cuda_malloc(data_tmp, m_size); + memcpy_gpu_gpu(data_tmp, m_data, m_size); + fcn_cuda_free(m_data); + + m_data = data_tmp; + data_tmp = nullptr; + } + else + { + fcn_cuda_free(m_data); + } + + m_capacity = m_size; + + if (shape().dim()==2) + { + if (m_s1==1) + m_s0 = m_size; + + if (m_s0==1) + m_s1 = m_size; + } + } + } + + template + void push_back(const U& val) + { + if (m_size >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_type(1), 2*m_size); + else + shape[1] *= size_type(2); + } + else + { + shape[2] *= size_type(2); + } + } + else + { + shape[3] *= size_type(2); + } + + this->allocate(shape, true); + } + + memcpy_cpu_gpu(m_data + m_size, &val, 1); + + m_size++; + } + + template + void push_back(const Vctr& vctr) + { + const size_type size_new = m_size + vctr.size(); + + if (size_new >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_new, 2*shape[0]); + else + shape[1] = max(size_new/shape[0], 2*shape[1]); + } + else + { + shape[2] = max(size_new/(shape[0]*shape[1]), 2*shape[2]); + } + } + else + { + shape[3] = max(size_new/(shape[0]*shape[1]*shape[2]), 2*shape[3]); + } + + this->allocate(shape, true); + } + + memcpy_cpu_gpu(m_data + m_size, vctr.data(), vctr.size()); + + m_size = size_new; + } + + void pop_back() + { + if (m_size >= 1) + { + m_size--; + } + } + + void fill(T val) + { + thrust::fill(this->begin(), this->end(), val); + } + + /***************************************************************************************/ + size_type s0() const + { + return m_s0; + } + + size_type s1() const + { + return m_s1; + } + + size_type s2() const + { + return m_s2; + } + + size_type s3() const + { + return m_s2; + } + + dt_int32 s0_32() const + { + return static_cast(m_s0); + } + + dt_int32 s1_32() const + { + return static_cast(m_s1); + } + + dt_int32 s2_32() const + { + return static_cast(m_s2); + } + + dt_int32 s3_32() const + { + return static_cast(m_s3); + } + + dt_int64 s0_64() const + { + return static_cast(m_s0); + } + + dt_int64 s1_64() const + { + return static_cast(m_s1); + } + + dt_int64 s2_64() const + { + return static_cast(m_s2); + } + + dt_int64 s3_64() const + { + return static_cast(m_s3); + } + + size_type s0h() const + { + return m_s0/size_type(2); + } + + size_type s1h() const + { + return m_s1/size_type(2); + } + + size_type s2h() const + { + return m_s2/size_type(2); + } + + size_type s3h() const + { + return m_s3/size_type(2); + } + + dt_shape_st shape() const + { + return {m_s0, m_s1, m_s2, m_s3}; + } + + dt_shape_st shape_2d_trs() const + { + return {m_s1, m_s0, m_s2, m_s3}; + } + + size_type shape_size() const + { + return m_s0*max(m_s1, size_type(1))*max(m_s2, size_type(1))*max(m_s3, size_type(1)); + } + + size_type pitch_s1() const + { + return m_pitch_s1; + } + + size_type pitch_s2() const + { + return m_pitch_s2; + } + + size_type pitch_s3() const + { + return m_pitch_s3; + } + + size_type size() const + { + return m_size; + } + + dt_int32 size_32() const + { + return static_cast(m_size); + } + + dt_int64 size_64() const + { + return static_cast(m_size); + } + + iGrid_1d igrid_1d() const + { + return {size_32()}; + } + + iGrid_2d igrid_2d() const + { + return {s1_32(), s0_32()}; + } + + iGrid_2d igrid_3d() const + { + return {s1_32(), s0_32(), s2_32()}; + } + + iGrid_1d_64 igrid_1d_64() const + { + return {size_64()}; + } + + iGrid_2d_64 igrid_2d_64() const + { + return {s1_64(), s0_64()}; + } + + iGrid_2d_64 igrid_3d_64() const + { + return {s1_64(), s0_64(), s2_64()}; + } + + size_type capacity() const + { + return m_capacity; + } + + dt_bool empty() const + { + return m_size == 0; + } + + dt_bool is_1d() const + { + return (m_s0 == 1) || (m_s1 == 1); + } + + void clear() + { + m_size = 0; + } + + void clear_shrink_to_fit() + { + destroy(); + } + + size_type sub_2_ind(const size_type& ix_0) const + { + return ix_0; + } + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1) const + { + return ix_0 + m_s0*ix_1; + } + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + { + return ix_0 + m_s0*(ix_1 + m_s1*ix_2); + } + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + { + return ix_0 + m_s0*(ix_1 + m_s1*(ix_2 + m_s2*ix_3)); + } + + // T& operator[](const size_type& iy) + // { + // return m_data[iy]; + // } + + // const T& operator[](const size_type& iy) const + // { + // return m_data[iy]; + // } + + // T& operator()(const size_type& iy) + // { + // return m_data[iy]; + // } + + // const T& operator()(const size_type& iy) const + // { + // return m_data[iy]; + // } + + // T& operator()(const size_type& ix_0, const size_type& ix_1) + // { + // return m_data[sub_2_ind(ix_0, ix_1)]; + // } + + // const T& operator()(const size_type& ix_0, const size_type& ix_1) const + // { + // return m_data[sub_2_ind(ix_0, ix_1)]; + // } + + // T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + // } + + // const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + // } + + // T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + // } + + // const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + // } + + thrust::device_ptr begin() noexcept + { + return thrust::device_ptr(m_data); + } + + const thrust::device_ptr begin() const + { + return thrust::device_ptr(m_data); + } + + thrust::device_ptr end() noexcept + { + return thrust::device_ptr(m_data) + m_size; + } + + const thrust::device_ptr end() const + { + return thrust::device_ptr(m_data) + m_size; + } + + T* data() + { + return m_data; + } + + const T* data() const + { + return m_data; + } + + template + U data_cast() + { + return reinterpret_cast(m_data); + } + + template + const U data_cast() const + { + return reinterpret_cast(m_data); + } + + // T& front() + // { + // return m_data[0]; + // } + + // const T& front() const + // { + // return m_data[0]; + // } + + // T& back(){ + // return m_data[m_size-1]; + // } + + // const T& back() const + // { + // return m_data[m_size-1]; + // } + + // set shape + void set_shape(const dt_shape_st& shape) + { + m_s0 = max(shape[0], size_type(0)); + m_s1 = max(shape[1], size_type(1)); + m_s2 = max(shape[2], size_type(1)); + m_s3 = max(shape[3], size_type(1)); + + set_picth(); + } + + void trs_shape_2d() + { + set_shape({m_s1, m_s0, m_s2, m_s3}); + } + + template + void set_shape(const Vctr& vctr, dt_bool bb_size = true) + { + this->set_shape(vctr.shape(), bb_size); + } + + FCNS_GPU_GRID_BLK_VCTR; + + private: + + void set_picth() + { + m_pitch_s1 = m_s0*sizeof(T); + m_pitch_s2 = m_pitch_s1*m_s1; + m_pitch_s3 = m_pitch_s2*m_s2; + } + + void set_capacity(size_type size_r) + { + m_capacity = max(m_capacity, size_r); + } + + void set_shape_cstr(dt_shape_st& shape) + { + shape[0] = max(shape[0], size_type(0)); + shape[1] = max(shape[1], size_type(1)); + shape[2] = max(shape[2], size_type(1)); + shape[3] = max(shape[3], size_type(1)); + } + + // reallocate and copy memory + void allocate(dt_shape_st shape, dt_bool bb_reserve=false) + { + set_shape_cstr(shape); + + auto size_r = shape[0]*shape[1]*shape[2]*shape[3]; + + if (size_r == 0) + { + return; + } + + if (m_size == 0) + { + fcn_cuda_free(m_data); + + fcn_cuda_malloc(m_data, size_r); + } + else if (size_r>m_capacity) + { + // allocate memory and transfer data + T* data_tmp = nullptr; + fcn_cuda_malloc(data_tmp, size_r); + memcpy_gpu_gpu(data_tmp, m_data, m_size); + fcn_cuda_free(m_data); + + m_data = data_tmp; + data_tmp = nullptr; + } + + this->set_shape(shape); + if (!bb_reserve) + { + m_size = size_r; + } + this->set_capacity(size_r); + } + + // initialization + void init() + { + m_data = nullptr; + m_s0 = 0; m_s1 = m_s2 = m_s3 = 1; + m_pitch_s1 = m_pitch_s2 = m_pitch_s3 = 0; + m_size = 0; + m_capacity = 0; + } + + // destroy memory on the device + void destroy() + { + if (m_data != nullptr) + { + fcn_cuda_free(m_data); + } + + init(); + } + }; + #endif + } + + /* derive vectors */ + namespace mt + { + template + using Vctr_std = std::vector; + + template + using Vctr_cpu = Vctr; + + template + using Vctr_gpu = Vctr; + + /***************************************************************************************/ + /***************************************************************************************/ + using Vctr_uint32_cpu = Vctr_cpu; + using Vctr_uint32_gpu = Vctr_gpu; + + using Vctr_int32_cpu = Vctr_cpu; + using Vctr_int32_gpu = Vctr_gpu; + + using Vctr_uint64_cpu = Vctr_cpu; + using Vctr_uint64_gpu = Vctr_gpu; + + using Vctr_int64_cpu = Vctr_cpu; + using Vctr_int64_gpu = Vctr_gpu; + + /***************************************************************************************/ + /***************************************************************************************/ + template + using Vctr_r_2d = Vctr, Dev>; + + template + using Vctr_r_2d_cpu = Vctr, edev_cpu>; + + template + using Vctr_r_2d_gpu = Vctr, edev_gpu>; + + /***************************************************************************************/ + template + struct is_vctr_cpu_r_2d: std::integral_constant::value && is_r_2d::value> {}; + + template + struct is_vctr_cpu_r_2d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_vctr_gpu_r_2d: std::integral_constant::value && is_r_2d::value> {}; + + template + struct is_vctr_gpu_r_2d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_r_2d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_cpu_r_2d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_gpu_r_2d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu_r_2d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + /***************************************************************************************/ + template + using Vctr_r_3d = Vctr, Dev>; + + template + using Vctr_r_3d_cpu = Vctr, edev_cpu>; + + /***************************************************************************************/ + template + struct is_vctr_cpu_r_3d: std::integral_constant::value && is_r_3d::value> {}; + + template + struct is_vctr_cpu_r_3d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_vctr_gpu_r_3d: std::integral_constant::value && is_r_3d::value> {}; + + template + struct is_vctr_gpu_r_3d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_r_3d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_cpu_r_3d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_gpu_r_3d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu_r_3d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + struct is_vctr_cpu_r_nd: std::integral_constant::value && is_r_nd::value> {}; + + template + struct is_vctr_cpu_r_nd_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_vctr_gpu_r_nd: std::integral_constant::value && is_r_nd::value> {}; + + template + struct is_vctr_gpu_r_nd_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_r_nd = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu_r_nd = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_cpu_r_nd_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_gpu_r_nd_and_vctr_cpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using Vctr_Mx_2x2 = Vctr, Dev>; + + template + using Vctr_Mx_3x3 = Vctr, Dev>; + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/const_enum.cuh b/src - Copy (2)/const_enum.cuh new file mode 100755 index 00000000..7c6e2210 --- /dev/null +++ b/src - Copy (2)/const_enum.cuh @@ -0,0 +1,700 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CONST_ENUM_H + #define CONST_ENUM_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + + #ifdef __CUDACC__ + #include + #include + #include + #include + using thrust::complex; + #else + using std::complex; + #endif + + #include "macros.cuh" + #include "shape_t.hpp" + + /*data type */ + using dt_bool = bool; + using dt_int8 = int8_t; + using dt_uint8 = uint8_t; + using dt_int16 = int16_t; + using dt_uint16 = uint16_t; + using dt_int32 = int32_t; + using dt_uint32 = uint32_t; + using dt_int64 = int64_t; + using dt_uint64 = uint64_t; + using dt_float32 = float; + using dt_float64 = double; + + using dt_cint8 = complex; + using dt_cuint8 = complex; + using dt_cint16 = complex; + using dt_cuint16 = complex; + using dt_cint32 = complex; + using dt_cuint32 = complex; + using dt_cint64 = complex; + using dt_cuint64 = complex; + using dt_cfloat32 = complex; + using dt_cfloat64 = complex; + + using dt_std_cint8 = std::complex; + using dt_std_cuint8 = std::complex; + using dt_std_cint16 = std::complex; + using dt_std_cuint16 = std::complex; + using dt_std_cint32 = std::complex; + using dt_std_cuint32 = std::complex; + using dt_std_cint64 = std::complex; + using dt_std_cuint64 = std::complex; + using dt_std_cfloat32 = std::complex; + using dt_std_cfloat64 = std::complex; + + #ifdef __CUDACC__ + using dt_thr_cint8 = thrust::complex; + using dt_thr_cuint8 = thrust::complex; + using dt_thr_cint16 = thrust::complex; + using dt_thr_cuint16 = thrust::complex; + using dt_thr_cint32 = thrust::complex; + using dt_thr_cuint32 = thrust::complex; + using dt_thr_cint64 = thrust::complex; + using dt_thr_cuint64 = thrust::complex; + using dt_thr_cfloat32 = thrust::complex; + using dt_thr_cfloat64 = thrust::complex; + #endif + + /* data type */ + enum eData_Typ + { + edt_none = 0, edt_bool = 1, + edt_int8 = 2, edt_uint8 = 3, edt_int16 = 4, edt_uint16 = 5, edt_int32 = 6, + edt_uint32 = 7, edt_int64 = 8, edt_uint64 = 9, edt_float32 = 10, edt_float64 = 11, + edt_cint8 = 12, edt_cuint8 = 13, edt_cint16 = 14, edt_cuint16 = 15, edt_cint32 = 16, + edt_cuint32 = 17, edt_cint64 = 18, edt_cuint64 = 19, edt_cfloat32 = 20, edt_cfloat64 = 21, + edt_std_cint8 = 22, edt_std_cuint8 = 23, edt_std_cint16 = 24, edt_std_cuint16 = 25, edt_std_cint32 = 26, + edt_std_cuint32 = 27, edt_std_cint64 = 28, edt_std_cuint64 = 29, edt_std_cfloat32 = 30, edt_std_cfloat64 = 31, + edt_thr_cint8 = 32, edt_thr_cuint8 = 33, edt_thr_cint16 = 34, edt_thr_cuint16 = 35, edt_thr_cint32 = 36, + edt_thr_cuint32 = 37, edt_thr_cint64 = 38, edt_thr_cuint64 = 39, edt_thr_cfloat32 = 40, edt_thr_cfloat64 = 41 + }; + + template + using Ctpr = const T* __restrict__; // const template pointer restrict + + template + using Tpr = T* __restrict__; // template pointer restrict + + template + using dt_init_list = std::initializer_list; + + using dt_init_list_int32 = std::initializer_list; + using dt_init_list_int64 = std::initializer_list; + + using dt_init_list_f32 = std::initializer_list; + using dt_init_list_f64 = std::initializer_list; + + /* physical constants */ + namespace mt + { + template + const T c_Ha = T(27.2113850656389L); // Hartree to electron-Volt + + template + const T c_a0 = T(0.52917721077817892L); // Bohr radius + + template + const T c_pot_factor = T(47.877645145863056L); // + + template + const T c_2Pi2a0 = T(10.445539456905012L); // 2*pi^2*a0 + + template + const T c_H = T(6.62606876e-34L); // Planck's constant - J s + + template + const T c_bH = T(1.054571596e-34L); // h/(2*pi) - J s + + template + const T c_C = T(2.99792458e+8L); // Velocity of light - m s^-1 + + template + const T c_Qe = T(1.602176462e-19L); // Elementary charge + + template + const T c_me = T(9.10938291e-31L); // Electron rest mass [kg] + + template + const T c_mp = T(1.672621637e-27L); // Proton rest mass [kg] + + template + const T c_KB = T(1.3806504e-23L); // Boltzmann's constant - J K^-1 + + template + const T c_Na = T(6.0221415e+23L); // Avogadro's Number - mol^-1 + + template + const T c_E0 = T(8.854187817e-12L); // Vacuum permittivity + } + + /* pi and power constants */ + namespace mt + { + template + const T c_E = T(2.7182818284590452354L); // e (base of natural log) + + template + const T c_pi = T(3.141592653589793238463L); // pi + + template + const T c_ipi = T(0.3183098861837906715378L); // 1.0/pi + + template + const T c_i2pi = T(1.570796326794896619231L); // pi/2 + + template + const T c_i3pi = T(1.047197551196597746154L); // pi/3 + + template + const T c_i4pi = T(0.7853981633974483096157L); // pi/4 + + template + const T c_2pi = T(6.283185307179586476925L); // 2*pi + + template + const T c_3pi = T(9.424777960769379715388L); // 3*pi + + template + const T c_4pi = T(12.56637061435917295385L); // 4*pi + + template + const T c_pi2 = T(9.869604401089358618834L); // pi^2 + + template + const T c_pi3 = T(31.00627668029982017548L); // pi^3 + + template + const T c_pi4 = T(97.4090910340024372364L); // pi^4 + + template + const T c_pii2 = T(1.772453850905516027298L); // pi^(1/2) + + template + const T c_pii3 = T(1.46459188756152326302L); // pi^(1/3) + + template + const T c_pii4 = T(1.331335363800389712798L); // pi^(1/4) + + template + const T c_2i2 = T(1.414213562373095048802L); // 2^(1/2) + + template + const T c_3i2 = T(1.732050807568877293527L); // 3^(1/2) + + template + const T c_5i2 = T(2.236067977499789696409L); // 5^(1/2) + + template + const T c_7i2 = T(2.645751311064590590502L); // 7^(1/2) + } + + /* others constants */ + namespace mt + { + const dt_int32 c_cSynCPU = 5; + + const dt_int32 c_n_atom_typ = 103; + const dt_int32 c_n_atom_ions = 15; + const dt_int32 c_nqz = 128; + const dt_int32 c_nR = 128; + + const dt_float64 c_vr_min = 0.001; // before was 0.015V + + const dt_float64 c_dflt_pos_ee = 1e-04; // position error + + const dt_float32 c_dflt_rms3d = 0.085f; // default 3d root mean squared displacement + const dt_float32 c_dflt_occ = 1.0f; // default occupancy + const dt_int32 c_dflt_tag = 0; // default tag + const dt_int32 c_dflt_charge = 0; // default charge + + const dt_int32 cSizeofI = sizeof(dt_int32); + const dt_int32 cSizeofRD = sizeof(dt_float64); + const dt_int32 cSizeofRF = sizeof(dt_float32); + const dt_int32 cSizeofCD = 2*cSizeofRD; + + const dt_uint64 c_bytes_2_kb = 1024; + const dt_uint64 c_bytes_2_mb = 1024*1024; + const dt_uint64 c_bytes_2_gb = 1024*1024*1024; + + template + const T c_hwhm_2_sigma = T(0.84932180028801907L); // hwhm to sigma 1/(sqrt(2*log(2))) + + template + const T c_fwhm_2_sigma = T(0.42466090014400953L); // fwhm to sigma 1/(2*sqrt(2*log(2))) + + template + const T c_iehwgd_2_sigma = T(0.70710678118654746L); // iehwgd to sigma 1/sqrt(2) + + template + const T c_mrad_2_rad = T(1.0e-03L); // mrad-->rad + + template + const T c_deg_2_rad = T(0.01745329251994329576924L); // degrees-->rad + + template + const T c_mm_2_angs = T(1.0e+07L); // mm-->Angstrom + + template + const T c_eV_2_keV = T(1e-03L); // ev-->keV + + template + const T c_cm3_A3 = T(1e24L); // cm^3 --> A^3 + } + + /* error class and fcns */ + namespace mt + { + template + CGPU_EXEC + T epsilon_eps(){ return 0; } + + template <> + CGPU_EXEC + dt_float64 epsilon_eps(){ return 10.0*DBL_EPSILON; } + + template <> + CGPU_EXEC + dt_float32 epsilon_eps(){ return 10.0*FLT_EPSILON; } + + template + CGPU_EXEC + T epsilon_abs(){ return 0; } + + template <> + CGPU_EXEC + dt_float64 epsilon_abs(){ return 1e-13; } + + template <> + CGPU_EXEC + dt_float32 epsilon_abs(){ return 1e-5f; } + + template + CGPU_EXEC + T epsilon_rel(){ return 0; } + + template <> + CGPU_EXEC + dt_float64 epsilon_rel(){ return 1e-8; } + + template <> + CGPU_EXEC + dt_float32 epsilon_rel(){ return 1e-4f; } + + + template + struct Epsilon + { + static const T eps; + static const T abs; + static const T rel; + }; + + template + const T Epsilon::eps = 0; + + template + const T Epsilon::abs = 0; + + template + const T Epsilon::rel = 0; + + template <> + const dt_float64 Epsilon::eps = 10.0*DBL_EPSILON; + + template <> + const dt_float64 Epsilon::abs = 1e-13; + + template <> + const dt_float64 Epsilon::rel = 1e-8; + + template <> + const dt_float32 Epsilon::eps = 10.0*FLT_EPSILON; + + template <> + const dt_float32 Epsilon::abs = 1e-5f; + + template <> + const dt_float32 Epsilon::rel = 1e-4f; + } + + /* enumerations */ + namespace mt + { + /* Dimension*/ + enum eDim + { + edim_1 = 1, edim_2 = 2, edim_3 = 3 + }; + + /* Distribution */ + // 1: uniform, 2: normal, 3: poisson + enum eDist + { + edist_u = 1, edist_n = 2, edist_p = 3 + }; + + /* Device type */ + enum eDev + { + edev_cpu = 1, edev_gpu = 2, edev_cpu_gpu = 3 + }; + + /* functions type */ + enum eFcn_typ + { + efcn_cos_tap = 1, efcn_gauss = 2, efcn_exp = 3, efcn_fermi = 5, efcn_butwth = 6, efcn_hann = 7 + }; + + /* modify vector */ + enum eModify_Vector + { + eMV_yes = 1, eMV_no = 2 + }; + + /* Multem type */ + enum ePrecision + { + eprc_float32 = 1, eprc_float64 = 2 + }; + + /* Show Data type */ + enum eShow_CData + { + escd_creal = 1, escs_cimag = 2, escd_cmod = 3, escd_cphase = 4 + }; + + /** operation mode */ + enum eOperation_Mode + { + eOM_Normal = 1, eOM_Advanced = 2 + }; + + enum eRot_Ctr_Typ + { + erct_none = 0, erct_geometric_ctr = 1, erct_user_def = 2 + }; + + /* real or fourier space */ + enum eSpace + { + esp_real = 1, esp_fourier = 2 + }; + + /* match boder */ + enum eMatch_Bdr + { + emb_none = 0, emb_min = 1, emb_max = 2, emb_minmax = 3 + }; + + /*** output type */ + enum eOutput_Typ + { + eot_matlab = 1, eot_vector = 2 + }; + + /* data sel type */ + enum eDat_Sel_Typ + { + edst_closest = 1, edst_less_than = 2, edst_greater_than = 3, edst_eless_than = 4, edst_egreater_than = 5 + }; + + /* fill sel type */ + enum eFil_Sel_Typ + { + efst_min = 1, efst_max = 2, efst_mean = 3, efst_min_mean = 4, efst_max_mean = 5, efst_user_def = 6, efst_same_in = 7 + }; + + /* structuring element */ + enum eStr_Ele + { + ese_disk = 1, ese_square = 2 + }; + + /** operation */ + enum eOP { + eOP_N = 1, eOP_T = 2, eOP_C = 3 + }; + + /* Exec type */ + enum eET { + eET_Matrix = 1, eET_Vector = 2 + }; + + /* quad_data coefficients */ + + // 1: eqt_tanh_sinh_int_n1_p1 -> int_-1^1 f(x) dx + // 2: eqt_exp_sinh_int_0_pinfty -> int_0^infty f(x) dx + // 3: eqt_exp_exp_int_0_pinfty -> int_0^infty f(x)exp(-x) dx + // 4: eqt_sinh_sinh_int_ninfty_pinfty -> int_-infty^infty f(x) dx + + // 5: eqt_fourier_sin_int_0_pinfty -> int_0^infty f(x)sin(wx) dx + // 6: eqt_fourier_cos_int_0_pinfty -> int_0^infty f(x)Cos(wx) dx + + // 7: eqt_gauss_legendre_int_n1_p1 -> int_-1^1 f(x) dx + + // 8: eqt_gauss_hermite_x0_int_ninfty_pinfty -> int_-infty^infty f(x) x^0 Exp[-x^2] dx + // 9: eqt_gauss_hermite_x1_int_ninfty_pinfty -> int_-infty^infty f(x) |x|^1 Exp[-x^2] dx + // 10: eqt_gauss_hermite_x2_int_ninfty_pinfty -> int_-infty^infty f(x) |x|^2 Exp[-x^2] dx + + // 11: eqt_gauss_laguerre_x0_int_0_pinfty -> int_0^infty f(x) x^0 Exp[-x] dx + // 12: eqt_gauss_laguerre_x1_int_0_pinfty -> int_0^infty f(x) x^1 Exp[-x] dx + // 13: eqt_gauss_laguerre_x2_int_0_pinfty -> int_0^infty f(x) x^2 Exp[-x] dx + // 14: eqt_gauss_laguerre_xi2_int_0_pinfty -> int_0^infty f(x) Exp[-x]/Sqrt[x] dx + + // 15: eqt_legendre -> legendre, (a, b) + // 16: eqt_chebyshev -> (a, b) ((b-x)*(x-a))^(-0.5) + // 17: eqt_gegenbauer -> (a, b) ((b-x)*(x-a))^alpha + // 18: eqt_jacobi -> (a, b) (b-x)^alpha*(x-a)^beta + // 19: eqt_laguerre -> (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 20: eqt_hermite -> (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 21: eqt_exponential -> (a, b) |x-(a+b)/2.0|^alpha + // 22: eqt_rational -> (a, inf) (x-a)^alpha*(x+b)^beta + + enum eQuad_Typ + { + eqt_none = 0, eqt_tanh_sinh_int_n1_p1 = 1, eqt_exp_sinh_int_0_pinfty = 2, eqt_exp_exp_int_0_pinfty = 3, + eqt_sinh_sinh_int_ninfty_pinfty = 4, eqt_fourier_sin_int_0_pinfty = 5, eqt_fourier_cos_int_0_pinfty = 6, + eqt_gauss_legendre_int_n1_p1 = 7, eqt_gauss_hermite_x0_int_ninfty_pinfty = 8, eqt_gauss_hermite_x1_int_ninfty_pinfty = 9, + eqt_gauss_hermite_x2_int_ninfty_pinfty = 10, eqt_gauss_laguerre_x0_int_0_pinfty = 11, eqt_gauss_laguerre_x1_int_0_pinfty = 12, + eqt_gauss_laguerre_x2_int_0_pinfty = 13, eqt_gauss_laguerre_xi2_int_0_pinfty = 14, eqt_legendre = 15, + eqt_chebyshev = 16, eqt_gegenbauer = 17, eqt_jacobi = 18, + eqt_laguerre = 19, eqt_hermite = 20, eqt_exponential = 21, + eqt_rational = 22 + }; + } + + /* constant - enumeration comparison */ + namespace mt + { + inline + dt_bool is_rot_ctr_none(const eRot_Ctr_Typ &type) + { + return type == mt::erct_none; + } + + inline + dt_bool is_rot_ctr_geometric_ctr(const eRot_Ctr_Typ &type) + { + return type == mt::erct_geometric_ctr; + } + + inline + dt_bool is_rot_ctr_user_def(const eRot_Ctr_Typ &type) + { + return type == mt::erct_user_def; + } + } + + /* R_xd */ + namespace mt + { + template class R_xtd; + + template + using R_1d = T; + + template + using R_xd = typename std::conditional>::type; + } + + /* pointers functions */ + namespace mt + { + template + dt_bool fcn_is_null_ptr(T* ptr) + { + return ptr==nullptr; + }; + } + + /* cuda grid and block constants */ + namespace mt + { + const dt_int32 c_blk_x = 4; + const dt_int32 c_blk_y = 16; + + const dt_int32 c_thr_1d = 256; + + const dt_int32 c_thr_2d_x = 32; + const dt_int32 c_thr_2d_y = 8; + + const dt_int32 c_thr_3d_x = 32; + const dt_int32 c_thr_3d_y = 4; + const dt_int32 c_thr_3d_z = 2; + } + + #ifdef __CUDACC__ + class D_Grid_Blk + { + public: + D_Grid_Blk(): grid(), blk() {} + + D_Grid_Blk(const dim3& grid, const dim3& blk): grid(grid), blk(blk) {} + + D_Grid_Blk(const dt_int32& grid, const dt_int32& blk): grid(grid), blk(blk) {} + + dt_int32 grid_size() + { + return grid.x*grid.y*grid.z; + }; + + dt_int32 blk_size() + { + return blk.x*blk.y*blk.z; + }; + + // shared memory size reduction + dt_int32 smems_red() + { + // when there is only one warp per block, we need to allocate two warps + // worth of shared memory so that we don't index shared memory out of bounds + auto threads = blk_size(); + dt_int32 smems = (threads <= 32) ? 2*threads:threads; + + return smems; + } + + dim3 blk; // Threads + dim3 grid; // Blocks + }; + + // cuda dimension grid + + template + dt_uint32 fcn_cdg(const ST& n, const dt_int32& dn) + { + return static_cast((n + ST(dn)-ST(1))/ST(dn)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_size() + { + return dim3(mt::c_thr_1d); + } + + template + dim3 fcn_cdg_size(const ST& n) + { + return dim3(fcn_cdg(n, mt::c_thr_1d)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_1d() + { + return dim3(mt::c_thr_1d); + } + + template + dim3 fcn_cdg_1d(const ST& n) + { + return dim3(fcn_cdg(n, mt::c_thr_1d)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_2d() + { + return dim3(mt::c_thr_2d_x, mt::c_thr_2d_y); + } + + template + dt_uint32 fcn_cdg_2d_x(const ST& n) + { + return fcn_cdg(n, mt::c_thr_2d_x); + } + + template + dt_uint32 fcn_cdg_2d_y(const ST& n) + { + return fcn_cdg(n, mt::c_thr_2d_y); + } + + template + dim3 fcn_cdg_2d(const ST& nx, const ST& ny) + { + return dim3(fcn_cdg_2d_x(nx), fcn_cdg_2d_y(ny)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_3d() + { + return dim3(mt::c_thr_3d_x, mt::c_thr_3d_y, mt::c_thr_3d_z); + } + + template + dt_uint32 fcn_cdg_3d_x(const ST& n) + { + return fcn_cdg(n, mt::c_thr_3d_x); + } + + template + dt_uint32 fcn_cdg_3d_y(const ST& n) + { + return fcn_cdg(n, mt::c_thr_3d_y); + } + + template + dt_uint32 fcn_cdg_3d_z(const ST& n) + { + return fcn_cdg(n, mt::c_thr_3d_z); + } + + template + dim3 fcn_cdg_3d(const ST& nx, const ST& ny, const ST& nz) + { + return dim3(fcn_cdg_3d_x(nx), fcn_cdg_3d_y(ny), fcn_cdg_3d_z(nz)); + } + + /***************************************************************************************/ + template + void fcn_cuda_malloc(T*& data, const ST& n_data) + { + cudaMalloc((void**)&data, n_data*sizeof(T)); + } + + template + void fcn_cuda_free(T*& data) + { + if (data != nullptr) + { + cudaFree(data); + data = nullptr; + } + } + + #endif +#endif \ No newline at end of file diff --git a/src - Copy (2)/const_enum_mt.cuh b/src - Copy (2)/const_enum_mt.cuh new file mode 100755 index 00000000..7c6c2160 --- /dev/null +++ b/src - Copy (2)/const_enum_mt.cuh @@ -0,0 +1,812 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CONST_ENUM_MT_H + #define CONST_ENUM_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "macros.cuh" + #include "const_enum.cuh" + + /*********************************************************************/ + /* enumeration definitions */ + /*********************************************************************/ + namespace mt + { + /*********************** specimen layer position *********************/ + enum eSpec_Lay_Pos + { + eslp_none = 0, eslp_top = 1, eslp_bottom = 2, eslp_middle = 3, eslp_user_def = 4 + }; + + /**************** electron microscopy simulation type *****************/ + enum eEM_Sim_Typ + { + eemst_stem = 11, eemst_istem = 12, + eemst_cbed = 21, eemst_cbei = 22, + eemst_ed = 31, eemst_hrtem = 32, + eemst_ped = 41, eemst_hctem = 42, + eemst_ewfs = 51, eemst_ewrs = 52, + eemst_stem_eels = 61, eemst_istem_eels = 62, + eemst_eftemfs = 71, eemst_eftemrs = 72, + eemst_iwfs = 81, eemst_iwrs = 82, + eemst_ppfs = 91, eemst_pprs = 92, // projected potential + eemst_tffs = 101, eemst_tfrs = 102, // transmission function + eemst_propfs = 111, eemst_proprs = 112 // fcn_propagate + }; + + /*************** electron specimen interaction model ******************/ + enum eElec_Spec_Interact_Mod + { + eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 + }; + + /************************** atomic vibration **************************/ + enum eAtomic_Vib_Mod + { + eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 + }; + + /********************* simulation thickness type **********************/ + enum eSim_Thick_Typ + { + estt_whole_spec = 1, estt_through_thick = 2, estt_through_slices = 3 + }; + + /************************ specimen slicing type ***********************/ + enum eSpec_Slic_Typ + { + esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + }; + + /****************** specimen slicing selection type *******************/ + enum eSpec_Slic_Sel_Typ + { + essso_tag = 1, essso_z = 2 + }; + + /*********************** feg parameterization *************************/ + // 1: doyle and Turner parameterization - 4 Gaussians - [0, 4 + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + // 4: Kirkland parameterization - 3 lorentzian + 3 Gaussians - [0, 12] + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] + // 10: Peng et al. parameterization ion - 5 Gaussians - [0, 4] + + enum eAtomic_Pot_Parm_Typ + { + eappt_none = 0, eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, + eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6, + eappt_peng_ion_0_4 = 10 + }; + + /*********************** incident wave type **************************/ + enum eIncident_Wave_Typ + { + eiwt_plane_wave = 1, eiwt_convergent_wave = 2, eiwt_user_def_Wave = 3, eiwt_auto = 4 + }; + + /************************** zero defocus type *************************/ + enum eZero_Def_Typ + { + ezdt_first = 1, ezdt_middle = 2, ezdt_last = 3, ezdt_user_def = 4 + }; + + /************************** scan pattern type **************************/ + enum eScan_Pat_Typ + { + espt_line = 1, espt_area = 2, espt_user_def = 3 + }; + + /************************* detector type *****************************/ + enum eDetector_Typ + { + edt_circular = 1, edt_radial = 2, edt_matrix = 3 + }; + + /************************ channelling type **************************/ + // 1: single channelling + // 2: mixed channelling + // 3: double channelling + enum eChan_Typ + { + ect_single_chan = 1, ect_mixed_chan = 2, eCT_double_chan = 3 + }; + + /**************************** in atoms ****************************/ + enum eIn_Atoms + { + eIA_yes = 1, eIA_no = 2 + }; + + /************************** slice memory type ************************/ + enum eSlice_Memory_Typ + { + esmt_none = 0, esmt_transmission = 1, esmt_potential = 2 + }; + + /************************ illumination model *************************/ + enum eIllum_Mod + { + eim_none = 0, eim_coherent = 1, eim_partial_coherent = 2, eim_trans_cross_coef = 3, eim_full_integration = 4 + }; + + /*********************** illumination incoherence **********************/ + enum eIllum_Inc + { + eii_none = 0, eii_temporal_spatial = 1, eii_temporal = 2, etst_spatial = 3 + }; + + /************************** lens variable type ***********************/ + enum eLens_Var_Typ + { + eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, + eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, + eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 + }; + + /************************ phonon model output ************************/ + enum eAtomic_Vib_Mod_Output + { + epmo_total = 1, epmo_coherent = 2, epmo_total_coherent = 3 + }; + + /********************* simulation data output ************************/ + enum eEM_Output_Typ + { + eemot_image_tot_coh = 1, eemot_image_tot = 2, + eemot_m2psi_tot_coh = 3, eemot_m2psi_tot = 4, + eemot_m2psi_tot_psi_coh = 5, eemot_psi_coh = 6, + eemot_psi_0 = 7, eemot_V = 8, eemot_trans = 9 + }; + /*********************************************************************/ + /*********************************************************************/ + } + + /*********************************************************************/ + /* enumeration comparison */ + /*********************************************************************/ + + /* specimen layer position */ + namespace mt + { + inline + dt_bool is_spec_lay_top(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_top; + } + + inline + dt_bool is_spec_lay_bottom(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_bottom; + } + + inline + dt_bool is_spec_lay_middle(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_middle; + } + + inline + dt_bool is_spec_lay_user_def(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_user_def; + } + } + + /* electron microscopy simulation type */ + namespace mt + { + inline + dt_bool is_STEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_stem; + } + + inline + dt_bool is_ISTEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_istem; + } + + inline + dt_bool is_CBED(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_cbed; + } + + inline + dt_bool is_CBEI(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_cbei; + } + + inline + dt_bool is_ED(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ed; + } + + inline + dt_bool is_HRTEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_hrtem; + } + + inline + dt_bool is_PED(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ped; + } + + inline + dt_bool is_HCTEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_hctem; + } + + inline + dt_bool is_EWFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ewfs; + } + + inline + dt_bool is_EWRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ewrs; + } + + inline + dt_bool is_STEM_EELS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_stem_eels; + } + + inline + dt_bool is_ISTEM_EELS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_istem_eels; + } + + inline + dt_bool is_STEM_ISTEM_EELS(const eEM_Sim_Typ &sim_type) + { + return is_STEM_EELS(sim_type) || is_ISTEM_EELS(sim_type); + } + + inline + dt_bool is_EFTEMFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_eftemfs; + } + + inline + dt_bool is_EFTEMRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_eftemrs; + } + + inline + dt_bool is_EFTEM(const eEM_Sim_Typ &sim_type) + { + return is_EFTEMFS(sim_type) || is_EFTEMRS(sim_type); + } + + inline + dt_bool is_IWFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_iwfs; + } + + inline + dt_bool is_IWRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_iwrs; + } + + inline + dt_bool is_PPFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ppfs; + } + + inline + dt_bool is_PPRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_pprs; + } + + inline + dt_bool is_TFFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_tffs; + } + + inline + dt_bool is_TFRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_tfrs; + } + + inline + dt_bool is_PropFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_propfs; + } + + inline + dt_bool is_PropRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_proprs; + } + + inline + dt_bool is_STEM_ISTEM(const eEM_Sim_Typ &sim_type) + { + return is_STEM(sim_type) || is_ISTEM(sim_type); + } + + inline + dt_bool is_CBED_CBEI(const eEM_Sim_Typ &sim_type) + { + return is_CBED(sim_type) || is_CBEI(sim_type); + } + + inline + dt_bool is_ED_HRTEM(const eEM_Sim_Typ &sim_type) + { + return is_ED(sim_type) || is_HRTEM(sim_type); + } + + inline + dt_bool is_PED_HCTEM(const eEM_Sim_Typ &sim_type) + { + return is_PED(sim_type) || is_HCTEM(sim_type); + } + + inline + dt_bool is_EWFS_EWRS(const eEM_Sim_Typ &sim_type) + { + return is_EWFS(sim_type) || is_EWRS(sim_type); + } + + inline + dt_bool is_EELS_EFTEM(const eEM_Sim_Typ &sim_type) + { + return is_STEM_ISTEM_EELS(sim_type) || is_EFTEM(sim_type); + } + + inline + dt_bool is_IWFS_IWRS(const eEM_Sim_Typ &sim_type) + { + return is_IWFS(sim_type) || is_IWRS(sim_type); + } + + inline + dt_bool is_PPFS_PPRS(const eEM_Sim_Typ &sim_type) + { + return is_PPFS(sim_type) || is_PPRS(sim_type); + } + + inline + dt_bool is_TFFS_TFRS(const eEM_Sim_Typ &sim_type) + { + return is_TFFS(sim_type) || is_TFRS(sim_type); + } + + inline + dt_bool is_PropFS_PropRS(const eEM_Sim_Typ &sim_type) + { + return is_PropFS(sim_type) || is_PropRS(sim_type); + } + + inline + dt_bool is_grid_FS(const eEM_Sim_Typ &sim_type) + { + auto bb = is_CBED(sim_type) || is_ED(sim_type) || is_PED(sim_type) || is_EWFS(sim_type); + bb = bb || is_EFTEMFS(sim_type) || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); + return bb; + } + + inline + dt_bool is_grid_RS(const eEM_Sim_Typ &sim_type) + { + return !is_grid_FS(sim_type); + } + + inline + dt_bool is_simulation_type_FS(const eEM_Sim_Typ &sim_type) + { + auto bb = is_STEM(sim_type) || is_CBED(sim_type) || is_ED(sim_type); + bb = bb || is_PED(sim_type) || is_EWFS(sim_type) || is_STEM_EELS(sim_type); + bb = bb || is_EFTEMFS(sim_type) || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); + return bb; + } + + inline + dt_bool is_simulation_type_RS(const eEM_Sim_Typ &sim_type) + { + return !is_simulation_type_FS(sim_type); + } + + inline + dt_bool is_specimen_required(const eEM_Sim_Typ &sim_type) + { + return !(is_IWFS_IWRS(sim_type) || is_PropFS_PropRS(sim_type)); + } + + inline + dt_bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS(const eEM_Sim_Typ &sim_type) + { + return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEMRS(sim_type); + } + + inline + dt_bool is_CBED_ED_EWFS_PED(const eEM_Sim_Typ &sim_type) + { + return is_CBED(sim_type) || is_ED(sim_type) || is_EWFS(sim_type) || is_PED(sim_type); + } + + inline + dt_bool is_obj_lens_temp_spat(const eEM_Sim_Typ &sim_type) + { + return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEMRS(sim_type); + } + + inline + dt_bool is_cond_lens_temp_spat(const eEM_Sim_Typ &sim_type) + { + return is_STEM_ISTEM(sim_type) || is_CBED_CBEI(sim_type) || is_STEM_ISTEM_EELS(sim_type) || is_EFTEM(sim_type); + } + + inline + eSpace get_simulation_space(const eEM_Sim_Typ &sim_type) + { + return (is_simulation_type_FS(sim_type) || is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS(sim_type))?mt::esp_fourier:mt::esp_real; + } + + inline + dt_bool is_scanning(const eEM_Sim_Typ &sim_type) + { + return is_STEM_ISTEM(sim_type) || is_STEM_ISTEM_EELS(sim_type); + } + } + + /* electron specimen interaction model */ + namespace mt + { + inline + dt_bool is_multislice(const eElec_Spec_Interact_Mod& int_model) + { + return int_model == mt::eesim_multislice; + } + + inline + dt_bool is_phase_object(const eElec_Spec_Interact_Mod& int_model) + { + return int_model == mt::eesim_phase_object; + } + + inline + dt_bool is_weak_phase_object(const eElec_Spec_Interact_Mod& int_model) + { + return int_model == mt::eesim_weak_phase_object; + } + } + + /* atomic vibration */ + namespace mt + { + inline + dt_bool is_avm_still_atom(const eAtomic_Vib_Mod& av_model) + { + return av_model == eavm_still_atom; + } + + inline + dt_bool is_avm_absorptive_pot(const eAtomic_Vib_Mod& av_model) + { + return av_model == eavm_absorptive_pot; + } + + inline + dt_bool is_avm_frozen_phonon(const eAtomic_Vib_Mod& av_model) + { + return av_model == eavm_frozen_phonon; + } + + inline + dt_bool is_avm_frozen_phonon_sgl_conf(const eAtomic_Vib_Mod& av_model, const dt_bool& av_sgl_conf) + { + return is_avm_frozen_phonon(av_model) && av_sgl_conf; + } + } + + /* simulation thickness type */ + namespace mt + { + inline + dt_bool is_sim_whole_spec(const eSim_Thick_Typ& thick_type) + { + return thick_type == estt_whole_spec; + } + + inline + dt_bool is_sim_through_thick(const eSim_Thick_Typ& thick_type) + { + return thick_type == estt_through_thick; + } + + inline + dt_bool is_sim_through_slices(const eSim_Thick_Typ& thick_type) + { + return thick_type == estt_through_slices; + } + } + + /* specimen slicing type */ + namespace mt + { + inline + dt_bool is_spec_slic_by_plns_proj(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt:: esst_plns_proj; + } + + + inline + dt_bool is_spec_slic_by_dz_proj(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_dz_proj; + } + + dt_bool is_spec_slic_by_plns_sub(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt:: esst_plns_sub; + } + + inline + dt_bool is_spec_slic_by_dz_sub(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_dz_sub; + } + + inline + dt_bool is_spec_slic_by_user_def(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_user_def; + } + + inline + dt_bool is_spec_slic_by_auto(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_auto; + } + + inline + dt_bool is_spec_slic_by_planes(const eSpec_Slic_Typ& spec_slic_typ) + { + return is_spec_slic_by_plns_proj(spec_slic_typ) || is_spec_slic_by_plns_sub(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_plns_proj(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_plns_proj(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_dz_proj(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_dz_proj(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_plns_sub(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_plns_sub(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_dz_sub(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_dz_sub(spec_slic_typ); + } + + + inline + dt_bool is_spec_slic_planes_sub_whole_spec(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ, const eSim_Thick_Typ& thick_type) + { + return mt::is_spec_slic_by_plns_sub(int_model, spec_slic_typ) && is_sim_whole_spec(thick_type); + } + + inline + dt_bool is_spec_slic_by_dz_sub_whole_spec(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ, const eSim_Thick_Typ& thick_type) + { + return mt::is_spec_slic_by_dz_sub(int_model, spec_slic_typ) && is_sim_whole_spec(thick_type); + } + } + + /* specimen slicing selection type */ + namespace mt + { + inline + dt_bool is_spec_slic_sel_typ_by_tag(const eSpec_Slic_Sel_Typ& spec_slic_sel_typ) + { + return spec_slic_sel_typ == essso_tag; + } + + inline + dt_bool is_spec_slic_sel_typ_by_z(const eSpec_Slic_Sel_Typ& spec_slic_sel_typ) + { + return spec_slic_sel_typ == essso_z; + } + + } + + /* incident wave type */ + namespace mt + { + inline + dt_bool is_plane_wave(const eIncident_Wave_Typ& iw_type) + { + return iw_type == eiwt_plane_wave; + } + + inline + dt_bool is_convergent_wave(const eIncident_Wave_Typ& iw_type) + { + return iw_type == eiwt_convergent_wave; + } + + inline + dt_bool is_user_define_wave(const eIncident_Wave_Typ& iw_type) + { + return iw_type == eiwt_user_def_Wave; + } + } + + /* zero defocus type */ + namespace mt + { + inline + dt_bool is_zdt_first(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_first; + } + + inline + dt_bool is_zdt_middle(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_middle; + } + + inline + dt_bool is_zdt_last(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_last; + } + + inline + dt_bool is_zdt_user_def(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_user_def; + } + } + + /* detector type */ + namespace mt + { + inline + dt_bool is_detector_circular(const eDetector_Typ& det_type) + { + return det_type == edt_circular; + } + + inline + dt_bool is_detector_radial(const eDetector_Typ& det_type) + { + return det_type == edt_radial; + } + + inline + dt_bool is_detector_matrix(const eDetector_Typ& det_type) + { + return det_type == edt_matrix; + } + } + + /* scan pattern type */ + namespace mt + { + dt_bool is_scan_pat_line(const eScan_Pat_Typ& scan_pat_type) + { + return scan_pat_type == espt_line; + } + + dt_bool is_scan_pat_area(const eScan_Pat_Typ& scan_pat_type) + { + return scan_pat_type == espt_area; + } + + dt_bool is_scan_pat_user_def(const eScan_Pat_Typ& scan_pat_type) + { + return scan_pat_type == espt_user_def; + } + } + + /* mixture */ + namespace mt + { + inline + dt_bool is_EWFS_SC(const eEM_Sim_Typ &sim_type, const eAtomic_Vib_Mod& av_model, const dt_bool& pn_sgl_conf) + { + return is_EWFS(sim_type) && (!is_avm_frozen_phonon(av_model) || is_avm_frozen_phonon_sgl_conf(av_model, pn_sgl_conf)); + } + + inline + dt_bool is_EWRS_SC(const eEM_Sim_Typ &sim_type, const eAtomic_Vib_Mod& av_model, const dt_bool& pn_sgl_conf) + { + return is_EWRS(sim_type) && (!is_avm_frozen_phonon(av_model) || is_avm_frozen_phonon_sgl_conf(av_model, pn_sgl_conf)); + } + + inline + dt_bool is_EWFS_EWRS_SC(const eEM_Sim_Typ &sim_type, const eAtomic_Vib_Mod& av_model, const dt_bool& pn_sgl_conf) + { + return is_EWFS_SC(sim_type, av_model, pn_sgl_conf) || is_EWRS_SC(sim_type, av_model, pn_sgl_conf); + } + + inline + dt_bool is_EWFS_convergent_wave(const eEM_Sim_Typ &sim_type, const eIncident_Wave_Typ &iw_type) + { + return is_EWFS(sim_type) && is_convergent_wave(iw_type); + } + + inline + dt_bool is_EWRS_convergent_wave(const eEM_Sim_Typ &sim_type, const eIncident_Wave_Typ &iw_type) + { + return is_EWRS(sim_type) && is_convergent_wave(iw_type); + } + + inline + dt_bool is_EW_convergent_wave(const eEM_Sim_Typ &sim_type, const eIncident_Wave_Typ &iw_type) + { + return is_EWFS_EWRS(sim_type) && is_convergent_wave(iw_type); + } + + inline + eIncident_Wave_Typ validate_incident_wave_type(const eEM_Sim_Typ &sim_type, eIncident_Wave_Typ iw_type) + { + if (iw_type == eiwt_auto) + { + auto bb = is_scanning(sim_type) || is_CBED_CBEI(sim_type); + bb = bb || ((is_EWFS_EWRS(sim_type) || is_EFTEM(sim_type) || is_IWFS_IWRS(sim_type)) && is_convergent_wave(iw_type)); + iw_type = (bb)?mt::eiwt_convergent_wave:mt::eiwt_plane_wave; + } + + return iw_type; + } + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cpu_detail.hpp b/src - Copy (2)/cpu_detail.hpp new file mode 100755 index 00000000..b10d2247 --- /dev/null +++ b/src - Copy (2)/cpu_detail.hpp @@ -0,0 +1,80 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CPU_DETAIL_H + #define CPU_DETAIL_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + + #include "macros.cuh" + #include "const_enum.cuh" + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + + namespace mt + { + /* for loops */ + namespace cpu_detail + { + template + void for_loop(const iThread_Rect_1d& range, TFcn& fcn, TArgs& ...arg) + { + for(auto ixy = range.ind_0; ixy < range.ind_e; ixy++) + { + fcn(ixy, arg...); + } + } + + template + void for_loop(const iThread_Rect_2d& range, TFcn& fcn, TArgs& ...arg) + { + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + fcn(ix, iy, arg...); + } + } + } + + template + void for_loop(const iThread_Rect_3d& range, TFcn& fcn, TArgs& ...arg) + { + for(auto iz = range.iz_0; iz < range.iz_e; iz++) + { + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + fcn(ix, iy, iz, arg...); + } + } + } + } + } + + } + +#endif diff --git a/src - Copy (2)/cpu_fcns.hpp b/src - Copy (2)/cpu_fcns.hpp new file mode 100755 index 00000000..a540cf1c --- /dev/null +++ b/src - Copy (2)/cpu_fcns.hpp @@ -0,0 +1,3148 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CPU_FCNS_H + #define CPU_FCNS_H + + #include + #include + #include + #include + #include + #include + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_vctr.cuh" + #include "kahan_sum.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_fcns_gen.cuh" + #include "grid.cuh" + #include "cgpu_detail.cuh" + #include "cpu_detail.hpp" + #include "border.cuh" + #include "region.cuh" + #include "types.cuh" + #include "fcns_wd.cuh" + + /* vector functions */ + namespace mt + { + /***************************************************************************************/ + template + enable_if_cvctr_cpu_and_rvctr_cpu + fcn_assign_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_real = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin(), cgpu_fctr::assign_real()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_real); + } + + template + enable_if_cvctr_cpu_and_rvctr_cpu + fcn_assign_max_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_max_real = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::assign_max_real(M_v, M_v)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_max_real); + } + + template + enable_if_cvctr_and_rvctr + fcn_assign_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (M_v>0) + { + fcn_assign_max_real(mx_i, T(0), mx_o, pstream); + } + else + { + fcn_assign_real(mx_i, mx_o, pstream); + } + } + + template + enable_if_cvctr_cpu_and_rvctr_cpu + fcn_assign_abs_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_abs_real = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::assign_abs_real()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_abs_real); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_assign_abs(TVctr_c& mx_i, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_abs = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::assign_abs()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_abs); + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu + fcn_fill(TVctr& mx_io, Value_type val, Stream_cpu* pstream = nullptr) + { + auto thr_fill = [&](const iThread_Rect_1d& ithread) + { + thrust::fill(mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_e, val); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_fill); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_scale(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_o.begin() + ithread.ind_0, cgpu_fctr::scale(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_scale); + } + + template + enable_if_vctr_cpu + fcn_scale(const Value_type& w_i, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, cgpu_fctr::scale(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_scale); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_norm_2(TVctr_1& mx_i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_o.begin() + ithread.ind_0, cgpu_fctr::norm_2()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_scale_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_o.begin() + ithread.ind_0, cgpu_fctr::scale_norm_2(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_scale_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_sub(TVctr_1&& mx_1i, TVctr_1&& mx_2i, TVctr_2&& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::sub()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add(TVctr_1&& mx_1i, TVctr_1&& mx_2i, TVctr_2&& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_sub = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_sub); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add(TVctr_1&& mx_i, TVctr_2&& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add); + } + + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale(Value_type w1_i, TVctr_1& mx_1i, + Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add_scale_i(w1_i, w2_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_scale); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add_scale(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add_scale); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_norm_2(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add_norm_2_i()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_norm_2(TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add_norm_2()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale_norm_2(Value_type w1_i, TVctr_1& mx_1i, Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add_scale_norm_2_i(w1_i, w2_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_scale_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add_scale_norm_2(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add_scale_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_mult(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_mult = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::mult()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_mult); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_mult(TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_mult = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::mult()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_mult); + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu + fcn_div_sft(Value_type mx_sft, Value_type mx_div, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_div_sft = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_e, mx_io.begin() + ithread.ind_0, cgpu_fctr::div_sft(mx_sft, mx_div));; + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_div_sft); + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu> + fcn_sum(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + KS sum_total = T(0); + + if (pstream == nullptr) + { + sum_total = thrust::reduce(mx_i.begin(), mx_i.end()); + } + else + { + auto thr_sum = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_norm_2(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::norm_2(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_norm_2 = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::norm_2(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_norm_2); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::norm_2_sft(x_sft), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_norm_2_sft = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::norm_2_sft(x_sft), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_norm_2_sft); + } + + return sum_total; + } + + template + enable_if_cvctr_cpu> + fcn_sum_max_real(TVctr& mx_i, Value_type_r v_min, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::assign_max_real(v_min, T_r(0)), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_max_real = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::assign_max_real(v_min, T_r(0)), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_max_real); + } + + return sum_total; + } + + template + enable_if_cvctr_cpu> + fcn_sum_abs_real(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::assign_abs_real(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_abs_real = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::assign_abs_real(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_abs_real); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_abs(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::assign_abs(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_abs = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::assign_abs(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_abs); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::abs_sft(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_abs_sft = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::abs_sft(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_abs_sft); + } + + return sum_total; + } + + /***************************************************************************************/ + /* calculate mean */ + template + enable_if_vctr_cpu> + fcn_mean(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum(mx_i, pstream)/T(mx_i.size()); + } + + /* calculate mean of the norm square */ + template + enable_if_vctr_cpu> + fcn_mean_norm_2(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2(mx_i, pstream)/T_r(mx_i.size()); + } + + /* calculate mean of the shifted norm square */ + template + enable_if_vctr_cpu> + fcn_mean_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + template + enable_if_cvctr_cpu> + fcn_mean_max_real(TVctr& mx_i, Value_type_r v_min, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_max_real(mx_i, v_min, pstream)/T(mx_i.size()); + } + + template + enable_if_cvctr_cpu> + fcn_mean_abs_real(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_abs_real(mx_i, pstream)/T(mx_i.size()); + } + + template + enable_if_vctr_cpu> + fcn_mean_abs(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_abs(mx_i, pstream)/T(mx_i.size()); + } + + template + enable_if_vctr_cpu> + fcn_mean_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_abs_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + /***************************************************************************************/ + /* calculate mean and variance */ + template + enable_if_vctr_cpu + fcn_mean_var(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_var, Stream_cpu* pstream = nullptr) + { + x_mean = fcn_mean(mx_i, pstream); + x_var = fcn_mean_norm_2_sft(mx_i, x_mean, pstream); + } + + /* calculate mean and standard deviation */ + template + enable_if_vctr_cpu + fcn_mean_std(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_std, Stream_cpu* pstream = nullptr) + { + fcn_mean_var(mx_i, x_mean, x_std, pstream); + x_std = ::sqrt(x_std); + } + + // mean and first absolute moment + template + enable_if_vctr_cpu + fcn_mean_moment_1a(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_ma1, Stream_cpu* pstream = nullptr) + { + x_mean = fcn_mean(mx_i, pstream); + x_ma1 = fcn_mean_abs_sft(mx_i, x_mean, pstream); + } + + /* variance */ + template + enable_if_vctr_cpu> + fcn_variance(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_var; + fcn_mean_var(mx_i, x_mean, x_var, pstream); + + return x_var; + } + + /* standard deviation */ + template + enable_if_vctr_cpu> + fcn_std(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + auto x_var = fcn_variance(mx_i, pstream); + + return ::sqrt(x_var); + } + + // first absolute moment + template + enable_if_vctr_cpu> + fcn_moment_1a(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_ma1; + fcn_mean_moment_1a(mx_i, x_mean, x_ma1, pstream); + + return x_ma1; + } + + /***************************************************************************************/ + /* minimum element of a vector */ + template + enable_if_vctr_cpu> + fcn_min_element(const TVctr& x, Stream_cpu* pstream = nullptr) + { + auto x_min = x[0]; + + if (pstream == nullptr) + { + x_min = *thrust::min_element(x.begin(), x.end()); + } + else + { + auto thr_min = [&](const iThread_Rect_1d& ithread) + { + auto x_min_partial = *thrust::min_element(x.begin() + ithread.ind_0, x.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + x_min = fcn_min(x_min, x_min_partial); + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(x.size_32(), thr_min); + } + + return x_min; + } + + /* maximum element of a vector */ + template + enable_if_vctr_cpu> + fcn_max_element(const TVctr& x, Stream_cpu* pstream = nullptr) + { + auto x_max = x[0]; + + if (pstream == nullptr) + { + x_max = *thrust::max_element(x.begin(), x.end()); + } + else + { + auto thr_max = [&](const iThread_Rect_1d& ithread) + { + auto x_max_partial = *thrust::max_element(x.begin() + ithread.ind_0, x.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + x_max = fcn_max(x_max, x_max_partial); + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(x.size_32(), thr_max); + } + + return x_max; + } + + /* minimum and maximum element of a vector */ + template + enable_if_vctr_cpu + fcn_minmax_element(const TVctr& x, Value_type& x_min, Value_type& x_max, Stream_cpu* pstream = nullptr) + { + x_min = x[0]; + x_max = x[0]; + + if (pstream == nullptr) + { + auto x_min_max = thrust::minmax_element(x.begin(), x.end()); + x_min = *(x_min_max.first); + x_max = *(x_min_max.second); + } + else + { + auto thr_min_max = [&](const iThread_Rect_1d& ithread) + { + auto x_min_max_partial = thrust::minmax_element(x.begin() + ithread.ind_0, x.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + x_min = fcn_min(x_min, *(x_min_max_partial.first)); + x_max = fcn_max(x_max, *(x_min_max_partial.second)); + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(x.size_32(), thr_min_max); + } + } + } + + /* add - assign - crop - norm_2 - fftsft */ + namespace mt + { + /* shift matrix respect to nx_h */ + template + enable_if_vctr_cpu + fcn_fftsft_1d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_1d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, cgpu_detail::fcn_fftsft_1d, igrid, mx_io.m_data); + } + + /* shift matrix respect to ny_h */ + template + enable_if_vctr_cpu + fcn_fftsft_bc_2d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny_h, cgpu_detail::fcn_fftsft_bc_2d, igrid, mx_io.m_data); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + //enable_if_vctr_cpu + void fcn_fftsft_2d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + // function fcn_fftsft_2d is overloading + void (*pfcn_fftsft_2d)(const dt_int32&, const dt_int32&, const iGrid_2d&, T*) = &cgpu_detail::fcn_fftsft_2d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, pfcn_fftsft_2d, igrid, mx_io.m_data); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + enable_if_vctr_cpu + fcn_fftsft_2d(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + // function fcn_fftsft_2d is overloading + void (*pfcn_fftsft_2d)(const dt_int32&, const dt_int32&, const iGrid_2d&, T*, T*) = &cgpu_detail::fcn_fftsft_2d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, pfcn_fftsft_2d, igrid, mx_i.m_data, mx_o.m_data); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_cpu + fcn_fftsft_3d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_3d(); + + // function fcn_fftsft_3d is overloading + void (*pfcn_fftsft_3d)(const dt_int32&, const dt_int32&, const iGrid_3d&, T*) = &cgpu_detail::fcn_fftsft_3d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, igrid.nz_h, pfcn_fftsft_3d, igrid, mx_io.m_data); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_cpu + fcn_fftsft_3d(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_3d(); + + // function fcn_fftsft_3d is overloading + void (*pfcn_fftsft_3d)(const dt_int32&, const dt_int32&, const iGrid_3d&, T*, T*) = &cgpu_detail::fcn_fftsft_3d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, igrid.nz_h, pfcn_fftsft_3d, igrid, mx_i.m_data, mx_o.m_data); + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + enable_if_vctr_cpu + fcn_add_sc_fftsft_2d(TVctr& mx_i, Value_type w, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_fftsft_2d, igrid, mx_i.m_data, w, mx_o.m_data); + } + + /* add, scale, square and shift */ + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_sc_norm_2_fftsft_2d(TVctr_1& mx_i, Value_type w, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_fftsft_2d, igrid, mx_i.m_data, w, mx_o.m_data); + } + + /***************************************************************************************/ + /* assign and crop */ + template + enable_if_vctr_cpu + fcn_assign_crop_2d(TVctr& mx_i, TVctr& mx_o, iRegion_Rect_2d& iregion, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_assign_crop_2d, igrid, mx_i.m_data, iregion, mx_o.m_data); + } + + /* assign, crop and shift */ + template + enable_if_vctr_cpu + fcn_assign_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_assign_crop_fftsft_2d, igrid, mx_i.m_data, iregion, mx_o.m_data); + } + + /* add, scale, crop and shift */ + template + enable_if_vctr_cpu + fcn_add_sc_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h,cgpu_detail::fcn_add_sc_crop_fftsft_2d, igrid, mx_i.m_data, iregion, w, mx_o.m_data); + } + + /* add, scale, square, crop and shift */ + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_sc_norm_2_crop_fftsft_2d(TVctr_1& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_crop_fftsft_2d, igrid, mx_i.m_data, iregion, w, mx_o.m_data); + } + } + + /* transpose - element wise matrix op vector */ + namespace mt + { + /* transpose */ + template + enable_if_vctr_cpu>> + fcn_trs_2d(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + Vctr_cpu mx_t(mx_i.shape_2d_trs()); + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d, igrid, mx_i.m_data, mx_t.m_data); + + return mx_t; + } + + /* transpose */ + template + enable_if_vctr_cpu + fcn_trs_2d(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + if (&mx_i != &mx_o) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d, igrid, mx_i.m_data, mx_o.m_data); + } + else + { + Vctr_cpu mx_t(mx_i.shape_2d_trs()); + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d, igrid, mx_i.m_data, mx_t.m_data); + mx_t.cpy_to_cpu_ptr(mx_o.m_data, mx_o.size()); + } + + } + + /* element wise addition: matrix + vector*/ + template + enable_if_vctr_cpu + fcn_ew_add_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_col, igrid, vctr.m_data, mx_io.m_data); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_row, igrid, vctr.m_data, mx_io.m_data); + } + } + + /* element wise subtraction: matrix - vector */ + template + enable_if_vctr_cpu + fcn_ew_sub_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_col, igrid, vctr.m_data, mx_io.m_data); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_row, igrid, vctr.m_data, mx_io.m_data); + } + } + + /* element wise multiplication matrix X vector */ + template + enable_if_vctr_cpu + fcn_ew_mult_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_col, igrid, vctr.m_data, mx_io.m_data); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_row, igrid, vctr.m_data, mx_io.m_data); + } + } + } + + /* aperture functions */ + namespace mt + { + template + enable_if_vctr_cpu + fcn_fermi_aperture(Grid_2d& grid, T g2_cut, T alpha, T w, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fermi_aperture, grid, g2_cut, alpha, w, mx_io.m_data); + } + + template + enable_if_vctr_cpu + fcn_hard_aperture(Grid_2d& grid, T g2_cut, T w, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_hard_aperture, grid, g2_cut, w, mx_io.m_data); + } + } + + /* phase shifts real space*/ + namespace mt + { + template + enable_if_vctr_cpu + fcn_rs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T gx, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_rs_exp_factor_1d, grid, psi_i.m_data, gx, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &gy, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d_bc, grid, alpha, psi_i.m_data, gy.m_data, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu + fcn_rs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d g, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d, grid, psi_i.m_data, g, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& g, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_mul_exp_factor_2d, grid, psi_i.m_data, g.m_data, w, psi_o.m_data); + } + } + + /* phase shifts fourier space*/ + namespace mt + { + template + enable_if_vctr_cpu + fcn_fs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T rx, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_fs_exp_factor_1d, grid, psi_i.m_data, rx, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_fs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &ry, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d_bc, grid, alpha, psi_i.m_data, ry.m_data, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu + fcn_fs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d r, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d, grid, psi_i.m_data, r, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_fs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& r, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_mul_exp_factor_2d, grid, psi_i.m_data, r.m_data, w, psi_o.m_data); + } + } + + /* gradient */ + namespace mt + { + template + enable_if_vctr_cpu + fcn_grad_x(TVctr& mx_i, TVctr& dmx_x, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_grad_x, igrid, mx_i.m_data, dmx_x.m_data); + } + + template + enable_if_vctr_cpu + fcn_grad_y(TVctr& mx_i, TVctr& dmx_y, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_grad_y, igrid, mx_i.m_data, dmx_y.m_data); + } + + template + enable_if_vctr_cpu + fcn_grad(TVctr& mx_i, TVctr& dmx_x, TVctr& dmx_y, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_grad, igrid, mx_i.m_data, dmx_x.m_data, dmx_y.m_data); + } + } + + /* function multiplication fourier space */ + namespace mt + { + #define FCN_MULT_FS_FCN_CPU(FN, FCN, POW, DIM) \ + template \ + enable_if_vctr_cpu \ + fcn_mult_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, T w, TVctr_c& mx_io, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_mult_fs_fcn_g##POW##_##DIM##d>, grid, fcn, w, mx_io.m_data); \ + } + + /* gaussian */ + FCN_MULT_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 1); // fcn_mult_fs_gauss_1d + FCN_MULT_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 2); // fcn_mult_fs_gauss_2d + FCN_MULT_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 3); // fcn_mult_fs_gauss_3d + + /* exponential */ + FCN_MULT_FS_FCN_CPU(exp, Fcn_Exp, , 1); // fcn_mult_fs_exp_1d + FCN_MULT_FS_FCN_CPU(exp, Fcn_Exp, , 2); // fcn_mult_fs_exp_2d + FCN_MULT_FS_FCN_CPU(exp, Fcn_Exp, , 3); // fcn_mult_fs_exp_3d + + /* fermi */ + FCN_MULT_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 1); // fcn_mult_fs_fermi_1d + FCN_MULT_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 2); // fcn_mult_fs_fermi_2d + FCN_MULT_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 3); // fcn_mult_fs_fermi_3d + + /* butterworth */ + FCN_MULT_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 1); // fcn_mult_fs_butwth_1d + FCN_MULT_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 2); // fcn_mult_fs_butwth_2d + FCN_MULT_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 3); // fcn_mult_fs_butwth_3d + + /* hann */ + FCN_MULT_FS_FCN_CPU(hann, Fcn_Hann, , 1); // fcn_mult_fs_hann_1d + FCN_MULT_FS_FCN_CPU(hann, Fcn_Hann, , 2); // fcn_mult_fs_hann_2d + FCN_MULT_FS_FCN_CPU(hann, Fcn_Hann, , 3); // fcn_mult_fs_hann_3d + } + + /* convolution */ + namespace mt + { + #define FCN_CV_FS_FCN_CPU(FN, FCN, POW, DIM) \ + template \ + enable_if_cvctr_cpu \ + fcn_cv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_cpu& fft, FCN& fcn, TVctr_c& mx_io, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_mult_fs_fcn_g##POW##_##DIM##d>, grid, fcn, w, mx_io.m_data); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_CV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 1); // fcn_cv_fs_gauss_1d + FCN_CV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 2); // fcn_cv_fs_gauss_2d + FCN_CV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 3); // fcn_cv_fs_gauss_3d + + /* exponential convolution */ + FCN_CV_FS_FCN_CPU(exp, Fcn_Exp, , 1); // fcn_cv_fs_exp_1d + FCN_CV_FS_FCN_CPU(exp, Fcn_Exp, , 2); // fcn_cv_fs_exp_2d + FCN_CV_FS_FCN_CPU(exp, Fcn_Exp, , 3); // fcn_cv_fs_exp_3d + + /* fermi convolution */ + FCN_CV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 1); // fcn_cv_fs_fermi_1d + FCN_CV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 2); // fcn_cv_fs_fermi_2d + FCN_CV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 3); // fcn_cv_fs_fermi_3d + + /* butterworth convolution */ + FCN_CV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 1); // fcn_cv_fs_butwth_1d + FCN_CV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 2); // fcn_cv_fs_butwth_2d + FCN_CV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 3); // fcn_cv_fs_butwth_3d + + /* hann convolution */ + FCN_CV_FS_FCN_CPU(hann, Fcn_Hann, , 1); // fcn_cv_fs_hann_1d + FCN_CV_FS_FCN_CPU(hann, Fcn_Hann, , 2); // fcn_cv_fs_hann_2d + FCN_CV_FS_FCN_CPU(hann, Fcn_Hann, , 3); // fcn_cv_fs_hann_3d + } + + /* deconvolution */ + namespace mt + { + #define FCN_DCV_FS_FCN_CPU(FN, FCN, POW, DIM) \ + template \ + enable_if_cvctr_cpu \ + fcn_dcv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_cpu& fft, FCN& fcn, T psnr, TVctr_c& mx_io, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_dcv_fs_fcn_g##POW##_##DIM##d>, grid, fcn, psnr, w, mx_io.m_data); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_DCV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 1); // fcn_dcv_fs_gauss_1d + FCN_DCV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 2); // fcn_dcv_fs_gauss_2d + FCN_DCV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 3); // fcn_dcv_fs_gauss_3d + + /* exponential convolution */ + FCN_DCV_FS_FCN_CPU(exp, Fcn_Exp, , 1); // fcn_dcv_fs_exp_1d + FCN_DCV_FS_FCN_CPU(exp, Fcn_Exp, , 2); // fcn_dcv_fs_exp_2d + FCN_DCV_FS_FCN_CPU(exp, Fcn_Exp, , 3); // fcn_dcv_fs_exp_3d + + /* fermi convolution */ + FCN_DCV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 1); // fcn_dcv_fs_fermi_1d + FCN_DCV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 2); // fcn_dcv_fs_fermi_2d + FCN_DCV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 3); // fcn_dcv_fs_fermi_3d + + /* butterworth convolution */ + FCN_DCV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 1); // fcn_dcv_fs_butwth_1d + FCN_DCV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 2); // fcn_dcv_fs_butwth_2d + FCN_DCV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 3); // fcn_dcv_fs_butwth_3d + + /* hann convolution */ + FCN_DCV_FS_FCN_CPU(hann, Fcn_Hann, , 1); // fcn_dcv_fs_hann_1d + FCN_DCV_FS_FCN_CPU(hann, Fcn_Hann, , 2); // fcn_dcv_fs_hann_2d + FCN_DCV_FS_FCN_CPU(hann, Fcn_Hann, , 3); // fcn_dcv_fs_hann_3d + } + + /* window functions */ + namespace mt + { + //template + //enable_if_vctr_cpu + //fcn_wd_fcn_xd(Grid_xd& grid, Wd_fcn_xd& fcn, dt_bool sft, TVctr& mx_o, Stream_cpu* pstream = nullptr) + //{ + // using U = Value_type; + // + // if (sft) + // { + // fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_sft_xd, grid, fcn, mx_o.m_data); + // } + // else + // { + // fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_xd, grid, fcn, mx_o.m_data) + // } + //} + + // FCN_WD_FCN_CPU(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + // FCN_WD_FCN_CPU(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + // FCN_WD_FCN_CPU(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + // FCN_WD_FCN_CPU(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + // FCN_WD_FCN_CPU(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + // FCN_WD_FCN_CPU(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + // FCN_WD_FCN_CPU(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + // FCN_WD_FCN_CPU(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + // FCN_WD_FCN_CPU(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + // FCN_WD_FCN_CPU(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + // FCN_WD_FCN_CPU(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + // FCN_WD_FCN_CPU(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + // FCN_WD_FCN_CPU(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + // FCN_WD_FCN_CPU(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + // FCN_WD_FCN_CPU(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d + + #define FCN_WD_FCN_CPU(FN, FCN, DIM) \ + template \ + enable_if_vctr_cpu \ + fcn_wd_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, dt_bool sft, TVctr& mx_o, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + if (sft) \ + { \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_sft_##DIM##d>, grid, fcn, mx_o.m_data); \ + } \ + else \ + { \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_##DIM##d>, grid, fcn, mx_o.m_data); \ + } \ + } + + FCN_WD_FCN_CPU(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + FCN_WD_FCN_CPU(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + FCN_WD_FCN_CPU(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + FCN_WD_FCN_CPU(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + FCN_WD_FCN_CPU(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + FCN_WD_FCN_CPU(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + FCN_WD_FCN_CPU(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + FCN_WD_FCN_CPU(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + FCN_WD_FCN_CPU(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + FCN_WD_FCN_CPU(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + FCN_WD_FCN_CPU(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + FCN_WD_FCN_CPU(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + FCN_WD_FCN_CPU(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + FCN_WD_FCN_CPU(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + FCN_WD_FCN_CPU(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d + } + + /* phase correlation */ + namespace mt + { + /****************** pcf data processing real space *******************/ + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Butwth_1d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_rs_pcf_1d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Butwth_2d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_pcf_2d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Butwth_3d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_rs_pcf_3d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + /***************** pcf data processing fourier space *****************/ + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Gauss_1d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_fs_pcf_1d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Gauss_2d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_pcf_2d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Gauss_3d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_fs_pcf_3d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + } + + /* optical flow */ + namespace mt + { + template + enable_if_vctr_cpu + fcn_opt_flow(TVctr& mx_s, TVctr& mx_m, T alpha, TVctr& dphi_x, TVctr& dphi_y, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto igrid = mx_s.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_opt_flow, igrid, mx_s.m_data, mx_m.m_data, alpha, dphi_x.m_data, dphi_y.m_data); + } + } + + /* bilinear interpolation */ + namespace mt + { + template + enable_if_vctr_cpu + fcn_intrpl_bl_rg_2d(Grid_2d& grid, TVctr& mx_i, TVctr& vx, TVctr& vy, T bg, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_intrpl_bl_rg_2d, grid, mx_i.m_data, vx.m_data, vy.m_data, bg, mx_o.m_data); + } + } + + /* histogram */ + namespace mt + { + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_hist(const TVctr_1& vctr, const Value_type& n_bins, TVctr_2& y, TVctr_2& x) + { + using T1 = Value_type; + using T2 = Value_type; + using size_type = Size_type; + + T1 vctr_min = 0; + T1 vctr_max = 0; + fcn_minmax_element(vctr, vctr_min, vctr_max); + auto dv = dt_float64(vctr_max-vctr_min)/dt_float64(n_bins); + + fcn_fill(y, T2(0)); + + const auto vctr_size = vctr.size(); + + for(size_type iv = 0; iv< vctr_size; iv++) + { + auto val = dt_float64(vctr[iv]); + auto iy = fcn_bcfloor((val - dt_float64(vctr_min))/dv, size_type(0), size_type(n_bins-1)); + y[iy]++; + } + + for(size_type ix = 0; ix < n_bins; ix++) + { + x[ix] = T2(vctr_min + dt_float64(ix)*dv); + } + } + } + + /* anscombe transform */ + namespace mt + { + /* forward anscombe transform */ + template + enable_if_vctr_cpu + fcn_anscombe(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto thr_anscombe_fwd = [](const iThread_Rect_1d& ithread, pVctr_cpu_32& mx_i, pVctr_cpu_32& mx_o) + { + thrust::transform(mx_i.begin()+ithread.ind_0, mx_i.begin()+ithread.ind_e, + mx_o.begin()+ithread.ind_0, cgpu_fctr::anscombe_fwd()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_i.size_32(), thr_anscombe_fwd, mx_i.ptr_32(), mx_o.ptr_32()); + } + + /* forward anscombe transform */ + template + enable_if_vctr_cpu + fcn_anscombe_inv(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto thr_anscombe_inv = [](const iThread_Rect_1d& ithread, pVctr_cpu_32& mx_i, pVctr_cpu_32& mx_o) + { + thrust::transform(mx_i.begin()+ithread.ind_0, mx_i.begin()+ithread.ind_e, + mx_o.begin()+ithread.ind_0, cgpu_fctr::anscombe_inv()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_i.size_32(), thr_anscombe_inv, mx_i.ptr_32(), mx_o.ptr_32()); + } + } + + /* border */ + namespace mt + { + /* replace border */ + template + enable_if_vctr_cpu>> + fcn_repl_bdr(TVctr& mx_i, iBorder_Rect_2d& iborder, eFil_Sel_Typ bg_opt=efst_min, Value_type bg=0, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + iRegion_Rect_2d iregion({iborder.bx_0, igrid.nx - iborder.bx_e, iborder.by_0, igrid.ny - iborder.by_e}); + + dt_int32 ic = 0; + T v_min = mx_i(iregion.ry_0, iregion.rx_0); + T v_max = v_min; + KS v_mean = 0; + + Vctr_cpu mx_o(mx_i); + + if (bg_opt<6) + { + for(auto ix = iregion.rx_0; ix < iregion.rx_e; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto v = mx_i(iy, ix); + v_min = fcn_min(v_min, v); + v_max = fcn_max(v_max, v); + v_mean += dt_float64(v); + ic++; + } + } + v_mean = v_mean/T(ic); + } + + auto val_f = fcn_select_bg(bg_opt, v_min, v_max, T(v_mean()), bg); + + // left + for(auto ix = 0; ix < iregion.rx_0; ix++) + { + for(auto iy = 0; iy < igrid.ny; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + // right + for(auto ix = iregion.rx_e; ix < igrid.nx; ix++) + { + for(auto iy = 0; iy < igrid.ny; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + // top + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = 0; iy < iregion.ry_0; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + // bottom + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = iregion.ry_e; iy < igrid.ny; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + return mx_o; + } + + /* add pbc border */ + template + enable_if_vctr_cpu>> + fcn_add_pbdr(TVctr& mx_i, iBorder_Rect_2d& iborder) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + iRegion_Rect_2d iregion({iborder.bx_0, igrid.nx + iborder.bx_0, iborder.by_0, igrid.ny + iborder.by_0}); + + Vctr_cpu mx_o(dt_shape(igrid.ny + iborder.by_sum(), igrid.nx + iborder.bx_sum())); + igrid.set_size(mx_o.s1_32(), mx_o.s0_32()); + + // copy central mx_i + for(auto ix = iregion.rx_0; ix < iregion.rx_e; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto ix_i = ix - iregion.rx_0; + const auto iy_i = iy - iregion.ry_0; + mx_o(iy, ix) = mx_i(iy_i, ix_i); + } + } + + // left + for(auto ix = 0; ix < iregion.rx_0; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto ix_i = 2*iregion.rx_0 - ix; + mx_o(iy, ix) = mx_o(iy, ix_i); + } + } + + // right + for(auto ix = iregion.rx_e; ix < igrid.nx; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto ix_i = max(0, iregion.rx_e - 1 - (ix - iregion.rx_e)); + mx_o(iy, ix) = mx_o(iy, ix_i); + } + } + + // top + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = 0; iy < iregion.ry_0; iy++) + { + const auto iy_i = 2*iregion.ry_0 - iy; + mx_o(iy, ix) = mx_o(iy_i, ix); + } + } + + // bottom + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = iregion.ry_e; iy < igrid.ny; iy++) + { + const auto iy_i = max(0, iregion.ry_e - 1 - (iy - iregion.ry_e)); + mx_o(iy, ix) = mx_o(iy_i, ix); + } + } + + return mx_o; + } + } + + /* radial distribution */ + namespace mt + { + // radial distribution: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist(TVctr& r_i, TVctr& fr_i, Value_type r_0, Value_type r_e, + dt_int32 n_r, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ, const TFcn& fcn) + { + using T = Value_type; + + const T dr = (r_e-r_0)/T(n_r); + + for(auto ir = 0; ir < n_r; ir++) + { + rl_o[ir] = r_0 + T(ir)*dr; + frl_o[ir] = T(0); + cfrl_o[ir] = T(0); + } + + for(auto ir = 0; ir < r_i.size(); ir++) + { + const auto r = r_i[ir]; + if (fcn_chk_bound(r, r_0, r_e)) + { + const auto ik = fcn(r); + frl_o[ik] += fr_i[ir]; + cfrl_o[ik] += T(1); + } + } + + if ((typ == 0) || (typ == 2)) + { + for(auto ir = 0; ir < n_r; ir++) + { + frl_o[ir] /= fcn_max(T(1), cfrl_o[ir]); + } + } + + if (typ > 1) + { + for(auto ir = 1; ir < n_r; ir++) + { + frl_o[ir] += frl_o[ir - 1]; + } + } + } + + // radial distribution by division: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist_by_div(TVctr& r_i, TVctr& fr_i, Value_type r_0, Value_type r_e, + dt_int32 n_r, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + const T dr = (r_e-r_0)/T(n_r); + + cgpu_fctr::rad_dist_ind_by_div fcn(r_0, dr, 0, n_r-1); + + fcn_rad_dist(r_i, fr_i, r_0, r_e, n_r, rl_o, frl_o, cfrl_o, typ, fcn); + } + + // radial distribution by search: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist_by_srch(TVctr& r_i, TVctr& fr_i, Value_type r_0, Value_type r_e, + dt_int32 n_r, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + + cgpu_fctr::rad_dist_ind_by_srch fcn(rl_o.data(), 0, n_r-1); + + fcn_rad_dist(r_i, fr_i, r_0, r_e, n_r, rl_o, frl_o, cfrl_o, typ, fcn); + } + } + + /* radial distribution 2d */ + namespace mt + { + // radial distribution 2d: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist_2d(Grid_2d>& grid, TVctr& mx_i, R_2d> p_c, + Value_type radius_i, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ, const TFcn& fcn) + { + using T = Value_type; + + dt_int32 ix_0, ix_e; + grid.ix_0_ix_e(p_c.x, radius_i, ix_0, ix_e); + + dt_int32 iy_0, iy_e; + grid.iy_0_iy_e(p_c.y, radius_i, iy_0, iy_e); + + const auto r2_max = ::square(radius_i); + const auto dr = grid.drx; + + for(auto ir = 0; ir < rl_o.size(); ir++) + { + rl_o[ir] = grid.rx(ir); + frl_o[ir] = T(0); + cfrl_o[ir] = T(0); + } + + for(auto ix = ix_0; ix < ix_e; ix++) + { + for(auto iy = iy_0; iy < iy_e; iy++) + { + const auto r2 = grid.r2(ix, iy, p_c); + if (r2 < r2_max) + { + const auto ir = fcn(::sqrt(r2)); + frl_o[ir] += mx_i[grid.sub_2_ind(ix, iy)]; + cfrl_o[ir] += T(1); + } + } + } + + if ((typ == 0) || (typ == 2)) + { + for(auto ir = 0; ir < rl_o.size(); ir++) + { + frl_o[ir] /= fcn_max(T(1), cfrl_o[ir]); + } + } + + if (typ > 1) + { + for(auto ir = 1; ir < rl_o.size(); ir++) + { + frl_o[ir] += frl_o[ir - 1]; + } + } + } + + + // radial distribution 2d by division + template + enable_if_vctr_cpu + fcn_rad_dist_2d_by_div(Grid_2d>& grid, TVctr& mx_i, R_2d> p_c, + Value_type radius_i, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + + cgpu_fctr::rad_dist_ind_by_div fcn(0, grid.drx, 0, rl_o.size()-1); + + fcn_rad_dist_2d(grid, mx_i, p_c, radius_i, rl_o, frl_o, cfrl_o, typ, fcn); + } + + // radial distribution 2d by search + template + enable_if_vctr_cpu + fcn_rad_dist_2d_by_srch(Grid_2d>& grid, TVctr& mx_i, R_2d> p_c, + Value_type radius_i, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + + cgpu_fctr::rad_dist_ind_by_srch fcn(rl_o.data(), 0, rl_o.size()-1); + + fcn_rad_dist_2d(grid, mx_i, p_c, radius_i, rl_o, frl_o, cfrl_o, typ, fcn); + } + } + + /* information limit for regular grid */ + namespace mt + { + /* filter mean */ + namespace cpu_fcn_image + { + /* 1d */ + template + enable_if_vctr_cpu + fltr_mean_1d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream); + } + + template + Value_type fcn_info_lim_2d(TGrid& grid, TVctr& mx_i) + { + using T = Value_type; + + const auto r_c = grid.bs_h(); + const auto radius = grid.bs_h_min(); + const auto n_r = fcn_min(grid.nx_h, grid.ny_h); + + Vctr_cpu r(n_r); + Vctr_cpu fr(n_r); + Vctr_cpu cfr(n_r); + + // cumulative radial integration + fcn_rad_dist_2d_by_div(grid, mx_i.ptr_64(), r_c, grid.bs_h_min(), r.ptr_64(), fr.ptr_64(), cfr.ptr_64(), 2); + + // shift and normalize + const T r_0 = r.front(); + const T fr_0 = fr.front(); + const T dr = r.back() - r_0; + const T dfr = fr.back() - fr_0; + for(auto ir = 0; ir < fr.size(); ir++) + { + r[ir] = (r[ir] - r_0)/dr; + fr[ir] = (fr[ir] - fr_0)/dfr; + } + + // fcn_smooth_mean_1d data + const dt_int32 nkr = max(5, fr.size()/100); + cpu_fcn_image::fltr_mean_1d(fr, nkr, cfr); + fr = cfr; + + // get maximum curvature point + dt_int32 ir_m = 0; + auto d_max = fcn_get_max_crv_2_ln_dist(r.front(), fr.front(), r.back(), fr.back(), 0, r.size(), r.data(), fr.data(), ir_m); + + return grid.rx(ir_m); + } + } + + /* unique / match vector */ + namespace mt + { + template + enable_if_vctr_cpu + fcn_uniq_vctr(TVctr& vctr) + { + using T = Value_type; + + std::sort(vctr.begin(), vctr.end()); + const auto size = std::distance(vctr.begin(), std::unique(vctr.begin(), vctr.end(), mt::fcn_is_equal)); + + if (vctr.s0()==1) + { + vctr.resize({1, size}); + } + else + { + vctr.resize({size, 1}); + } + } + + template + enable_if_vctr_cpu + fcn_match_vctr(InputIterator v_first, InputIterator v_last, TVctr& vs, Value_type dv=0.1) + { + using T = Value_type; + + TVctr vr(v_first, v_last); + + // find min and max values + T v_min, v_max; + fcn_minmax_element(vr, v_min, v_max); + + // add tolerance + v_min -= dv; + v_max += dv; + + // remove elements of vs outside the ithread + auto fcn_rm = [v_min, v_max](T a)->dt_bool + { + return ((a < v_min) || (a > v_max)); + }; + + const auto size = std::distance(vr.begin(), std::remove_if(vs.begin(), vs.end(), fcn_rm)); + vr.resize(size); + + vs.erase(std::remove_if(vs.begin(), vs.end(), fcn_rm), vs.end()); + + Vctr v_c(vr.size(), true); + dt_int32 m_size = min(vr.size(), vs.size()); + TVctr A_d; + A_d.reserve(m_size); + + for(auto i = 0; i < vs.size(); i++) + { + T val = vs[i]; + auto it = std::min_element(vr.begin(), vr.end(), cgpu_fctr::closest_element(val)); + auto imin = static_cast(it - vr.begin()); + + if (v_c[imin]) + { + v_c[imin] = false; + A_d.push_back(*it); + } + } + vs = A_d; + vs.shrink_to_fit(); + } + } + + namespace mt + { + // /***************************************************************************************/ + // /***************************************************************************************/ + // template + // enable_if_vctr_cpu_and_vctr_cpu + // cpy_to_host(Stream_cpu& stream, TVctr_i &mx_i, TVctr_o &mx_o, + // TVctr_i *M_i_h = nullptr) + // { + // mt::assign(mx_i, mx_o, M_i_h); + // } + + // template + // enable_if_vctr_cpu_and_vctr_cpu + // add_sc_to_host(Stream_cpu& stream, Value_type w_i, + // TVctr_i &mx_i, TVctr_o &mx_o, TVctr_i *M_i_h = nullptr) + // { + // mt::add_scale(stream, w_i, mx_i, mx_o); + // } + + // template + // enable_if_vctr_cpu_and_vctr_cpu + // add_sc_square_to_host(Stream_cpu& stream, Value_type w_i, + // TVctr_i &mx_i, TVctr_o &mx_o, TVctr_i *M_i_h = nullptr) + // { + // mt::add_scale_norm_2(stream, w_i, mx_i, mx_o); + // } + + // template + // enable_if_vctr_cpu_and_vctr_cpu + // add_sc_m2psi_psi_to_host(Stream_cpu& stream, Value_type w_i, + // TVctr_c_i &psi_i, TVctr_r_o &m2psi_o, TVctr_c_o &psi_o, TVctr_c_i *psi_i_h = nullptr) + // { + // mt::add_scale(stream, w_i, psi_i, psi_o); + // mt::add_scale_norm_2(stream, w_i, psi_i, m2psi_o); + // } + // /***************************************************************************************/ + // /***************************************************************************************/ + // template + // TVctr lsf_poly_n(TVctr& x, TVctr& y, dt_int32 n) + // { + // using T = Value_type; + + // dt_int32 m = x.size(); + // n++; // add bias term + + // TVctr M(m*n); + // for(auto in = 0; in < n; in++) + // { + // for(auto im = 0; im < m; im++) + // { + // M[in*m + im] = (in == 0)?1:x[im] * M[(in - 1)*m + im]; + // } + // } + + // TVctr coef(n); + // lapack::GELS gels; + // gels(m, n, M.data(), 1, y.data(), coef.data()); + + // return coef; + // } + + // /***************************************************************************************/ + // // extract region ix_0<=x + // TVctr_o extract_region_real_part(Stream_cpu& stream, dt_int32 nx_src, dt_int32 ny_src, + // TVctr_i &Im_src, dt_int32 ix0_src, dt_int32 ixe_src, dt_int32 iy0_src, dt_int32 iye_src) + // { + // auto nx_dst = ixe_src - ix0_src; + // auto ny_dst = iye_src - iy0_src; + + // TVctr_o Im_dst(nx_dst*ny_dst); + + // auto thr_extract_region = [&](const iRegion_Rect_2d& ithread) + // { + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + // { + // Im_dst[ix*ny_dst + iy] = Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)].real(); + // } + // } + // }; + + // stream.set_n_stream_act(nx_dst); + // stream.set_grid(nx_dst, ny_dst); + // stream.exec_xd_fcn(thr_extract_region); + + // return Im_dst; + // } + + // // extract real part of vector + // template + // TVctr_o extract_real_part(Stream_cpu& stream, TVctr_i &Im_src) + // { + // TVctr_o Im_dst(Im_src.size()); + + // auto thr_extract_real = [](const iThread_Rect_2d& ithread, TVctr_i &Im_src, TVctr_o &Im_dst) + // { + // for(auto ixy = ithread.ind_0; ixy < ithread.ind_e; ixy++) + // { + // Im_dst[ixy] = Im_src[ixy].real(); + // } + // }; + + // stream.set_n_stream_act(Im_src.size()); + // stream.set_grid(Im_src.size(), 1); + // stream.exec_xd_fcn(thr_extract_real, Im_src, Im_dst); + + // return Im_dst; + // } + + // // extract region ix_0<=x + // TVctr_o extract_region_abs(Stream_cpu& stream, dt_int32 nx_src, dt_int32 ny_src, + // TVctr_i &Im_src, dt_int32 ix0_src, dt_int32 ixe_src, dt_int32 iy0_src, dt_int32 iye_src) + // { + // auto nx_dst = ixe_src - ix0_src; + // auto ny_dst = iye_src - iy0_src; + + // TVctr_o Im_dst(nx_dst*ny_dst); + + // auto thr_extract_region = [&](const iThread_Rect_2d& ithread) + // { + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + // { + // Im_dst[ix*ny_dst + iy] = fabs(Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)]); + // } + // } + // }; + + // stream.set_n_stream_act(nx_dst); + // stream.set_grid(nx_dst, ny_dst); + // stream.exec_xd_fcn(thr_extract_region); + + // return Im_dst; + // } + + // // extract abs of vector + // template + // TVctr_o extract_abs(Stream_cpu& stream, TVctr_i &Im_src) + // { + // TVctr_o Im_dst(Im_src.size()); + + // auto thr_extract_abs = [](const iThread_Rect_2d& ithread, TVctr_i &Im_src, TVctr_o &Im_dst) + // { + // for(auto ixy = ithread.ind_0; ixy < ithread.ind_e; ixy++) + // { + // Im_dst[ixy] = fabs(Im_src[ixy]); + // } + // }; + + // stream.set_n_stream_act(Im_src.size()); + // stream.set_grid(Im_src.size(), 1); + // stream.exec_xd_fcn(thr_extract_abs, Im_src, Im_dst); + + // return Im_dst; + // } + + // /***************************************************************************************/ + // // get weighted position + // template + // R_2d> Rx_Ry_weight(TGrid& grid_2d, TVctr& Im, R_2d> p_i, Value_type radius_i, dt_bool env) + // { + // using T = Value_type; + + // T dR = grid_2d.drx; + // dt_int32 nrl = static_cast(::floor(radius_i/dR + 0.5)); + // T R_max = dR*nrl; + + // auto ix_i = static_cast(::floor(p_i.x/dR)); + // dt_int32 ix_0 = max(ix_i - nrl, 0); + // dt_int32 ix_e = min(ix_i + nrl + 1, grid_2d.nx); + + // auto iy_i = static_cast(::floor(p_i.y/dR)); + // dt_int32 iy_0 = max(iy_i - nrl, 0); + // dt_int32 iy_e = min(iy_i + nrl + 1, grid_2d.ny); + + // T R2_max = pow(R_max, 2); + + // R_2d p(0, 0); + + // T alpha = 0.5/pow(R_max, 2); + // T wt = 0; + // for(auto ix = ix_0; ix < ix_e; ix++) + // { + // for(auto iy = iy_0; iy < iy_e; iy++) + // { + // auto R2 = grid_2d.r2(ix, iy, p_i.x, p_i.y); + // if (R2 < R2_max) + // { + // dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + // auto imv = ((env)?exp(-alpha*R2):1)*Im[ixy]; + // p += imv*R_2d(grid_2d.rx(ix), grid_2d.ry(iy)); + // wt += imv; + // } + // } + // } + // p /= wt; + + // if (norm(p - p_i) >= radius_i) + // { + // p = p_i; + // } + + // return p; + // } + + // // fit gaussian 1d + // template + // TVctr fit_gauss_1d(TGrid& grid_1d, TVctr& Im_i, Value_type x_i, + // Value_type sigma_i, Value_type radius_i) + // { + // using T = Value_type; + + // auto select_cir_reg = [](TGrid& grid_1d, TVctr& Im, T x0, + // T radius, TVctr& Rx, TVctr& Ix, T& Rx_sf, T& Rx_sc, T& Ix_sc) + // { + // T R_max = radius; + // T R2_max = pow(R_max, 2); + + // auto ithread = grid_1d.region_ind(x0, R_max); + + // Rx.clear(); + // Rx.reserve(ithread.ind_e); + // Ix.clear(); + // Ix.reserve(ithread.ind_e); + + // // select circular region + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // if (grid_1d.r2(ix, x0) < R2_max) + // { + // Rx.push_back(grid_1d.rx(ix)); + // Ix.push_back(Im[ix]); + // } + // } + + // Rx_sf = x0; + // Rx_sc = R_max; + + // Ix_sc = fcn_max_element(Ix); + // dt_int32 m = Ix.size(); + // for(auto ix = 0; ix < m; ix++) + // { + // Rx[ix] = (Rx[ix] - Rx_sf)/Rx_sc; + // Ix[ix] = Ix[ix]/Ix_sc; + // } + + // Rx.shrink_to_fit(); + // Ix.shrink_to_fit(); + // }; + + // TVctr Rx, Ix; + // T Rx_sf, Rx_sc, Ix_sc; + + // select_cir_reg(grid_1d, Im_i, x_i, radius_i, Rx, Ix, Rx_sf, Rx_sc, Ix_sc); + + // T sigma = sigma_i/Rx_sc; + + // dt_int32 m = Ix.size(); + // dt_int32 n = 3; + + // TVctr J(m*n); + // TVctr d_Ix(m); + + // auto get_chi2 = [](TVctr& Rx, TVctr& Ix, TVctr& coef)->T + // { + // T x0 = coef[0]; + // T A = coef[1]; + // T alpha = 0.5/pow(coef[2], 2); + + // T chi2 = 0; + // T chi2_ee = 0; + // const dt_int32 m = Ix.size(); + // for(auto im = 0; im < m; im++) + // { + // T x = Rx[im] - x0; + // T v = Ix[im] - A*exp(-alpha*x*x); + // fcn_kh_sum(chi2, v*v, chi2_ee); + // } + // return chi2; + // }; + + // auto get_dIx_J = [](TVctr& Rx, TVctr& Ix, TVctr& coef, + // TVctr& dIx, TVctr& J) + // { + // T x0 = coef[0]; + // T A = coef[1]; + // T alpha = 0.5/pow(coef[2], 2); + + // T c_x0 = 1.0/pow(coef[2], 2); + // T c_A = 1; + // T c_sx = 1.0/pow(coef[2], 3); + + // const dt_int32 m = Ix.size(); + // for(auto im = 0; im < m; im++) + // { + // T x = Rx[im] - x0; + // T v = exp(-alpha*x*x); + // T f = A*v; + + // J[0 * m + im] = c_x0*x*f; + // J[1 * m + im] = c_A*v; + // J[2 * m + im] = c_sx*x*x*f; + + // dIx[im] = Ix[im] - f; + // } + // }; + + // T dx_max = ::fmax(grid_1d.drx/Rx_sc, 0.25*::fmin(sigma, radius_i/Rx_sc)); + + // vector c_coef_0 = { 0, 1, sigma }; + // vector c_coef_min = { -dx_max, 0.5, sigma/3 }; + // vector c_coef_max = { dx_max, 1.25, 3 * sigma }; + + // TVctr coef_0 = c_coef_0; + // TVctr coef_min = c_coef_min; + // TVctr coef_max = c_coef_max; + // TVctr coef = coef_0; + + // T chi2 = get_chi2(Rx, Ix, coef); + + // T lambda = 2; + // T lambda_f = 2; + + // lapack::LSF_1 fls_1; + + // const dt_int32 niter = 100; + // for(auto iter = 0; iter < niter; iter++) + // { + // get_dIx_J(Rx, Ix, coef, d_Ix, J); + + // TVctr d_coef(n); + // TVctr D(n); + // TVctr G(n); + // fls_1(m, n, J.data(), d_Ix.data(), d_coef.data(), lambda, D.data(), G.data()); + + // TVctr coef_t = coef; + // T rho_f = 0; + // T G_max = 0; + // for(auto ic = 0; ic < n; ic++) + // { + // coef_t[ic] += d_coef[ic]; + // rho_f += coef_t[ic] * (D[ic] * coef_t[ic] + G[ic]); + // G_max = ::fmax(G_max, fabs(G[ic])); + // } + + // T chi2_t = get_chi2(Rx, Ix, coef_t); + // T rho = (chi2 - chi2_t)/rho_f; + + // if ((G_max < 5e-7) || fabs(chi2 - chi2_t) < 5e-8) + // { + // break; + // } + + // if (rho > 0) + // { + // coef = coef_t; + + // for(auto ic = 0; ic < n; ic++) + // { + // coef[ic] = min(max(coef[ic], coef_min[ic]), coef_max[ic]); + // } + + // chi2 = get_chi2(Rx, Ix, coef); + + // lambda = (rho > 1e-6)?(::fmax(lambda/lambda_f, 1e-7)):lambda; + // } + // else + // { + // lambda = ::fmin(lambda*lambda_f, 1e+7); + // } + // } + + // coef[0] = coef[0] * Rx_sc + Rx_sf; + // coef[1] = coef[1] * Ix_sc; + // coef[2] = coef[2] * Rx_sc; + + // return coef; + // } + + // template + // Value_type neighbor_radius(TGrid& grid_i, TVctr& Im_i, R_2d> p_i, Value_type radius_i) + // { + // using T = Value_type; + + // T R2_max = pow(radius_i, 2); + + // dt_int32 ix_0 = grid_i.rx_2_irx_bfds(p_i.x - radius_i); + // dt_int32 ix_e = grid_i.rx_2_irx_bcds(p_i.x + radius_i); + + // dt_int32 iy_0 = grid_i.ry_2_iry_bfds(p_i.y - radius_i); + // dt_int32 iy_e = grid_i.ry_2_iry_bcds(p_i.y + radius_i); + + // dt_int32 nrl = grid_i.r_2_ir_cds_dr_min(radius_i); + + // // get radial distribution + // TVctr frl(nrl); + // TVctr cfrl(nrl); + + // T dR = grid_i.dR_min(); + + // for(auto ix = ix_0; ix < ix_e; ix++) + // { + // for(auto iy = iy_0; iy < iy_e; iy++) + // { + // T R2_d = grid_i.r2(ix, iy, p_i.x, p_i.y); + // if (R2_d < R2_max) + // { + // auto ir = static_cast(::floor(::sqrt(R2_d)/dR)); + // frl[ir] += Im_i[grid_i.sub_2_ind(ix, iy)]; + // cfrl[ir] += 1.0; + // } + // } + // } + + // for(auto ir = 0; ir < frl.size(); ir++) + // { + // frl[ir] /= ::fmax(1.0, cfrl[ir]); + // } + + // frl[0] = ::fmax(frl[0], 1.01*frl[1]); + + // frl = fcn_smooth_mean_1d(frl, 1); + + // // derivative and minimum + // dt_int32 ir0 = frl.size() - 1; + // for(auto ir = 0; ir < frl.size() - 1; ir++) + // { + // if (frl[ir] < frl[ir + 1]) + // { + // ir0 = ir + 1; + // break; + // } + // } + + // dt_int32 irm = frl.size() - 1; + // for(auto ir = ir0; ir < frl.size() - 1; ir++) + // { + // if (frl[ir] > frl[ir + 1]) + // { + // irm = ir; + // break; + // } + // } + + // return max(2, irm)*dR; + // } + + // // select circular region + // template + // Value_type mean_cir_reg(TGrid& grid_i, TVctr& Im_i, R_2d> p_i, + // Value_type radius_i, Value_type bg_i) + // { + // using T = Value_type; + + // T R2_max = radius_i*radius_i; + + // auto ithread = grid_i.region_ind(p_i, radius_i); + + // // select circular region + // T I_mean = 0; + // dt_int32 Ic = 0; + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + // { + // T R2_d = grid_i.r2(ix, iy, p_i.x, p_i.y); + // if (R2_d < R2_max) + // { + // I_mean += Im_i[grid_i.sub_2_ind(ix, iy)] - bg_i; + // Ic++; + // } + // } + // } + // I_mean /= Ic; + // return I_mean; + // } + + // /***************************************************************************************/ + // template + // TVctr intrplprofile(TGrid& grid_2d, TVctr& Im, const R_2d>& p1, const R_2d>& p2, dt_int32 nr) + // { + // TVctr v; + + // if (!(grid_2d.chk_bound_eps(p1) && grid_2d.chk_bound_eps(p2))) + // { + // return v; + // } + + // if (norm(p1 - p2) < grid_2d.dR_min()) + // { + // return v; + // } + + // using T = Value_type; + + // auto fcn_intrpl_bl_rg_2d = [](const R_2d& p, TGrid& grid_2d, TVctr& Im)->T + // { + // auto ix = grid_2d.rx_2_irx_bfds(p.x); + // auto iy = grid_2d.ry_2_iry_bfds(p.y); + + // T f11 = Im[grid_2d.sub_2_ind(ix, iy)]; + // T f12 = Im[grid_2d.sub_2_ind(ix, iy + 1)]; + // T f21 = Im[grid_2d.sub_2_ind(ix + 1, iy)]; + // T f22 = Im[grid_2d.sub_2_ind(ix + 1, iy + 1)]; + + // T x1 = grid_2d.rx(ix); + // T x2 = grid_2d.rx(ix + 1); + // T y1 = grid_2d.ry(iy); + // T y2 = grid_2d.ry(iy + 1); + + // T dx1 = p.x - x1; + // T dx2 = x2 - p.x; + // T dy1 = p.y - y1; + // T dy2 = y2 - p.y; + + // T f = (dx2*(f11*dy2 + f12*dy1) + dx1*(f21*dy2 + f22*dy1))/((x2 - x1)*(y2 - y1)); + // return f; + + // }; + + // R_2d p12 = p2 - p1; + // T mp12 = p12.norm(); + + // nr = (nr <= 0)?static_cast(::ceil(mp12/grid_2d.dR_min())):nr; + // nr = max(nr, 2); + // T dr = mp12/(nr - 1); + // R_2d u = dr*normalize(p12); + + // v.reserve(nr); + // for(auto ir = 0; ir < nr; ir++) + // { + // R_2d p = p1 + T(ir)*u; + // v.push_back(fcn_intrpl_bl_rg_2d(p, grid_2d, Im)); + // } + // return v; + // } + + // template + // void intrplprofile(Stream_cpu& stream, TGrid& grid_2d, TVctr& Im, Value_type bg, R_2d> p1, R_2d> p2, + // TVctr& x, TVctr& y) + // { + // x.clear(); + // y.clear(); + + // if (!(grid_2d.chk_bound_eps(p1) && grid_2d.chk_bound_eps(p2))) + // { + // return; + // } + + // if (norm(p1 - p2) < grid_2d.dR_min()) + // { + // return; + // } + + // using T = Value_type; + + // auto fcn_intrpl_bl_rg_2d = [](const R_2d& p, TGrid& grid_2d, TVctr& Im)->T + // { + // auto ix = grid_2d.rx_2_irx_bfds(p.x); + // auto iy = grid_2d.ry_2_iry_bfds(p.y); + + // T f11 = Im[grid_2d.sub_2_ind(ix, iy)]; + // T f12 = Im[grid_2d.sub_2_ind(ix, iy + 1)]; + // T f21 = Im[grid_2d.sub_2_ind(ix + 1, iy)]; + // T f22 = Im[grid_2d.sub_2_ind(ix + 1, iy + 1)]; + + // T x1 = grid_2d.rx(ix); + // T x2 = grid_2d.rx(ix + 1); + // T y1 = grid_2d.ry(iy); + // T y2 = grid_2d.ry(iy + 1); + + // T dx1 = p.x - x1; + // T dx2 = x2 - p.x; + // T dy1 = p.y - y1; + // T dy2 = y2 - p.y; + + // T f = (dx2*(f11*dy2 + f12*dy1) + dx1*(f21*dy2 + f22*dy1))/((x2 - x1)*(y2 - y1)); + // return f; + + // }; + + // dt_int32 Ixy_1 = Im[grid_2d.rv_2_ir_bfds(p1.x, p1.y)]; + // dt_int32 Ixy_2 = Im[grid_2d.rv_2_ir_bfds(p2.x, p2.y)]; + + // R_2d p12 = p2 - p1; + // T mp12 = p12.norm(); + // dt_int32 nr = grid_2d.r_2_ir_cds_dr_min(mp12); + // T dr = mp12/(nr - 1); + // R_2d u = dr*normalize(p12); + + // x.reserve(nr); + // y.reserve(nr); + // for(auto ir = 0; ir < nr; ir++) + // { + // x.push_back(ir*dr); + // R_2d p = p1 + T(ir)*u; + // T v = fcn_intrpl_bl_rg_2d(p, grid_2d, Im); + // y.push_back(v - bg); + // } + // } + + // // find one maximum in all areas above the thr + // template + // TVctr fd_peaks_vector_typ_1(TVctr& x, TVctr& y, Value_type y_thr) + // { + // using T = Value_type; + // TVctr x_peak(y.size()); + + // T x_max = 0; + // T y_max = y_thr; + // dt_bool bb = y[0] > y_thr; + // dt_int32 ipeak = 0; + // for(auto ix = 0; ix < y.size(); ix++) + // { + // if (y[ix] > y_thr) + // { + // if (y_max < y[ix]) + // { + // y_max = y[ix]; + // x_max = x[ix]; + // } + // bb = true; + // } + // else if (bb) + // { + // x_peak[ipeak++] = x_max; + // y_max = y_thr; + // bb = false; + // } + // } + + // if (bb) + // { + // x_peak[ipeak++] = x_max; + // } + + // x_peak.resize(ipeak); + // x_peak.shrink_to_fit(); + + // return x_peak; + // } + + // // find all maximum in all areas above the thr + // template + // TVctr fd_peaks_vector_typ_2(TVctr& x, TVctr& y, Value_type y_thr) + // { + // using T = Value_type; + // TVctr x_peak; + // x_peak.reserve(y.size()); + + // for(auto ix = 1; ix < y.size() - 1; ix++) + // { + // if (y[ix] > y_thr) + // { + // if ((y[ix - 1] < y[ix]) && (y[ix + 1] < y[ix])) + // { + // x_peak.push_back(x[ix]); + // } + // } + // } + // x_peak.shrink_to_fit(); + + // return x_peak; + // } + + // /***************************************************************************************/ + // // find peak position 1d + // template + // enable_if_vctr_cpu> + // fit_max_pos_1d(TGrid& grid_1d, TVctr& Im, Value_type p_i, + // Value_type sigma_i, Value_type radius_i) + // { + // using T = Value_type; + + // auto ithread = grid_1d.region_ind(p_i, radius_i); + // dt_int32 ix_c = grid_1d.rx_2_irx_fds(p_i); + + // dt_int32 ix_0 = ithread.ix_0; + // for(auto ix = ix_c - 1; ix >= ithread.ix_0; ix--) + // { + // if (Im[ix - 1] > Im[ix]) + // { + // ix_0 = ix; + // break; + // } + // } + + // dt_int32 ix_e = ithread.ix_e; + // for(auto ix = ix_c + 1; ix <= ithread.ix_e; ix++) + // { + // if (Im[ix] < Im[ix + 1]) + // { + // ix_e = ix; + // break; + // } + // } + + // // if there are few points + // if (fabs(ix_e - ix_0) <= 3) + // { + // T x = 0; + // T sI = 0; + // for(auto ix = ix_0; ix <= ix_e; ix++) + // { + // x += Im[ix] * grid_1d.rx(ix); + // sI += Im[ix]; + // } + // x = x/sI; + + // return x; + // } + + // if ((ix_0 = !ithread.ix_0) || (ix_e = !ithread.ix_e)) + // { + // T x_min = grid_1d.rx(ix_0); + // T x_max = grid_1d.rx(ix_e); + // radius_i = ::fmin(p_i - x_min, x_max - p_i); + // } + + // auto coef = fit_gauss_1d(grid_1d, Im, p_i, sigma_i, radius_i); + + // return coef[0]; + // } + + // /***************************************************************************************/ + // // get projective standard deviation + // template + // TVctr projected_intensity(TGrid& grid_2d, TVctr& mx_i, Value_type np_min, Value_type delta) + // { + // using T = Value_type; + + // vector> pts_c = { R_2d(0, 0), R_2d(grid_2d.nx - 1, 0), R_2d(grid_2d.nx - 1, grid_2d.ny - 1), R_2d(0, grid_2d.ny - 1) }; + + // auto n_pp = static_cast(::ceil(norm(R_2d(grid_2d.nx, grid_2d.ny)) + 2)); + // TVctr y_pt(n_pp); + // TVctr c_pt(n_pp); + + // T cos_d, sin_d; + // sincos(delta, &sin_d, &cos_d); + + // // get projected points + // auto krn_proj_point = [&](const T& cos_d, const T& sin_d, const R_2d& p)->R_2d + // { + // return R_2d(cos_d*p.x + sin_d*p.y, -sin_d*p.x + cos_d*p.y); + // }; + + // // get reference corner point + // auto p_0 = krn_proj_point(cos_d, sin_d, pts_c[0]); + // for(auto ixy = 1; ixy < pts_c.size(); ixy++) + // { + // auto p_r = krn_proj_point(cos_d, sin_d, pts_c[ixy]); + // if (p_0.y > p_r.y) + // { + // p_0 = p_r; + // } + // } + + // for(auto ix = 0; ix < grid_2d.nx; ix++) + // { + // for(auto iy = 0; iy < grid_2d.ny; iy++) + // { + // auto ixy = grid_2d.sub_2_ind(ix, iy); + // auto p_r = krn_proj_point(cos_d, sin_d, R_2d(ix, iy)) - p_0; + // auto j = static_cast(::floor(p_r.y)); + // y_pt[j] += mx_i[ixy]; + // c_pt[j] += 1; + // } + // } + + // TVctr V_o; + // V_o.reserve(n_pp); + // for(auto j = 0; j < n_pp; j++) + // { + // if (c_pt[j] > np_min) + // { + // V_o.push_back(y_pt[j]/c_pt[j]); + // } + // } + // V_o.shrink_to_fit(); + + // return V_o; + // } + + // // get projective standard deviation + // template + // void PSD(Stream_cpu& stream, TGrid& grid_2d, TVctr& mx_i, Value_type np_min, + // Value_type del_0, Value_type del_e, Value_type d_del, TVctr& x_o, TVctr& y_o) + // { + // // get number of angles + // auto n_delta = static_cast(::floor((del_e - del_0)/d_del + 0.5)); + // x_o.resize(n_delta); + // y_o.resize(n_delta); + + // auto thr_psd = [&](const iThread_Rect_2d& ithread) + // { + // for(auto idel = ithread.ind_0; idel < ithread.ind_e; idel++) + // { + // auto delta = (del_0 + idel*d_del)*c_pi/180; + // x_o[idel] = delta * 180/c_pi; + + // auto pIm = projected_intensity(grid_2d, mx_i, np_min, delta); + + // y_o[idel] = fcn_variance(pIm); + // } + // }; + + // stream.set_n_stream_act(n_delta); + // stream.set_grid(n_delta); + // stream.exec_xd_fcn(thr_psd); + // } + + // // get projective standard deviation + // template + // TVctr PSD_fd_peaks(Stream_cpu& stream, TGrid& grid_2d, TVctr& mx_i, Value_type np_min, + // TVctr x_i, TVctr y_i) + // { + // using T = Value_type; + + // T d_del = fabs(x_i[1] - x_i[0]); + // dt_int32 nr = max(1, static_cast(::ceil(3.0/d_del))); + // auto y_f = fltr_median_1d(stream, y_i, nr); + + // T y_mean = 0; + // T y_max = y_i[0] - y_f[0]; + // for(auto ix = 0; ix < y_i.size(); ix++) + // { + // y_f[ix] = y_i[ix] - y_f[ix]; + // y_mean += y_f[ix]; + // y_max = max(y_max, y_f[ix]); + // } + // y_mean /= y_i.size(); + // auto y_thr = y_mean + 0.2*(y_mean + y_max); + + // auto x_peaks = fd_peaks_vector_typ_1(x_i, y_f, y_thr); + + // TVctr x_ref, y_ref; + // for(auto ix = 0; ix < x_peaks.size(); ix++) + // { + // auto delta = x_peaks[ix]; + // auto delta_0 = delta - d_del; + // auto delta_e = delta + d_del; + // auto d_delta = 0.1*d_del; + // PSD(stream, grid_2d, mx_i, np_min, delta_0, delta_e, d_delta, x_ref, y_ref); + // std::for_each(y_ref.begin(), y_ref.end(), [](T& y) {y = log(1 + y); }); + // auto coef = lsf_poly_n(x_ref, y_ref, 2); + // T px = -coef[1]/(2 * coef[2]); + // if ((px <= delta_0) || (delta_e <= px)) + // { + // dt_int32 idx = std::max_element(y_ref.begin(), y_ref.end()) - y_ref.begin(); + // px = x_ref[idx]; + // } + // x_peaks[ix] = px; + // } + + // return x_peaks; + // } + // /************************ read matlab binary file ***********************/ + // template + // enable_if_float + // read_mat_matrix(std::ifstream &bin_file, dt_int32 nxy, TVctr& matrix) + // { + // using T_o = Value_type; + + // vector vect_r(nxy); + // bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T_i)); + + // for(auto ik = 0; ik < nxy; ik++) + // { + // matrix[ik] = T_o(vect_r[ik]); + // } + // } + + // template + // enable_if_cfloat + // read_mat_matrix(std::ifstream &bin_file, dt_int32 nxy, TVctr& matrix) + // { + // using T = Value_type_r; + // using T_o = Value_type_r; + + // vector vect_r(nxy); + // bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T)); + // vector vect_i(nxy); + // bin_file.read(reinterpret_cast(vect_i.data()), nxy * sizeof(T)); + + // auto matrix_ptr = reinterpret_cast*>(matrix.data()); + + // for(auto ik = 0; ik < nxy; ik++) + // { + // matrix_ptr[ik].real(vect_r[ik]); + // matrix_ptr[ik].imag(vect_i[ik]); + // } + // } + + // template + // void read_mat_binary_matrix(const char *filename, Grid_2d>& grid_2d, TVctr& matrix) + // { + // dt_int32 nx, ny; + // dt_float64 dx, dy; + // dt_int32 type; + + // std::ifstream bin_file(filename, std::ofstream::binary); + // bin_file.read(reinterpret_cast(&nx), sizeof(dt_int32)); + // bin_file.read(reinterpret_cast(&ny), sizeof(dt_int32)); + // bin_file.read(reinterpret_cast(&dx), sizeof(dt_float64)); + // bin_file.read(reinterpret_cast(&dy), sizeof(dt_float64)); + // bin_file.read(reinterpret_cast(&type), sizeof(dt_int32)); + + // grid_2d.set_in_data(nx, ny, nx*dx, ny*dy); + + // auto nxy = nx*ny; + // matrix.resize(nxy); + + // switch (type) + // { + // case 1: + // { + // read_mat_matrix(bin_file, nxy, matrix); + // } + // break; + // case 2: + // { + // read_mat_matrix(bin_file, nxy, matrix); + // } + // break; + // case 3: + // { + // read_mat_matrix>(bin_file, nxy, matrix); + // } + // break; + // case 4: + // { + // read_mat_matrix>(bin_file, nxy, matrix); + // } + // break; + // } + // bin_file.close(); + // } + // /************************ write matlab binary file ***********************/ + // template + // enable_if_real_vctr_cpu + // write_mat_matrix(std::ofstream &bin_file, TVctr& matrix) + // { + // // using T = Value_type; + + // // bin_file.write(reinterpret_cast(matrix.data()), matrix.size()*sizeof(T)); + // } + + // template + // enable_if_cfloat_vctr_cpu + // write_mat_matrix(std::ofstream &bin_file, TVctr& matrix) + // { + // // using T = Value_type_r; + + // // vector vect_r(nxy); + // // vector vect_i(nxy); + // // for(auto ik = 0; ik(vect_r.data()), matrix.size()*sizeof(T)); + // // bin_file.write(reinterpret_cast(vect_i.data()), matrix.size()*sizeof(T)); + // } + + // template + // void write_mat_binary_matrix(const char *filename, Grid_2d>& grid_2d, TVctr& matrix) + // { + // // dt_int32 type = matrix_type; + + // // std::ofstream bin_file(filename, std::ofstream::binary); + // // bin_file.write(reinterpret_cast(&(grid_2d.nx)), sizeof(dt_int32)); + // // bin_file.write(reinterpret_cast(&(grid_2d.ny)), sizeof(dt_int32)); + // // bin_file.write(reinterpret_cast(&(grid_2d.drx)), sizeof(dt_float64)); + // // bin_file.write(reinterpret_cast(&(grid_2d.dry)), sizeof(dt_float64)); + // // bin_file.write(reinterpret_cast(&type), sizeof(dt_int32)); + + // // switch (type) + // // { + // // case 1: + // // { + // // write_mat_matrix(bin_file, matrix); + // // } + // // break; + // // case 2: + // // { + // // write_mat_matrix(bin_file, matrix); + // // } + // // break; + // // case 3: + // // { + // // write_mat_matrix>(bin_file, matrix); + // // } + // // break; + // // case 4: + // // { + // // write_mat_matrix>(bin_file, matrix); + // // } + // // break; + // // } + // // bin_file.close(); + // } + + // /************************ extract real vector form complex vector**********************/ + // template + // void from_complex_to_real(eShow_CData show_data, TVctr_c& cdata, TVctr_r &data) + // { + // switch (show_data) + // { + // case escd_creal: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = cdata[ixy].real(); + // } + // break; + // case escs_cimag: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = cdata[ixy].imag(); + // } + // break; + // case escd_cmod: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = abs(cdata[ixy]); + // } + // break; + // case escd_cphase: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = arg(cdata[ixy]); + // } + // break; + // } + // } + } + + namespace mt + { + // /***************************************************************************************/ + // template + // enable_if_vctr_cpu> + // atom_cost_function(TGrid& grid_2d, const Atom_Sa>& atom_Ip, TVctr_r& mx_i) + // { + // return cpu_detail::atom_cost_function(grid_2d, atom_Ip, mx_i); + // } + + // template + // enable_if_vctr_cpu + // subtract_atom(Stream_cpu& stream, TGrid& grid_2d, Vctr>, edev_cpu>& atom_Ip, TVctr_r& mx_i) + // { + // if (stream.n_stream_act <= 0) + // { + // return; + // } + + // for(auto istm = 0; istm < stream.n_stream_act; istm++) + // { + // stream[istm] = std::thread(std::bind(cpu_detail::subtract_atom, std::ref(stream), std::ref(grid_2d), std::ref(atom_Ip[istm]), std::ref(mx_i))); + // } + // stream.synchronize(); + // } + + // // Linear projected potential: V and zV + // template + // enable_if_host + // linear_Vz(Stream_cpu& stream, eAtomic_Pot_Parm_Typ atomic_pot_parm_typ, TQ1 &qz, TVAtom &vatom) + // { + // using TAtom = Value_type; + + // if (stream.n_stream_act <= 0) + // { + // return; + // } + + // auto thr_linear_Vz = [](const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, TQ1 &qz, TAtom &atom) + // { + // if (atom.charge == 0) + // { + // switch (atomic_pot_parm_typ) + // { + // case eappt_doyle_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_kirkland_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_weickenmeier_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_lobato_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // } + // } + // else + // { + // switch (atomic_pot_parm_typ) + // { + // case eappt_doyle_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_kirkland_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_weickenmeier_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_lobato_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // } + // } + // }; + + // for(auto istm = 0; istm < stream.n_stream_act - 1; istm++) + // { + // stream[istm] = std::thread(std::bind(thr_linear_Vz, atomic_pot_parm_typ, std::ref(qz), std::ref(vatom[istm]))); + // } + + // thr_linear_Vz(atomic_pot_parm_typ, qz, vatom[stream.n_stream_act - 1]); + + // stream.synchronize(); + // } + + // // Get local interpolation coefficients + // template + // enable_if_host + // fcn_vd_2_coef_poly3(Stream_cpu& stream, TVAtom &vatom) + // { + // using TAtom = Value_type; + + // if (stream.n_stream_act <= 0) + // { + // return; + // } + + // for(auto istm = 0; istm < stream.n_stream_act - 1; istm++) + // { + // stream[istm] = std::thread(std::bind(cpu_detail::fcn_vd_2_coef_poly3, std::ref(vatom[istm]))); + // } + + // cpu_detail::fcn_vd_2_coef_poly3(vatom[stream.n_stream_act - 1]); + + // stream.synchronize(); + // } + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/cpu_fcns_image.hpp b/src - Copy (2)/cpu_fcns_image.hpp new file mode 100755 index 00000000..1edc81e1 --- /dev/null +++ b/src - Copy (2)/cpu_fcns_image.hpp @@ -0,0 +1,1005 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CPU_FCNS_IMAGE_H + #define CPU_FCNS_IMAGE_H + + #include + #include + #include + + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_stream.cuh" + #include "r_2d.cuh" + #include "cpu_fcns.hpp" + + namespace mt + { + /* threshold */ + namespace cpu_fcn_image + { + /* otsu threshold*/ + template + enable_if_vctr_cpu> + fcn_otsu_thr(const TVctr& vctr, const dt_uint32& n_bins) + { + using T = dt_float64; + using size_type = Size_type; + + Vctr_cpu vctr_rang(n_bins); + Vctr_cpu vctr_hist(n_bins); + + /* get histogram */ + fcn_hist(vctr, n_bins, vctr_hist, vctr_rang); + + T sum_i = T(); + for(size_type ibins = 0; ibins < n_bins; ibins++) + { + sum_i += vctr_rang[ibins]*vctr_hist[ibins]; + } + + T sum_b = T(); + + dt_int64 w_b = dt_int64(); + dt_int64 w_f = dt_int64(); + + T var_max = T(); + T thr = T(); + + dt_int64 vctr_size = dt_int64(vctr.size()); + + for(size_type ibins = 0; ibins < n_bins; ibins++) + { + /* weight background */ + w_b += dt_int64(vctr_hist[ibins]); + + if (w_b == 0) + { + continue; + } + + /* weight foreground */ + w_f = vctr_size - w_b; + if (w_f == 0) + { + break; + } + + sum_b += vctr_rang[ibins]*vctr_hist[ibins]; + + /* fcn_mean background */ + T m_B = sum_b/T(w_b); + + /* fcn_mean Foreground */ + T m_F = (sum_i - sum_b)/T(w_f); + + /* calculate Between class Variance */ + auto var_between = T(w_b)*T(w_f)*::square(m_B-m_F); + + /* check if new maximum found */ + if (var_between > var_max) + { + var_max = var_between; + thr = vctr_rang[ibins]; + } + } + + return Value_type(thr); + } + + /* matrix binarization */ + template + enable_if_vctr_cpu>> + fcn_binarize_mx(const TVctr& mx_i, const Value_type& thr, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + Vctr_cpu mx_o(mx_i.shape()); + + auto thr_binarize_mx = [&](const iThread_Rect_1d &ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::binarize(thr)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_binarize_mx); + + return mx_o; + } + + /* maximum threshold */ + template + enable_if_vctr_cpu>> + fcn_threshold_max(const TVctr& mx_i, const Value_type& thr, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + Vctr_cpu mx_o(mx_i.shape()); + + auto thr_threshold_max = [&](const iThread_Rect_1d &ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::threshold_max(thr)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_threshold_max); + + return mx_o; + } + + /* maximum threshold */ + template + enable_if_vctr_cpu>> + fcn_threshold_min(const TVctr& mx_i, const Value_type& thr, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + Vctr_cpu mx_o(mx_i.shape()); + + auto thr_threshold_min = [&](const iThread_Rect_1d &ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::threshold_min(thr)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_threshold_min); + + return mx_o; + } + } + + /* morphological operations */ + namespace cpu_fcn_image + { + /* gray scale dilation */ + template + enable_if_vctr_cpu>> + fcn_morp_op(TVctr& mx_i, dt_int32 nkr, TFcn fcn, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + Vctr_cpu mx_o(mx_i.shape()); + + /* column dilation and transpose*/ + auto thr_morp_op = [nkr, fcn](const iThread_Rect_2d& ithread, pVctr_cpu_32& mx_i, pVctr_cpu_32& mx_o) + { + std::deque wd; + + const dt_int32 ny = mx_i.m_s0; + const dt_int32 nx = mx_i.m_s1; + const dt_int32 wkr = 2*nkr+1; + + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + dt_int32 iy = 0; + dt_int32 iy_tk = 0; + dt_int32 iy_o = 0; + + for(; iy < nkr; iy++) + { + fcn(ix, iy, mx_i, wd); + } + + for(; iy < ny; iy++, iy_o++) + { + fcn(ix, iy, mx_i, wd); + + mx_o[iy_o*nx + ix] = mx_i(wd.front(), ix); + if (iy + 1 >= wkr) + { + if (wd.front() == iy_tk) + { + wd.pop_front(); + } + iy_tk++; + } + } + + for(; iy_o < ny; iy_o++) + { + mx_o[iy_o*nx + ix] = mx_i(wd.front(), ix); + if (wd.front() == iy_tk) + { + wd.pop_front(); + } + iy_tk++; + } + wd.clear(); + } + }; + + /* run dilation along y */ + fcn_stream_exec_xd_fcn(pstream, mx_i.s1_32(), mx_i.s0_32(), thr_morp_op, mx_i.ptr_32(), mx_o.ptr_32()); + + auto mx_t = mx_o; + + /* transpose shape */ + mx_t.trs_shape_2d(); + + /* run dilation along y */ + fcn_stream_exec_xd_fcn(pstream, mx_t.s1_32(), mx_t.s0_32(), thr_morp_op, mx_t.ptr_32(), mx_o.ptr_32()); + + return mx_o; + } + + /* gray value data dilation */ + template + enable_if_vctr_cpu>> + fcn_morp_op_dilate(TVctr& mx_i, dt_int32 nkr, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto fcn_wedge_push = [](const dt_int32& ix, const dt_int32& iy, pVctr_cpu_32& mx_i, std::deque& wd) + { + while ((!wd.empty()) && (mx_i(wd.back(), ix) <= mx_i(iy, ix))) + { + wd.pop_back(); + } + wd.push_back(iy); + }; + + return fcn_morp_op(mx_i, nkr, fcn_wedge_push, pstream); + } + + /* gray value data erosion */ + template + enable_if_vctr_cpu>> + fcn_morp_op_erode(TVctr& mx_i, dt_int32 nkr, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto fcn_wedge_push = [](const dt_int32& ix, const dt_int32& iy, pVctr_cpu_32& mx_i, std::deque& wd) + { + while ((!wd.empty()) && (mx_i(wd.back(), ix) >= mx_i(iy, ix))) + { + wd.pop_back(); + } + wd.push_back(iy); + }; + + return fcn_morp_op(mx_i, nkr, fcn_wedge_push, pstream); + } + + /* gray value data opening */ + template + enable_if_vctr_cpu>> + fcn_morp_op_open(TVctr& mx_i, dt_int32 nkr, Stream_cpu* pstream = nullptr) + { + auto mx_o = fcn_morp_op_erode(mx_i, nkr, pstream); + return fcn_morp_op_dilate(mx_o, nkr, pstream); + } + + /* gray value data closing */ + template + enable_if_vctr_cpu>> + fcn_morp_op_close(TVctr& mx_i, dt_int32 nkr, Stream_cpu* pstream = nullptr) + { + auto mx_o = fcn_morp_op_dilate(mx_i, nkr, pstream); + return fcn_morp_op_erode(mx_o, nkr, pstream); + } + + /* gray value datatophat */ + template + enable_if_vctr_cpu>> + fcn_morp_op_tophat(TVctr& mx_i, dt_int32 nkr, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto mx_o = fcn_morp_op_open(mx_i, nkr, pstream); + fcn_sub(mx_i.ptr_32(), mx_o.ptr_32(), mx_o.ptr_32(), pstream); + + return mx_o; + } + } + + /* filter wiener */ + namespace cpu_fcn_image + { + /* 1d */ + template + enable_if_vctr_cpu + fltr_wiener_1d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.size_32(); + + Vctr_cpu mx_mean(nx_i, T(0)); + Vctr_cpu mx_var(nx_i, T(0)); + + /* get local mean and var */ + auto krn_mean_var = [n_k0, n_ke, nx_i, &mx_i](const dt_int32& ix_i, Vctr_cpu& mx_mean, Vctr_cpu& mx_var, KS& v2) + { + const dt_int32 ix_0 = fcn_max(ix_i+n_k0, 0); + const dt_int32 ix_e = fcn_min(ix_i+n_ke, nx_i); + + T v_mean = 0; + T v_var = 0; + for(auto ix = ix_0; ix < ix_e; ix++) + { + const auto x = mx_i[ix]; + v_mean += x; + v_var += x*x; + } + + v_mean = v_mean/T(ix_e-ix_0); + v_var = v_var/T(ix_e-ix_0) - v_mean*v_mean; + + mx_mean[ix_i] = v_mean; + mx_var[ix_i] = v_var; + + v2 += v_var; + }; + + auto v2 = fcn_stream_exec_xd_krn_reduce(pstream, nx_i, std::plus>(), T(0), krn_mean_var, mx_mean, mx_var); + v2 /= T(nx_i); + + /* apply wiener filter */ + auto krn_fltr_wiener = [v2, &mx_i, &mx_o](const dt_int32& ix, Vctr_cpu& mx_mean, Vctr_cpu& mx_var) + { + mx_o[ix] = mx_mean[ix] + ::fmax(T(0), mx_var[ix]-v2)*(mx_i[ix]-mx_mean[ix])/::fmax(mx_var[ix], v2); + }; + + fcn_stream_exec_xd_krn(pstream, nx_i, krn_fltr_wiener, mx_mean, mx_var); + } + + /* 2d by col */ + template + enable_if_vctr_cpu + fltr_wiener_2d_bc(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.s1_32(); + const dt_int32 ny_i = mx_i.s0_32(); + + Vctr_cpu mx_mean(mx_i.shape(), T(0)); + Vctr_cpu mx_var(mx_i.shape(), T(0)); + + /* get local mean and var */ + auto krn_mean_var = [n_k0, n_ke, ny_i, &mx_i](const dt_int32& ix_i, const dt_int32& iy_i, Vctr_cpu& mx_mean, Vctr_cpu& mx_var) + { + const dt_int32 iy_0 = max(iy_i+n_k0, 0); + const dt_int32 iy_e = min(iy_i+n_ke, ny_i); + + T v_mean = 0; + T v_var = 0; + for(auto iy = iy_0; iy < iy_e; iy++) + { + const auto y = mx_i(iy, ix_i); + v_mean += y; + v_var += y*y; + } + + v_mean = v_mean/T(iy_e-iy_0); + v_var = v_var/T(iy_e-iy_0) - v_mean*v_mean; + + const auto ind = mx_i.sub_2_ind(iy_i, ix_i); + mx_mean[ind] = v_mean; + mx_var[ind] = v_var; + }; + + fcn_stream_exec_xd_krn(pstream, nx_i, ny_i, krn_mean_var, mx_mean, mx_var); + + /* apply wiener filter */ + auto krn_fltr_wiener = [ny_i, &mx_i, &mx_o](const dt_int32& ix_i, Vctr_cpu& mx_mean, Vctr_cpu& mx_var) + { + KS v2 = T(0); + for(auto iy = 0; iy < ny_i; iy++) + { + v2 += mx_var(iy, ix_i); + } + v2 /= T(ny_i); + + for(auto iy = 0; iy < ny_i; iy++) + { + auto ind = mx_i.sub_2_ind(iy, ix_i); + mx_o[ind] = mx_mean[ind] + ::fmax(T(0), mx_var[ind]-v2.m_sum)*(mx_i[ind]-mx_mean[ind])/::fmax(mx_var[ind], v2.m_sum); + } + }; + + fcn_stream_exec_xd_krn(pstream, nx_i, krn_fltr_wiener, mx_mean, mx_var); + } + + /* 2d */ + template + enable_if_vctr_cpu + fltr_wiener_2d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.s1_32(); + const dt_int32 ny_i = mx_i.s0_32(); + + const T radius_2 = ::square(T(n_kr)) + epsilon_rel(); + + Vctr_cpu mx_mean(mx_i.shape(), T(0)); + Vctr_cpu mx_var(mx_i.shape(), T(0)); + + /* get local mean and var */ + auto krn_mean_var = [n_k0, n_ke, radius_2, nx_i, ny_i, &mx_i](const dt_int32& ix_i, const dt_int32& iy_i, Vctr_cpu& mx_mean, Vctr_cpu& mx_var, KS& v2) + { + const dt_int32 ix_0 = max(ix_i+n_k0, 0); + const dt_int32 ix_e = min(ix_i+n_ke, nx_i); + + const dt_int32 iy_0 = max(iy_i+n_k0, 0); + const dt_int32 iy_e = min(iy_i+n_ke, ny_i); + + T v_mean = 0; + T v_var = 0; + for(auto ix = ix_0; ix < ix_e; ix++) + { + for(auto iy = iy_0; iy < iy_e; iy++) + { + if (R_2d(ix-ix_i, iy-iy_i).norm_2()<=radius_2) + { + const auto y = mx_i(iy, ix); + v_mean += y; + v_var += y*y; + } + } + } + + v_mean = v_mean/T((iy_e-iy_0)*(ix_e-ix_0)); + v_var = v_var/T((iy_e-iy_0)*(ix_e-ix_0)) - v_mean*v_mean; + + const auto ind = mx_i.sub_2_ind(iy_i, ix_i); + mx_mean[ind] = v_mean; + mx_var[ind] = v_var; + + v2 += v_var; + }; + + auto v2 = fcn_stream_exec_xd_krn_reduce(pstream, nx_i, ny_i, std::plus>(), T(0), krn_mean_var, mx_mean, mx_var); + v2 /= T(nx_i*ny_i); + + /* apply wiener filter */ + auto krn_fltr_wiener = [nx_i, ny_i, v2, &mx_i, &mx_o](const dt_int32& ix, const dt_int32& iy, Vctr_cpu& mx_mean, Vctr_cpu& mx_var) + { + auto ind = mx_i.sub_2_ind(iy, ix); + mx_o[ind] = mx_mean[ind] + ::fmax(T(0), mx_var[ind]-v2)*(mx_i[ind]-mx_mean[ind])/::fmax(mx_var[ind], v2); + }; + + fcn_stream_exec_xd_krn(pstream, nx_i, ny_i, krn_fltr_wiener, mx_mean, mx_var); + } + } + + /* filter mean */ + namespace cpu_fcn_image + { + /* 1d */ + template + enable_if_vctr_cpu + fltr_mean_1d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.size_32(); + + auto thr_fltr_mean = [n_k0, n_ke, nx_i, &mx_i, &mx_o](const iThread_Rect_1d& ithread) + { + std::vector vctr_t(n_ke-n_k0); + + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + const dt_int32 ix_0 = fcn_max(ind+n_k0, 0); + const dt_int32 ix_e = fcn_min(ind+n_ke, nx_i); + + T mv = T(0); + dt_int32 ic = 0; + for(auto ix = ix_0; ix < ix_e; ix++) + { + mv += mx_i[ix]; + ic++; + } + + mx_o[ind] = mv/T(ic); + } + }; + + fcn_stream_exec_xd_fcn(pstream, nx_i, thr_fltr_mean); + } + + /* 2d */ + template + enable_if_vctr_cpu + fltr_mean_2d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.s1_32(); + const dt_int32 ny_i = mx_i.s0_32(); + + const T radius_2 = ::square(T(n_kr)) + epsilon_rel(); + + auto thr_fltr_mean = [n_k0, n_ke, radius_2, nx_i, ny_i, &mx_i, &mx_o](const iThread_Rect_2d& ithread) + { + std::vector vctr_t(::square(n_ke-n_k0)); + + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + const dt_int32 ix_0 = max(ix+n_k0, 0); + const dt_int32 ix_e = min(ix+n_ke, nx_i); + + const dt_int32 iy_0 = max(iy+n_k0, 0); + const dt_int32 iy_e = min(iy+n_ke, ny_i); + + T mv = T(0); + dt_int32 ic = 0; + for(auto ix_t = ix_0; ix_t < ix_e; ix_t++) + { + for(auto iy_t = iy_0; iy_t < iy_e; iy_t++) + { + if (R_2d(ix_t-ix, iy_t-iy).norm_2()<=radius_2) + { + mv += mx_i(iy_t, ix_t); + ic++; + } + } + } + + mx_o(iy, ix) = mv/T(ic); + } + } + }; + + fcn_stream_exec_xd_fcn(pstream, nx_i, ny_i, thr_fltr_mean); + } + } + + /* filter median */ + namespace cpu_fcn_image + { + /* 1d */ + template + enable_if_vctr_cpu + fltr_median_1d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.size_32(); + + auto thr_fltr_median = [n_k0, n_ke, nx_i, &mx_i, &mx_o](const iThread_Rect_1d& ithread) + { + std::vector vctr_t(n_ke-n_k0); + + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + const dt_int32 ix_0 = fcn_max(ind+n_k0, 0); + const dt_int32 ix_e = fcn_min(ind+n_ke, nx_i); + + dt_int32 ic = 0; + for(auto ix = ix_0; ix < ix_e; ix++) + { + vctr_t[ic++] = mx_i[ix]; + } + + auto median = vctr_t.begin() + ic/2; + std::nth_element(vctr_t.begin(), median, vctr_t.begin() + ic); + mx_o[ind] = *median; + } + }; + + fcn_stream_exec_xd_fcn(pstream, nx_i, thr_fltr_median); + } + + /* 2d by col */ + template + enable_if_vctr_cpu + fltr_median_2d_bc(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.s1_32(); + const dt_int32 ny_i = mx_i.s0_32(); + + auto thr_fltr_median = [n_k0, n_ke, ny_i, &mx_i, &mx_o](const iThread_Rect_2d& ithread) + { + std::vector vctr_t(n_ke-n_k0); + + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + const dt_int32 iy_0 = fcn_max(iy+n_k0, 0); + const dt_int32 iy_e = fcn_min(iy+n_ke, ny_i); + + dt_int32 ic = 0; + for(auto iy_t = iy_0; iy_t < iy_e; iy_t++) + { + vctr_t[ic++] = mx_i(iy_t, ix); + } + + auto median = vctr_t.begin() + ic/2; + std::nth_element(vctr_t.begin(), median, vctr_t.begin() + ic); + mx_o(iy, ix) = *median; + } + } + }; + + fcn_stream_exec_xd_fcn(pstream, nx_i, ny_i, thr_fltr_median); + } + + /* 2d */ + template + enable_if_vctr_cpu + fltr_median_2d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (n_kr<=0) + { + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.s1_32(); + const dt_int32 ny_i = mx_i.s0_32(); + + const T radius_2 = ::square(T(n_kr)) + epsilon_rel(); + + auto thr_fltr_median = [n_k0, n_ke, radius_2, nx_i, ny_i, &mx_i, &mx_o](const iThread_Rect_2d& ithread) + { + std::vector vctr_t(::square(n_ke-n_k0)); + + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + const dt_int32 ix_0 = max(ix+n_k0, 0); + const dt_int32 ix_e = min(ix+n_ke, nx_i); + + const dt_int32 iy_0 = max(iy+n_k0, 0); + const dt_int32 iy_e = min(iy+n_ke, ny_i); + + dt_int32 ic = 0; + for(auto ix_t = ix_0; ix_t < ix_e; ix_t++) + { + for(auto iy_t = iy_0; iy_t < iy_e; iy_t++) + { + if (R_2d(ix_t-ix, iy_t-iy).norm_2()<=radius_2) + { + vctr_t[ic++] = mx_i(iy_t, ix_t); + } + } + } + + auto median = vctr_t.begin() + ic/2; + std::nth_element(vctr_t.begin(), median, vctr_t.begin() + ic); + mx_o(iy, ix) = *median; + } + } + }; + + fcn_stream_exec_xd_fcn(pstream, nx_i, ny_i, thr_fltr_median); + } + } + + /* filter median by position */ + namespace cpu_fcn_image + { + /* 1d */ + template + enable_if_vctr_cpu_and_vctr_cpu + fltr_median_1d_pos(TVctr& mx_i, dt_int32 n_kr, TVctr_idx& vctr_idx, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + + if (n_kr<=0) + { + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.size_32(); + + auto thr_fltr_median = [n_k0, n_ke, nx_i, &mx_i, &vctr_idx, &mx_o](const iThread_Rect_1d& ithread) + { + std::vector vctr_t(n_ke-n_k0); + + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + const dt_int32 idx = vctr_idx[ind]; + + const dt_int32 ix_0 = fcn_max(idx+n_k0, 0); + const dt_int32 ix_e = fcn_min(idx+n_ke, nx_i); + + dt_int32 ic = 0; + for(auto ix = ix_0; ix < ix_e; ix++) + { + vctr_t[ic++] = mx_i[ix]; + } + + auto median = vctr_t.begin() + ic/2; + std::nth_element(vctr_t.begin(), median, vctr_t.begin() + ic); + mx_o[idx] = *median; + } + }; + + fcn_stream_exec_xd_fcn(pstream, vctr_idx.size_32(), thr_fltr_median); + } + + // 2d for specific points + template + enable_if_vctr_cpu_r_2d_and_vctr_cpu + fltr_median_2d_pos(TVctr& mx_i, dt_int32 n_kr, TVctr_idx& vctr_idx, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); + + if (n_kr<=0) + { + return; + } + + const dt_int32 n_k0 = -n_kr; + const dt_int32 n_ke = n_kr+1; + const dt_int32 nx_i = mx_i.s1_32(); + const dt_int32 ny_i = mx_i.s0_32(); + + const T radius_2 = ::square(T(n_kr)) + epsilon_rel(); + + auto thr_fltr_median = [n_k0, n_ke, radius_2, nx_i, ny_i, &mx_i, &vctr_idx, &mx_o](const iThread_Rect_1d& ithread) + { + std::vector vctr_t(::square(n_ke-n_k0)); + + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + const R_2d r_2d = vctr_idx[ind]; + + const dt_int32 ix_0 = max(r_2d.x+n_k0, 0); + const dt_int32 ix_e = min(r_2d.x+n_ke, nx_i); + + const dt_int32 iy_0 = max(r_2d.y+n_k0, 0); + const dt_int32 iy_e = min(r_2d.y+n_ke, ny_i); + + dt_int32 ic = 0; + for(auto ix_t = ix_0; ix_t < ix_e; ix_t++) + { + for(auto iy_t = iy_0; iy_t < iy_e; iy_t++) + { + if (R_2d(ix_t-r_2d.x, iy_t-r_2d.y).norm_2()<=radius_2) + { + vctr_t[ic++] = mx_i(iy_t, ix_t); + } + } + } + + auto median = vctr_t.begin() + ic/2; + std::nth_element(vctr_t.begin(), median, vctr_t.begin() + ic); + mx_o(r_2d.y, r_2d.x) = *median; + } + }; + + fcn_stream_exec_xd_fcn(pstream, vctr_idx.size_32(), thr_fltr_median); + } + } + + /* filter poisson noise */ + namespace cpu_fcn_image + { + #define CPU_FTR_POISS_NOIS(EXT) \ + template \ + enable_if_vctr_cpu \ + fltr_poiss_nois_##EXT(TVctr& mx_i, dt_int32 nkr_w, dt_int32 nkr_m, TVctr& mx_o, Stream_cpu* pstream = nullptr) \ + { \ + using T = Value_type; \ + \ + if ((nkr_w == 0) && (nkr_m == 0)) \ + { \ + memcpy_cpu_cpu(mx_o.m_data, mx_i.m_data, mx_i.size_64()); \ + return; \ + } \ + \ + Vctr_cpu mx_tmp(mx_i.shape()); \ + \ + fcn_anscombe(mx_i, mx_tmp, pstream); \ + fltr_wiener_##EXT(mx_tmp, nkr_w, mx_o, pstream); \ + fltr_median_##EXT(mx_o, nkr_m, mx_tmp, pstream); \ + fcn_anscombe_inv(mx_tmp, mx_o, pstream); \ + } + + CPU_FTR_POISS_NOIS(1d); // fltr_poiss_nois_1d + CPU_FTR_POISS_NOIS(2d_bc); // fltr_poiss_nois_2d_bc + CPU_FTR_POISS_NOIS(2d); // fltr_poiss_nois_2d + } + + /* peak signal to noise ratio */ + namespace cpu_fcn_image + { + template + enable_if_vctr_cpu> + fcn_get_psnr(TVctr& mx_i, TVctr& mx_r, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto var_r = fcn_variance(mx_r, pstream); + Vctr_cpu mx_n(mx_r.size()); + fcn_sub(mx_i, mx_r, mx_n, pstream); + + auto var_n = fcn_variance(mx_n, pstream); + + return var_n/var_r; + } + + template + enable_if_vctr_cpu> + fcn_get_psnr(TVctr& mx_i, dt_int32 nkr_w, dt_int32 nkr_m, Stream_cpu* pstream = nullptr) + { + auto mx_r = fltr_poiss_nois_2d(mx_i, nkr_w, nkr_m, pstream); + + auto var_r = fcn_variance(mx_r, pstream); + auto& mx_n = mx_r; + fcn_sub(mx_i, mx_r, mx_n, pstream); + + auto var_n = fcn_variance(mx_n, pstream); + + return var_n/var_r; + } + } + + /* others */ + namespace cpu_fcn_image + { + //// scale_image + //template + //TVctr scale_image_mean(Stream& stream, dt_int32 ny_i, dt_int32 nx_i, TVctr& Im_i, Value_type shrink_factor, dt_int32& ny_o, dt_int32& nx_o) + //{ + // using T = Value_type; + // TVctr Im_o; + + // dt_int32 nkr = max(dt_int32(1.0/(2.0*shrink_factor)), 1); + // dt_int32 nk0 = -nkr; + // dt_int32 nke = nkr+1; + + // nx_o = max(dt_int32(::floor(nx_i*shrink_factor)), 1); + // ny_o = max(dt_int32(::floor(ny_i*shrink_factor)), 1); + + // if ((nx_i == nx_o) && (ny_i == ny_o)) + // { + // Im_o.assign(Im_i.begin(), Im_i.end()); + // return Im_o; + // } + // Im_o.resize(nx_o*ny_o); + + // auto krn_sc_image = [&](const dt_int32& ix_i, const dt_int32& iy_i, TVctr& Im_i, TVctr& Im_o) + // { + // auto ix_t = static_cast(ix_i/shrink_factor); + // auto iy_t = static_cast(iy_i/shrink_factor); + + // dt_int32 ix_0 = max(ix_t+nk0, 0); + // dt_int32 ix_e = min(ix_t+nke, nx_i); + + // dt_int32 iy_0 = max(iy_t+nk0, 0); + // dt_int32 iy_e = min(iy_t+nke, ny_i); + + // T sum = 0; + // for(auto ix = ix_0; ix < ix_e; ix++) + // { + // for(auto iy = iy_0; iy < iy_e; iy++) + // { + // sum += Im_i[ix*ny_i+iy]; + // } + // } + + // Im_o[ix_i*ny_o+iy_i] = sum/((ix_e-ix_0)*(iy_e-iy_0)); + // }; + + // auto thr_sc_image = [&](const iThread_Rect_2d& ithread) + // { + // cpu_detail::matrix_iter(ithread, krn_sc_image, Im_i, Im_o); + // }; + + // stream.set_n_stream_act(nx_o); + // stream.set_grid(nx_o, ny_o); + // stream.exec(thr_sc_image); + + // return Im_o; + //} + + //// copy image + //template + //TVctr cpy_image(Stream& stream, dt_int32 ny_src, dt_int32 nx_src, TVctr& Im_src, dt_int32 iy_0, dt_int32 ix_0, dt_int32 iy_e, dt_int32 ix_e, dt_int32 ny_dst, dt_int32 nx_dst) + //{ + // TVctr Im_dst(nx_dst*ny_dst); + + // dt_int32 nx = min(nx_src, nx_dst); + // ix_e = (ix_e + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CPU_FCNS_MT_H + #define CPU_FCNS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "types_mt.cuh" + #include "type_traits_mt.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_stream.cuh" + #include "quad_data.cuh" + #include "cgpu_detail_mt.cuh" + #include "cpu_fcns.hpp" + + /* atomic functions */ + namespace mt + { + /*********************************** pFcn_clnl_3_x **********************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx, pFcn_clnl_3_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_3_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /********************************* pFcn_clnl_4_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& c, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx, pFcn_clnl_4_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], c, coef.cl, coef.cnl); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& c, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_4_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], c, coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /********************************* pFcn_clnl_6_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx, pFcn_clnl_6_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_6_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + + /********************************* pFcn_clnl_8_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx, pFcn_clnl_8_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_8_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + + /***************************************************************************************/ + /***************************************************************************************/ + /***************************************************************************************/ + #define SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn, ...) \ + switch(atomic_pot_parm_typ) \ + { \ + case eappt_doyle_0_4: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_peng_0_4: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_peng_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_kirkland_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_weickenmeier_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_lobato_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_peng_ion_0_4: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + default: \ + { \ + return 0; \ + } \ + } + + #define SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn, ...) \ + switch(atomic_pot_parm_typ) \ + { \ + case eappt_doyle_0_4: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_peng_0_4: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_peng_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_kirkland_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_weickenmeier_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_lobato_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_peng_ion_0_4: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + } + + /************************************** feg ********************************************/ + template + CPU_EXEC + T fcn_feg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const pLNL_Coef_cpu& coef) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_feg, g, coef.cl, coef.cnl); + } + + template + CPU_EXEC + void fcn_feg_dfeg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_feg_dfeg, g, coef.cl, coef.cnl, y, dy); + } + + /*************************************** fxg *******************************************/ + template + CPU_EXEC + T fcn_fxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const T& Z, const pLNL_Coef_cpu& coef) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_peng_0_4: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_peng_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_kirkland_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_weickenmeier_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, coef.cl, coef.cnl); + } + case eappt_lobato_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, coef.cl, coef.cnl); + } + case eappt_peng_ion_0_4: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + default: + { + return 0; + } + } + } + + template + CPU_EXEC + void fcn_fxg_dfxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const T& Z, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_4: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_kirkland_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_weickenmeier_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_lobato_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_ion_0_4: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + } + } + + /*************************************** pr ********************************************/ + template + CPU_EXEC + T fcn_pr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_pr, r, coef.cl, coef.cnl); + } + + template + CPU_EXEC + void fcn_pr_dpr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_pr_dpr, r, coef.cl, coef.cnl, y, dy); + } + + /**************************************** vr *******************************************/ + template + CPU_EXEC + T fcn_vr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_vr, r, coef.cl, coef.cnl); + } + + template + CPU_EXEC + void fcn_vr_dvr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_vr_dvr, r, coef.cl, coef.cnl, y, dy); + } + + /************************************** vz *********************************************/ + template + CPU_EXEC + T fcn_vz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_vz, r, z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + + template + CPU_EXEC + void fcn_vz_dvz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_vz_dvz, r, z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, y, dy); + } + + /************************************* vzp *********************************************/ + template + CPU_EXEC + T fcn_vzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, pQuad_Coef_1d_cpu* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_peng_0_4: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_peng_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_kirkland_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_weickenmeier_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl, pquad->m_size, pquad->x, pquad->w); + } + case eappt_lobato_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_peng_ion_0_4: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + default: + { + return 0; + } + } + } + + template + CPU_EXEC + void fcn_vzp_dvzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, T& y, T& dy, pQuad_Coef_1d_cpu* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_4: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_kirkland_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_weickenmeier_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, pquad->m_size, pquad->x, pquad->w, y, dy); + } + break; + case eappt_lobato_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_ion_0_4: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + } + } + } + + /* detector integration */ + namespace mt + { + template + enable_if_vctr_cpu> + fcn_int_det_ring(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), T(0), cgpu_detail_mt::fcn_int_det_ring, grid, g2_min, g2_max, mx_i.m_data); + } + + template + enable_if_vctr_cpu> + fcn_int_det_ring_norm_2(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), Ur(0), cgpu_detail_mt::fcn_int_det_ring_norm_2, grid, g2_min, g2_max, mx_i.m_data); + } + + template + enable_if_vctr_cpu> + fcn_int_det_sen(Grid_2d& grid, TVctr& sen_i, TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + KS sum_total = U(0); + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), U(0), cgpu_detail_mt::fcn_int_det_sen, grid, sen_i.m_data, mx_i.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu> + fcn_int_det_sen_norm_2(Grid_2d& grid, TVctr_1& sen_i, TVctr_2& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), Ur(0), cgpu_detail_mt::fcn_int_det_sen_norm_2, grid, sen_i.m_data, mx_i.m_data); + } + } + + /* wave propagation */ + namespace mt + { + /* propagate */ + template + enable_if_vctr_cpu + fcn_fs_propagate(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate, grid, psi_i.m_data, g_0, w_g2, w, psi_o.m_data); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + enable_if_vctr_cpu + fcn_fs_propagate_bw_f(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T alpha, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_f, grid, psi_i.m_data, g_0, w_g2, g2_cut, alpha, w, psi_o.m_data); + } + + /* propagate and bandwith limit using a hard aperture */ + template + enable_if_vctr_cpu + fcn_fs_propagate_bw_h(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_h, grid, psi_i.m_data, g_0, w_g2, g2_cut, w, psi_o.m_data); + } + } + + /* probe - ctf - pctf */ + namespace mt + { + template + enable_if_vctr_cpu + fcn_fs_probe(Grid_2d& grid, Lens& lens, R_2d r, R_2d gu, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_probe, grid, lens, r, gu, psi_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_probe, grid, lens, r, gu, psi_o.m_data); + } + + auto tot_intensity = fcn_sum_norm_2(psi_o, pstream); + auto sc_fctr = sqrt(T(1)/tot_intensity); + + fcn_scale(sc_fctr, psi_o, pstream); + } + + template + enable_if_vctr_cpu + fcn_fs_apply_ctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, R_2d gu, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_ctf, grid, psi_i, lens, gu, psi_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_ctf, grid, psi_i, lens, gu, psi_o.m_data); + } + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + enable_if_vctr_cpu + fcn_fs_apply_pctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, R_2d gu, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_pctf, grid, psi_i, lens, gu, psi_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_pctf, grid, psi_i, lens, gu, psi_o.m_data); + } + } + } + + /* transmission function */ + namespace mt + { + template + enable_if_vctr_cpu_and_vctr_cpu + transmission_fcn(eElec_Spec_Interact_Mod esim, TVctr_1& vzp_i, T w, TVctr_2& tfcn_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + iGrid_1d igrid(vzp_i.size()); + + if (esim==eesim_weak_phase_object) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, cgpu_detail_mt::fcn_trans_fcn, igrid, vzp_i.m_data, w, tfcn_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, cgpu_detail_mt::fcn_trans_fcn, igrid, vzp_i.m_data, w, tfcn_o.m_data); + } + } + } + + /* eels */ + namespace mt + { + template + T fcn_eels_lorentz_norm_factor_cpu(Grid_2d& grid, EELS& eels, Stream_cpu* pstream = nullptr) + { + auto sum_total = fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), T(0),cgpu_detail_mt::fcn_eels_lorentz_norm_factor, grid, eels.gc2, eels.ge2); + + return sqrt(eels.occ)/sum_total; + } + + template + enable_if_vctr_cpu + fcn_eels_w_xyz(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_x, TVctr_c& w_y, TVctr_c& w_z, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_xyz, grid, eels, w_x.m_data, w_y.m_data, w_z.m_data); + + fft.inverse(w_x); + fft.inverse(w_y); + fft.inverse(w_z); + } + + template + enable_if_vctr_cpu + fcn_eels_w_x(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_x, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_x, grid, eels, w_x.m_data); + + fft.inverse(w_x); + } + + template + enable_if_vctr_cpu + fcn_eels_w_y(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_y, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_y, grid, eels, w_y.m_data); + + fft.inverse(w_y); + } + + template + enable_if_vctr_cpu + fcn_eels_w_z(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_z, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_z, grid, eels, w_z.m_data); + + fft.inverse(w_z); + } + + template + enable_if_vctr_cpu + fcn_eels_w_mn1(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_mn1, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mn1, grid, eels, w_mn1.m_data); + + fft.inverse(w_mn1); + } + + template + enable_if_vctr_cpu + fcn_eels_w_mp1(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_mp1, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mp1, grid, eels, w_mp1.m_data); + + fft.inverse(w_mp1); + } + } + + namespace mt + { + // /***********************Temporal and Spatial quadratures*********************/ + // template + // void obj_lens_temporal_spatial_quadratures(Lens& lens, Quad_Coef_1d& qt, Quad_Coef_2d& qs) + // { + // /*********************Temporal quad_data**********************/ + // Quad_Data quad_data; + // quad_data(7, lens.tp_inc_npts, qt); // 7: int_-infty^infty f(x) x^0 Exp[-x^2] dx + // std::for_each(qt.w.begin(), qt.w.end(), [](T& v) { v = v/c_pii2; }); + + // /*********************Spatial quad_data**********************/ + // qs.reserve((2 * lens.ngxs + 1)*(2 * lens.ngys + 1)); + // dt_int32 iqs = 0; + // T sum_w = 0; + // T sum_ee = 0; + // T alpha = 0.5/pow(lens.spt_inc_sigma, 2); + + // for(auto ix = -lens.ngxs; ix <= lens.ngxs; ix++) + // { + // for(auto iy = -lens.ngys; iy <= lens.ngys; iy++) + // { + // T gxs = lens.gxs(ix); + // T gys = lens.gys(iy); + // T g2s = gxs*gxs + gys*gys; + // if (g2s < lens.g2_outers) + // { + // qs.x.push_back(gxs); + // qs.y.push_back(gys); + // T v = exp(-alpha*g2s); + // qs.w.push_back(v); + // fcn_kh_sum(sum_w, v, sum_ee); + // } + // } + // } + // qs.resize(iqs); + // std::for_each(qs.w.begin(), qs.w.end(), [sum_w](T& v) { v = v/sum_w; }); + // } + + // template + // void cond_lens_temporal_spatial_quadratures(Lens& lens, Quad_Coef_1d& qt, Quad_Coef_2d& qs) + // { + // /*********************Temporal quad_data**********************/ + // dt_bool bb_ti = (lens.tp_inc_npts > 1) && fcn_is_nzero(lens.tp_inc_sigma); + // Quad_Data quad_data; + + // if (bb_ti) + // { + // dt_float64 a = (fcn_is_zero(lens.tp_inc_sigma))?0:(lens.tp_inc_a/(sqrt(c_2pi)*lens.tp_inc_sigma)); + // dt_float64 b = (fcn_is_zero(lens.tp_inc_sigma))?0:(0.5/lens.tp_inc_sigma_2()); + // dt_float64 c = (fcn_is_zero(lens.tp_inc_beta))?0:((1-lens.tp_inc_a)/(2*lens.tp_inc_beta)); + // dt_float64 d = (fcn_is_zero(lens.tp_inc_beta))?0:(1.0/lens.tp_inc_beta); + + // dt_float64 b_q = 0.5/sqrt(lens.tp_inc_a*lens.tp_inc_sigma_2() + 2*(1-lens.tp_inc_a)*lens.tp_inc_beta_2()); + + // // 26, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // quad_data(26, lens.tp_inc_npts, qt, 0, 0, 0, b_q); + + // for(auto it = 0; it < lens.tp_inc_npts; it++) + // { + // dt_float64 r = abs(qt.x[it]); // positive + // dt_float64 f = a*exp(-b*r*r + b_q*r*r) + c*exp(-d*r + b_q*r*r); + // qt.w[it] *= f; + // } + // } + // else + // { + // qt.resize(1); + // qt.x[0] = 0; + // qt.w[0] = 1; + // } + + // /*********************Spatial quad_data**********************/ + // dt_bool bb_si = ((lens.spt_inc_rad_npts > 1) || (lens.spt_inc_azm_npts > 1)) && !fcn_is_zero(lens.spt_inc_sigma, lens.spt_inc_beta); + + // if (bb_si) + // { + // dt_float64 a = (fcn_is_zero(lens.spt_inc_sigma))?0:(lens.spt_inc_a/(c_2pi*lens.spt_inc_sigma_2())); + // dt_float64 b = (fcn_is_zero(lens.spt_inc_sigma))?0:(0.5/lens.spt_inc_sigma_2()); + // dt_float64 c = (fcn_is_zero(lens.spt_inc_beta))?0:((1-lens.spt_inc_a)/(c_2pi*lens.spt_inc_beta_2())); + // dt_float64 d = (fcn_is_zero(lens.spt_inc_beta))?0:(1.0/lens.spt_inc_beta); + + // dt_float64 b_q = 1.0/sqrt((2*lens.spt_inc_a*lens.spt_inc_sigma_2()+ 6*(1-lens.spt_inc_a)*lens.spt_inc_beta_2())/6); + + // // radial part + // Quad_Coef_1d qr; + // // 25, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // quad_data(25, lens.spt_inc_rad_npts, qr, 1, 0, 0, b_q); + + // for(auto ir = 0; ir < lens.spt_inc_rad_npts; ir++) + // { + // dt_float64 r = abs(qr.x[ir]); // positive + // dt_float64 f = a*exp(-b*r*r + b_q*r) + c*exp(-d*r + b_q*r); + // qr.w[ir] *= f; + // } + + // // Azimuth part + // Quad_Coef_1d qa; + // qa.resize(lens.spt_inc_azm_npts); + // dt_float64 h = c_2pi/lens.spt_inc_azm_npts; + // for(auto ia = 0; ia < lens.spt_inc_azm_npts; ia++) + // { + // qa.x[ia] = ia*h; + // qa.w[ia] = h; + // } + + // qs.reserve(lens.spt_inc_rad_npts*lens.spt_inc_azm_npts); + // for(auto ir = 0; ir < lens.spt_inc_rad_npts; ir++) + // { + // for(auto ia = 0; ia < lens.spt_inc_azm_npts; ia++) + // { + // dt_float64 sin_theta, cos_theta; + // sincos(qa.x[ia], &sin_theta, &cos_theta); + // qs.x.push_back(qr.x[ir]*cos_theta); + // qs.y.push_back(qr.x[ir]*sin_theta); + // qs.w.push_back(qr.w[ir]*qa.w[ia]); + // } + // } + // } + // else + // { + // qs.resize(1); + // qs.x[0] = 0; + // qs.y[0] = 0; + // qs.w[0] = 1; + // } + // } + } + +#endif \ No newline at end of file diff --git a/src/gpu_fcns.cuh b/src - Copy (2)/device_functions.cuh old mode 100644 new mode 100755 similarity index 97% rename from src/gpu_fcns.cuh rename to src - Copy (2)/device_functions.cuh index 282c91bf..d9479a69 --- a/src/gpu_fcns.cuh +++ b/src - Copy (2)/device_functions.cuh @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,8 +16,8 @@ * along with MULTEM. If not, see . */ -#ifndef GPU_FCNS_H -#define GPU_FCNS_H +#ifndef DEVICE_FUNCTIONS_H +#define DEVICE_FUNCTIONS_H #include #include @@ -35,8 +35,8 @@ #include #include -#include "cgpu_fcns.cuh" -#include "cpu_fcns.hpp" +#include "host_device_functions.cuh" +#include "host_functions.hpp" #define reduce_array_256(tid, sum, Mshare) \ { \ @@ -363,7 +363,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nx)&&(iy < grid_2d.nyh)) { host_device_detail::fft2_sft_bc(ix, iy, grid_2d, M_io); } @@ -376,7 +376,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nxh) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) { host_device_detail::fft2_shift(ix, iy, grid_2d, M_io); } @@ -390,7 +390,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nxh) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) { host_device_detail::fft2_shift(ix, iy, grid_2d, M_i, M_o); } @@ -403,7 +403,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nxh) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) { host_device_detail::add_scale_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); } @@ -416,7 +416,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nxh) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) { host_device_detail::add_scale_square_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); } @@ -429,7 +429,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::assign_crop(ix, iy, grid_2d, M_i, M_o); } @@ -442,7 +442,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nxh) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) { host_device_detail::assign_crop_shift_2d(ix, iy, grid_2d, M_i, range, M_o); } @@ -455,7 +455,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nxh) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) { host_device_detail::add_scale_crop_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); } @@ -468,7 +468,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nxh) && (iy < grid_2d.nyh)) + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) { host_device_detail::add_scale_square_crop_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); } @@ -587,7 +587,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::bandwidth_limit(ix, iy, grid_2d, M_io); } @@ -599,7 +599,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::hard_aperture(ix, iy, grid_2d, g2_max, w, M_io); } @@ -613,7 +613,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::propagate(ix, iy, grid_2d, w, gxu, gyu, psi_i, psi_o); } @@ -640,7 +640,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::exp_r_factor_2d_bc(ix, iy, grid_2d, alpha, gy, psi_i, psi_o); } @@ -654,7 +654,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::exp_r_factor_2d(ix, iy, grid_2d, gx, gy, psi_i, psi_o); } @@ -670,7 +670,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::mul_exp_r_factor_2d(ix, iy, grid_2d, gx, gy, psi_i, psi_o); } @@ -697,7 +697,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::exp_g_factor_2d_bc(ix, iy, grid_2d, alpha, Ry, psi_i, psi_o); } @@ -711,7 +711,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::exp_g_factor_2d(ix, iy, grid_2d, Rx, Ry, psi_i, psi_o); } @@ -727,7 +727,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::mul_exp_g_factor_2d(ix, iy, grid_2d, Rx, Ry, psi_i, psi_o); } @@ -742,7 +742,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::probe(ix, iy, grid_2d, lens, x, y, gxu, gyu, fPsi_o); } @@ -756,7 +756,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::apply_CTF(ix, iy, grid_2d, lens, gxu, gyu, fPsi_i, fPsi_o); } @@ -769,7 +769,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::apply_PCTF(ix, iy, grid_2d, lens, fPsi_i, fPsi_o); } @@ -828,7 +828,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::kernel_xyz(ix, iy, grid_2d, eels, k_x, k_y, k_z); } @@ -840,7 +840,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::kernel_x(ix, iy, grid_2d, eels, k_x); } @@ -852,7 +852,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::kernel_y(ix, iy, grid_2d, eels, k_y); } @@ -864,7 +864,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::kernel_z(ix, iy, grid_2d, eels, k_z); } @@ -876,7 +876,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::kernel_mn1(ix, iy, grid_2d, eels, k_mn1); } @@ -888,7 +888,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::kernel_mp1(ix, iy, grid_2d, eels, k_mp1); } @@ -901,7 +901,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < ncols) && (iy < nrows)) + if((ix < ncols)&&(iy < nrows)) { host_device_detail::trs(ix, iy, ncols, nrows, M_i, M_o); } @@ -915,7 +915,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::vector_col_x_matrix(ix, iy, grid_2d, fg, M_io); } @@ -942,7 +942,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::gauss_cv_2d(ix, iy, grid_2d, alpha, M_io); } @@ -969,7 +969,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::gauss_dcv_2d(ix, iy, grid_2d, alpha, PSNR, M_io); } @@ -1009,7 +1009,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d_i.nx) && (iy < grid_2d_i.ny)) + if((ix < grid_2d_i.nx)&&(iy < grid_2d_i.ny)) { host_device_detail::pcf_2d_bc_pp(ix, iy, iy_s, grid_2d_i, grid_2d_o, M_i, fh, M_o); } @@ -1023,7 +1023,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::pcf_2d_bc_gaussian(ix, iy, grid_2d, M_1, M_2, fg, pcf); } @@ -1037,7 +1037,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d_i.nx) && (iy < grid_2d_i.ny)) + if((ix < grid_2d_i.nx)&&(iy < grid_2d_i.ny)) { int ixy_i = grid_2d_o.ind_col(ix, iy+iy_s); int ixy_o = grid_2d_i.ind_col(ix, iy); @@ -1054,7 +1054,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::pcf_2d_pp(ix, iy, grid_2d, bw_2d, M_i, M_o); } @@ -1068,7 +1068,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d.nx) && (iy < grid_2d.ny)) + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) { host_device_detail::pcf_2d_gaussian(ix, iy, grid_2d, gs_2d, M_1, M_2, pcf); } @@ -1081,7 +1081,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d_o.nx) && (iy < grid_2d_o.ny)) + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) { host_device_detail::sc_2d(ix, iy, grid_2d_i, M_i, fxy, grid_2d_o, M_o); } @@ -1095,7 +1095,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d_o.nx) && (iy < grid_2d_o.ny)) + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) { host_device_detail::rot_2d(ix, iy, grid_2d_i, M_i, theta, p0, bg, grid_2d_o, M_o); } @@ -1109,7 +1109,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d_o.nx) && (iy < grid_2d_o.ny)) + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) { host_device_detail::rot_sca_sft_2d(ix, iy, grid_2d_i, M_i, theta, p0, fx, fy, ps, bg, grid_2d_o, M_o); } @@ -1122,7 +1122,7 @@ namespace mt int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; - if((ix < grid_2d_o.nx) && (iy < grid_2d_o.ny)) + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) { host_device_detail::shx_scy(ix, iy, grid_2d_i, M_i, fx, fy, bg, grid_2d_o, M_o); } diff --git a/src - Copy (2)/energy_loss.cuh b/src - Copy (2)/energy_loss.cuh new file mode 100755 index 00000000..61b9ada6 --- /dev/null +++ b/src - Copy (2)/energy_loss.cuh @@ -0,0 +1,276 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ENERGY_LOSS_H + #define ENERGY_LOSS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_fcns_gen.cuh" + // #include "in_classes.cuh" + // #include "cpu_fcns.hpp" + // #include "gpu_fcns.cuh" + // #include "cgpu_fcns.cuh" + + namespace mt + { + template + class EELS + { + public: + using value_type = T; + + eSpace space; // real or reciprocal space + + T E_0; // incident energy + dt_int32 m_sel; // selection rule + T coll_angle; // collection angle(rad) + eChan_Typ chan_type; // channelling type + T g_coll; // collection angle(recirpocal Angstroms) + + dt_int32 Z; // atomic type + T x; // x position + T y; // y position + T occ; // y occupancy + T E_loss; // energy loss + T ge; // relativistic corrected effective scattering momentum transfer + T ge2; // ge square + T gc; // ge cut-off at the Bethe Ridge + T gc2; // gc square + T lrtz_factor; // lorentz factor = sum 1/(g^2+ge^2) + + /************************************* constructors ************************************/ + EELS(): space(esp_real), E_0(0), m_sel(0), coll_angle(0), chan_type(eCT_double_chan), + g_coll(0), lrtz_factor(1), Z(0), x(0), y(0), occ(0), E_loss(0), ge(0), ge2(0), gc(0), gc2(0){} + + /* copy constructor */ + EELS(const EELS& eels) + { + *this = eels; + } + + /* converting constructor */ + template + EELS(const EELS& eels) + { + *this = eels; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + EELS& operator=(const EELS& eels) + { + if (this != &eels) + { + space = eels.space; + + E_0 = eels.E_0; + m_sel = eels.m_sel; + coll_angle = eels.coll_angle; + chan_type = eels.chan_type; + g_coll = eels.g_coll; + + Z = eels.Z; + x = eels.x; + y = eels.y; + occ = eels.occ; + E_loss = eels.E_loss; + ge = eels.ge; + ge2 = eels.ge2; + gc = eels.gc; + gc2 = eels.gc2; + lrtz_factor = eels.lrtz_factor; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + EELS& operator=(const EELS& eels) + { + space = eels.space; + + E_0 = T(eels.E_0); + m_sel = eels.m_sel; + coll_angle = T(eels.coll_angle); + chan_type = eels.chan_type; + g_coll = T(eels.g_coll); + + Z = eels.Z; + x = T(eels.x); + y = T(eels.y); + occ = T(eels.occ); + E_loss = T(eels.E_loss); + ge = T(eels.ge); + ge2 = T(eels.ge2); + gc = T(eels.gc); + gc2 = T(eels.gc2); + lrtz_factor = T(eels.lrtz_factor); + + return *this; + } + + template + void assign(const EELS& eels) + { + *this = eels; + } + + /***************************************************************************************/ + void set_in_data(const eSpace& space, const T& E_0, dt_int32 m_sel, const T& coll_angle, eChan_Typ chan_type, const dt_int32& Z, const T& E_loss) + { + this->space = space; + this->E_0 = E_0; + this->m_sel = m_sel; + set_coll_angle(coll_angle); + this->chan_type = chan_type; + + this->Z = Z; + set_e_loss(E_loss); + } + + void set_coll_angle(const T& coll_angle) + { + this->coll_angle = coll_angle; + g_coll = coll_angle/fcn_lambda(E_0); + } + + void set_e_loss(const T& E_loss) + { + const auto gamma = fcn_gamma(E_0); + const auto lambda = fcn_lambda(E_0); + + auto theta = theta_efect(E_loss, E_0); + ge = theta/(lambda*gamma*gamma); + ge2 = pow(gamma*ge, 2); + gc = sqrt(T(2)*theta)/lambda; + gc2 = pow(gc, 2); + } + + // effective scattering angle + T theta_efect(const T& E_loss, const T& E_0) + { + const auto emass = T(510.99906); + const auto x = (emass + E_0)/(T(2)*emass + E_0); + return E_loss*x/E_0; + } + + dt_bool is_Single_Chan() const + { + return chan_type == ect_single_chan; + } + + dt_bool is_Mixed_Chan() const + { + return chan_type == ect_mixed_chan; + } + + dt_bool is_Double_Chan() const + { + return chan_type == eCT_double_chan; + } + + dt_bool is_real_space() const + { + return space == esp_real; + } + + dt_bool is_reciprocal_space() const + { + return space == esp_fourier; + } + }; + + /* + template + class Energy_Loss + { + public: + using T_r = T; + using T_c = complex; + + void set_in_data(Multem_In_Parm *multem_in_parm, Stream *stream, FFT *fft2) + { + this->multem_in_parm = multem_in_parm; + this->stream = stream; + this->fft_2d = fft2; + + if (multem_in_parm->eels_fr.m_sel>2) + { + kernel.resize(3); + } + else + { + kernel.resize(1); + } + + for(auto ikn = 0; ikngrid_2d.size()); + } + + } + + void set_atom_type(EELS& eels) + { + if (eels.m_sel>2) + { + mt::fcn_eels_w_xyz(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0], kernel[1], kernel[2]); + } + else if (eels.m_sel == -2) + { + mt::fcn_eels_w_x(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == -1) + { + mt::fcn_eels_w_mn1(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == 0) + { + mt::fcn_eels_w_z(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == 1) + { + mt::fcn_eels_w_mp1(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == 2) + { + mt::fcn_eels_w_y(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + } + + Vctr, edev_cpu> kernel; + private: + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + }; + */ + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/eval_fit_atomic_columns.hpp b/src - Copy (2)/eval_fit_atomic_columns.hpp new file mode 100755 index 00000000..7801747e --- /dev/null +++ b/src - Copy (2)/eval_fit_atomic_columns.hpp @@ -0,0 +1,731 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef EVAL_FIT_ATOMIC_COLUMN_H +#define EVAL_FIT_ATOMIC_COLUMN_H + +#include +#include +#include +#include + +#include +#include "math.cuh" +#include "type_traits_gen.cuh" +#include "types.cuh" +#include "lapack.hpp" + namespace mt +{ + template + class Eval_Atomic_Columns + { + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + Eval_Atomic_Columns() {}; + + void operator()(TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, TVctr_r &coef, TVctr_r &Ixy) + { + auto pos = split_pos_by_types(pos_i); + + const dt_int32 n_pos = pos.size(); + const dt_int32 n_coef_pa = coef.size()/n_pos; + const dt_int32 nxy = Rx_i.size(); + + KS Ixy_p; + + for(auto ixy = 0; ixy < nxy; ixy++) + { + Ixy_p = 0; + + for(auto ipt = 0; ipt < n_pos; ipt++) + { + const dt_int32 idx_c = n_coef_pa*ipt; + + const T a1 = coef[idx_c + 0]; + const T a2 = coef[idx_c + 1]; + const T alpha = coef[idx_c + 2]; + const T sigma1 = coef[idx_c + 3]; + const T sigma2 = coef[idx_c + 4]; + + const T f_sigma1 = 1.0/(2*sigma1*sigma1); + const T f_sigma2 = 1.0/(2*sigma2*sigma2); + + const auto &p = pos[ipt].p; + const dt_int32 np = p.size(); + + const R_2d Rxy = R_2d(Rx_i[ixy], Ry_i[ixy]); + + // sum over positions + for(auto ip = 0; ip < np; ip++) + { + const T r2 = norm_2(Rxy-p[ip]); + const T ep_1 = a1*exp(-f_sigma1*r2); + const T ep_2 = a2*pow(r2, alpha)*exp(-f_sigma2*r2); + + Ixy_p += ep_1 + ep_2; + } + } + + Ixy[ixy] = Ixy_p; + } + } + + private: + struct PTypes + { + public: + TVctr_r2d p; + + dt_int32 size() const + { + return p.size(); + } + + void reserve(size_type n_pos) + { + p.reserve(n_pos); + } + + void shrink_to_fit() + { + p.shrink_to_fit(); + } + }; + + using VPTypes = vector; + + VPTypes split_pos_by_types(TVctr_r &pos_i) + { + const auto n_pos = pos_i.size()/3; + + // get unique types + TVctr_r ptypes_u(pos_i.begin()+2*n_pos, pos_i.end()); + std::sort(ptypes_u.begin(), ptypes_u.end()); + ptypes_u.erase(std::unique(ptypes_u.begin(), ptypes_u.end(), mt::fcn_is_equal), ptypes_u.end()); + ptypes_u.shrink_to_fit(); + + dt_int32 n_ptypes_u = ptypes_u.size(); + VPTypes pos_typ(n_ptypes_u); + + // create map + std::map mptypes_u; + for(auto idx=0; idx(pos_i[n_pos*2+ip]); + idx = mptypes_u[idx]; + T x = pos_i[n_pos*0+ip]; + T y = pos_i[n_pos*1+ip]; + pos_typ[idx].p.push_back(R_2d(x, y)); + } + + // shrink to fit + for(dt_int32 idx=0; idx + class Fit_Atomic_Columns + { + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Fit_Atomic_Columns():n_pos_typ(0), n_coef_pa(5), n_coef_nl_pa(3), n_coef(0), n_coef_nl(0), n_cstr(0), r2_min(1e-10) {}; + + T fit(TVctr_r &Ixy_i, TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, T lambda_0, TVctr_r &coef, TVctr_r &cstr_i) + { + // set random seed + std::random_device rd; + gen_c.seed(rd()); + + auto pos_typ = split_pos_by_types(pos_i); + + n_pos_typ = pos_typ.size(); + n_coef = n_coef_pa*n_pos_typ; + n_coef_nl = n_coef_nl_pa*n_pos_typ; + nxy = Ixy_i.size(); + n_cstr = cstr_i.size(); + + // allocate memory + set_size_local_variables(nxy, n_coef); + + // assign in data + assign_in_data(Ixy_i, Rx_i, Ry_i, cstr_i); + + TVctr_r coef_min(n_coef); + TVctr_r coef_max(n_coef); + + // set initial coefficients and limits + set_coef_min_max(coef_min, coef_max); + + // SVD minimum-norm solution + mns_svd.init(n_coef, n_coef); + + const T ee_ee = 1e-5; + const T ee_G_max = 1e-5; + const T ee_coef = 1e-7; + const dt_int32 n_iter = 150; + dt_bool bb_A_b = true; + dt_bool bb_shrink_lambda = false; + + T G_max; + T ee_coef_max; + T ee_t; + TVctr_r d_coef(n_coef); + TVctr_r coef_t(n_coef); + + T lambda = lambda_0; + const T lambda_fu = 8; + const T lambda_du = 5; + + // from mixed to nonlinear -linear coeff + mixed_2_nonlinear_linear(coef); + + // forward transformation coefficients + fw_transformation_coef(coef); + + // set dependent coefficients + // set_dependent_coef(cstr, coef); + + // call ee + T ee_b = cal_ee_Ixy_dIxy_J(pos_typ, Rxy_0, Ixy_0, coef, Ixy, dIxy, J); + + for(auto iter = 0; iter < n_iter; iter++) + { + if (bb_A_b) + { + // calculate matrix A and b + get_A_b(J, dIxy, A, b); + + // get the maximum gradient + G_max = maximum_gradient(n_coef, b); + } + + // add lamba x diagonal to matrix A_lambda + add_lambda(n_coef, A, lambda, A_lambda); + + // solve the system of equations for d_coef + mns_svd(A_lambda.data(), b.data(), d_coef.data()); + + // add d_coef + add_d_coef(coef, d_coef, coef_t); + + // increase lambda + // if (increase_lambda(coef_min, coef_max, coef_t)) + // { + // lambda = ::fmin(lambda*lambda_fu, 1e+8); + // continue; + // } + + // set constraints + set_constraints(coef, coef_min, coef_max, coef_t); + + // set dependent coefficients + // set_dependent_coef(cstr, coef_t); + + // calculate maximum error coefficients + ee_coef_max = diff_coef(coef, coef_t); + + // calculate error + ee_t = cal_ee_Ixy_dIxy_J(pos_typ, Rxy_0, Ixy_0, coef_t, Ixy, dIxy, J); + + if ((G_max < ee_G_max)||(fabs(ee_b-ee_t) < ee_ee)||(ee_coef_max < ee_coef)) + { + break; + } + + if (ee_b > ee_t) + { + coef = coef_t; + ee_b = ee_t; + lambda = (bb_shrink_lambda)?::fmax(lambda/lambda_du, 1e-10):lambda; + bb_A_b = true; + bb_shrink_lambda = true; + } + else + { + lambda = ::fmin(lambda*lambda_fu, 1e+8); + bb_A_b = false; + bb_shrink_lambda = false; + } + } + + // backward transformation coefficients + bk_transformation_coef(coef); + + // from nonlinear - linear coeff to mixed + nonlinear_linear_2_mixed(coef); + + return ee_b; + } + + private: + const T r2_min; + T Ixy_i_sc; + T Ixy_0_sum; + dt_int32 n_pos_typ; + dt_int32 n_coef_pa; + dt_int32 n_coef_nl_pa; + dt_int32 n_coef; + dt_int32 n_coef_nl; + dt_int32 nxy; + dt_int32 n_cstr; + + std::mt19937_64 gen_c; + std::uniform_real_distribution rand_c; + + TVctr_r2d Rxy_0; + TVctr_r Ixy_0; + TVctr_r Ixy; + TVctr_r dIxy; + TVctr_r J; + TVctr_r A; + TVctr_r A_lambda; + TVctr_r b; + TVctr_r cstr; + + lapack::MNS_SVD mns_svd; + + struct PTypes + { + public: + TVctr_r2d p; + + dt_int32 size() const + { + return p.size(); + } + + void reserve(size_type n_pos) + { + p.reserve(n_pos); + } + + void shrink_to_fit() + { + p.shrink_to_fit(); + } + }; + + using VPTypes = vector; + + VPTypes split_pos_by_types(TVctr_r &pos_i) + { + const auto n_pos = pos_i.size()/3; + + // get unique types + TVctr_r ptypes_u(pos_i.begin()+2*n_pos, pos_i.end()); + std::sort(ptypes_u.begin(), ptypes_u.end()); + ptypes_u.erase(std::unique(ptypes_u.begin(), ptypes_u.end(), mt::fcn_is_equal), ptypes_u.end()); + ptypes_u.shrink_to_fit(); + + dt_int32 n_ptypes_u = ptypes_u.size(); + VPTypes pos_typ(n_ptypes_u); + + // create map + std::map mptypes_u; + for(auto idx=0; idx(pos_i[n_pos*2+ip]); + idx = mptypes_u[idx]; + T x = pos_i[n_pos*0+ip]; + T y = pos_i[n_pos*1+ip]; + pos_typ[idx].p.push_back(R_2d(x, y)); + } + + // shrink to fit + for(dt_int32 idx=0; idx sum = 0; + for(auto ixy = 0; ixy < nxy; ixy++) + { + T Ixy = Ixy_i[ixy]/Ixy_i_sc; + sum += Ixy; + + Ixy_0[ixy] = Ixy; + Rxy_0[ixy] = R_2d(Rx_i[ixy], Ry_i[ixy]); + } + Ixy_0_sum = sum; + + cstr = cstr_i; + for(auto ik = 2; ik < n_cstr; ik++) + { + cstr[ik] /= Ixy_i_sc; + } + } + + // add lamba x diagonal to matrix A_lambda + void add_lambda(dt_int32 n, TVctr_r &A, T lambda, TVctr_r &B) + { + std::copy(A.begin(), A.end(), B.begin()); + for(auto ic=0; ic*ss)); + + // for(auto ic = 0; ic < n_coef_nl; ic++) + // { + // coef[ic] *= f; + // } + } + + // add d_coef + void add_d_coef(TVctr_r &coef_i, TVctr_r &d_coef, TVctr_r &coef_o) + { + std::transform(coef_i.begin(), coef_i.end(), d_coef.begin(), coef_o.begin(), std::plus()); + } + + // forward transformation coefficients + void fw_transformation_coef(TVctr_r &coef) + { + for(auto ic = n_coef_nl; ic < n_coef; ic++) + { + coef[ic] = log(coef[ic]/Ixy_i_sc); + } + } + + // backward transformation coefficients + void bk_transformation_coef(TVctr_r &coef) + { + for(auto ic = n_coef_nl; ic < n_coef; ic++) + { + coef[ic] = Ixy_i_sc*exp(coef[ic]); + } + } + + // check lambda + dt_bool increase_lambda(TVctr_r &coef_min, TVctr_r &coef_max, TVctr_r &coef) + { + dt_bool bb_lambda = false; + for(auto ic = 0; ic < n_coef; ic++) + { + if ((coef_min[ic]>coef[ic])||(coef[ic]>coef_max[ic])) + { + bb_lambda = true; + break; + } + } + + return bb_lambda; + } + + // set constraints + void set_constraints(TVctr_r &coef_i, TVctr_r &coef_min, + TVctr_r &coef_max, TVctr_r &coef_o) + { + dt_int32 is = 0; + for(auto ic = 0; ic < n_coef; ic++) + { + if ((coef_min[ic]>coef_o[ic])||(coef_o[ic]>coef_max[ic])) + { + coef_o[ic] = coef_i[ic]; + is++; + } + } + + if (is==n_coef) + { + for(auto ic = 0; ic < n_coef; ic++) + { + T f = 0.9 + 0.0999*rand_c(gen_c); + coef_o[ic] = f*coef_i[ic]; + } + } + } + + // from mixed tononlinear -linear coeff + void mixed_2_nonlinear_linear(TVctr_r &coef) + { + auto coef_t = coef; + + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx = n_coef_pa*ipt; + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + coef[idx_l+0]= coef_t[idx+0]; + coef[idx_l+1] = coef_t[idx+1]; + + coef[idx_nl+0] = coef_t[idx+2]; + coef[idx_nl+1] = coef_t[idx+3]; + coef[idx_nl+2] = coef_t[idx+4]; + } + } + + // from nonlinear - linear coeff to mixed + void nonlinear_linear_2_mixed(TVctr_r &coef) + { + auto coef_t = coef; + + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx = n_coef_pa*ipt; + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + coef[idx+0] = coef_t[idx_l+0]; + coef[idx+1] = coef_t[idx_l+1]; + + coef[idx+2] = coef_t[idx_nl+0]; + coef[idx+3]= coef_t[idx_nl+1]; + coef[idx+4] = coef_t[idx_nl+2]; + } + } + + // calculate error, jacobian, and dIxy + T cal_ee_Ixy_dIxy_J(VPTypes &pos_typ, TVctr_r2d &Rxy_0, TVctr_r &Ixy_0, + TVctr_r &coef, TVctr_r &Ixy, TVctr_r &dIxy, TVctr_r &J) + { + KS Ixy_p; + + KS J0; + KS J1; + + KS J2; + KS J3; + KS J4; + + // set zero Ixy + std::fill(Ixy.begin(), Ixy.end(), T(0)); + + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + const T alpha = coef[idx_nl + 0]; + const T sigma1 = coef[idx_nl + 1]; + const T sigma2 = coef[idx_nl + 2]; + + const T a1 = coef[idx_l + 0]; + const T a2 = coef[idx_l + 1]; + + const T sigma1_2 = sigma1*sigma1; + const T sigma1_3 = sigma1_2*sigma1; + const T f_sigma1 = 1.0/(2*sigma1_2); + + const T sigma2_2 = sigma2*sigma2; + const T sigma2_3 = sigma2_2*sigma2; + const T f_sigma2 = 1.0/(2*sigma2_2); + + const auto &p = pos_typ[ipt].p; + const dt_int32 np = p.size(); + + for(auto ixy = 0; ixy < nxy; ixy++) + { + Ixy_p = 0; + J0 = J1 = J2 = J3 = J4 = 0; + + const auto Rxy = Rxy_0[ixy]; + // sum over positions + for(auto ip = 0; ip < np; ip++) + { + const T r2 = norm_2(Rxy-p[ip]); + const T ln_r2 = (r2>r2_min)?log(r2):0; + + const T ep_1 = exp(a1-f_sigma1*r2); + const T ep_2 = (r2>r2_min)?exp(a2+ln_r2*alpha-f_sigma2*r2):0; + + Ixy_p += ep_1 + ep_2; + + J0 += ln_r2*ep_2; + J1 += ep_1*r2; + J2 += ep_2*r2; + J3 += ep_1; + J4 += ep_2; + } + + // assign values + Ixy[ixy] += Ixy_p; + + J[(idx_nl + 0)*nxy + ixy] = J0; + J[(idx_nl + 1)*nxy + ixy] = J1/sigma1_3; + J[(idx_nl + 2)*nxy + ixy] = J2/sigma2_3; + J[(idx_l + 0)*nxy + ixy] = J3; + J[(idx_l + 1)*nxy + ixy] = J4; + } + } + + /***************************************************************************************/ + KS ee = 0; + for(auto ixy = 0; ixy < nxy; ixy++) + { + T dIxy_p = Ixy_0[ixy] - Ixy[ixy]; + dIxy[ixy] = dIxy_p; + ee += ::fabs(dIxy_p); + } + + ee = 100*ee/Ixy_0_sum; + + return ee; + } + + // calculate matrix A and b + void get_A_b(TVctr_r &J, TVctr_r &dIxy, TVctr_r &A, TVctr_r &b) + { + const dt_int32 nxy = dIxy.size(); + const dt_int32 n_coef = b.size(); + + /***************************************************************************************/ + // get ATxA + KS ks; + for(auto ic=0; ic + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef FIT_ATOMIC_COLUMN_C_H +#define FIT_ATOMIC_COLUMN_C_H + +#include +#include +#include +#include + +#include +#include "math.cuh" +#include "type_traits_gen.cuh" +#include "types.cuh" +#include "lapack.hpp" + namespace mt +{ + template + class Fit_Atomic_Columns_C + { + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Fit_Atomic_Columns_C():n_coef_pa(4), n_coef_nl_pa(2), r2_min(1e-8) {}; + + T fit(TVctr_r &Ixy_i, TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, TVctr_r &cstr_i, TVctr_r &coef) + { + // set random seed + std::random_device rd; + gen_c.seed(rd()); + + auto pos_typ = split_pos_by_types(pos_i); + + dt_int32 n_pos_typ = pos_typ.size(); + dt_int32 n_coef = n_coef_pa*n_pos_typ; + dt_int32 nxy = Ixy_i.size(); + + // allocate memory + set_size_local_variables(nxy, n_coef); + + // calculate intensity scaling factor + Ixy_i_sc = fcn_max_element(Ixy_i); + + // copy Ixy_i + std::copy(Ixy_i.begin(), Ixy_i.end(), Ixy_0.begin()); + + // rescale image + std::for_each(Ixy_0.begin(), Ixy_0.end(), [=](T& v) { v = v/Ixy_i_sc; }); + + Ixy_0_sum = nxy*fcn_mean(Ixy_0); + + // assign cstr_i + cstr = cstr_i; + + // rescale cstr + cstr[0] /= Ixy_i_sc; + + TVctr_r coef_min(n_coef); + TVctr_r coef_max(n_coef); + + // set initial coefficients and limits + set_coef_min_max(Ixy_0, coef_min, coef_max); + + // SVD minimum-norm solution + mns_svd.init(n_coef, n_coef); + + const T ee_ee = 1e-5; + const T ee_G_max = 1e-5; + const T ee_coef = 1e-7; + const dt_int32 n_iter = 150; + dt_bool bb_A_b = true; + dt_bool bb_shrink_lambda = false; + + T G_max; + T ee_coef_max; + T ee_t; + TVctr_r d_coef(n_coef); + TVctr_r coef_t(n_coef); + + T lambda = 1e-2; + const T lambda_fu = 8; + const T lambda_du = 5; + + // from mixed to nonlinear -linear coeff + mixed_2_nonlinear_linear(coef); + + // forward scaling coefficients + fw_scaling_coef(coef); + + // set dependent coefficients + // set_dependent_coef(cstr, coef); + + // call ee + T ee_b = cal_ee_Ixy_dIxy_J(pos_typ, Rx_i, Ry_i, Ixy_0, coef, Ixy, dIxy, J); + + for(auto iter = 0; iter < n_iter; iter++) + { + if (bb_A_b) + { + // calculate matrix A and b + get_A_b(J, dIxy, A, b); + + // get the maximum gradient + G_max = maximum_gradient(n_coef, b); + } + + // add lamba x diagonal to matrix A_lambda + add_lambda(n_coef, A, lambda, A_lambda); + + // solve the system of equations for d_coef + mns_svd(A_lambda.data(), b.data(), d_coef.data()); + + // add d_coef + add_d_coef(coef, d_coef, coef_t); + + // set constraints + set_constraints(coef, coef_min, coef_max, coef_t); + + // set dependent coefficients + // set_dependent_coef(cstr, coef_t); + + // calculate maximum error coefficients + ee_coef_max = diff_coef(coef, coef_t); + + // calculate error + ee_t = cal_ee_Ixy_dIxy_J(pos_typ, Rx_i, Ry_i, Ixy_0, coef_t, Ixy, dIxy, J); + + if ((G_max < ee_G_max)||(fabs(ee_b-ee_t) < ee_ee)||(ee_coef_max < ee_coef)) + { + break; + } + + if (ee_b > ee_t) + { + coef = coef_t; + ee_b = ee_t; + lambda = (bb_shrink_lambda)?::fmax(lambda/lambda_du, 1e-8):lambda; + bb_A_b = true; + bb_shrink_lambda = true; + } + else + { + lambda = ::fmin(lambda*lambda_fu, 1e+8); + bb_A_b = false; + bb_shrink_lambda = false; + } + } + + // backward scaling coefficients + bk_scaling_coef(coef); + + // from nonlinear - linear coeff to mixed + nonlinear_linear_2_mixed(coef); + + return ee_b; + } + + private: + const T r2_min; + T Ixy_i_sc; + T Ixy_0_sum; + dt_int32 n_coef_pa; + dt_int32 n_coef_nl_pa; + dt_int32 n_cstr; + + std::mt19937_64 gen_c; + std::uniform_real_distribution rand_c; + + TVctr_r Ixy_0; + TVctr_r Ixy; + TVctr_r dIxy; + TVctr_r J; + TVctr_r A; + TVctr_r A_lambda; + TVctr_r b; + TVctr_r cstr; + + lapack::MNS_SVD mns_svd; + + struct PTypes + { + public: + TVctr_r2d p; + + dt_int32 size() const + { + return p.size(); + } + + void reserve(size_type n_pos) + { + p.reserve(n_pos); + } + + void shrink_to_fit() + { + p.shrink_to_fit(); + } + }; + + using VPTypes = vector; + + VPTypes split_pos_by_types(TVctr_r &pos_i) + { + const auto n_pos = pos_i.size()/3; + + // get unique types + TVctr_r ptypes_u(pos_i.begin()+2*n_pos, pos_i.end()); + std::sort(ptypes_u.begin(), ptypes_u.end()); + ptypes_u.erase(std::unique(ptypes_u.begin(), ptypes_u.end(), mt::fcn_is_equal), ptypes_u.end()); + ptypes_u.shrink_to_fit(); + + dt_int32 n_ptypes_u = ptypes_u.size(); + VPTypes pos_typ(n_ptypes_u); + + // create map + std::map mptypes_u; + for(auto idx=0; idx(pos_i[n_pos*2+ip]); + idx = mptypes_u[idx]; + T x = pos_i[n_pos*0+ip]; + T y = pos_i[n_pos*1+ip]; + pos_typ[idx].p.push_back(R_2d(x, y)); + } + + // shrink to fit + for(dt_int32 idx=0; idx*ss)); + + for(auto ic = 0; ic < n_coef_nl; ic++) + { + coef[ic] *= f; + } + } + + // add d_coef + void add_d_coef(TVctr_r &coef_i, TVctr_r &d_coef, TVctr_r &coef_o) + { + std::transform(coef_i.begin(), coef_i.end(), d_coef.begin(), coef_o.begin(), std::plus()); + } + + // forward scaling coefficients + void fw_scaling_coef(TVctr_r &coef) + { + const dt_int32 n_coef = coef.size(); + const dt_int32 n_coef_nl = n_coef/n_coef_nl_pa; + + for(auto ic = n_coef_nl; ic < n_coef; ic++) + { + coef[ic] /= Ixy_i_sc; + } + } + + // backward scaling coefficients + void bk_scaling_coef(TVctr_r &coef) + { + const dt_int32 n_coef = coef.size(); + const dt_int32 n_coef_nl = n_coef/n_coef_nl_pa; + + for(auto ic = n_coef_nl; ic < n_coef; ic++) + { + coef[ic] *= Ixy_i_sc; + } + } + + // set constraints + void set_constraints(TVctr_r &coef_i, TVctr_r &coef_min, + TVctr_r &coef_max, TVctr_r &coef_o) + { + const dt_int32 n_coef = coef_i.size(); + dt_int32 is = 0; + for(auto ic = 0; ic < n_coef; ic++) + { + if ((coef_min[ic]>coef_o[ic])||(coef_o[ic]>coef_max[ic])) + { + coef_o[ic] = coef_i[ic]; + is++; + } + } + + if (is==n_coef) + { + for(auto ic = 0; ic < n_coef; ic++) + { + T f = 0.9 + 0.0999*rand_c(gen_c); + coef_o[ic] = f*coef_i[ic]; + } + } + } + + // from mixed tononlinear -linear coeff + void mixed_2_nonlinear_linear(TVctr_r &coef) + { + const dt_int32 n_coef = coef.size(); + const dt_int32 n_typ = n_coef/n_coef_pa; + const dt_int32 n_coef_nl = n_coef/n_coef_nl_pa; + auto coef_t = coef; + + for(auto ipt = 0; ipt < n_typ; ipt++) + { + const dt_int32 idx = n_coef_pa*ipt; + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + coef[idx_l+0]= coef_t[idx+0]; + coef[idx_l+1] = coef_t[idx+1]; + coef[idx_nl+0] = coef_t[idx+2]; + coef[idx_nl+1] = coef_t[idx+3]; + } + } + + // from nonlinear - linear coeff to mixed + void nonlinear_linear_2_mixed(TVctr_r &coef) + { + const dt_int32 n_coef = coef.size(); + const dt_int32 n_typ = n_coef/n_coef_pa; + const dt_int32 n_coef_nl = n_coef/n_coef_nl_pa; + auto coef_t = coef; + + for(auto ipt = 0; ipt < n_typ; ipt++) + { + const dt_int32 idx = n_coef_pa*ipt; + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + coef[idx] = coef_t[idx_l+0]; + coef[idx+1] = coef_t[idx_l+1]; + coef[idx+2]= coef_t[idx_nl+0]; + coef[idx+3] = coef_t[idx_nl+1]; + } + } + + // calculate error, jacobian, and dIxy + T cal_ee_Ixy_dIxy_J(VPTypes &pos_typ, TVctr_r &Rx, TVctr_r &Ry, TVctr_r &Ixy_0, + TVctr_r &coef, TVctr_r &Ixy, TVctr_r &dIxy, TVctr_r &J) + { + const dt_int32 n_typ = pos_typ.size(); + const dt_int32 nxy = Rx.size(); + const dt_int32 n_coef = n_coef_pa*n_typ; + const dt_int32 n_coef_nl = n_coef/n_coef_nl_pa; + + // set zero Ixy + std::fill(Ixy.begin(), Ixy.end(), T(0)); + + for(auto ipt = 0; ipt < n_typ; ipt++) + { + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + const T alpha = coef[idx_nl + 0]; + const T sigma = coef[idx_nl + 1]; + + const T a1 = coef[idx_l + 0]; + const T a2 = coef[idx_l + 1]; + + const T sigma_2 = sigma*sigma; + const T sigma_3 = sigma_2*sigma; + const T f_sigma = 1.0/(2*sigma_2); + + const auto &p = pos_typ[ipt].p; + const dt_int32 np = p.size(); + + KS Ixy_p; + + KS J0; + KS J1; + + KS J2; + KS J3; + + for(auto ixy = 0; ixy < nxy; ixy++) + { + Ixy_p = 0; + J0 = J1 = J2 = J3 = 0; + + const R_2d Rxy = R_2d(Rx[ixy], Ry[ixy]); + + // sum over positions + for(auto ip = 0; ip < np; ip++) + { + const T r2 = norm_2(Rxy-p[ip]); + const T ep_p = pow(r2, alpha); + const T ep_g = exp(-f_sigma*r2); + const T ep_pg = ep_p*ep_g; + + const T ln_r2 = (r2>r2_min)?log(r2):0; + + Ixy_p += (a1+a2*ep_p)*ep_g; + + J0 += ln_r2*ep_pg; + J1 += ep_g*r2; + J2 += ep_g; + J3 += ep_pg; + } + + // assign values + Ixy[ixy] += Ixy_p; + + J[(idx_nl + 0)*nxy + ixy] = a2*J0; + J[(idx_nl + 1)*nxy + ixy] = J1/sigma_3; + + J[(idx_l + 0)*nxy + ixy] = J2; + J[(idx_l + 1)*nxy + ixy] = J3; + } + } + + /***************************************************************************************/ + KS ee = 0; + for(auto ixy = 0; ixy < nxy; ixy++) + { + T dIxy_p = Ixy_0[ixy] - Ixy[ixy]; + dIxy[ixy] = dIxy_p; + ee += ::fabs(dIxy_p); + } + + ee = 100*ee/Ixy_0_sum; + + return ee; + } + + // calculate matrix A and b + void get_A_b(TVctr_r &J, TVctr_r &dIxy, TVctr_r &A, TVctr_r &b) + { + const dt_int32 nxy = dIxy.size(); + const dt_int32 n_coef = b.size(); + + /***************************************************************************************/ + // get ATxA + KS ks; + for(auto ic=0; ic + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef FIT_ATOMIC_COLUMN_C_H +#define FIT_ATOMIC_COLUMN_C_H + +#include +#include +#include +#include + +#include +#include "math.cuh" +#include "type_traits_gen.cuh" +#include "types.cuh" +#include "lapack.hpp" + namespace mt +{ + template + class Fit_Atomic_Columns_C + { + public: + using T_r = T; + using TVector_r = vector; + using TVector_r2d = vector>; + using size_type = std::size_t; + + static const eDev device = dev; + + Fit_Atomic_Columns_C():n_coef_pa(4), n_coef_nl_pa(2){}; + + T fit(TVector_r &Ixy_i, TVector_r &Rx_i, TVector_r &Ry_i, TVector_r &pos_i, TVector_r &cstr_i, TVector_r &coef) + { + // set random seed + std::random_device rd; + gen_c.seed(rd()); + + auto pos_typ = split_pos_by_types(pos_i); + + int n_pos_typ = pos_typ.size(); + int n_coef = n_coef_pa*n_pos_typ; + int nxy = Ixy_i.size(); + + // allocate memory + set_size_local_variables(nxy, n_coef); + + // calculate intensity scaling factor + Ixy_i_sc = max_element(Ixy_i); + + // copy Ixy_i + std::copy(Ixy_i.begin(), Ixy_i.end(), Ixy_0.begin()); + + // rescale image + std::for_each(Ixy_0.begin(), Ixy_0.end(), [=](T &v) { v = v/Ixy_i_sc;}); + + Ixy_0_sum = nxy*mean(Ixy_0); + + // assign cstr_i + cstr = cstr_i; + + // rescale cstr + cstr[0] /= Ixy_i_sc; + + TVector_r coef_min(n_coef); + TVector_r coef_max(n_coef); + + // set initial coefficients and limits + set_coef_min_max(Ixy_0, coef_min, coef_max); + + // SVD minimum-norm solution + mns_svd.init(n_coef, n_coef); + + const T ee_ee = 1e-5; + const T ee_G_max = 1e-5; + const T ee_coef = 1e-7; + const int n_iter = 150; + bool bb_A_b = true; + bool bb_shrink_lambda = false; + + T G_max; + T ee_coef_max; + T ee_t; + TVector_r d_coef(n_coef); + TVector_r coef_t(n_coef); + + T lambda = 1e-2; + const T lambda_fu = 8; + const T lambda_du = 5; + + // from mixed to nonlinear - linear coeff + mixed_2_nonlinear_linear(coef); + + // forward scaling coefficients + fw_scaling_coef(coef); + + // set dependent coefficients + // set_dependent_coef(cstr, coef); + + // set scs order + set_scs_order(coef); + + // call ee + T ee_b = cal_ee_Ixy_dIxy_J(pos_typ, Rx_i, Ry_i, Ixy_0, coef, Ixy, dIxy, J); + + for (auto iter = 0;iter < n_iter;iter++) + { + if (bb_A_b) + { + // calculate matrix A and b + get_A_b(J, dIxy, A, b); + + // get the maximum gradient + G_max = maximum_gradient(n_coef, b); + } + + // add lamba x diagonal to matrix A_lambda + add_lambda(n_coef, A, lambda, A_lambda); + + // solve the system of equations for d_coef + mns_svd(A_lambda.data(), b.data(), d_coef.data()); + + // add d_coef + add_d_coef(coef, d_coef, coef_t); + + // set constraints + set_constraints(coef, coef_min, coef_max, coef_t); + + // set dependent coefficients + // set_dependent_coef(cstr, coef_t); + + // calculate maximum error coefficients + ee_coef_max = diff_coef(coef, coef_t); + + // calculate error + ee_t = cal_ee_Ixy_dIxy_J(pos_typ, Rx_i, Ry_i, Ixy_0, coef_t, Ixy, dIxy, J); + + if ((G_max < ee_G_max)||(fabs(ee_b-ee_t) < ee_ee)||(ee_coef_max < ee_coef)) + { + break; + } + + if (ee_b > ee_t) + { + // set scs order + set_scs_order(coef_t); + + coef = coef_t; + ee_b = ee_t; + lambda = (bb_shrink_lambda)?::fmax(lambda/lambda_du, 1e-8):lambda; + bb_A_b = true; + bb_shrink_lambda = true; + } + else + { + lambda = ::fmin(lambda*lambda_fu, 1e+8); + bb_A_b = false; + bb_shrink_lambda = false; + } + } + + // backward scaling coefficients + bk_scaling_coef(coef); + + // from nonlinear - linear coeff to mixed + nonlinear_linear_2_mixed_(n_coef, coef); + + return ee_b; + } + + private: + T Ixy_i_sc; + T Ixy_0_sum; + int n_coef_pa; + int n_coef_nl_pa; + int n_cstr; + + std::mt19937_64 gen_c; + std::uniform_real_distribution rand_c; + + TVector_r Ixy_0; + TVector_r Ixy; + TVector_r dIxy; + TVector_r J; + TVector_r A; + TVector_r A_lambda; + TVector_r b; + TVector_r cstr; + + lapack::MNS_SVD mns_svd; + + struct PTypes + { + public: + TVector_r2d p; + + int size() const + { + return p.size(); + } + + void reserve(size_type n_pos) + { + p.reserve(n_pos); + } + + void shrink_to_fit() + { + p.shrink_to_fit(); + } + }; + + using VPTypes = vector; + + VPTypes split_pos_by_types(TVector_r &pos_i) + { + const auto n_pos = pos_i.size()/3; + + // get unique types + TVector_r ptypes_u(pos_i.begin()+2*n_pos, pos_i.end()); + std::sort(ptypes_u.begin(), ptypes_u.end()); + ptypes_u.erase(std::unique(ptypes_u.begin(), ptypes_u.end(), mt::isEqual), ptypes_u.end()); + ptypes_u.shrink_to_fit(); + + int n_ptypes_u = ptypes_u.size(); + VPTypes pos_typ(n_ptypes_u); + + // create map + std::map mptypes_u; + for(auto idx=0;idx(pos_i[n_pos*2+ip]); + idx = mptypes_u[idx]; + T x = pos_i[n_pos*0+ip]; + T y = pos_i[n_pos*1+ip]; + pos_typ[idx].p.push_back(r2d(x, y)); + } + + // shrink to fit + for(int idx=0;idx()); + } + + // forward scaling coefficients + void fw_scaling_coef(TVector_r &coef) + { + const int n_coef = coef.size(); + const int n_coef_nl = n_coef/n_coef_nl_pa; + + for (auto ic = n_coef_nl;ic < n_coef;ic++) + { + coef[ic] /= Ixy_i_sc; + } + } + + // backward scaling coefficients + void bk_scaling_coef(TVector_r &coef) + { + const int n_coef = coef.size(); + const int n_coef_nl = n_coef/n_coef_nl_pa; + + for (auto ic = n_coef_nl;ic < n_coef;ic++) + { + coef[ic] *= Ixy_i_sc; + } + } + + // set constraints + void set_constraints(TVector_r &coef_i, TVector_r &coef_min, + TVector_r &coef_max, TVector_r &coef_o) + { + const int n_coef = coef_i.size(); + int is = 0; + for (auto ic = 0;ic < n_coef;ic++) + { + if ((coef_min[ic]>coef_o[ic])||(coef_o[ic]>coef_max[ic])) + { + coef_o[ic] = coef_i[ic]; + is++; + } + } + + if (is==n_coef) + { + for (auto ic = 0;ic < n_coef;ic++) + { + T f = 0.9 + 0.0999*rand_c(gen_c); + coef_o[ic] = f*coef_i[ic]; + } + } + } + + // from mixed to nonlinear - linear coeff + void mixed_2_nonlinear_linear(TVector_r &coef) + { + const int n_coef = coef.size(); + const int n_coef_nl = n_coef/n_coef_nl_pa; + auto coef_t = coef; + + for (auto ic = 0;ic < n_coef_nl;ic++) + { + coef[ic] = coef_t[2*ic+1]; // non linear coefficients + coef[n_coef_nl+ic] = coef_t[2*ic]; // non linear coefficients + } + } + + // from nonlinear - linear coeff to mixed + void nonlinear_linear_2_mixed_(const int &n_coef, TVector_r &coef) + { + const int n_coef_nl = n_coef/n_coef_nl_pa; + auto coef_t = coef; + + for (auto ic = 0;ic < n_coef_nl;ic++) + { + coef[2*ic] = coef_t[n_coef_nl+ic]; // non linear coefficients + coef[2*ic+1] = coef_t[ic]; // non linear coefficients + } + } + + // set order + void set_scs_order(TVector_r &coef) + { + const int n_coef = coef.size(); + const int n_coef_nl = n_coef/n_coef_nl_pa; + int n_typ = n_coef/n_coef_pa; + + for (auto ipt = 0;ipt < n_typ;ipt++) + { + const int idx_nl = n_coef_nl_pa*ipt; + const int idx_l = n_coef_nl + idx_nl; + + const T sigma1 = coef[idx_nl + 0]; + const T sigma2 = coef[idx_nl + 1]; + const T a1 = coef[idx_l + 0]; + const T a2 = coef[idx_l + 1]; + + if (a1*sigma1*sigma1 < a2*sigma2*sigma2) + { + coef[idx_nl + 0] = sigma2; + coef[idx_nl + 1] = sigma1; + + coef[idx_l + 0] = a2; + coef[idx_l + 1] = a1; + } + } + } + + // calculate error, Jacobian, and dIxy + T cal_ee_Ixy_dIxy_J(VPTypes &pos_typ, TVector_r &Rx, TVector_r &Ry, TVector_r &Ixy_0, + TVector_r &coef, TVector_r &Ixy, TVector_r &dIxy, TVector_r &J) + { + const int n_typ = pos_typ.size(); + const int nxy = Rx.size(); + const int n_coef = n_coef_pa*n_typ; + const int n_coef_nl = n_coef/n_coef_nl_pa; + + // set zero Ixy + std::fill(Ixy.begin(), Ixy.end(), T(0)); + + for (auto ipt = 0;ipt < n_typ;ipt++) + { + const int idx_nl = n_coef_nl_pa*ipt; + const int idx_l = n_coef_nl + idx_nl; + + const T sigma1 = coef[idx_nl + 0]; + const T sigma2 = coef[idx_nl + 1]; + + const T a1 = coef[idx_l + 0]; + const T a2 = coef[idx_l + 1]; + + const T sigma1_2 = sigma1*sigma1; + const T sigma1_3 = sigma1_2*sigma1; + const T f_sigma1 = 1.0/(2*sigma1_2); + + const T sigma2_2 = sigma2*sigma2; + const T sigma2_3 = sigma2_2*sigma2; + const T f_sigma2 = 1.0/(2*sigma2_2); + + const auto &p = pos_typ[ipt].p; + const int np = p.size(); + + KS Ixy_p; + + KS sg1_0; + KS sg1_2; + + KS sg2_0; + KS sg2_2; + + for (auto ixy = 0;ixy < nxy;ixy++) + { + Ixy_p = 0; + sg1_0 = sg1_2 = 0; + sg2_0 = sg2_2 = 0; + + const r2d Rxy = r2d(Rx[ixy], Ry[ixy]); + + // sum over positions + for (auto ip = 0;ip < np;ip++) + { + const T r2 = norm(Rxy-p[ip]); + const T ep_g1 = exp(-f_sigma1*r2); + const T ep_g2 = exp(-f_sigma2*r2); + + Ixy_p += a1*ep_g1 + a2*ep_g2; + + sg1_0 += ep_g1; + sg1_2 += ep_g1*r2; + + sg2_0 += ep_g2; + sg2_2 += ep_g2*r2; + } + + // assign calculate values + Ixy[ixy] += Ixy_p; + + J[(idx_nl + 0)*nxy + ixy] = a1*sg1_2/sigma1_3; + J[(idx_nl + 1)*nxy + ixy] = a2*sg2_2/sigma2_3; + + J[(idx_l + 0)*nxy + ixy] = sg1_0; + J[(idx_l + 1)*nxy + ixy] = sg2_0; + } + } + + /****************************************************************************/ + KS ee = 0; + for (auto ixy = 0;ixy < nxy;ixy++) + { + T dIxy_p = Ixy_0[ixy] - Ixy[ixy]; + dIxy[ixy] = dIxy_p; + ee += ::fabs(dIxy_p); + } + + ee = 100*ee/Ixy_0_sum; + + return ee; + } + + // calculate matrix A and b + void get_A_b(TVector_r &J, TVector_r &dIxy, TVector_r &A, TVector_r &b) + { + const int nxy = dIxy.size(); + const int n_coef = b.size(); + + /****************************************************************************/ + // get ATxA + KS ks; + for(auto ic=0;ic + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef EVAL_FIT_GAUSSIANS_H +#define EVAL_FIT_GAUSSIANS_H + +#include +#include +#include +#include + +#include "math.cuh" +#include "type_traits_gen.cuh" +#include "types.cuh" +#include "lapack.hpp" + + namespace mt +{ + template + class Fit_one_rad_fcn_2d + { + public: + using T_r = T; + using TVctr_r = vector; + using TRegion_r = Region_Rad_2d; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Fit_one_rad_fcn_2d():n_coef(6), n_coef_nl(4), n_coef_l(2), lambda(1), + lambda_fu(8), lambda_du(5), ee_ee(1e-5), ee_G_max(1e-5), ee_coef(1e-7) {}; + + template + TVctr_r fit(TVctr& Ixy_i, R_2d pos_i, T sigma_i, T radius_i) + { + thrust::copy(Ixy_i.begin(), Ixy_i.end(), Ixy.begin()); + + // select circular region + select_cir_reg(Ixy, pos_i, radius_i, region); + + // set initial coefficients and limits + set_init_min_max_coef_0(pos_i, region.Ixy_sc, sigma_i, radius_i, coef, coef_min, coef_max); + + const dt_int32 n_it_o = 4; + for(auto it = 0; it < n_it_o; it++) + { + const dt_int32 n_it_i = (it == n_it_o-1)?35:15; + + T ee_b = fit_region(region, coef, coef_min, coef_max, lambda, n_it_i); + + if (it < n_it_o - 1) + { + // select elliptical region + select_ellip_reg(Ixy, coef, 0.5, region); + + // set coefficients and limits + set_min_max_coef(coef, coef_min, coef_max); + } + lambda = lambda/2; + } + + return coef; + } + + protected: + T lambda; + T lambda_fu; + T lambda_du; + + dt_int32 n_iter; + T ee_ee; + T ee_G_max; + T ee_coef; + + dt_int32 n_coef; + dt_int32 n_coef_nl; + dt_int32 n_coef_l; + + std::mt19937_64 gen_c; + std::uniform_real_distribution rand_c; + + Grid_2d grid_2d; + + TVctr_r Ixy; + TVctr_r dIxy; + TVctr_r J; + TVctr_r A; + TVctr_r A_lambda; + TVctr_r b; + + TVctr_r coef_min; + TVctr_r coef_max; + TVctr_r coef; + TVctr_r d_coef; + TVctr_r coef_t; + + lapack::MNS_SVD mns_svd; + + TRegion_r region; + + /***************************************************************************************/ + // set initial coefficients and limits + virtual void set_init_min_max_coef_0(R_2d p, T Ip_max, T sigma, T radius, TVctr_r &coef, TVctr_r &coef_min, TVctr_r &coef_max) = 0; + + // set coefficients and limits + virtual void set_min_max_coef(TVctr_r &coef, TVctr_r &coef_min, TVctr_r &coef_max) = 0; + + // forward transformation coefficients + virtual void fw_transformation_coef(TRegion_r ®ion, TVctr_r &coef) = 0; + + // backward transformation coefficients + virtual void bk_transformation_coef(TRegion_r ®ion, TVctr_r &coef) =0; + + // set order coef + virtual void set_order_coef(TVctr_r &coef) = 0; + + // calculate error, jacobian, and dIxy + virtual T cal_ee_dIxy_J(TRegion_r ®ion, TVctr_r &coef, TVctr_r &dIxy, TVctr_r &J) = 0; + + /***************************************************************************************/ + T fit_region(TRegion_r ®ion, TVctr_r &coef, TVctr_r coef_min, TVctr_r coef_max, T lambda, dt_int32 n_iter) + { + const dt_int32 nxy = region.size(); + + dt_bool bb_A_b = true; + dt_bool bb_shrink_lambda = false; + + T G_max; + T ee_coef_max; + T ee_t; + + // forward transformation coefficients + fw_transformation_coef(region, coef); + fw_transformation_coef(region, coef_min); + fw_transformation_coef(region, coef_max); + + // set order coef + set_order_coef(coef); + + // call ee + T ee = cal_ee_dIxy_J(region, coef, dIxy, J); + + for(auto iter = 0; iter < n_iter; iter++) + { + if (bb_A_b) + { + // calculate matrix A and b + cal_A_b(nxy, J, dIxy, A, b); + + // get the maximum gradient + G_max = maximum_gradient(b); + } + + // add lamba x diagonal to matrix A_lambda + add_lambda(A, lambda, A_lambda); + + // solve the system of equations for d_coef + mns_svd(A_lambda.data(), b.data(), d_coef.data()); + + // add d_coef + add_d_coef(coef, d_coef, coef_t); + + // set order coef + set_order_coef(coef_t); + + // set constraints + set_constraints(coef, coef_min, coef_max, coef_t); + + // calculate maximum error coefficients + ee_coef_max = diff_coef(coef, coef_t); + + // calculate error + ee_t = cal_ee_dIxy_J(region, coef_t, dIxy, J); + + if ((G_max < ee_G_max)||(fabs(ee-ee_t) < ee_ee)||(ee_coef_max < ee_coef)) + { + break; + } + + if (ee > ee_t) + { + coef = coef_t; + ee = ee_t; + lambda = (bb_shrink_lambda)?::fmax(lambda/lambda_du, 1e-8):lambda; + bb_A_b = true; + bb_shrink_lambda = true; + } + else + { + lambda = ::fmin(lambda*lambda_fu, 1e+8); + bb_A_b = false; + bb_shrink_lambda = false; + } + } + + // backward transformation coefficients + bk_transformation_coef(region, coef); + + return ee; + } + + /***************************************************************************************/ + // set random seed + void set_random_seed() + { + std::random_device rd; + gen_c.seed(rd()); + } + + // allocate memory + void set_size_local_variables(dt_int32 nxy, dt_int32 n_coef) + { + Ixy.resize(nxy); + dIxy.resize(nxy); + J.resize(nxy*n_coef); + A.resize(n_coef*n_coef); + A_lambda.resize(n_coef*n_coef); + b.resize(n_coef); + + coef_min.resize(n_coef); + coef_max.resize(n_coef); + coef.resize(n_coef); + d_coef.resize(n_coef); + coef_t.resize(n_coef); + } + + void init_variables(Grid_2d& grid_2d_i, T lambda_i, + dt_int32 n_coef_i, dt_int32 n_coef_nl_i) + { + // set random seed + set_random_seed(); + + grid_2d = grid_2d_i; + + n_coef = n_coef_i; + n_coef_nl = n_coef_nl_i; + n_coef_l = n_coef - n_coef_nl; + + // set default values + ee_ee = 1e-5; + ee_G_max = 1e-5; + ee_coef = 1e-7; + + lambda = lambda_i; + lambda_fu = 8; + lambda_du = 5; + + // allocate memory + set_size_local_variables(grid_2d.size(), n_coef); + + // SVD minimum-norm solution + mns_svd.init(n_coef, n_coef); + } + + /***************************************************************************************/ + // add lamba x diagonal to matrix A_lambda + void add_lambda(TVctr_r &A, T lambda, TVctr_r &B) + { + std::copy(A.begin(), A.end(), B.begin()); + for(auto ic=0; ic()); + } + + // set constraints + void set_constraints(TVctr_r &coef_i, TVctr_r &coef_min, + TVctr_r &coef_max, TVctr_r &coef_o) + { + dt_int32 is = 0; + for(auto ic = 0; ic < n_coef; ic++) + { + if ((coef_min[ic]>coef_o[ic])||(coef_o[ic]>coef_max[ic])) + { + coef_o[ic] = coef_i[ic]; + is++; + } + } + + if (is==n_coef) + { + for(auto ic = 0; ic < n_coef; ic++) + { + T f = 0.9 + 0.0999*rand_c(gen_c); + coef_o[ic] = f*coef_i[ic]; + } + } + } + + // calculate matrix A and b + void cal_A_b(dt_int32 nxy, TVctr_r &J, TVctr_r &dIxy, TVctr_r &A, TVctr_r &b) + { + /***************************************************************************************/ + // get ATxA + KS ks; + for(auto ic=0; ic& p, T radius, TRegion_r ®ion) + { + const T R_max = radius; + const T R2_max = pow(R_max, 2); + const T Rl2_max = pow(2.5*grid_2d.dR_min(), 2); + + auto range = grid_2d.region_ind(p, R_max); + + region.clear(); + region.reserve(range.ind_e); + + // select circular region + KS I_xy_m = 0; + dt_int32 I_c = 0; + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + const T R2 = grid_2d.r2(ix, iy, p.x, p.y); + if (R2 < R2_max) + { + auto v = Ixy[grid_2d.sub_2_ind(ix, iy)]; + region.Rx.push_back(grid_2d.rx(ix)); + region.Ry.push_back(grid_2d.ry(iy)); + region.Ixy.push_back(v); + if (R2 < Rl2_max) + { + I_xy_m += v; + I_c++; + } + } + + } + } + region.shrink_to_fit(); + + I_xy_m = I_xy_m/I_c; + region.R_max = R_max; + region.Rx_sf = p.x; + region.Ry_sf = p.y; + region.Rxy_sc = region.R_max; + region.Ixy_sf = 0.0; + region.Ixy_sc = 0.5*(I_xy_m + fcn_max_element(region.Ixy)); + + // scaling and shifting data + region.sf_sc(); + }; + + void select_ellip_reg(TVctr_r &Ixy, TVctr_r &coef, T f0, TRegion_r ®ion) + { + const R_2d p(coef[0], coef[1]); + + T a, b, c; + ellipse_var(coef[3], coef[4], coef[5], a, b, c); + + const T d = log(f0); + const T dd = c*c - 4*a*b; + + const T radius_y = sqrt(fabs(4*a*d/dd)); + const T radius_x = sqrt(fabs(4*b*d/dd)); + + const T x_0 = p.x - radius_x; + const T x_e = p.x + radius_x; + + const T y_0 = p.y - radius_y; + const T y_e = p.y + radius_y; + + const dt_int32 ix_0 = grid_2d.rx_2_irx_cds(x_0); + const dt_int32 ix_e = grid_2d.rx_2_irx_fds(x_e) + 1; + + const dt_int32 iy_0 = grid_2d.ry_2_iry_cds(y_0); + const dt_int32 iy_e = grid_2d.ry_2_iry_fds(y_e) + 1; + + region.clear(); + region.reserve((ix_e - ix_0)*(iy_e - iy_0)); + + // select elliptical region + for(auto ix = ix_0; ix < ix_e; ix++) + { + T dx = grid_2d.rx(ix) - p.x; + T ddy = sqrt(fabs(dd*dx*dx - 4*b*d)); + + T y_0 = (-c*dx - ddy)/(2*b) + p.y; + T y_e = (-c*dx + ddy)/(2*b) + p.y; + + dt_int32 iy_0 = grid_2d.ry_2_iry_bfds(y_0); + dt_int32 iy_e = grid_2d.ry_2_iry_bcds(y_e) + 1; + + for(auto iy = iy_0; iy < iy_e; iy++) + { + region.Rx.push_back(grid_2d.rx(ix)); + region.Ry.push_back(grid_2d.ry(iy)); + region.Ixy.push_back(Ixy[grid_2d.sub_2_ind(ix, iy)]); + } + } + region.shrink_to_fit(); + + region.R_max = max(coef[3], coef[4]); + region.Rx_sf = p.x; + region.Ry_sf = p.y; + region.Rxy_sc = region.R_max; + region.Ixy_sf = 0.0; + region.Ixy_sc = fcn_max_element(region.Ixy); + + // scaling and shifting data + region.sf_sc(); + }; + }; + + /***************************************************************************************/ + /***************************************************************************************/ + + template + class Eval_Ellipt_Gauss_2d + { + public: + using T_r = T; + using TVctr_r = vector; + using TRegion_r = Region_Rad_2d; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Eval_Ellipt_Gauss_2d() {}; + + void operator()(TVctr_r &coef, TVctr_r &Rx, TVctr_r &Ry, TVctr_r &Ixy) + { + const T x_0 = coef[0]; + const T y_0 = coef[1]; + const T A = coef[2]; + const T theta = coef[5]; + const T cos_1t = cos(theta); + const T sin_1t = sin(theta); + const T cos_2t = cos(2*theta); + const T sin_2t = sin(2*theta); + + const T sx2 = pow(coef[3], 2); + const T sy2 = pow(coef[4], 2); + + const T a = 0.5*(cos_1t*cos_1t/sx2 + sin_1t*sin_1t/sy2); + const T b = 0.5*(sin_1t*sin_1t/sx2 + cos_1t*cos_1t/sy2); + const T c = 0.5*(-sin_2t/sx2 + sin_2t/sy2); + + const dt_int32 nxy = Ixy.size(); + for(auto ixy = 0; ixy < nxy; ixy++) + { + T x = Rx[ixy] - x_0; + T y = Ry[ixy] - y_0; + + T v = exp(-a*x*x - b*y*y - c*x*y); + Ixy[ixy] = A*v; + } + } + }; + + template + class Fit_Ellipt_Gauss_2d: public Fit_one_rad_fcn_2d{ + public: + using T_r = T; + using TVctr_r = vector; + using TRegion_r = Region_Rad_2d; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Fit_Ellipt_Gauss_2d():Fit_one_rad_fcn_2d() {}; + + void init_variables(Grid_2d& grid_2d_i, T lambda_i) + { + Fit_one_rad_fcn_2d::init_variables(grid_2d_i, lambda_i, 6, 4); + } + + template + R_2d fd_max_peak_pos(TVctr& Ixy_i) + { + dt_int32 ixy_max = thrust::max_element(Ixy_i.begin(), Ixy_i.end())-Ixy_i.begin(); + dt_int32 ix_max, iy_max; + grid_2d.ind_2_sub(ixy_max, ix_max, iy_max); + + return R_2d(grid_2d.rx(ix_max), grid_2d.ry(iy_max)); + } + + template + R_2d fit_peak_pos(TVctr& Ixy_i, R_2d pos_i, T sigma_i, T radius_i) + { + auto coef = this->fit(Ixy_i, pos_i, sigma_i, radius_i); + return R_2d(coef[0], coef[1]); + } + + protected: + // set initial coefficients and limits + void set_init_min_max_coef_0(R_2d p, T Ip_max, T sigma, T radius, TVctr_r &coef, TVctr_r &coef_min, TVctr_r &coef_max) + { + const T sigma_x = sigma; + const T sigma_y = sigma; + + /***************************************************************************************/ + // 0.8 = exp(-0.5*f^2) + const T dx = ::fmax(0.668*sigma_x, 1.5*grid_2d.drx); + const T x_min = grid_2d.set_bound_x(p.x-dx); + const T x_max = grid_2d.set_bound_x(p.x+dx); + + // 0.8 = exp(-0.5*f^2) + const T dy = ::fmax(0.668*sigma_y, 1.5*grid_2d.dry); + const T y_min = grid_2d.set_bound_y(p.y-dy); + const T y_max = grid_2d.set_bound_y(p.y+dy); + + const T sigma_x_min = ::fmax(sigma_x/5, 0.5*grid_2d.drx); + const T sigma_x_max = ::fmin(10*radius, grid_2d.bs_x_h()); + + const T sigma_y_min = ::fmax(sigma_y/5, 0.5*grid_2d.dry); + const T sigma_y_max = ::fmin(10*radius, grid_2d.bs_y_h()); + + /***************************************************************************************/ + coef = { p.x, p.y, Ip_max, sigma, sigma, T(c_pi)}; + coef_min = { x_min, y_min, T(0.25*Ip_max), sigma_x_min, sigma_y_min, T(0) }; + coef_max = { x_max, y_max, T(1.5*Ip_max), sigma_x_max, sigma_y_max, T(c_2pi) }; + } + + // set coefficients and limits + void set_min_max_coef(TVctr_r &coef, TVctr_r &coef_min, TVctr_r &coef_max) + { + T Ip_max = coef[2]; + + R_2d p(coef[0], coef[1]); + + const T sigma_x = coef[3]; + const T sigma_y = coef[4]; + + /***************************************************************************************/ + const T dx = ::fmax(sigma_x/4.0, 1.5*grid_2d.drx); + const T x_min = grid_2d.set_bound_x(p.x-dx); + const T x_max = grid_2d.set_bound_x(p.x+dx); + + const T dy = ::fmax(sigma_y/4.0, 1.5*grid_2d.dry); + const T y_min = grid_2d.set_bound_y(p.y-dy); + const T y_max = grid_2d.set_bound_y(p.y+dy); + + const T sigma_x_min = ::fmax(sigma_x/5.0, 0.5*grid_2d.drx); + const T sigma_x_max = ::fmin(3.0*sigma_x, grid_2d.bs_x_h()); + + const T sigma_y_min = ::fmax(sigma_y/5.0, 0.5*grid_2d.dry); + const T sigma_y_max = ::fmin(3.0*sigma_y, grid_2d.bs_y_h()); + + /***************************************************************************************/ + coef_min = { x_min, y_min, T(0.5*Ip_max), sigma_x_min, sigma_y_min, T(0) }; + coef_max = { x_max, y_max, T(1.50*Ip_max), sigma_x_max, sigma_y_max, T(c_2pi) }; + } + + // forward transformation coefficients + void fw_transformation_coef(TRegion_r ®ion, TVctr_r &coef) + { + coef[0] = (coef[0] - region.Rx_sf)/region.Rxy_sc; + coef[1] = (coef[1] - region.Ry_sf)/region.Rxy_sc; + coef[2] = coef[2]/region.Ixy_sc; + coef[3] = coef[3]/region.Rxy_sc; + coef[4] = coef[4]/region.Rxy_sc; + } + + // backward transformation coefficients + void bk_transformation_coef(TRegion_r ®ion, TVctr_r &coef) + { + coef[0] = coef[0]*region.Rxy_sc + region.Rx_sf; + coef[1] = coef[1]*region.Rxy_sc + region.Ry_sf; + coef[2] = coef[2]*region.Ixy_sc; + coef[3] = coef[3]*region.Rxy_sc; + coef[4] = coef[4]*region.Rxy_sc; + } + + // set order + void set_order_coef(TVctr_r &coef) + { + T theta = coef[5]; + theta = theta - ::floor(theta/c_2pi)*c_2pi; + coef[5] = theta; + } + + T cal_ee_dIxy_J(TRegion_r ®ion, TVctr_r &coef, TVctr_r &d_Ixy, TVctr_r &J) + { + const T x_0 = coef[0]; + const T y_0 = coef[1]; + const T A = coef[2]; + const T theta = coef[5]; + const T cos_1t = cos(theta); + const T sin_1t = sin(theta); + const T cos_2t = cos(2*theta); + const T sin_2t = sin(2*theta); + + const T sx2 = pow(coef[3], 2); + const T sy2 = pow(coef[4], 2); + + const T sx3 = pow(coef[3], 3); + const T sy3 = pow(coef[4], 3); + + const T a = 0.5*(cos_1t*cos_1t/sx2 + sin_1t*sin_1t/sy2); + const T b = 0.5*(sin_1t*sin_1t/sx2 + cos_1t*cos_1t/sy2); + const T c = 0.5*(-sin_2t/sx2 + sin_2t/sy2); + + KS ee = 0; + + const dt_int32 nxy = region.size(); + for(auto ixy = 0; ixy < nxy; ixy++) + { + T x = region.Rx[ixy] - x_0; + T y = region.Ry[ixy] - y_0; + + T v = exp(-a*x*x - b*y*y - c*x*y); + T Ixy_p = A*v; + + J[0*nxy + ixy] = (2*a*x + c*y)*Ixy_p; + J[1*nxy + ixy] = (2*b*y + c*x)*Ixy_p; + J[2*nxy + ixy] = v; + J[3*nxy + ixy] = (pow(cos_1t*x, 2) + pow(sin_1t*y, 2) - sin_2t*x*y)*Ixy_p/sx3; + J[4*nxy + ixy] = (pow(sin_1t*x, 2) + pow(cos_1t*y, 2) + sin_2t*x*y)*Ixy_p/sy3; + J[5*nxy + ixy] = (sin_2t*x*x - sin_2t*y*y + 2*cos_2t*x*y)*Ixy_p*(0.5/sx2 - 0.5/sy2); + + T dIxy_p = region.Ixy[ixy] - Ixy_p; + d_Ixy[ixy] = dIxy_p; + ee += ::fabs(dIxy_p); + } + ee = 100*ee/region.Ixy_sum; + + return ee; + } + }; + + /***************************************************************************************/ + /***************************************************************************************/ + template + class Eval_2d_PAC + { + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + Eval_2d_PAC() {}; + + virtual void operator()(TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, TVctr_r &coef, TVctr_r &Ixy)=0; + + protected: + struct PTypes + { + public: + TVctr_r2d p; + + dt_int32 size() const + { + return p.size(); + } + + void reserve(size_type n_pos_typ) + { + p.reserve(n_pos_typ); + } + + void shrink_to_fit() + { + p.shrink_to_fit(); + } + }; + + using VPTypes = vector; + + VPTypes split_pos_by_types(TVctr_r &pos_i) + { + const auto n_pos_typ = pos_i.size()/3; + + // get unique types + TVctr_r ptypes_u(pos_i.begin()+2*n_pos_typ, pos_i.end()); + std::sort(ptypes_u.begin(), ptypes_u.end()); + ptypes_u.erase(std::unique(ptypes_u.begin(), ptypes_u.end(), mt::fcn_is_equal), ptypes_u.end()); + ptypes_u.shrink_to_fit(); + + dt_int32 n_ptypes_u = ptypes_u.size(); + VPTypes pos_typ(n_ptypes_u); + + // create map + std::map mptypes_u; + for(auto idx=0; idx(pos_i[n_pos_typ*2+ip]); + idx = mptypes_u[idx]; + T x = pos_i[n_pos_typ*0+ip]; + T y = pos_i[n_pos_typ*1+ip]; + pos_typ[idx].p.push_back(R_2d(x, y)); + } + + // shrink to fit + for(dt_int32 idx=0; idx + class Fit_2d_PAC + { + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Fit_2d_PAC():n_pos_typ(1), n_coef_pa(2), n_coef_nl_pa(1), n_coef_l_pa(1), n_coef(0), n_coef_nl(0), n_cstr(0), + lambda(1), lambda_fu(8), lambda_du(5), r2_min(1e-10), Ixy_i_sc(1), Ixy_0_sum(1), + ee_ee(1e-5), ee_G_max(1e-5), ee_coef(1e-7), n_iter(150) {}; + + T fit(TVctr_r &Ixy_i, TVctr_r &cstr_i, TVctr_r &coef) + { + dt_bool bb_A_b = true; + dt_bool bb_shrink_lambda = false; + + T G_max; + T ee_coef_max; + T ee_t; + + // set Ixy and constraints + set_Ixy_cstr(Ixy_i, cstr_i); + + // forward transformation coefficients + fw_transformation_coef(coef); + + // set order coef + set_order_coef(coef); + + // set initial coefficients and limits + set_min_max_coef(coef_min, coef_max); + + // call ee + T ee = cal_ee_Ixy_dIxy_J(pos_typ, Rxy_0, Ixy_0, coef, Ixy, dIxy, J); + + for(auto iter = 0; iter < n_iter; iter++) + { + if (bb_A_b) + { + // calculate matrix A and b + cal_A_b(J, dIxy, A, b); + + // get the maximum gradient + G_max = maximum_gradient(b); + } + + // add lamba x diagonal to matrix A_lambda + add_lambda(A, lambda, A_lambda); + + // solve the system of equations for d_coef + mns_svd(A_lambda.data(), b.data(), d_coef.data()); + + // add d_coef + add_d_coef(coef, d_coef, coef_t); + + // set constraints + set_constraints(coef, coef_min, coef_max, coef_t); + + // calculate maximum error coefficients + ee_coef_max = diff_coef(coef, coef_t); + + // calculate error + ee_t = cal_ee_Ixy_dIxy_J(pos_typ, Rxy_0, Ixy_0, coef_t, Ixy, dIxy, J); + + if ((G_max < ee_G_max)||(fabs(ee-ee_t) < ee_ee)||(ee_coef_max < ee_coef)) + { + break; + } + + if (ee > ee_t) + { + set_order_coef(coef_t); + + coef = coef_t; + ee = ee_t; + lambda = (bb_shrink_lambda)?::fmax(lambda/lambda_du, 1e-8):lambda; + bb_A_b = true; + bb_shrink_lambda = true; + } + else + { + lambda = ::fmin(lambda*lambda_fu, 1e+8); + bb_A_b = false; + bb_shrink_lambda = false; + } + } + + // backward transformation coefficients + bk_transformation_coef(coef); + + return ee; + } + + protected: + struct PTypes + { + public: + TVctr_r2d p; + + dt_int32 size() const + { + return p.size(); + } + + void reserve(size_type n_pos) + { + p.reserve(n_pos); + } + + void shrink_to_fit() + { + p.shrink_to_fit(); + } + }; + + using VPTypes = vector; + + T lambda; + T lambda_fu; + T lambda_du; + + dt_int32 n_iter; + T ee_ee; + T ee_G_max; + T ee_coef; + T r2_min; + + T Ixy_i_sc; + T Ixy_0_sum; + + dt_int32 n_pos_typ; + dt_int32 n_coef_pa; + dt_int32 n_coef_nl_pa; + dt_int32 n_coef_l_pa; + dt_int32 n_coef; + dt_int32 n_coef_nl; + dt_int32 nxy; + dt_int32 n_cstr; + + std::mt19937_64 gen_c; + std::uniform_real_distribution rand_c; + + VPTypes pos_typ; + TVctr_r2d Rxy_0; + TVctr_r Ixy_0; + TVctr_r Ixy; + TVctr_r dIxy; + TVctr_r J; + TVctr_r A; + TVctr_r A_lambda; + TVctr_r b; + TVctr_r cstr; + + TVctr_r coef_min; + TVctr_r coef_max; + TVctr_r coef; + TVctr_r d_coef; + TVctr_r coef_t; + + lapack::MNS_SVD mns_svd; + + /***************************************************************************************/ + // set initial coefficients and limits + virtual void set_min_max_coef(TVctr_r &coef_min, TVctr_r &coef_max) = 0; + + // set order + virtual void set_order_coef(TVctr_r &coef) = 0; + + // calculate error, jacobian, and dIxy + virtual T cal_ee_Ixy_dIxy_J(VPTypes &pos_typ, TVctr_r2d &Rxy_0, TVctr_r &Ixy_0, + TVctr_r &coef, TVctr_r &Ixy, TVctr_r &dIxy, TVctr_r &J) = 0; + + /***************************************************************************************/ + // set Ixy and constraints + void set_Ixy_cstr(TVctr_r &Ixy_i, TVctr_r &cstr_i) + { + // calculate intensity scaling factor + Ixy_i_sc = fcn_max_element(Ixy_i); + + // assign data + KS sum = 0; + for(auto ixy = 0; ixy < nxy; ixy++) + { + T Ixy = Ixy_i[ixy]/Ixy_i_sc; + sum += Ixy; + + Ixy_0[ixy] = Ixy; + } + Ixy_0_sum = sum; + + cstr = cstr_i; + n_cstr = cstr_i.size(); + for(auto ik = 0; ik < n_cstr; ik++) + { + cstr[ik] /= Ixy_i_sc; + } + } + + // set random seed + void set_random_seed() + { + std::random_device rd; + gen_c.seed(rd()); + } + + // allocate memory + void set_size_local_variables(dt_int32 nxy, dt_int32 n_coef) + { + Rxy_0.resize(nxy); + Ixy_0.resize(nxy); + Ixy.resize(nxy); + dIxy.resize(nxy); + J.resize(nxy*n_coef); + A.resize(n_coef*n_coef); + A_lambda.resize(n_coef*n_coef); + b.resize(n_coef); + + coef_min.resize(n_coef); + coef_max.resize(n_coef); + coef.resize(n_coef); + d_coef.resize(n_coef); + coef_t.resize(n_coef); + } + + // set Rxy_0 + void set_rv(TVctr_r &Rx_i, TVctr_r &Ry_i) + { + for(auto ixy = 0; ixy < nxy; ixy++) + { + Rxy_0[ixy] = R_2d(Rx_i[ixy], Ry_i[ixy]); + } + } + + VPTypes split_pos_by_types(TVctr_r &pos_i) + { + const auto n_pos = pos_i.size()/3; + + // get unique types + TVctr_r ptypes_u(pos_i.begin()+2*n_pos, pos_i.end()); + std::sort(ptypes_u.begin(), ptypes_u.end()); + ptypes_u.erase(std::unique(ptypes_u.begin(), ptypes_u.end(), mt::fcn_is_equal), ptypes_u.end()); + ptypes_u.shrink_to_fit(); + + dt_int32 n_ptypes_u = ptypes_u.size(); + VPTypes pos_typ(n_ptypes_u); + + // create map + std::map mptypes_u; + for(auto idx=0; idx(pos_i[n_pos*2+ip]); + idx = mptypes_u[idx]; + T x = pos_i[n_pos*0+ip]; + T y = pos_i[n_pos*1+ip]; + pos_typ[idx].p.push_back(R_2d(x, y)); + } + + // shrink to fit + for(dt_int32 idx=0; idx()); + } + + // check lambda + dt_bool increase_lambda(TVctr_r &coef_min, TVctr_r &coef_max, TVctr_r &coef) + { + dt_bool bb_lambda = false; + for(auto ic = 0; ic < n_coef; ic++) + { + if ((coef_min[ic]>coef[ic])||(coef[ic]>coef_max[ic])) + { + bb_lambda = true; + break; + } + } + + return bb_lambda; + } + + // set constraints + void set_constraints(TVctr_r &coef_i, TVctr_r &coef_min, + TVctr_r &coef_max, TVctr_r &coef_o) + { + dt_int32 is = 0; + for(auto ic = 0; ic < n_coef; ic++) + { + if ((coef_min[ic]>coef_o[ic])||(coef_o[ic]>coef_max[ic])) + { + coef_o[ic] = coef_i[ic]; + is++; + } + } + + if (is==n_coef) + { + for(auto ic = 0; ic < n_coef; ic++) + { + T f = 0.9 + 0.0999*rand_c(gen_c); + coef_o[ic] = f*coef_i[ic]; + } + } + } + + // from mixed tononlinear -linear coeff + void mixed_2_nonlinear_linear(TVctr_r &coef) + { + auto coef_t = coef; + + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx = n_coef_pa*ipt; + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + for(auto ic = 0; ic < n_coef_pa; ic++) + { + auto idx_s = (ic ks; + for(auto ic=0; ic ee = 0; + for(auto ixy = 0; ixy < nxy; ixy++) + { + const T dIxy_p = Ixy_0[ixy] - Ixy[ixy]; + dIxy[ixy] = dIxy_p; + ee += ::fabs(dIxy_p); + } + + ee = 100*ee/Ixy_0_sum; + + return ee; + } + + // set vector to zero + void fill_vector(TVctr_r &Ixy, T val) + { + std::fill(Ixy.begin(), Ixy.end(), val); + } + }; + + /***************************************************************************************/ + template + class Eval_2_Gauss_PAC: public Eval_2d_PAC{ + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + Eval_2_Gauss_PAC(): Eval_2d_PAC() {}; + + void operator()(TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, TVctr_r &coef, TVctr_r &Ixy) + { + auto pos_typ = split_pos_by_types(pos_i); + + const dt_int32 n_pos_typ = pos_typ.size(); + const dt_int32 n_coef_pa = coef.size()/n_pos_typ; + const dt_int32 nxy = Rx_i.size(); + + KS Ixy_p; + + for(auto ixy = 0; ixy < nxy; ixy++) + { + Ixy_p = 0; + + const R_2d Rxy = R_2d(Rx_i[ixy], Ry_i[ixy]); + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx_c = n_coef_pa*ipt; + + const T a1 = coef[idx_c + 0]; + const T a2 = coef[idx_c + 1]; + + const T sigma1 = coef[idx_c + 2]; + const T f_sigma1 = 1.0/(2*sigma1*sigma1); + + const T sigma2 = coef[idx_c + 3]; + const T f_sigma2 = 1.0/(2*sigma2*sigma2); + + const auto &p = pos_typ[ipt].p; + const dt_int32 np = p.size(); + + // sum over positions + for(auto ip = 0; ip < np; ip++) + { + const T r2 = norm_2(Rxy-p[ip]); + const T ep_1 = a1*exp(-f_sigma1*r2); + const T ep_2 = a2*exp(-f_sigma2*r2); + + Ixy_p += ep_1 + ep_2; + } + } + + Ixy[ixy] = Ixy_p; + } + } + }; + + // fit two gaussians per atomic column + template + class Fit_2_Gauss_PAC: public Fit_2d_PAC{ + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Fit_2_Gauss_PAC(): Fit_2d_PAC() {}; + + void init_variables(TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, T lambda_i) + { + Fit_2d_PAC::init_variables(Rx_i, Ry_i, pos_i, lambda_i, 4, 2); + } + + protected: + // set initial coefficients and limits + void set_min_max_coef(TVctr_r &coef_min, TVctr_r &coef_max) + { + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx = n_coef_pa*ipt; + + coef_min[idx + 0] = 1e-2*Ixy_i_sc; + coef_min[idx + 1] = 1e-2*Ixy_i_sc; + coef_min[idx + 2] = 0.10; + coef_min[idx + 3] = 0.10; + + coef_max[idx + 0] = 1.10*Ixy_i_sc; + coef_max[idx + 1] = 1.10*Ixy_i_sc; + coef_max[idx + 2] = 5.0; + coef_max[idx + 3] = 5.0; + } + + this->fw_transformation_coef(coef_min); + this->fw_transformation_coef(coef_max); + } + + void set_order_coef(TVctr_r &coef) + { + + } + + // calculate error, jacobian, and dIxy + T cal_ee_Ixy_dIxy_J(VPTypes &pos_typ, TVctr_r2d &Rxy_0, TVctr_r &Ixy_0, + TVctr_r &coef, TVctr_r &Ixy, TVctr_r &dIxy, TVctr_r &J) + { + KS Ixy_p; + + KS J0; + KS J1; + + KS J2; + KS J3; + + // set zero Ixy + this->fill_vector(Ixy, 0); + + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + const T sigma1 = coef[idx_nl + 0]; + const T sigma2 = coef[idx_nl + 1]; + + const T a1 = coef[idx_l + 0]; + const T a2 = coef[idx_l + 1]; + + const T sigma1_2 = sigma1*sigma1; + const T sigma1_3 = sigma1_2*sigma1; + const T f_sigma1 = 1.0/(2*sigma1_2); + + const T sigma2_2 = sigma2*sigma2; + const T sigma2_3 = sigma2_2*sigma2; + const T f_sigma2 = 1.0/(2*sigma2_2); + + const auto &p = pos_typ[ipt].p; + const dt_int32 np = p.size(); + + for(auto ixy = 0; ixy < nxy; ixy++) + { + Ixy_p = 0; + J0 = J1 = J2 = J3 = 0; + + const auto Rxy = Rxy_0[ixy]; + for(auto ip = 0; ip < np; ip++) + { + const T r2 = norm_2(Rxy-p[ip]); + const T ep_1 = exp(a1-f_sigma1*r2); + const T ep_2 = exp(a2-f_sigma2*r2); + + Ixy_p += ep_1 + ep_2; + + J0 += ep_1*r2; + J1 += ep_2*r2; + J2 += ep_1; + J3 += ep_2; + } + + // assign values + Ixy[ixy] += Ixy_p; + + J[(idx_nl + 0)*nxy + ixy] = J0/sigma1_3; + J[(idx_nl + 1)*nxy + ixy] = J1/sigma2_3; + J[(idx_l + 0)*nxy + ixy] = J2; + J[(idx_l + 1)*nxy + ixy] = J3; + } + } + + T ee = this->cal_dIxy_ee(Ixy_0, Ixy, dIxy); + + return ee; + } + }; + + /***************************************************************************************/ + template + class Eval_Gauss_1P_PAC: public Eval_2d_PAC{ + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + Eval_Gauss_1P_PAC(): Eval_2d_PAC() {}; + + void operator()(TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, TVctr_r &coef, TVctr_r &Ixy) + { + auto pos_typ = split_pos_by_types(pos_i); + + const dt_int32 n_pos_typ = pos_typ.size(); + const dt_int32 n_coef_pa = coef.size()/n_pos_typ; + const dt_int32 nxy = Rx_i.size(); + + KS Ixy_p; + + for(auto ixy = 0; ixy < nxy; ixy++) + { + Ixy_p = 0; + const R_2d Rxy = R_2d(Rx_i[ixy], Ry_i[ixy]); + + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx_c = n_coef_pa*ipt; + + const T a1 = coef[idx_c + 0]; + const T a2 = coef[idx_c + 1]; + const T alpha = coef[idx_c + 2]; + const T sigma = coef[idx_c + 3]; + const T f_sigma = 1.0/(2*sigma*sigma); + + const auto &p = pos_typ[ipt].p; + const dt_int32 np = p.size(); + + // sum over positions + for(auto ip = 0; ip < np; ip++) + { + const T r2 = norm_2(Rxy-p[ip]); + const T ep_p = pow(r2, alpha); + const T ep_g = exp(-f_sigma*r2); + + Ixy_p += (a1 + a2*ep_p)*ep_g; + } + } + + Ixy[ixy] = Ixy_p; + } + } + }; + + template + class Fit_Gauss_1P_PAC: public Fit_2d_PAC{ + public: + using T_r = T; + using TVctr_r = vector; + using TVctr_r2d = vector>; + using size_type = dt_uint64; + + static const eDev device = Dev; + + Fit_Gauss_1P_PAC(): Fit_2d_PAC() {}; + + void init_variables(TVctr_r &Rx_i, TVctr_r &Ry_i, TVctr_r &pos_i, T lambda_i) + { + Fit_2d_PAC::init_variables(Rx_i, Ry_i, pos_i, lambda_i, 4, 2); + } + + protected: + void set_min_max_coef(TVctr_r &coef_min, TVctr_r &coef_max) + { + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx = n_coef_pa*ipt; + + coef_min[idx + 0] = 1e-2*Ixy_i_sc; + coef_min[idx + 1] = 1e-3*Ixy_i_sc; + coef_min[idx + 2] = 0.01; + coef_min[idx + 3] = 0.10; + + coef_max[idx + 0] = 1.10*Ixy_i_sc; + coef_max[idx + 1] = 1.0*Ixy_i_sc; + coef_max[idx + 2] = 8.0; + coef_max[idx + 3] = 5.0; + } + + this->fw_transformation_coef(coef_min); + this->fw_transformation_coef(coef_max); + } + + void set_order_coef(TVctr_r &coef) + { + + } + + // calculate error, jacobian, and dIxy + T cal_ee_Ixy_dIxy_J(VPTypes &pos_typ, TVctr_r2d &Rxy_0, TVctr_r &Ixy_0, + TVctr_r &coef, TVctr_r &Ixy, TVctr_r &dIxy, TVctr_r &J) + { + KS Ixy_p; + + KS J0; + KS J1; + + KS J2; + KS J3; + + // set zero Ixy + this->fill_vector(Ixy, 0); + + for(auto ipt = 0; ipt < n_pos_typ; ipt++) + { + const dt_int32 idx_nl = n_coef_nl_pa*ipt; + const dt_int32 idx_l = n_coef_nl + idx_nl; + + const T alpha = coef[idx_nl + 0]; + const T sigma1 = coef[idx_nl + 1]; + + const T a1 = coef[idx_l + 0]; + const T a2 = coef[idx_l + 1]; + + const T sigma1_2 = sigma1*sigma1; + const T sigma1_3 = sigma1_2*sigma1; + const T f_sigma1 = 1.0/(2*sigma1_2); + + const auto &p = pos_typ[ipt].p; + const dt_int32 np = p.size(); + + for(auto ixy = 0; ixy < nxy; ixy++) + { + Ixy_p = 0; + J0 = J1 = J2 = J3 = 0; + + const auto Rxy = Rxy_0[ixy]; + for(auto ip = 0; ip < np; ip++) + { + const T r2 = norm_2(Rxy-p[ip]); + const T ln_r2 = (r2>r2_min)?log(r2):0; + + const T ep_1 = exp(a1-f_sigma1*r2); + const T ep_2 = (r2>r2_min)?exp(a2+ln_r2*alpha-f_sigma1*r2):0; + + Ixy_p += ep_1 + ep_2; + + J0 += ln_r2*ep_2; + J1 += ep_1*r2; + J2 += ep_1; + J3 += ep_2; + } + + // assign values + Ixy[ixy] += Ixy_p; + + J[(idx_nl + 0)*nxy + ixy] = J0; + J[(idx_nl + 1)*nxy + ixy] = J1/sigma1_3; + J[(idx_l + 0)*nxy + ixy] = J2; + J[(idx_l + 1)*nxy + ixy] = J3; + } + } + + T ee = this->cal_dIxy_ee(Ixy_0, Ixy, dIxy); + + return ee; + } + }; + +} +#endif \ No newline at end of file diff --git a/src - Copy (2)/fcns_elem.cuh b/src - Copy (2)/fcns_elem.cuh new file mode 100755 index 00000000..bb1dd60d --- /dev/null +++ b/src - Copy (2)/fcns_elem.cuh @@ -0,0 +1,912 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef FCNS_ELEM_H + #define FCNS_ELEM_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + + /***************************************************************************************/ + /********************************* base class definitions ******************************/ + /***************************************************************************************/ + namespace mt + { + template class Fcn_Elem; + } + + /***************************************************************************************/ + /********************************** forward definitions ********************************/ + /***************************************************************************************/ + namespace mt + { + template + using Fcn_Cos_Tap = Fcn_Elem; + + template + using Fcn_Gauss = Fcn_Elem; + + template + using Fcn_Exp = Fcn_Elem; + + template + using Fcn_Fermi = Fcn_Elem; + + template + using Fcn_Butwth = Fcn_Elem; + + template + using Fcn_Hann = Fcn_Elem; + } + + /***************************************************************************************/ + /******************************** cosine tapering function *****************************/ + /***************************************************************************************/ + namespace mt + { + template + class Fcn_Elem + { + public: + using value_type = T; + + T r_tap; + T r_max; + T coef_tap; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(): r_tap(0), r_max(0), coef_tap(0){} + + Fcn_Elem(const T& r_tap, const T& r_max) + { + set_in_data(r_tap, r_max); + } + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /* converting constructor */ + template + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + r_tap = parm.r_tap; + r_max = parm.r_max; + coef_tap = parm.coef_tap; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + r_tap = T(parm.r_tap); + r_max = T(parm.r_max); + coef_tap = T(parm.coef_tap); + + return *this; + } + + template + CGPU_EXEC + void assign(const Fcn_Elem& parm) + { + *this = parm; + } + + /***************************************************************************************/ + void set_in_data(const T& r_tap, const T& r_max) + { + this->r_tap = r_tap; + this->r_max = r_max; + + coef_tap = fcn_coef_tap(r_tap, r_max); + } + + CGPU_EXEC + void clear() + { + r_tap = T(0); + r_max = T(0); + coef_tap = T(0); + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& r_tap, const T& r_max) const + { + const T coef_tap = fcn_coef_tap(r_tap, r_max); + return fcn_cos_tap(r_tap, coef_tap, r); + } + + CGPU_EXEC + T eval_r(const T& r) const + { + return fcn_cos_tap(r_tap, coef_tap, r); + } + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const + { + return {eval_r(r.x), eval_r(r.y)}; + } + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const + { + return {eval_r(r.x), eval_r(r.y), eval_r(r.z)}; + } + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r, const T& r_tap, const T& r_max) const + { + return eval_r(r, r_tap, r_max); + } + + CGPU_EXEC + T operator()(const T& r) const + { + return eval_r(r); + } + + CGPU_EXEC + R_2d operator()(const R_2d& r) const + { + return eval_r(r); + } + + CGPU_EXEC + R_3d operator()(const R_3d& r) const + { + return eval_r(r); + } + }; + } + + /***************************************************************************************/ + /********************************** gaussian function **********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(): a_1(0), b_1(0) {} + + Fcn_Elem(const T& sigma) + { + set_in_data(T(1), sigma); + } + + Fcn_Elem(const T& a, const T& sigma) + { + set_in_data(a, sigma); + } + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + a_1 = T(parm.a_1); + b_1 = T(parm.b_1); + + return *this; + } + + template + CGPU_EXEC + void assign(const Fcn_Elem& parm) + { + *this = parm; + } + + /***************************************************************************************/ + void set_in_data(const T& a, const T& sigma) + { + a_1 = a; + b_1 = T(1)/(T(2)*sigma*sigma); + } + + CGPU_EXEC + void clear() + { + a_1 = T(0); + b_1 = T(0); + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& sigma) const + { + return a_1*exp(-r2/(T(2)*sigma*sigma)); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return a_1*exp(-b_1*r2); + } + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y)}; + } + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y), eval_r2(r2.z)}; + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& sigma) const + { + return eval_r2(::square(r), sigma); + } + + CGPU_EXEC + T eval_r(const T& r) const + { + return eval_r2(::square(r)); + } + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const + { + return eval_r2(square(r)); + } + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const + { + return eval_r2(square(r)); + } + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r2, const T& sigma) const + { + return eval_r2(r2, sigma); + } + + CGPU_EXEC + T operator()(const T& r2) const + { + return eval_r2(r2); + } + + CGPU_EXEC + R_2d operator()(const R_2d& r2) const + { + return eval_r2(r2); + } + + CGPU_EXEC + R_3d operator()(const R_3d& r2) const + { + return eval_r2(r2); + } + }; + } + + /***************************************************************************************/ + /********************************* exponential function ********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(): a_1(0), b_1(0) {} + + Fcn_Elem(const T& a, const T& beta) + { + set_in_data(a, beta); + } + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + } + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const T& a, const T& beta) + { + a_1 = a; + b_1 = T(1)/(beta); + } + + CGPU_EXEC + void clear() + { + a_1 = T(0); + b_1 = T(0); + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& beta) const + { + return a_1*exp(-r/beta); + } + + CGPU_EXEC + T eval_r(const T& r) const + { + return a_1*exp(-b_1*r); + } + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const + { + return {eval_r(r.x), eval_r(r.y)}; + } + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const + { + return {eval_r(r.x), eval_r(r.y), eval_r(r.z)}; + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& beta) const + { + return eval_r(::sqrt(r2), beta); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return eval_r(::sqrt(r2)); + } + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const + { + return eval_r(::sqrt(r2)); + } + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const + { + return eval_r(::sqrt(r2)); + } + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r, const T& beta) const + { + return eval_r(r, beta); + } + + CGPU_EXEC + T operator()(const T& r) const + { + return eval_r(r); + } + + CGPU_EXEC + R_2d operator()(const R_2d& r) const + { + return eval_r(r); + } + + CGPU_EXEC + R_3d operator()(const R_3d& r) const + { + return eval_r(r); + } + }; + } + + /***************************************************************************************/ + /************************************ fermi function ***********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + T b_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(): a_1(0), b_1(0), b_2(0) {} + + Fcn_Elem(const T& a, const T& alpha, const T& radius) + { + set_in_data(a, alpha, radius); + } + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + b_2 = parm.b_2; + } + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const T& a, const T& alpha, const T& radius) + { + a_1 = a; + b_1 = alpha; + b_2 = ::square(radius); + } + + CGPU_EXEC + void clear() + { + a_1 = T(0); + b_1 = T(0); + b_2 = T(0); + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& radius) const + { + return a_1/(T(1) + exp(b_1*(r2-::square(radius)))); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return a_1/(T(1) + exp(b_1*(r2-b_2))); + } + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y)}; + } + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y), eval_r2(r2.z)}; + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& radius) const + { + return eval_r2(::square(r), radius); + } + + CGPU_EXEC + T eval_r(const T& r) const + { + return eval_r2(::square(r)); + } + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const + { + return eval_r2(square(r)); + } + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const + { + return eval_r2(square(r)); + } + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r2, const T& radius) const + { + return eval_r2(r2, radius); + } + + CGPU_EXEC + T operator()(const T& r2) const + { + return eval_r2(r2); + } + + CGPU_EXEC + R_2d operator()(const R_2d& r2) const + { + return eval_r2(r2); + } + + CGPU_EXEC + R_3d operator()(const R_3d& r2) const + { + return eval_r2(r2); + } + }; + } + + /***************************************************************************************/ + /********************************** butterworth function *******************************/ + /***************************************************************************************/ + namespace mt + { + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + dt_int32 b_1; + T b_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(): a_1(0), b_1(0), b_2(0) {} + + Fcn_Elem(const T& a, const dt_int32& n, const T& radius) + { + set_in_data(a, n, radius); + } + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + b_2 = parm.b_2; + } + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const T& a, const dt_int32& n, const T& radius) + { + a_1 = a; + b_1 = n; + b_2 = ::square(radius); + } + + CGPU_EXEC + void clear() + { + a_1 = T(0); + b_1 = dt_int32(0); + b_2 = T(0); + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const dt_int32& n, const T& radius) const + { + return a_1/(T(1)+pow(r2/::square(radius), n)); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return a_1/(T(1)+pow(r2/b_2, b_1)); + } + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y)}; + } + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y), eval_r2(r2.z)}; + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const dt_int32& n, const T& radius) const + { + return eval_r2(::square(r), n, radius); + } + + CGPU_EXEC + T eval_r(const T& r) const + { + return eval_r2(::square(r)); + } + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const + { + return eval_r2(square(r)); + } + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const + { + return eval_r2(square(r)); + } + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r2, const dt_int32& n, const T& radius) const + { + return eval_r2(r2, n, radius); + } + + CGPU_EXEC + T operator()(const T& r2) const + { + return eval_r2(r2); + } + + CGPU_EXEC + R_2d operator()(const R_2d& r2) const + { + return eval_r2(r2); + } + + CGPU_EXEC + R_3d operator()(const R_3d& r2) const + { + return eval_r2(r2); + } + }; + } + + /***************************************************************************************/ + /************************************ hann function ************************************/ + /***************************************************************************************/ + namespace mt + { + // https:// en.wikipedia.org/wiki/Hann_function + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(): a_1(0), b_1(0) {} + + Fcn_Elem(const T& a, const T& l) + { + set_in_data(a, l); + } + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + } + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const T& a, const T& l) + { + a_1 = a; + b_1 = c_pi/l; + } + + CGPU_EXEC + void clear() + { + a_1 = T(0); + b_1 = T(0); + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& l) const + { + return a_1*::square(cos(c_pi*r/l)); // r<=l/2, otherwise 0 + } + + CGPU_EXEC + T eval_r(const T& r) const + { + return a_1*::square(cos(b_1*r)); // r<=l/2, otherwise 0 + } + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const + { + return {eval_r(r.x), eval_r(r.y)}; + } + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const + { + return {eval_r(r.x), eval_r(r.y), eval_r(r.z)}; + } + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& l) const + { + return eval_r(::sqrt(r2), l); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return eval_r(::sqrt(r2)); + } + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const + { + return eval_r(::sqrt(r2)); + } + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const + { + return eval_r(::sqrt(r2)); + } + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r, const T& l) const + { + return eval_r(r, l); + } + + CGPU_EXEC + T operator()(const T& r) const + { + return eval_r(r); + } + + CGPU_EXEC + R_2d operator()(const R_2d& r) const + { + return eval_r(r); + } + + CGPU_EXEC + R_3d operator()(const R_3d& r) const + { + return eval_r(r); + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/fcns_wd.cuh b/src - Copy (2)/fcns_wd.cuh new file mode 100755 index 00000000..5a4f3c67 --- /dev/null +++ b/src - Copy (2)/fcns_wd.cuh @@ -0,0 +1,422 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details.Gauss_wd_ + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef FCNS_WD_H + #define FCNS_WD_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "cgpu_fcns_gen.cuh" + #include "cgpu_stream.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "fcns_elem.cuh" + #include "cgpu_detail.cuh" + + /***************************************************************************************/ + /********************************** base class fcn window ******************************/ + /***************************************************************************************/ + namespace mt + { + template + class Wdb_fcn_xd: public Fcn_Elem + { + public: + using value_type = T; + + R_xd r; + T r_wd_2; + T r_max_2; + T sft; + T sc; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wdb_fcn_xd(): Fcn_Elem(), r(), r_wd_2(0), r_max_2(0), sft(0), sc(1) {} + + /* copy constructor */ + CGPU_EXEC + Wdb_fcn_xd(const Wdb_fcn_xd& wd) + { + *this = wd; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wdb_fcn_xd& operator=(const Wdb_fcn_xd& wd) + { + if (this != &wd) + { + Fcn_Elem::operator=(wd); + + r = wd.r; + r_wd_2 = wd.r_wd_2; + r_max_2 = wd.r_max_2; + sft = wd.sft; + sc = wd.sc; + } + + return *this; + } + + CGPU_EXEC + void assign(const Wdb_fcn_xd& wd) + { + *this = wd; + } + + /***************************************************************************************/ + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + + r = T(0); + r_wd_2 = T(0); + r_max_2 = T(0); + sft = T(0); + sc = T(1); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return (r2::eval_r2(r2) - sft)/sc):T(0); + } + + CGPU_EXEC + T eval_r2(const R_2d& r2) const + { + return eval_r2(r2.x)*eval_r2(r2.y); + } + + CGPU_EXEC + T eval_r2(const R_3d& r2) const + { + return eval_r2(r2.x)*eval_r2(r2.y)*eval_r2(r2.z); + } + + void set_in_data(const R_xd& r, const T& r_wd, const T& r_max) + { + this->r = r; + r_wd_2 = ::square(r_wd); + r_max_2 = ::square(r_max); + sft = Fcn_Elem::eval_r2(r_max_2); + sc = Fcn_Elem::eval_r2(r_wd_2) - sft; + } + }; + } + + /***************************************************************************************/ + /********************************** forward definitions ********************************/ + /***************************************************************************************/ + namespace mt + { + template class Wd_fcn_xd; + + /* Gauss */ + template + using Wd_Gauss_xd = Wd_fcn_xd; + + template + using Wd_Gauss_1d = Wd_fcn_xd; + + template + using Wd_Gauss_2d = Wd_fcn_xd; + + template + using Wd_Gauss_3d = Wd_fcn_xd; + + /* Exp */ + template + using Wd_Exp_xd = Wd_fcn_xd; + + template + using Wd_Exp_1d = Wd_fcn_xd; + + template + using Wd_Exp_2d = Wd_fcn_xd; + + template + using Wd_Exp_3d = Wd_fcn_xd; + + /* Fermi */ + template + using Wd_Fermi_xd = Wd_fcn_xd; + + template + using Wd_Fermi_1d = Wd_fcn_xd; + + template + using Wd_Fermi_2d = Wd_fcn_xd; + + template + using Wd_Fermi_3d = Wd_fcn_xd; + + /* Butwth */ + template + using Wd_Butwth_xd = Wd_fcn_xd; + + template + using Wd_Butwth_1d = Wd_fcn_xd; + + template + using Wd_Butwth_2d = Wd_fcn_xd; + + template + using Wd_Butwth_3d = Wd_fcn_xd; + + /* Hann */ + template + using Wd_Hann_xd = Wd_fcn_xd; + + template + using Wd_Hann_1d = Wd_fcn_xd; + + template + using Wd_Hann_2d = Wd_fcn_xd; + + template + using Wd_Hann_3d = Wd_fcn_xd; + } + + /***************************************************************************************/ + /********************************** gaussian window ************************************/ + /***************************************************************************************/ + namespace mt + { + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(): Wdb_fcn_xd() {} + + Wd_fcn_xd(const R_xd& r, const T& sigma, const T& r_wd, const T& r_max) + { + set_in_data(r, sigma, r_wd, r_max); + } + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wdb_fcn_xd& operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& sigma, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), sigma); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } + + }; + } + + /***************************************************************************************/ + /********************************* exponential window **********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(): Wdb_fcn_xd() {} + + Wd_fcn_xd(const R_xd& r, const T& beta, const T& r_wd, const T& r_max) + { + set_in_data(r, beta, r_wd, r_max); + } + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wdb_fcn_xd& operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& beta, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), beta); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } + + }; + } + + /***************************************************************************************/ + /************************************ fermi window *************************************/ + /***************************************************************************************/ + namespace mt + { + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(): Wdb_fcn_xd() {} + + Wd_fcn_xd(const R_xd& r, const T& alpha, const T& r_wd, const T& r_max) + { + set_in_data(r, alpha, r_wd, r_max); + } + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wdb_fcn_xd& operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& alpha, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), alpha, r_wd); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } + + }; + } + + /***************************************************************************************/ + /********************************* butterworth window **********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(): Wdb_fcn_xd() {} + + Wd_fcn_xd(const R_xd& r, const dt_int32& n, const T& r_wd, const T& r_max) + { + set_in_data(r, n, r_wd, r_max); + } + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wdb_fcn_xd& operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const dt_int32& n, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), n, r_wd); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } + + }; + } + + /***************************************************************************************/ + /************************************* hann window *************************************/ + /***************************************************************************************/ + namespace mt + { + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(): Wdb_fcn_xd() {} + + Wd_fcn_xd(const R_xd& r, const T& l, const T& r_wd, const T& r_max) + { + set_in_data(r, l, r_wd, r_max); + } + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wdb_fcn_xd& operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& l, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), l); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } + + }; + } + +#endif \ No newline at end of file diff --git a/src/fft.cuh b/src - Copy (2)/fft.cuh old mode 100644 new mode 100755 similarity index 99% rename from src/fft.cuh rename to src - Copy (2)/fft.cuh index 98a56a9b..dafba7f6 --- a/src/fft.cuh +++ b/src - Copy (2)/fft.cuh @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src - Copy (2)/fftw3.h b/src - Copy (2)/fftw3.h new file mode 100755 index 00000000..aa0a2dcb --- /dev/null +++ b/src - Copy (2)/fftw3.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2003, 2007-14 Matteo Frigo + * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology + * + * The following statement of license applies *only* to this header file, + * and *not* to the other files distributed with FFTW or derived therefrom: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************** NOTE TO USERS ********************************* + * + * THIS IS A HEADER FILE, NOT A MANUAL + * + * If you want to know how to use FFTW, please read the manual, + * online at http:// www.fftw.org/doc/ and also included with FFTW. + * For a quick start, see the manual's tutorial section. + * + * (Reading header files to learn how to use a library is a habit + * stemming from code lacking a proper manual. Arguably, it's a + * *bad* habit in most cases, because header files can contain + * interfaces that are not part of the public, stable API.) + * + ****************************************************************************/ + +#ifndef FFTW3_H +#define FFTW3_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* If is included, use the C99 complex type. Otherwise + define a type bit-compatible with C99 complex */ +#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C +#else +# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] +#endif + +#define FFTW_CONCAT(prefix, name) prefix ## name +#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) +#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) +#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) +#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) + +/* IMPORTANT: for Windows compilers, you should add a line +*/ +#define FFTW_DLL +/* + here and in kernel/ifftw.h if you are compiling/using FFTW as a + DLL, in order to do the proper importing/exporting, or + alternatively compile with -DFFTW_DLL or the equivalent + command-line flag. This is not necessary under MinGW/Cygwin, where + libtool does the imports/exports automatically. */ +#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) + /* annoying Windows syntax for shared-library declarations */ +# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ +# define FFTW_EXTERN extern __declspec(dllexport) +# else /* user is calling FFTW; import symbol */ +# define FFTW_EXTERN extern __declspec(dllimport) +# endif +#else +# define FFTW_EXTERN extern +#endif + +enum fftw_r2r_kind_do_not_use_me { + FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, + FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, + FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 +}; + +struct fftw_iodim_do_not_use_me { + int n; /* dimension size */ + int is; /* input stride */ + int os; /* output stride */ +}; + +#include /* for ptrdiff_t */ +struct fftw_iodim64_do_not_use_me { + ptrdiff_t n; /* dimension size */ + ptrdiff_t is; /* input stride */ + ptrdiff_t os; /* output stride */ +}; + +typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *); +typedef int (*fftw_read_char_func_do_not_use_me)(void *); + +/* + huge second-order macro that defines prototypes for all API + functions. We expand this macro for each supported precision + + X: name-mangling macro + R: real data type + C: complex data type +*/ + +#define FFTW_DEFINE_API(X, R, C) \ + \ +FFTW_DEFINE_COMPLEX(R, C); \ + \ +typedef struct X(plan_s) *X(plan); \ + \ +typedef struct fftw_iodim_do_not_use_me X(iodim); \ +typedef struct fftw_iodim64_do_not_use_me X(iodim64); \ + \ +typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ + \ +typedef fftw_write_char_func_do_not_use_me X(write_char_func); \ +typedef fftw_read_char_func_do_not_use_me X(read_char_func); \ + \ +FFTW_EXTERN void X(execute)(const X(plan) p); \ + \ +FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \ + C *in, C *out, int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \ +FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ + R *ro, R *io); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n, R *in, C *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \ + R *in, C *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \ + int n2, \ + R *in, C *out, unsigned flags); \ + \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n, C *in, R *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \ + C *in, R *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \ + int n2, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ +FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ + \ +FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \ + R *in, R *ro, R *io); \ +FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \ + R *ri, R *ii, R *out); \ + \ +FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \ + X(r2r_kind) kind, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ + X(r2r_kind) kind0, X(r2r_kind) kind1, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \ + R *in, R *out, X(r2r_kind) kind0, \ + X(r2r_kind) kind1, X(r2r_kind) kind2, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \ + \ +FFTW_EXTERN void X(destroy_plan)(X(plan) p); \ +FFTW_EXTERN void X(forget_wisdom)(void); \ +FFTW_EXTERN void X(cleanup)(void); \ + \ +FFTW_EXTERN void X(set_timelimit)(double t); \ + \ +FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \ +FFTW_EXTERN int X(init_threads)(void); \ +FFTW_EXTERN void X(cleanup_threads)(void); \ +FFTW_EXTERN void X(make_planner_thread_safe)(void); \ + \ +FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \ +FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \ +FFTW_EXTERN char *X(export_wisdom_to_string)(void); \ +FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \ + void *data); \ +FFTW_EXTERN int X(import_system_wisdom)(void); \ +FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \ +FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \ +FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \ +FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \ + \ +FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \ +FFTW_EXTERN void X(print_plan)(const X(plan) p); \ +FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \ + \ +FFTW_EXTERN void *X(malloc)(size_t n); \ +FFTW_EXTERN R *X(alloc_real)(size_t n); \ +FFTW_EXTERN C *X(alloc_complex)(size_t n); \ +FFTW_EXTERN void X(free)(void *p); \ + \ +FFTW_EXTERN void X(flops)(const X(plan) p, \ + double *add, double *mul, double *fmas); \ +FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \ +FFTW_EXTERN double X(cost)(const X(plan) p); \ + \ +FFTW_EXTERN int X(alignment_of)(R *p); \ +FFTW_EXTERN const char X(version)[]; \ +FFTW_EXTERN const char X(cc)[]; \ +FFTW_EXTERN const char X(codelet_optim)[]; + + +/* end of FFTW_DEFINE_API macro */ + +FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) +FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) +FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) + +/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64 + for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */ +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \ + && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \ + && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__)) +# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +/* note: __float128 is a typedef, which is not supported with the _Complex + keyword in gcc, so instead we use this ugly __attribute__ version. + However, we can't simply pass the __attribute__ version to + FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer + types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */ +# undef FFTW_DEFINE_COMPLEX +# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C +# endif +FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex) +#endif + +#define FFTW_FORWARD (-1) +#define FFTW_BACKWARD (+1) + +#define FFTW_NO_TIMELIMIT (-1.0) + +/* documented flags */ +#define FFTW_MEASURE (0U) +#define FFTW_DESTROY_INPUT (1U << 0) +#define FFTW_UNALIGNED (1U << 1) +#define FFTW_CONSERVE_MEMORY (1U << 2) +#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ +#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ +#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ +#define FFTW_ESTIMATE (1U << 6) +#define FFTW_WISDOM_ONLY (1U << 21) + +/* undocumented beyond-guru flags */ +#define FFTW_ESTIMATE_PATIENT (1U << 7) +#define FFTW_BELIEVE_PCOST (1U << 8) +#define FFTW_NO_DFT_R2HC (1U << 9) +#define FFTW_NO_NONTHREADED (1U << 10) +#define FFTW_NO_BUFFERING (1U << 11) +#define FFTW_NO_INDIRECT_OP (1U << 12) +#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ +#define FFTW_NO_RANK_SPLITS (1U << 14) +#define FFTW_NO_VRANK_SPLITS (1U << 15) +#define FFTW_NO_VRECURSE (1U << 16) +#define FFTW_NO_SIMD (1U << 17) +#define FFTW_NO_SLOW (1U << 18) +#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) +#define FFTW_ALLOW_PRUNING (1U << 20) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* FFTW3_H */ diff --git a/src - Copy (2)/fxeg_data.hpp b/src - Copy (2)/fxeg_data.hpp new file mode 100755 index 00000000..89af222c --- /dev/null +++ b/src - Copy (2)/fxeg_data.hpp @@ -0,0 +1,816 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef FXEG_DATA_H + #define FXEG_DATA_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "cgpu_vctr.cuh" + + namespace mt + { + template + class fxeg_Data + { + public: + + fxeg_Data(const dt_int32& typ, const dt_int32& Z, dt_int32 dng, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + operator()(typ, Z, dng, g, fxg, feg); + } + + void operator()(const dt_int32& typ, const dt_int32& Z, dt_int32 dng, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + switch(typ) + { + case 1: + { + load_fxeg_kirkland(Z, g, fxg, feg); + } + break; + case 2: + { + load_fxeg_lobato(Z, g, fxg, feg); + } + break; + } + + dng = max(1, dng); + + if (dng==1) + { + return; + } + + dt_int32 ig = 0; + dt_int32 ik = 0; + + while (ig < g.size()) + { + g[ik] = g[ig]; + fxg[ik] = fxg[ig]; + feg[ik] = feg[ig]; + + ig += dng; + ik++; + } + + g.resize(ik); + fxg.resize(ik); + feg.resize(ik); + } + + private: + void load_fxeg_kirkland(const dt_int32& Z, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + switch(Z) + { + case 1: + { + g = Vctr_cpu({0.0000000000000000e+00, 5.0000000000000003e-02, 1.0000000000000001e-01, 1.5000000000000002e-01, 2.0000000000000001e-01, 2.5000000000000000e-01, 3.0000000000000004e-01, 3.5000000000000003e-01, 4.0000000000000002e-01, 4.5000000000000001e-01, 5.0000000000000000e-01, 5.5000000000000004e-01, 6.0000000000000009e-01, 6.5000000000000002e-01, 7.0000000000000007e-01, 7.5000000000000000e-01, 8.0000000000000004e-01, 8.5000000000000009e-01, 9.0000000000000002e-01, 9.5000000000000007e-01, 1.0000000000000000e+00, 1.0500000000000000e+00, 1.1000000000000001e+00, 1.1500000000000001e+00, 1.2000000000000002e+00, 1.2500000000000000e+00, 1.3000000000000000e+00, 1.3500000000000001e+00, 1.4000000000000001e+00, 1.4500000000000002e+00, 1.5000000000000000e+00, 1.5500000000000000e+00, 1.6000000000000001e+00, 1.6500000000000001e+00, 1.7000000000000002e+00, 1.7500000000000000e+00, 1.7999999999999998e+00, 1.8499999999999999e+00, 1.8999999999999999e+00, 1.9500000000000000e+00, 2.0000000000000000e+00, 2.0499999999999998e+00, 2.0999999999999996e+00, 2.1499999999999999e+00, 2.2000000000000002e+00, 2.2500000000000000e+00, 2.2999999999999998e+00, 2.3499999999999996e+00, 2.3999999999999999e+00, 2.4500000000000002e+00, 2.5000000000000000e+00, 2.5499999999999998e+00, 2.6000000000000001e+00, 2.6499999999999999e+00, 2.7000000000000002e+00, 2.7500000000000000e+00, 2.7999999999999998e+00, 2.8500000000000001e+00, 2.8999999999999999e+00, 2.9500000000000002e+00, 3.0000000000000000e+00, 3.0499999999999998e+00, 3.1000000000000001e+00, 3.1499999999999999e+00, 3.2000000000000002e+00, 3.2500000000000000e+00, 3.2999999999999998e+00, 3.3500000000000001e+00, 3.3999999999999999e+00, 3.4500000000000002e+00, 3.5000000000000000e+00}); + fxg = Vctr_cpu({1.0000000000000000e+00, 9.8632305882146931e-01, 9.4693449431522780e-01, 8.8633888266404548e-01, 8.1081751005624991e-01, 7.2710935171612368e-01, 6.4129284612105375e-01, 5.5811420076772189e-01, 4.8078069526412032e-01, 4.1109116523666106e-01, 3.4973752174225664e-01, 2.9664389797585239e-01, 2.5126541911343342e-01, 2.1281605988549140e-01, 1.8042458218770130e-01, 1.5323114063569815e-01, 1.3044056400490822e-01, 1.1134671897585470e-01, 9.5339049733758591e-02, 8.1899049191269432e-02, 7.0591706678070243e-02, 6.1055010645627322e-02, 5.2989260870033097e-02, 4.6147102560467279e-02, 4.0324686038064640e-02, 3.5354064709704515e-02, 3.1096789143846087e-02, 2.7438581628507139e-02, 2.4284948842277231e-02, 2.1557588759807365e-02, 1.9191458882981287e-02, 1.7132389020261554e-02, 1.5335139128426002e-02, 1.3761819146890376e-02, 1.2380602387067150e-02, 1.1164676602016449e-02, 1.0091387392769066e-02, 9.1415372965883562e-03, 8.2988109947624063e-03, 7.5493028247337795e-03, 6.8811274161826828e-03, 6.2840979969970810e-03, 5.7494599057461293e-03, 5.2696692457298404e-03, 4.8382085391719138e-03, 4.4494327835947738e-03, 4.0984405522127504e-03, 3.7809657774127946e-03, 3.4932866598361241e-03, 3.2321487940852357e-03, 2.9947001265890577e-03, 2.7784357862813153e-03, 2.5811511740829116e-03, 2.4009019783462399e-03, 2.2359700128773063e-03, 2.0848339618541214e-03, 1.9461442698720168e-03, 1.8187015418536596e-03, 1.7014379217915681e-03, 1.5934010053713723e-03, 1.4937399127832802e-03, 1.4016932071572960e-03, 1.3165783932337139e-03, 1.2377827718729815e-03, 1.1647554602571618e-03, 1.0970004163124516e-03, 1.0340703299472009e-03, 9.7556126393818577e-04, 9.2110794435402944e-04, 8.7037961480902445e-04, 8.2307638103044142e-04}); + feg = Vctr_cpu({5.2917721077817892e-01, 5.2374283721610537e-01, 5.0802072888340088e-01, 4.8361362625383103e-01, 4.5278295755871933e-01, 4.1800142448896865e-01, 3.8156335147101500e-01, 3.4533697651742540e-01, 3.1067047020286392e-01, 2.7841470405691926e-01, 2.4901058712784352e-01, 2.2259684610025274e-01, 1.9911066238571343e-01, 1.7836869626462978e-01, 1.6012604235474073e-01, 1.4411576034945436e-01, 1.3007337958444765e-01, 1.1775073410121434e-01, 1.0692270852136421e-01, 9.7389548551727517e-02, 8.8976571976619706e-02, 8.1532484512507719e-02, 7.4927054427602918e-02, 6.9048595422691400e-02, 6.3801510013041379e-02, 5.9104022452155423e-02, 5.4886156119332841e-02, 5.1087967646298020e-02, 4.7658027013818209e-02, 4.4552121661498537e-02, 4.1732158397521382e-02, 3.9165236509655137e-02, 3.6822867106561567e-02, 3.4680316261132417e-02, 3.2716052358321902e-02, 3.0911280828591629e-02, 2.9249552005489250e-02, 2.7716430112046362e-02, 2.6299213340960925e-02, 2.4986696662356037e-02, 2.3768970398348299e-02, 2.2637248778637105e-02, 2.1583723668818808e-02, 2.0601439473761522e-02, 1.9684185889370136e-02, 1.8826405730974674e-02, 1.8023115525393936e-02, 1.7269836933243830e-02, 1.6562537382241456e-02, 1.5897578552651559e-02, 1.5271671572146013e-02, 1.4681837957018844e-02, 1.4125375486332256e-02, 1.3599828320422766e-02, 1.3102960779581179e-02, 1.2632734286171021e-02, 1.2187287046867289e-02, 1.1764916113465184e-02, 1.1364061512785639e-02, 1.0983292180206397e-02, 1.0621293468605932e-02, 1.0276856036123242e-02, 9.9488659430214364e-03, 9.6362958108527057e-03, 9.3381969166852260e-03, 9.0536921118920307e-03, 8.7819694693541655e-03, 8.5222765752608377e-03, 8.2739153923030301e-03, 8.0362376302109979e-03, 7.8086405674960340e-03}); + } + break; + case 2: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00}); + fxg = Vctr_cpu({2.0000e+00, 1.9891e+00, 1.9571e+00, 1.9056e+00, 1.8372e+00, 1.7550e+00, 1.6626e+00, 1.5633e+00, 1.4603e+00, 1.3565e+00, 1.2541e+00, 1.1548e+00, 1.0601e+00, 9.7070e-01, 8.8710e-01, 8.0960e-01, 7.3820e-01, 6.7270e-01, 6.1290e-01, 5.5830e-01, 5.0880e-01, 4.6380e-01, 4.2310e-01, 3.8620e-01, 3.5280e-01, 3.2260e-01, 2.9520e-01, 2.7040e-01, 2.4800e-01, 2.2760e-01, 2.0910e-01, 1.9240e-01, 1.7720e-01, 1.6330e-01, 1.5070e-01, 1.3930e-01, 1.2880e-01, 1.1920e-01, 1.1050e-01, 1.0250e-01, 9.5200e-02, 8.8500e-02, 8.2300e-02, 7.6700e-02, 7.1500e-02, 6.6700e-02, 6.2300e-02, 5.8300e-02, 5.4500e-02, 5.1100e-02, 4.7900e-02, 4.4900e-02, 4.2200e-02, 3.9600e-02, 3.7200e-02, 3.5100e-02, 3.3000e-02, 3.1100e-02, 2.9300e-02, 2.7700e-02, 2.6200e-02, 2.4700e-02, 2.3400e-02, 2.2100e-02, 2.1000e-02, 1.9900e-02, 1.8800e-02, 1.7900e-02, 1.7000e-02, 1.6100e-02, 1.5300e-02, 1.4600e-02, 1.3900e-02, 1.3200e-02, 1.2600e-02, 1.2000e-02, 1.1400e-02, 1.0900e-02, 1.0400e-02, 9.9000e-03}); + feg = Vctr_cpu({4.1800e-01, 4.1610e-01, 4.1060e-01, 4.0160e-01, 3.8960e-01, 3.7520e-01, 3.5890e-01, 3.4130e-01, 3.2290e-01, 3.0420e-01, 2.8570e-01, 2.6750e-01, 2.4990e-01, 2.3320e-01, 2.1740e-01, 2.0260e-01, 1.8870e-01, 1.7590e-01, 1.6390e-01, 1.5290e-01, 1.4280e-01, 1.3340e-01, 1.2480e-01, 1.1680e-01, 1.0950e-01, 1.0280e-01, 9.6600e-02, 9.0900e-02, 8.5600e-02, 8.0700e-02, 7.6200e-02, 7.2000e-02, 6.8200e-02, 6.4600e-02, 6.1300e-02, 5.8200e-02, 5.5300e-02, 5.2600e-02, 5.0100e-02, 4.7800e-02, 4.5600e-02, 4.3500e-02, 4.1600e-02, 3.9800e-02, 3.8100e-02, 3.6600e-02, 3.5100e-02, 3.3700e-02, 3.2300e-02, 3.1100e-02, 2.9900e-02, 2.8800e-02, 2.7700e-02, 2.6700e-02, 2.5800e-02, 2.4900e-02, 2.4000e-02, 2.3200e-02, 2.2400e-02, 2.1700e-02, 2.1000e-02, 2.0300e-02, 1.9700e-02, 1.9100e-02, 1.8500e-02, 1.7900e-02, 1.7400e-02, 1.6900e-02, 1.6400e-02, 1.6000e-02, 1.5500e-02, 1.5100e-02, 1.4700e-02, 1.4300e-02, 1.3900e-02, 1.3500e-02, 1.3200e-02, 1.2800e-02, 1.2500e-02, 1.2200e-02}); + } + break; + case 3: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00}); + fxg = Vctr_cpu({3.0000e+00, 2.9177e+00, 2.7075e+00, 2.4501e+00, 2.2151e+00, 2.0332e+00, 1.9037e+00, 1.8117e+00, 1.7416e+00, 1.6821e+00, 1.6261e+00, 1.5701e+00, 1.5127e+00, 1.4537e+00, 1.3932e+00, 1.3320e+00, 1.2705e+00, 1.2094e+00, 1.1491e+00, 1.0901e+00, 1.0327e+00, 9.7710e-01, 9.2370e-01, 8.7240e-01, 8.2340e-01, 7.7670e-01, 7.3230e-01, 6.9030e-01, 6.5050e-01, 6.1290e-01, 5.7740e-01, 5.4390e-01, 5.1240e-01, 4.8280e-01, 4.5500e-01, 4.2880e-01, 4.0430e-01, 3.8120e-01, 3.5960e-01, 3.3930e-01, 3.2030e-01, 3.0240e-01, 2.8560e-01, 2.6990e-01, 2.5510e-01, 2.4130e-01, 2.2830e-01, 2.1610e-01, 2.0460e-01, 1.9380e-01, 1.8370e-01, 1.7420e-01, 1.6520e-01, 1.5680e-01, 1.4890e-01, 1.4140e-01, 1.3430e-01, 1.2770e-01, 1.2150e-01, 1.1560e-01, 1.1000e-01, 1.0480e-01, 9.9800e-02, 9.5100e-02, 9.0700e-02, 8.6600e-02, 8.2600e-02, 7.8800e-02, 7.5300e-02, 7.2000e-02, 6.8800e-02, 6.5800e-02, 6.3000e-02, 6.0300e-02, 5.7700e-02, 5.5200e-02, 5.2900e-02, 5.0800e-02, 4.8700e-02, 4.6600e-02, 4.4700e-02, 4.3000e-02, 4.1300e-02, 3.9600e-02, 3.7900e-02, 3.6500e-02, 3.5200e-02, 3.4000e-02, 3.2600e-02, 3.1200e-02, 3.0000e-02, 2.9100e-02, 2.8100e-02, 2.7000e-02, 2.5800e-02, 2.4800e-02, 2.4100e-02, 2.3500e-02, 2.2700e-02, 2.1700e-02, 2.0700e-02, 2.0000e-02, 1.9500e-02, 1.9100e-02, 1.8500e-02, 1.7600e-02, 1.6700e-02, 1.6200e-02, 1.5900e-02, 1.5700e-02, 1.5300e-02, 1.4600e-02, 1.3700e-02, 1.3100e-02, 1.2900e-02, 1.2900e-02, 1.2800e-02, 1.2300e-02, 1.1600e-02, 1.0900e-02, 1.0400e-02, 1.0400e-02, 1.0500e-02, 1.0500e-02, 1.0100e-02, 9.4000e-03}); + feg = Vctr_cpu({3.2861e+00, 3.1524e+00, 2.8000e+00, 2.3396e+00, 1.8787e+00, 1.4809e+00, 1.1662e+00, 9.2870e-01, 7.5290e-01, 6.2310e-01, 5.2610e-01, 4.5250e-01, 3.9550e-01, 3.5040e-01, 3.1390e-01, 2.8390e-01, 2.5870e-01, 2.3730e-01, 2.1880e-01, 2.0260e-01, 1.8830e-01, 1.7570e-01, 1.6430e-01, 1.5400e-01, 1.4470e-01, 1.3620e-01, 1.2850e-01, 1.2130e-01, 1.1480e-01, 1.0870e-01, 1.0310e-01, 9.7900e-02, 9.3000e-02, 8.8500e-02, 8.4300e-02, 8.0400e-02, 7.6700e-02, 7.3300e-02, 7.0000e-02, 6.7000e-02, 6.4100e-02, 6.1500e-02, 5.8900e-02, 5.6500e-02, 5.4300e-02, 5.2200e-02, 5.0200e-02, 4.8300e-02, 4.6500e-02, 4.4800e-02, 4.3100e-02, 4.1600e-02, 4.0100e-02, 3.8800e-02, 3.7400e-02, 3.6200e-02, 3.5000e-02, 3.3900e-02, 3.2800e-02, 3.1700e-02, 3.0700e-02, 2.9800e-02, 2.8900e-02, 2.8000e-02, 2.7200e-02, 2.6400e-02, 2.5600e-02, 2.4900e-02, 2.4200e-02, 2.3600e-02, 2.2900e-02, 2.2300e-02, 2.1700e-02, 2.1100e-02, 2.0600e-02, 2.0000e-02, 1.9500e-02, 1.9000e-02, 1.8600e-02, 1.8100e-02, 1.7700e-02, 1.7300e-02, 1.6800e-02, 1.6500e-02, 1.6100e-02, 1.5700e-02, 1.5400e-02, 1.5000e-02, 1.4700e-02, 1.4400e-02, 1.4000e-02, 1.3700e-02, 1.3400e-02, 1.3200e-02, 1.2900e-02, 1.2600e-02, 1.2400e-02, 1.2100e-02, 1.1900e-02, 1.1600e-02, 1.1400e-02, 1.1200e-02, 1.1000e-02, 1.0800e-02, 1.0600e-02, 1.0400e-02, 1.0200e-02, 1.0000e-02, 9.8000e-03, 9.6000e-03, 9.4000e-03, 9.3000e-03, 9.1000e-03, 9.0000e-03, 8.8000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.4000e-03, 7.3000e-03}); + } + break; + case 4: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00}); + fxg = Vctr_cpu({4.0000e+00, 3.9219e+00, 3.7067e+00, 3.4022e+00, 3.0652e+00, 2.7426e+00, 2.4626e+00, 2.2356e+00, 2.0598e+00, 1.9272e+00, 1.8277e+00, 1.7520e+00, 1.6923e+00, 1.6429e+00, 1.5996e+00, 1.5594e+00, 1.5205e+00, 1.4818e+00, 1.4427e+00, 1.4029e+00, 1.3623e+00, 1.3211e+00, 1.2794e+00, 1.2374e+00, 1.1953e+00, 1.1534e+00, 1.1117e+00, 1.0705e+00, 1.0299e+00, 9.9010e-01, 9.5120e-01, 9.1330e-01, 8.7640e-01, 8.4050e-01, 8.0580e-01, 7.7230e-01, 7.3990e-01, 7.0870e-01, 6.7870e-01, 6.4990e-01, 6.2220e-01, 5.9560e-01, 5.7010e-01, 5.4570e-01, 5.2230e-01, 4.9990e-01, 4.7850e-01, 4.5810e-01, 4.3860e-01, 4.1990e-01, 4.0210e-01, 3.8510e-01, 3.6880e-01, 3.5330e-01, 3.3850e-01, 3.2440e-01, 3.1090e-01, 2.9810e-01, 2.8580e-01, 2.7410e-01, 2.6290e-01, 2.5220e-01, 2.4210e-01, 2.3240e-01, 2.2310e-01, 2.1420e-01, 2.0580e-01, 1.9770e-01, 1.9000e-01, 1.8260e-01, 1.7560e-01, 1.6880e-01, 1.6240e-01, 1.5620e-01, 1.5040e-01, 1.4470e-01, 1.3940e-01, 1.3420e-01, 1.2930e-01, 1.2460e-01, 1.2010e-01, 1.1570e-01, 1.1160e-01, 1.0760e-01, 1.0380e-01, 1.0020e-01, 9.6700e-02, 9.3300e-02, 9.0100e-02, 8.7000e-02, 8.4100e-02, 8.1200e-02, 7.8500e-02, 7.5800e-02, 7.3300e-02, 7.1000e-02, 6.8700e-02, 6.6400e-02, 6.4200e-02, 6.2100e-02, 6.0200e-02, 5.8400e-02, 5.6500e-02, 5.4700e-02, 5.2900e-02, 5.1300e-02, 4.9800e-02, 4.8400e-02, 4.6900e-02, 4.5300e-02, 4.3900e-02, 4.2600e-02, 4.1400e-02, 4.0400e-02, 3.9200e-02, 3.7900e-02, 3.6700e-02, 3.5600e-02, 3.4600e-02, 3.3800e-02, 3.3000e-02, 3.2100e-02, 3.1000e-02, 2.9900e-02, 2.9100e-02, 2.8400e-02, 2.7800e-02, 2.7300e-02, 2.6500e-02, 2.5600e-02, 2.4700e-02, 2.3900e-02, 2.3300e-02, 2.3000e-02, 2.2600e-02, 2.2200e-02, 2.1500e-02, 2.0600e-02, 1.9800e-02, 1.9200e-02, 1.8900e-02, 1.8800e-02, 1.8600e-02, 1.8200e-02, 1.7600e-02, 1.6800e-02, 1.6100e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5300e-02, 1.5200e-02, 1.4700e-02, 1.4100e-02, 1.3300e-02, 1.2700e-02, 1.2400e-02, 1.2400e-02, 1.2500e-02, 1.2600e-02, 1.2500e-02, 1.2100e-02, 1.1500e-02, 1.0700e-02, 1.0200e-02, 9.9000e-03}); + feg = Vctr_cpu({3.0539e+00, 2.9892e+00, 2.8078e+00, 2.5434e+00, 2.2372e+00, 1.9260e+00, 1.6354e+00, 1.3789e+00, 1.1609e+00, 9.8000e-01, 8.3190e-01, 7.1150e-01, 6.1370e-01, 5.3410e-01, 4.6900e-01, 4.1540e-01, 3.7090e-01, 3.3370e-01, 3.0230e-01, 2.7550e-01, 2.5250e-01, 2.3260e-01, 2.1520e-01, 2.0000e-01, 1.8650e-01, 1.7440e-01, 1.6360e-01, 1.5390e-01, 1.4510e-01, 1.3710e-01, 1.2970e-01, 1.2300e-01, 1.1680e-01, 1.1110e-01, 1.0580e-01, 1.0090e-01, 9.6300e-02, 9.2100e-02, 8.8100e-02, 8.4300e-02, 8.0800e-02, 7.7600e-02, 7.4500e-02, 7.1500e-02, 6.8800e-02, 6.6200e-02, 6.3700e-02, 6.1400e-02, 5.9200e-02, 5.7100e-02, 5.5100e-02, 5.3200e-02, 5.1400e-02, 4.9700e-02, 4.8100e-02, 4.6500e-02, 4.5000e-02, 4.3600e-02, 4.2300e-02, 4.1000e-02, 3.9800e-02, 3.8600e-02, 3.7400e-02, 3.6400e-02, 3.5300e-02, 3.4300e-02, 3.3400e-02, 3.2400e-02, 3.1600e-02, 3.0700e-02, 2.9900e-02, 2.9100e-02, 2.8300e-02, 2.7600e-02, 2.6900e-02, 2.6200e-02, 2.5600e-02, 2.5000e-02, 2.4400e-02, 2.3800e-02, 2.3200e-02, 2.2700e-02, 2.2100e-02, 2.1600e-02, 2.1100e-02, 2.0700e-02, 2.0200e-02, 1.9800e-02, 1.9300e-02, 1.8900e-02, 1.8500e-02, 1.8100e-02, 1.7700e-02, 1.7400e-02, 1.7000e-02, 1.6700e-02, 1.6300e-02, 1.6000e-02, 1.5700e-02, 1.5400e-02, 1.5100e-02, 1.4800e-02, 1.4500e-02, 1.4200e-02, 1.4000e-02, 1.3700e-02, 1.3500e-02, 1.3200e-02, 1.3000e-02, 1.2700e-02, 1.2500e-02, 1.2300e-02, 1.2100e-02, 1.1900e-02, 1.1700e-02, 1.1500e-02, 1.1300e-02, 1.1100e-02, 1.0900e-02, 1.0700e-02, 1.0500e-02, 1.0400e-02, 1.0200e-02, 1.0000e-02, 9.9000e-03, 9.7000e-03, 9.6000e-03, 9.4000e-03, 9.3000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.4000e-03, 6.4000e-03, 6.3000e-03, 6.2000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03}); + } + break; + case 5: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01}); + fxg = Vctr_cpu({5.0000e+00, 4.9281e+00, 4.7244e+00, 4.4211e+00, 4.0599e+00, 3.6809e+00, 3.3160e+00, 2.9853e+00, 2.6989e+00, 2.4589e+00, 2.2627e+00, 2.1048e+00, 1.9790e+00, 1.8789e+00, 1.7989e+00, 1.7342e+00, 1.6808e+00, 1.6354e+00, 1.5958e+00, 1.5599e+00, 1.5265e+00, 1.4946e+00, 1.4634e+00, 1.4325e+00, 1.4017e+00, 1.3706e+00, 1.3393e+00, 1.3077e+00, 1.2758e+00, 1.2438e+00, 1.2116e+00, 1.1793e+00, 1.1471e+00, 1.1151e+00, 1.0832e+00, 1.0517e+00, 1.0205e+00, 9.8970e-01, 9.5940e-01, 9.2960e-01, 9.0040e-01, 8.7170e-01, 8.4380e-01, 8.1650e-01, 7.8980e-01, 7.6390e-01, 7.3860e-01, 7.1410e-01, 6.9020e-01, 6.6710e-01, 6.4470e-01, 6.2290e-01, 6.0190e-01, 5.8150e-01, 5.6180e-01, 5.4270e-01, 5.2430e-01, 5.0650e-01, 4.8930e-01, 4.7270e-01, 4.5670e-01, 4.4120e-01, 4.2630e-01, 4.1200e-01, 3.9810e-01, 3.8470e-01, 3.7180e-01, 3.5940e-01, 3.4740e-01, 3.3580e-01, 3.2470e-01, 3.1400e-01, 3.0360e-01, 2.9370e-01, 2.8410e-01, 2.7480e-01, 2.6590e-01, 2.5730e-01, 2.4900e-01, 2.4100e-01, 2.3330e-01, 2.2590e-01, 2.1870e-01, 2.1180e-01, 2.0520e-01, 1.9880e-01, 1.9260e-01, 1.8660e-01, 1.8090e-01, 1.7530e-01, 1.7000e-01, 1.6480e-01, 1.5980e-01, 1.5500e-01, 1.5030e-01, 1.4590e-01, 1.4160e-01, 1.3740e-01, 1.3330e-01, 1.2940e-01, 1.2570e-01, 1.2210e-01, 1.1850e-01, 1.1510e-01, 1.1180e-01, 1.0860e-01, 1.0560e-01, 1.0270e-01, 9.9800e-02, 9.7000e-02, 9.4300e-02, 9.1700e-02, 8.9200e-02, 8.6800e-02, 8.4500e-02, 8.2200e-02, 7.9900e-02, 7.7700e-02, 7.5700e-02, 7.3800e-02, 7.1900e-02, 7.0000e-02, 6.8100e-02, 6.6300e-02, 6.4500e-02, 6.3000e-02, 6.1500e-02, 6.0000e-02, 5.8400e-02, 5.6900e-02, 5.5300e-02, 5.3900e-02, 5.2600e-02, 5.1500e-02, 5.0300e-02, 4.9100e-02, 4.7900e-02, 4.6600e-02, 4.5300e-02, 4.4200e-02, 4.3200e-02, 4.2400e-02, 4.1600e-02, 4.0600e-02, 3.9600e-02, 3.8500e-02, 3.7400e-02, 3.6500e-02, 3.5700e-02, 3.5100e-02, 3.4500e-02, 3.3900e-02, 3.3100e-02, 3.2100e-02, 3.1200e-02, 3.0300e-02, 2.9600e-02, 2.9100e-02, 2.8800e-02, 2.8400e-02, 2.7900e-02, 2.7200e-02, 2.6400e-02, 2.5500e-02, 2.4700e-02, 2.4200e-02, 2.3800e-02, 2.3600e-02, 2.3500e-02, 2.3200e-02, 2.2700e-02, 2.2000e-02, 2.1200e-02, 2.0500e-02, 1.9900e-02, 1.9500e-02, 1.9300e-02, 1.9300e-02, 1.9300e-02, 1.9100e-02, 1.8700e-02, 1.8100e-02, 1.7400e-02, 1.6600e-02, 1.6100e-02, 1.5700e-02, 1.5600e-02, 1.5700e-02, 1.5800e-02, 1.5900e-02, 1.5700e-02, 1.5300e-02, 1.4600e-02, 1.3900e-02, 1.3200e-02, 1.2700e-02, 1.2500e-02, 1.2600e-02, 1.2800e-02, 1.3000e-02, 1.3100e-02, 1.3100e-02, 1.2800e-02, 1.2200e-02, 1.1500e-02, 1.0700e-02, 1.0200e-02, 9.9000e-03}); + feg = Vctr_cpu({2.7950e+00, 2.7542e+00, 2.6382e+00, 2.4630e+00, 2.2501e+00, 2.0205e+00, 1.7913e+00, 1.5745e+00, 1.3769e+00, 1.2013e+00, 1.0482e+00, 9.1630e-01, 8.0340e-01, 7.0720e-01, 6.2540e-01, 5.5580e-01, 4.9650e-01, 4.4580e-01, 4.0230e-01, 3.6490e-01, 3.3250e-01, 3.0440e-01, 2.7980e-01, 2.5820e-01, 2.3920e-01, 2.2240e-01, 2.0740e-01, 1.9400e-01, 1.8190e-01, 1.7100e-01, 1.6120e-01, 1.5220e-01, 1.4410e-01, 1.3660e-01, 1.2970e-01, 1.2340e-01, 1.1760e-01, 1.1220e-01, 1.0720e-01, 1.0250e-01, 9.8100e-02, 9.4000e-02, 9.0200e-02, 8.6600e-02, 8.3300e-02, 8.0100e-02, 7.7100e-02, 7.4300e-02, 7.1600e-02, 6.9100e-02, 6.6700e-02, 6.4400e-02, 6.2300e-02, 6.0200e-02, 5.8300e-02, 5.6400e-02, 5.4700e-02, 5.3000e-02, 5.1300e-02, 4.9800e-02, 4.8300e-02, 4.6900e-02, 4.5600e-02, 4.4300e-02, 4.3000e-02, 4.1800e-02, 4.0700e-02, 3.9600e-02, 3.8500e-02, 3.7500e-02, 3.6500e-02, 3.5600e-02, 3.4700e-02, 3.3800e-02, 3.3000e-02, 3.2200e-02, 3.1400e-02, 3.0600e-02, 2.9900e-02, 2.9200e-02, 2.8500e-02, 2.7900e-02, 2.7200e-02, 2.6600e-02, 2.6000e-02, 2.5400e-02, 2.4900e-02, 2.4400e-02, 2.3800e-02, 2.3300e-02, 2.2800e-02, 2.2400e-02, 2.1900e-02, 2.1500e-02, 2.1000e-02, 2.0600e-02, 2.0200e-02, 1.9800e-02, 1.9400e-02, 1.9000e-02, 1.8700e-02, 1.8300e-02, 1.8000e-02, 1.7600e-02, 1.7300e-02, 1.7000e-02, 1.6700e-02, 1.6400e-02, 1.6100e-02, 1.5800e-02, 1.5500e-02, 1.5300e-02, 1.5000e-02, 1.4700e-02, 1.4500e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3500e-02, 1.3300e-02, 1.3100e-02, 1.2900e-02, 1.2700e-02, 1.2500e-02, 1.2300e-02, 1.2100e-02, 1.1900e-02, 1.1700e-02, 1.1500e-02, 1.1400e-02, 1.1200e-02, 1.1000e-02, 1.0900e-02, 1.0700e-02, 1.0600e-02, 1.0400e-02, 1.0300e-02, 1.0100e-02, 1.0000e-02, 9.8000e-03, 9.7000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.4000e-03, 6.4000e-03, 6.3000e-03, 6.2000e-03, 6.2000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.5000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03, 5.2000e-03, 5.2000e-03, 5.1000e-03, 5.1000e-03, 5.0000e-03, 5.0000e-03, 4.9000e-03, 4.9000e-03, 4.8000e-03, 4.8000e-03, 4.7000e-03, 4.7000e-03, 4.6000e-03, 4.6000e-03, 4.5000e-03, 4.5000e-03, 4.5000e-03}); + } + break; + case 6: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.0000e+00, 5.9352e+00, 5.7488e+00, 5.4626e+00, 5.1069e+00, 4.7136e+00, 4.3112e+00, 3.9217e+00, 3.5600e+00, 3.2345e+00, 2.9488e+00, 2.7026e+00, 2.4934e+00, 2.3177e+00, 2.1711e+00, 2.0494e+00, 1.9484e+00, 1.8645e+00, 1.7944e+00, 1.7353e+00, 1.6850e+00, 1.6414e+00, 1.6030e+00, 1.5685e+00, 1.5368e+00, 1.5073e+00, 1.4793e+00, 1.4522e+00, 1.4258e+00, 1.3998e+00, 1.3739e+00, 1.3482e+00, 1.3224e+00, 1.2965e+00, 1.2706e+00, 1.2446e+00, 1.2186e+00, 1.1925e+00, 1.1664e+00, 1.1403e+00, 1.1144e+00, 1.0885e+00, 1.0628e+00, 1.0373e+00, 1.0120e+00, 9.8700e-01, 9.6230e-01, 9.3790e-01, 9.1390e-01, 8.9020e-01, 8.6700e-01, 8.4410e-01, 8.2170e-01, 7.9970e-01, 7.7820e-01, 7.5710e-01, 7.3650e-01, 7.1630e-01, 6.9660e-01, 6.7740e-01, 6.5860e-01, 6.4030e-01, 6.2250e-01, 6.0510e-01, 5.8820e-01, 5.7170e-01, 5.5570e-01, 5.4010e-01, 5.2500e-01, 5.1020e-01, 4.9590e-01, 4.8200e-01, 4.6840e-01, 4.5530e-01, 4.4250e-01, 4.3010e-01, 4.1810e-01, 4.0640e-01, 3.9510e-01, 3.8410e-01, 3.7340e-01, 3.6310e-01, 3.5300e-01, 3.4330e-01, 3.3380e-01, 3.2460e-01, 3.1570e-01, 3.0710e-01, 2.9870e-01, 2.9060e-01, 2.8270e-01, 2.7510e-01, 2.6770e-01, 2.6050e-01, 2.5350e-01, 2.4670e-01, 2.4020e-01, 2.3380e-01, 2.2760e-01, 2.2160e-01, 2.1580e-01, 2.1020e-01, 2.0470e-01, 1.9940e-01, 1.9420e-01, 1.8920e-01, 1.8440e-01, 1.7970e-01, 1.7510e-01, 1.7060e-01, 1.6630e-01, 1.6210e-01, 1.5810e-01, 1.5410e-01, 1.5030e-01, 1.4660e-01, 1.4290e-01, 1.3940e-01, 1.3610e-01, 1.3270e-01, 1.2950e-01, 1.2640e-01, 1.2330e-01, 1.2030e-01, 1.1750e-01, 1.1470e-01, 1.1200e-01, 1.0940e-01, 1.0680e-01, 1.0420e-01, 1.0180e-01, 9.9500e-02, 9.7300e-02, 9.5000e-02, 9.2800e-02, 9.0700e-02, 8.8600e-02, 8.6500e-02, 8.4600e-02, 8.2800e-02, 8.1000e-02, 7.9200e-02, 7.7400e-02, 7.5600e-02, 7.3900e-02, 7.2300e-02, 7.0800e-02, 6.9400e-02, 6.7900e-02, 6.6500e-02, 6.5000e-02, 6.3500e-02, 6.2100e-02, 6.0700e-02, 5.9500e-02, 5.8400e-02, 5.7300e-02, 5.6100e-02, 5.4900e-02, 5.3700e-02, 5.2500e-02, 5.1300e-02, 5.0300e-02, 4.9300e-02, 4.8500e-02, 4.7600e-02, 4.6800e-02, 4.5800e-02, 4.4700e-02, 4.3700e-02, 4.2700e-02, 4.1800e-02, 4.1100e-02, 4.0500e-02, 3.9900e-02, 3.9200e-02, 3.8500e-02, 3.7600e-02, 3.6700e-02, 3.5800e-02, 3.5000e-02, 3.4400e-02, 3.3800e-02, 3.3400e-02, 3.3000e-02, 3.2600e-02, 3.2000e-02, 3.1200e-02, 3.0400e-02, 2.9600e-02, 2.8900e-02, 2.8400e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.6800e-02, 2.6300e-02, 2.5600e-02, 2.4900e-02, 2.4200e-02, 2.3600e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2700e-02, 2.2600e-02, 2.2300e-02, 2.1900e-02, 2.1300e-02, 2.0600e-02, 2.0000e-02, 1.9400e-02, 1.8900e-02, 1.8700e-02, 1.8600e-02, 1.8700e-02, 1.8700e-02, 1.8700e-02, 1.8500e-02, 1.8100e-02, 1.7600e-02, 1.6900e-02, 1.6300e-02, 1.5700e-02, 1.5300e-02, 1.5100e-02, 1.5100e-02, 1.5200e-02, 1.5400e-02, 1.5600e-02, 1.5600e-02, 1.5300e-02, 1.4900e-02, 1.4300e-02, 1.3600e-02, 1.3000e-02, 1.2500e-02, 1.2200e-02, 1.2100e-02, 1.2100e-02}); + feg = Vctr_cpu({2.5087e+00, 2.4821e+00, 2.4052e+00, 2.2865e+00, 2.1374e+00, 1.9704e+00, 1.7964e+00, 1.6242e+00, 1.4600e+00, 1.3074e+00, 1.1684e+00, 1.0436e+00, 9.3250e-01, 8.3440e-01, 7.4810e-01, 6.7240e-01, 6.0610e-01, 5.4800e-01, 4.9710e-01, 4.5240e-01, 4.1310e-01, 3.7850e-01, 3.4790e-01, 3.2080e-01, 2.9670e-01, 2.7530e-01, 2.5610e-01, 2.3890e-01, 2.2340e-01, 2.0950e-01, 1.9680e-01, 1.8540e-01, 1.7490e-01, 1.6540e-01, 1.5670e-01, 1.4870e-01, 1.4130e-01, 1.3450e-01, 1.2820e-01, 1.2240e-01, 1.1690e-01, 1.1190e-01, 1.0720e-01, 1.0280e-01, 9.8700e-02, 9.4800e-02, 9.1200e-02, 8.7800e-02, 8.4500e-02, 8.1500e-02, 7.8600e-02, 7.5900e-02, 7.3300e-02, 7.0900e-02, 6.8600e-02, 6.6400e-02, 6.4300e-02, 6.2300e-02, 6.0400e-02, 5.8600e-02, 5.6800e-02, 5.5200e-02, 5.3600e-02, 5.2100e-02, 5.0600e-02, 4.9200e-02, 4.7900e-02, 4.6600e-02, 4.5300e-02, 4.4200e-02, 4.3000e-02, 4.1900e-02, 4.0900e-02, 3.9800e-02, 3.8900e-02, 3.7900e-02, 3.7000e-02, 3.6100e-02, 3.5300e-02, 3.4500e-02, 3.3700e-02, 3.2900e-02, 3.2200e-02, 3.1400e-02, 3.0800e-02, 3.0100e-02, 2.9400e-02, 2.8800e-02, 2.8200e-02, 2.7600e-02, 2.7000e-02, 2.6500e-02, 2.5900e-02, 2.5400e-02, 2.4900e-02, 2.4400e-02, 2.3900e-02, 2.3500e-02, 2.3000e-02, 2.2600e-02, 2.2100e-02, 2.1700e-02, 2.1300e-02, 2.0900e-02, 2.0600e-02, 2.0200e-02, 1.9800e-02, 1.9500e-02, 1.9100e-02, 1.8800e-02, 1.8500e-02, 1.8100e-02, 1.7800e-02, 1.7500e-02, 1.7200e-02, 1.6900e-02, 1.6700e-02, 1.6400e-02, 1.6100e-02, 1.5900e-02, 1.5600e-02, 1.5400e-02, 1.5100e-02, 1.4900e-02, 1.4700e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3600e-02, 1.3400e-02, 1.3200e-02, 1.3000e-02, 1.2800e-02, 1.2600e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.1900e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1200e-02, 1.1100e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0500e-02, 1.0400e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.7000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.1000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.4000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03, 5.2000e-03, 5.2000e-03, 5.1000e-03, 5.1000e-03, 5.0000e-03, 5.0000e-03, 5.0000e-03, 4.9000e-03, 4.9000e-03, 4.8000e-03, 4.8000e-03, 4.7000e-03, 4.7000e-03, 4.6000e-03, 4.6000e-03, 4.6000e-03, 4.5000e-03, 4.5000e-03, 4.4000e-03, 4.4000e-03, 4.4000e-03, 4.3000e-03, 4.3000e-03, 4.3000e-03, 4.2000e-03, 4.2000e-03, 4.2000e-03, 4.1000e-03, 4.1000e-03, 4.0000e-03, 4.0000e-03, 4.0000e-03}); + } + break; + case 7: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.0000e+00, 6.9426e+00, 6.7755e+00, 6.5136e+00, 6.1781e+00, 5.7931e+00, 5.3822e+00, 4.9659e+00, 4.5602e+00, 4.1768e+00, 3.8229e+00, 3.5025e+00, 3.2168e+00, 2.9651e+00, 2.7455e+00, 2.5554e+00, 2.3917e+00, 2.2514e+00, 2.1315e+00, 2.0290e+00, 1.9414e+00, 1.8664e+00, 1.8018e+00, 1.7460e+00, 1.6973e+00, 1.6545e+00, 1.6164e+00, 1.5822e+00, 1.5509e+00, 1.5221e+00, 1.4951e+00, 1.4695e+00, 1.4450e+00, 1.4214e+00, 1.3983e+00, 1.3756e+00, 1.3532e+00, 1.3310e+00, 1.3089e+00, 1.2869e+00, 1.2649e+00, 1.2429e+00, 1.2209e+00, 1.1990e+00, 1.1770e+00, 1.1551e+00, 1.1333e+00, 1.1115e+00, 1.0897e+00, 1.0681e+00, 1.0466e+00, 1.0253e+00, 1.0041e+00, 9.8310e-01, 9.6240e-01, 9.4180e-01, 9.2150e-01, 9.0140e-01, 8.8160e-01, 8.6200e-01, 8.4280e-01, 8.2380e-01, 8.0520e-01, 7.8680e-01, 7.6880e-01, 7.5110e-01, 7.3370e-01, 7.1670e-01, 7.0000e-01, 6.8360e-01, 6.6750e-01, 6.5180e-01, 6.3640e-01, 6.2130e-01, 6.0660e-01, 5.9210e-01, 5.7800e-01, 5.6420e-01, 5.5080e-01, 5.3760e-01, 5.2480e-01, 5.1220e-01, 5.0000e-01, 4.8800e-01, 4.7630e-01, 4.6490e-01, 4.5380e-01, 4.4300e-01, 4.3240e-01, 4.2210e-01, 4.1200e-01, 4.0220e-01, 3.9260e-01, 3.8330e-01, 3.7420e-01, 3.6540e-01, 3.5670e-01, 3.4830e-01, 3.4010e-01, 3.3210e-01, 3.2430e-01, 3.1670e-01, 3.0930e-01, 3.0210e-01, 2.9510e-01, 2.8820e-01, 2.8160e-01, 2.7510e-01, 2.6870e-01, 2.6260e-01, 2.5660e-01, 2.5070e-01, 2.4500e-01, 2.3940e-01, 2.3400e-01, 2.2870e-01, 2.2360e-01, 2.1850e-01, 2.1370e-01, 2.0890e-01, 2.0420e-01, 1.9970e-01, 1.9530e-01, 1.9100e-01, 1.8680e-01, 1.8270e-01, 1.7870e-01, 1.7480e-01, 1.7100e-01, 1.6730e-01, 1.6370e-01, 1.6020e-01, 1.5680e-01, 1.5350e-01, 1.5020e-01, 1.4700e-01, 1.4390e-01, 1.4090e-01, 1.3790e-01, 1.3510e-01, 1.3230e-01, 1.2950e-01, 1.2680e-01, 1.2420e-01, 1.2160e-01, 1.1910e-01, 1.1670e-01, 1.1440e-01, 1.1210e-01, 1.0990e-01, 1.0760e-01, 1.0540e-01, 1.0330e-01, 1.0120e-01, 9.9200e-02, 9.7300e-02, 9.5500e-02, 9.3600e-02, 9.1800e-02, 8.9900e-02, 8.8100e-02, 8.6400e-02, 8.4700e-02, 8.3200e-02, 8.1700e-02, 8.0200e-02, 7.8700e-02, 7.7200e-02, 7.5600e-02, 7.4100e-02, 7.2700e-02, 7.1300e-02, 7.0000e-02, 6.8800e-02, 6.7700e-02, 6.6500e-02, 6.5300e-02, 6.4000e-02, 6.2700e-02, 6.1500e-02, 6.0300e-02, 5.9200e-02, 5.8300e-02, 5.7400e-02, 5.6500e-02, 5.5500e-02, 5.4600e-02, 5.3500e-02, 5.2400e-02, 5.1400e-02, 5.0400e-02, 4.9500e-02, 4.8700e-02, 4.8000e-02, 4.7400e-02, 4.6700e-02, 4.6000e-02, 4.5100e-02, 4.4200e-02, 4.3300e-02, 4.2400e-02, 4.1600e-02, 4.0900e-02, 4.0300e-02, 3.9800e-02, 3.9400e-02, 3.8900e-02, 3.8300e-02, 3.7700e-02, 3.6900e-02, 3.6100e-02, 3.5300e-02, 3.4600e-02, 3.3900e-02, 3.3500e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1800e-02, 3.1200e-02, 3.0500e-02, 2.9800e-02, 2.9100e-02, 2.8400e-02, 2.7900e-02, 2.7500e-02, 2.7200e-02, 2.7100e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6200e-02, 2.5600e-02, 2.5000e-02, 2.4300e-02, 2.3700e-02, 2.3100e-02, 2.2700e-02, 2.2400e-02, 2.2300e-02}); + feg = Vctr_cpu({2.2170e+00, 2.1997e+00, 2.1491e+00, 2.0696e+00, 1.9671e+00, 1.8486e+00, 1.7208e+00, 1.5897e+00, 1.4598e+00, 1.3347e+00, 1.2166e+00, 1.1069e+00, 1.0061e+00, 9.1430e-01, 8.3120e-01, 7.5650e-01, 6.8930e-01, 6.2920e-01, 5.7540e-01, 5.2730e-01, 4.8430e-01, 4.4580e-01, 4.1130e-01, 3.8030e-01, 3.5250e-01, 3.2750e-01, 3.0500e-01, 2.8460e-01, 2.6620e-01, 2.4940e-01, 2.3420e-01, 2.2040e-01, 2.0770e-01, 1.9620e-01, 1.8560e-01, 1.7580e-01, 1.6690e-01, 1.5860e-01, 1.5090e-01, 1.4380e-01, 1.3730e-01, 1.3110e-01, 1.2550e-01, 1.2010e-01, 1.1520e-01, 1.1050e-01, 1.0620e-01, 1.0210e-01, 9.8200e-02, 9.4600e-02, 9.1200e-02, 8.8000e-02, 8.4900e-02, 8.2000e-02, 7.9300e-02, 7.6700e-02, 7.4200e-02, 7.1900e-02, 6.9600e-02, 6.7500e-02, 6.5500e-02, 6.3600e-02, 6.1700e-02, 5.9900e-02, 5.8300e-02, 5.6600e-02, 5.5100e-02, 5.3600e-02, 5.2200e-02, 5.0800e-02, 4.9500e-02, 4.8200e-02, 4.7000e-02, 4.5800e-02, 4.4700e-02, 4.3600e-02, 4.2600e-02, 4.1600e-02, 4.0600e-02, 3.9700e-02, 3.8700e-02, 3.7900e-02, 3.7000e-02, 3.6200e-02, 3.5400e-02, 3.4600e-02, 3.3900e-02, 3.3200e-02, 3.2500e-02, 3.1800e-02, 3.1100e-02, 3.0500e-02, 2.9900e-02, 2.9300e-02, 2.8700e-02, 2.8200e-02, 2.7600e-02, 2.7100e-02, 2.6600e-02, 2.6100e-02, 2.5600e-02, 2.5100e-02, 2.4600e-02, 2.4200e-02, 2.3700e-02, 2.3300e-02, 2.2900e-02, 2.2500e-02, 2.2100e-02, 2.1700e-02, 2.1300e-02, 2.1000e-02, 2.0600e-02, 2.0300e-02, 1.9900e-02, 1.9600e-02, 1.9300e-02, 1.9000e-02, 1.8700e-02, 1.8400e-02, 1.8100e-02, 1.7800e-02, 1.7500e-02, 1.7200e-02, 1.7000e-02, 1.6700e-02, 1.6500e-02, 1.6200e-02, 1.6000e-02, 1.5700e-02, 1.5500e-02, 1.5300e-02, 1.5000e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3600e-02, 1.3400e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2000e-02, 1.1900e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1300e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.9000e-03, 6.8000e-03, 6.7000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.2000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.5000e-03, 5.4000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03, 5.2000e-03, 5.2000e-03, 5.1000e-03, 5.1000e-03, 5.0000e-03, 5.0000e-03, 5.0000e-03, 4.9000e-03, 4.9000e-03, 4.8000e-03, 4.8000e-03, 4.8000e-03, 4.7000e-03, 4.7000e-03, 4.6000e-03}); + } + break; + case 8: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.0000e+00, 7.9484e+00, 7.7972e+00, 7.5570e+00, 7.2433e+00, 6.8745e+00, 6.4696e+00, 6.0464e+00, 5.6203e+00, 5.2036e+00, 4.8052e+00, 4.4316e+00, 4.0863e+00, 3.7712e+00, 3.4866e+00, 3.2317e+00, 3.0049e+00, 2.8043e+00, 2.6276e+00, 2.4726e+00, 2.3369e+00, 2.2184e+00, 2.1149e+00, 2.0245e+00, 1.9455e+00, 1.8763e+00, 1.8155e+00, 1.7619e+00, 1.7144e+00, 1.6721e+00, 1.6340e+00, 1.5996e+00, 1.5682e+00, 1.5393e+00, 1.5125e+00, 1.4873e+00, 1.4634e+00, 1.4407e+00, 1.4189e+00, 1.3977e+00, 1.3771e+00, 1.3569e+00, 1.3370e+00, 1.3173e+00, 1.2979e+00, 1.2786e+00, 1.2594e+00, 1.2402e+00, 1.2212e+00, 1.2021e+00, 1.1832e+00, 1.1642e+00, 1.1453e+00, 1.1265e+00, 1.1077e+00, 1.0890e+00, 1.0704e+00, 1.0519e+00, 1.0335e+00, 1.0152e+00, 9.9700e-01, 9.7900e-01, 9.6110e-01, 9.4330e-01, 9.2580e-01, 9.0840e-01, 8.9120e-01, 8.7420e-01, 8.5740e-01, 8.4080e-01, 8.2440e-01, 8.0830e-01, 7.9240e-01, 7.7670e-01, 7.6120e-01, 7.4600e-01, 7.3100e-01, 7.1630e-01, 7.0180e-01, 6.8750e-01, 6.7350e-01, 6.5970e-01, 6.4620e-01, 6.3300e-01, 6.1990e-01, 6.0710e-01, 5.9460e-01, 5.8230e-01, 5.7020e-01, 5.5840e-01, 5.4680e-01, 5.3540e-01, 5.2430e-01, 5.1340e-01, 5.0270e-01, 4.9220e-01, 4.8200e-01, 4.7190e-01, 4.6210e-01, 4.5250e-01, 4.4310e-01, 4.3390e-01, 4.2480e-01, 4.1600e-01, 4.0740e-01, 3.9890e-01, 3.9070e-01, 3.8260e-01, 3.7470e-01, 3.6700e-01, 3.5940e-01, 3.5200e-01, 3.4480e-01, 3.3770e-01, 3.3080e-01, 3.2400e-01, 3.1740e-01, 3.1090e-01, 3.0460e-01, 2.9840e-01, 2.9240e-01, 2.8650e-01, 2.8070e-01, 2.7500e-01, 2.6950e-01, 2.6410e-01, 2.5880e-01, 2.5370e-01, 2.4860e-01, 2.4370e-01, 2.3880e-01, 2.3410e-01, 2.2950e-01, 2.2500e-01, 2.2060e-01, 2.1630e-01, 2.1210e-01, 2.0790e-01, 2.0390e-01, 1.9990e-01, 1.9610e-01, 1.9230e-01, 1.8870e-01, 1.8500e-01, 1.8150e-01, 1.7800e-01, 1.7460e-01, 1.7130e-01, 1.6810e-01, 1.6500e-01, 1.6190e-01, 1.5890e-01, 1.5590e-01, 1.5300e-01, 1.5010e-01, 1.4730e-01, 1.4460e-01, 1.4200e-01, 1.3940e-01, 1.3690e-01, 1.3440e-01, 1.3200e-01, 1.2950e-01, 1.2710e-01, 1.2480e-01, 1.2260e-01, 1.2040e-01, 1.1830e-01, 1.1630e-01, 1.1430e-01, 1.1220e-01, 1.1020e-01, 1.0820e-01, 1.0630e-01, 1.0440e-01, 1.0260e-01, 1.0090e-01, 9.9200e-02, 9.7600e-02, 9.5900e-02, 9.4300e-02, 9.2600e-02, 9.0900e-02, 8.9300e-02, 8.7700e-02, 8.6300e-02, 8.4900e-02, 8.3600e-02, 8.2300e-02, 8.1000e-02, 7.9600e-02, 7.8300e-02, 7.6900e-02, 7.5500e-02, 7.4200e-02, 7.2900e-02, 7.1800e-02, 7.0700e-02, 6.9600e-02, 6.8700e-02, 6.7600e-02, 6.6600e-02, 6.5500e-02, 6.4300e-02, 6.3200e-02, 6.2000e-02, 6.1000e-02, 6.0000e-02, 5.9100e-02, 5.8300e-02, 5.7600e-02, 5.6800e-02, 5.6100e-02, 5.5200e-02, 5.4300e-02, 5.3300e-02, 5.2300e-02, 5.1400e-02, 5.0400e-02, 4.9600e-02, 4.9000e-02, 4.8400e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6200e-02, 4.5500e-02, 4.4700e-02, 4.3800e-02, 4.2900e-02, 4.2100e-02, 4.1300e-02, 4.0700e-02, 4.0200e-02, 3.9800e-02, 3.9500e-02, 3.9100e-02, 3.8800e-02, 3.8300e-02, 3.7800e-02, 3.7200e-02}); + feg = Vctr_cpu({1.9884e+00, 1.9764e+00, 1.9410e+00, 1.8848e+00, 1.8111e+00, 1.7240e+00, 1.6279e+00, 1.5267e+00, 1.4238e+00, 1.3220e+00, 1.2234e+00, 1.1293e+00, 1.0408e+00, 9.5820e-01, 8.8180e-01, 8.1150e-01, 7.4720e-01, 6.8850e-01, 6.3500e-01, 5.8630e-01, 5.4220e-01, 5.0200e-01, 4.6560e-01, 4.3260e-01, 4.0250e-01, 3.7520e-01, 3.5030e-01, 3.2770e-01, 3.0700e-01, 2.8810e-01, 2.7090e-01, 2.5500e-01, 2.4050e-01, 2.2720e-01, 2.1490e-01, 2.0360e-01, 1.9310e-01, 1.8350e-01, 1.7450e-01, 1.6620e-01, 1.5850e-01, 1.5130e-01, 1.4460e-01, 1.3840e-01, 1.3260e-01, 1.2710e-01, 1.2200e-01, 1.1720e-01, 1.1270e-01, 1.0840e-01, 1.0440e-01, 1.0060e-01, 9.7100e-02, 9.3700e-02, 9.0500e-02, 8.7500e-02, 8.4600e-02, 8.1900e-02, 7.9300e-02, 7.6800e-02, 7.4500e-02, 7.2300e-02, 7.0100e-02, 6.8100e-02, 6.6100e-02, 6.4300e-02, 6.2500e-02, 6.0800e-02, 5.9200e-02, 5.7600e-02, 5.6100e-02, 5.4600e-02, 5.3200e-02, 5.1900e-02, 5.0600e-02, 4.9400e-02, 4.8200e-02, 4.7000e-02, 4.5900e-02, 4.4900e-02, 4.3800e-02, 4.2800e-02, 4.1900e-02, 4.1000e-02, 4.0100e-02, 3.9200e-02, 3.8300e-02, 3.7500e-02, 3.6700e-02, 3.6000e-02, 3.5200e-02, 3.4500e-02, 3.3800e-02, 3.3100e-02, 3.2500e-02, 3.1900e-02, 3.1200e-02, 3.0600e-02, 3.0100e-02, 2.9500e-02, 2.8900e-02, 2.8400e-02, 2.7900e-02, 2.7400e-02, 2.6900e-02, 2.6400e-02, 2.5900e-02, 2.5500e-02, 2.5000e-02, 2.4600e-02, 2.4200e-02, 2.3800e-02, 2.3400e-02, 2.3000e-02, 2.2600e-02, 2.2200e-02, 2.1900e-02, 2.1500e-02, 2.1200e-02, 2.0800e-02, 2.0500e-02, 2.0200e-02, 1.9900e-02, 1.9600e-02, 1.9300e-02, 1.9000e-02, 1.8700e-02, 1.8400e-02, 1.8100e-02, 1.7800e-02, 1.7600e-02, 1.7300e-02, 1.7100e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6100e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5200e-02, 1.5000e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3700e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2800e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.1900e-02, 1.1800e-02, 1.1600e-02, 1.1500e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.2000e-03, 7.1000e-03, 7.0000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.2000e-03, 6.1000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.5000e-03, 5.4000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03}); + } + break; + case 9: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.0000e+00, 8.9531e+00, 8.8152e+00, 8.5939e+00, 8.3009e+00, 7.9507e+00, 7.5585e+00, 7.1395e+00, 6.7075e+00, 6.2742e+00, 5.8494e+00, 5.4402e+00, 5.0521e+00, 4.6883e+00, 4.3509e+00, 4.0407e+00, 3.7575e+00, 3.5005e+00, 3.2685e+00, 3.0600e+00, 2.8733e+00, 2.7065e+00, 2.5579e+00, 2.4257e+00, 2.3083e+00, 2.2040e+00, 2.1115e+00, 2.0293e+00, 1.9562e+00, 1.8912e+00, 1.8331e+00, 1.7812e+00, 1.7345e+00, 1.6925e+00, 1.6544e+00, 1.6197e+00, 1.5879e+00, 1.5587e+00, 1.5315e+00, 1.5062e+00, 1.4823e+00, 1.4598e+00, 1.4383e+00, 1.4178e+00, 1.3979e+00, 1.3787e+00, 1.3600e+00, 1.3417e+00, 1.3237e+00, 1.3060e+00, 1.2886e+00, 1.2713e+00, 1.2541e+00, 1.2371e+00, 1.2202e+00, 1.2033e+00, 1.1866e+00, 1.1699e+00, 1.1532e+00, 1.1366e+00, 1.1201e+00, 1.1036e+00, 1.0872e+00, 1.0709e+00, 1.0546e+00, 1.0384e+00, 1.0223e+00, 1.0064e+00, 9.9050e-01, 9.7470e-01, 9.5900e-01, 9.4340e-01, 9.2800e-01, 9.1270e-01, 8.9760e-01, 8.8260e-01, 8.6770e-01, 8.5300e-01, 8.3850e-01, 8.2410e-01, 8.0990e-01, 7.9580e-01, 7.8200e-01, 7.6830e-01, 7.5480e-01, 7.4150e-01, 7.2830e-01, 7.1540e-01, 7.0260e-01, 6.9000e-01, 6.7760e-01, 6.6540e-01, 6.5340e-01, 6.4160e-01, 6.2990e-01, 6.1850e-01, 6.0720e-01, 5.9610e-01, 5.8520e-01, 5.7450e-01, 5.6400e-01, 5.5360e-01, 5.4350e-01, 5.3350e-01, 5.2370e-01, 5.1400e-01, 5.0460e-01, 4.9530e-01, 4.8620e-01, 4.7720e-01, 4.6840e-01, 4.5980e-01, 4.5130e-01, 4.4300e-01, 4.3480e-01, 4.2680e-01, 4.1900e-01, 4.1130e-01, 4.0370e-01, 3.9630e-01, 3.8910e-01, 3.8190e-01, 3.7500e-01, 3.6810e-01, 3.6140e-01, 3.5480e-01, 3.4830e-01, 3.4200e-01, 3.3580e-01, 3.2970e-01, 3.2370e-01, 3.1790e-01, 3.1210e-01, 3.0650e-01, 3.0100e-01, 2.9560e-01, 2.9030e-01, 2.8510e-01, 2.8000e-01, 2.7500e-01, 2.7010e-01, 2.6530e-01, 2.6060e-01, 2.5600e-01, 2.5140e-01, 2.4700e-01, 2.4270e-01, 2.3840e-01, 2.3430e-01, 2.3020e-01, 2.2610e-01, 2.2220e-01, 2.1830e-01, 2.1450e-01, 2.1090e-01, 2.0720e-01, 2.0370e-01, 2.0020e-01, 1.9670e-01, 1.9340e-01, 1.9010e-01, 1.8680e-01, 1.8370e-01, 1.8060e-01, 1.7760e-01, 1.7460e-01, 1.7170e-01, 1.6880e-01, 1.6590e-01, 1.6310e-01, 1.6040e-01, 1.5780e-01, 1.5520e-01, 1.5270e-01, 1.5020e-01, 1.4770e-01, 1.4530e-01, 1.4290e-01, 1.4050e-01, 1.3820e-01, 1.3600e-01, 1.3380e-01, 1.3170e-01, 1.2960e-01, 1.2760e-01, 1.2560e-01, 1.2350e-01, 1.2150e-01, 1.1960e-01, 1.1760e-01, 1.1580e-01, 1.1390e-01, 1.1220e-01, 1.1050e-01, 1.0880e-01, 1.0720e-01, 1.0550e-01, 1.0390e-01, 1.0220e-01, 1.0060e-01, 9.9000e-02, 9.7400e-02, 9.6000e-02, 9.4500e-02, 9.3200e-02, 9.1900e-02, 9.0500e-02, 8.9200e-02, 8.7900e-02, 8.6500e-02, 8.5100e-02, 8.3800e-02, 8.2400e-02, 8.1200e-02, 8.0000e-02, 7.8900e-02, 7.7900e-02, 7.6800e-02, 7.5800e-02, 7.4700e-02, 7.3600e-02, 7.2500e-02, 7.1400e-02, 7.0200e-02, 6.9100e-02, 6.8000e-02, 6.7100e-02, 6.6200e-02, 6.5400e-02, 6.4600e-02, 6.3800e-02, 6.3000e-02, 6.2100e-02, 6.1200e-02, 6.0300e-02, 5.9300e-02, 5.8300e-02, 5.7400e-02, 5.6500e-02, 5.5700e-02, 5.5000e-02}); + feg = Vctr_cpu({1.8040e+00, 1.7953e+00, 1.7695e+00, 1.7281e+00, 1.6731e+00, 1.6073e+00, 1.5333e+00, 1.4540e+00, 1.3717e+00, 1.2886e+00, 1.2065e+00, 1.1266e+00, 1.0499e+00, 9.7700e-01, 9.0830e-01, 8.4410e-01, 7.8420e-01, 7.2870e-01, 6.7740e-01, 6.3010e-01, 5.8650e-01, 5.4650e-01, 5.0970e-01, 4.7590e-01, 4.4490e-01, 4.1640e-01, 3.9020e-01, 3.6620e-01, 3.4400e-01, 3.2370e-01, 3.0490e-01, 2.8770e-01, 2.7170e-01, 2.5700e-01, 2.4330e-01, 2.3070e-01, 2.1900e-01, 2.0820e-01, 1.9810e-01, 1.8870e-01, 1.7990e-01, 1.7180e-01, 1.6420e-01, 1.5700e-01, 1.5040e-01, 1.4410e-01, 1.3830e-01, 1.3280e-01, 1.2760e-01, 1.2270e-01, 1.1810e-01, 1.1380e-01, 1.0970e-01, 1.0580e-01, 1.0220e-01, 9.8700e-02, 9.5400e-02, 9.2300e-02, 8.9300e-02, 8.6500e-02, 8.3800e-02, 8.1300e-02, 7.8800e-02, 7.6500e-02, 7.4300e-02, 7.2200e-02, 7.0100e-02, 6.8200e-02, 6.6300e-02, 6.4500e-02, 6.2800e-02, 6.1200e-02, 5.9600e-02, 5.8100e-02, 5.6700e-02, 5.5300e-02, 5.3900e-02, 5.2600e-02, 5.1400e-02, 5.0200e-02, 4.9000e-02, 4.7900e-02, 4.6800e-02, 4.5800e-02, 4.4700e-02, 4.3800e-02, 4.2800e-02, 4.1900e-02, 4.1000e-02, 4.0200e-02, 3.9300e-02, 3.8500e-02, 3.7800e-02, 3.7000e-02, 3.6300e-02, 3.5600e-02, 3.4900e-02, 3.4200e-02, 3.3600e-02, 3.2900e-02, 3.2300e-02, 3.1700e-02, 3.1100e-02, 3.0600e-02, 3.0000e-02, 2.9500e-02, 2.9000e-02, 2.8400e-02, 2.8000e-02, 2.7500e-02, 2.7000e-02, 2.6500e-02, 2.6100e-02, 2.5700e-02, 2.5200e-02, 2.4800e-02, 2.4400e-02, 2.4000e-02, 2.3600e-02, 2.3300e-02, 2.2900e-02, 2.2500e-02, 2.2200e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.0900e-02, 2.0600e-02, 2.0300e-02, 2.0000e-02, 1.9700e-02, 1.9400e-02, 1.9100e-02, 1.8800e-02, 1.8600e-02, 1.8300e-02, 1.8000e-02, 1.7800e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2700e-02, 1.2600e-02, 1.2400e-02, 1.2300e-02, 1.2100e-02, 1.2000e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.1000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03}); + } + break; + case 10: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0000e+01, 9.9570e+00, 9.8302e+00, 9.6253e+00, 9.3514e+00, 9.0199e+00, 8.6433e+00, 8.2343e+00, 7.8049e+00, 7.3662e+00, 6.9275e+00, 6.4965e+00, 6.0792e+00, 5.6800e+00, 5.3021e+00, 4.9474e+00, 4.6169e+00, 4.3109e+00, 4.0291e+00, 3.7708e+00, 3.5350e+00, 3.3203e+00, 3.1255e+00, 2.9492e+00, 2.7899e+00, 2.6462e+00, 2.5168e+00, 2.4002e+00, 2.2954e+00, 2.2011e+00, 2.1163e+00, 2.0400e+00, 1.9713e+00, 1.9093e+00, 1.8533e+00, 1.8026e+00, 1.7566e+00, 1.7148e+00, 1.6766e+00, 1.6416e+00, 1.6094e+00, 1.5796e+00, 1.5520e+00, 1.5263e+00, 1.5021e+00, 1.4794e+00, 1.4578e+00, 1.4373e+00, 1.4177e+00, 1.3988e+00, 1.3806e+00, 1.3630e+00, 1.3458e+00, 1.3290e+00, 1.3126e+00, 1.2964e+00, 1.2805e+00, 1.2647e+00, 1.2492e+00, 1.2338e+00, 1.2185e+00, 1.2033e+00, 1.1882e+00, 1.1732e+00, 1.1583e+00, 1.1434e+00, 1.1287e+00, 1.1139e+00, 1.0993e+00, 1.0847e+00, 1.0701e+00, 1.0556e+00, 1.0412e+00, 1.0269e+00, 1.0126e+00, 9.9840e-01, 9.8430e-01, 9.7030e-01, 9.5640e-01, 9.4260e-01, 9.2890e-01, 9.1520e-01, 9.0170e-01, 8.8830e-01, 8.7500e-01, 8.6190e-01, 8.4880e-01, 8.3590e-01, 8.2310e-01, 8.1050e-01, 7.9790e-01, 7.8550e-01, 7.7330e-01, 7.6120e-01, 7.4920e-01, 7.3740e-01, 7.2570e-01, 7.1420e-01, 7.0280e-01, 6.9150e-01, 6.8040e-01, 6.6950e-01, 6.5870e-01, 6.4800e-01, 6.3750e-01, 6.2720e-01, 6.1700e-01, 6.0690e-01, 5.9700e-01, 5.8730e-01, 5.7760e-01, 5.6820e-01, 5.5890e-01, 5.4970e-01, 5.4060e-01, 5.3170e-01, 5.2300e-01, 5.1440e-01, 5.0590e-01, 4.9750e-01, 4.8930e-01, 4.8120e-01, 4.7330e-01, 4.6550e-01, 4.5780e-01, 4.5030e-01, 4.4280e-01, 4.3550e-01, 4.2830e-01, 4.2130e-01, 4.1430e-01, 4.0750e-01, 4.0080e-01, 3.9420e-01, 3.8770e-01, 3.8140e-01, 3.7510e-01, 3.6900e-01, 3.6290e-01, 3.5700e-01, 3.5110e-01, 3.4540e-01, 3.3980e-01, 3.3420e-01, 3.2880e-01, 3.2350e-01, 3.1820e-01, 3.1310e-01, 3.0800e-01, 3.0300e-01, 2.9810e-01, 2.9330e-01, 2.8860e-01, 2.8400e-01, 2.7940e-01, 2.7500e-01, 2.7060e-01, 2.6620e-01, 2.6200e-01, 2.5780e-01, 2.5370e-01, 2.4970e-01, 2.4580e-01, 2.4190e-01, 2.3810e-01, 2.3440e-01, 2.3070e-01, 2.2710e-01, 2.2350e-01, 2.2000e-01, 2.1660e-01, 2.1320e-01, 2.0990e-01, 2.0670e-01, 2.0350e-01, 2.0040e-01, 1.9730e-01, 1.9420e-01, 1.9130e-01, 1.8830e-01, 1.8550e-01, 1.8270e-01, 1.7990e-01, 1.7720e-01, 1.7450e-01, 1.7190e-01, 1.6930e-01, 1.6670e-01, 1.6420e-01, 1.6180e-01, 1.5940e-01, 1.5700e-01, 1.5470e-01, 1.5250e-01, 1.5020e-01, 1.4800e-01, 1.4580e-01, 1.4360e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3350e-01, 1.3160e-01, 1.2970e-01, 1.2790e-01, 1.2600e-01, 1.2420e-01, 1.2240e-01, 1.2060e-01, 1.1880e-01, 1.1720e-01, 1.1560e-01, 1.1400e-01, 1.1240e-01, 1.1090e-01, 1.0930e-01, 1.0780e-01, 1.0630e-01, 1.0470e-01, 1.0320e-01, 1.0170e-01, 1.0030e-01, 9.9000e-02, 9.7700e-02, 9.6400e-02, 9.5100e-02, 9.3900e-02, 9.2600e-02, 9.1400e-02, 9.0100e-02, 8.8800e-02, 8.7500e-02, 8.6300e-02, 8.5100e-02, 8.4000e-02, 8.2900e-02, 8.1900e-02, 8.0900e-02, 7.9900e-02, 7.8900e-02}); + feg = Vctr_cpu({1.6519e+00, 1.6453e+00, 1.6258e+00, 1.5944e+00, 1.5523e+00, 1.5012e+00, 1.4431e+00, 1.3799e+00, 1.3134e+00, 1.2452e+00, 1.1766e+00, 1.1088e+00, 1.0427e+00, 9.7890e-01, 9.1790e-01, 8.5990e-01, 8.0520e-01, 7.5380e-01, 7.0570e-01, 6.6080e-01, 6.1890e-01, 5.8000e-01, 5.4390e-01, 5.1040e-01, 4.7930e-01, 4.5060e-01, 4.2390e-01, 3.9920e-01, 3.7630e-01, 3.5510e-01, 3.3540e-01, 3.1720e-01, 3.0020e-01, 2.8450e-01, 2.6990e-01, 2.5630e-01, 2.4360e-01, 2.3180e-01, 2.2070e-01, 2.1040e-01, 2.0080e-01, 1.9180e-01, 1.8340e-01, 1.7550e-01, 1.6810e-01, 1.6110e-01, 1.5460e-01, 1.4840e-01, 1.4260e-01, 1.3720e-01, 1.3200e-01, 1.2720e-01, 1.2260e-01, 1.1820e-01, 1.1410e-01, 1.1020e-01, 1.0650e-01, 1.0300e-01, 9.9600e-02, 9.6400e-02, 9.3400e-02, 9.0500e-02, 8.7800e-02, 8.5200e-02, 8.2700e-02, 8.0300e-02, 7.8000e-02, 7.5800e-02, 7.3700e-02, 7.1700e-02, 6.9800e-02, 6.7900e-02, 6.6200e-02, 6.4500e-02, 6.2800e-02, 6.1300e-02, 5.9800e-02, 5.8300e-02, 5.6900e-02, 5.5600e-02, 5.4300e-02, 5.3000e-02, 5.1800e-02, 5.0600e-02, 4.9500e-02, 4.8400e-02, 4.7400e-02, 4.6400e-02, 4.5400e-02, 4.4400e-02, 4.3500e-02, 4.2600e-02, 4.1700e-02, 4.0900e-02, 4.0100e-02, 3.9300e-02, 3.8500e-02, 3.7800e-02, 3.7100e-02, 3.6400e-02, 3.5700e-02, 3.5000e-02, 3.4400e-02, 3.3800e-02, 3.3100e-02, 3.2600e-02, 3.2000e-02, 3.1400e-02, 3.0900e-02, 3.0300e-02, 2.9800e-02, 2.9300e-02, 2.8800e-02, 2.8300e-02, 2.7900e-02, 2.7400e-02, 2.7000e-02, 2.6500e-02, 2.6100e-02, 2.5700e-02, 2.5300e-02, 2.4900e-02, 2.4500e-02, 2.4100e-02, 2.3800e-02, 2.3400e-02, 2.3100e-02, 2.2700e-02, 2.2400e-02, 2.2000e-02, 2.1700e-02, 2.1400e-02, 2.1100e-02, 2.0800e-02, 2.0500e-02, 2.0200e-02, 1.9900e-02, 1.9600e-02, 1.9400e-02, 1.9100e-02, 1.8900e-02, 1.8600e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.6900e-02, 1.6700e-02, 1.6500e-02, 1.6300e-02, 1.6100e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3100e-02, 1.3000e-02, 1.2800e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.7000e-03, 6.6000e-03}); + } + break; + case 11: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.1000e+01, 1.0880e+01, 1.0568e+01, 1.0167e+01, 9.7603e+00, 9.3812e+00, 9.0267e+00, 8.6821e+00, 8.3354e+00, 7.9809e+00, 7.6183e+00, 7.2503e+00, 6.8810e+00, 6.5147e+00, 6.1555e+00, 5.8068e+00, 5.4712e+00, 5.1509e+00, 4.8473e+00, 4.5612e+00, 4.2931e+00, 4.0430e+00, 3.8107e+00, 3.5957e+00, 3.3973e+00, 3.2148e+00, 3.0472e+00, 2.8937e+00, 2.7534e+00, 2.6252e+00, 2.5084e+00, 2.4019e+00, 2.3049e+00, 2.2167e+00, 2.1364e+00, 2.0633e+00, 1.9967e+00, 1.9361e+00, 1.8807e+00, 1.8302e+00, 1.7840e+00, 1.7417e+00, 1.7028e+00, 1.6670e+00, 1.6340e+00, 1.6034e+00, 1.5750e+00, 1.5485e+00, 1.5237e+00, 1.5004e+00, 1.4785e+00, 1.4577e+00, 1.4379e+00, 1.4191e+00, 1.4010e+00, 1.3836e+00, 1.3668e+00, 1.3505e+00, 1.3347e+00, 1.3192e+00, 1.3041e+00, 1.2893e+00, 1.2747e+00, 1.2604e+00, 1.2462e+00, 1.2322e+00, 1.2183e+00, 1.2046e+00, 1.1910e+00, 1.1774e+00, 1.1639e+00, 1.1505e+00, 1.1372e+00, 1.1239e+00, 1.1106e+00, 1.0976e+00, 1.0846e+00, 1.0715e+00, 1.0584e+00, 1.0455e+00, 1.0327e+00, 1.0200e+00, 1.0071e+00, 9.9430e-01, 9.8180e-01, 9.6940e-01, 9.5690e-01, 9.4430e-01, 9.3180e-01, 9.1970e-01, 9.0780e-01, 8.9570e-01, 8.8350e-01, 8.7140e-01, 8.5970e-01, 8.4830e-01, 8.3680e-01, 8.2510e-01, 8.1340e-01, 8.0200e-01, 7.9110e-01, 7.8030e-01, 7.6930e-01, 7.5810e-01, 7.4710e-01, 7.3650e-01, 7.2630e-01, 7.1620e-01, 7.0590e-01, 6.9530e-01, 6.8490e-01, 6.7500e-01, 6.6550e-01, 6.5620e-01, 6.4670e-01, 6.3700e-01, 6.2720e-01, 6.1780e-01, 6.0890e-01, 6.0030e-01, 5.9180e-01, 5.8310e-01, 5.7400e-01, 5.6500e-01, 5.5650e-01, 5.4850e-01, 5.4080e-01, 5.3310e-01, 5.2520e-01, 5.1700e-01, 5.0870e-01, 5.0090e-01, 4.9360e-01, 4.8660e-01, 4.7980e-01, 4.7290e-01, 4.6560e-01, 4.5810e-01, 4.5080e-01, 4.4400e-01, 4.3760e-01, 4.3150e-01, 4.2550e-01, 4.1940e-01, 4.1290e-01, 4.0620e-01, 3.9970e-01, 3.9360e-01, 3.8800e-01, 3.8250e-01, 3.7730e-01, 3.7200e-01, 3.6650e-01, 3.6060e-01, 3.5470e-01, 3.4910e-01, 3.4410e-01, 3.3920e-01, 3.3450e-01, 3.3000e-01, 3.2550e-01, 3.2070e-01, 3.1550e-01, 3.1030e-01, 3.0540e-01, 3.0100e-01, 2.9690e-01, 2.9280e-01, 2.8880e-01, 2.8500e-01, 2.8110e-01, 2.7670e-01, 2.7210e-01, 2.6760e-01, 2.6370e-01, 2.6010e-01, 2.5660e-01, 2.5310e-01, 2.4970e-01, 2.4650e-01, 2.4330e-01, 2.3950e-01, 2.3550e-01, 2.3160e-01, 2.2820e-01, 2.2520e-01, 2.2220e-01, 2.1920e-01, 2.1620e-01, 2.1350e-01, 2.1090e-01, 2.0810e-01, 2.0470e-01, 2.0120e-01, 1.9790e-01, 1.9520e-01, 1.9280e-01, 1.9030e-01, 1.8770e-01, 1.8520e-01, 1.8300e-01, 1.8090e-01, 1.7860e-01, 1.7590e-01, 1.7280e-01, 1.6980e-01, 1.6740e-01, 1.6550e-01, 1.6350e-01, 1.6140e-01, 1.5910e-01, 1.5710e-01, 1.5530e-01, 1.5370e-01, 1.5180e-01, 1.4940e-01, 1.4670e-01, 1.4420e-01, 1.4220e-01, 1.4070e-01, 1.3920e-01, 1.3740e-01, 1.3550e-01, 1.3360e-01, 1.3210e-01, 1.3090e-01, 1.2960e-01, 1.2780e-01, 1.2560e-01, 1.2330e-01, 1.2120e-01, 1.1980e-01, 1.1870e-01, 1.1750e-01, 1.1600e-01, 1.1430e-01, 1.1270e-01, 1.1150e-01, 1.1050e-01, 1.0960e-01, 1.0830e-01}); + feg = Vctr_cpu({4.7719e+00, 4.5955e+00, 4.1349e+00, 3.5444e+00, 2.9670e+00, 2.4796e+00, 2.0991e+00, 1.8115e+00, 1.5944e+00, 1.4273e+00, 1.2950e+00, 1.1867e+00, 1.0954e+00, 1.0163e+00, 9.4650e-01, 8.8390e-01, 8.2700e-01, 7.7500e-01, 7.2720e-01, 6.8300e-01, 6.4210e-01, 6.0410e-01, 5.6880e-01, 5.3600e-01, 5.0540e-01, 4.7700e-01, 4.5050e-01, 4.2580e-01, 4.0280e-01, 3.8130e-01, 3.6130e-01, 3.4260e-01, 3.2520e-01, 3.0890e-01, 2.9360e-01, 2.7940e-01, 2.6600e-01, 2.5350e-01, 2.4180e-01, 2.3090e-01, 2.2060e-01, 2.1090e-01, 2.0180e-01, 1.9330e-01, 1.8530e-01, 1.7770e-01, 1.7060e-01, 1.6380e-01, 1.5750e-01, 1.5150e-01, 1.4580e-01, 1.4050e-01, 1.3540e-01, 1.3060e-01, 1.2610e-01, 1.2170e-01, 1.1760e-01, 1.1370e-01, 1.1000e-01, 1.0650e-01, 1.0310e-01, 9.9900e-02, 9.6900e-02, 9.4000e-02, 9.1200e-02, 8.8500e-02, 8.6000e-02, 8.3600e-02, 8.1200e-02, 7.9000e-02, 7.6900e-02, 7.4800e-02, 7.2900e-02, 7.1000e-02, 6.9200e-02, 6.7400e-02, 6.5700e-02, 6.4100e-02, 6.2600e-02, 6.1100e-02, 5.9600e-02, 5.8200e-02, 5.6900e-02, 5.5600e-02, 5.4400e-02, 5.3200e-02, 5.2000e-02, 5.0900e-02, 4.9800e-02, 4.8700e-02, 4.7700e-02, 4.6700e-02, 4.5800e-02, 4.4800e-02, 4.3900e-02, 4.3100e-02, 4.2200e-02, 4.1400e-02, 4.0600e-02, 3.9800e-02, 3.9100e-02, 3.8400e-02, 3.7700e-02, 3.7000e-02, 3.6300e-02, 3.5600e-02, 3.5000e-02, 3.4400e-02, 3.3800e-02, 3.3200e-02, 3.2600e-02, 3.2100e-02, 3.1500e-02, 3.1000e-02, 3.0500e-02, 3.0000e-02, 2.9500e-02, 2.9000e-02, 2.8600e-02, 2.8100e-02, 2.7700e-02, 2.7200e-02, 2.6800e-02, 2.6400e-02, 2.6000e-02, 2.5600e-02, 2.5200e-02, 2.4900e-02, 2.4500e-02, 2.4100e-02, 2.3800e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2400e-02, 2.2100e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0100e-02, 1.9800e-02, 1.9600e-02, 1.9300e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8300e-02, 1.8100e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.7000e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6000e-02, 1.5800e-02, 1.5600e-02, 1.5400e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4500e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3100e-02, 1.3000e-02, 1.2900e-02, 1.2700e-02, 1.2600e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03}); + } + break; + case 12: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.2000e+01, 1.1868e+01, 1.1508e+01, 1.1011e+01, 1.0473e+01, 9.9603e+00, 9.5019e+00, 9.0978e+00, 8.7354e+00, 8.3995e+00, 8.0776e+00, 7.7614e+00, 7.4465e+00, 7.1315e+00, 6.8168e+00, 6.5038e+00, 6.1944e+00, 5.8909e+00, 5.5951e+00, 5.3089e+00, 5.0335e+00, 4.7702e+00, 4.5196e+00, 4.2823e+00, 4.0585e+00, 3.8482e+00, 3.6514e+00, 3.4676e+00, 3.2965e+00, 3.1376e+00, 2.9903e+00, 2.8541e+00, 2.7282e+00, 2.6122e+00, 2.5053e+00, 2.4069e+00, 2.3164e+00, 2.2332e+00, 2.1567e+00, 2.0865e+00, 2.0220e+00, 1.9627e+00, 1.9082e+00, 1.8580e+00, 1.8117e+00, 1.7691e+00, 1.7298e+00, 1.6933e+00, 1.6596e+00, 1.6283e+00, 1.5991e+00, 1.5719e+00, 1.5464e+00, 1.5226e+00, 1.5001e+00, 1.4788e+00, 1.4587e+00, 1.4396e+00, 1.4214e+00, 1.4040e+00, 1.3873e+00, 1.3711e+00, 1.3556e+00, 1.3405e+00, 1.3258e+00, 1.3115e+00, 1.2976e+00, 1.2839e+00, 1.2705e+00, 1.2572e+00, 1.2442e+00, 1.2314e+00, 1.2187e+00, 1.2061e+00, 1.1937e+00, 1.1813e+00, 1.1690e+00, 1.1568e+00, 1.1447e+00, 1.1327e+00, 1.1207e+00, 1.1087e+00, 1.0968e+00, 1.0850e+00, 1.0733e+00, 1.0615e+00, 1.0498e+00, 1.0381e+00, 1.0266e+00, 1.0151e+00, 1.0036e+00, 9.9200e-01, 9.8060e-01, 9.6930e-01, 9.5820e-01, 9.4690e-01, 9.3560e-01, 9.2440e-01, 9.1340e-01, 9.0260e-01, 8.9180e-01, 8.8080e-01, 8.6990e-01, 8.5910e-01, 8.4860e-01, 8.3830e-01, 8.2790e-01, 8.1740e-01, 8.0680e-01, 7.9660e-01, 7.8660e-01, 7.7690e-01, 7.6710e-01, 7.5700e-01, 7.4690e-01, 7.3710e-01, 7.2770e-01, 7.1850e-01, 7.0940e-01, 7.0000e-01, 6.9050e-01, 6.8110e-01, 6.7200e-01, 6.6340e-01, 6.5500e-01, 6.4650e-01, 6.3780e-01, 6.2880e-01, 6.2000e-01, 6.1160e-01, 6.0370e-01, 5.9600e-01, 5.8840e-01, 5.8040e-01, 5.7220e-01, 5.6390e-01, 5.5600e-01, 5.4860e-01, 5.4160e-01, 5.3480e-01, 5.2780e-01, 5.2040e-01, 5.1280e-01, 5.0530e-01, 4.9810e-01, 4.9150e-01, 4.8540e-01, 4.7940e-01, 4.7310e-01, 4.6650e-01, 4.5970e-01, 4.5280e-01, 4.4620e-01, 4.4010e-01, 4.3460e-01, 4.2940e-01, 4.2400e-01, 4.1830e-01, 4.1230e-01, 4.0610e-01, 3.9990e-01, 3.9410e-01, 3.8890e-01, 3.8420e-01, 3.7970e-01, 3.7500e-01, 3.7010e-01, 3.6480e-01, 3.5920e-01, 3.5370e-01, 3.4830e-01, 3.4360e-01, 3.3950e-01, 3.3570e-01, 3.3180e-01, 3.2760e-01, 3.2310e-01, 3.1840e-01, 3.1350e-01, 3.0860e-01, 3.0390e-01, 2.9990e-01, 2.9650e-01, 2.9330e-01, 2.9010e-01, 2.8650e-01, 2.8270e-01, 2.7860e-01, 2.7440e-01, 2.7000e-01, 2.6580e-01, 2.6200e-01, 2.5890e-01, 2.5630e-01, 2.5380e-01, 2.5090e-01, 2.4780e-01, 2.4440e-01, 2.4090e-01, 2.3720e-01, 2.3340e-01, 2.2970e-01, 2.2640e-01, 2.2380e-01, 2.2170e-01, 2.1970e-01, 2.1740e-01, 2.1480e-01, 2.1190e-01, 2.0900e-01, 2.0600e-01, 2.0270e-01, 1.9940e-01, 1.9620e-01, 1.9360e-01, 1.9170e-01, 1.9020e-01, 1.8860e-01, 1.8660e-01, 1.8430e-01, 1.8190e-01, 1.7940e-01, 1.7690e-01, 1.7420e-01, 1.7130e-01, 1.6840e-01, 1.6600e-01, 1.6430e-01, 1.6310e-01, 1.6200e-01, 1.6060e-01, 1.5880e-01, 1.5670e-01, 1.5460e-01, 1.5260e-01, 1.5060e-01, 1.4830e-01, 1.4570e-01, 1.4320e-01, 1.4110e-01, 1.3960e-01}); + feg = Vctr_cpu({5.2015e+00, 5.0711e+00, 4.7130e+00, 4.2097e+00, 3.6555e+00, 3.1243e+00, 2.6573e+00, 2.2681e+00, 1.9533e+00, 1.7022e+00, 1.5021e+00, 1.3414e+00, 1.2109e+00, 1.1032e+00, 1.0127e+00, 9.3540e-01, 8.6840e-01, 8.0950e-01, 7.5700e-01, 7.0980e-01, 6.6690e-01, 6.2780e-01, 5.9180e-01, 5.5870e-01, 5.2800e-01, 4.9950e-01, 4.7290e-01, 4.4820e-01, 4.2510e-01, 4.0350e-01, 3.8340e-01, 3.6440e-01, 3.4670e-01, 3.3010e-01, 3.1450e-01, 2.9990e-01, 2.8610e-01, 2.7320e-01, 2.6100e-01, 2.4960e-01, 2.3880e-01, 2.2870e-01, 2.1910e-01, 2.1000e-01, 2.0150e-01, 1.9350e-01, 1.8590e-01, 1.7870e-01, 1.7190e-01, 1.6540e-01, 1.5930e-01, 1.5350e-01, 1.4800e-01, 1.4280e-01, 1.3790e-01, 1.3320e-01, 1.2870e-01, 1.2450e-01, 1.2040e-01, 1.1660e-01, 1.1290e-01, 1.0940e-01, 1.0600e-01, 1.0280e-01, 9.9800e-02, 9.6900e-02, 9.4100e-02, 9.1400e-02, 8.8900e-02, 8.6400e-02, 8.4100e-02, 8.1800e-02, 7.9600e-02, 7.7600e-02, 7.5600e-02, 7.3700e-02, 7.1800e-02, 7.0000e-02, 6.8300e-02, 6.6700e-02, 6.5100e-02, 6.3600e-02, 6.2100e-02, 6.0700e-02, 5.9300e-02, 5.8000e-02, 5.6700e-02, 5.5500e-02, 5.4300e-02, 5.3100e-02, 5.2000e-02, 5.0900e-02, 4.9900e-02, 4.8800e-02, 4.7900e-02, 4.6900e-02, 4.6000e-02, 4.5100e-02, 4.4200e-02, 4.3400e-02, 4.2500e-02, 4.1700e-02, 4.1000e-02, 4.0200e-02, 3.9500e-02, 3.8800e-02, 3.8100e-02, 3.7400e-02, 3.6700e-02, 3.6100e-02, 3.5500e-02, 3.4900e-02, 3.4300e-02, 3.3700e-02, 3.3200e-02, 3.2600e-02, 3.2100e-02, 3.1600e-02, 3.1100e-02, 3.0600e-02, 3.0100e-02, 2.9600e-02, 2.9100e-02, 2.8700e-02, 2.8300e-02, 2.7800e-02, 2.7400e-02, 2.7000e-02, 2.6600e-02, 2.6200e-02, 2.5800e-02, 2.5400e-02, 2.5100e-02, 2.4700e-02, 2.4400e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3000e-02, 2.2700e-02, 2.2400e-02, 2.2100e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.1000e-02, 2.0700e-02, 2.0400e-02, 2.0200e-02, 1.9900e-02, 1.9600e-02, 1.9400e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6200e-02, 1.6000e-02, 1.5800e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3500e-02, 1.3400e-02, 1.3200e-02, 1.3100e-02, 1.3000e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.1000e-03, 8.0000e-03, 8.0000e-03, 7.9000e-03}); + } + break; + case 13: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.3000e+01, 1.2850e+01, 1.2439e+01, 1.1864e+01, 1.1230e+01, 1.0614e+01, 1.0059e+01, 9.5759e+00, 9.1582e+00, 8.7927e+00, 8.4648e+00, 8.1616e+00, 7.8731e+00, 7.5925e+00, 7.3157e+00, 7.0405e+00, 6.7663e+00, 6.4934e+00, 6.2226e+00, 5.9552e+00, 5.6924e+00, 5.4357e+00, 5.1861e+00, 4.9448e+00, 4.7124e+00, 4.4896e+00, 4.2770e+00, 4.0748e+00, 3.8831e+00, 3.7020e+00, 3.5314e+00, 3.3709e+00, 3.2205e+00, 3.0797e+00, 2.9482e+00, 2.8256e+00, 2.7114e+00, 2.6052e+00, 2.5066e+00, 2.4150e+00, 2.3301e+00, 2.2514e+00, 2.1785e+00, 2.1109e+00, 2.0484e+00, 1.9905e+00, 1.9368e+00, 1.8871e+00, 1.8411e+00, 1.7983e+00, 1.7586e+00, 1.7217e+00, 1.6873e+00, 1.6553e+00, 1.6254e+00, 1.5975e+00, 1.5713e+00, 1.5467e+00, 1.5236e+00, 1.5017e+00, 1.4811e+00, 1.4615e+00, 1.4429e+00, 1.4251e+00, 1.4082e+00, 1.3919e+00, 1.3763e+00, 1.3612e+00, 1.3466e+00, 1.3325e+00, 1.3188e+00, 1.3054e+00, 1.2924e+00, 1.2796e+00, 1.2671e+00, 1.2548e+00, 1.2427e+00, 1.2308e+00, 1.2190e+00, 1.2073e+00, 1.1958e+00, 1.1845e+00, 1.1732e+00, 1.1619e+00, 1.1507e+00, 1.1397e+00, 1.1288e+00, 1.1178e+00, 1.1068e+00, 1.0959e+00, 1.0852e+00, 1.0745e+00, 1.0638e+00, 1.0530e+00, 1.0423e+00, 1.0318e+00, 1.0214e+00, 1.0109e+00, 1.0003e+00, 9.8970e-01, 9.7930e-01, 9.6920e-01, 9.5900e-01, 9.4870e-01, 9.3830e-01, 9.2800e-01, 9.1800e-01, 9.0820e-01, 8.9840e-01, 8.8830e-01, 8.7820e-01, 8.6810e-01, 8.5840e-01, 8.4900e-01, 8.3970e-01, 8.3010e-01, 8.2030e-01, 8.1060e-01, 8.0110e-01, 7.9200e-01, 7.8320e-01, 7.7430e-01, 7.6510e-01, 7.5570e-01, 7.4640e-01, 7.3740e-01, 7.2900e-01, 7.2070e-01, 7.1240e-01, 7.0380e-01, 6.9490e-01, 6.8600e-01, 6.7750e-01, 6.6950e-01, 6.6190e-01, 6.5430e-01, 6.4640e-01, 6.3830e-01, 6.2990e-01, 6.2160e-01, 6.1390e-01, 6.0670e-01, 5.9980e-01, 5.9290e-01, 5.8570e-01, 5.7810e-01, 5.7030e-01, 5.6260e-01, 5.5540e-01, 5.4880e-01, 5.4260e-01, 5.3650e-01, 5.3010e-01, 5.2340e-01, 5.1620e-01, 5.0900e-01, 5.0210e-01, 4.9580e-01, 4.9010e-01, 4.8470e-01, 4.7930e-01, 4.7360e-01, 4.6750e-01, 4.6100e-01, 4.5430e-01, 4.4800e-01, 4.4230e-01, 4.3730e-01, 4.3250e-01, 4.2780e-01, 4.2290e-01, 4.1770e-01, 4.1200e-01, 4.0600e-01, 4.0000e-01, 3.9450e-01, 3.8980e-01, 3.8550e-01, 3.8150e-01, 3.7740e-01, 3.7320e-01, 3.6870e-01, 3.6360e-01, 3.5810e-01, 3.5270e-01, 3.4770e-01, 3.4340e-01, 3.3970e-01, 3.3630e-01, 3.3290e-01, 3.2940e-01, 3.2570e-01, 3.2150e-01, 3.1690e-01, 3.1190e-01, 3.0700e-01, 3.0280e-01, 2.9920e-01, 2.9620e-01, 2.9330e-01, 2.9050e-01, 2.8760e-01, 2.8450e-01, 2.8110e-01, 2.7710e-01, 2.7270e-01, 2.6820e-01, 2.6420e-01, 2.6090e-01, 2.5820e-01, 2.5590e-01, 2.5350e-01, 2.5110e-01, 2.4870e-01, 2.4610e-01, 2.4310e-01, 2.3960e-01, 2.3560e-01, 2.3160e-01, 2.2800e-01, 2.2520e-01, 2.2300e-01, 2.2110e-01, 2.1920e-01, 2.1720e-01, 2.1520e-01, 2.1320e-01, 2.1100e-01, 2.0830e-01, 2.0500e-01, 2.0140e-01, 1.9780e-01, 1.9480e-01, 1.9260e-01, 1.9100e-01, 1.8950e-01, 1.8800e-01, 1.8630e-01, 1.8470e-01, 1.8310e-01, 1.8140e-01}); + feg = Vctr_cpu({5.8861e+00, 5.7481e+00, 5.3687e+00, 4.8331e+00, 4.2367e+00, 3.6540e+00, 3.1280e+00, 2.6760e+00, 2.2987e+00, 1.9890e+00, 1.7367e+00, 1.5313e+00, 1.3634e+00, 1.2253e+00, 1.1106e+00, 1.0143e+00, 9.3250e-01, 8.6220e-01, 8.0100e-01, 7.4730e-01, 6.9960e-01, 6.5680e-01, 6.1820e-01, 5.8310e-01, 5.5100e-01, 5.2140e-01, 4.9410e-01, 4.6880e-01, 4.4530e-01, 4.2340e-01, 4.0290e-01, 3.8370e-01, 3.6570e-01, 3.4880e-01, 3.3300e-01, 3.1810e-01, 3.0400e-01, 2.9080e-01, 2.7830e-01, 2.6650e-01, 2.5540e-01, 2.4490e-01, 2.3490e-01, 2.2550e-01, 2.1660e-01, 2.0820e-01, 2.0020e-01, 1.9260e-01, 1.8550e-01, 1.7870e-01, 1.7220e-01, 1.6600e-01, 1.6020e-01, 1.5470e-01, 1.4940e-01, 1.4430e-01, 1.3960e-01, 1.3500e-01, 1.3060e-01, 1.2650e-01, 1.2250e-01, 1.1870e-01, 1.1510e-01, 1.1170e-01, 1.0840e-01, 1.0520e-01, 1.0220e-01, 9.9300e-02, 9.6500e-02, 9.3800e-02, 9.1300e-02, 8.8800e-02, 8.6500e-02, 8.4200e-02, 8.2000e-02, 8.0000e-02, 7.7900e-02, 7.6000e-02, 7.4200e-02, 7.2400e-02, 7.0600e-02, 6.9000e-02, 6.7400e-02, 6.5800e-02, 6.4300e-02, 6.2900e-02, 6.1500e-02, 6.0100e-02, 5.8800e-02, 5.7600e-02, 5.6300e-02, 5.5100e-02, 5.4000e-02, 5.2900e-02, 5.1800e-02, 5.0800e-02, 4.9800e-02, 4.8800e-02, 4.7800e-02, 4.6900e-02, 4.6000e-02, 4.5200e-02, 4.4300e-02, 4.3500e-02, 4.2700e-02, 4.1900e-02, 4.1200e-02, 4.0400e-02, 3.9700e-02, 3.9000e-02, 3.8400e-02, 3.7700e-02, 3.7100e-02, 3.6400e-02, 3.5800e-02, 3.5200e-02, 3.4700e-02, 3.4100e-02, 3.3500e-02, 3.3000e-02, 3.2500e-02, 3.2000e-02, 3.1500e-02, 3.1000e-02, 3.0500e-02, 3.0100e-02, 2.9600e-02, 2.9200e-02, 2.8700e-02, 2.8300e-02, 2.7900e-02, 2.7500e-02, 2.7100e-02, 2.6700e-02, 2.6300e-02, 2.5900e-02, 2.5600e-02, 2.5200e-02, 2.4900e-02, 2.4500e-02, 2.4200e-02, 2.3900e-02, 2.3500e-02, 2.3200e-02, 2.2900e-02, 2.2600e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.0900e-02, 2.0700e-02, 2.0400e-02, 2.0200e-02, 1.9900e-02, 1.9700e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6500e-02, 1.6300e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4000e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03}); + } + break; + case 14: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.4000e+01, 1.3851e+01, 1.3435e+01, 1.2831e+01, 1.2135e+01, 1.1430e+01, 1.0770e+01, 1.0183e+01, 9.6736e+00, 9.2366e+00, 8.8595e+00, 8.5286e+00, 8.2313e+00, 7.9572e+00, 7.6980e+00, 7.4477e+00, 7.2025e+00, 6.9599e+00, 6.7187e+00, 6.4786e+00, 6.2398e+00, 6.0029e+00, 5.7687e+00, 5.5382e+00, 5.3123e+00, 5.0918e+00, 4.8774e+00, 4.6699e+00, 4.4699e+00, 4.2776e+00, 4.0934e+00, 3.9176e+00, 3.7502e+00, 3.5912e+00, 3.4405e+00, 3.2981e+00, 3.1637e+00, 3.0372e+00, 2.9182e+00, 2.8065e+00, 2.7017e+00, 2.6036e+00, 2.5118e+00, 2.4260e+00, 2.3459e+00, 2.2711e+00, 2.2014e+00, 2.1363e+00, 2.0757e+00, 2.0191e+00, 1.9664e+00, 1.9173e+00, 1.8714e+00, 1.8287e+00, 1.7888e+00, 1.7515e+00, 1.7166e+00, 1.6840e+00, 1.6535e+00, 1.6248e+00, 1.5979e+00, 1.5726e+00, 1.5487e+00, 1.5262e+00, 1.5049e+00, 1.4847e+00, 1.4656e+00, 1.4474e+00, 1.4300e+00, 1.4133e+00, 1.3974e+00, 1.3821e+00, 1.3674e+00, 1.3532e+00, 1.3394e+00, 1.3261e+00, 1.3132e+00, 1.3006e+00, 1.2883e+00, 1.2763e+00, 1.2645e+00, 1.2529e+00, 1.2416e+00, 1.2304e+00, 1.2194e+00, 1.2085e+00, 1.1978e+00, 1.1872e+00, 1.1766e+00, 1.1662e+00, 1.1559e+00, 1.1456e+00, 1.1354e+00, 1.1252e+00, 1.1152e+00, 1.1052e+00, 1.0951e+00, 1.0852e+00, 1.0752e+00, 1.0654e+00, 1.0557e+00, 1.0459e+00, 1.0361e+00, 1.0263e+00, 1.0166e+00, 1.0071e+00, 9.9750e-01, 9.8800e-01, 9.7830e-01, 9.6870e-01, 9.5930e-01, 9.5000e-01, 9.4070e-01, 9.3140e-01, 9.2200e-01, 9.1260e-01, 9.0330e-01, 8.9430e-01, 8.8530e-01, 8.7640e-01, 8.6730e-01, 8.5810e-01, 8.4900e-01, 8.4010e-01, 8.3150e-01, 8.2300e-01, 8.1440e-01, 8.0560e-01, 7.9670e-01, 7.8800e-01, 7.7950e-01, 7.7140e-01, 7.6340e-01, 7.5520e-01, 7.4690e-01, 7.3840e-01, 7.2990e-01, 7.2180e-01, 7.1410e-01, 7.0660e-01, 6.9910e-01, 6.9130e-01, 6.8340e-01, 6.7530e-01, 6.6740e-01, 6.5990e-01, 6.5270e-01, 6.4590e-01, 6.3900e-01, 6.3180e-01, 6.2430e-01, 6.1670e-01, 6.0930e-01, 6.0220e-01, 5.9560e-01, 5.8930e-01, 5.8310e-01, 5.7670e-01, 5.6990e-01, 5.6280e-01, 5.5580e-01, 5.4900e-01, 5.4260e-01, 5.3670e-01, 5.3120e-01, 5.2570e-01, 5.1990e-01, 5.1370e-01, 5.0720e-01, 5.0060e-01, 4.9430e-01, 4.8840e-01, 4.8310e-01, 4.7810e-01, 4.7340e-01, 4.6840e-01, 4.6300e-01, 4.5710e-01, 4.5110e-01, 4.4510e-01, 4.3950e-01, 4.3440e-01, 4.2980e-01, 4.2560e-01, 4.2150e-01, 4.1720e-01, 4.1230e-01, 4.0710e-01, 4.0150e-01, 3.9610e-01, 3.9100e-01, 3.8630e-01, 3.8210e-01, 3.7840e-01, 3.7490e-01, 3.7140e-01, 3.6750e-01, 3.6300e-01, 3.5810e-01, 3.5310e-01, 3.4830e-01, 3.4370e-01, 3.3960e-01, 3.3600e-01, 3.3300e-01, 3.3020e-01, 3.2730e-01, 3.2410e-01, 3.2020e-01, 3.1580e-01, 3.1130e-01, 3.0690e-01, 3.0270e-01, 2.9890e-01, 2.9560e-01, 2.9270e-01, 2.9030e-01, 2.8820e-01, 2.8580e-01, 2.8300e-01, 2.7940e-01, 2.7550e-01, 2.7140e-01, 2.6750e-01, 2.6380e-01, 2.6040e-01, 2.5750e-01, 2.5500e-01, 2.5300e-01, 2.5130e-01, 2.4970e-01, 2.4750e-01, 2.4480e-01, 2.4140e-01, 2.3770e-01, 2.3410e-01, 2.3070e-01, 2.2760e-01, 2.2470e-01, 2.2220e-01, 2.2020e-01}); + feg = Vctr_cpu({5.8107e+00, 5.7053e+00, 5.4089e+00, 4.9733e+00, 4.4630e+00, 3.9366e+00, 3.4356e+00, 2.9833e+00, 2.5886e+00, 2.2520e+00, 1.9685e+00, 1.7316e+00, 1.5341e+00, 1.3692e+00, 1.2313e+00, 1.1152e+00, 1.0168e+00, 9.3280e-01, 8.6060e-01, 7.9780e-01, 7.4290e-01, 6.9440e-01, 6.5130e-01, 6.1250e-01, 5.7760e-01, 5.4580e-01, 5.1680e-01, 4.9010e-01, 4.6550e-01, 4.4270e-01, 4.2150e-01, 4.0180e-01, 3.8330e-01, 3.6600e-01, 3.4980e-01, 3.3450e-01, 3.2020e-01, 3.0670e-01, 2.9390e-01, 2.8180e-01, 2.7040e-01, 2.5960e-01, 2.4940e-01, 2.3970e-01, 2.3050e-01, 2.2180e-01, 2.1350e-01, 2.0570e-01, 1.9820e-01, 1.9110e-01, 1.8430e-01, 1.7790e-01, 1.7180e-01, 1.6590e-01, 1.6040e-01, 1.5510e-01, 1.5000e-01, 1.4520e-01, 1.4050e-01, 1.3610e-01, 1.3190e-01, 1.2790e-01, 1.2400e-01, 1.2040e-01, 1.1680e-01, 1.1340e-01, 1.1020e-01, 1.0710e-01, 1.0410e-01, 1.0120e-01, 9.8500e-02, 9.5900e-02, 9.3300e-02, 9.0900e-02, 8.8500e-02, 8.6300e-02, 8.4100e-02, 8.2000e-02, 8.0000e-02, 7.8100e-02, 7.6200e-02, 7.4400e-02, 7.2700e-02, 7.1000e-02, 6.9400e-02, 6.7800e-02, 6.6300e-02, 6.4800e-02, 6.3400e-02, 6.2000e-02, 6.0700e-02, 5.9400e-02, 5.8200e-02, 5.7000e-02, 5.5800e-02, 5.4700e-02, 5.3600e-02, 5.2600e-02, 5.1500e-02, 5.0500e-02, 4.9600e-02, 4.8600e-02, 4.7700e-02, 4.6800e-02, 4.6000e-02, 4.5100e-02, 4.4300e-02, 4.3500e-02, 4.2800e-02, 4.2000e-02, 4.1300e-02, 4.0600e-02, 3.9900e-02, 3.9200e-02, 3.8500e-02, 3.7900e-02, 3.7300e-02, 3.6700e-02, 3.6100e-02, 3.5500e-02, 3.4900e-02, 3.4400e-02, 3.3800e-02, 3.3300e-02, 3.2800e-02, 3.2300e-02, 3.1800e-02, 3.1300e-02, 3.0900e-02, 3.0400e-02, 3.0000e-02, 2.9500e-02, 2.9100e-02, 2.8700e-02, 2.8300e-02, 2.7900e-02, 2.7500e-02, 2.7100e-02, 2.6700e-02, 2.6300e-02, 2.6000e-02, 2.5600e-02, 2.5300e-02, 2.5000e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2500e-02, 2.2200e-02, 2.1900e-02, 2.1600e-02, 2.1400e-02, 2.1100e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0100e-02, 1.9900e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5400e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4100e-02, 1.4000e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.2000e-03}); + } + break; + case 15: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.5000e+01, 1.4858e+01, 1.4457e+01, 1.3856e+01, 1.3136e+01, 1.2373e+01, 1.1627e+01, 1.0939e+01, 1.0326e+01, 9.7930e+00, 9.3348e+00, 8.9412e+00, 8.6001e+00, 8.2998e+00, 8.0298e+00, 7.7813e+00, 7.5473e+00, 7.3228e+00, 7.1040e+00, 6.8884e+00, 6.6746e+00, 6.4618e+00, 6.2499e+00, 6.0390e+00, 5.8296e+00, 5.6222e+00, 5.4177e+00, 5.2165e+00, 5.0195e+00, 4.8272e+00, 4.6402e+00, 4.4588e+00, 4.2836e+00, 4.1148e+00, 3.9525e+00, 3.7971e+00, 3.6485e+00, 3.5067e+00, 3.3717e+00, 3.2435e+00, 3.1219e+00, 3.0067e+00, 2.8978e+00, 2.7950e+00, 2.6980e+00, 2.6066e+00, 2.5206e+00, 2.4398e+00, 2.3638e+00, 2.2924e+00, 2.2255e+00, 2.1626e+00, 2.1037e+00, 2.0485e+00, 1.9967e+00, 1.9482e+00, 1.9026e+00, 1.8600e+00, 1.8200e+00, 1.7824e+00, 1.7471e+00, 1.7140e+00, 1.6829e+00, 1.6536e+00, 1.6260e+00, 1.5999e+00, 1.5754e+00, 1.5522e+00, 1.5302e+00, 1.5094e+00, 1.4896e+00, 1.4708e+00, 1.4528e+00, 1.4357e+00, 1.4194e+00, 1.4037e+00, 1.3886e+00, 1.3742e+00, 1.3602e+00, 1.3467e+00, 1.3337e+00, 1.3210e+00, 1.3087e+00, 1.2968e+00, 1.2851e+00, 1.2737e+00, 1.2625e+00, 1.2516e+00, 1.2409e+00, 1.2303e+00, 1.2199e+00, 1.2097e+00, 1.1995e+00, 1.1896e+00, 1.1797e+00, 1.1699e+00, 1.1602e+00, 1.1506e+00, 1.1410e+00, 1.1316e+00, 1.1222e+00, 1.1128e+00, 1.1035e+00, 1.0942e+00, 1.0850e+00, 1.0759e+00, 1.0668e+00, 1.0577e+00, 1.0486e+00, 1.0395e+00, 1.0305e+00, 1.0216e+00, 1.0127e+00, 1.0038e+00, 9.9490e-01, 9.8600e-01, 9.7710e-01, 9.6840e-01, 9.5980e-01, 9.5120e-01, 9.4240e-01, 9.3370e-01, 9.2490e-01, 9.1640e-01, 9.0800e-01, 8.9970e-01, 8.9120e-01, 8.8270e-01, 8.7420e-01, 8.6570e-01, 8.5740e-01, 8.4940e-01, 8.4140e-01, 8.3330e-01, 8.2510e-01, 8.1680e-01, 8.0850e-01, 8.0050e-01, 7.9270e-01, 7.8510e-01, 7.7750e-01, 7.6980e-01, 7.6180e-01, 7.5390e-01, 7.4600e-01, 7.3840e-01, 7.3120e-01, 7.2410e-01, 7.1690e-01, 7.0960e-01, 7.0210e-01, 6.9450e-01, 6.8700e-01, 6.7980e-01, 6.7290e-01, 6.6630e-01, 6.5980e-01, 6.5310e-01, 6.4610e-01, 6.3890e-01, 6.3180e-01, 6.2480e-01, 6.1820e-01, 6.1200e-01, 6.0600e-01, 6.0010e-01, 5.9390e-01, 5.8750e-01, 5.8080e-01, 5.7400e-01, 5.6750e-01, 5.6140e-01, 5.5560e-01, 5.5020e-01, 5.4500e-01, 5.3950e-01, 5.3370e-01, 5.2760e-01, 5.2140e-01, 5.1510e-01, 5.0920e-01, 5.0380e-01, 4.9870e-01, 4.9400e-01, 4.8940e-01, 4.8460e-01, 4.7940e-01, 4.7380e-01, 4.6800e-01, 4.6220e-01, 4.5670e-01, 4.5170e-01, 4.4710e-01, 4.4290e-01, 4.3900e-01, 4.3490e-01, 4.3050e-01, 4.2570e-01, 4.2050e-01, 4.1510e-01, 4.0990e-01, 4.0500e-01, 4.0050e-01, 3.9660e-01, 3.9300e-01, 3.8970e-01, 3.8640e-01, 3.8260e-01, 3.7840e-01, 3.7370e-01, 3.6880e-01, 3.6400e-01, 3.5940e-01, 3.5520e-01, 3.5150e-01, 3.4830e-01, 3.4550e-01, 3.4290e-01, 3.4000e-01, 3.3670e-01, 3.3280e-01, 3.2860e-01, 3.2410e-01, 3.1970e-01, 3.1560e-01, 3.1190e-01, 3.0860e-01, 3.0580e-01, 3.0350e-01, 3.0140e-01, 2.9920e-01, 2.9660e-01, 2.9350e-01, 2.8990e-01, 2.8590e-01, 2.8180e-01, 2.7800e-01, 2.7440e-01, 2.7110e-01, 2.6840e-01, 2.6610e-01}); + feg = Vctr_cpu({5.4946e+00, 5.4177e+00, 5.1982e+00, 4.8661e+00, 4.4615e+00, 4.0243e+00, 3.5875e+00, 3.1739e+00, 2.7967e+00, 2.4617e+00, 2.1694e+00, 1.9175e+00, 1.7019e+00, 1.5182e+00, 1.3618e+00, 1.2286e+00, 1.1148e+00, 1.0173e+00, 9.3320e-01, 8.6050e-01, 7.9700e-01, 7.4140e-01, 6.9230e-01, 6.4870e-01, 6.0970e-01, 5.7460e-01, 5.4280e-01, 5.1390e-01, 4.8750e-01, 4.6320e-01, 4.4080e-01, 4.2000e-01, 4.0080e-01, 3.8280e-01, 3.6600e-01, 3.5020e-01, 3.3540e-01, 3.2150e-01, 3.0840e-01, 2.9600e-01, 2.8430e-01, 2.7320e-01, 2.6270e-01, 2.5280e-01, 2.4330e-01, 2.3440e-01, 2.2580e-01, 2.1770e-01, 2.1000e-01, 2.0270e-01, 1.9570e-01, 1.8900e-01, 1.8260e-01, 1.7660e-01, 1.7080e-01, 1.6520e-01, 1.5990e-01, 1.5490e-01, 1.5000e-01, 1.4540e-01, 1.4100e-01, 1.3670e-01, 1.3270e-01, 1.2880e-01, 1.2500e-01, 1.2150e-01, 1.1800e-01, 1.1470e-01, 1.1160e-01, 1.0850e-01, 1.0560e-01, 1.0280e-01, 1.0010e-01, 9.7500e-02, 9.5000e-02, 9.2600e-02, 9.0200e-02, 8.8000e-02, 8.5900e-02, 8.3800e-02, 8.1800e-02, 7.9800e-02, 7.8000e-02, 7.6200e-02, 7.4400e-02, 7.2800e-02, 7.1100e-02, 6.9600e-02, 6.8000e-02, 6.6600e-02, 6.5100e-02, 6.3800e-02, 6.2400e-02, 6.1100e-02, 5.9900e-02, 5.8700e-02, 5.7500e-02, 5.6400e-02, 5.5300e-02, 5.4200e-02, 5.3100e-02, 5.2100e-02, 5.1100e-02, 5.0200e-02, 4.9300e-02, 4.8400e-02, 4.7500e-02, 4.6600e-02, 4.5800e-02, 4.5000e-02, 4.4200e-02, 4.3400e-02, 4.2700e-02, 4.2000e-02, 4.1300e-02, 4.0600e-02, 3.9900e-02, 3.9300e-02, 3.8600e-02, 3.8000e-02, 3.7400e-02, 3.6800e-02, 3.6200e-02, 3.5600e-02, 3.5100e-02, 3.4600e-02, 3.4000e-02, 3.3500e-02, 3.3000e-02, 3.2500e-02, 3.2000e-02, 3.1600e-02, 3.1100e-02, 3.0700e-02, 3.0200e-02, 2.9800e-02, 2.9400e-02, 2.9000e-02, 2.8600e-02, 2.8200e-02, 2.7800e-02, 2.7400e-02, 2.7000e-02, 2.6700e-02, 2.6300e-02, 2.6000e-02, 2.5600e-02, 2.5300e-02, 2.5000e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2600e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.1000e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.5000e-02, 1.4800e-02, 1.4700e-02, 1.4500e-02, 1.4400e-02, 1.4200e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03}); + } + break; + case 16: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.6000e+01, 1.5867e+01, 1.5483e+01, 1.4898e+01, 1.4175e+01, 1.3383e+01, 1.2581e+01, 1.1813e+01, 1.1107e+01, 1.0477e+01, 9.9259e+00, 9.4495e+00, 9.0393e+00, 8.6850e+00, 8.3761e+00, 8.1029e+00, 7.8567e+00, 7.6303e+00, 7.4178e+00, 7.2148e+00, 7.0178e+00, 6.8246e+00, 6.6334e+00, 6.4434e+00, 6.2541e+00, 6.0654e+00, 5.8774e+00, 5.6905e+00, 5.5052e+00, 5.3219e+00, 5.1412e+00, 4.9636e+00, 4.7897e+00, 4.6197e+00, 4.4543e+00, 4.2936e+00, 4.1379e+00, 3.9876e+00, 3.8427e+00, 3.7034e+00, 3.5698e+00, 3.4418e+00, 3.3194e+00, 3.2027e+00, 3.0914e+00, 2.9856e+00, 2.8850e+00, 2.7895e+00, 2.6991e+00, 2.6134e+00, 2.5323e+00, 2.4557e+00, 2.3834e+00, 2.3150e+00, 2.2506e+00, 2.1898e+00, 2.1325e+00, 2.0785e+00, 2.0276e+00, 1.9797e+00, 1.9346e+00, 1.8921e+00, 1.8520e+00, 1.8143e+00, 1.7787e+00, 1.7451e+00, 1.7135e+00, 1.6836e+00, 1.6554e+00, 1.6287e+00, 1.6034e+00, 1.5795e+00, 1.5568e+00, 1.5353e+00, 1.5149e+00, 1.4954e+00, 1.4769e+00, 1.4592e+00, 1.4423e+00, 1.4262e+00, 1.4107e+00, 1.3958e+00, 1.3815e+00, 1.3677e+00, 1.3544e+00, 1.3416e+00, 1.3291e+00, 1.3170e+00, 1.3053e+00, 1.2938e+00, 1.2827e+00, 1.2718e+00, 1.2612e+00, 1.2507e+00, 1.2405e+00, 1.2305e+00, 1.2206e+00, 1.2109e+00, 1.2013e+00, 1.1918e+00, 1.1825e+00, 1.1732e+00, 1.1641e+00, 1.1550e+00, 1.1460e+00, 1.1371e+00, 1.1283e+00, 1.1195e+00, 1.1107e+00, 1.1020e+00, 1.0934e+00, 1.0848e+00, 1.0763e+00, 1.0678e+00, 1.0593e+00, 1.0508e+00, 1.0424e+00, 1.0340e+00, 1.0257e+00, 1.0174e+00, 1.0091e+00, 1.0008e+00, 9.9250e-01, 9.8430e-01, 9.7620e-01, 9.6810e-01, 9.6000e-01, 9.5190e-01, 9.4370e-01, 9.3560e-01, 9.2760e-01, 9.1980e-01, 9.1190e-01, 9.0410e-01, 8.9610e-01, 8.8810e-01, 8.8020e-01, 8.7240e-01, 8.6480e-01, 8.5720e-01, 8.4970e-01, 8.4200e-01, 8.3430e-01, 8.2660e-01, 8.1890e-01, 8.1140e-01, 8.0420e-01, 7.9700e-01, 7.8980e-01, 7.8250e-01, 7.7500e-01, 7.6760e-01, 7.6020e-01, 7.5300e-01, 7.4610e-01, 7.3930e-01, 7.3260e-01, 7.2570e-01, 7.1870e-01, 7.1160e-01, 7.0450e-01, 6.9750e-01, 6.9080e-01, 6.8440e-01, 6.7810e-01, 6.7190e-01, 6.6550e-01, 6.5890e-01, 6.5210e-01, 6.4540e-01, 6.3880e-01, 6.3250e-01, 6.2650e-01, 6.2070e-01, 6.1510e-01, 6.0930e-01, 6.0320e-01, 5.9700e-01, 5.9060e-01, 5.8430e-01, 5.7820e-01, 5.7250e-01, 5.6710e-01, 5.6200e-01, 5.5690e-01, 5.5170e-01, 5.4620e-01, 5.4040e-01, 5.3440e-01, 5.2850e-01, 5.2280e-01, 5.1750e-01, 5.1260e-01, 5.0800e-01, 5.0350e-01, 4.9900e-01, 4.9420e-01, 4.8910e-01, 4.8360e-01, 4.7810e-01, 4.7270e-01, 4.6750e-01, 4.6270e-01, 4.5840e-01, 4.5440e-01, 4.5060e-01, 4.4670e-01, 4.4250e-01, 4.3790e-01, 4.3300e-01, 4.2790e-01, 4.2280e-01, 4.1800e-01, 4.1350e-01, 4.0950e-01, 4.0590e-01, 4.0260e-01, 3.9940e-01, 3.9610e-01, 3.9240e-01, 3.8820e-01, 3.8370e-01, 3.7900e-01, 3.7430e-01, 3.6990e-01, 3.6590e-01, 3.6230e-01, 3.5910e-01, 3.5640e-01, 3.5380e-01, 3.5110e-01, 3.4810e-01, 3.4460e-01, 3.4070e-01, 3.3650e-01, 3.3220e-01, 3.2800e-01, 3.2410e-01, 3.2050e-01, 3.1750e-01, 3.1490e-01}); + feg = Vctr_cpu({5.1696e+00, 5.1119e+00, 4.9455e+00, 4.6888e+00, 4.3674e+00, 4.0087e+00, 3.6373e+00, 3.2726e+00, 2.9279e+00, 2.6112e+00, 2.3260e+00, 2.0731e+00, 1.8511e+00, 1.6575e+00, 1.4895e+00, 1.3440e+00, 1.2181e+00, 1.1090e+00, 1.0143e+00, 9.3190e-01, 8.5990e-01, 7.9670e-01, 7.4110e-01, 6.9180e-01, 6.4790e-01, 6.0870e-01, 5.7340e-01, 5.4150e-01, 5.1260e-01, 4.8620e-01, 4.6200e-01, 4.3980e-01, 4.1920e-01, 4.0020e-01, 3.8250e-01, 3.6590e-01, 3.5050e-01, 3.3600e-01, 3.2240e-01, 3.0960e-01, 2.9750e-01, 2.8610e-01, 2.7530e-01, 2.6500e-01, 2.5530e-01, 2.4610e-01, 2.3730e-01, 2.2900e-01, 2.2110e-01, 2.1350e-01, 2.0630e-01, 1.9940e-01, 1.9280e-01, 1.8660e-01, 1.8060e-01, 1.7480e-01, 1.6930e-01, 1.6410e-01, 1.5910e-01, 1.5420e-01, 1.4960e-01, 1.4520e-01, 1.4090e-01, 1.3690e-01, 1.3300e-01, 1.2920e-01, 1.2560e-01, 1.2210e-01, 1.1880e-01, 1.1560e-01, 1.1250e-01, 1.0950e-01, 1.0670e-01, 1.0390e-01, 1.0130e-01, 9.8700e-02, 9.6300e-02, 9.3900e-02, 9.1600e-02, 8.9400e-02, 8.7300e-02, 8.5200e-02, 8.3300e-02, 8.1300e-02, 7.9500e-02, 7.7700e-02, 7.6000e-02, 7.4300e-02, 7.2700e-02, 7.1100e-02, 6.9600e-02, 6.8100e-02, 6.6700e-02, 6.5300e-02, 6.4000e-02, 6.2700e-02, 6.1400e-02, 6.0200e-02, 5.9000e-02, 5.7900e-02, 5.6700e-02, 5.5700e-02, 5.4600e-02, 5.3600e-02, 5.2600e-02, 5.1600e-02, 5.0700e-02, 4.9800e-02, 4.8900e-02, 4.8000e-02, 4.7200e-02, 4.6400e-02, 4.5600e-02, 4.4800e-02, 4.4000e-02, 4.3300e-02, 4.2600e-02, 4.1900e-02, 4.1200e-02, 4.0500e-02, 3.9900e-02, 3.9200e-02, 3.8600e-02, 3.8000e-02, 3.7400e-02, 3.6800e-02, 3.6300e-02, 3.5700e-02, 3.5200e-02, 3.4700e-02, 3.4200e-02, 3.3700e-02, 3.3200e-02, 3.2700e-02, 3.2200e-02, 3.1800e-02, 3.1300e-02, 3.0900e-02, 3.0400e-02, 3.0000e-02, 2.9600e-02, 2.9200e-02, 2.8800e-02, 2.8400e-02, 2.8000e-02, 2.7700e-02, 2.7300e-02, 2.6900e-02, 2.6600e-02, 2.6200e-02, 2.5900e-02, 2.5600e-02, 2.5300e-02, 2.4900e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3200e-02, 2.2900e-02, 2.2600e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1300e-02, 2.1100e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7800e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4200e-02, 1.4000e-02, 1.3900e-02, 1.3800e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02}); + } + break; + case 17: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.7000e+01, 1.6874e+01, 1.6510e+01, 1.5945e+01, 1.5233e+01, 1.4431e+01, 1.3595e+01, 1.2770e+01, 1.1990e+01, 1.1274e+01, 1.0632e+01, 1.0068e+01, 9.5760e+00, 9.1504e+00, 8.7821e+00, 8.4621e+00, 8.1814e+00, 7.9320e+00, 7.7066e+00, 7.4994e+00, 7.3053e+00, 7.1205e+00, 6.9420e+00, 6.7674e+00, 6.5953e+00, 6.4245e+00, 6.2543e+00, 6.0846e+00, 5.9152e+00, 5.7463e+00, 5.5782e+00, 5.4111e+00, 5.2456e+00, 5.0819e+00, 4.9207e+00, 4.7621e+00, 4.6068e+00, 4.4548e+00, 4.3067e+00, 4.1626e+00, 4.0227e+00, 3.8873e+00, 3.7564e+00, 3.6302e+00, 3.5087e+00, 3.3919e+00, 3.2799e+00, 3.1726e+00, 3.0699e+00, 2.9718e+00, 2.8782e+00, 2.7890e+00, 2.7041e+00, 2.6233e+00, 2.5465e+00, 2.4736e+00, 2.4044e+00, 2.3388e+00, 2.2766e+00, 2.2177e+00, 2.1619e+00, 2.1091e+00, 2.0591e+00, 2.0118e+00, 1.9671e+00, 1.9248e+00, 1.8847e+00, 1.8469e+00, 1.8111e+00, 1.7771e+00, 1.7451e+00, 1.7147e+00, 1.6859e+00, 1.6586e+00, 1.6327e+00, 1.6081e+00, 1.5848e+00, 1.5626e+00, 1.5415e+00, 1.5214e+00, 1.5022e+00, 1.4839e+00, 1.4665e+00, 1.4497e+00, 1.4337e+00, 1.4184e+00, 1.4036e+00, 1.3894e+00, 1.3757e+00, 1.3625e+00, 1.3498e+00, 1.3375e+00, 1.3255e+00, 1.3139e+00, 1.3026e+00, 1.2917e+00, 1.2810e+00, 1.2705e+00, 1.2603e+00, 1.2503e+00, 1.2405e+00, 1.2309e+00, 1.2215e+00, 1.2122e+00, 1.2030e+00, 1.1940e+00, 1.1851e+00, 1.1763e+00, 1.1676e+00, 1.1590e+00, 1.1504e+00, 1.1420e+00, 1.1336e+00, 1.1253e+00, 1.1170e+00, 1.1088e+00, 1.1007e+00, 1.0926e+00, 1.0846e+00, 1.0766e+00, 1.0686e+00, 1.0606e+00, 1.0527e+00, 1.0448e+00, 1.0370e+00, 1.0292e+00, 1.0214e+00, 1.0136e+00, 1.0058e+00, 9.9810e-01, 9.9040e-01, 9.8280e-01, 9.7530e-01, 9.6770e-01, 9.6010e-01, 9.5240e-01, 9.4480e-01, 9.3730e-01, 9.2990e-01, 9.2260e-01, 9.1520e-01, 9.0780e-01, 9.0030e-01, 8.9290e-01, 8.8550e-01, 8.7820e-01, 8.7110e-01, 8.6400e-01, 8.5690e-01, 8.4970e-01, 8.4250e-01, 8.3520e-01, 8.2800e-01, 8.2100e-01, 8.1410e-01, 8.0730e-01, 8.0050e-01, 7.9370e-01, 7.8670e-01, 7.7970e-01, 7.7280e-01, 7.6590e-01, 7.5920e-01, 7.5270e-01, 7.4630e-01, 7.3990e-01, 7.3350e-01, 7.2680e-01, 7.2010e-01, 7.1350e-01, 7.0690e-01, 7.0050e-01, 6.9440e-01, 6.8840e-01, 6.8250e-01, 6.7650e-01, 6.7030e-01, 6.6400e-01, 6.5770e-01, 6.5140e-01, 6.4520e-01, 6.3930e-01, 6.3370e-01, 6.2830e-01, 6.2290e-01, 6.1730e-01, 6.1160e-01, 6.0570e-01, 5.9970e-01, 5.9370e-01, 5.8800e-01, 5.8240e-01, 5.7720e-01, 5.7230e-01, 5.6740e-01, 5.6250e-01, 5.5740e-01, 5.5210e-01, 5.4650e-01, 5.4090e-01, 5.3530e-01, 5.3000e-01, 5.2500e-01, 5.2030e-01, 5.1600e-01, 5.1170e-01, 5.0740e-01, 5.0280e-01, 4.9800e-01, 4.9290e-01, 4.8760e-01, 4.8240e-01, 4.7740e-01, 4.7270e-01, 4.6840e-01, 4.6440e-01, 4.6070e-01, 4.5700e-01, 4.5320e-01, 4.4910e-01, 4.4470e-01, 4.4000e-01, 4.3510e-01, 4.3030e-01, 4.2570e-01, 4.2140e-01, 4.1750e-01, 4.1400e-01, 4.1080e-01, 4.0770e-01, 4.0460e-01, 4.0120e-01, 3.9740e-01, 3.9330e-01, 3.8880e-01, 3.8440e-01, 3.8000e-01, 3.7580e-01, 3.7200e-01, 3.6870e-01, 3.6570e-01}); + feg = Vctr_cpu({4.8630e+00, 4.8186e+00, 4.6895e+00, 4.4877e+00, 4.2299e+00, 3.9353e+00, 3.6220e+00, 3.3056e+00, 2.9979e+00, 2.7072e+00, 2.4384e+00, 2.1939e+00, 1.9743e+00, 1.7787e+00, 1.6056e+00, 1.4531e+00, 1.3191e+00, 1.2016e+00, 1.0984e+00, 1.0078e+00, 9.2810e-01, 8.5790e-01, 7.9580e-01, 7.4070e-01, 6.9170e-01, 6.4800e-01, 6.0870e-01, 5.7340e-01, 5.4140e-01, 5.1240e-01, 4.8600e-01, 4.6180e-01, 4.3960e-01, 4.1910e-01, 4.0010e-01, 3.8260e-01, 3.6620e-01, 3.5090e-01, 3.3660e-01, 3.2320e-01, 3.1060e-01, 2.9870e-01, 2.8750e-01, 2.7690e-01, 2.6690e-01, 2.5730e-01, 2.4830e-01, 2.3970e-01, 2.3150e-01, 2.2370e-01, 2.1630e-01, 2.0920e-01, 2.0250e-01, 1.9600e-01, 1.8980e-01, 1.8390e-01, 1.7820e-01, 1.7280e-01, 1.6760e-01, 1.6260e-01, 1.5780e-01, 1.5320e-01, 1.4880e-01, 1.4460e-01, 1.4050e-01, 1.3660e-01, 1.3290e-01, 1.2930e-01, 1.2580e-01, 1.2240e-01, 1.1920e-01, 1.1610e-01, 1.1310e-01, 1.1020e-01, 1.0750e-01, 1.0480e-01, 1.0220e-01, 9.9700e-02, 9.7300e-02, 9.5000e-02, 9.2700e-02, 9.0600e-02, 8.8500e-02, 8.6400e-02, 8.4500e-02, 8.2600e-02, 8.0800e-02, 7.9000e-02, 7.7300e-02, 7.5600e-02, 7.4000e-02, 7.2400e-02, 7.0900e-02, 6.9500e-02, 6.8000e-02, 6.6700e-02, 6.5300e-02, 6.4000e-02, 6.2800e-02, 6.1500e-02, 6.0300e-02, 5.9200e-02, 5.8100e-02, 5.7000e-02, 5.5900e-02, 5.4900e-02, 5.3900e-02, 5.2900e-02, 5.2000e-02, 5.1100e-02, 5.0200e-02, 4.9300e-02, 4.8400e-02, 4.7600e-02, 4.6800e-02, 4.6000e-02, 4.5200e-02, 4.4500e-02, 4.3800e-02, 4.3100e-02, 4.2400e-02, 4.1700e-02, 4.1000e-02, 4.0400e-02, 3.9800e-02, 3.9100e-02, 3.8500e-02, 3.8000e-02, 3.7400e-02, 3.6800e-02, 3.6300e-02, 3.5700e-02, 3.5200e-02, 3.4700e-02, 3.4200e-02, 3.3700e-02, 3.3200e-02, 3.2800e-02, 3.2300e-02, 3.1900e-02, 3.1400e-02, 3.1000e-02, 3.0600e-02, 3.0200e-02, 2.9800e-02, 2.9400e-02, 2.9000e-02, 2.8600e-02, 2.8200e-02, 2.7900e-02, 2.7500e-02, 2.7100e-02, 2.6800e-02, 2.6500e-02, 2.6100e-02, 2.5800e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3100e-02, 2.2900e-02, 2.2600e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9500e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.8000e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1100e-02}); + } + break; + case 18: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.8000e+01, 1.7881e+01, 1.7536e+01, 1.6993e+01, 1.6298e+01, 1.5499e+01, 1.4647e+01, 1.3785e+01, 1.2949e+01, 1.2162e+01, 1.1440e+01, 1.0791e+01, 1.0216e+01, 9.7112e+00, 9.2716e+00, 8.8898e+00, 8.5575e+00, 8.2671e+00, 8.0109e+00, 7.7823e+00, 7.5753e+00, 7.3849e+00, 7.2068e+00, 7.0377e+00, 6.8749e+00, 6.7162e+00, 6.5601e+00, 6.4056e+00, 6.2519e+00, 6.0985e+00, 5.9452e+00, 5.7921e+00, 5.6393e+00, 5.4869e+00, 5.3352e+00, 5.1846e+00, 5.0355e+00, 4.8880e+00, 4.7427e+00, 4.5998e+00, 4.4596e+00, 4.3224e+00, 4.1884e+00, 4.0578e+00, 3.9309e+00, 3.8076e+00, 3.6882e+00, 3.5728e+00, 3.4613e+00, 3.3538e+00, 3.2504e+00, 3.1510e+00, 3.0556e+00, 2.9640e+00, 2.8764e+00, 2.7925e+00, 2.7123e+00, 2.6358e+00, 2.5627e+00, 2.4931e+00, 2.4267e+00, 2.3635e+00, 2.3034e+00, 2.2462e+00, 2.1918e+00, 2.1401e+00, 2.0910e+00, 2.0443e+00, 2.0000e+00, 1.9580e+00, 1.9180e+00, 1.8801e+00, 1.8441e+00, 1.8099e+00, 1.7775e+00, 1.7467e+00, 1.7174e+00, 1.6895e+00, 1.6630e+00, 1.6378e+00, 1.6139e+00, 1.5910e+00, 1.5693e+00, 1.5485e+00, 1.5287e+00, 1.5098e+00, 1.4917e+00, 1.4744e+00, 1.4578e+00, 1.4419e+00, 1.4266e+00, 1.4120e+00, 1.3978e+00, 1.3842e+00, 1.3711e+00, 1.3584e+00, 1.3462e+00, 1.3343e+00, 1.3228e+00, 1.3116e+00, 1.3007e+00, 1.2902e+00, 1.2798e+00, 1.2698e+00, 1.2599e+00, 1.2503e+00, 1.2409e+00, 1.2316e+00, 1.2225e+00, 1.2136e+00, 1.2048e+00, 1.1962e+00, 1.1876e+00, 1.1792e+00, 1.1709e+00, 1.1626e+00, 1.1545e+00, 1.1465e+00, 1.1385e+00, 1.1306e+00, 1.1227e+00, 1.1149e+00, 1.1072e+00, 1.0995e+00, 1.0919e+00, 1.0843e+00, 1.0768e+00, 1.0692e+00, 1.0617e+00, 1.0543e+00, 1.0469e+00, 1.0395e+00, 1.0322e+00, 1.0249e+00, 1.0175e+00, 1.0102e+00, 1.0030e+00, 9.9570e-01, 9.8860e-01, 9.8150e-01, 9.7430e-01, 9.6720e-01, 9.6000e-01, 9.5290e-01, 9.4580e-01, 9.3880e-01, 9.3180e-01, 9.2490e-01, 9.1800e-01, 9.1100e-01, 9.0400e-01, 8.9710e-01, 8.9010e-01, 8.8330e-01, 8.7650e-01, 8.6980e-01, 8.6310e-01, 8.5640e-01, 8.4970e-01, 8.4290e-01, 8.3610e-01, 8.2940e-01, 8.2280e-01, 8.1630e-01, 8.0990e-01, 8.0350e-01, 7.9710e-01, 7.9060e-01, 7.8400e-01, 7.7740e-01, 7.7100e-01, 7.6470e-01, 7.5850e-01, 7.5240e-01, 7.4640e-01, 7.4030e-01, 7.3420e-01, 7.2790e-01, 7.2160e-01, 7.1530e-01, 7.0920e-01, 7.0330e-01, 6.9750e-01, 6.9190e-01, 6.8630e-01, 6.8060e-01, 6.7480e-01, 6.6880e-01, 6.6280e-01, 6.5690e-01, 6.5100e-01, 6.4540e-01, 6.4000e-01, 6.3480e-01, 6.2970e-01, 6.2450e-01, 6.1920e-01, 6.1370e-01, 6.0810e-01, 6.0250e-01, 5.9690e-01, 5.9140e-01, 5.8630e-01, 5.8140e-01, 5.7670e-01, 5.7200e-01, 5.6740e-01, 5.6260e-01, 5.5750e-01, 5.5230e-01, 5.4700e-01, 5.4170e-01, 5.3660e-01, 5.3170e-01, 5.2720e-01, 5.2290e-01, 5.1880e-01, 5.1470e-01, 5.1050e-01, 5.0610e-01, 5.0150e-01, 4.9670e-01, 4.9170e-01, 4.8680e-01, 4.8200e-01, 4.7760e-01, 4.7340e-01, 4.6960e-01, 4.6600e-01, 4.6250e-01, 4.5890e-01, 4.5510e-01, 4.5110e-01, 4.4670e-01, 4.4220e-01, 4.3760e-01, 4.3310e-01, 4.2880e-01, 4.2480e-01, 4.2110e-01, 4.1780e-01}); + feg = Vctr_cpu({4.5818e+00, 4.5468e+00, 4.4447e+00, 4.2833e+00, 4.0743e+00, 3.8309e+00, 3.5667e+00, 3.2938e+00, 3.0224e+00, 2.7601e+00, 2.5120e+00, 2.2815e+00, 2.0701e+00, 1.8782e+00, 1.7053e+00, 1.5505e+00, 1.4125e+00, 1.2897e+00, 1.1806e+00, 1.0839e+00, 9.9800e-01, 9.2180e-01, 8.5400e-01, 7.9360e-01, 7.3960e-01, 6.9140e-01, 6.4800e-01, 6.0900e-01, 5.7380e-01, 5.4190e-01, 5.1290e-01, 4.8650e-01, 4.6220e-01, 4.4000e-01, 4.1950e-01, 4.0060e-01, 3.8310e-01, 3.6680e-01, 3.5160e-01, 3.3740e-01, 3.2410e-01, 3.1160e-01, 2.9980e-01, 2.8880e-01, 2.7830e-01, 2.6840e-01, 2.5900e-01, 2.5010e-01, 2.4160e-01, 2.3360e-01, 2.2590e-01, 2.1860e-01, 2.1160e-01, 2.0500e-01, 1.9860e-01, 1.9250e-01, 1.8670e-01, 1.8110e-01, 1.7570e-01, 1.7060e-01, 1.6570e-01, 1.6090e-01, 1.5640e-01, 1.5200e-01, 1.4780e-01, 1.4370e-01, 1.3990e-01, 1.3610e-01, 1.3250e-01, 1.2900e-01, 1.2570e-01, 1.2250e-01, 1.1930e-01, 1.1630e-01, 1.1340e-01, 1.1060e-01, 1.0800e-01, 1.0530e-01, 1.0280e-01, 1.0040e-01, 9.8000e-02, 9.5800e-02, 9.3600e-02, 9.1400e-02, 8.9400e-02, 8.7400e-02, 8.5500e-02, 8.3600e-02, 8.1800e-02, 8.0000e-02, 7.8400e-02, 7.6700e-02, 7.5100e-02, 7.3600e-02, 7.2100e-02, 7.0600e-02, 6.9200e-02, 6.7800e-02, 6.6500e-02, 6.5200e-02, 6.3900e-02, 6.2700e-02, 6.1500e-02, 6.0400e-02, 5.9300e-02, 5.8200e-02, 5.7100e-02, 5.6100e-02, 5.5100e-02, 5.4100e-02, 5.3200e-02, 5.2200e-02, 5.1300e-02, 5.0400e-02, 4.9600e-02, 4.8800e-02, 4.7900e-02, 4.7100e-02, 4.6400e-02, 4.5600e-02, 4.4900e-02, 4.4200e-02, 4.3500e-02, 4.2800e-02, 4.2100e-02, 4.1500e-02, 4.0800e-02, 4.0200e-02, 3.9600e-02, 3.9000e-02, 3.8400e-02, 3.7800e-02, 3.7300e-02, 3.6700e-02, 3.6200e-02, 3.5700e-02, 3.5200e-02, 3.4700e-02, 3.4200e-02, 3.3700e-02, 3.3300e-02, 3.2800e-02, 3.2400e-02, 3.1900e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9500e-02, 2.9100e-02, 2.8700e-02, 2.8400e-02, 2.8000e-02, 2.7600e-02, 2.7300e-02, 2.7000e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5400e-02, 2.5100e-02, 2.4800e-02, 2.4500e-02, 2.4200e-02, 2.3900e-02, 2.3600e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2600e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7200e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6300e-02, 1.6200e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3100e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02}); + } + break; + case 19: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.9000e+01, 1.8776e+01, 1.8206e+01, 1.7482e+01, 1.6733e+01, 1.5990e+01, 1.5243e+01, 1.4486e+01, 1.3728e+01, 1.2983e+01, 1.2268e+01, 1.1596e+01, 1.0976e+01, 1.0413e+01, 9.9076e+00, 9.4582e+00, 9.0611e+00, 8.7112e+00, 8.4030e+00, 8.1306e+00, 7.8885e+00, 7.6713e+00, 7.4744e+00, 7.2935e+00, 7.1251e+00, 6.9661e+00, 6.8140e+00, 6.6668e+00, 6.5229e+00, 6.3812e+00, 6.2408e+00, 6.1011e+00, 5.9617e+00, 5.8225e+00, 5.6833e+00, 5.5443e+00, 5.4056e+00, 5.2675e+00, 5.1300e+00, 4.9936e+00, 4.8585e+00, 4.7249e+00, 4.5932e+00, 4.4636e+00, 4.3363e+00, 4.2116e+00, 4.0895e+00, 3.9704e+00, 3.8543e+00, 3.7414e+00, 3.6318e+00, 3.5255e+00, 3.4225e+00, 3.3231e+00, 3.2270e+00, 3.1343e+00, 3.0451e+00, 2.9593e+00, 2.8768e+00, 2.7976e+00, 2.7217e+00, 2.6489e+00, 2.5791e+00, 2.5124e+00, 2.4487e+00, 2.3877e+00, 2.3294e+00, 2.2739e+00, 2.2209e+00, 2.1702e+00, 2.1218e+00, 2.0760e+00, 2.0323e+00, 1.9904e+00, 1.9505e+00, 1.9127e+00, 1.8769e+00, 1.8424e+00, 1.8094e+00, 1.7782e+00, 1.7489e+00, 1.7207e+00, 1.6934e+00, 1.6674e+00, 1.6431e+00, 1.6200e+00, 1.5977e+00, 1.5759e+00, 1.5553e+00, 1.5360e+00, 1.5178e+00, 1.5000e+00, 1.4823e+00, 1.4655e+00, 1.4500e+00, 1.4353e+00, 1.4210e+00, 1.4066e+00, 1.3925e+00, 1.3793e+00, 1.3672e+00, 1.3555e+00, 1.3437e+00, 1.3317e+00, 1.3201e+00, 1.3094e+00, 1.2994e+00, 1.2897e+00, 1.2798e+00, 1.2695e+00, 1.2594e+00, 1.2501e+00, 1.2415e+00, 1.2332e+00, 1.2246e+00, 1.2156e+00, 1.2064e+00, 1.1979e+00, 1.1900e+00, 1.1824e+00, 1.1749e+00, 1.1671e+00, 1.1587e+00, 1.1503e+00, 1.1426e+00, 1.1354e+00, 1.1284e+00, 1.1215e+00, 1.1142e+00, 1.1063e+00, 1.0983e+00, 1.0909e+00, 1.0840e+00, 1.0773e+00, 1.0707e+00, 1.0640e+00, 1.0568e+00, 1.0490e+00, 1.0415e+00, 1.0346e+00, 1.0280e+00, 1.0215e+00, 1.0151e+00, 1.0086e+00, 1.0016e+00, 9.9400e-01, 9.8670e-01, 9.8000e-01, 9.7360e-01, 9.6710e-01, 9.6080e-01, 9.5460e-01, 9.4810e-01, 9.4090e-01, 9.3350e-01, 9.2670e-01, 9.2040e-01, 9.1420e-01, 9.0780e-01, 9.0160e-01, 8.9570e-01, 8.8930e-01, 8.8220e-01, 8.7500e-01, 8.6840e-01, 8.6240e-01, 8.5630e-01, 8.5000e-01, 8.4390e-01, 8.3820e-01, 8.3240e-01, 8.2580e-01, 8.1870e-01, 8.1190e-01, 8.0590e-01, 8.0030e-01, 7.9440e-01, 7.8820e-01, 7.8240e-01, 7.7690e-01, 7.7140e-01, 7.6520e-01, 7.5830e-01, 7.5170e-01, 7.4590e-01, 7.4060e-01, 7.3520e-01, 7.2930e-01, 7.2350e-01, 7.1820e-01, 7.1320e-01, 7.0770e-01, 7.0150e-01, 6.9490e-01, 6.8880e-01, 6.8360e-01, 6.7870e-01, 6.7350e-01, 6.6800e-01, 6.6250e-01, 6.5750e-01, 6.5290e-01, 6.4800e-01, 6.4230e-01, 6.3600e-01, 6.3000e-01, 6.2480e-01, 6.2040e-01, 6.1580e-01, 6.1080e-01, 6.0560e-01, 6.0060e-01, 5.9620e-01, 5.9200e-01, 5.8740e-01, 5.8200e-01, 5.7610e-01, 5.7040e-01, 5.6560e-01, 5.6160e-01, 5.5750e-01, 5.5310e-01, 5.4830e-01, 5.4360e-01, 5.3950e-01, 5.3570e-01, 5.3180e-01, 5.2730e-01, 5.2200e-01, 5.1640e-01, 5.1130e-01, 5.0720e-01, 5.0370e-01, 5.0000e-01, 4.9600e-01, 4.9170e-01, 4.8750e-01, 4.8380e-01, 4.8050e-01, 4.7710e-01, 4.7310e-01}); + feg = Vctr_cpu({8.9440e+00, 8.5626e+00, 7.6043e+00, 6.4578e+00, 5.4248e+00, 4.6108e+00, 3.9968e+00, 3.5277e+00, 3.1545e+00, 2.8445e+00, 2.5779e+00, 2.3432e+00, 2.1338e+00, 1.9457e+00, 1.7764e+00, 1.6240e+00, 1.4867e+00, 1.3633e+00, 1.2525e+00, 1.1530e+00, 1.0638e+00, 9.8370e-01, 9.1190e-01, 8.4740e-01, 7.8950e-01, 7.3730e-01, 6.9030e-01, 6.4790e-01, 6.0940e-01, 5.7460e-01, 5.4290e-01, 5.1400e-01, 4.8760e-01, 4.6340e-01, 4.4110e-01, 4.2060e-01, 4.0170e-01, 3.8410e-01, 3.6780e-01, 3.5260e-01, 3.3850e-01, 3.2520e-01, 3.1270e-01, 3.0110e-01, 2.9000e-01, 2.7970e-01, 2.6980e-01, 2.6050e-01, 2.5170e-01, 2.4340e-01, 2.3540e-01, 2.2780e-01, 2.2060e-01, 2.1370e-01, 2.0710e-01, 2.0080e-01, 1.9480e-01, 1.8910e-01, 1.8350e-01, 1.7820e-01, 1.7320e-01, 1.6830e-01, 1.6360e-01, 1.5910e-01, 1.5470e-01, 1.5060e-01, 1.4660e-01, 1.4270e-01, 1.3900e-01, 1.3540e-01, 1.3190e-01, 1.2860e-01, 1.2530e-01, 1.2220e-01, 1.1920e-01, 1.1630e-01, 1.1350e-01, 1.1080e-01, 1.0820e-01, 1.0570e-01, 1.0320e-01, 1.0090e-01, 9.8600e-02, 9.6300e-02, 9.4200e-02, 9.2100e-02, 9.0100e-02, 8.8200e-02, 8.6300e-02, 8.4400e-02, 8.2600e-02, 8.0900e-02, 7.9300e-02, 7.7600e-02, 7.6100e-02, 7.4500e-02, 7.3000e-02, 7.1600e-02, 7.0200e-02, 6.8800e-02, 6.7500e-02, 6.6200e-02, 6.5000e-02, 6.3800e-02, 6.2600e-02, 6.1400e-02, 6.0300e-02, 5.9200e-02, 5.8200e-02, 5.7100e-02, 5.6100e-02, 5.5200e-02, 5.4200e-02, 5.3300e-02, 5.2400e-02, 5.1500e-02, 5.0600e-02, 4.9800e-02, 4.9000e-02, 4.8200e-02, 4.7400e-02, 4.6600e-02, 4.5900e-02, 4.5200e-02, 4.4500e-02, 4.3800e-02, 4.3100e-02, 4.2400e-02, 4.1800e-02, 4.1200e-02, 4.0600e-02, 4.0000e-02, 3.9400e-02, 3.8800e-02, 3.8200e-02, 3.7700e-02, 3.7100e-02, 3.6600e-02, 3.6100e-02, 3.5600e-02, 3.5100e-02, 3.4600e-02, 3.4200e-02, 3.3700e-02, 3.3200e-02, 3.2800e-02, 3.2400e-02, 3.1900e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9500e-02, 2.9200e-02, 2.8800e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6400e-02, 2.6100e-02, 2.5800e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3800e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2500e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6600e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5800e-02, 1.5700e-02, 1.5500e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02}); + } + break; + case 20: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.0000e+01, 1.9750e+01, 1.9091e+01, 1.8226e+01, 1.7331e+01, 1.6493e+01, 1.5723e+01, 1.5000e+01, 1.4304e+01, 1.3625e+01, 1.2961e+01, 1.2319e+01, 1.1705e+01, 1.1127e+01, 1.0590e+01, 1.0097e+01, 9.6494e+00, 9.2461e+00, 8.8848e+00, 8.5623e+00, 8.2747e+00, 8.0180e+00, 7.7878e+00, 7.5803e+00, 7.3916e+00, 7.2182e+00, 7.0572e+00, 6.9058e+00, 6.7619e+00, 6.6236e+00, 6.4893e+00, 6.3577e+00, 6.2281e+00, 6.0996e+00, 5.9718e+00, 5.8443e+00, 5.7170e+00, 5.5898e+00, 5.4626e+00, 5.3357e+00, 5.2091e+00, 5.0830e+00, 4.9576e+00, 4.8332e+00, 4.7099e+00, 4.5881e+00, 4.4678e+00, 4.3494e+00, 4.2329e+00, 4.1187e+00, 4.0068e+00, 3.8973e+00, 3.7905e+00, 3.6863e+00, 3.5850e+00, 3.4864e+00, 3.3908e+00, 3.2982e+00, 3.2084e+00, 3.1217e+00, 3.0379e+00, 2.9571e+00, 2.8791e+00, 2.8041e+00, 2.7319e+00, 2.6624e+00, 2.5957e+00, 2.5317e+00, 2.4703e+00, 2.4114e+00, 2.3549e+00, 2.3009e+00, 2.2492e+00, 2.1996e+00, 2.1521e+00, 2.1069e+00, 2.0638e+00, 2.0223e+00, 1.9826e+00, 1.9449e+00, 1.9090e+00, 1.8746e+00, 1.8415e+00, 1.8099e+00, 1.7800e+00, 1.7517e+00, 1.7242e+00, 1.6977e+00, 1.6724e+00, 1.6488e+00, 1.6263e+00, 1.6044e+00, 1.5830e+00, 1.5626e+00, 1.5436e+00, 1.5257e+00, 1.5082e+00, 1.4908e+00, 1.4740e+00, 1.4583e+00, 1.4437e+00, 1.4298e+00, 1.4158e+00, 1.4017e+00, 1.3881e+00, 1.3756e+00, 1.3641e+00, 1.3530e+00, 1.3415e+00, 1.3298e+00, 1.3183e+00, 1.3079e+00, 1.2984e+00, 1.2893e+00, 1.2799e+00, 1.2699e+00, 1.2598e+00, 1.2504e+00, 1.2420e+00, 1.2343e+00, 1.2266e+00, 1.2182e+00, 1.2092e+00, 1.2002e+00, 1.1921e+00, 1.1848e+00, 1.1780e+00, 1.1712e+00, 1.1638e+00, 1.1555e+00, 1.1472e+00, 1.1394e+00, 1.1326e+00, 1.1263e+00, 1.1202e+00, 1.1137e+00, 1.1064e+00, 1.0984e+00, 1.0906e+00, 1.0836e+00, 1.0773e+00, 1.0715e+00, 1.0658e+00, 1.0596e+00, 1.0525e+00, 1.0447e+00, 1.0371e+00, 1.0303e+00, 1.0243e+00, 1.0186e+00, 1.0131e+00, 1.0073e+00, 1.0009e+00, 9.9350e-01, 9.8590e-01, 9.7880e-01, 9.7260e-01, 9.6690e-01, 9.6140e-01, 9.5600e-01, 9.5040e-01, 9.4400e-01, 9.3680e-01, 9.2930e-01, 9.2240e-01, 9.1640e-01, 9.1070e-01, 9.0520e-01, 8.9990e-01, 8.9460e-01, 8.8890e-01, 8.8220e-01, 8.7480e-01, 8.6770e-01, 8.6150e-01, 8.5590e-01, 8.5040e-01, 8.4500e-01, 8.3980e-01, 8.3470e-01, 8.2930e-01, 8.2280e-01, 8.1560e-01, 8.0860e-01, 8.0260e-01, 7.9720e-01, 7.9200e-01, 7.8660e-01, 7.8140e-01, 7.7650e-01, 7.7170e-01, 7.6610e-01, 7.5960e-01, 7.5260e-01, 7.4610e-01, 7.4060e-01, 7.3570e-01, 7.3080e-01, 7.2550e-01, 7.2040e-01, 7.1570e-01, 7.1130e-01, 7.0630e-01, 7.0030e-01, 6.9360e-01, 6.8710e-01, 6.8170e-01, 6.7710e-01, 6.7260e-01, 6.6770e-01, 6.6260e-01, 6.5780e-01, 6.5360e-01, 6.4960e-01, 6.4480e-01, 6.3910e-01, 6.3260e-01, 6.2650e-01, 6.2150e-01, 6.1730e-01, 6.1330e-01, 6.0880e-01, 6.0390e-01, 5.9920e-01, 5.9520e-01, 5.9160e-01, 5.8770e-01, 5.8290e-01, 5.7720e-01, 5.7110e-01, 5.6560e-01, 5.6130e-01, 5.5780e-01, 5.5420e-01, 5.5000e-01, 5.4540e-01, 5.4090e-01, 5.3710e-01, 5.3390e-01, 5.3070e-01, 5.2660e-01}); + feg = Vctr_cpu({9.9065e+00, 9.5755e+00, 8.6998e+00, 7.5496e+00, 6.3881e+00, 5.3718e+00, 4.5497e+00, 3.9074e+00, 3.4080e+00, 3.0140e+00, 2.6955e+00, 2.4310e+00, 2.2059e+00, 2.0106e+00, 1.8385e+00, 1.6854e+00, 1.5483e+00, 1.4249e+00, 1.3137e+00, 1.2133e+00, 1.1225e+00, 1.0405e+00, 9.6620e-01, 8.9910e-01, 8.3820e-01, 7.8310e-01, 7.3320e-01, 6.8780e-01, 6.4660e-01, 6.0910e-01, 5.7490e-01, 5.4360e-01, 5.1500e-01, 4.8880e-01, 4.6470e-01, 4.4250e-01, 4.2200e-01, 4.0310e-01, 3.8550e-01, 3.6920e-01, 3.5400e-01, 3.3980e-01, 3.2650e-01, 3.1410e-01, 3.0240e-01, 2.9140e-01, 2.8110e-01, 2.7130e-01, 2.6210e-01, 2.5330e-01, 2.4500e-01, 2.3710e-01, 2.2960e-01, 2.2240e-01, 2.1560e-01, 2.0900e-01, 2.0280e-01, 1.9690e-01, 1.9110e-01, 1.8570e-01, 1.8040e-01, 1.7540e-01, 1.7060e-01, 1.6590e-01, 1.6140e-01, 1.5710e-01, 1.5300e-01, 1.4900e-01, 1.4520e-01, 1.4150e-01, 1.3790e-01, 1.3450e-01, 1.3110e-01, 1.2790e-01, 1.2480e-01, 1.2180e-01, 1.1890e-01, 1.1610e-01, 1.1340e-01, 1.1080e-01, 1.0820e-01, 1.0580e-01, 1.0340e-01, 1.0110e-01, 9.8900e-02, 9.6700e-02, 9.4600e-02, 9.2600e-02, 9.0600e-02, 8.8700e-02, 8.6900e-02, 8.5100e-02, 8.3300e-02, 8.1600e-02, 8.0000e-02, 7.8400e-02, 7.6800e-02, 7.5300e-02, 7.3900e-02, 7.2400e-02, 7.1100e-02, 6.9700e-02, 6.8400e-02, 6.7100e-02, 6.5900e-02, 6.4700e-02, 6.3500e-02, 6.2400e-02, 6.1300e-02, 6.0200e-02, 5.9100e-02, 5.8100e-02, 5.7100e-02, 5.6100e-02, 5.5200e-02, 5.4200e-02, 5.3300e-02, 5.2500e-02, 5.1600e-02, 5.0700e-02, 4.9900e-02, 4.9100e-02, 4.8300e-02, 4.7600e-02, 4.6800e-02, 4.6100e-02, 4.5400e-02, 4.4700e-02, 4.4000e-02, 4.3400e-02, 4.2700e-02, 4.2100e-02, 4.1500e-02, 4.0900e-02, 4.0300e-02, 3.9700e-02, 3.9100e-02, 3.8600e-02, 3.8000e-02, 3.7500e-02, 3.7000e-02, 3.6500e-02, 3.6000e-02, 3.5500e-02, 3.5000e-02, 3.4500e-02, 3.4100e-02, 3.3600e-02, 3.3200e-02, 3.2700e-02, 3.2300e-02, 3.1900e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9600e-02, 2.9200e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6800e-02, 2.6500e-02, 2.6200e-02, 2.5900e-02, 2.5600e-02, 2.5300e-02, 2.5000e-02, 2.4800e-02, 2.4500e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3400e-02, 2.3200e-02, 2.2900e-02, 2.2700e-02, 2.2400e-02, 2.2200e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6500e-02, 1.6300e-02, 1.6200e-02, 1.6000e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02}); + } + break; + case 21: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.1000e+01, 2.0765e+01, 2.0132e+01, 1.9274e+01, 1.8354e+01, 1.7467e+01, 1.6641e+01, 1.5867e+01, 1.5130e+01, 1.4419e+01, 1.3729e+01, 1.3061e+01, 1.2421e+01, 1.1813e+01, 1.1243e+01, 1.0713e+01, 1.0225e+01, 9.7804e+00, 9.3773e+00, 9.0138e+00, 8.6872e+00, 8.3944e+00, 8.1316e+00, 7.8955e+00, 7.6824e+00, 7.4889e+00, 7.3120e+00, 7.1487e+00, 6.9967e+00, 6.8535e+00, 6.7174e+00, 6.5867e+00, 6.4601e+00, 6.3364e+00, 6.2147e+00, 6.0945e+00, 5.9752e+00, 5.8564e+00, 5.7379e+00, 5.6195e+00, 5.5013e+00, 5.3832e+00, 5.2653e+00, 5.1477e+00, 5.0305e+00, 4.9140e+00, 4.7983e+00, 4.6836e+00, 4.5700e+00, 4.4577e+00, 4.3470e+00, 4.2379e+00, 4.1307e+00, 4.0254e+00, 3.9222e+00, 3.8212e+00, 3.7225e+00, 3.6261e+00, 3.5322e+00, 3.4408e+00, 3.3519e+00, 3.2656e+00, 3.1819e+00, 3.1008e+00, 3.0222e+00, 2.9462e+00, 2.8728e+00, 2.8020e+00, 2.7336e+00, 2.6677e+00, 2.6042e+00, 2.5431e+00, 2.4843e+00, 2.4277e+00, 2.3734e+00, 2.3213e+00, 2.2712e+00, 2.2230e+00, 2.1769e+00, 2.1328e+00, 2.0904e+00, 2.0496e+00, 2.0106e+00, 1.9734e+00, 1.9378e+00, 1.9036e+00, 1.8706e+00, 1.8392e+00, 1.8093e+00, 1.7807e+00, 1.7531e+00, 1.7264e+00, 1.7010e+00, 1.6770e+00, 1.6540e+00, 1.6318e+00, 1.6101e+00, 1.5894e+00, 1.5699e+00, 1.5514e+00, 1.5335e+00, 1.5159e+00, 1.4987e+00, 1.4825e+00, 1.4673e+00, 1.4529e+00, 1.4386e+00, 1.4244e+00, 1.4105e+00, 1.3974e+00, 1.3853e+00, 1.3738e+00, 1.3623e+00, 1.3506e+00, 1.3390e+00, 1.3279e+00, 1.3178e+00, 1.3084e+00, 1.2991e+00, 1.2894e+00, 1.2795e+00, 1.2697e+00, 1.2606e+00, 1.2524e+00, 1.2447e+00, 1.2368e+00, 1.2283e+00, 1.2196e+00, 1.2109e+00, 1.2029e+00, 1.1958e+00, 1.1892e+00, 1.1823e+00, 1.1749e+00, 1.1671e+00, 1.1590e+00, 1.1514e+00, 1.1447e+00, 1.1386e+00, 1.1326e+00, 1.1262e+00, 1.1192e+00, 1.1118e+00, 1.1043e+00, 1.0972e+00, 1.0910e+00, 1.0855e+00, 1.0800e+00, 1.0739e+00, 1.0674e+00, 1.0603e+00, 1.0530e+00, 1.0460e+00, 1.0398e+00, 1.0344e+00, 1.0293e+00, 1.0238e+00, 1.0177e+00, 1.0112e+00, 1.0043e+00, 9.9720e-01, 9.9050e-01, 9.8470e-01, 9.7960e-01, 9.7470e-01, 9.6930e-01, 9.6340e-01, 9.5710e-01, 9.5040e-01, 9.4350e-01, 9.3680e-01, 9.3080e-01, 9.2570e-01, 9.2100e-01, 9.1600e-01, 9.1040e-01, 9.0450e-01, 8.9830e-01, 8.9180e-01, 8.8500e-01, 8.7840e-01, 8.7270e-01, 8.6800e-01, 8.6350e-01, 8.5860e-01, 8.5320e-01, 8.4740e-01, 8.4150e-01, 8.3530e-01, 8.2880e-01, 8.2230e-01, 8.1630e-01, 8.1140e-01, 8.0710e-01, 8.0270e-01, 7.9780e-01, 7.9230e-01, 7.8660e-01, 7.8100e-01, 7.7520e-01, 7.6890e-01, 7.6250e-01, 7.5680e-01, 7.5200e-01, 7.4800e-01, 7.4400e-01, 7.3930e-01, 7.3400e-01, 7.2860e-01, 7.2340e-01, 7.1810e-01, 7.1240e-01, 7.0620e-01, 7.0020e-01, 6.9510e-01, 6.9090e-01, 6.8730e-01, 6.8350e-01, 6.7890e-01, 6.7380e-01, 6.6860e-01, 6.6370e-01, 6.5890e-01, 6.5370e-01, 6.4800e-01, 6.4210e-01, 6.3690e-01, 6.3270e-01, 6.2940e-01, 6.2620e-01, 6.2230e-01, 6.1760e-01, 6.1260e-01, 6.0790e-01, 6.0350e-01, 5.9910e-01, 5.9420e-01, 5.8880e-01, 5.8330e-01, 5.7830e-01, 5.7450e-01}); + feg = Vctr_cpu({9.2799e+00, 9.0161e+00, 8.3058e+00, 7.3430e+00, 6.3323e+00, 5.4114e+00, 4.6371e+00, 4.0114e+00, 3.5121e+00, 3.1113e+00, 2.7845e+00, 2.5125e+00, 2.2814e+00, 2.0816e+00, 1.9063e+00, 1.7508e+00, 1.6117e+00, 1.4866e+00, 1.3737e+00, 1.2715e+00, 1.1788e+00, 1.0946e+00, 1.0181e+00, 9.4860e-01, 8.8540e-01, 8.2780e-01, 7.7540e-01, 7.2760e-01, 6.8400e-01, 6.4410e-01, 6.0770e-01, 5.7430e-01, 5.4370e-01, 5.1560e-01, 4.8980e-01, 4.6590e-01, 4.4390e-01, 4.2360e-01, 4.0470e-01, 3.8720e-01, 3.7090e-01, 3.5580e-01, 3.4160e-01, 3.2830e-01, 3.1590e-01, 3.0420e-01, 2.9320e-01, 2.8290e-01, 2.7310e-01, 2.6380e-01, 2.5510e-01, 2.4680e-01, 2.3890e-01, 2.3140e-01, 2.2430e-01, 2.1750e-01, 2.1100e-01, 2.0480e-01, 1.9880e-01, 1.9320e-01, 1.8770e-01, 1.8250e-01, 1.7750e-01, 1.7270e-01, 1.6810e-01, 1.6360e-01, 1.5940e-01, 1.5520e-01, 1.5130e-01, 1.4750e-01, 1.4380e-01, 1.4020e-01, 1.3680e-01, 1.3350e-01, 1.3030e-01, 1.2720e-01, 1.2420e-01, 1.2130e-01, 1.1850e-01, 1.1580e-01, 1.1310e-01, 1.1060e-01, 1.0810e-01, 1.0580e-01, 1.0350e-01, 1.0120e-01, 9.9000e-02, 9.6900e-02, 9.4900e-02, 9.2900e-02, 9.1000e-02, 8.9100e-02, 8.7300e-02, 8.5600e-02, 8.3800e-02, 8.2200e-02, 8.0600e-02, 7.9000e-02, 7.7500e-02, 7.6000e-02, 7.4500e-02, 7.3100e-02, 7.1800e-02, 7.0400e-02, 6.9200e-02, 6.7900e-02, 6.6700e-02, 6.5500e-02, 6.4300e-02, 6.3200e-02, 6.2100e-02, 6.1000e-02, 5.9900e-02, 5.8900e-02, 5.7900e-02, 5.7000e-02, 5.6000e-02, 5.5100e-02, 5.4200e-02, 5.3300e-02, 5.2400e-02, 5.1600e-02, 5.0800e-02, 5.0000e-02, 4.9200e-02, 4.8400e-02, 4.7700e-02, 4.7000e-02, 4.6300e-02, 4.5600e-02, 4.4900e-02, 4.4200e-02, 4.3600e-02, 4.2900e-02, 4.2300e-02, 4.1700e-02, 4.1100e-02, 4.0500e-02, 3.9900e-02, 3.9400e-02, 3.8800e-02, 3.8300e-02, 3.7800e-02, 3.7300e-02, 3.6800e-02, 3.6300e-02, 3.5800e-02, 3.5300e-02, 3.4800e-02, 3.4400e-02, 3.3900e-02, 3.3500e-02, 3.3100e-02, 3.2700e-02, 3.2200e-02, 3.1800e-02, 3.1400e-02, 3.1000e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9600e-02, 2.9200e-02, 2.8900e-02, 2.8500e-02, 2.8200e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5400e-02, 2.5100e-02, 2.4800e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3800e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7800e-02, 1.7600e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5700e-02, 1.5500e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.5000e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4500e-02, 1.4400e-02, 1.4300e-02, 1.4100e-02, 1.4000e-02, 1.3900e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02}); + } + break; + case 22: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.2000e+01, 2.1778e+01, 2.1173e+01, 2.0334e+01, 1.9409e+01, 1.8496e+01, 1.7631e+01, 1.6816e+01, 1.6039e+01, 1.5291e+01, 1.4568e+01, 1.3868e+01, 1.3195e+01, 1.2554e+01, 1.1947e+01, 1.1379e+01, 1.0851e+01, 1.0364e+01, 9.9193e+00, 9.5143e+00, 9.1474e+00, 8.8162e+00, 8.5178e+00, 8.2490e+00, 8.0066e+00, 7.7875e+00, 7.5887e+00, 7.4072e+00, 7.2405e+00, 7.0861e+00, 6.9419e+00, 6.8059e+00, 6.6765e+00, 6.5524e+00, 6.4323e+00, 6.3152e+00, 6.2003e+00, 6.0870e+00, 5.9748e+00, 5.8633e+00, 5.7523e+00, 5.6415e+00, 5.5309e+00, 5.4204e+00, 5.3101e+00, 5.1999e+00, 5.0902e+00, 4.9808e+00, 4.8719e+00, 4.7638e+00, 4.6565e+00, 4.5502e+00, 4.4450e+00, 4.3412e+00, 4.2387e+00, 4.1378e+00, 4.0385e+00, 3.9410e+00, 3.8454e+00, 3.7517e+00, 3.6602e+00, 3.5707e+00, 3.4833e+00, 3.3981e+00, 3.3152e+00, 3.2346e+00, 3.1562e+00, 3.0801e+00, 3.0063e+00, 2.9348e+00, 2.8655e+00, 2.7985e+00, 2.7337e+00, 2.6711e+00, 2.6106e+00, 2.5522e+00, 2.4960e+00, 2.4417e+00, 2.3895e+00, 2.3391e+00, 2.2907e+00, 2.2441e+00, 2.1993e+00, 2.1562e+00, 2.1147e+00, 2.0749e+00, 2.0368e+00, 2.0001e+00, 1.9647e+00, 1.9308e+00, 1.8983e+00, 1.8673e+00, 1.8374e+00, 1.8085e+00, 1.7807e+00, 1.7542e+00, 1.7290e+00, 1.7048e+00, 1.6812e+00, 1.6584e+00, 1.6367e+00, 1.6161e+00, 1.5964e+00, 1.5773e+00, 1.5586e+00, 1.5405e+00, 1.5233e+00, 1.5071e+00, 1.4917e+00, 1.4765e+00, 1.4614e+00, 1.4467e+00, 1.4329e+00, 1.4199e+00, 1.4076e+00, 1.3954e+00, 1.3831e+00, 1.3709e+00, 1.3593e+00, 1.3485e+00, 1.3384e+00, 1.3286e+00, 1.3186e+00, 1.3083e+00, 1.2982e+00, 1.2886e+00, 1.2798e+00, 1.2717e+00, 1.2635e+00, 1.2551e+00, 1.2463e+00, 1.2375e+00, 1.2291e+00, 1.2215e+00, 1.2145e+00, 1.2077e+00, 1.2005e+00, 1.1928e+00, 1.1849e+00, 1.1771e+00, 1.1699e+00, 1.1634e+00, 1.1575e+00, 1.1514e+00, 1.1448e+00, 1.1377e+00, 1.1304e+00, 1.1232e+00, 1.1165e+00, 1.1106e+00, 1.1052e+00, 1.0997e+00, 1.0937e+00, 1.0871e+00, 1.0802e+00, 1.0733e+00, 1.0667e+00, 1.0607e+00, 1.0555e+00, 1.0505e+00, 1.0452e+00, 1.0393e+00, 1.0329e+00, 1.0262e+00, 1.0195e+00, 1.0131e+00, 1.0074e+00, 1.0023e+00, 9.9770e-01, 9.9270e-01, 9.8710e-01, 9.8090e-01, 9.7440e-01, 9.6800e-01, 9.6160e-01, 9.5560e-01, 9.5030e-01, 9.4580e-01, 9.4130e-01, 9.3620e-01, 9.3050e-01, 9.2440e-01, 9.1810e-01, 9.1190e-01, 9.0570e-01, 8.9980e-01, 8.9460e-01, 8.9010e-01, 8.8590e-01, 8.8110e-01, 8.7570e-01, 8.6980e-01, 8.6370e-01, 8.5770e-01, 8.5170e-01, 8.4570e-01, 8.4010e-01, 8.3540e-01, 8.3130e-01, 8.2720e-01, 8.2250e-01, 8.1710e-01, 8.1130e-01, 8.0550e-01, 7.9980e-01, 7.9400e-01, 7.8810e-01, 7.8260e-01, 7.7780e-01, 7.7380e-01, 7.7000e-01, 7.6590e-01, 7.6090e-01, 7.5540e-01, 7.4970e-01, 7.4430e-01, 7.3900e-01, 7.3350e-01, 7.2780e-01, 7.2250e-01, 7.1800e-01, 7.1430e-01, 7.1090e-01, 7.0700e-01, 7.0230e-01, 6.9700e-01, 6.9160e-01, 6.8650e-01, 6.8160e-01, 6.7650e-01, 6.7120e-01, 6.6580e-01, 6.6110e-01, 6.5720e-01, 6.5400e-01, 6.5080e-01, 6.4710e-01, 6.4250e-01, 6.3730e-01, 6.3220e-01, 6.2750e-01}); + feg = Vctr_cpu({8.7360e+00, 8.5162e+00, 7.9179e+00, 7.0909e+00, 6.2005e+00, 5.3669e+00, 4.6472e+00, 4.0516e+00, 3.5667e+00, 3.1716e+00, 2.8461e+00, 2.5735e+00, 2.3414e+00, 2.1404e+00, 1.9641e+00, 1.8077e+00, 1.6678e+00, 1.5418e+00, 1.4278e+00, 1.3245e+00, 1.2304e+00, 1.1448e+00, 1.0667e+00, 9.9540e-01, 9.3030e-01, 8.7080e-01, 8.1640e-01, 7.6650e-01, 7.2090e-01, 6.7910e-01, 6.4070e-01, 6.0550e-01, 5.7300e-01, 5.4320e-01, 5.1570e-01, 4.9030e-01, 4.6680e-01, 4.4510e-01, 4.2500e-01, 4.0630e-01, 3.8890e-01, 3.7270e-01, 3.5750e-01, 3.4340e-01, 3.3010e-01, 3.1770e-01, 3.0600e-01, 2.9500e-01, 2.8470e-01, 2.7490e-01, 2.6570e-01, 2.5690e-01, 2.4860e-01, 2.4070e-01, 2.3320e-01, 2.2610e-01, 2.1930e-01, 2.1280e-01, 2.0670e-01, 2.0070e-01, 1.9510e-01, 1.8970e-01, 1.8450e-01, 1.7950e-01, 1.7470e-01, 1.7010e-01, 1.6570e-01, 1.6140e-01, 1.5730e-01, 1.5330e-01, 1.4950e-01, 1.4590e-01, 1.4230e-01, 1.3890e-01, 1.3560e-01, 1.3240e-01, 1.2930e-01, 1.2630e-01, 1.2340e-01, 1.2060e-01, 1.1790e-01, 1.1530e-01, 1.1280e-01, 1.1030e-01, 1.0790e-01, 1.0560e-01, 1.0340e-01, 1.0120e-01, 9.9100e-02, 9.7000e-02, 9.5000e-02, 9.3100e-02, 9.1200e-02, 8.9400e-02, 8.7600e-02, 8.5900e-02, 8.4200e-02, 8.2600e-02, 8.1000e-02, 7.9500e-02, 7.8000e-02, 7.6500e-02, 7.5100e-02, 7.3700e-02, 7.2400e-02, 7.1100e-02, 6.9800e-02, 6.8500e-02, 6.7300e-02, 6.6100e-02, 6.5000e-02, 6.3900e-02, 6.2800e-02, 6.1700e-02, 6.0700e-02, 5.9700e-02, 5.8700e-02, 5.7700e-02, 5.6800e-02, 5.5800e-02, 5.4900e-02, 5.4100e-02, 5.3200e-02, 5.2400e-02, 5.1600e-02, 5.0800e-02, 5.0000e-02, 4.9200e-02, 4.8500e-02, 4.7700e-02, 4.7000e-02, 4.6300e-02, 4.5600e-02, 4.5000e-02, 4.4300e-02, 4.3700e-02, 4.3100e-02, 4.2500e-02, 4.1900e-02, 4.1300e-02, 4.0700e-02, 4.0100e-02, 3.9600e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7500e-02, 3.7000e-02, 3.6500e-02, 3.6000e-02, 3.5600e-02, 3.5100e-02, 3.4700e-02, 3.4200e-02, 3.3800e-02, 3.3400e-02, 3.2900e-02, 3.2500e-02, 3.2100e-02, 3.1700e-02, 3.1300e-02, 3.1000e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9500e-02, 2.9200e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3900e-02, 2.3600e-02, 2.3400e-02, 2.3100e-02, 2.2900e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9300e-02, 1.9100e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7800e-02, 1.7600e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5800e-02, 1.5700e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5200e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4200e-02}); + } + break; + case 23: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.3000e+01, 2.2790e+01, 2.2211e+01, 2.1394e+01, 2.0474e+01, 1.9547e+01, 1.8654e+01, 1.7805e+01, 1.6994e+01, 1.6213e+01, 1.5457e+01, 1.4725e+01, 1.4019e+01, 1.3344e+01, 1.2701e+01, 1.2095e+01, 1.1527e+01, 1.1000e+01, 1.0514e+01, 1.0067e+01, 9.6591e+00, 9.2883e+00, 8.9519e+00, 8.6475e+00, 8.3724e+00, 8.1234e+00, 7.8979e+00, 7.6930e+00, 7.5062e+00, 7.3349e+00, 7.1768e+00, 7.0300e+00, 6.8925e+00, 6.7627e+00, 6.6392e+00, 6.5207e+00, 6.4062e+00, 6.2948e+00, 6.1856e+00, 6.0783e+00, 5.9722e+00, 5.8669e+00, 5.7622e+00, 5.6580e+00, 5.5539e+00, 5.4501e+00, 5.3464e+00, 5.2430e+00, 5.1397e+00, 5.0368e+00, 4.9342e+00, 4.8322e+00, 4.7308e+00, 4.6300e+00, 4.5302e+00, 4.4314e+00, 4.3336e+00, 4.2371e+00, 4.1419e+00, 4.0481e+00, 3.9558e+00, 3.8652e+00, 3.7763e+00, 3.6891e+00, 3.6037e+00, 3.5202e+00, 3.4387e+00, 3.3591e+00, 3.2814e+00, 3.2058e+00, 3.1322e+00, 3.0607e+00, 2.9911e+00, 2.9235e+00, 2.8581e+00, 2.7946e+00, 2.7330e+00, 2.6734e+00, 2.6158e+00, 2.5601e+00, 2.5062e+00, 2.4541e+00, 2.4038e+00, 2.3553e+00, 2.3085e+00, 2.2634e+00, 2.2198e+00, 2.1779e+00, 2.1375e+00, 2.0986e+00, 2.0612e+00, 2.0250e+00, 1.9902e+00, 1.9568e+00, 1.9248e+00, 1.8939e+00, 1.8641e+00, 1.8353e+00, 1.8077e+00, 1.7813e+00, 1.7560e+00, 1.7316e+00, 1.7079e+00, 1.6850e+00, 1.6631e+00, 1.6423e+00, 1.6223e+00, 1.6028e+00, 1.5838e+00, 1.5655e+00, 1.5480e+00, 1.5315e+00, 1.5156e+00, 1.5000e+00, 1.4847e+00, 1.4698e+00, 1.4556e+00, 1.4422e+00, 1.4295e+00, 1.4170e+00, 1.4045e+00, 1.3921e+00, 1.3802e+00, 1.3690e+00, 1.3585e+00, 1.3484e+00, 1.3383e+00, 1.3280e+00, 1.3178e+00, 1.3079e+00, 1.2986e+00, 1.2901e+00, 1.2819e+00, 1.2736e+00, 1.2649e+00, 1.2561e+00, 1.2475e+00, 1.2394e+00, 1.2320e+00, 1.2251e+00, 1.2182e+00, 1.2109e+00, 1.2033e+00, 1.1955e+00, 1.1879e+00, 1.1810e+00, 1.1746e+00, 1.1686e+00, 1.1626e+00, 1.1562e+00, 1.1492e+00, 1.1421e+00, 1.1351e+00, 1.1286e+00, 1.1227e+00, 1.1173e+00, 1.1120e+00, 1.1063e+00, 1.1001e+00, 1.0934e+00, 1.0867e+00, 1.0803e+00, 1.0743e+00, 1.0689e+00, 1.0640e+00, 1.0591e+00, 1.0537e+00, 1.0477e+00, 1.0413e+00, 1.0349e+00, 1.0287e+00, 1.0228e+00, 1.0175e+00, 1.0127e+00, 1.0082e+00, 1.0033e+00, 9.9780e-01, 9.9170e-01, 9.8540e-01, 9.7920e-01, 9.7330e-01, 9.6780e-01, 9.6270e-01, 9.5820e-01, 9.5380e-01, 9.4910e-01, 9.4380e-01, 9.3780e-01, 9.3160e-01, 9.2560e-01, 9.1980e-01, 9.1430e-01, 9.0920e-01, 9.0450e-01, 9.0040e-01, 8.9610e-01, 8.9130e-01, 8.8570e-01, 8.7970e-01, 8.7370e-01, 8.6800e-01, 8.6250e-01, 8.5710e-01, 8.5210e-01, 8.4760e-01, 8.4360e-01, 8.3970e-01, 8.3510e-01, 8.2970e-01, 8.2390e-01, 8.1800e-01, 8.1240e-01, 8.0710e-01, 8.0190e-01, 7.9680e-01, 7.9210e-01, 7.8800e-01, 7.8440e-01, 7.8050e-01, 7.7600e-01, 7.7060e-01, 7.6490e-01, 7.5920e-01, 7.5400e-01, 7.4900e-01, 7.4400e-01, 7.3900e-01, 7.3440e-01, 7.3030e-01, 7.2680e-01, 7.2340e-01, 7.1940e-01, 7.1460e-01, 7.0920e-01, 7.0360e-01, 6.9840e-01, 6.9360e-01, 6.8900e-01, 6.8430e-01, 6.7950e-01, 6.7510e-01}); + feg = Vctr_cpu({8.2468e+00, 8.0613e+00, 7.5516e+00, 6.8348e+00, 6.0460e+00, 5.2899e+00, 4.6228e+00, 4.0598e+00, 3.5937e+00, 3.2088e+00, 2.8887e+00, 2.6190e+00, 2.3883e+00, 2.1881e+00, 2.0122e+00, 1.8560e+00, 1.7161e+00, 1.5900e+00, 1.4758e+00, 1.3719e+00, 1.2772e+00, 1.1906e+00, 1.1115e+00, 1.0390e+00, 9.7250e-01, 9.1150e-01, 8.5550e-01, 8.0410e-01, 7.5680e-01, 7.1330e-01, 6.7330e-01, 6.3640e-01, 6.0240e-01, 5.7100e-01, 5.4200e-01, 5.1510e-01, 4.9030e-01, 4.6730e-01, 4.4590e-01, 4.2600e-01, 4.0750e-01, 3.9030e-01, 3.7420e-01, 3.5920e-01, 3.4510e-01, 3.3190e-01, 3.1950e-01, 3.0780e-01, 2.9680e-01, 2.8650e-01, 2.7670e-01, 2.6750e-01, 2.5870e-01, 2.5040e-01, 2.4260e-01, 2.3510e-01, 2.2790e-01, 2.2110e-01, 2.1470e-01, 2.0850e-01, 2.0260e-01, 1.9690e-01, 1.9150e-01, 1.8630e-01, 1.8130e-01, 1.7660e-01, 1.7200e-01, 1.6750e-01, 1.6330e-01, 1.5920e-01, 1.5530e-01, 1.5150e-01, 1.4780e-01, 1.4430e-01, 1.4090e-01, 1.3760e-01, 1.3440e-01, 1.3130e-01, 1.2830e-01, 1.2540e-01, 1.2260e-01, 1.1990e-01, 1.1730e-01, 1.1480e-01, 1.1230e-01, 1.0990e-01, 1.0760e-01, 1.0530e-01, 1.0320e-01, 1.0100e-01, 9.9000e-02, 9.7000e-02, 9.5100e-02, 9.3200e-02, 9.1300e-02, 8.9600e-02, 8.7800e-02, 8.6100e-02, 8.4500e-02, 8.2900e-02, 8.1400e-02, 7.9800e-02, 7.8400e-02, 7.6900e-02, 7.5500e-02, 7.4200e-02, 7.2900e-02, 7.1600e-02, 7.0300e-02, 6.9100e-02, 6.7900e-02, 6.6700e-02, 6.5600e-02, 6.4500e-02, 6.3400e-02, 6.2300e-02, 6.1300e-02, 6.0300e-02, 5.9300e-02, 5.8400e-02, 5.7400e-02, 5.6500e-02, 5.5600e-02, 5.4800e-02, 5.3900e-02, 5.3100e-02, 5.2200e-02, 5.1500e-02, 5.0700e-02, 4.9900e-02, 4.9200e-02, 4.8400e-02, 4.7700e-02, 4.7000e-02, 4.6400e-02, 4.5700e-02, 4.5000e-02, 4.4400e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2000e-02, 4.1400e-02, 4.0800e-02, 4.0300e-02, 3.9700e-02, 3.9200e-02, 3.8700e-02, 3.8200e-02, 3.7700e-02, 3.7200e-02, 3.6700e-02, 3.6200e-02, 3.5800e-02, 3.5300e-02, 3.4900e-02, 3.4400e-02, 3.4000e-02, 3.3600e-02, 3.3200e-02, 3.2800e-02, 3.2400e-02, 3.2000e-02, 3.1600e-02, 3.1200e-02, 3.0900e-02, 3.0500e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9100e-02, 2.8800e-02, 2.8500e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3400e-02, 2.3200e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8600e-02, 1.8400e-02, 1.8200e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5100e-02, 1.5000e-02, 1.4800e-02}); + } + break; + case 24: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.4000e+01, 2.3822e+01, 2.3328e+01, 2.2615e+01, 2.1784e+01, 2.0903e+01, 2.0011e+01, 1.9124e+01, 1.8248e+01, 1.7388e+01, 1.6550e+01, 1.5738e+01, 1.4957e+01, 1.4212e+01, 1.3507e+01, 1.2844e+01, 1.2224e+01, 1.1648e+01, 1.1116e+01, 1.0627e+01, 1.0179e+01, 9.7705e+00, 9.3988e+00, 9.0614e+00, 8.7555e+00, 8.4782e+00, 8.2268e+00, 7.9985e+00, 7.7908e+00, 7.6011e+00, 7.4271e+00, 7.2666e+00, 7.1178e+00, 6.9789e+00, 6.8483e+00, 6.7246e+00, 6.6066e+00, 6.4932e+00, 6.3836e+00, 6.2768e+00, 6.1723e+00, 6.0696e+00, 5.9682e+00, 5.8678e+00, 5.7681e+00, 5.6688e+00, 5.5700e+00, 5.4714e+00, 5.3730e+00, 5.2748e+00, 5.1769e+00, 5.0793e+00, 4.9820e+00, 4.8851e+00, 4.7888e+00, 4.6930e+00, 4.5980e+00, 4.5037e+00, 4.4103e+00, 4.3180e+00, 4.2267e+00, 4.1366e+00, 4.0478e+00, 3.9603e+00, 3.8743e+00, 3.7898e+00, 3.7068e+00, 3.6254e+00, 3.5457e+00, 3.4677e+00, 3.3914e+00, 3.3169e+00, 3.2442e+00, 3.1732e+00, 3.1041e+00, 3.0368e+00, 2.9713e+00, 2.9076e+00, 2.8457e+00, 2.7857e+00, 2.7274e+00, 2.6707e+00, 2.6159e+00, 2.5628e+00, 2.5114e+00, 2.4616e+00, 2.4133e+00, 2.3666e+00, 2.3217e+00, 2.2782e+00, 2.2361e+00, 2.1954e+00, 2.1561e+00, 2.1183e+00, 2.0819e+00, 2.0467e+00, 2.0125e+00, 1.9796e+00, 1.9481e+00, 1.9178e+00, 1.8885e+00, 1.8601e+00, 1.8326e+00, 1.8062e+00, 1.7810e+00, 1.7568e+00, 1.7333e+00, 1.7104e+00, 1.6882e+00, 1.6670e+00, 1.6469e+00, 1.6275e+00, 1.6087e+00, 1.5902e+00, 1.5723e+00, 1.5551e+00, 1.5388e+00, 1.5233e+00, 1.5082e+00, 1.4933e+00, 1.4786e+00, 1.4644e+00, 1.4509e+00, 1.4382e+00, 1.4260e+00, 1.4140e+00, 1.4021e+00, 1.3902e+00, 1.3787e+00, 1.3678e+00, 1.3575e+00, 1.3478e+00, 1.3381e+00, 1.3284e+00, 1.3186e+00, 1.3089e+00, 1.2997e+00, 1.2910e+00, 1.2829e+00, 1.2750e+00, 1.2670e+00, 1.2588e+00, 1.2506e+00, 1.2424e+00, 1.2346e+00, 1.2273e+00, 1.2206e+00, 1.2139e+00, 1.2071e+00, 1.2000e+00, 1.1928e+00, 1.1856e+00, 1.1785e+00, 1.1720e+00, 1.1661e+00, 1.1603e+00, 1.1544e+00, 1.1482e+00, 1.1418e+00, 1.1352e+00, 1.1286e+00, 1.1222e+00, 1.1164e+00, 1.1111e+00, 1.1059e+00, 1.1005e+00, 1.0948e+00, 1.0889e+00, 1.0827e+00, 1.0765e+00, 1.0704e+00, 1.0648e+00, 1.0598e+00, 1.0550e+00, 1.0500e+00, 1.0448e+00, 1.0392e+00, 1.0335e+00, 1.0276e+00, 1.0216e+00, 1.0158e+00, 1.0106e+00, 1.0058e+00, 1.0013e+00, 9.9660e-01, 9.9150e-01, 9.8620e-01, 9.8070e-01, 9.7500e-01, 9.6920e-01, 9.6350e-01, 9.5810e-01, 9.5330e-01, 9.4890e-01, 9.4460e-01, 9.3990e-01, 9.3480e-01, 9.2960e-01, 9.2420e-01, 9.1870e-01, 9.1300e-01, 9.0740e-01, 9.0210e-01, 8.9750e-01, 8.9330e-01, 8.8910e-01, 8.8460e-01, 8.7980e-01, 8.7470e-01, 8.6960e-01, 8.6430e-01, 8.5890e-01, 8.5330e-01, 8.4780e-01, 8.4290e-01, 8.3870e-01, 8.3470e-01, 8.3070e-01, 8.2630e-01, 8.2150e-01, 8.1660e-01, 8.1170e-01, 8.0670e-01, 8.0150e-01, 7.9600e-01, 7.9060e-01, 7.8570e-01, 7.8140e-01, 7.7760e-01, 7.7400e-01, 7.7000e-01, 7.6550e-01, 7.6080e-01, 7.5610e-01, 7.5140e-01, 7.4660e-01, 7.4160e-01, 7.3630e-01, 7.3110e-01, 7.2630e-01, 7.2220e-01}); + feg = Vctr_cpu({6.9630e+00, 6.8202e+00, 6.4312e+00, 5.8918e+00, 5.3049e+00, 4.7437e+00, 4.2430e+00, 3.8110e+00, 3.4419e+00, 3.1259e+00, 2.8530e+00, 2.6148e+00, 2.4047e+00, 2.2178e+00, 2.0501e+00, 1.8988e+00, 1.7616e+00, 1.6367e+00, 1.5228e+00, 1.4186e+00, 1.3231e+00, 1.2356e+00, 1.1552e+00, 1.0814e+00, 1.0135e+00, 9.5100e-01, 8.9350e-01, 8.4050e-01, 7.9170e-01, 7.4670e-01, 7.0520e-01, 6.6680e-01, 6.3130e-01, 5.9850e-01, 5.6820e-01, 5.4000e-01, 5.1390e-01, 4.8970e-01, 4.6720e-01, 4.4620e-01, 4.2670e-01, 4.0850e-01, 3.9140e-01, 3.7550e-01, 3.6060e-01, 3.4670e-01, 3.3350e-01, 3.2120e-01, 3.0960e-01, 2.9870e-01, 2.8830e-01, 2.7860e-01, 2.6930e-01, 2.6060e-01, 2.5230e-01, 2.4440e-01, 2.3690e-01, 2.2980e-01, 2.2300e-01, 2.1650e-01, 2.1030e-01, 2.0440e-01, 1.9880e-01, 1.9330e-01, 1.8820e-01, 1.8320e-01, 1.7840e-01, 1.7380e-01, 1.6940e-01, 1.6510e-01, 1.6110e-01, 1.5710e-01, 1.5330e-01, 1.4970e-01, 1.4610e-01, 1.4270e-01, 1.3940e-01, 1.3620e-01, 1.3310e-01, 1.3020e-01, 1.2730e-01, 1.2450e-01, 1.2180e-01, 1.1920e-01, 1.1660e-01, 1.1420e-01, 1.1180e-01, 1.0940e-01, 1.0720e-01, 1.0500e-01, 1.0290e-01, 1.0080e-01, 9.8800e-02, 9.6900e-02, 9.5000e-02, 9.3100e-02, 9.1400e-02, 8.9600e-02, 8.7900e-02, 8.6300e-02, 8.4700e-02, 8.3100e-02, 8.1600e-02, 8.0100e-02, 7.8700e-02, 7.7300e-02, 7.5900e-02, 7.4600e-02, 7.3300e-02, 7.2000e-02, 7.0700e-02, 6.9500e-02, 6.8400e-02, 6.7200e-02, 6.6100e-02, 6.5000e-02, 6.3900e-02, 6.2900e-02, 6.1900e-02, 6.0900e-02, 5.9900e-02, 5.8900e-02, 5.8000e-02, 5.7100e-02, 5.6200e-02, 5.5400e-02, 5.4500e-02, 5.3700e-02, 5.2900e-02, 5.2100e-02, 5.1300e-02, 5.0500e-02, 4.9800e-02, 4.9100e-02, 4.8400e-02, 4.7700e-02, 4.7000e-02, 4.6300e-02, 4.5700e-02, 4.5000e-02, 4.4400e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2000e-02, 4.1500e-02, 4.0900e-02, 4.0400e-02, 3.9800e-02, 3.9300e-02, 3.8800e-02, 3.8300e-02, 3.7800e-02, 3.7300e-02, 3.6900e-02, 3.6400e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4600e-02, 3.4200e-02, 3.3800e-02, 3.3400e-02, 3.3000e-02, 3.2600e-02, 3.2200e-02, 3.1800e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0400e-02, 3.0000e-02, 2.9700e-02, 2.9400e-02, 2.9000e-02, 2.8700e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8200e-02, 1.8000e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5500e-02}); + } + break; + case 25: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.5000e+01, 2.4809e+01, 2.4276e+01, 2.3505e+01, 2.2610e+01, 2.1679e+01, 2.0758e+01, 1.9866e+01, 1.9003e+01, 1.8166e+01, 1.7354e+01, 1.6563e+01, 1.5796e+01, 1.5056e+01, 1.4346e+01, 1.3668e+01, 1.3025e+01, 1.2420e+01, 1.1854e+01, 1.1326e+01, 1.0837e+01, 1.0386e+01, 9.9707e+00, 9.5907e+00, 9.2435e+00, 8.9268e+00, 8.6383e+00, 8.3757e+00, 8.1364e+00, 7.9183e+00, 7.7189e+00, 7.5362e+00, 7.3682e+00, 7.2130e+00, 7.0689e+00, 6.9342e+00, 6.8077e+00, 6.6880e+00, 6.5739e+00, 6.4646e+00, 6.3592e+00, 6.2568e+00, 6.1569e+00, 6.0591e+00, 5.9627e+00, 5.8674e+00, 5.7731e+00, 5.6793e+00, 5.5861e+00, 5.4932e+00, 5.4005e+00, 5.3081e+00, 5.2159e+00, 5.1240e+00, 5.0322e+00, 4.9408e+00, 4.8498e+00, 4.7591e+00, 4.6690e+00, 4.5795e+00, 4.4907e+00, 4.4026e+00, 4.3153e+00, 4.2290e+00, 4.1437e+00, 4.0595e+00, 3.9764e+00, 3.8946e+00, 3.8140e+00, 3.7348e+00, 3.6570e+00, 3.5806e+00, 3.5057e+00, 3.4323e+00, 3.3605e+00, 3.2903e+00, 3.2216e+00, 3.1545e+00, 3.0891e+00, 3.0253e+00, 2.9631e+00, 2.9025e+00, 2.8435e+00, 2.7862e+00, 2.7304e+00, 2.6763e+00, 2.6236e+00, 2.5725e+00, 2.5230e+00, 2.4750e+00, 2.4284e+00, 2.3833e+00, 2.3395e+00, 2.2972e+00, 2.2563e+00, 2.2167e+00, 2.1783e+00, 2.1412e+00, 2.1052e+00, 2.0707e+00, 2.0373e+00, 2.0050e+00, 1.9736e+00, 1.9433e+00, 1.9141e+00, 1.8861e+00, 1.8590e+00, 1.8328e+00, 1.8072e+00, 1.7826e+00, 1.7589e+00, 1.7363e+00, 1.7145e+00, 1.6933e+00, 1.6725e+00, 1.6524e+00, 1.6331e+00, 1.6148e+00, 1.5972e+00, 1.5801e+00, 1.5632e+00, 1.5467e+00, 1.5308e+00, 1.5157e+00, 1.5014e+00, 1.4876e+00, 1.4740e+00, 1.4605e+00, 1.4472e+00, 1.4344e+00, 1.4223e+00, 1.4109e+00, 1.4000e+00, 1.3891e+00, 1.3782e+00, 1.3672e+00, 1.3566e+00, 1.3465e+00, 1.3372e+00, 1.3283e+00, 1.3196e+00, 1.3107e+00, 1.3016e+00, 1.2925e+00, 1.2837e+00, 1.2755e+00, 1.2679e+00, 1.2607e+00, 1.2536e+00, 1.2461e+00, 1.2384e+00, 1.2305e+00, 1.2229e+00, 1.2157e+00, 1.2091e+00, 1.2030e+00, 1.1971e+00, 1.1908e+00, 1.1842e+00, 1.1772e+00, 1.1703e+00, 1.1636e+00, 1.1574e+00, 1.1517e+00, 1.1465e+00, 1.1413e+00, 1.1357e+00, 1.1297e+00, 1.1233e+00, 1.1169e+00, 1.1107e+00, 1.1049e+00, 1.0996e+00, 1.0948e+00, 1.0901e+00, 1.0853e+00, 1.0799e+00, 1.0739e+00, 1.0678e+00, 1.0619e+00, 1.0561e+00, 1.0508e+00, 1.0459e+00, 1.0415e+00, 1.0372e+00, 1.0326e+00, 1.0275e+00, 1.0218e+00, 1.0159e+00, 1.0101e+00, 1.0046e+00, 9.9930e-01, 9.9450e-01, 9.9010e-01, 9.8600e-01, 9.8190e-01, 9.7730e-01, 9.7200e-01, 9.6630e-01, 9.6060e-01, 9.5500e-01, 9.4970e-01, 9.4470e-01, 9.4000e-01, 9.3570e-01, 9.3190e-01, 9.2800e-01, 9.2360e-01, 9.1850e-01, 9.1300e-01, 9.0730e-01, 9.0190e-01, 8.9670e-01, 8.9170e-01, 8.8690e-01, 8.8250e-01, 8.7850e-01, 8.7490e-01, 8.7110e-01, 8.6670e-01, 8.6160e-01, 8.5610e-01, 8.5060e-01, 8.4540e-01, 8.4040e-01, 8.3560e-01, 8.3080e-01, 8.2640e-01, 8.2240e-01, 8.1890e-01, 8.1550e-01, 8.1160e-01, 8.0690e-01, 8.0170e-01, 7.9630e-01, 7.9110e-01, 7.8620e-01, 7.8150e-01, 7.7680e-01, 7.7220e-01, 7.6790e-01}); + feg = Vctr_cpu({7.4716e+00, 7.3280e+00, 6.9301e+00, 6.3611e+00, 5.7199e+00, 5.0875e+00, 4.5123e+00, 4.0126e+00, 3.5884e+00, 3.2306e+00, 2.9282e+00, 2.6702e+00, 2.4475e+00, 2.2532e+00, 2.0816e+00, 1.9287e+00, 1.7912e+00, 1.6669e+00, 1.5538e+00, 1.4505e+00, 1.3559e+00, 1.2690e+00, 1.1891e+00, 1.1155e+00, 1.0475e+00, 9.8480e-01, 9.2690e-01, 8.7330e-01, 8.2370e-01, 7.7780e-01, 7.3530e-01, 6.9590e-01, 6.5940e-01, 6.2550e-01, 5.9400e-01, 5.6470e-01, 5.3750e-01, 5.1220e-01, 4.8860e-01, 4.6670e-01, 4.4610e-01, 4.2700e-01, 4.0910e-01, 3.9230e-01, 3.7660e-01, 3.6180e-01, 3.4800e-01, 3.3490e-01, 3.2270e-01, 3.1110e-01, 3.0020e-01, 2.8990e-01, 2.8020e-01, 2.7100e-01, 2.6220e-01, 2.5390e-01, 2.4610e-01, 2.3860e-01, 2.3140e-01, 2.2460e-01, 2.1820e-01, 2.1200e-01, 2.0610e-01, 2.0040e-01, 1.9500e-01, 1.8980e-01, 1.8480e-01, 1.8000e-01, 1.7550e-01, 1.7100e-01, 1.6680e-01, 1.6270e-01, 1.5880e-01, 1.5500e-01, 1.5130e-01, 1.4780e-01, 1.4440e-01, 1.4110e-01, 1.3790e-01, 1.3480e-01, 1.3190e-01, 1.2900e-01, 1.2620e-01, 1.2350e-01, 1.2090e-01, 1.1830e-01, 1.1590e-01, 1.1350e-01, 1.1110e-01, 1.0890e-01, 1.0670e-01, 1.0460e-01, 1.0250e-01, 1.0050e-01, 9.8600e-02, 9.6700e-02, 9.4800e-02, 9.3000e-02, 9.1300e-02, 8.9600e-02, 8.7900e-02, 8.6300e-02, 8.4800e-02, 8.3200e-02, 8.1700e-02, 8.0300e-02, 7.8900e-02, 7.7500e-02, 7.6100e-02, 7.4800e-02, 7.3600e-02, 7.2300e-02, 7.1100e-02, 6.9900e-02, 6.8700e-02, 6.7600e-02, 6.6500e-02, 6.5400e-02, 6.4400e-02, 6.3300e-02, 6.2300e-02, 6.1300e-02, 6.0400e-02, 5.9400e-02, 5.8500e-02, 5.7600e-02, 5.6700e-02, 5.5900e-02, 5.5000e-02, 5.4200e-02, 5.3400e-02, 5.2600e-02, 5.1900e-02, 5.1100e-02, 5.0400e-02, 4.9700e-02, 4.9000e-02, 4.8300e-02, 4.7600e-02, 4.6900e-02, 4.6300e-02, 4.5600e-02, 4.5000e-02, 4.4400e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2100e-02, 4.1500e-02, 4.1000e-02, 4.0400e-02, 3.9900e-02, 3.9400e-02, 3.8900e-02, 3.8400e-02, 3.7900e-02, 3.7500e-02, 3.7000e-02, 3.6500e-02, 3.6100e-02, 3.5600e-02, 3.5200e-02, 3.4800e-02, 3.4400e-02, 3.4000e-02, 3.3600e-02, 3.3200e-02, 3.2800e-02, 3.2400e-02, 3.2000e-02, 3.1700e-02, 3.1300e-02, 3.0900e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9600e-02, 2.9200e-02, 2.8900e-02, 2.8600e-02, 2.8300e-02, 2.8000e-02, 2.7700e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6500e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.8000e-02, 1.7800e-02, 1.7700e-02, 1.7500e-02, 1.7400e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6500e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02}); + } + break; + case 26: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.6000e+01, 2.5816e+01, 2.5304e+01, 2.4555e+01, 2.3677e+01, 2.2751e+01, 2.1825e+01, 2.0920e+01, 2.0040e+01, 1.9183e+01, 1.8347e+01, 1.7531e+01, 1.6738e+01, 1.5969e+01, 1.5228e+01, 1.4517e+01, 1.3840e+01, 1.3199e+01, 1.2594e+01, 1.2028e+01, 1.1500e+01, 1.1009e+01, 1.0555e+01, 1.0136e+01, 9.7519e+00, 9.3991e+00, 9.0762e+00, 8.7811e+00, 8.5115e+00, 8.2651e+00, 8.0400e+00, 7.8339e+00, 7.6448e+00, 7.4710e+00, 7.3105e+00, 7.1617e+00, 7.0232e+00, 6.8935e+00, 6.7714e+00, 6.6558e+00, 6.5456e+00, 6.4400e+00, 6.3382e+00, 6.2395e+00, 6.1434e+00, 6.0493e+00, 5.9569e+00, 5.8657e+00, 5.7755e+00, 5.6860e+00, 5.5972e+00, 5.5087e+00, 5.4207e+00, 5.3329e+00, 5.2453e+00, 5.1580e+00, 5.0709e+00, 4.9841e+00, 4.8976e+00, 4.8114e+00, 4.7256e+00, 4.6403e+00, 4.5556e+00, 4.4714e+00, 4.3879e+00, 4.3052e+00, 4.2233e+00, 4.1423e+00, 4.0623e+00, 3.9832e+00, 3.9053e+00, 3.8285e+00, 3.7528e+00, 3.6784e+00, 3.6053e+00, 3.5335e+00, 3.4630e+00, 3.3939e+00, 3.3262e+00, 3.2599e+00, 3.1951e+00, 3.1316e+00, 3.0697e+00, 3.0092e+00, 2.9502e+00, 2.8927e+00, 2.8365e+00, 2.7819e+00, 2.7287e+00, 2.6770e+00, 2.6266e+00, 2.5776e+00, 2.5300e+00, 2.4839e+00, 2.4391e+00, 2.3955e+00, 2.3532e+00, 2.3121e+00, 2.2724e+00, 2.2340e+00, 2.1968e+00, 2.1605e+00, 2.1253e+00, 2.0914e+00, 2.0587e+00, 2.0271e+00, 1.9964e+00, 1.9665e+00, 1.9374e+00, 1.9095e+00, 1.8828e+00, 1.8570e+00, 1.8319e+00, 1.8073e+00, 1.7834e+00, 1.7605e+00, 1.7386e+00, 1.7176e+00, 1.6972e+00, 1.6772e+00, 1.6576e+00, 1.6386e+00, 1.6205e+00, 1.6033e+00, 1.5868e+00, 1.5706e+00, 1.5546e+00, 1.5389e+00, 1.5236e+00, 1.5091e+00, 1.4954e+00, 1.4824e+00, 1.4696e+00, 1.4568e+00, 1.4441e+00, 1.4315e+00, 1.4196e+00, 1.4084e+00, 1.3979e+00, 1.3877e+00, 1.3776e+00, 1.3672e+00, 1.3569e+00, 1.3467e+00, 1.3371e+00, 1.3281e+00, 1.3198e+00, 1.3117e+00, 1.3034e+00, 1.2950e+00, 1.2863e+00, 1.2777e+00, 1.2695e+00, 1.2620e+00, 1.2550e+00, 1.2484e+00, 1.2417e+00, 1.2347e+00, 1.2274e+00, 1.2200e+00, 1.2126e+00, 1.2056e+00, 1.1993e+00, 1.1936e+00, 1.1880e+00, 1.1823e+00, 1.1763e+00, 1.1699e+00, 1.1633e+00, 1.1566e+00, 1.1503e+00, 1.1445e+00, 1.1393e+00, 1.1344e+00, 1.1295e+00, 1.1243e+00, 1.1187e+00, 1.1128e+00, 1.1067e+00, 1.1005e+00, 1.0947e+00, 1.0895e+00, 1.0849e+00, 1.0805e+00, 1.0761e+00, 1.0712e+00, 1.0660e+00, 1.0605e+00, 1.0548e+00, 1.0490e+00, 1.0433e+00, 1.0381e+00, 1.0335e+00, 1.0294e+00, 1.0254e+00, 1.0210e+00, 1.0163e+00, 1.0112e+00, 1.0060e+00, 1.0004e+00, 9.9480e-01, 9.8930e-01, 9.8420e-01, 9.7980e-01, 9.7600e-01, 9.7220e-01, 9.6810e-01, 9.6350e-01, 9.5870e-01, 9.5370e-01, 9.4850e-01, 9.4310e-01, 9.3750e-01, 9.3230e-01, 9.2760e-01, 9.2360e-01, 9.2000e-01, 9.1630e-01, 9.1220e-01, 9.0780e-01, 9.0300e-01, 8.9820e-01, 8.9320e-01, 8.8800e-01, 8.8250e-01, 8.7720e-01, 8.7250e-01, 8.6840e-01, 8.6490e-01, 8.6150e-01, 8.5780e-01, 8.5360e-01, 8.4910e-01, 8.4440e-01, 8.3980e-01, 8.3500e-01, 8.2990e-01, 8.2460e-01, 8.1940e-01, 8.1470e-01, 8.1070e-01}); + feg = Vctr_cpu({7.1598e+00, 7.0290e+00, 6.6666e+00, 6.1478e+00, 5.5606e+00, 4.9769e+00, 4.4406e+00, 3.9698e+00, 3.5661e+00, 3.2230e+00, 2.9308e+00, 2.6802e+00, 2.4631e+00, 2.2729e+00, 2.1046e+00, 1.9543e+00, 1.8189e+00, 1.6962e+00, 1.5844e+00, 1.4821e+00, 1.3882e+00, 1.3017e+00, 1.2220e+00, 1.1483e+00, 1.0802e+00, 1.0171e+00, 9.5870e-01, 9.0450e-01, 8.5420e-01, 8.0750e-01, 7.6420e-01, 7.2390e-01, 6.8640e-01, 6.5160e-01, 6.1910e-01, 5.8890e-01, 5.6070e-01, 5.3450e-01, 5.0990e-01, 4.8700e-01, 4.6560e-01, 4.4560e-01, 4.2680e-01, 4.0930e-01, 3.9280e-01, 3.7730e-01, 3.6270e-01, 3.4900e-01, 3.3610e-01, 3.2400e-01, 3.1250e-01, 3.0170e-01, 2.9140e-01, 2.8170e-01, 2.7260e-01, 2.6380e-01, 2.5560e-01, 2.4770e-01, 2.4020e-01, 2.3310e-01, 2.2630e-01, 2.1980e-01, 2.1360e-01, 2.0770e-01, 2.0210e-01, 1.9660e-01, 1.9140e-01, 1.8650e-01, 1.8170e-01, 1.7710e-01, 1.7270e-01, 1.6840e-01, 1.6430e-01, 1.6040e-01, 1.5660e-01, 1.5290e-01, 1.4940e-01, 1.4600e-01, 1.4270e-01, 1.3950e-01, 1.3650e-01, 1.3350e-01, 1.3060e-01, 1.2780e-01, 1.2510e-01, 1.2250e-01, 1.1990e-01, 1.1750e-01, 1.1510e-01, 1.1280e-01, 1.1050e-01, 1.0830e-01, 1.0620e-01, 1.0410e-01, 1.0210e-01, 1.0020e-01, 9.8300e-02, 9.6400e-02, 9.4600e-02, 9.2900e-02, 9.1200e-02, 8.9500e-02, 8.7900e-02, 8.6300e-02, 8.4800e-02, 8.3300e-02, 8.1800e-02, 8.0400e-02, 7.9000e-02, 7.7600e-02, 7.6300e-02, 7.5000e-02, 7.3800e-02, 7.2600e-02, 7.1400e-02, 7.0200e-02, 6.9000e-02, 6.7900e-02, 6.6800e-02, 6.5800e-02, 6.4700e-02, 6.3700e-02, 6.2700e-02, 6.1800e-02, 6.0800e-02, 5.9900e-02, 5.9000e-02, 5.8100e-02, 5.7200e-02, 5.6400e-02, 5.5500e-02, 5.4700e-02, 5.3900e-02, 5.3100e-02, 5.2400e-02, 5.1600e-02, 5.0900e-02, 5.0200e-02, 4.9500e-02, 4.8800e-02, 4.8100e-02, 4.7400e-02, 4.6800e-02, 4.6200e-02, 4.5500e-02, 4.4900e-02, 4.4300e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2100e-02, 4.1500e-02, 4.1000e-02, 4.0500e-02, 4.0000e-02, 3.9500e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7500e-02, 3.7100e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5300e-02, 3.4900e-02, 3.4500e-02, 3.4100e-02, 3.3700e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2200e-02, 3.1800e-02, 3.1500e-02, 3.1100e-02, 3.0800e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9400e-02, 2.9100e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7600e-02, 2.7300e-02, 2.7000e-02, 2.6700e-02, 2.6500e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5400e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9300e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8700e-02, 1.8500e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7200e-02, 1.7000e-02, 1.6900e-02, 1.6700e-02}); + } + break; + case 27: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.7000e+01, 2.6824e+01, 2.6331e+01, 2.5605e+01, 2.4743e+01, 2.3825e+01, 2.2898e+01, 2.1985e+01, 2.1090e+01, 2.0216e+01, 1.9361e+01, 1.8523e+01, 1.7706e+01, 1.6912e+01, 1.6142e+01, 1.5402e+01, 1.4692e+01, 1.4017e+01, 1.3377e+01, 1.2774e+01, 1.2208e+01, 1.1679e+01, 1.1187e+01, 1.0730e+01, 1.0308e+01, 9.9185e+00, 9.5604e+00, 9.2314e+00, 8.9297e+00, 8.6532e+00, 8.3998e+00, 8.1676e+00, 7.9546e+00, 7.7589e+00, 7.5788e+00, 7.4126e+00, 7.2586e+00, 7.1155e+00, 6.9819e+00, 6.8566e+00, 6.7384e+00, 6.6264e+00, 6.5197e+00, 6.4174e+00, 6.3188e+00, 6.2234e+00, 6.1305e+00, 6.0398e+00, 5.9508e+00, 5.8631e+00, 5.7766e+00, 5.6909e+00, 5.6059e+00, 5.5214e+00, 5.4374e+00, 5.3537e+00, 5.2703e+00, 5.1871e+00, 5.1042e+00, 5.0216e+00, 4.9392e+00, 4.8571e+00, 4.7753e+00, 4.6940e+00, 4.6130e+00, 4.5326e+00, 4.4527e+00, 4.3735e+00, 4.2949e+00, 4.2170e+00, 4.1399e+00, 4.0637e+00, 3.9884e+00, 3.9140e+00, 3.8407e+00, 3.7684e+00, 3.6972e+00, 3.6270e+00, 3.5581e+00, 3.4904e+00, 3.4239e+00, 3.3587e+00, 3.2946e+00, 3.2320e+00, 3.1706e+00, 3.1105e+00, 3.0517e+00, 2.9943e+00, 2.9382e+00, 2.8835e+00, 2.8300e+00, 2.7777e+00, 2.7269e+00, 2.6774e+00, 2.6292e+00, 2.5822e+00, 2.5364e+00, 2.4919e+00, 2.4487e+00, 2.4067e+00, 2.3660e+00, 2.3262e+00, 2.2875e+00, 2.2500e+00, 2.2138e+00, 2.1787e+00, 2.1446e+00, 2.1113e+00, 2.0789e+00, 2.0477e+00, 2.0176e+00, 1.9886e+00, 1.9602e+00, 1.9326e+00, 1.9057e+00, 1.8797e+00, 1.8548e+00, 1.8309e+00, 1.8077e+00, 1.7849e+00, 1.7626e+00, 1.7410e+00, 1.7203e+00, 1.7005e+00, 1.6815e+00, 1.6630e+00, 1.6447e+00, 1.6267e+00, 1.6093e+00, 1.5927e+00, 1.5769e+00, 1.5618e+00, 1.5470e+00, 1.5324e+00, 1.5178e+00, 1.5036e+00, 1.4900e+00, 1.4772e+00, 1.4651e+00, 1.4533e+00, 1.4416e+00, 1.4299e+00, 1.4182e+00, 1.4068e+00, 1.3959e+00, 1.3858e+00, 1.3762e+00, 1.3669e+00, 1.3576e+00, 1.3481e+00, 1.3386e+00, 1.3291e+00, 1.3201e+00, 1.3116e+00, 1.3038e+00, 1.2964e+00, 1.2889e+00, 1.2812e+00, 1.2733e+00, 1.2653e+00, 1.2573e+00, 1.2499e+00, 1.2430e+00, 1.2367e+00, 1.2306e+00, 1.2244e+00, 1.2179e+00, 1.2112e+00, 1.2042e+00, 1.1973e+00, 1.1906e+00, 1.1845e+00, 1.1790e+00, 1.1739e+00, 1.1687e+00, 1.1632e+00, 1.1574e+00, 1.1513e+00, 1.1451e+00, 1.1389e+00, 1.1329e+00, 1.1276e+00, 1.1228e+00, 1.1183e+00, 1.1137e+00, 1.1088e+00, 1.1036e+00, 1.0981e+00, 1.0923e+00, 1.0865e+00, 1.0808e+00, 1.0756e+00, 1.0710e+00, 1.0669e+00, 1.0628e+00, 1.0585e+00, 1.0538e+00, 1.0487e+00, 1.0435e+00, 1.0380e+00, 1.0325e+00, 1.0270e+00, 1.0221e+00, 1.0178e+00, 1.0139e+00, 1.0101e+00, 1.0061e+00, 1.0016e+00, 9.9690e-01, 9.9200e-01, 9.8680e-01, 9.8150e-01, 9.7610e-01, 9.7100e-01, 9.6640e-01, 9.6240e-01, 9.5880e-01, 9.5520e-01, 9.5130e-01, 9.4690e-01, 9.4230e-01, 9.3750e-01, 9.3260e-01, 9.2750e-01, 9.2220e-01, 9.1700e-01, 9.1240e-01, 9.0830e-01, 9.0490e-01, 9.0150e-01, 8.9790e-01, 8.9380e-01, 8.8940e-01, 8.8490e-01, 8.8020e-01, 8.7550e-01, 8.7050e-01, 8.6530e-01, 8.6020e-01, 8.5560e-01, 8.5170e-01}); + feg = Vctr_cpu({6.8497e+00, 6.7326e+00, 6.4069e+00, 5.9375e+00, 5.4015e+00, 4.8632e+00, 4.3631e+00, 3.9196e+00, 3.5359e+00, 3.2071e+00, 2.9254e+00, 2.6826e+00, 2.4715e+00, 2.2859e+00, 2.1213e+00, 1.9740e+00, 1.8410e+00, 1.7203e+00, 1.6101e+00, 1.5091e+00, 1.4161e+00, 1.3304e+00, 1.2512e+00, 1.1778e+00, 1.1097e+00, 1.0466e+00, 9.8790e-01, 9.3340e-01, 8.8260e-01, 8.3540e-01, 7.9140e-01, 7.5040e-01, 7.1220e-01, 6.7660e-01, 6.4330e-01, 6.1230e-01, 5.8330e-01, 5.5620e-01, 5.3090e-01, 5.0710e-01, 4.8490e-01, 4.6410e-01, 4.4460e-01, 4.2630e-01, 4.0910e-01, 3.9290e-01, 3.7770e-01, 3.6340e-01, 3.4990e-01, 3.3710e-01, 3.2510e-01, 3.1370e-01, 3.0300e-01, 2.9280e-01, 2.8320e-01, 2.7400e-01, 2.6530e-01, 2.5710e-01, 2.4920e-01, 2.4180e-01, 2.3470e-01, 2.2790e-01, 2.2140e-01, 2.1520e-01, 2.0930e-01, 2.0360e-01, 1.9820e-01, 1.9300e-01, 1.8800e-01, 1.8320e-01, 1.7870e-01, 1.7420e-01, 1.7000e-01, 1.6590e-01, 1.6200e-01, 1.5820e-01, 1.5450e-01, 1.5100e-01, 1.4750e-01, 1.4430e-01, 1.4110e-01, 1.3800e-01, 1.3500e-01, 1.3210e-01, 1.2930e-01, 1.2660e-01, 1.2400e-01, 1.2150e-01, 1.1900e-01, 1.1660e-01, 1.1430e-01, 1.1200e-01, 1.0980e-01, 1.0770e-01, 1.0560e-01, 1.0360e-01, 1.0160e-01, 9.9700e-02, 9.7900e-02, 9.6100e-02, 9.4300e-02, 9.2600e-02, 9.1000e-02, 8.9300e-02, 8.7800e-02, 8.6200e-02, 8.4700e-02, 8.3200e-02, 8.1800e-02, 8.0400e-02, 7.9100e-02, 7.7700e-02, 7.6400e-02, 7.5200e-02, 7.3900e-02, 7.2700e-02, 7.1600e-02, 7.0400e-02, 6.9300e-02, 6.8200e-02, 6.7100e-02, 6.6100e-02, 6.5000e-02, 6.4000e-02, 6.3100e-02, 6.2100e-02, 6.1200e-02, 6.0200e-02, 5.9300e-02, 5.8500e-02, 5.7600e-02, 5.6800e-02, 5.5900e-02, 5.5100e-02, 5.4300e-02, 5.3600e-02, 5.2800e-02, 5.2100e-02, 5.1300e-02, 5.0600e-02, 4.9900e-02, 4.9300e-02, 4.8600e-02, 4.7900e-02, 4.7300e-02, 4.6700e-02, 4.6000e-02, 4.5400e-02, 4.4800e-02, 4.4200e-02, 4.3700e-02, 4.3100e-02, 4.2600e-02, 4.2000e-02, 4.1500e-02, 4.1000e-02, 4.0500e-02, 4.0000e-02, 3.9500e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7600e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.5800e-02, 3.5400e-02, 3.5000e-02, 3.4600e-02, 3.4200e-02, 3.3800e-02, 3.3400e-02, 3.3000e-02, 3.2700e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6700e-02, 2.6400e-02, 2.6100e-02, 2.5900e-02, 2.5600e-02, 2.5400e-02, 2.5100e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.8000e-02, 1.7800e-02, 1.7700e-02, 1.7500e-02, 1.7400e-02}); + } + break; + case 28: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.8000e+01, 2.7832e+01, 2.7357e+01, 2.6652e+01, 2.5807e+01, 2.4898e+01, 2.3972e+01, 2.3052e+01, 2.2147e+01, 2.1259e+01, 2.0387e+01, 1.9531e+01, 1.8693e+01, 1.7875e+01, 1.7081e+01, 1.6313e+01, 1.5574e+01, 1.4867e+01, 1.4194e+01, 1.3556e+01, 1.2955e+01, 1.2389e+01, 1.1860e+01, 1.1367e+01, 1.0908e+01, 1.0482e+01, 1.0089e+01, 9.7256e+00, 9.3909e+00, 9.0829e+00, 8.7997e+00, 8.5395e+00, 8.3003e+00, 8.0804e+00, 7.8780e+00, 7.6915e+00, 7.5192e+00, 7.3597e+00, 7.2116e+00, 7.0735e+00, 6.9443e+00, 6.8229e+00, 6.7083e+00, 6.5996e+00, 6.4959e+00, 6.3965e+00, 6.3008e+00, 6.2083e+00, 6.1184e+00, 6.0306e+00, 5.9446e+00, 5.8601e+00, 5.7768e+00, 5.6944e+00, 5.6129e+00, 5.5319e+00, 5.4515e+00, 5.3714e+00, 5.2918e+00, 5.2124e+00, 5.1332e+00, 5.0543e+00, 4.9757e+00, 4.8974e+00, 4.8193e+00, 4.7416e+00, 4.6643e+00, 4.5873e+00, 4.5108e+00, 4.4349e+00, 4.3595e+00, 4.2846e+00, 4.2105e+00, 4.1370e+00, 4.0643e+00, 3.9925e+00, 3.9214e+00, 3.8512e+00, 3.7820e+00, 3.7138e+00, 3.6466e+00, 3.5804e+00, 3.5153e+00, 3.4512e+00, 3.3883e+00, 3.3266e+00, 3.2659e+00, 3.2065e+00, 3.1482e+00, 3.0912e+00, 3.0353e+00, 2.9806e+00, 2.9271e+00, 2.8749e+00, 2.8239e+00, 2.7741e+00, 2.7254e+00, 2.6778e+00, 2.6315e+00, 2.5864e+00, 2.5425e+00, 2.4997e+00, 2.4579e+00, 2.4171e+00, 2.3776e+00, 2.3392e+00, 2.3019e+00, 2.2656e+00, 2.2301e+00, 2.1956e+00, 2.1622e+00, 2.1300e+00, 2.0986e+00, 2.0681e+00, 2.0383e+00, 2.0093e+00, 1.9812e+00, 1.9542e+00, 1.9281e+00, 1.9027e+00, 1.8778e+00, 1.8536e+00, 1.8301e+00, 1.8075e+00, 1.7858e+00, 1.7648e+00, 1.7443e+00, 1.7241e+00, 1.7044e+00, 1.6853e+00, 1.6671e+00, 1.6497e+00, 1.6328e+00, 1.6163e+00, 1.6000e+00, 1.5840e+00, 1.5684e+00, 1.5535e+00, 1.5394e+00, 1.5258e+00, 1.5126e+00, 1.4995e+00, 1.4864e+00, 1.4736e+00, 1.4612e+00, 1.4494e+00, 1.4382e+00, 1.4276e+00, 1.4171e+00, 1.4066e+00, 1.3961e+00, 1.3856e+00, 1.3754e+00, 1.3657e+00, 1.3567e+00, 1.3481e+00, 1.3398e+00, 1.3314e+00, 1.3228e+00, 1.3141e+00, 1.3054e+00, 1.2972e+00, 1.2894e+00, 1.2821e+00, 1.2753e+00, 1.2686e+00, 1.2617e+00, 1.2545e+00, 1.2471e+00, 1.2398e+00, 1.2327e+00, 1.2261e+00, 1.2199e+00, 1.2142e+00, 1.2086e+00, 1.2029e+00, 1.1969e+00, 1.1905e+00, 1.1840e+00, 1.1777e+00, 1.1716e+00, 1.1659e+00, 1.1607e+00, 1.1558e+00, 1.1511e+00, 1.1461e+00, 1.1408e+00, 1.1351e+00, 1.1292e+00, 1.1234e+00, 1.1178e+00, 1.1125e+00, 1.1077e+00, 1.1032e+00, 1.0990e+00, 1.0948e+00, 1.0901e+00, 1.0850e+00, 1.0796e+00, 1.0741e+00, 1.0687e+00, 1.0636e+00, 1.0587e+00, 1.0542e+00, 1.0501e+00, 1.0463e+00, 1.0424e+00, 1.0382e+00, 1.0334e+00, 1.0282e+00, 1.0229e+00, 1.0178e+00, 1.0128e+00, 1.0080e+00, 1.0035e+00, 9.9940e-01, 9.9570e-01, 9.9210e-01, 9.8840e-01, 9.8420e-01, 9.7950e-01, 9.7440e-01, 9.6930e-01, 9.6440e-01, 9.5960e-01, 9.5500e-01, 9.5060e-01, 9.4650e-01, 9.4280e-01, 9.3940e-01, 9.3600e-01, 9.3220e-01, 9.2780e-01, 9.2300e-01, 9.1790e-01, 9.1300e-01, 9.0830e-01, 9.0370e-01, 8.9930e-01, 8.9500e-01, 8.9100e-01}); + feg = Vctr_cpu({6.5539e+00, 6.4501e+00, 6.1597e+00, 5.7370e+00, 5.2484e+00, 4.7516e+00, 4.2849e+00, 3.8669e+00, 3.5019e+00, 3.1869e+00, 2.9154e+00, 2.6803e+00, 2.4750e+00, 2.2942e+00, 2.1334e+00, 1.9891e+00, 1.8587e+00, 1.7402e+00, 1.6317e+00, 1.5321e+00, 1.4404e+00, 1.3555e+00, 1.2770e+00, 1.2041e+00, 1.1363e+00, 1.0733e+00, 1.0146e+00, 9.5990e-01, 9.0890e-01, 8.6140e-01, 8.1690e-01, 7.7550e-01, 7.3670e-01, 7.0050e-01, 6.6660e-01, 6.3480e-01, 6.0520e-01, 5.7740e-01, 5.5130e-01, 5.2690e-01, 5.0390e-01, 4.8240e-01, 4.6220e-01, 4.4320e-01, 4.2530e-01, 4.0850e-01, 3.9270e-01, 3.7780e-01, 3.6370e-01, 3.5040e-01, 3.3780e-01, 3.2600e-01, 3.1470e-01, 3.0410e-01, 2.9400e-01, 2.8440e-01, 2.7530e-01, 2.6670e-01, 2.5850e-01, 2.5070e-01, 2.4320e-01, 2.3610e-01, 2.2940e-01, 2.2290e-01, 2.1670e-01, 2.1080e-01, 2.0510e-01, 1.9970e-01, 1.9450e-01, 1.8950e-01, 1.8480e-01, 1.8020e-01, 1.7570e-01, 1.7150e-01, 1.6740e-01, 1.6340e-01, 1.5960e-01, 1.5600e-01, 1.5240e-01, 1.4900e-01, 1.4570e-01, 1.4250e-01, 1.3940e-01, 1.3650e-01, 1.3360e-01, 1.3080e-01, 1.2810e-01, 1.2540e-01, 1.2290e-01, 1.2040e-01, 1.1800e-01, 1.1570e-01, 1.1340e-01, 1.1120e-01, 1.0910e-01, 1.0700e-01, 1.0500e-01, 1.0310e-01, 1.0120e-01, 9.9300e-02, 9.7500e-02, 9.5700e-02, 9.4000e-02, 9.2300e-02, 9.0700e-02, 8.9100e-02, 8.7600e-02, 8.6100e-02, 8.4600e-02, 8.3200e-02, 8.1800e-02, 8.0400e-02, 7.9100e-02, 7.7800e-02, 7.6500e-02, 7.5300e-02, 7.4000e-02, 7.2900e-02, 7.1700e-02, 7.0600e-02, 6.9500e-02, 6.8400e-02, 6.7300e-02, 6.6300e-02, 6.5300e-02, 6.4300e-02, 6.3300e-02, 6.2400e-02, 6.1500e-02, 6.0600e-02, 5.9700e-02, 5.8800e-02, 5.7900e-02, 5.7100e-02, 5.6300e-02, 5.5500e-02, 5.4700e-02, 5.4000e-02, 5.3200e-02, 5.2500e-02, 5.1800e-02, 5.1000e-02, 5.0400e-02, 4.9700e-02, 4.9000e-02, 4.8400e-02, 4.7700e-02, 4.7100e-02, 4.6500e-02, 4.5900e-02, 4.5300e-02, 4.4700e-02, 4.4100e-02, 4.3600e-02, 4.3000e-02, 4.2500e-02, 4.2000e-02, 4.1400e-02, 4.0900e-02, 4.0400e-02, 3.9900e-02, 3.9400e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7600e-02, 3.7200e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.3900e-02, 3.3500e-02, 3.3100e-02, 3.2800e-02, 3.2400e-02, 3.2100e-02, 3.1700e-02, 3.1400e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0000e-02, 2.9700e-02, 2.9400e-02, 2.9100e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7700e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5500e-02, 2.5300e-02, 2.5000e-02, 2.4800e-02, 2.4600e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8800e-02, 1.8600e-02, 1.8500e-02, 1.8300e-02, 1.8200e-02, 1.8000e-02}); + } + break; + case 29: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.9000e+01, 2.8857e+01, 2.8449e+01, 2.7837e+01, 2.7086e+01, 2.6251e+01, 2.5370e+01, 2.4462e+01, 2.3539e+01, 2.2612e+01, 2.1687e+01, 2.0770e+01, 1.9868e+01, 1.8987e+01, 1.8132e+01, 1.7306e+01, 1.6513e+01, 1.5755e+01, 1.5034e+01, 1.4351e+01, 1.3706e+01, 1.3100e+01, 1.2532e+01, 1.2001e+01, 1.1507e+01, 1.1047e+01, 1.0620e+01, 1.0225e+01, 9.8602e+00, 9.5233e+00, 9.2127e+00, 8.9264e+00, 8.6627e+00, 8.4199e+00, 8.1960e+00, 7.9896e+00, 7.7990e+00, 7.6226e+00, 7.4592e+00, 7.3073e+00, 7.1657e+00, 7.0333e+00, 6.9090e+00, 6.7919e+00, 6.6810e+00, 6.5757e+00, 6.4750e+00, 6.3785e+00, 6.2855e+00, 6.1954e+00, 6.1080e+00, 6.0227e+00, 5.9392e+00, 5.8572e+00, 5.7764e+00, 5.6967e+00, 5.6178e+00, 5.5397e+00, 5.4621e+00, 5.3850e+00, 5.3082e+00, 5.2319e+00, 5.1558e+00, 5.0801e+00, 5.0046e+00, 4.9294e+00, 4.8545e+00, 4.7799e+00, 4.7056e+00, 4.6317e+00, 4.5583e+00, 4.4852e+00, 4.4127e+00, 4.3407e+00, 4.2692e+00, 4.1984e+00, 4.1282e+00, 4.0587e+00, 3.9900e+00, 3.9220e+00, 3.8549e+00, 3.7886e+00, 3.7231e+00, 3.6586e+00, 3.5951e+00, 3.5325e+00, 3.4709e+00, 3.4103e+00, 3.3507e+00, 3.2922e+00, 3.2348e+00, 3.1784e+00, 3.1230e+00, 3.0688e+00, 3.0158e+00, 2.9638e+00, 2.9129e+00, 2.8630e+00, 2.8143e+00, 2.7667e+00, 2.7202e+00, 2.6748e+00, 2.6304e+00, 2.5870e+00, 2.5448e+00, 2.5036e+00, 2.4635e+00, 2.4244e+00, 2.3861e+00, 2.3489e+00, 2.3127e+00, 2.2775e+00, 2.2434e+00, 2.2100e+00, 2.1774e+00, 2.1457e+00, 2.1149e+00, 2.0852e+00, 2.0563e+00, 2.0281e+00, 2.0006e+00, 1.9738e+00, 1.9478e+00, 1.9226e+00, 1.8983e+00, 1.8748e+00, 1.8518e+00, 1.8293e+00, 1.8073e+00, 1.7860e+00, 1.7655e+00, 1.7458e+00, 1.7267e+00, 1.7080e+00, 1.6897e+00, 1.6717e+00, 1.6543e+00, 1.6375e+00, 1.6214e+00, 1.6059e+00, 1.5908e+00, 1.5759e+00, 1.5612e+00, 1.5469e+00, 1.5330e+00, 1.5196e+00, 1.5069e+00, 1.4946e+00, 1.4826e+00, 1.4707e+00, 1.4589e+00, 1.4473e+00, 1.4360e+00, 1.4252e+00, 1.4149e+00, 1.4050e+00, 1.3954e+00, 1.3859e+00, 1.3764e+00, 1.3668e+00, 1.3575e+00, 1.3484e+00, 1.3398e+00, 1.3316e+00, 1.3237e+00, 1.3161e+00, 1.3084e+00, 1.3005e+00, 1.2926e+00, 1.2849e+00, 1.2773e+00, 1.2701e+00, 1.2633e+00, 1.2568e+00, 1.2505e+00, 1.2442e+00, 1.2377e+00, 1.2310e+00, 1.2243e+00, 1.2178e+00, 1.2115e+00, 1.2055e+00, 1.1997e+00, 1.1943e+00, 1.1890e+00, 1.1837e+00, 1.1781e+00, 1.1722e+00, 1.1663e+00, 1.1605e+00, 1.1549e+00, 1.1496e+00, 1.1444e+00, 1.1396e+00, 1.1350e+00, 1.1304e+00, 1.1255e+00, 1.1204e+00, 1.1150e+00, 1.1097e+00, 1.1044e+00, 1.0994e+00, 1.0945e+00, 1.0899e+00, 1.0855e+00, 1.0814e+00, 1.0772e+00, 1.0728e+00, 1.0680e+00, 1.0630e+00, 1.0580e+00, 1.0531e+00, 1.0483e+00, 1.0436e+00, 1.0392e+00, 1.0349e+00, 1.0309e+00, 1.0271e+00, 1.0233e+00, 1.0190e+00, 1.0144e+00, 1.0096e+00, 1.0047e+00, 1.0001e+00, 9.9550e-01, 9.9100e-01, 9.8670e-01, 9.8260e-01, 9.7870e-01, 9.7510e-01, 9.7150e-01, 9.6770e-01, 9.6340e-01, 9.5870e-01, 9.5400e-01, 9.4930e-01, 9.4490e-01, 9.4050e-01, 9.3620e-01, 9.3200e-01, 9.2800e-01}); + feg = Vctr_cpu({5.5767e+00, 5.4964e+00, 5.2729e+00, 4.9505e+00, 4.5819e+00, 4.2102e+00, 3.8616e+00, 3.5468e+00, 3.2673e+00, 3.0200e+00, 2.8006e+00, 2.6046e+00, 2.4284e+00, 2.2688e+00, 2.1234e+00, 1.9903e+00, 1.8679e+00, 1.7551e+00, 1.6507e+00, 1.5540e+00, 1.4642e+00, 1.3807e+00, 1.3029e+00, 1.2305e+00, 1.1630e+00, 1.1000e+00, 1.0412e+00, 9.8620e-01, 9.3490e-01, 8.8680e-01, 8.4190e-01, 7.9990e-01, 7.6050e-01, 7.2370e-01, 6.8920e-01, 6.5680e-01, 6.2640e-01, 5.9800e-01, 5.7120e-01, 5.4620e-01, 5.2260e-01, 5.0040e-01, 4.7960e-01, 4.5990e-01, 4.4150e-01, 4.2410e-01, 4.0760e-01, 3.9220e-01, 3.7750e-01, 3.6370e-01, 3.5060e-01, 3.3830e-01, 3.2660e-01, 3.1550e-01, 3.0500e-01, 2.9500e-01, 2.8550e-01, 2.7650e-01, 2.6790e-01, 2.5980e-01, 2.5200e-01, 2.4460e-01, 2.3750e-01, 2.3080e-01, 2.2430e-01, 2.1820e-01, 2.1230e-01, 2.0660e-01, 2.0120e-01, 1.9600e-01, 1.9100e-01, 1.8620e-01, 1.8160e-01, 1.7720e-01, 1.7290e-01, 1.6880e-01, 1.6490e-01, 1.6110e-01, 1.5740e-01, 1.5390e-01, 1.5050e-01, 1.4710e-01, 1.4400e-01, 1.4090e-01, 1.3790e-01, 1.3500e-01, 1.3220e-01, 1.2950e-01, 1.2680e-01, 1.2430e-01, 1.2180e-01, 1.1940e-01, 1.1710e-01, 1.1480e-01, 1.1260e-01, 1.1050e-01, 1.0840e-01, 1.0640e-01, 1.0440e-01, 1.0250e-01, 1.0060e-01, 9.8800e-02, 9.7100e-02, 9.5300e-02, 9.3700e-02, 9.2000e-02, 9.0400e-02, 8.8900e-02, 8.7400e-02, 8.5900e-02, 8.4500e-02, 8.3100e-02, 8.1700e-02, 8.0300e-02, 7.9000e-02, 7.7800e-02, 7.6500e-02, 7.5300e-02, 7.4100e-02, 7.2900e-02, 7.1800e-02, 7.0700e-02, 6.9600e-02, 6.8500e-02, 6.7500e-02, 6.6500e-02, 6.5500e-02, 6.4500e-02, 6.3600e-02, 6.2600e-02, 6.1700e-02, 6.0800e-02, 5.9900e-02, 5.9100e-02, 5.8200e-02, 5.7400e-02, 5.6600e-02, 5.5800e-02, 5.5100e-02, 5.4300e-02, 5.3600e-02, 5.2800e-02, 5.2100e-02, 5.1400e-02, 5.0700e-02, 5.0100e-02, 4.9400e-02, 4.8700e-02, 4.8100e-02, 4.7500e-02, 4.6900e-02, 4.6300e-02, 4.5700e-02, 4.5100e-02, 4.4500e-02, 4.4000e-02, 4.3400e-02, 4.2900e-02, 4.2400e-02, 4.1900e-02, 4.1300e-02, 4.0900e-02, 4.0400e-02, 3.9900e-02, 3.9400e-02, 3.8900e-02, 3.8500e-02, 3.8000e-02, 3.7600e-02, 3.7200e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.3900e-02, 3.3600e-02, 3.3200e-02, 3.2800e-02, 3.2500e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1100e-02, 3.0800e-02, 3.0500e-02, 3.0200e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.8900e-02, 2.8600e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02, 2.6700e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5400e-02, 2.5200e-02, 2.5000e-02, 2.4700e-02, 2.4500e-02, 2.4300e-02, 2.4000e-02, 2.3800e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9800e-02, 1.9600e-02, 1.9500e-02, 1.9300e-02, 1.9100e-02, 1.9000e-02, 1.8800e-02, 1.8700e-02}); + } + break; + case 30: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.0000e+01, 2.9844e+01, 2.9401e+01, 2.8736e+01, 2.7926e+01, 2.7040e+01, 2.6123e+01, 2.5200e+01, 2.4283e+01, 2.3375e+01, 2.2478e+01, 2.1592e+01, 2.0720e+01, 1.9864e+01, 1.9026e+01, 1.8211e+01, 1.7421e+01, 1.6658e+01, 1.5926e+01, 1.5225e+01, 1.4558e+01, 1.3925e+01, 1.3327e+01, 1.2764e+01, 1.2234e+01, 1.1738e+01, 1.1275e+01, 1.0843e+01, 1.0441e+01, 1.0069e+01, 9.7231e+00, 9.4031e+00, 9.1071e+00, 8.8336e+00, 8.5809e+00, 8.3474e+00, 8.1315e+00, 7.9319e+00, 7.7471e+00, 7.5757e+00, 7.4165e+00, 7.2683e+00, 7.1300e+00, 7.0004e+00, 6.8787e+00, 6.7640e+00, 6.6554e+00, 6.5522e+00, 6.4537e+00, 6.3594e+00, 6.2687e+00, 6.1810e+00, 6.0959e+00, 6.0132e+00, 5.9323e+00, 5.8531e+00, 5.7752e+00, 5.6984e+00, 5.6226e+00, 5.5476e+00, 5.4732e+00, 5.3994e+00, 5.3261e+00, 5.2531e+00, 5.1804e+00, 5.1081e+00, 5.0361e+00, 4.9643e+00, 4.8928e+00, 4.8215e+00, 4.7506e+00, 4.6799e+00, 4.6096e+00, 4.5397e+00, 4.4701e+00, 4.4010e+00, 4.3324e+00, 4.2642e+00, 4.1966e+00, 4.1296e+00, 4.0632e+00, 3.9974e+00, 3.9323e+00, 3.8679e+00, 3.8043e+00, 3.7415e+00, 3.6795e+00, 3.6182e+00, 3.5579e+00, 3.4985e+00, 3.4400e+00, 3.3824e+00, 3.3256e+00, 3.2699e+00, 3.2152e+00, 3.1615e+00, 3.1087e+00, 3.0568e+00, 3.0060e+00, 2.9562e+00, 2.9075e+00, 2.8598e+00, 2.8130e+00, 2.7671e+00, 2.7223e+00, 2.6785e+00, 2.6359e+00, 2.5942e+00, 2.5533e+00, 2.5132e+00, 2.4742e+00, 2.4362e+00, 2.3993e+00, 2.3633e+00, 2.3281e+00, 2.2936e+00, 2.2599e+00, 2.2272e+00, 2.1955e+00, 2.1648e+00, 2.1348e+00, 2.1054e+00, 2.0766e+00, 2.0485e+00, 2.0214e+00, 1.9952e+00, 1.9699e+00, 1.9452e+00, 1.9210e+00, 1.8971e+00, 1.8739e+00, 1.8514e+00, 1.8299e+00, 1.8091e+00, 1.7890e+00, 1.7692e+00, 1.7496e+00, 1.7304e+00, 1.7118e+00, 1.6939e+00, 1.6768e+00, 1.6604e+00, 1.6444e+00, 1.6286e+00, 1.6129e+00, 1.5974e+00, 1.5824e+00, 1.5680e+00, 1.5543e+00, 1.5412e+00, 1.5286e+00, 1.5160e+00, 1.5035e+00, 1.4910e+00, 1.4786e+00, 1.4668e+00, 1.4556e+00, 1.4450e+00, 1.4349e+00, 1.4250e+00, 1.4151e+00, 1.4050e+00, 1.3949e+00, 1.3849e+00, 1.3753e+00, 1.3663e+00, 1.3578e+00, 1.3498e+00, 1.3420e+00, 1.3341e+00, 1.3261e+00, 1.3179e+00, 1.3096e+00, 1.3015e+00, 1.2938e+00, 1.2866e+00, 1.2799e+00, 1.2735e+00, 1.2673e+00, 1.2610e+00, 1.2544e+00, 1.2475e+00, 1.2404e+00, 1.2335e+00, 1.2270e+00, 1.2209e+00, 1.2153e+00, 1.2100e+00, 1.2048e+00, 1.1996e+00, 1.1942e+00, 1.1885e+00, 1.1824e+00, 1.1762e+00, 1.1702e+00, 1.1646e+00, 1.1595e+00, 1.1547e+00, 1.1501e+00, 1.1457e+00, 1.1412e+00, 1.1366e+00, 1.1316e+00, 1.1262e+00, 1.1205e+00, 1.1150e+00, 1.1098e+00, 1.1050e+00, 1.1006e+00, 1.0965e+00, 1.0924e+00, 1.0885e+00, 1.0845e+00, 1.0803e+00, 1.0756e+00, 1.0705e+00, 1.0652e+00, 1.0600e+00, 1.0551e+00, 1.0507e+00, 1.0466e+00, 1.0427e+00, 1.0389e+00, 1.0352e+00, 1.0316e+00, 1.0278e+00, 1.0237e+00, 1.0191e+00, 1.0141e+00, 1.0089e+00, 1.0040e+00, 9.9950e-01, 9.9540e-01, 9.9160e-01, 9.8790e-01, 9.8430e-01, 9.8080e-01, 9.7730e-01, 9.7380e-01, 9.7000e-01, 9.6570e-01}); + feg = Vctr_cpu({6.0665e+00, 5.9796e+00, 5.7360e+00, 5.3793e+00, 4.9628e+00, 4.5336e+00, 4.1239e+00, 3.7510e+00, 3.4208e+00, 3.1321e+00, 2.8806e+00, 2.6609e+00, 2.4678e+00, 2.2968e+00, 2.1440e+00, 2.0064e+00, 1.8817e+00, 1.7679e+00, 1.6634e+00, 1.5672e+00, 1.4783e+00, 1.3958e+00, 1.3191e+00, 1.2477e+00, 1.1811e+00, 1.1189e+00, 1.0607e+00, 1.0063e+00, 9.5530e-01, 9.0750e-01, 8.6280e-01, 8.2070e-01, 7.8130e-01, 7.4430e-01, 7.0950e-01, 6.7690e-01, 6.4620e-01, 6.1730e-01, 5.9010e-01, 5.6460e-01, 5.4050e-01, 5.1780e-01, 4.9650e-01, 4.7630e-01, 4.5730e-01, 4.3940e-01, 4.2250e-01, 4.0650e-01, 3.9140e-01, 3.7700e-01, 3.6350e-01, 3.5070e-01, 3.3850e-01, 3.2700e-01, 3.1610e-01, 3.0570e-01, 2.9580e-01, 2.8640e-01, 2.7750e-01, 2.6900e-01, 2.6090e-01, 2.5320e-01, 2.4580e-01, 2.3880e-01, 2.3200e-01, 2.2560e-01, 2.1950e-01, 2.1360e-01, 2.0790e-01, 2.0250e-01, 1.9730e-01, 1.9230e-01, 1.8760e-01, 1.8300e-01, 1.7850e-01, 1.7430e-01, 1.7020e-01, 1.6620e-01, 1.6240e-01, 1.5870e-01, 1.5520e-01, 1.5180e-01, 1.4850e-01, 1.4530e-01, 1.4220e-01, 1.3920e-01, 1.3630e-01, 1.3350e-01, 1.3080e-01, 1.2810e-01, 1.2560e-01, 1.2310e-01, 1.2070e-01, 1.1830e-01, 1.1610e-01, 1.1390e-01, 1.1170e-01, 1.0970e-01, 1.0760e-01, 1.0570e-01, 1.0370e-01, 1.0190e-01, 1.0010e-01, 9.8300e-02, 9.6600e-02, 9.4900e-02, 9.3300e-02, 9.1700e-02, 9.0100e-02, 8.8600e-02, 8.7100e-02, 8.5700e-02, 8.4300e-02, 8.2900e-02, 8.1500e-02, 8.0200e-02, 7.8900e-02, 7.7700e-02, 7.6500e-02, 7.5300e-02, 7.4100e-02, 7.3000e-02, 7.1800e-02, 7.0700e-02, 6.9700e-02, 6.8600e-02, 6.7600e-02, 6.6600e-02, 6.5600e-02, 6.4700e-02, 6.3700e-02, 6.2800e-02, 6.1900e-02, 6.1000e-02, 6.0200e-02, 5.9300e-02, 5.8500e-02, 5.7700e-02, 5.6900e-02, 5.6100e-02, 5.5300e-02, 5.4600e-02, 5.3900e-02, 5.3100e-02, 5.2400e-02, 5.1700e-02, 5.1100e-02, 5.0400e-02, 4.9700e-02, 4.9100e-02, 4.8500e-02, 4.7800e-02, 4.7200e-02, 4.6600e-02, 4.6100e-02, 4.5500e-02, 4.4900e-02, 4.4400e-02, 4.3800e-02, 4.3300e-02, 4.2800e-02, 4.2200e-02, 4.1700e-02, 4.1200e-02, 4.0800e-02, 4.0300e-02, 3.9800e-02, 3.9300e-02, 3.8900e-02, 3.8400e-02, 3.8000e-02, 3.7600e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3200e-02, 3.2900e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1500e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7600e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6600e-02, 2.6300e-02, 2.6100e-02, 2.5800e-02, 2.5600e-02, 2.5300e-02, 2.5100e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9500e-02, 1.9300e-02}); + } + break; + case 31: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.1000e+01, 3.0818e+01, 3.0308e+01, 2.9560e+01, 2.8675e+01, 2.7733e+01, 2.6782e+01, 2.5847e+01, 2.4934e+01, 2.4044e+01, 2.3173e+01, 2.2320e+01, 2.1481e+01, 2.0656e+01, 1.9846e+01, 1.9053e+01, 1.8278e+01, 1.7524e+01, 1.6793e+01, 1.6088e+01, 1.5410e+01, 1.4761e+01, 1.4141e+01, 1.3553e+01, 1.2995e+01, 1.2469e+01, 1.1973e+01, 1.1508e+01, 1.1073e+01, 1.0665e+01, 1.0286e+01, 9.9321e+00, 9.6034e+00, 9.2982e+00, 9.0151e+00, 8.7527e+00, 8.5095e+00, 8.2841e+00, 8.0753e+00, 7.8816e+00, 7.7019e+00, 7.5349e+00, 7.3794e+00, 7.2343e+00, 7.0988e+00, 6.9717e+00, 6.8523e+00, 6.7396e+00, 6.6330e+00, 6.5317e+00, 6.4352e+00, 6.3428e+00, 6.2540e+00, 6.1684e+00, 6.0855e+00, 6.0050e+00, 5.9265e+00, 5.8497e+00, 5.7743e+00, 5.7002e+00, 5.6272e+00, 5.5550e+00, 5.4836e+00, 5.4127e+00, 5.3424e+00, 5.2725e+00, 5.2031e+00, 5.1339e+00, 5.0650e+00, 4.9964e+00, 4.9280e+00, 4.8599e+00, 4.7921e+00, 4.7245e+00, 4.6572e+00, 4.5902e+00, 4.5235e+00, 4.4572e+00, 4.3913e+00, 4.3258e+00, 4.2607e+00, 4.1960e+00, 4.1319e+00, 4.0684e+00, 4.0054e+00, 3.9430e+00, 3.8812e+00, 3.8201e+00, 3.7597e+00, 3.7001e+00, 3.6411e+00, 3.5829e+00, 3.5255e+00, 3.4689e+00, 3.4133e+00, 3.3584e+00, 3.3042e+00, 3.2510e+00, 3.1987e+00, 3.1474e+00, 3.0970e+00, 3.0473e+00, 2.9985e+00, 2.9507e+00, 2.9040e+00, 2.8583e+00, 2.8133e+00, 2.7691e+00, 2.7258e+00, 2.6835e+00, 2.6423e+00, 2.6020e+00, 2.5626e+00, 2.5238e+00, 2.4858e+00, 2.4487e+00, 2.4128e+00, 2.3779e+00, 2.3437e+00, 2.3101e+00, 2.2771e+00, 2.2449e+00, 2.2137e+00, 2.1836e+00, 2.1543e+00, 2.1257e+00, 2.0974e+00, 2.0697e+00, 2.0427e+00, 2.0166e+00, 1.9915e+00, 1.9672e+00, 1.9435e+00, 1.9200e+00, 1.8969e+00, 1.8744e+00, 1.8525e+00, 1.8316e+00, 1.8116e+00, 1.7921e+00, 1.7729e+00, 1.7539e+00, 1.7351e+00, 1.7168e+00, 1.6992e+00, 1.6825e+00, 1.6665e+00, 1.6510e+00, 1.6356e+00, 1.6202e+00, 1.6050e+00, 1.5900e+00, 1.5757e+00, 1.5621e+00, 1.5492e+00, 1.5369e+00, 1.5247e+00, 1.5124e+00, 1.5001e+00, 1.4879e+00, 1.4759e+00, 1.4644e+00, 1.4538e+00, 1.4438e+00, 1.4341e+00, 1.4245e+00, 1.4148e+00, 1.4049e+00, 1.3949e+00, 1.3851e+00, 1.3757e+00, 1.3669e+00, 1.3589e+00, 1.3513e+00, 1.3437e+00, 1.3360e+00, 1.3280e+00, 1.3199e+00, 1.3117e+00, 1.3036e+00, 1.2960e+00, 1.2889e+00, 1.2826e+00, 1.2766e+00, 1.2706e+00, 1.2643e+00, 1.2578e+00, 1.2510e+00, 1.2441e+00, 1.2372e+00, 1.2305e+00, 1.2243e+00, 1.2189e+00, 1.2140e+00, 1.2091e+00, 1.2041e+00, 1.1987e+00, 1.1931e+00, 1.1872e+00, 1.1812e+00, 1.1751e+00, 1.1692e+00, 1.1639e+00, 1.1592e+00, 1.1551e+00, 1.1511e+00, 1.1468e+00, 1.1422e+00, 1.1372e+00, 1.1321e+00, 1.1268e+00, 1.1213e+00, 1.1158e+00, 1.1106e+00, 1.1060e+00, 1.1021e+00, 1.0986e+00, 1.0951e+00, 1.0912e+00, 1.0870e+00, 1.0824e+00, 1.0778e+00, 1.0729e+00, 1.0678e+00, 1.0626e+00, 1.0576e+00, 1.0531e+00, 1.0493e+00, 1.0460e+00, 1.0430e+00, 1.0396e+00, 1.0358e+00, 1.0317e+00, 1.0274e+00, 1.0230e+00, 1.0184e+00, 1.0135e+00, 1.0085e+00, 1.0037e+00, 9.9930e-01, 9.9570e-01}); + feg = Vctr_cpu({7.1003e+00, 6.9737e+00, 6.6241e+00, 6.1259e+00, 5.5638e+00, 5.0042e+00, 4.4865e+00, 4.0274e+00, 3.6296e+00, 3.2887e+00, 2.9971e+00, 2.7471e+00, 2.5314e+00, 2.3438e+00, 2.1792e+00, 2.0333e+00, 1.9030e+00, 1.7856e+00, 1.6791e+00, 1.5818e+00, 1.4925e+00, 1.4101e+00, 1.3339e+00, 1.2630e+00, 1.1970e+00, 1.1354e+00, 1.0778e+00, 1.0239e+00, 9.7330e-01, 9.2590e-01, 8.8140e-01, 8.3950e-01, 8.0020e-01, 7.6310e-01, 7.2830e-01, 6.9550e-01, 6.6450e-01, 6.3540e-01, 6.0790e-01, 5.8200e-01, 5.5760e-01, 5.3450e-01, 5.1280e-01, 4.9220e-01, 4.7280e-01, 4.5440e-01, 4.3700e-01, 4.2060e-01, 4.0500e-01, 3.9020e-01, 3.7630e-01, 3.6300e-01, 3.5050e-01, 3.3850e-01, 3.2720e-01, 3.1640e-01, 3.0620e-01, 2.9640e-01, 2.8720e-01, 2.7830e-01, 2.6990e-01, 2.6190e-01, 2.5420e-01, 2.4690e-01, 2.3990e-01, 2.3320e-01, 2.2680e-01, 2.2070e-01, 2.1480e-01, 2.0920e-01, 2.0380e-01, 1.9860e-01, 1.9360e-01, 1.8880e-01, 1.8420e-01, 1.7980e-01, 1.7550e-01, 1.7140e-01, 1.6750e-01, 1.6370e-01, 1.6000e-01, 1.5640e-01, 1.5300e-01, 1.4970e-01, 1.4650e-01, 1.4340e-01, 1.4040e-01, 1.3750e-01, 1.3470e-01, 1.3200e-01, 1.2930e-01, 1.2680e-01, 1.2430e-01, 1.2190e-01, 1.1960e-01, 1.1730e-01, 1.1510e-01, 1.1290e-01, 1.1090e-01, 1.0880e-01, 1.0690e-01, 1.0490e-01, 1.0310e-01, 1.0120e-01, 9.9500e-02, 9.7700e-02, 9.6100e-02, 9.4400e-02, 9.2800e-02, 9.1300e-02, 8.9700e-02, 8.8300e-02, 8.6800e-02, 8.5400e-02, 8.4000e-02, 8.2700e-02, 8.1400e-02, 8.0100e-02, 7.8800e-02, 7.7600e-02, 7.6400e-02, 7.5200e-02, 7.4100e-02, 7.2900e-02, 7.1800e-02, 7.0800e-02, 6.9700e-02, 6.8700e-02, 6.7700e-02, 6.6700e-02, 6.5700e-02, 6.4800e-02, 6.3900e-02, 6.3000e-02, 6.2100e-02, 6.1200e-02, 6.0300e-02, 5.9500e-02, 5.8700e-02, 5.7900e-02, 5.7100e-02, 5.6300e-02, 5.5600e-02, 5.4800e-02, 5.4100e-02, 5.3400e-02, 5.2700e-02, 5.2000e-02, 5.1300e-02, 5.0700e-02, 5.0000e-02, 4.9400e-02, 4.8800e-02, 4.8200e-02, 4.7600e-02, 4.7000e-02, 4.6400e-02, 4.5800e-02, 4.5300e-02, 4.4700e-02, 4.4200e-02, 4.3600e-02, 4.3100e-02, 4.2600e-02, 4.2100e-02, 4.1600e-02, 4.1100e-02, 4.0600e-02, 4.0200e-02, 3.9700e-02, 3.9300e-02, 3.8800e-02, 3.8400e-02, 3.7900e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4400e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.0900e-02, 3.0600e-02, 3.0300e-02, 3.0000e-02, 2.9700e-02, 2.9400e-02, 2.9100e-02, 2.8800e-02, 2.8600e-02, 2.8300e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6700e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4500e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02}); + } + break; + case 32: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.2000e+01, 3.1810e+01, 3.1276e+01, 3.0482e+01, 2.9534e+01, 2.8520e+01, 2.7503e+01, 2.6514e+01, 2.5567e+01, 2.4660e+01, 2.3791e+01, 2.2951e+01, 2.2136e+01, 2.1340e+01, 2.0560e+01, 1.9796e+01, 1.9046e+01, 1.8313e+01, 1.7598e+01, 1.6902e+01, 1.6227e+01, 1.5575e+01, 1.4947e+01, 1.4345e+01, 1.3770e+01, 1.3222e+01, 1.2701e+01, 1.2209e+01, 1.1744e+01, 1.1307e+01, 1.0896e+01, 1.0511e+01, 1.0150e+01, 9.8139e+00, 9.5001e+00, 9.2080e+00, 8.9361e+00, 8.6834e+00, 8.4485e+00, 8.2302e+00, 8.0274e+00, 7.8389e+00, 7.6635e+00, 7.5001e+00, 7.3477e+00, 7.2054e+00, 7.0722e+00, 6.9472e+00, 6.8297e+00, 6.7188e+00, 6.6138e+00, 6.5142e+00, 6.4193e+00, 6.3286e+00, 6.2415e+00, 6.1577e+00, 6.0766e+00, 5.9981e+00, 5.9216e+00, 5.8470e+00, 5.7740e+00, 5.7023e+00, 5.6317e+00, 5.5621e+00, 5.4933e+00, 5.4252e+00, 5.3577e+00, 5.2907e+00, 5.2241e+00, 5.1579e+00, 5.0920e+00, 5.0263e+00, 4.9609e+00, 4.8958e+00, 4.8309e+00, 4.7662e+00, 4.7018e+00, 4.6376e+00, 4.5737e+00, 4.5101e+00, 4.4467e+00, 4.3838e+00, 4.3212e+00, 4.2590e+00, 4.1971e+00, 4.1357e+00, 4.0749e+00, 4.0145e+00, 3.9546e+00, 3.8953e+00, 3.8365e+00, 3.7784e+00, 3.7210e+00, 3.6642e+00, 3.6080e+00, 3.5525e+00, 3.4978e+00, 3.4440e+00, 3.3908e+00, 3.3383e+00, 3.2865e+00, 3.2356e+00, 3.1856e+00, 3.1365e+00, 3.0881e+00, 3.0404e+00, 2.9935e+00, 2.9476e+00, 2.9027e+00, 2.8587e+00, 2.8153e+00, 2.7727e+00, 2.7308e+00, 2.6899e+00, 2.6500e+00, 2.6111e+00, 2.5729e+00, 2.5352e+00, 2.4983e+00, 2.4622e+00, 2.4271e+00, 2.3930e+00, 2.3598e+00, 2.3271e+00, 2.2949e+00, 2.2633e+00, 2.2325e+00, 2.2028e+00, 2.1740e+00, 2.1460e+00, 2.1184e+00, 2.0912e+00, 2.0645e+00, 2.0384e+00, 2.0133e+00, 1.9892e+00, 1.9658e+00, 1.9429e+00, 1.9203e+00, 1.8978e+00, 1.8758e+00, 1.8546e+00, 1.8342e+00, 1.8147e+00, 1.7959e+00, 1.7773e+00, 1.7589e+00, 1.7406e+00, 1.7226e+00, 1.7051e+00, 1.6885e+00, 1.6727e+00, 1.6576e+00, 1.6428e+00, 1.6281e+00, 1.6132e+00, 1.5985e+00, 1.5840e+00, 1.5701e+00, 1.5571e+00, 1.5448e+00, 1.5330e+00, 1.5214e+00, 1.5097e+00, 1.4978e+00, 1.4859e+00, 1.4741e+00, 1.4628e+00, 1.4523e+00, 1.4426e+00, 1.4333e+00, 1.4242e+00, 1.4151e+00, 1.4057e+00, 1.3960e+00, 1.3862e+00, 1.3767e+00, 1.3677e+00, 1.3596e+00, 1.3521e+00, 1.3449e+00, 1.3378e+00, 1.3305e+00, 1.3230e+00, 1.3151e+00, 1.3070e+00, 1.2989e+00, 1.2913e+00, 1.2845e+00, 1.2784e+00, 1.2727e+00, 1.2671e+00, 1.2614e+00, 1.2554e+00, 1.2490e+00, 1.2423e+00, 1.2353e+00, 1.2285e+00, 1.2221e+00, 1.2165e+00, 1.2116e+00, 1.2070e+00, 1.2025e+00, 1.1978e+00, 1.1928e+00, 1.1875e+00, 1.1818e+00, 1.1757e+00, 1.1695e+00, 1.1636e+00, 1.1584e+00, 1.1539e+00, 1.1500e+00, 1.1463e+00, 1.1424e+00, 1.1383e+00, 1.1339e+00, 1.1292e+00, 1.1241e+00, 1.1185e+00, 1.1128e+00, 1.1073e+00, 1.1025e+00, 1.0984e+00, 1.0949e+00, 1.0917e+00, 1.0884e+00, 1.0848e+00, 1.0810e+00, 1.0769e+00, 1.0725e+00, 1.0676e+00, 1.0623e+00, 1.0568e+00, 1.0517e+00, 1.0473e+00, 1.0436e+00, 1.0406e+00, 1.0377e+00, 1.0347e+00, 1.0314e+00}); + feg = Vctr_cpu({7.3784e+00, 7.2619e+00, 6.9356e+00, 6.4585e+00, 5.9023e+00, 5.3297e+00, 4.7835e+00, 4.2872e+00, 3.8494e+00, 3.4699e+00, 3.1435e+00, 2.8636e+00, 2.6231e+00, 2.4155e+00, 2.2351e+00, 2.0771e+00, 1.9377e+00, 1.8136e+00, 1.7022e+00, 1.6016e+00, 1.5101e+00, 1.4263e+00, 1.3492e+00, 1.2780e+00, 1.2120e+00, 1.1506e+00, 1.0932e+00, 1.0396e+00, 9.8940e-01, 9.4220e-01, 8.9800e-01, 8.5630e-01, 8.1710e-01, 7.8020e-01, 7.4530e-01, 7.1250e-01, 6.8150e-01, 6.5220e-01, 6.2460e-01, 5.9840e-01, 5.7380e-01, 5.5040e-01, 5.2830e-01, 5.0740e-01, 4.8760e-01, 4.6890e-01, 4.5110e-01, 4.3430e-01, 4.1830e-01, 4.0320e-01, 3.8890e-01, 3.7520e-01, 3.6230e-01, 3.5000e-01, 3.3830e-01, 3.2710e-01, 3.1660e-01, 3.0650e-01, 2.9690e-01, 2.8770e-01, 2.7900e-01, 2.7060e-01, 2.6270e-01, 2.5510e-01, 2.4780e-01, 2.4090e-01, 2.3420e-01, 2.2780e-01, 2.2170e-01, 2.1590e-01, 2.1030e-01, 2.0490e-01, 1.9970e-01, 1.9480e-01, 1.9000e-01, 1.8540e-01, 1.8100e-01, 1.7670e-01, 1.7260e-01, 1.6870e-01, 1.6490e-01, 1.6120e-01, 1.5760e-01, 1.5420e-01, 1.5090e-01, 1.4770e-01, 1.4460e-01, 1.4160e-01, 1.3870e-01, 1.3590e-01, 1.3310e-01, 1.3050e-01, 1.2790e-01, 1.2550e-01, 1.2300e-01, 1.2070e-01, 1.1840e-01, 1.1620e-01, 1.1410e-01, 1.1200e-01, 1.1000e-01, 1.0800e-01, 1.0610e-01, 1.0420e-01, 1.0240e-01, 1.0060e-01, 9.8900e-02, 9.7200e-02, 9.5500e-02, 9.3900e-02, 9.2400e-02, 9.0800e-02, 8.9400e-02, 8.7900e-02, 8.6500e-02, 8.5100e-02, 8.3700e-02, 8.2400e-02, 8.1100e-02, 7.9900e-02, 7.8600e-02, 7.7400e-02, 7.6300e-02, 7.5100e-02, 7.4000e-02, 7.2900e-02, 7.1800e-02, 7.0700e-02, 6.9700e-02, 6.8700e-02, 6.7700e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3100e-02, 6.2200e-02, 6.1300e-02, 6.0500e-02, 5.9700e-02, 5.8900e-02, 5.8100e-02, 5.7300e-02, 5.6500e-02, 5.5800e-02, 5.5000e-02, 5.4300e-02, 5.3600e-02, 5.2900e-02, 5.2300e-02, 5.1600e-02, 5.0900e-02, 5.0300e-02, 4.9700e-02, 4.9000e-02, 4.8400e-02, 4.7800e-02, 4.7300e-02, 4.6700e-02, 4.6100e-02, 4.5600e-02, 4.5000e-02, 4.4500e-02, 4.3900e-02, 4.3400e-02, 4.2900e-02, 4.2400e-02, 4.1900e-02, 4.1400e-02, 4.1000e-02, 4.0500e-02, 4.0000e-02, 3.9600e-02, 3.9100e-02, 3.8700e-02, 3.8300e-02, 3.7900e-02, 3.7400e-02, 3.7000e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.8900e-02, 2.8600e-02, 2.8300e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6500e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5600e-02, 2.5300e-02, 2.5100e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3800e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0800e-02, 2.0600e-02}); + } + break; + case 33: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.3000e+01, 3.2811e+01, 3.2273e+01, 3.1460e+01, 3.0471e+01, 2.9395e+01, 2.8305e+01, 2.7244e+01, 2.6234e+01, 2.5283e+01, 2.4386e+01, 2.3536e+01, 2.2724e+01, 2.1943e+01, 2.1186e+01, 2.0448e+01, 1.9726e+01, 1.9019e+01, 1.8326e+01, 1.7649e+01, 1.6988e+01, 1.6345e+01, 1.5721e+01, 1.5117e+01, 1.4534e+01, 1.3975e+01, 1.3439e+01, 1.2928e+01, 1.2441e+01, 1.1979e+01, 1.1541e+01, 1.1129e+01, 1.0740e+01, 1.0374e+01, 1.0031e+01, 9.7103e+00, 9.4099e+00, 9.1293e+00, 8.8675e+00, 8.6233e+00, 8.3958e+00, 8.1838e+00, 7.9863e+00, 7.8023e+00, 7.6306e+00, 7.4705e+00, 7.3209e+00, 7.1809e+00, 7.0497e+00, 6.9265e+00, 6.8105e+00, 6.7011e+00, 6.5976e+00, 6.4994e+00, 6.4059e+00, 6.3166e+00, 6.2310e+00, 6.1487e+00, 6.0693e+00, 5.9925e+00, 5.9179e+00, 5.8452e+00, 5.7742e+00, 5.7046e+00, 5.6363e+00, 5.5690e+00, 5.5027e+00, 5.4371e+00, 5.3721e+00, 5.3077e+00, 5.2438e+00, 5.1803e+00, 5.1171e+00, 5.0542e+00, 4.9916e+00, 4.9293e+00, 4.8671e+00, 4.8052e+00, 4.7435e+00, 4.6820e+00, 4.6208e+00, 4.5597e+00, 4.4990e+00, 4.4385e+00, 4.3783e+00, 4.3184e+00, 4.2588e+00, 4.1996e+00, 4.1408e+00, 4.0824e+00, 4.0245e+00, 3.9670e+00, 3.9099e+00, 3.8535e+00, 3.7976e+00, 3.7422e+00, 3.6873e+00, 3.6331e+00, 3.5795e+00, 3.5266e+00, 3.4744e+00, 3.4227e+00, 3.3718e+00, 3.3215e+00, 3.2721e+00, 3.2234e+00, 3.1754e+00, 3.1281e+00, 3.0815e+00, 3.0357e+00, 2.9908e+00, 2.9468e+00, 2.9034e+00, 2.8606e+00, 2.8186e+00, 2.7774e+00, 2.7372e+00, 2.6978e+00, 2.6592e+00, 2.6211e+00, 2.5837e+00, 2.5471e+00, 2.5113e+00, 2.4765e+00, 2.4425e+00, 2.4091e+00, 2.3762e+00, 2.3440e+00, 2.3124e+00, 2.2817e+00, 2.2519e+00, 2.2230e+00, 2.1946e+00, 2.1666e+00, 2.1390e+00, 2.1120e+00, 2.0858e+00, 2.0605e+00, 2.0361e+00, 2.0122e+00, 1.9887e+00, 1.9655e+00, 1.9426e+00, 1.9203e+00, 1.8987e+00, 1.8780e+00, 1.8581e+00, 1.8387e+00, 1.8195e+00, 1.8004e+00, 1.7816e+00, 1.7631e+00, 1.7453e+00, 1.7283e+00, 1.7120e+00, 1.6963e+00, 1.6809e+00, 1.6655e+00, 1.6501e+00, 1.6348e+00, 1.6199e+00, 1.6056e+00, 1.5922e+00, 1.5794e+00, 1.5671e+00, 1.5549e+00, 1.5427e+00, 1.5302e+00, 1.5178e+00, 1.5056e+00, 1.4940e+00, 1.4831e+00, 1.4729e+00, 1.4632e+00, 1.4537e+00, 1.4441e+00, 1.4342e+00, 1.4241e+00, 1.4140e+00, 1.4041e+00, 1.3948e+00, 1.3862e+00, 1.3783e+00, 1.3709e+00, 1.3635e+00, 1.3559e+00, 1.3480e+00, 1.3398e+00, 1.3314e+00, 1.3231e+00, 1.3152e+00, 1.3080e+00, 1.3015e+00, 1.2956e+00, 1.2899e+00, 1.2840e+00, 1.2779e+00, 1.2713e+00, 1.2644e+00, 1.2573e+00, 1.2502e+00, 1.2435e+00, 1.2375e+00, 1.2322e+00, 1.2275e+00, 1.2231e+00, 1.2184e+00, 1.2135e+00, 1.2080e+00, 1.2022e+00, 1.1961e+00, 1.1898e+00, 1.1837e+00, 1.1781e+00, 1.1732e+00, 1.1690e+00, 1.1653e+00, 1.1617e+00, 1.1578e+00, 1.1535e+00, 1.1488e+00, 1.1437e+00, 1.1382e+00, 1.1325e+00, 1.1269e+00, 1.1216e+00, 1.1170e+00, 1.1132e+00, 1.1100e+00, 1.1070e+00, 1.1039e+00, 1.1003e+00, 1.0963e+00, 1.0919e+00, 1.0871e+00, 1.0820e+00, 1.0767e+00, 1.0714e+00, 1.0665e+00, 1.0622e+00, 1.0587e+00}); + feg = Vctr_cpu({7.3340e+00, 7.2375e+00, 6.9633e+00, 6.5514e+00, 6.0541e+00, 5.5219e+00, 4.9946e+00, 4.4986e+00, 4.0482e+00, 3.6484e+00, 3.2987e+00, 2.9952e+00, 2.7326e+00, 2.5054e+00, 2.3083e+00, 2.1364e+00, 1.9856e+00, 1.8526e+00, 1.7343e+00, 1.6284e+00, 1.5329e+00, 1.4462e+00, 1.3671e+00, 1.2946e+00, 1.2276e+00, 1.1657e+00, 1.1081e+00, 1.0544e+00, 1.0042e+00, 9.5720e-01, 9.1300e-01, 8.7150e-01, 8.3240e-01, 7.9560e-01, 7.6090e-01, 7.2800e-01, 6.9700e-01, 6.6770e-01, 6.4000e-01, 6.1370e-01, 5.8890e-01, 5.6530e-01, 5.4300e-01, 5.2190e-01, 5.0180e-01, 4.8280e-01, 4.6470e-01, 4.4760e-01, 4.3130e-01, 4.1590e-01, 4.0120e-01, 3.8720e-01, 3.7390e-01, 3.6130e-01, 3.4920e-01, 3.3780e-01, 3.2690e-01, 3.1650e-01, 3.0660e-01, 2.9710e-01, 2.8810e-01, 2.7950e-01, 2.7120e-01, 2.6340e-01, 2.5580e-01, 2.4860e-01, 2.4170e-01, 2.3510e-01, 2.2880e-01, 2.2270e-01, 2.1690e-01, 2.1130e-01, 2.0600e-01, 2.0080e-01, 1.9590e-01, 1.9110e-01, 1.8650e-01, 1.8210e-01, 1.7790e-01, 1.7380e-01, 1.6980e-01, 1.6600e-01, 1.6230e-01, 1.5880e-01, 1.5530e-01, 1.5200e-01, 1.4880e-01, 1.4570e-01, 1.4270e-01, 1.3980e-01, 1.3700e-01, 1.3430e-01, 1.3160e-01, 1.2900e-01, 1.2660e-01, 1.2410e-01, 1.2180e-01, 1.1950e-01, 1.1730e-01, 1.1520e-01, 1.1310e-01, 1.1100e-01, 1.0910e-01, 1.0710e-01, 1.0530e-01, 1.0340e-01, 1.0160e-01, 9.9900e-02, 9.8200e-02, 9.6600e-02, 9.5000e-02, 9.3400e-02, 9.1900e-02, 9.0400e-02, 8.8900e-02, 8.7500e-02, 8.6100e-02, 8.4800e-02, 8.3400e-02, 8.2100e-02, 8.0900e-02, 7.9700e-02, 7.8400e-02, 7.7300e-02, 7.6100e-02, 7.5000e-02, 7.3900e-02, 7.2800e-02, 7.1700e-02, 7.0700e-02, 6.9700e-02, 6.8700e-02, 6.7700e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3100e-02, 6.2300e-02, 6.1400e-02, 6.0600e-02, 5.9800e-02, 5.9000e-02, 5.8200e-02, 5.7400e-02, 5.6700e-02, 5.5900e-02, 5.5200e-02, 5.4500e-02, 5.3800e-02, 5.3100e-02, 5.2500e-02, 5.1800e-02, 5.1200e-02, 5.0500e-02, 4.9900e-02, 4.9300e-02, 4.8700e-02, 4.8100e-02, 4.7500e-02, 4.6900e-02, 4.6400e-02, 4.5800e-02, 4.5300e-02, 4.4800e-02, 4.4200e-02, 4.3700e-02, 4.3200e-02, 4.2700e-02, 4.2200e-02, 4.1700e-02, 4.1300e-02, 4.0800e-02, 4.0400e-02, 3.9900e-02, 3.9500e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7400e-02, 3.7000e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5400e-02, 3.5000e-02, 3.4700e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8400e-02, 2.8100e-02, 2.7900e-02, 2.7600e-02, 2.7400e-02, 2.7100e-02, 2.6900e-02, 2.6600e-02, 2.6400e-02, 2.6100e-02, 2.5900e-02, 2.5700e-02, 2.5400e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4500e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02}); + } + break; + case 34: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.4000e+01, 3.3814e+01, 3.3279e+01, 3.2461e+01, 3.1447e+01, 3.0326e+01, 2.9173e+01, 2.8041e+01, 2.6960e+01, 2.5947e+01, 2.5001e+01, 2.4117e+01, 2.3288e+01, 2.2502e+01, 2.1752e+01, 2.1029e+01, 2.0328e+01, 1.9645e+01, 1.8977e+01, 1.8323e+01, 1.7682e+01, 1.7056e+01, 1.6444e+01, 1.5848e+01, 1.5268e+01, 1.4707e+01, 1.4166e+01, 1.3644e+01, 1.3144e+01, 1.2665e+01, 1.2208e+01, 1.1774e+01, 1.1361e+01, 1.0971e+01, 1.0602e+01, 1.0254e+01, 9.9266e+00, 9.6192e+00, 9.3308e+00, 9.0606e+00, 8.8078e+00, 8.5714e+00, 8.3505e+00, 8.1441e+00, 7.9513e+00, 7.7713e+00, 7.6030e+00, 7.4457e+00, 7.2984e+00, 7.1605e+00, 7.0310e+00, 6.9094e+00, 6.7948e+00, 6.6866e+00, 6.5843e+00, 6.4873e+00, 6.3949e+00, 6.3068e+00, 6.2225e+00, 6.1415e+00, 6.0635e+00, 5.9882e+00, 5.9152e+00, 5.8442e+00, 5.7750e+00, 5.7073e+00, 5.6410e+00, 5.5758e+00, 5.5116e+00, 5.4483e+00, 5.3857e+00, 5.3237e+00, 5.2622e+00, 5.2012e+00, 5.1405e+00, 5.0802e+00, 5.0202e+00, 4.9604e+00, 4.9009e+00, 4.8416e+00, 4.7824e+00, 4.7235e+00, 4.6648e+00, 4.6063e+00, 4.5479e+00, 4.4898e+00, 4.4320e+00, 4.3743e+00, 4.3170e+00, 4.2600e+00, 4.2032e+00, 4.1468e+00, 4.0908e+00, 4.0351e+00, 3.9799e+00, 3.9250e+00, 3.8706e+00, 3.8167e+00, 3.7633e+00, 3.7104e+00, 3.6581e+00, 3.6062e+00, 3.5550e+00, 3.5043e+00, 3.4543e+00, 3.4049e+00, 3.3561e+00, 3.3079e+00, 3.2604e+00, 3.2136e+00, 3.1675e+00, 3.1221e+00, 3.0773e+00, 3.0332e+00, 2.9898e+00, 2.9471e+00, 2.9052e+00, 2.8641e+00, 2.8237e+00, 2.7839e+00, 2.7447e+00, 2.7062e+00, 2.6686e+00, 2.6318e+00, 2.5957e+00, 2.5603e+00, 2.5254e+00, 2.4912e+00, 2.4576e+00, 2.4249e+00, 2.3930e+00, 2.3618e+00, 2.3312e+00, 2.3011e+00, 2.2715e+00, 2.2425e+00, 2.2142e+00, 2.1868e+00, 2.1601e+00, 2.1341e+00, 2.1085e+00, 2.0832e+00, 2.0584e+00, 2.0341e+00, 2.0106e+00, 1.9878e+00, 1.9658e+00, 1.9443e+00, 1.9231e+00, 1.9022e+00, 1.8815e+00, 1.8613e+00, 1.8417e+00, 1.8228e+00, 1.8047e+00, 1.7872e+00, 1.7699e+00, 1.7528e+00, 1.7357e+00, 1.7189e+00, 1.7025e+00, 1.6867e+00, 1.6717e+00, 1.6573e+00, 1.6434e+00, 1.6296e+00, 1.6159e+00, 1.6021e+00, 1.5884e+00, 1.5750e+00, 1.5621e+00, 1.5499e+00, 1.5384e+00, 1.5274e+00, 1.5166e+00, 1.5057e+00, 1.4947e+00, 1.4836e+00, 1.4725e+00, 1.4616e+00, 1.4513e+00, 1.4418e+00, 1.4328e+00, 1.4243e+00, 1.4159e+00, 1.4074e+00, 1.3987e+00, 1.3896e+00, 1.3805e+00, 1.3715e+00, 1.3629e+00, 1.3550e+00, 1.3477e+00, 1.3410e+00, 1.3346e+00, 1.3280e+00, 1.3212e+00, 1.3140e+00, 1.3065e+00, 1.2988e+00, 1.2913e+00, 1.2842e+00, 1.2777e+00, 1.2719e+00, 1.2666e+00, 1.2616e+00, 1.2566e+00, 1.2512e+00, 1.2453e+00, 1.2391e+00, 1.2326e+00, 1.2259e+00, 1.2196e+00, 1.2137e+00, 1.2085e+00, 1.2039e+00, 1.1999e+00, 1.1960e+00, 1.1919e+00, 1.1874e+00, 1.1824e+00, 1.1770e+00, 1.1712e+00, 1.1653e+00, 1.1595e+00, 1.1541e+00, 1.1494e+00, 1.1454e+00, 1.1420e+00, 1.1388e+00, 1.1356e+00, 1.1320e+00, 1.1280e+00, 1.1234e+00, 1.1184e+00, 1.1131e+00, 1.1076e+00, 1.1023e+00, 1.0973e+00, 1.0930e+00, 1.0894e+00}); + feg = Vctr_cpu({7.2181e+00, 7.1373e+00, 6.9052e+00, 6.5505e+00, 6.1115e+00, 5.6281e+00, 5.1349e+00, 4.6574e+00, 4.2120e+00, 3.8073e+00, 3.4461e+00, 3.1276e+00, 2.8487e+00, 2.6053e+00, 2.3930e+00, 2.2076e+00, 2.0451e+00, 1.9021e+00, 1.7756e+00, 1.6630e+00, 1.5622e+00, 1.4713e+00, 1.3890e+00, 1.3140e+00, 1.2453e+00, 1.1821e+00, 1.1236e+00, 1.0693e+00, 1.0187e+00, 9.7150e-01, 9.2720e-01, 8.8570e-01, 8.4660e-01, 8.0980e-01, 7.7510e-01, 7.4230e-01, 7.1130e-01, 6.8200e-01, 6.5420e-01, 6.2790e-01, 6.0290e-01, 5.7930e-01, 5.5680e-01, 5.3550e-01, 5.1520e-01, 4.9600e-01, 4.7770e-01, 4.6030e-01, 4.4380e-01, 4.2810e-01, 4.1310e-01, 3.9880e-01, 3.8530e-01, 3.7240e-01, 3.6000e-01, 3.4830e-01, 3.3710e-01, 3.2640e-01, 3.1620e-01, 3.0650e-01, 2.9720e-01, 2.8830e-01, 2.7980e-01, 2.7170e-01, 2.6390e-01, 2.5640e-01, 2.4930e-01, 2.4250e-01, 2.3590e-01, 2.2960e-01, 2.2360e-01, 2.1780e-01, 2.1230e-01, 2.0690e-01, 2.0180e-01, 1.9690e-01, 1.9210e-01, 1.8760e-01, 1.8320e-01, 1.7890e-01, 1.7480e-01, 1.7090e-01, 1.6710e-01, 1.6340e-01, 1.5980e-01, 1.5640e-01, 1.5310e-01, 1.4990e-01, 1.4680e-01, 1.4380e-01, 1.4090e-01, 1.3810e-01, 1.3530e-01, 1.3270e-01, 1.3010e-01, 1.2760e-01, 1.2520e-01, 1.2280e-01, 1.2060e-01, 1.1830e-01, 1.1620e-01, 1.1410e-01, 1.1210e-01, 1.1010e-01, 1.0810e-01, 1.0630e-01, 1.0440e-01, 1.0270e-01, 1.0090e-01, 9.9200e-02, 9.7600e-02, 9.6000e-02, 9.4400e-02, 9.2900e-02, 9.1400e-02, 8.9900e-02, 8.8500e-02, 8.7100e-02, 8.5700e-02, 8.4400e-02, 8.3100e-02, 8.1800e-02, 8.0600e-02, 7.9400e-02, 7.8200e-02, 7.7100e-02, 7.5900e-02, 7.4800e-02, 7.3700e-02, 7.2700e-02, 7.1600e-02, 7.0600e-02, 6.9600e-02, 6.8600e-02, 6.7700e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3200e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9100e-02, 5.8300e-02, 5.7500e-02, 5.6800e-02, 5.6100e-02, 5.5400e-02, 5.4700e-02, 5.4000e-02, 5.3300e-02, 5.2600e-02, 5.2000e-02, 5.1300e-02, 5.0700e-02, 5.0100e-02, 4.9500e-02, 4.8900e-02, 4.8300e-02, 4.7700e-02, 4.7200e-02, 4.6600e-02, 4.6100e-02, 4.5500e-02, 4.5000e-02, 4.4500e-02, 4.4000e-02, 4.3500e-02, 4.3000e-02, 4.2500e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0600e-02, 4.0200e-02, 3.9700e-02, 3.9300e-02, 3.8900e-02, 3.8500e-02, 3.8100e-02, 3.7700e-02, 3.7200e-02, 3.6900e-02, 3.6500e-02, 3.6100e-02, 3.5700e-02, 3.5300e-02, 3.5000e-02, 3.4600e-02, 3.4300e-02, 3.3900e-02, 3.3600e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7700e-02, 2.7400e-02, 2.7200e-02, 2.6900e-02, 2.6700e-02, 2.6400e-02, 2.6200e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5300e-02, 2.5100e-02, 2.4800e-02, 2.4600e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3800e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2100e-02, 2.1900e-02}); + } + break; + case 35: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.5000e+01, 3.4817e+01, 3.4290e+01, 3.3474e+01, 3.2448e+01, 3.1296e+01, 3.0093e+01, 2.8897e+01, 2.7747e+01, 2.6664e+01, 2.5657e+01, 2.4724e+01, 2.3857e+01, 2.3049e+01, 2.2288e+01, 2.1566e+01, 2.0875e+01, 2.0207e+01, 1.9559e+01, 1.8926e+01, 1.8307e+01, 1.7701e+01, 1.7107e+01, 1.6526e+01, 1.5958e+01, 1.5404e+01, 1.4865e+01, 1.4342e+01, 1.3836e+01, 1.3349e+01, 1.2880e+01, 1.2430e+01, 1.2000e+01, 1.1590e+01, 1.1200e+01, 1.0829e+01, 1.0479e+01, 1.0147e+01, 9.8336e+00, 9.5386e+00, 9.2611e+00, 9.0004e+00, 8.7558e+00, 8.5264e+00, 8.3115e+00, 8.1102e+00, 7.9217e+00, 7.7453e+00, 7.5800e+00, 7.4253e+00, 7.2801e+00, 7.1440e+00, 7.0160e+00, 6.8957e+00, 6.7823e+00, 6.6752e+00, 6.5738e+00, 6.4777e+00, 6.3864e+00, 6.2992e+00, 6.2160e+00, 6.1361e+00, 6.0593e+00, 5.9852e+00, 5.9136e+00, 5.8441e+00, 5.7764e+00, 5.7104e+00, 5.6458e+00, 5.5825e+00, 5.5202e+00, 5.4589e+00, 5.3984e+00, 5.3386e+00, 5.2793e+00, 5.2206e+00, 5.1623e+00, 5.1044e+00, 5.0467e+00, 4.9894e+00, 4.9323e+00, 4.8754e+00, 4.8187e+00, 4.7622e+00, 4.7059e+00, 4.6497e+00, 4.5937e+00, 4.5379e+00, 4.4823e+00, 4.4269e+00, 4.3718e+00, 4.3168e+00, 4.2621e+00, 4.2077e+00, 4.1536e+00, 4.0998e+00, 4.0463e+00, 3.9931e+00, 3.9403e+00, 3.8880e+00, 3.8360e+00, 3.7845e+00, 3.7334e+00, 3.6827e+00, 3.6326e+00, 3.5830e+00, 3.5340e+00, 3.4854e+00, 3.4374e+00, 3.3899e+00, 3.3431e+00, 3.2968e+00, 3.2512e+00, 3.2062e+00, 3.1617e+00, 3.1179e+00, 3.0747e+00, 3.0323e+00, 2.9905e+00, 2.9493e+00, 2.9087e+00, 2.8688e+00, 2.8295e+00, 2.7910e+00, 2.7531e+00, 2.7160e+00, 2.6794e+00, 2.6435e+00, 2.6081e+00, 2.5735e+00, 2.5396e+00, 2.5064e+00, 2.4739e+00, 2.4419e+00, 2.4104e+00, 2.3796e+00, 2.3493e+00, 2.3198e+00, 2.2910e+00, 2.2629e+00, 2.2353e+00, 2.2082e+00, 2.1815e+00, 2.1553e+00, 2.1298e+00, 2.1049e+00, 2.0808e+00, 2.0573e+00, 2.0342e+00, 2.0115e+00, 1.9891e+00, 1.9671e+00, 1.9456e+00, 1.9248e+00, 1.9047e+00, 1.8852e+00, 1.8662e+00, 1.8474e+00, 1.8288e+00, 1.8104e+00, 1.7924e+00, 1.7750e+00, 1.7582e+00, 1.7420e+00, 1.7263e+00, 1.7110e+00, 1.6958e+00, 1.6807e+00, 1.6657e+00, 1.6510e+00, 1.6367e+00, 1.6230e+00, 1.6100e+00, 1.5974e+00, 1.5852e+00, 1.5731e+00, 1.5610e+00, 1.5488e+00, 1.5366e+00, 1.5248e+00, 1.5134e+00, 1.5026e+00, 1.4924e+00, 1.4826e+00, 1.4731e+00, 1.4636e+00, 1.4539e+00, 1.4440e+00, 1.4341e+00, 1.4243e+00, 1.4150e+00, 1.4062e+00, 1.3980e+00, 1.3903e+00, 1.3829e+00, 1.3755e+00, 1.3679e+00, 1.3600e+00, 1.3518e+00, 1.3436e+00, 1.3356e+00, 1.3280e+00, 1.3210e+00, 1.3145e+00, 1.3086e+00, 1.3029e+00, 1.2971e+00, 1.2911e+00, 1.2847e+00, 1.2779e+00, 1.2709e+00, 1.2640e+00, 1.2574e+00, 1.2513e+00, 1.2459e+00, 1.2409e+00, 1.2364e+00, 1.2320e+00, 1.2274e+00, 1.2224e+00, 1.2169e+00, 1.2110e+00, 1.2049e+00, 1.1988e+00, 1.1930e+00, 1.1878e+00, 1.1830e+00, 1.1789e+00, 1.1752e+00, 1.1718e+00, 1.1682e+00, 1.1642e+00, 1.1597e+00, 1.1546e+00, 1.1492e+00, 1.1436e+00, 1.1382e+00, 1.1331e+00, 1.1285e+00, 1.1244e+00, 1.1210e+00}); + feg = Vctr_cpu({7.0661e+00, 6.9977e+00, 6.8001e+00, 6.4938e+00, 6.1077e+00, 5.6733e+00, 5.2194e+00, 4.7693e+00, 4.3397e+00, 3.9408e+00, 3.5778e+00, 3.2523e+00, 2.9632e+00, 2.7080e+00, 2.4836e+00, 2.2864e+00, 2.1129e+00, 1.9601e+00, 1.8250e+00, 1.7051e+00, 1.5981e+00, 1.5021e+00, 1.4157e+00, 1.3373e+00, 1.2660e+00, 1.2007e+00, 1.1406e+00, 1.0851e+00, 1.0337e+00, 9.8590e-01, 9.4120e-01, 8.9940e-01, 8.6010e-01, 8.2320e-01, 7.8840e-01, 7.5560e-01, 7.2460e-01, 6.9520e-01, 6.6740e-01, 6.4100e-01, 6.1600e-01, 5.9230e-01, 5.6970e-01, 5.4830e-01, 5.2790e-01, 5.0850e-01, 4.9000e-01, 4.7250e-01, 4.5570e-01, 4.3980e-01, 4.2460e-01, 4.1010e-01, 3.9630e-01, 3.8310e-01, 3.7060e-01, 3.5860e-01, 3.4710e-01, 3.3620e-01, 3.2570e-01, 3.1570e-01, 3.0620e-01, 2.9700e-01, 2.8830e-01, 2.7990e-01, 2.7190e-01, 2.6430e-01, 2.5690e-01, 2.4990e-01, 2.4310e-01, 2.3660e-01, 2.3040e-01, 2.2440e-01, 2.1870e-01, 2.1310e-01, 2.0780e-01, 2.0270e-01, 1.9780e-01, 1.9310e-01, 1.8850e-01, 1.8410e-01, 1.7990e-01, 1.7580e-01, 1.7190e-01, 1.6810e-01, 1.6440e-01, 1.6090e-01, 1.5740e-01, 1.5410e-01, 1.5090e-01, 1.4780e-01, 1.4480e-01, 1.4190e-01, 1.3910e-01, 1.3630e-01, 1.3370e-01, 1.3110e-01, 1.2860e-01, 1.2620e-01, 1.2380e-01, 1.2160e-01, 1.1930e-01, 1.1720e-01, 1.1510e-01, 1.1300e-01, 1.1110e-01, 1.0910e-01, 1.0720e-01, 1.0540e-01, 1.0360e-01, 1.0190e-01, 1.0020e-01, 9.8500e-02, 9.6900e-02, 9.5300e-02, 9.3800e-02, 9.2300e-02, 9.0900e-02, 8.9400e-02, 8.8000e-02, 8.6700e-02, 8.5300e-02, 8.4000e-02, 8.2800e-02, 8.1500e-02, 8.0300e-02, 7.9100e-02, 7.8000e-02, 7.6800e-02, 7.5700e-02, 7.4600e-02, 7.3600e-02, 7.2500e-02, 7.1500e-02, 7.0500e-02, 6.9500e-02, 6.8500e-02, 6.7600e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3200e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9100e-02, 5.8400e-02, 5.7600e-02, 5.6900e-02, 5.6200e-02, 5.5500e-02, 5.4800e-02, 5.4100e-02, 5.3400e-02, 5.2800e-02, 5.2100e-02, 5.1500e-02, 5.0900e-02, 5.0300e-02, 4.9700e-02, 4.9100e-02, 4.8500e-02, 4.7900e-02, 4.7400e-02, 4.6800e-02, 4.6300e-02, 4.5800e-02, 4.5200e-02, 4.4700e-02, 4.4200e-02, 4.3700e-02, 4.3200e-02, 4.2700e-02, 4.2300e-02, 4.1800e-02, 4.1300e-02, 4.0900e-02, 4.0400e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8700e-02, 3.8300e-02, 3.7900e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6400e-02, 3.6000e-02, 3.5600e-02, 3.5300e-02, 3.4900e-02, 3.4600e-02, 3.4200e-02, 3.3900e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02, 2.6700e-02, 2.6500e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5600e-02, 2.5400e-02, 2.5100e-02, 2.4900e-02, 2.4700e-02, 2.4500e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02}); + } + break; + case 36: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.6000e+01, 3.5821e+01, 3.5303e+01, 3.4495e+01, 3.3466e+01, 3.2295e+01, 3.1054e+01, 2.9804e+01, 2.8590e+01, 2.7438e+01, 2.6363e+01, 2.5369e+01, 2.4453e+01, 2.3606e+01, 2.2820e+01, 2.2083e+01, 2.1387e+01, 2.0724e+01, 2.0087e+01, 1.9470e+01, 1.8870e+01, 1.8284e+01, 1.7709e+01, 1.7146e+01, 1.6594e+01, 1.6053e+01, 1.5523e+01, 1.5007e+01, 1.4504e+01, 1.4015e+01, 1.3542e+01, 1.3084e+01, 1.2644e+01, 1.2220e+01, 1.1814e+01, 1.1426e+01, 1.1056e+01, 1.0703e+01, 1.0368e+01, 1.0051e+01, 9.7509e+00, 9.4672e+00, 9.1997e+00, 8.9477e+00, 8.7105e+00, 8.4875e+00, 8.2781e+00, 8.0815e+00, 7.8969e+00, 7.7238e+00, 7.5613e+00, 7.4088e+00, 7.2656e+00, 7.1310e+00, 7.0044e+00, 6.8852e+00, 6.7728e+00, 6.6665e+00, 6.5660e+00, 6.4707e+00, 6.3801e+00, 6.2938e+00, 6.2114e+00, 6.1324e+00, 6.0566e+00, 5.9836e+00, 5.9131e+00, 5.8448e+00, 5.7785e+00, 5.7139e+00, 5.6509e+00, 5.5892e+00, 5.5287e+00, 5.4692e+00, 5.4105e+00, 5.3527e+00, 5.2954e+00, 5.2388e+00, 5.1826e+00, 5.1268e+00, 5.0714e+00, 5.0163e+00, 4.9615e+00, 4.9069e+00, 4.8525e+00, 4.7982e+00, 4.7442e+00, 4.6903e+00, 4.6366e+00, 4.5830e+00, 4.5296e+00, 4.4763e+00, 4.4232e+00, 4.3703e+00, 4.3177e+00, 4.2652e+00, 4.2129e+00, 4.1609e+00, 4.1092e+00, 4.0578e+00, 4.0066e+00, 3.9558e+00, 3.9053e+00, 3.8552e+00, 3.8054e+00, 3.7561e+00, 3.7072e+00, 3.6587e+00, 3.6106e+00, 3.5630e+00, 3.5159e+00, 3.4693e+00, 3.4232e+00, 3.3776e+00, 3.3325e+00, 3.2880e+00, 3.2440e+00, 3.2007e+00, 3.1579e+00, 3.1157e+00, 3.0740e+00, 3.0329e+00, 2.9924e+00, 2.9525e+00, 2.9133e+00, 2.8747e+00, 2.8367e+00, 2.7992e+00, 2.7624e+00, 2.7261e+00, 2.6906e+00, 2.6557e+00, 2.6214e+00, 2.5877e+00, 2.5546e+00, 2.5219e+00, 2.4899e+00, 2.4586e+00, 2.4280e+00, 2.3979e+00, 2.3685e+00, 2.3395e+00, 2.3110e+00, 2.2830e+00, 2.2556e+00, 2.2289e+00, 2.2028e+00, 2.1774e+00, 2.1524e+00, 2.1278e+00, 2.1036e+00, 2.0798e+00, 2.0566e+00, 2.0340e+00, 2.0121e+00, 1.9907e+00, 1.9698e+00, 1.9492e+00, 1.9289e+00, 1.9088e+00, 1.8892e+00, 1.8702e+00, 1.8517e+00, 1.8338e+00, 1.8165e+00, 1.7994e+00, 1.7826e+00, 1.7660e+00, 1.7495e+00, 1.7334e+00, 1.7177e+00, 1.7026e+00, 1.6881e+00, 1.6741e+00, 1.6604e+00, 1.6468e+00, 1.6333e+00, 1.6199e+00, 1.6066e+00, 1.5935e+00, 1.5810e+00, 1.5690e+00, 1.5576e+00, 1.5466e+00, 1.5358e+00, 1.5251e+00, 1.5143e+00, 1.5034e+00, 1.4925e+00, 1.4819e+00, 1.4717e+00, 1.4619e+00, 1.4528e+00, 1.4441e+00, 1.4356e+00, 1.4273e+00, 1.4187e+00, 1.4100e+00, 1.4012e+00, 1.3923e+00, 1.3836e+00, 1.3754e+00, 1.3676e+00, 1.3605e+00, 1.3537e+00, 1.3472e+00, 1.3407e+00, 1.3340e+00, 1.3270e+00, 1.3197e+00, 1.3122e+00, 1.3049e+00, 1.2979e+00, 1.2913e+00, 1.2853e+00, 1.2799e+00, 1.2748e+00, 1.2698e+00, 1.2646e+00, 1.2592e+00, 1.2533e+00, 1.2471e+00, 1.2407e+00, 1.2344e+00, 1.2283e+00, 1.2227e+00, 1.2177e+00, 1.2133e+00, 1.2092e+00, 1.2053e+00, 1.2013e+00, 1.1970e+00, 1.1923e+00, 1.1870e+00, 1.1814e+00, 1.1757e+00, 1.1701e+00, 1.1648e+00, 1.1601e+00, 1.1559e+00, 1.1522e+00}); + feg = Vctr_cpu({6.8983e+00, 6.8398e+00, 6.6699e+00, 6.4040e+00, 6.0641e+00, 5.6751e+00, 5.2608e+00, 4.8419e+00, 4.4339e+00, 4.0479e+00, 3.6903e+00, 3.3644e+00, 3.0707e+00, 2.8083e+00, 2.5752e+00, 2.3686e+00, 2.1858e+00, 2.0241e+00, 1.8807e+00, 1.7534e+00, 1.6399e+00, 1.5384e+00, 1.4472e+00, 1.3648e+00, 1.2902e+00, 1.2222e+00, 1.1600e+00, 1.1028e+00, 1.0500e+00, 1.0011e+00, 9.5560e-01, 9.1310e-01, 8.7340e-01, 8.3620e-01, 8.0120e-01, 7.6820e-01, 7.3710e-01, 7.0760e-01, 6.7970e-01, 6.5330e-01, 6.2820e-01, 6.0440e-01, 5.8180e-01, 5.6030e-01, 5.3980e-01, 5.2030e-01, 5.0170e-01, 4.8400e-01, 4.6710e-01, 4.5100e-01, 4.3560e-01, 4.2090e-01, 4.0690e-01, 3.9360e-01, 3.8080e-01, 3.6860e-01, 3.5690e-01, 3.4570e-01, 3.3510e-01, 3.2480e-01, 3.1510e-01, 3.0570e-01, 2.9680e-01, 2.8820e-01, 2.7990e-01, 2.7210e-01, 2.6450e-01, 2.5720e-01, 2.5030e-01, 2.4360e-01, 2.3720e-01, 2.3100e-01, 2.2510e-01, 2.1940e-01, 2.1390e-01, 2.0860e-01, 2.0360e-01, 1.9870e-01, 1.9400e-01, 1.8940e-01, 1.8510e-01, 1.8080e-01, 1.7680e-01, 1.7280e-01, 1.6900e-01, 1.6540e-01, 1.6180e-01, 1.5840e-01, 1.5510e-01, 1.5190e-01, 1.4880e-01, 1.4580e-01, 1.4290e-01, 1.4000e-01, 1.3730e-01, 1.3470e-01, 1.3210e-01, 1.2960e-01, 1.2720e-01, 1.2480e-01, 1.2250e-01, 1.2030e-01, 1.1810e-01, 1.1600e-01, 1.1400e-01, 1.1200e-01, 1.1010e-01, 1.0820e-01, 1.0630e-01, 1.0450e-01, 1.0280e-01, 1.0110e-01, 9.9400e-02, 9.7800e-02, 9.6300e-02, 9.4700e-02, 9.3200e-02, 9.1800e-02, 9.0300e-02, 8.8900e-02, 8.7600e-02, 8.6200e-02, 8.4900e-02, 8.3600e-02, 8.2400e-02, 8.1200e-02, 8.0000e-02, 7.8800e-02, 7.7700e-02, 7.6600e-02, 7.5500e-02, 7.4400e-02, 7.3400e-02, 7.2300e-02, 7.1300e-02, 7.0300e-02, 6.9400e-02, 6.8400e-02, 6.7500e-02, 6.6600e-02, 6.5700e-02, 6.4800e-02, 6.4000e-02, 6.3100e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9200e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5600e-02, 5.4900e-02, 5.4200e-02, 5.3500e-02, 5.2900e-02, 5.2300e-02, 5.1600e-02, 5.1000e-02, 5.0400e-02, 4.9800e-02, 4.9200e-02, 4.8700e-02, 4.8100e-02, 4.7600e-02, 4.7000e-02, 4.6500e-02, 4.5900e-02, 4.5400e-02, 4.4900e-02, 4.4400e-02, 4.3900e-02, 4.3400e-02, 4.3000e-02, 4.2500e-02, 4.2000e-02, 4.1600e-02, 4.1100e-02, 4.0700e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7400e-02, 3.7000e-02, 3.6600e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5200e-02, 3.4800e-02, 3.4500e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02, 2.6800e-02, 2.6500e-02, 2.6300e-02, 2.6100e-02, 2.5900e-02, 2.5600e-02, 2.5400e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02}); + } + break; + case 37: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.7000e+01, 3.6706e+01, 3.5950e+01, 3.4967e+01, 3.3907e+01, 3.2811e+01, 3.1680e+01, 3.0525e+01, 2.9368e+01, 2.8235e+01, 2.7147e+01, 2.6119e+01, 2.5158e+01, 2.4263e+01, 2.3432e+01, 2.2658e+01, 2.1934e+01, 2.1252e+01, 2.0605e+01, 1.9986e+01, 1.9391e+01, 1.8814e+01, 1.8252e+01, 1.7704e+01, 1.7167e+01, 1.6641e+01, 1.6125e+01, 1.5620e+01, 1.5126e+01, 1.4643e+01, 1.4173e+01, 1.3715e+01, 1.3271e+01, 1.2842e+01, 1.2427e+01, 1.2027e+01, 1.1644e+01, 1.1276e+01, 1.0924e+01, 1.0589e+01, 1.0269e+01, 9.9654e+00, 9.6772e+00, 9.4042e+00, 9.1460e+00, 8.9021e+00, 8.6719e+00, 8.4550e+00, 8.2507e+00, 8.0584e+00, 7.8775e+00, 7.7074e+00, 7.5474e+00, 7.3970e+00, 7.2554e+00, 7.1222e+00, 6.9967e+00, 6.8785e+00, 6.7668e+00, 6.6612e+00, 6.5613e+00, 6.4666e+00, 6.3765e+00, 6.2908e+00, 6.2091e+00, 6.1307e+00, 6.0555e+00, 5.9834e+00, 5.9139e+00, 5.8465e+00, 5.7811e+00, 5.7179e+00, 5.6563e+00, 5.5958e+00, 5.5365e+00, 5.4787e+00, 5.4220e+00, 5.3658e+00, 5.3100e+00, 5.2552e+00, 5.2013e+00, 5.1477e+00, 5.0939e+00, 5.0406e+00, 4.9880e+00, 4.9360e+00, 4.8837e+00, 4.8312e+00, 4.7789e+00, 4.7275e+00, 4.6764e+00, 4.6250e+00, 4.5731e+00, 4.5215e+00, 4.4707e+00, 4.4204e+00, 4.3699e+00, 4.3189e+00, 4.2679e+00, 4.2177e+00, 4.1682e+00, 4.1190e+00, 4.0696e+00, 4.0197e+00, 3.9702e+00, 3.9216e+00, 3.8738e+00, 3.8263e+00, 3.7787e+00, 3.7307e+00, 3.6832e+00, 3.6367e+00, 3.5910e+00, 3.5459e+00, 3.5009e+00, 3.4556e+00, 3.4105e+00, 3.3663e+00, 3.3233e+00, 3.2809e+00, 3.2390e+00, 3.1973e+00, 3.1553e+00, 3.1137e+00, 3.0734e+00, 3.0340e+00, 2.9953e+00, 2.9573e+00, 2.9194e+00, 2.8813e+00, 2.8436e+00, 2.8071e+00, 2.7716e+00, 2.7367e+00, 2.7026e+00, 2.6690e+00, 2.6353e+00, 2.6015e+00, 2.5686e+00, 2.5369e+00, 2.5060e+00, 2.4756e+00, 2.4459e+00, 2.4169e+00, 2.3877e+00, 2.3583e+00, 2.3298e+00, 2.3025e+00, 2.2760e+00, 2.2498e+00, 2.2243e+00, 2.1996e+00, 2.1749e+00, 2.1499e+00, 2.1252e+00, 2.1016e+00, 2.0792e+00, 2.0571e+00, 2.0352e+00, 2.0140e+00, 1.9936e+00, 1.9732e+00, 1.9523e+00, 1.9316e+00, 1.9120e+00, 1.8936e+00, 1.8755e+00, 1.8574e+00, 1.8398e+00, 1.8231e+00, 1.8067e+00, 1.7897e+00, 1.7724e+00, 1.7558e+00, 1.7404e+00, 1.7259e+00, 1.7113e+00, 1.6966e+00, 1.6826e+00, 1.6693e+00, 1.6563e+00, 1.6426e+00, 1.6284e+00, 1.6147e+00, 1.6023e+00, 1.5908e+00, 1.5793e+00, 1.5676e+00, 1.5561e+00, 1.5455e+00, 1.5353e+00, 1.5248e+00, 1.5135e+00, 1.5019e+00, 1.4911e+00, 1.4816e+00, 1.4727e+00, 1.4636e+00, 1.4543e+00, 1.4453e+00, 1.4369e+00, 1.4291e+00, 1.4209e+00, 1.4119e+00, 1.4023e+00, 1.3932e+00, 1.3852e+00, 1.3782e+00, 1.3713e+00, 1.3640e+00, 1.3567e+00, 1.3497e+00, 1.3434e+00, 1.3373e+00, 1.3307e+00, 1.3233e+00, 1.3152e+00, 1.3076e+00, 1.3010e+00, 1.2955e+00, 1.2901e+00, 1.2844e+00, 1.2786e+00, 1.2730e+00, 1.2679e+00, 1.2631e+00, 1.2581e+00, 1.2523e+00, 1.2457e+00, 1.2387e+00, 1.2324e+00, 1.2272e+00, 1.2228e+00, 1.2185e+00, 1.2139e+00, 1.2092e+00, 1.2047e+00, 1.2006e+00, 1.1968e+00, 1.1928e+00, 1.1881e+00}); + feg = Vctr_cpu({1.1723e+01, 1.1245e+01, 1.0055e+01, 8.6511e+00, 7.4017e+00, 6.4165e+00, 5.6588e+00, 5.0604e+00, 4.5667e+00, 4.1439e+00, 3.7730e+00, 3.4435e+00, 3.1492e+00, 2.8861e+00, 2.6509e+00, 2.4409e+00, 2.2537e+00, 2.0867e+00, 1.9377e+00, 1.8048e+00, 1.6858e+00, 1.5792e+00, 1.4833e+00, 1.3968e+00, 1.3185e+00, 1.2474e+00, 1.1825e+00, 1.1231e+00, 1.0684e+00, 1.0180e+00, 9.7130e-01, 9.2790e-01, 8.8740e-01, 8.4950e-01, 8.1400e-01, 7.8070e-01, 7.4920e-01, 7.1960e-01, 6.9150e-01, 6.6500e-01, 6.3980e-01, 6.1590e-01, 5.9310e-01, 5.7150e-01, 5.5090e-01, 5.3130e-01, 5.1270e-01, 4.9480e-01, 4.7780e-01, 4.6160e-01, 4.4610e-01, 4.3130e-01, 4.1710e-01, 4.0360e-01, 3.9060e-01, 3.7820e-01, 3.6640e-01, 3.5500e-01, 3.4420e-01, 3.3380e-01, 3.2380e-01, 3.1420e-01, 3.0510e-01, 2.9630e-01, 2.8790e-01, 2.7980e-01, 2.7200e-01, 2.6460e-01, 2.5740e-01, 2.5060e-01, 2.4400e-01, 2.3760e-01, 2.3150e-01, 2.2570e-01, 2.2000e-01, 2.1460e-01, 2.0940e-01, 2.0430e-01, 1.9950e-01, 1.9480e-01, 1.9030e-01, 1.8590e-01, 1.8170e-01, 1.7770e-01, 1.7370e-01, 1.6990e-01, 1.6630e-01, 1.6280e-01, 1.5930e-01, 1.5600e-01, 1.5280e-01, 1.4970e-01, 1.4670e-01, 1.4380e-01, 1.4100e-01, 1.3820e-01, 1.3560e-01, 1.3300e-01, 1.3050e-01, 1.2810e-01, 1.2570e-01, 1.2340e-01, 1.2120e-01, 1.1900e-01, 1.1690e-01, 1.1490e-01, 1.1290e-01, 1.1100e-01, 1.0910e-01, 1.0720e-01, 1.0540e-01, 1.0370e-01, 1.0200e-01, 1.0030e-01, 9.8700e-02, 9.7100e-02, 9.5600e-02, 9.4100e-02, 9.2600e-02, 9.1200e-02, 8.9800e-02, 8.8400e-02, 8.7100e-02, 8.5800e-02, 8.4500e-02, 8.3200e-02, 8.2000e-02, 8.0800e-02, 7.9700e-02, 7.8500e-02, 7.7400e-02, 7.6300e-02, 7.5200e-02, 7.4200e-02, 7.3100e-02, 7.2100e-02, 7.1100e-02, 7.0200e-02, 6.9200e-02, 6.8300e-02, 6.7400e-02, 6.6500e-02, 6.5600e-02, 6.4800e-02, 6.3900e-02, 6.3100e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9200e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5600e-02, 5.4900e-02, 5.4300e-02, 5.3600e-02, 5.3000e-02, 5.2400e-02, 5.1700e-02, 5.1100e-02, 5.0500e-02, 5.0000e-02, 4.9400e-02, 4.8800e-02, 4.8300e-02, 4.7700e-02, 4.7200e-02, 4.6600e-02, 4.6100e-02, 4.5600e-02, 4.5100e-02, 4.4600e-02, 4.4100e-02, 4.3600e-02, 4.3200e-02, 4.2700e-02, 4.2200e-02, 4.1800e-02, 4.1300e-02, 4.0900e-02, 4.0500e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8800e-02, 3.8400e-02, 3.8000e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6500e-02, 3.6100e-02, 3.5800e-02, 3.5400e-02, 3.5100e-02, 3.4700e-02, 3.4400e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1200e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8500e-02, 2.8300e-02, 2.8000e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6300e-02, 2.6100e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4600e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3800e-02}); + } + break; + case 38: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.8000e+01, 3.7671e+01, 3.6803e+01, 3.5659e+01, 3.4457e+01, 3.3292e+01, 3.2170e+01, 3.1073e+01, 2.9987e+01, 2.8914e+01, 2.7863e+01, 2.6846e+01, 2.5874e+01, 2.4954e+01, 2.4090e+01, 2.3280e+01, 2.2522e+01, 2.1811e+01, 2.1141e+01, 2.0506e+01, 1.9902e+01, 1.9323e+01, 1.8764e+01, 1.8223e+01, 1.7696e+01, 1.7181e+01, 1.6678e+01, 1.6185e+01, 1.5702e+01, 1.5229e+01, 1.4766e+01, 1.4313e+01, 1.3872e+01, 1.3442e+01, 1.3025e+01, 1.2620e+01, 1.2229e+01, 1.1852e+01, 1.1488e+01, 1.1139e+01, 1.0805e+01, 1.0485e+01, 1.0179e+01, 9.8880e+00, 9.6110e+00, 9.3479e+00, 9.0985e+00, 8.8621e+00, 8.6386e+00, 8.4274e+00, 8.2279e+00, 8.0396e+00, 7.8622e+00, 7.6950e+00, 7.5373e+00, 7.3888e+00, 7.2488e+00, 7.1168e+00, 6.9924e+00, 6.8749e+00, 6.7638e+00, 6.6588e+00, 6.5594e+00, 6.4651e+00, 6.3754e+00, 6.2901e+00, 6.2088e+00, 6.1309e+00, 6.0563e+00, 5.9848e+00, 5.9159e+00, 5.8494e+00, 5.7850e+00, 5.7225e+00, 5.6618e+00, 5.6028e+00, 5.5449e+00, 5.4881e+00, 5.4326e+00, 5.3781e+00, 5.3243e+00, 5.2710e+00, 5.2183e+00, 5.1664e+00, 5.1151e+00, 5.0639e+00, 5.0127e+00, 4.9620e+00, 4.9120e+00, 4.8622e+00, 4.8122e+00, 4.7620e+00, 4.7122e+00, 4.6630e+00, 4.6141e+00, 4.5649e+00, 4.5153e+00, 4.4660e+00, 4.4173e+00, 4.3692e+00, 4.3210e+00, 4.2722e+00, 4.2233e+00, 4.1750e+00, 4.1276e+00, 4.0806e+00, 4.0334e+00, 3.9857e+00, 3.9380e+00, 3.8911e+00, 3.8452e+00, 3.7999e+00, 3.7545e+00, 3.7086e+00, 3.6626e+00, 3.6174e+00, 3.5733e+00, 3.5303e+00, 3.4874e+00, 3.4441e+00, 3.4006e+00, 3.3574e+00, 3.3153e+00, 3.2745e+00, 3.2346e+00, 3.1947e+00, 3.1545e+00, 3.1143e+00, 3.0743e+00, 3.0355e+00, 2.9982e+00, 2.9619e+00, 2.9256e+00, 2.8891e+00, 2.8526e+00, 2.8162e+00, 2.7807e+00, 2.7466e+00, 2.7139e+00, 2.6817e+00, 2.6493e+00, 2.6169e+00, 2.5845e+00, 2.5524e+00, 2.5211e+00, 2.4915e+00, 2.4631e+00, 2.4350e+00, 2.4068e+00, 2.3786e+00, 2.3506e+00, 2.3226e+00, 2.2952e+00, 2.2692e+00, 2.2447e+00, 2.2209e+00, 2.1969e+00, 2.1728e+00, 2.1489e+00, 2.1251e+00, 2.1014e+00, 2.0783e+00, 2.0567e+00, 2.0365e+00, 2.0168e+00, 1.9967e+00, 1.9765e+00, 1.9565e+00, 1.9368e+00, 1.9170e+00, 1.8975e+00, 1.8792e+00, 1.8624e+00, 1.8464e+00, 1.8301e+00, 1.8134e+00, 1.7968e+00, 1.7807e+00, 1.7647e+00, 1.7484e+00, 1.7324e+00, 1.7177e+00, 1.7045e+00, 1.6918e+00, 1.6787e+00, 1.6650e+00, 1.6516e+00, 1.6386e+00, 1.6258e+00, 1.6127e+00, 1.5994e+00, 1.5869e+00, 1.5760e+00, 1.5661e+00, 1.5561e+00, 1.5454e+00, 1.5343e+00, 1.5235e+00, 1.5134e+00, 1.5033e+00, 1.4927e+00, 1.4818e+00, 1.4716e+00, 1.4630e+00, 1.4555e+00, 1.4480e+00, 1.4396e+00, 1.4305e+00, 1.4216e+00, 1.4135e+00, 1.4057e+00, 1.3975e+00, 1.3885e+00, 1.3797e+00, 1.3719e+00, 1.3657e+00, 1.3602e+00, 1.3543e+00, 1.3474e+00, 1.3399e+00, 1.3327e+00, 1.3262e+00, 1.3201e+00, 1.3136e+00, 1.3063e+00, 1.2987e+00, 1.2919e+00, 1.2866e+00, 1.2824e+00, 1.2783e+00, 1.2733e+00, 1.2673e+00, 1.2609e+00, 1.2552e+00, 1.2501e+00, 1.2452e+00, 1.2397e+00, 1.2334e+00, 1.2269e+00, 1.2211e+00, 1.2167e+00}); + feg = Vctr_cpu({1.3049e+01, 1.2610e+01, 1.1456e+01, 9.9599e+00, 8.4789e+00, 7.2114e+00, 6.2013e+00, 5.4136e+00, 4.7944e+00, 4.2956e+00, 3.8820e+00, 3.5300e+00, 3.2247e+00, 2.9560e+00, 2.7177e+00, 2.5053e+00, 2.3153e+00, 2.1452e+00, 1.9926e+00, 1.8557e+00, 1.7326e+00, 1.6218e+00, 1.5219e+00, 1.4316e+00, 1.3499e+00, 1.2756e+00, 1.2078e+00, 1.1459e+00, 1.0891e+00, 1.0369e+00, 9.8860e-01, 9.4390e-01, 9.0230e-01, 8.6360e-01, 8.2730e-01, 7.9340e-01, 7.6150e-01, 7.3140e-01, 7.0310e-01, 6.7630e-01, 6.5090e-01, 6.2680e-01, 6.0400e-01, 5.8220e-01, 5.6150e-01, 5.4180e-01, 5.2300e-01, 5.0510e-01, 4.8800e-01, 4.7170e-01, 4.5600e-01, 4.4110e-01, 4.2680e-01, 4.1310e-01, 4.0000e-01, 3.8750e-01, 3.7550e-01, 3.6400e-01, 3.5300e-01, 3.4240e-01, 3.3230e-01, 3.2250e-01, 3.1320e-01, 3.0430e-01, 2.9570e-01, 2.8740e-01, 2.7950e-01, 2.7190e-01, 2.6450e-01, 2.5750e-01, 2.5070e-01, 2.4420e-01, 2.3800e-01, 2.3190e-01, 2.2610e-01, 2.2060e-01, 2.1520e-01, 2.1000e-01, 2.0500e-01, 2.0020e-01, 1.9550e-01, 1.9100e-01, 1.8670e-01, 1.8250e-01, 1.7850e-01, 1.7460e-01, 1.7080e-01, 1.6710e-01, 1.6360e-01, 1.6020e-01, 1.5690e-01, 1.5370e-01, 1.5060e-01, 1.4760e-01, 1.4470e-01, 1.4190e-01, 1.3910e-01, 1.3650e-01, 1.3390e-01, 1.3140e-01, 1.2900e-01, 1.2660e-01, 1.2430e-01, 1.2210e-01, 1.1990e-01, 1.1780e-01, 1.1580e-01, 1.1380e-01, 1.1180e-01, 1.0990e-01, 1.0810e-01, 1.0630e-01, 1.0450e-01, 1.0280e-01, 1.0120e-01, 9.9600e-02, 9.8000e-02, 9.6400e-02, 9.4900e-02, 9.3400e-02, 9.2000e-02, 9.0600e-02, 8.9200e-02, 8.7900e-02, 8.6600e-02, 8.5300e-02, 8.4000e-02, 8.2800e-02, 8.1600e-02, 8.0500e-02, 7.9300e-02, 7.8200e-02, 7.7100e-02, 7.6000e-02, 7.5000e-02, 7.3900e-02, 7.2900e-02, 7.1900e-02, 7.1000e-02, 7.0000e-02, 6.9100e-02, 6.8200e-02, 6.7300e-02, 6.6400e-02, 6.5500e-02, 6.4700e-02, 6.3800e-02, 6.3000e-02, 6.2200e-02, 6.1400e-02, 6.0700e-02, 5.9900e-02, 5.9200e-02, 5.8500e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4300e-02, 5.3700e-02, 5.3100e-02, 5.2400e-02, 5.1800e-02, 5.1200e-02, 5.0600e-02, 5.0100e-02, 4.9500e-02, 4.8900e-02, 4.8400e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5700e-02, 4.5200e-02, 4.4800e-02, 4.4300e-02, 4.3800e-02, 4.3300e-02, 4.2900e-02, 4.2400e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4600e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2700e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0300e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8500e-02, 2.8300e-02, 2.8000e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02, 2.6100e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5300e-02, 2.5100e-02, 2.4900e-02, 2.4700e-02, 2.4500e-02}); + } + break; + case 39: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.9000e+01, 3.8679e+01, 3.7817e+01, 3.6641e+01, 3.5365e+01, 3.4108e+01, 3.2905e+01, 3.1752e+01, 3.0635e+01, 2.9547e+01, 2.8490e+01, 2.7468e+01, 2.6489e+01, 2.5558e+01, 2.4679e+01, 2.3853e+01, 2.3077e+01, 2.2350e+01, 2.1666e+01, 2.1021e+01, 2.0410e+01, 1.9828e+01, 1.9270e+01, 1.8732e+01, 1.8211e+01, 1.7704e+01, 1.7210e+01, 1.6727e+01, 1.6253e+01, 1.5789e+01, 1.5334e+01, 1.4888e+01, 1.4451e+01, 1.4024e+01, 1.3607e+01, 1.3201e+01, 1.2806e+01, 1.2423e+01, 1.2052e+01, 1.1693e+01, 1.1348e+01, 1.1015e+01, 1.0695e+01, 1.0389e+01, 1.0096e+01, 9.8165e+00, 9.5498e+00, 9.2959e+00, 9.0545e+00, 8.8254e+00, 8.6082e+00, 8.4024e+00, 8.2077e+00, 8.0235e+00, 7.8495e+00, 7.6851e+00, 7.5299e+00, 7.3833e+00, 7.2450e+00, 7.1143e+00, 6.9909e+00, 6.8742e+00, 6.7639e+00, 6.6594e+00, 6.5603e+00, 6.4664e+00, 6.3771e+00, 6.2920e+00, 6.2109e+00, 6.1335e+00, 6.0593e+00, 5.9882e+00, 5.9197e+00, 5.8537e+00, 5.7900e+00, 5.7284e+00, 5.6684e+00, 5.6100e+00, 5.5532e+00, 5.4977e+00, 5.4433e+00, 5.3898e+00, 5.3371e+00, 5.2854e+00, 5.2345e+00, 5.1839e+00, 5.1337e+00, 5.0840e+00, 5.0350e+00, 4.9864e+00, 4.9377e+00, 4.8890e+00, 4.8407e+00, 4.7930e+00, 4.7456e+00, 4.6979e+00, 4.6500e+00, 4.6022e+00, 4.5551e+00, 4.5084e+00, 4.4616e+00, 4.4144e+00, 4.3670e+00, 4.3201e+00, 4.2739e+00, 4.2281e+00, 4.1820e+00, 4.1354e+00, 4.0888e+00, 4.0428e+00, 3.9978e+00, 3.9532e+00, 3.9084e+00, 3.8632e+00, 3.8178e+00, 3.7730e+00, 3.7294e+00, 3.6865e+00, 3.6438e+00, 3.6006e+00, 3.5571e+00, 3.5139e+00, 3.4717e+00, 3.4308e+00, 3.3905e+00, 3.3503e+00, 3.3097e+00, 3.2688e+00, 3.2284e+00, 3.1890e+00, 3.1510e+00, 3.1139e+00, 3.0769e+00, 3.0395e+00, 3.0020e+00, 2.9646e+00, 2.9281e+00, 2.8930e+00, 2.8592e+00, 2.8259e+00, 2.7924e+00, 2.7587e+00, 2.7249e+00, 2.6914e+00, 2.6589e+00, 2.6279e+00, 2.5982e+00, 2.5688e+00, 2.5394e+00, 2.5097e+00, 2.4799e+00, 2.4503e+00, 2.4215e+00, 2.3940e+00, 2.3681e+00, 2.3428e+00, 2.3175e+00, 2.2920e+00, 2.2664e+00, 2.2408e+00, 2.2154e+00, 2.1908e+00, 2.1677e+00, 2.1460e+00, 2.1248e+00, 2.1035e+00, 2.0819e+00, 2.0603e+00, 2.0387e+00, 2.0172e+00, 1.9962e+00, 1.9764e+00, 1.9582e+00, 1.9408e+00, 1.9233e+00, 1.9055e+00, 1.8876e+00, 1.8698e+00, 1.8520e+00, 1.8341e+00, 1.8167e+00, 1.8007e+00, 1.7862e+00, 1.7723e+00, 1.7582e+00, 1.7436e+00, 1.7290e+00, 1.7145e+00, 1.7001e+00, 1.6855e+00, 1.6709e+00, 1.6574e+00, 1.6453e+00, 1.6344e+00, 1.6235e+00, 1.6120e+00, 1.6001e+00, 1.5883e+00, 1.5768e+00, 1.5653e+00, 1.5533e+00, 1.5414e+00, 1.5304e+00, 1.5209e+00, 1.5125e+00, 1.5042e+00, 1.4952e+00, 1.4856e+00, 1.4760e+00, 1.4669e+00, 1.4578e+00, 1.4484e+00, 1.4386e+00, 1.4290e+00, 1.4206e+00, 1.4136e+00, 1.4075e+00, 1.4011e+00, 1.3939e+00, 1.3860e+00, 1.3782e+00, 1.3709e+00, 1.3639e+00, 1.3564e+00, 1.3483e+00, 1.3402e+00, 1.3329e+00, 1.3271e+00, 1.3225e+00, 1.3179e+00, 1.3127e+00, 1.3064e+00, 1.2998e+00, 1.2936e+00, 1.2879e+00, 1.2823e+00, 1.2761e+00, 1.2693e+00, 1.2623e+00, 1.2562e+00, 1.2515e+00}); + feg = Vctr_cpu({1.2636e+01, 1.2279e+01, 1.1322e+01, 1.0036e+01, 8.7004e+00, 7.4937e+00, 6.4830e+00, 5.6642e+00, 5.0051e+00, 4.4689e+00, 4.0248e+00, 3.6496e+00, 3.3271e+00, 3.0458e+00, 2.7980e+00, 2.5780e+00, 2.3818e+00, 2.2062e+00, 2.0487e+00, 1.9071e+00, 1.7797e+00, 1.6648e+00, 1.5611e+00, 1.4672e+00, 1.3821e+00, 1.3048e+00, 1.2343e+00, 1.1700e+00, 1.1110e+00, 1.0569e+00, 1.0070e+00, 9.6080e-01, 9.1800e-01, 8.7830e-01, 8.4120e-01, 8.0650e-01, 7.7400e-01, 7.4340e-01, 7.1460e-01, 6.8750e-01, 6.6180e-01, 6.3750e-01, 6.1450e-01, 5.9250e-01, 5.7170e-01, 5.5190e-01, 5.3300e-01, 5.1490e-01, 4.9770e-01, 4.8130e-01, 4.6550e-01, 4.5050e-01, 4.3610e-01, 4.2230e-01, 4.0910e-01, 3.9640e-01, 3.8430e-01, 3.7260e-01, 3.6150e-01, 3.5080e-01, 3.4050e-01, 3.3060e-01, 3.2110e-01, 3.1200e-01, 3.0330e-01, 2.9490e-01, 2.8680e-01, 2.7900e-01, 2.7150e-01, 2.6440e-01, 2.5740e-01, 2.5080e-01, 2.4440e-01, 2.3820e-01, 2.3220e-01, 2.2650e-01, 2.2100e-01, 2.1570e-01, 2.1050e-01, 2.0560e-01, 2.0080e-01, 1.9620e-01, 1.9170e-01, 1.8740e-01, 1.8330e-01, 1.7920e-01, 1.7530e-01, 1.7160e-01, 1.6800e-01, 1.6440e-01, 1.6100e-01, 1.5770e-01, 1.5450e-01, 1.5150e-01, 1.4850e-01, 1.4550e-01, 1.4270e-01, 1.4000e-01, 1.3730e-01, 1.3480e-01, 1.3230e-01, 1.2980e-01, 1.2750e-01, 1.2520e-01, 1.2290e-01, 1.2080e-01, 1.1870e-01, 1.1660e-01, 1.1460e-01, 1.1270e-01, 1.1080e-01, 1.0890e-01, 1.0710e-01, 1.0540e-01, 1.0370e-01, 1.0200e-01, 1.0040e-01, 9.8800e-02, 9.7200e-02, 9.5700e-02, 9.4300e-02, 9.2800e-02, 9.1400e-02, 9.0000e-02, 8.8700e-02, 8.7400e-02, 8.6100e-02, 8.4800e-02, 8.3600e-02, 8.2400e-02, 8.1200e-02, 8.0100e-02, 7.9000e-02, 7.7800e-02, 7.6800e-02, 7.5700e-02, 7.4700e-02, 7.3700e-02, 7.2700e-02, 7.1700e-02, 7.0700e-02, 6.9800e-02, 6.8900e-02, 6.8000e-02, 6.7100e-02, 6.6200e-02, 6.5400e-02, 6.4600e-02, 6.3700e-02, 6.2900e-02, 6.2200e-02, 6.1400e-02, 6.0600e-02, 5.9900e-02, 5.9100e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4400e-02, 5.3700e-02, 5.3100e-02, 5.2500e-02, 5.1900e-02, 5.1300e-02, 5.0700e-02, 5.0100e-02, 4.9600e-02, 4.9000e-02, 4.8500e-02, 4.7900e-02, 4.7400e-02, 4.6900e-02, 4.6400e-02, 4.5900e-02, 4.5400e-02, 4.4900e-02, 4.4400e-02, 4.3900e-02, 4.3500e-02, 4.3000e-02, 4.2600e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.0800e-02, 4.0400e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8800e-02, 3.8400e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.6900e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4800e-02, 3.4500e-02, 3.4200e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2000e-02, 3.1700e-02, 3.1400e-02, 3.1100e-02, 3.0900e-02, 3.0600e-02, 3.0300e-02, 3.0000e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7100e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5300e-02, 2.5100e-02}); + } + break; + case 40: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.0000e+01, 3.9690e+01, 3.8846e+01, 3.7667e+01, 3.6353e+01, 3.5031e+01, 3.3754e+01, 3.2533e+01, 3.1361e+01, 3.0231e+01, 2.9143e+01, 2.8097e+01, 2.7097e+01, 2.6147e+01, 2.5250e+01, 2.4406e+01, 2.3614e+01, 2.2871e+01, 2.2174e+01, 2.1518e+01, 2.0900e+01, 2.0313e+01, 1.9753e+01, 1.9217e+01, 1.8700e+01, 1.8200e+01, 1.7713e+01, 1.7239e+01, 1.6775e+01, 1.6320e+01, 1.5873e+01, 1.5435e+01, 1.5005e+01, 1.4583e+01, 1.4169e+01, 1.3765e+01, 1.3370e+01, 1.2985e+01, 1.2610e+01, 1.2245e+01, 1.1892e+01, 1.1550e+01, 1.1221e+01, 1.0903e+01, 1.0597e+01, 1.0303e+01, 1.0021e+01, 9.7522e+00, 9.4949e+00, 9.2495e+00, 9.0157e+00, 8.7933e+00, 8.5819e+00, 8.3813e+00, 8.1910e+00, 8.0107e+00, 7.8400e+00, 7.6783e+00, 7.5254e+00, 7.3808e+00, 7.2440e+00, 7.1146e+00, 6.9921e+00, 6.8763e+00, 6.7665e+00, 6.6625e+00, 6.5638e+00, 6.4701e+00, 6.3811e+00, 6.2962e+00, 6.2153e+00, 6.1381e+00, 6.0642e+00, 5.9932e+00, 5.9251e+00, 5.8596e+00, 5.7964e+00, 5.7351e+00, 5.6757e+00, 5.6181e+00, 5.5621e+00, 5.5074e+00, 5.4537e+00, 5.4011e+00, 5.3498e+00, 5.2994e+00, 5.2495e+00, 5.1999e+00, 5.1511e+00, 5.1031e+00, 5.0557e+00, 5.0083e+00, 4.9609e+00, 4.9138e+00, 4.8675e+00, 4.8216e+00, 4.7756e+00, 4.7292e+00, 4.6829e+00, 4.6372e+00, 4.5920e+00, 4.5470e+00, 4.5015e+00, 4.4557e+00, 4.4100e+00, 4.3650e+00, 4.3207e+00, 4.2763e+00, 4.2315e+00, 4.1863e+00, 4.1412e+00, 4.0969e+00, 4.0534e+00, 4.0102e+00, 3.9666e+00, 3.9224e+00, 3.8782e+00, 3.8348e+00, 3.7923e+00, 3.7505e+00, 3.7088e+00, 3.6667e+00, 3.6241e+00, 3.5817e+00, 3.5403e+00, 3.5000e+00, 3.4605e+00, 3.4211e+00, 3.3813e+00, 3.3411e+00, 3.3010e+00, 3.2619e+00, 3.2240e+00, 3.1872e+00, 3.1508e+00, 3.1142e+00, 3.0772e+00, 3.0399e+00, 3.0032e+00, 2.9678e+00, 2.9336e+00, 2.9003e+00, 2.8674e+00, 2.8344e+00, 2.8008e+00, 2.7671e+00, 2.7339e+00, 2.7020e+00, 2.6714e+00, 2.6417e+00, 2.6127e+00, 2.5837e+00, 2.5543e+00, 2.5244e+00, 2.4946e+00, 2.4659e+00, 2.4385e+00, 2.4123e+00, 2.3868e+00, 2.3618e+00, 2.3369e+00, 2.3115e+00, 2.2855e+00, 2.2597e+00, 2.2349e+00, 2.2115e+00, 2.1891e+00, 2.1674e+00, 2.1463e+00, 2.1254e+00, 2.1042e+00, 2.0824e+00, 2.0602e+00, 2.0386e+00, 2.0183e+00, 1.9992e+00, 1.9808e+00, 1.9630e+00, 1.9456e+00, 1.9286e+00, 1.9112e+00, 1.8930e+00, 1.8744e+00, 1.8563e+00, 1.8393e+00, 1.8236e+00, 1.8086e+00, 1.7940e+00, 1.7798e+00, 1.7661e+00, 1.7524e+00, 1.7380e+00, 1.7228e+00, 1.7074e+00, 1.6928e+00, 1.6794e+00, 1.6670e+00, 1.6551e+00, 1.6434e+00, 1.6321e+00, 1.6213e+00, 1.6106e+00, 1.5994e+00, 1.5872e+00, 1.5744e+00, 1.5621e+00, 1.5510e+00, 1.5410e+00, 1.5316e+00, 1.5223e+00, 1.5131e+00, 1.5044e+00, 1.4961e+00, 1.4879e+00, 1.4789e+00, 1.4689e+00, 1.4583e+00, 1.4481e+00, 1.4392e+00, 1.4314e+00, 1.4242e+00, 1.4169e+00, 1.4096e+00, 1.4026e+00, 1.3961e+00, 1.3899e+00, 1.3834e+00, 1.3758e+00, 1.3672e+00, 1.3583e+00, 1.3501e+00, 1.3433e+00, 1.3375e+00, 1.3320e+00, 1.3263e+00, 1.3204e+00, 1.3148e+00, 1.3097e+00, 1.3051e+00, 1.3002e+00, 1.2944e+00}); + feg = Vctr_cpu({1.2165e+01, 1.1863e+01, 1.1044e+01, 9.9245e+00, 8.7288e+00, 7.6117e+00, 6.6437e+00, 5.8355e+00, 5.1692e+00, 4.6183e+00, 4.1577e+00, 3.7671e+00, 3.4313e+00, 3.1389e+00, 2.8818e+00, 2.6540e+00, 2.4512e+00, 2.2697e+00, 2.1069e+00, 1.9605e+00, 1.8286e+00, 1.7095e+00, 1.6019e+00, 1.5045e+00, 1.4161e+00, 1.3357e+00, 1.2625e+00, 1.1956e+00, 1.1344e+00, 1.0783e+00, 1.0266e+00, 9.7890e-01, 9.3470e-01, 8.9380e-01, 8.5570e-01, 8.2010e-01, 7.8690e-01, 7.5570e-01, 7.2640e-01, 6.9880e-01, 6.7270e-01, 6.4810e-01, 6.2480e-01, 6.0260e-01, 5.8160e-01, 5.6160e-01, 5.4250e-01, 5.2440e-01, 5.0700e-01, 4.9040e-01, 4.7460e-01, 4.5940e-01, 4.4490e-01, 4.3100e-01, 4.1770e-01, 4.0500e-01, 3.9270e-01, 3.8100e-01, 3.6970e-01, 3.5880e-01, 3.4840e-01, 3.3840e-01, 3.2880e-01, 3.1960e-01, 3.1070e-01, 3.0220e-01, 2.9390e-01, 2.8600e-01, 2.7840e-01, 2.7110e-01, 2.6400e-01, 2.5720e-01, 2.5070e-01, 2.4440e-01, 2.3830e-01, 2.3240e-01, 2.2680e-01, 2.2130e-01, 2.1600e-01, 2.1100e-01, 2.0610e-01, 2.0130e-01, 1.9670e-01, 1.9230e-01, 1.8810e-01, 1.8390e-01, 1.7990e-01, 1.7610e-01, 1.7230e-01, 1.6870e-01, 1.6520e-01, 1.6180e-01, 1.5850e-01, 1.5530e-01, 1.5230e-01, 1.4930e-01, 1.4640e-01, 1.4350e-01, 1.4080e-01, 1.3820e-01, 1.3560e-01, 1.3310e-01, 1.3070e-01, 1.2830e-01, 1.2600e-01, 1.2380e-01, 1.2160e-01, 1.1950e-01, 1.1740e-01, 1.1540e-01, 1.1350e-01, 1.1160e-01, 1.0970e-01, 1.0790e-01, 1.0620e-01, 1.0450e-01, 1.0280e-01, 1.0120e-01, 9.9600e-02, 9.8000e-02, 9.6500e-02, 9.5000e-02, 9.3600e-02, 9.2200e-02, 9.0800e-02, 8.9500e-02, 8.8100e-02, 8.6800e-02, 8.5600e-02, 8.4400e-02, 8.3200e-02, 8.2000e-02, 8.0800e-02, 7.9700e-02, 7.8600e-02, 7.7500e-02, 7.6400e-02, 7.5400e-02, 7.4400e-02, 7.3400e-02, 7.2400e-02, 7.1500e-02, 7.0500e-02, 6.9600e-02, 6.8700e-02, 6.7800e-02, 6.6900e-02, 6.6100e-02, 6.5300e-02, 6.4400e-02, 6.3600e-02, 6.2800e-02, 6.2100e-02, 6.1300e-02, 6.0600e-02, 5.9800e-02, 5.9100e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3200e-02, 5.2500e-02, 5.1900e-02, 5.1400e-02, 5.0800e-02, 5.0200e-02, 4.9700e-02, 4.9100e-02, 4.8600e-02, 4.8000e-02, 4.7500e-02, 4.7000e-02, 4.6500e-02, 4.6000e-02, 4.5500e-02, 4.5000e-02, 4.4500e-02, 4.4100e-02, 4.3600e-02, 4.3200e-02, 4.2700e-02, 4.2300e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0600e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6400e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1400e-02, 3.1100e-02, 3.0800e-02, 3.0500e-02, 3.0300e-02, 3.0000e-02, 2.9700e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02}); + } + break; + case 41: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.1000e+01, 4.0726e+01, 3.9967e+01, 3.8871e+01, 3.7595e+01, 3.6251e+01, 3.4902e+01, 3.3579e+01, 3.2295e+01, 3.1060e+01, 2.9879e+01, 2.8757e+01, 2.7696e+01, 2.6700e+01, 2.5767e+01, 2.4897e+01, 2.4086e+01, 2.3331e+01, 2.2626e+01, 2.1966e+01, 2.1346e+01, 2.0760e+01, 2.0204e+01, 1.9674e+01, 1.9165e+01, 1.8673e+01, 1.8196e+01, 1.7731e+01, 1.7277e+01, 1.6831e+01, 1.6394e+01, 1.5964e+01, 1.5542e+01, 1.5126e+01, 1.4718e+01, 1.4317e+01, 1.3923e+01, 1.3538e+01, 1.3162e+01, 1.2794e+01, 1.2436e+01, 1.2088e+01, 1.1750e+01, 1.1423e+01, 1.1107e+01, 1.0802e+01, 1.0508e+01, 1.0225e+01, 9.9538e+00, 9.6939e+00, 9.4451e+00, 9.2074e+00, 8.9806e+00, 8.7644e+00, 8.5586e+00, 8.3629e+00, 8.1769e+00, 8.0003e+00, 7.8327e+00, 7.6739e+00, 7.5233e+00, 7.3806e+00, 7.2454e+00, 7.1173e+00, 6.9959e+00, 6.8808e+00, 6.7717e+00, 6.6682e+00, 6.5699e+00, 6.4765e+00, 6.3876e+00, 6.3030e+00, 6.2222e+00, 6.1450e+00, 6.0712e+00, 6.0005e+00, 5.9326e+00, 5.8672e+00, 5.8041e+00, 5.7432e+00, 5.6844e+00, 5.6273e+00, 5.5716e+00, 5.5174e+00, 5.4646e+00, 5.4131e+00, 5.3624e+00, 5.3124e+00, 5.2634e+00, 5.2153e+00, 5.1679e+00, 5.1208e+00, 5.0740e+00, 5.0277e+00, 4.9821e+00, 4.9369e+00, 4.8918e+00, 4.8467e+00, 4.8017e+00, 4.7571e+00, 4.7131e+00, 4.6691e+00, 4.6250e+00, 4.5806e+00, 4.5365e+00, 4.4928e+00, 4.4495e+00, 4.4062e+00, 4.3627e+00, 4.3189e+00, 4.2752e+00, 4.2321e+00, 4.1894e+00, 4.1470e+00, 4.1043e+00, 4.0613e+00, 4.0183e+00, 3.9757e+00, 3.9339e+00, 3.8925e+00, 3.8512e+00, 3.8096e+00, 3.7678e+00, 3.7261e+00, 3.6851e+00, 3.6450e+00, 3.6053e+00, 3.5659e+00, 3.5261e+00, 3.4862e+00, 3.4464e+00, 3.4074e+00, 3.3692e+00, 3.3318e+00, 3.2948e+00, 3.2577e+00, 3.2204e+00, 3.1830e+00, 3.1461e+00, 3.1102e+00, 3.0752e+00, 3.0409e+00, 3.0070e+00, 2.9731e+00, 2.9389e+00, 2.9046e+00, 2.8709e+00, 2.8382e+00, 2.8065e+00, 2.7755e+00, 2.7451e+00, 2.7148e+00, 2.6844e+00, 2.6536e+00, 2.6232e+00, 2.5935e+00, 2.5649e+00, 2.5373e+00, 2.5103e+00, 2.4838e+00, 2.4574e+00, 2.4307e+00, 2.4038e+00, 2.3771e+00, 2.3512e+00, 2.3264e+00, 2.3026e+00, 2.2794e+00, 2.2567e+00, 2.2342e+00, 2.2116e+00, 2.1886e+00, 2.1655e+00, 2.1428e+00, 2.1212e+00, 2.1007e+00, 2.0808e+00, 2.0616e+00, 2.0427e+00, 2.0241e+00, 2.0052e+00, 1.9859e+00, 1.9664e+00, 1.9472e+00, 1.9291e+00, 1.9120e+00, 1.8956e+00, 1.8797e+00, 1.8642e+00, 1.8490e+00, 1.8339e+00, 1.8183e+00, 1.8021e+00, 1.7859e+00, 1.7702e+00, 1.7557e+00, 1.7420e+00, 1.7289e+00, 1.7162e+00, 1.7038e+00, 1.6918e+00, 1.6798e+00, 1.6673e+00, 1.6542e+00, 1.6407e+00, 1.6276e+00, 1.6155e+00, 1.6044e+00, 1.5939e+00, 1.5837e+00, 1.5738e+00, 1.5641e+00, 1.5548e+00, 1.5454e+00, 1.5354e+00, 1.5247e+00, 1.5136e+00, 1.5028e+00, 1.4931e+00, 1.4843e+00, 1.4761e+00, 1.4681e+00, 1.4603e+00, 1.4527e+00, 1.4455e+00, 1.4384e+00, 1.4309e+00, 1.4226e+00, 1.4135e+00, 1.4043e+00, 1.3956e+00, 1.3880e+00, 1.3813e+00, 1.3751e+00, 1.3689e+00, 1.3627e+00, 1.3568e+00, 1.3513e+00, 1.3459e+00, 1.3402e+00, 1.3338e+00}); + feg = Vctr_cpu({1.0711e+01, 1.0491e+01, 9.8905e+00, 9.0584e+00, 8.1501e+00, 7.2749e+00, 6.4866e+00, 5.7997e+00, 5.2083e+00, 4.6992e+00, 4.2586e+00, 3.8748e+00, 3.5379e+00, 3.2403e+00, 2.9761e+00, 2.7406e+00, 2.5300e+00, 2.3413e+00, 2.1717e+00, 2.0191e+00, 1.8816e+00, 1.7575e+00, 1.6453e+00, 1.5438e+00, 1.4517e+00, 1.3680e+00, 1.2918e+00, 1.2223e+00, 1.1588e+00, 1.1005e+00, 1.0469e+00, 9.9760e-01, 9.5200e-01, 9.0980e-01, 8.7060e-01, 8.3410e-01, 8.0010e-01, 7.6820e-01, 7.3830e-01, 7.1010e-01, 6.8360e-01, 6.5860e-01, 6.3500e-01, 6.1260e-01, 5.9130e-01, 5.7110e-01, 5.5180e-01, 5.3350e-01, 5.1600e-01, 4.9930e-01, 4.8330e-01, 4.6810e-01, 4.5350e-01, 4.3950e-01, 4.2600e-01, 4.1320e-01, 4.0080e-01, 3.8890e-01, 3.7760e-01, 3.6660e-01, 3.5610e-01, 3.4600e-01, 3.3630e-01, 3.2690e-01, 3.1790e-01, 3.0920e-01, 3.0090e-01, 2.9290e-01, 2.8510e-01, 2.7770e-01, 2.7050e-01, 2.6360e-01, 2.5690e-01, 2.5050e-01, 2.4430e-01, 2.3830e-01, 2.3250e-01, 2.2690e-01, 2.2150e-01, 2.1630e-01, 2.1130e-01, 2.0650e-01, 2.0180e-01, 1.9720e-01, 1.9290e-01, 1.8860e-01, 1.8450e-01, 1.8060e-01, 1.7670e-01, 1.7300e-01, 1.6940e-01, 1.6590e-01, 1.6250e-01, 1.5930e-01, 1.5610e-01, 1.5300e-01, 1.5000e-01, 1.4710e-01, 1.4430e-01, 1.4160e-01, 1.3900e-01, 1.3640e-01, 1.3390e-01, 1.3150e-01, 1.2910e-01, 1.2680e-01, 1.2460e-01, 1.2240e-01, 1.2030e-01, 1.1820e-01, 1.1620e-01, 1.1430e-01, 1.1240e-01, 1.1050e-01, 1.0870e-01, 1.0700e-01, 1.0520e-01, 1.0360e-01, 1.0190e-01, 1.0030e-01, 9.8800e-02, 9.7300e-02, 9.5800e-02, 9.4300e-02, 9.2900e-02, 9.1600e-02, 9.0200e-02, 8.8900e-02, 8.7600e-02, 8.6300e-02, 8.5100e-02, 8.3900e-02, 8.2700e-02, 8.1500e-02, 8.0400e-02, 7.9300e-02, 7.8200e-02, 7.7200e-02, 7.6100e-02, 7.5100e-02, 7.4100e-02, 7.3100e-02, 7.2200e-02, 7.1200e-02, 7.0300e-02, 6.9400e-02, 6.8500e-02, 6.7600e-02, 6.6800e-02, 6.5900e-02, 6.5100e-02, 6.4300e-02, 6.3500e-02, 6.2700e-02, 6.2000e-02, 6.1200e-02, 6.0500e-02, 5.9800e-02, 5.9000e-02, 5.8300e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3200e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0800e-02, 5.0300e-02, 4.9700e-02, 4.9200e-02, 4.8600e-02, 4.8100e-02, 4.7600e-02, 4.7100e-02, 4.6600e-02, 4.6100e-02, 4.5600e-02, 4.5100e-02, 4.4700e-02, 4.4200e-02, 4.3700e-02, 4.3300e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0300e-02, 3.9900e-02, 3.9500e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8000e-02, 3.7600e-02, 3.7300e-02, 3.6900e-02, 3.6600e-02, 3.6200e-02, 3.5900e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2700e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0500e-02, 3.0200e-02, 2.9900e-02, 2.9700e-02, 2.9400e-02, 2.9200e-02, 2.8900e-02, 2.8700e-02, 2.8400e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02}); + } + break; + case 42: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.2000e+01, 4.1736e+01, 4.1000e+01, 3.9922e+01, 3.8646e+01, 3.7280e+01, 3.5892e+01, 3.4519e+01, 3.3181e+01, 3.1890e+01, 3.0656e+01, 2.9483e+01, 2.8377e+01, 2.7338e+01, 2.6367e+01, 2.5462e+01, 2.4621e+01, 2.3838e+01, 2.3111e+01, 2.2433e+01, 2.1798e+01, 2.1203e+01, 2.0640e+01, 2.0107e+01, 1.9598e+01, 1.9109e+01, 1.8637e+01, 1.8179e+01, 1.7733e+01, 1.7297e+01, 1.6870e+01, 1.6450e+01, 1.6037e+01, 1.5630e+01, 1.5230e+01, 1.4836e+01, 1.4448e+01, 1.4067e+01, 1.3693e+01, 1.3326e+01, 1.2967e+01, 1.2617e+01, 1.2275e+01, 1.1943e+01, 1.1620e+01, 1.1307e+01, 1.1004e+01, 1.0711e+01, 1.0428e+01, 1.0156e+01, 9.8943e+00, 9.6432e+00, 9.4024e+00, 9.1719e+00, 8.9516e+00, 8.7412e+00, 8.5405e+00, 8.3493e+00, 8.1673e+00, 7.9941e+00, 7.8295e+00, 7.6731e+00, 7.5245e+00, 7.3836e+00, 7.2498e+00, 7.1228e+00, 7.0023e+00, 6.8880e+00, 6.7794e+00, 6.6762e+00, 6.5781e+00, 6.4849e+00, 6.3961e+00, 6.3115e+00, 6.2307e+00, 6.1536e+00, 6.0799e+00, 6.0091e+00, 5.9412e+00, 5.8760e+00, 5.8132e+00, 5.7526e+00, 5.6938e+00, 5.6369e+00, 5.5818e+00, 5.5283e+00, 5.4760e+00, 5.4248e+00, 5.3747e+00, 5.3258e+00, 5.2779e+00, 5.2305e+00, 5.1837e+00, 5.1376e+00, 5.0922e+00, 5.0474e+00, 5.0029e+00, 4.9585e+00, 4.9144e+00, 4.8708e+00, 4.8276e+00, 4.7847e+00, 4.7417e+00, 4.6986e+00, 4.6557e+00, 4.6132e+00, 4.5711e+00, 4.5290e+00, 4.4868e+00, 4.4443e+00, 4.4019e+00, 4.3600e+00, 4.3185e+00, 4.2771e+00, 4.2355e+00, 4.1936e+00, 4.1517e+00, 4.1102e+00, 4.0693e+00, 4.0287e+00, 3.9881e+00, 3.9473e+00, 3.9063e+00, 3.8654e+00, 3.8250e+00, 3.7853e+00, 3.7460e+00, 3.7069e+00, 3.6675e+00, 3.6279e+00, 3.5884e+00, 3.5495e+00, 3.5114e+00, 3.4740e+00, 3.4368e+00, 3.3996e+00, 3.3622e+00, 3.3247e+00, 3.2876e+00, 3.2513e+00, 3.2159e+00, 3.1811e+00, 3.1466e+00, 3.1121e+00, 3.0774e+00, 3.0426e+00, 3.0084e+00, 2.9749e+00, 2.9424e+00, 2.9106e+00, 2.8793e+00, 2.8481e+00, 2.8167e+00, 2.7851e+00, 2.7538e+00, 2.7232e+00, 2.6936e+00, 2.6649e+00, 2.6368e+00, 2.6091e+00, 2.5815e+00, 2.5537e+00, 2.5257e+00, 2.4979e+00, 2.4709e+00, 2.4449e+00, 2.4198e+00, 2.3954e+00, 2.3714e+00, 2.3476e+00, 2.3237e+00, 2.2995e+00, 2.2752e+00, 2.2513e+00, 2.2285e+00, 2.2066e+00, 2.1855e+00, 2.1649e+00, 2.1447e+00, 2.1247e+00, 2.1046e+00, 2.0840e+00, 2.0633e+00, 2.0430e+00, 2.0236e+00, 2.0052e+00, 1.9875e+00, 1.9704e+00, 1.9536e+00, 1.9372e+00, 1.9207e+00, 1.9039e+00, 1.8866e+00, 1.8693e+00, 1.8525e+00, 1.8368e+00, 1.8219e+00, 1.8077e+00, 1.7938e+00, 1.7803e+00, 1.7671e+00, 1.7539e+00, 1.7404e+00, 1.7262e+00, 1.7118e+00, 1.6977e+00, 1.6846e+00, 1.6724e+00, 1.6608e+00, 1.6497e+00, 1.6388e+00, 1.6282e+00, 1.6179e+00, 1.6075e+00, 1.5966e+00, 1.5850e+00, 1.5731e+00, 1.5615e+00, 1.5509e+00, 1.5412e+00, 1.5321e+00, 1.5233e+00, 1.5147e+00, 1.5064e+00, 1.4984e+00, 1.4905e+00, 1.4821e+00, 1.4731e+00, 1.4634e+00, 1.4535e+00, 1.4442e+00, 1.4359e+00, 1.4285e+00, 1.4215e+00, 1.4147e+00, 1.4081e+00, 1.4016e+00, 1.3955e+00, 1.3895e+00, 1.3832e+00, 1.3761e+00}); + feg = Vctr_cpu({1.0286e+01, 1.0095e+01, 9.5730e+00, 8.8405e+00, 8.0278e+00, 7.2300e+00, 6.4973e+00, 5.8467e+00, 5.2770e+00, 4.7796e+00, 4.3442e+00, 3.9613e+00, 3.6229e+00, 3.3223e+00, 3.0544e+00, 2.8147e+00, 2.5997e+00, 2.4065e+00, 2.2325e+00, 2.0757e+00, 1.9340e+00, 1.8059e+00, 1.6900e+00, 1.5848e+00, 1.4894e+00, 1.4026e+00, 1.3235e+00, 1.2513e+00, 1.1853e+00, 1.1248e+00, 1.0693e+00, 1.0181e+00, 9.7090e-01, 9.2730e-01, 8.8680e-01, 8.4920e-01, 8.1410e-01, 7.8140e-01, 7.5070e-01, 7.2190e-01, 6.9490e-01, 6.6940e-01, 6.4530e-01, 6.2250e-01, 6.0090e-01, 5.8040e-01, 5.6100e-01, 5.4240e-01, 5.2470e-01, 5.0790e-01, 4.9180e-01, 4.7640e-01, 4.6160e-01, 4.4750e-01, 4.3400e-01, 4.2100e-01, 4.0860e-01, 3.9660e-01, 3.8510e-01, 3.7410e-01, 3.6350e-01, 3.5330e-01, 3.4340e-01, 3.3400e-01, 3.2490e-01, 3.1610e-01, 3.0770e-01, 2.9950e-01, 2.9170e-01, 2.8410e-01, 2.7680e-01, 2.6980e-01, 2.6300e-01, 2.5650e-01, 2.5010e-01, 2.4400e-01, 2.3810e-01, 2.3250e-01, 2.2700e-01, 2.2170e-01, 2.1650e-01, 2.1160e-01, 2.0680e-01, 2.0210e-01, 1.9760e-01, 1.9330e-01, 1.8910e-01, 1.8500e-01, 1.8110e-01, 1.7730e-01, 1.7360e-01, 1.7000e-01, 1.6660e-01, 1.6320e-01, 1.6000e-01, 1.5680e-01, 1.5370e-01, 1.5080e-01, 1.4790e-01, 1.4510e-01, 1.4230e-01, 1.3970e-01, 1.3710e-01, 1.3460e-01, 1.3220e-01, 1.2990e-01, 1.2760e-01, 1.2530e-01, 1.2320e-01, 1.2100e-01, 1.1900e-01, 1.1700e-01, 1.1500e-01, 1.1310e-01, 1.1130e-01, 1.0950e-01, 1.0770e-01, 1.0600e-01, 1.0430e-01, 1.0270e-01, 1.0110e-01, 9.9500e-02, 9.8000e-02, 9.6500e-02, 9.5100e-02, 9.3700e-02, 9.2300e-02, 9.0900e-02, 8.9600e-02, 8.8300e-02, 8.7000e-02, 8.5800e-02, 8.4600e-02, 8.3400e-02, 8.2200e-02, 8.1100e-02, 8.0000e-02, 7.8900e-02, 7.7800e-02, 7.6800e-02, 7.5800e-02, 7.4800e-02, 7.3800e-02, 7.2800e-02, 7.1900e-02, 7.1000e-02, 7.0000e-02, 6.9200e-02, 6.8300e-02, 6.7400e-02, 6.6600e-02, 6.5800e-02, 6.4900e-02, 6.4200e-02, 6.3400e-02, 6.2600e-02, 6.1900e-02, 6.1100e-02, 6.0400e-02, 5.9700e-02, 5.9000e-02, 5.8300e-02, 5.7600e-02, 5.6900e-02, 5.6300e-02, 5.5600e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3200e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9200e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7200e-02, 4.6700e-02, 4.6200e-02, 4.5700e-02, 4.5200e-02, 4.4700e-02, 4.4300e-02, 4.3800e-02, 4.3400e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.0800e-02, 4.0400e-02, 4.0100e-02, 3.9700e-02, 3.9300e-02, 3.8900e-02, 3.8500e-02, 3.8100e-02, 3.7800e-02, 3.7400e-02, 3.7100e-02, 3.6700e-02, 3.6400e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2000e-02, 3.1700e-02, 3.1500e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0400e-02, 3.0100e-02, 2.9900e-02, 2.9600e-02, 2.9400e-02, 2.9100e-02, 2.8900e-02, 2.8600e-02, 2.8400e-02, 2.8100e-02, 2.7900e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02}); + } + break; + case 43: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.3000e+01, 4.2722e+01, 4.1947e+01, 4.0813e+01, 3.9481e+01, 3.8072e+01, 3.6659e+01, 3.5276e+01, 3.3938e+01, 3.2650e+01, 3.1414e+01, 3.0233e+01, 2.9111e+01, 2.8049e+01, 2.7050e+01, 2.6113e+01, 2.5237e+01, 2.4420e+01, 2.3659e+01, 2.2950e+01, 2.2288e+01, 2.1669e+01, 2.1088e+01, 2.0540e+01, 2.0020e+01, 1.9525e+01, 1.9050e+01, 1.8593e+01, 1.8151e+01, 1.7721e+01, 1.7301e+01, 1.6890e+01, 1.6486e+01, 1.6089e+01, 1.5698e+01, 1.5313e+01, 1.4934e+01, 1.4560e+01, 1.4193e+01, 1.3831e+01, 1.3476e+01, 1.3127e+01, 1.2786e+01, 1.2452e+01, 1.2127e+01, 1.1809e+01, 1.1501e+01, 1.1201e+01, 1.0910e+01, 1.0629e+01, 1.0357e+01, 1.0095e+01, 9.8426e+00, 9.5998e+00, 9.3667e+00, 9.1430e+00, 8.9288e+00, 8.7238e+00, 8.5280e+00, 8.3410e+00, 8.1625e+00, 7.9925e+00, 7.8306e+00, 7.6765e+00, 7.5298e+00, 7.3903e+00, 7.2578e+00, 7.1318e+00, 7.0120e+00, 6.8982e+00, 6.7900e+00, 6.6871e+00, 6.5891e+00, 6.4958e+00, 6.4071e+00, 6.3224e+00, 6.2415e+00, 6.1643e+00, 6.0904e+00, 6.0197e+00, 5.9517e+00, 5.8864e+00, 5.8236e+00, 5.7631e+00, 5.7046e+00, 5.6480e+00, 5.5931e+00, 5.5398e+00, 5.4880e+00, 5.4374e+00, 5.3881e+00, 5.3397e+00, 5.2922e+00, 5.2457e+00, 5.2000e+00, 5.1549e+00, 5.1104e+00, 5.0663e+00, 5.0228e+00, 4.9798e+00, 4.9372e+00, 4.8948e+00, 4.8526e+00, 4.8105e+00, 4.7688e+00, 4.7275e+00, 4.6864e+00, 4.6452e+00, 4.6039e+00, 4.5628e+00, 4.5219e+00, 4.4814e+00, 4.4410e+00, 4.4005e+00, 4.3598e+00, 4.3191e+00, 4.2787e+00, 4.2387e+00, 4.1989e+00, 4.1591e+00, 4.1190e+00, 4.0788e+00, 4.0387e+00, 3.9992e+00, 3.9601e+00, 3.9213e+00, 3.8823e+00, 3.8431e+00, 3.8038e+00, 3.7648e+00, 3.7264e+00, 3.6886e+00, 3.6512e+00, 3.6137e+00, 3.5759e+00, 3.5381e+00, 3.5005e+00, 3.4636e+00, 3.4274e+00, 3.3918e+00, 3.3564e+00, 3.3208e+00, 3.2851e+00, 3.2494e+00, 3.2141e+00, 3.1797e+00, 3.1460e+00, 3.1131e+00, 3.0803e+00, 3.0474e+00, 3.0142e+00, 2.9811e+00, 2.9486e+00, 2.9168e+00, 2.8858e+00, 2.8557e+00, 2.8261e+00, 2.7964e+00, 2.7664e+00, 2.7363e+00, 2.7065e+00, 2.6774e+00, 2.6491e+00, 2.6217e+00, 2.5951e+00, 2.5689e+00, 2.5426e+00, 2.5160e+00, 2.4893e+00, 2.4629e+00, 2.4371e+00, 2.4121e+00, 2.3880e+00, 2.3648e+00, 2.3422e+00, 2.3196e+00, 2.2966e+00, 2.2734e+00, 2.2502e+00, 2.2276e+00, 2.2056e+00, 2.1843e+00, 2.1640e+00, 2.1445e+00, 2.1255e+00, 2.1064e+00, 2.0869e+00, 2.0671e+00, 2.0473e+00, 2.0280e+00, 2.0093e+00, 1.9913e+00, 1.9739e+00, 1.9575e+00, 1.9418e+00, 1.9263e+00, 1.9104e+00, 1.8939e+00, 1.8772e+00, 1.8607e+00, 1.8448e+00, 1.8294e+00, 1.8146e+00, 1.8004e+00, 1.7871e+00, 1.7745e+00, 1.7621e+00, 1.7493e+00, 1.7358e+00, 1.7220e+00, 1.7082e+00, 1.6950e+00, 1.6823e+00, 1.6700e+00, 1.6582e+00, 1.6471e+00, 1.6368e+00, 1.6271e+00, 1.6173e+00, 1.6070e+00, 1.5959e+00, 1.5844e+00, 1.5732e+00, 1.5625e+00, 1.5522e+00, 1.5423e+00, 1.5327e+00, 1.5236e+00, 1.5154e+00, 1.5079e+00, 1.5006e+00, 1.4928e+00, 1.4841e+00, 1.4748e+00, 1.4654e+00, 1.4563e+00, 1.4478e+00, 1.4397e+00, 1.4318e+00, 1.4241e+00, 1.4169e+00}); + feg = Vctr_cpu({1.0824e+01, 1.0628e+01, 1.0083e+01, 9.3033e+00, 8.4226e+00, 7.5488e+00, 6.7451e+00, 6.0360e+00, 5.4219e+00, 4.8931e+00, 4.4368e+00, 4.0405e+00, 3.6936e+00, 3.3877e+00, 3.1163e+00, 2.8741e+00, 2.6571e+00, 2.4619e+00, 2.2859e+00, 2.1268e+00, 1.9828e+00, 1.8522e+00, 1.7337e+00, 1.6259e+00, 1.5278e+00, 1.4383e+00, 1.3567e+00, 1.2821e+00, 1.2137e+00, 1.1511e+00, 1.0935e+00, 1.0404e+00, 9.9150e-01, 9.4630e-01, 9.0440e-01, 8.6550e-01, 8.2930e-01, 7.9550e-01, 7.6400e-01, 7.3440e-01, 7.0660e-01, 6.8050e-01, 6.5590e-01, 6.3270e-01, 6.1070e-01, 5.8980e-01, 5.7010e-01, 5.5130e-01, 5.3340e-01, 5.1630e-01, 5.0000e-01, 4.8450e-01, 4.6960e-01, 4.5530e-01, 4.4170e-01, 4.2860e-01, 4.1600e-01, 4.0400e-01, 3.9240e-01, 3.8130e-01, 3.7060e-01, 3.6030e-01, 3.5040e-01, 3.4080e-01, 3.3160e-01, 3.2280e-01, 3.1420e-01, 3.0600e-01, 2.9800e-01, 2.9040e-01, 2.8300e-01, 2.7590e-01, 2.6900e-01, 2.6230e-01, 2.5590e-01, 2.4970e-01, 2.4370e-01, 2.3790e-01, 2.3230e-01, 2.2690e-01, 2.2170e-01, 2.1660e-01, 2.1170e-01, 2.0700e-01, 2.0240e-01, 1.9800e-01, 1.9370e-01, 1.8950e-01, 1.8550e-01, 1.8160e-01, 1.7780e-01, 1.7420e-01, 1.7060e-01, 1.6720e-01, 1.6380e-01, 1.6060e-01, 1.5740e-01, 1.5440e-01, 1.5140e-01, 1.4860e-01, 1.4580e-01, 1.4300e-01, 1.4040e-01, 1.3780e-01, 1.3540e-01, 1.3290e-01, 1.3060e-01, 1.2830e-01, 1.2610e-01, 1.2390e-01, 1.2180e-01, 1.1970e-01, 1.1770e-01, 1.1580e-01, 1.1390e-01, 1.1200e-01, 1.1020e-01, 1.0840e-01, 1.0670e-01, 1.0500e-01, 1.0340e-01, 1.0180e-01, 1.0020e-01, 9.8700e-02, 9.7200e-02, 9.5800e-02, 9.4400e-02, 9.3000e-02, 9.1600e-02, 9.0300e-02, 8.9000e-02, 8.7700e-02, 8.6500e-02, 8.5300e-02, 8.4100e-02, 8.2900e-02, 8.1800e-02, 8.0700e-02, 7.9600e-02, 7.8500e-02, 7.7500e-02, 7.6400e-02, 7.5400e-02, 7.4400e-02, 7.3500e-02, 7.2500e-02, 7.1600e-02, 7.0700e-02, 6.9800e-02, 6.8900e-02, 6.8100e-02, 6.7200e-02, 6.6400e-02, 6.5600e-02, 6.4800e-02, 6.4000e-02, 6.3200e-02, 6.2500e-02, 6.1700e-02, 6.1000e-02, 6.0300e-02, 5.9600e-02, 5.8900e-02, 5.8200e-02, 5.7500e-02, 5.6900e-02, 5.6200e-02, 5.5600e-02, 5.5000e-02, 5.4400e-02, 5.3700e-02, 5.3200e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7200e-02, 4.6700e-02, 4.6200e-02, 4.5800e-02, 4.5300e-02, 4.4800e-02, 4.4400e-02, 4.3900e-02, 4.3500e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0600e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8300e-02, 3.7900e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4300e-02, 3.3900e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1400e-02, 3.1100e-02, 3.0800e-02, 3.0600e-02, 3.0300e-02, 3.0000e-02, 2.9800e-02, 2.9500e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8600e-02, 2.8300e-02, 2.8100e-02, 2.7900e-02, 2.7600e-02}); + } + break; + case 44: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.4000e+01, 4.3755e+01, 4.3061e+01, 4.2027e+01, 4.0771e+01, 3.9394e+01, 3.7961e+01, 3.6518e+01, 3.5091e+01, 3.3701e+01, 3.2361e+01, 3.1083e+01, 2.9873e+01, 2.8734e+01, 2.7670e+01, 2.6678e+01, 2.5758e+01, 2.4905e+01, 2.4115e+01, 2.3384e+01, 2.2705e+01, 2.2074e+01, 2.1485e+01, 2.0932e+01, 2.0412e+01, 1.9918e+01, 1.9447e+01, 1.8995e+01, 1.8560e+01, 1.8138e+01, 1.7727e+01, 1.7326e+01, 1.6932e+01, 1.6544e+01, 1.6163e+01, 1.5786e+01, 1.5415e+01, 1.5048e+01, 1.4687e+01, 1.4330e+01, 1.3978e+01, 1.3632e+01, 1.3292e+01, 1.2958e+01, 1.2631e+01, 1.2310e+01, 1.1998e+01, 1.1693e+01, 1.1396e+01, 1.1107e+01, 1.0827e+01, 1.0555e+01, 1.0293e+01, 1.0039e+01, 9.7949e+00, 9.5595e+00, 9.3331e+00, 9.1157e+00, 8.9070e+00, 8.7071e+00, 8.5158e+00, 8.3328e+00, 8.1580e+00, 7.9911e+00, 7.8319e+00, 7.6801e+00, 7.5354e+00, 7.3977e+00, 7.2665e+00, 7.1416e+00, 7.0227e+00, 6.9096e+00, 6.8019e+00, 6.6993e+00, 6.6016e+00, 6.5085e+00, 6.4198e+00, 6.3351e+00, 6.2541e+00, 6.1768e+00, 6.1029e+00, 6.0320e+00, 5.9639e+00, 5.8985e+00, 5.8357e+00, 5.7752e+00, 5.7167e+00, 5.6601e+00, 5.6053e+00, 5.5522e+00, 5.5007e+00, 5.4504e+00, 5.4012e+00, 5.3532e+00, 5.3063e+00, 5.2605e+00, 5.2154e+00, 5.1708e+00, 5.1268e+00, 5.0836e+00, 5.0411e+00, 4.9991e+00, 4.9572e+00, 4.9156e+00, 4.8743e+00, 4.8335e+00, 4.7931e+00, 4.7530e+00, 4.7127e+00, 4.6725e+00, 4.6323e+00, 4.5926e+00, 4.5533e+00, 4.5140e+00, 4.4747e+00, 4.4351e+00, 4.3955e+00, 4.3562e+00, 4.3173e+00, 4.2786e+00, 4.2400e+00, 4.2011e+00, 4.1620e+00, 4.1230e+00, 4.0843e+00, 4.0461e+00, 4.0082e+00, 3.9704e+00, 3.9323e+00, 3.8939e+00, 3.8557e+00, 3.8178e+00, 3.7805e+00, 3.7437e+00, 3.7070e+00, 3.6703e+00, 3.6333e+00, 3.5963e+00, 3.5596e+00, 3.5234e+00, 3.4879e+00, 3.4528e+00, 3.4180e+00, 3.3831e+00, 3.3480e+00, 3.3129e+00, 3.2781e+00, 3.2440e+00, 3.2106e+00, 3.1778e+00, 3.1453e+00, 3.1129e+00, 3.0804e+00, 3.0478e+00, 3.0153e+00, 2.9835e+00, 2.9524e+00, 2.9221e+00, 2.8923e+00, 2.8628e+00, 2.8335e+00, 2.8039e+00, 2.7743e+00, 2.7449e+00, 2.7161e+00, 2.6882e+00, 2.6610e+00, 2.6344e+00, 2.6082e+00, 2.5822e+00, 2.5561e+00, 2.5298e+00, 2.5036e+00, 2.4777e+00, 2.4527e+00, 2.4285e+00, 2.4050e+00, 2.3821e+00, 2.3595e+00, 2.3371e+00, 2.3145e+00, 2.2917e+00, 2.2689e+00, 2.2464e+00, 2.2248e+00, 2.2040e+00, 2.1839e+00, 2.1643e+00, 2.1451e+00, 2.1262e+00, 2.1073e+00, 2.0882e+00, 2.0687e+00, 2.0493e+00, 2.0304e+00, 2.0124e+00, 1.9952e+00, 1.9786e+00, 1.9624e+00, 1.9466e+00, 1.9311e+00, 1.9156e+00, 1.8998e+00, 1.8836e+00, 1.8673e+00, 1.8513e+00, 1.8361e+00, 1.8218e+00, 1.8081e+00, 1.7948e+00, 1.7819e+00, 1.7693e+00, 1.7569e+00, 1.7444e+00, 1.7315e+00, 1.7181e+00, 1.7046e+00, 1.6914e+00, 1.6789e+00, 1.6674e+00, 1.6564e+00, 1.6459e+00, 1.6356e+00, 1.6255e+00, 1.6158e+00, 1.6060e+00, 1.5960e+00, 1.5854e+00, 1.5743e+00, 1.5631e+00, 1.5524e+00, 1.5426e+00, 1.5336e+00, 1.5251e+00, 1.5169e+00, 1.5088e+00, 1.5011e+00, 1.4935e+00, 1.4860e+00, 1.4783e+00, 1.4699e+00}); + feg = Vctr_cpu({9.5520e+00, 9.4015e+00, 8.9865e+00, 8.3958e+00, 7.7274e+00, 7.0558e+00, 6.4235e+00, 5.8475e+00, 5.3307e+00, 4.8691e+00, 4.4569e+00, 4.0879e+00, 3.7569e+00, 3.4591e+00, 3.1906e+00, 2.9481e+00, 2.7288e+00, 2.5302e+00, 2.3502e+00, 2.1869e+00, 2.0386e+00, 1.9039e+00, 1.7814e+00, 1.6698e+00, 1.5682e+00, 1.4755e+00, 1.3909e+00, 1.3135e+00, 1.2426e+00, 1.1776e+00, 1.1179e+00, 1.0629e+00, 1.0123e+00, 9.6550e-01, 9.2210e-01, 8.8200e-01, 8.4460e-01, 8.0980e-01, 7.7740e-01, 7.4700e-01, 7.1850e-01, 6.9180e-01, 6.6660e-01, 6.4290e-01, 6.2050e-01, 5.9930e-01, 5.7920e-01, 5.6010e-01, 5.4190e-01, 5.2460e-01, 5.0810e-01, 4.9240e-01, 4.7740e-01, 4.6300e-01, 4.4920e-01, 4.3600e-01, 4.2330e-01, 4.1120e-01, 3.9950e-01, 3.8830e-01, 3.7750e-01, 3.6710e-01, 3.5710e-01, 3.4740e-01, 3.3810e-01, 3.2920e-01, 3.2060e-01, 3.1220e-01, 3.0420e-01, 2.9650e-01, 2.8900e-01, 2.8180e-01, 2.7480e-01, 2.6800e-01, 2.6150e-01, 2.5520e-01, 2.4920e-01, 2.4330e-01, 2.3760e-01, 2.3210e-01, 2.2680e-01, 2.2160e-01, 2.1660e-01, 2.1180e-01, 2.0710e-01, 2.0260e-01, 1.9820e-01, 1.9400e-01, 1.8990e-01, 1.8590e-01, 1.8200e-01, 1.7830e-01, 1.7460e-01, 1.7110e-01, 1.6770e-01, 1.6440e-01, 1.6120e-01, 1.5800e-01, 1.5500e-01, 1.5210e-01, 1.4920e-01, 1.4640e-01, 1.4370e-01, 1.4110e-01, 1.3850e-01, 1.3600e-01, 1.3360e-01, 1.3130e-01, 1.2900e-01, 1.2680e-01, 1.2460e-01, 1.2250e-01, 1.2040e-01, 1.1840e-01, 1.1650e-01, 1.1460e-01, 1.1270e-01, 1.1090e-01, 1.0910e-01, 1.0740e-01, 1.0570e-01, 1.0410e-01, 1.0250e-01, 1.0090e-01, 9.9400e-02, 9.7900e-02, 9.6500e-02, 9.5000e-02, 9.3600e-02, 9.2300e-02, 9.1000e-02, 8.9700e-02, 8.8400e-02, 8.7100e-02, 8.5900e-02, 8.4700e-02, 8.3600e-02, 8.2400e-02, 8.1300e-02, 8.0200e-02, 7.9200e-02, 7.8100e-02, 7.7100e-02, 7.6100e-02, 7.5100e-02, 7.4100e-02, 7.3200e-02, 7.2200e-02, 7.1300e-02, 7.0400e-02, 6.9500e-02, 6.8700e-02, 6.7800e-02, 6.7000e-02, 6.6200e-02, 6.5400e-02, 6.4600e-02, 6.3800e-02, 6.3100e-02, 6.2300e-02, 6.1600e-02, 6.0900e-02, 6.0200e-02, 5.9500e-02, 5.8800e-02, 5.8100e-02, 5.7400e-02, 5.6800e-02, 5.6200e-02, 5.5500e-02, 5.4900e-02, 5.4300e-02, 5.3700e-02, 5.3100e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5800e-02, 4.5300e-02, 4.4900e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3100e-02, 4.2700e-02, 4.2300e-02, 4.1900e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0300e-02, 3.9900e-02, 3.9500e-02, 3.9100e-02, 3.8800e-02, 3.8400e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0500e-02, 3.0200e-02, 3.0000e-02, 2.9700e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8300e-02}); + } + break; + case 45: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.5000e+01, 4.4762e+01, 4.4089e+01, 4.3076e+01, 4.1835e+01, 4.0460e+01, 3.9017e+01, 3.7550e+01, 3.6089e+01, 3.4658e+01, 3.3272e+01, 3.1944e+01, 3.0682e+01, 2.9492e+01, 2.8377e+01, 2.7338e+01, 2.6372e+01, 2.5477e+01, 2.4649e+01, 2.3884e+01, 2.3176e+01, 2.2520e+01, 2.1910e+01, 2.1341e+01, 2.0807e+01, 2.0305e+01, 1.9829e+01, 1.9375e+01, 1.8941e+01, 1.8522e+01, 1.8116e+01, 1.7721e+01, 1.7335e+01, 1.6956e+01, 1.6584e+01, 1.6217e+01, 1.5855e+01, 1.5498e+01, 1.5144e+01, 1.4795e+01, 1.4450e+01, 1.4110e+01, 1.3774e+01, 1.3443e+01, 1.3118e+01, 1.2798e+01, 1.2485e+01, 1.2178e+01, 1.1877e+01, 1.1584e+01, 1.1299e+01, 1.1021e+01, 1.0751e+01, 1.0489e+01, 1.0236e+01, 9.9905e+00, 9.7537e+00, 9.5253e+00, 9.3053e+00, 9.0937e+00, 8.8904e+00, 8.6953e+00, 8.5082e+00, 8.3290e+00, 8.1575e+00, 7.9935e+00, 7.8367e+00, 7.6871e+00, 7.5442e+00, 7.4080e+00, 7.2780e+00, 7.1541e+00, 7.0360e+00, 6.9234e+00, 6.8161e+00, 6.7138e+00, 6.6163e+00, 6.5232e+00, 6.4344e+00, 6.3496e+00, 6.2686e+00, 6.1911e+00, 6.1168e+00, 6.0457e+00, 5.9776e+00, 5.9121e+00, 5.8491e+00, 5.7883e+00, 5.7297e+00, 5.6733e+00, 5.6186e+00, 5.5656e+00, 5.5140e+00, 5.4638e+00, 5.4151e+00, 5.3676e+00, 5.3212e+00, 5.2755e+00, 5.2307e+00, 5.1868e+00, 5.1438e+00, 5.1014e+00, 5.0595e+00, 5.0179e+00, 4.9767e+00, 4.9362e+00, 4.8962e+00, 4.8566e+00, 4.8169e+00, 4.7774e+00, 4.7380e+00, 4.6991e+00, 4.6606e+00, 4.6222e+00, 4.5838e+00, 4.5452e+00, 4.5067e+00, 4.4684e+00, 4.4305e+00, 4.3929e+00, 4.3552e+00, 4.3174e+00, 4.2793e+00, 4.2413e+00, 4.2036e+00, 4.1664e+00, 4.1293e+00, 4.0923e+00, 4.0550e+00, 4.0176e+00, 3.9802e+00, 3.9431e+00, 3.9064e+00, 3.8702e+00, 3.8341e+00, 3.7979e+00, 3.7614e+00, 3.7249e+00, 3.6886e+00, 3.6528e+00, 3.6176e+00, 3.5827e+00, 3.5481e+00, 3.5133e+00, 3.4784e+00, 3.4434e+00, 3.4087e+00, 3.3746e+00, 3.3411e+00, 3.3081e+00, 3.2754e+00, 3.2428e+00, 3.2100e+00, 3.1771e+00, 3.1444e+00, 3.1122e+00, 3.0808e+00, 3.0499e+00, 3.0196e+00, 2.9896e+00, 2.9596e+00, 2.9295e+00, 2.8993e+00, 2.8693e+00, 2.8399e+00, 2.8112e+00, 2.7832e+00, 2.7558e+00, 2.7288e+00, 2.7019e+00, 2.6750e+00, 2.6479e+00, 2.6208e+00, 2.5942e+00, 2.5683e+00, 2.5431e+00, 2.5186e+00, 2.4946e+00, 2.4710e+00, 2.4475e+00, 2.4240e+00, 2.4002e+00, 2.3764e+00, 2.3530e+00, 2.3304e+00, 2.3085e+00, 2.2873e+00, 2.2666e+00, 2.2463e+00, 2.2263e+00, 2.2063e+00, 2.1860e+00, 2.1656e+00, 2.1452e+00, 2.1253e+00, 2.1062e+00, 2.0879e+00, 2.0702e+00, 2.0529e+00, 2.0360e+00, 2.0193e+00, 2.0027e+00, 1.9859e+00, 1.9687e+00, 1.9514e+00, 1.9344e+00, 1.9182e+00, 1.9029e+00, 1.8881e+00, 1.8738e+00, 1.8598e+00, 1.8461e+00, 1.8327e+00, 1.8192e+00, 1.8053e+00, 1.7910e+00, 1.7766e+00, 1.7625e+00, 1.7492e+00, 1.7367e+00, 1.7248e+00, 1.7133e+00, 1.7020e+00, 1.6911e+00, 1.6804e+00, 1.6697e+00, 1.6588e+00, 1.6473e+00, 1.6355e+00, 1.6236e+00, 1.6122e+00, 1.6016e+00, 1.5917e+00, 1.5824e+00, 1.5734e+00, 1.5646e+00, 1.5560e+00, 1.5477e+00, 1.5395e+00, 1.5309e+00, 1.5219e+00}); + feg = Vctr_cpu({9.2363e+00, 9.1005e+00, 8.7249e+00, 8.1875e+00, 7.5750e+00, 6.9544e+00, 6.3646e+00, 5.8225e+00, 5.3316e+00, 4.8893e+00, 4.4911e+00, 4.1320e+00, 3.8076e+00, 3.5139e+00, 3.2477e+00, 3.0060e+00, 2.7865e+00, 2.5869e+00, 2.4052e+00, 2.2399e+00, 2.0893e+00, 1.9520e+00, 1.8269e+00, 1.7127e+00, 1.6084e+00, 1.5131e+00, 1.4259e+00, 1.3460e+00, 1.2728e+00, 1.2056e+00, 1.1439e+00, 1.0870e+00, 1.0346e+00, 9.8610e-01, 9.4130e-01, 8.9980e-01, 8.6120e-01, 8.2520e-01, 7.9180e-01, 7.6050e-01, 7.3120e-01, 7.0370e-01, 6.7790e-01, 6.5360e-01, 6.3060e-01, 6.0900e-01, 5.8840e-01, 5.6900e-01, 5.5050e-01, 5.3300e-01, 5.1620e-01, 5.0030e-01, 4.8500e-01, 4.7050e-01, 4.5650e-01, 4.4320e-01, 4.3040e-01, 4.1810e-01, 4.0630e-01, 3.9500e-01, 3.8410e-01, 3.7360e-01, 3.6350e-01, 3.5380e-01, 3.4440e-01, 3.3540e-01, 3.2670e-01, 3.1830e-01, 3.1020e-01, 3.0240e-01, 2.9480e-01, 2.8750e-01, 2.8040e-01, 2.7360e-01, 2.6700e-01, 2.6060e-01, 2.5450e-01, 2.4850e-01, 2.4270e-01, 2.3720e-01, 2.3170e-01, 2.2650e-01, 2.2140e-01, 2.1650e-01, 2.1180e-01, 2.0720e-01, 2.0270e-01, 1.9840e-01, 1.9420e-01, 1.9010e-01, 1.8620e-01, 1.8240e-01, 1.7860e-01, 1.7500e-01, 1.7160e-01, 1.6820e-01, 1.6490e-01, 1.6170e-01, 1.5860e-01, 1.5560e-01, 1.5260e-01, 1.4980e-01, 1.4700e-01, 1.4430e-01, 1.4170e-01, 1.3920e-01, 1.3670e-01, 1.3430e-01, 1.3190e-01, 1.2960e-01, 1.2740e-01, 1.2530e-01, 1.2310e-01, 1.2110e-01, 1.1910e-01, 1.1710e-01, 1.1520e-01, 1.1340e-01, 1.1160e-01, 1.0980e-01, 1.0810e-01, 1.0640e-01, 1.0480e-01, 1.0320e-01, 1.0160e-01, 1.0010e-01, 9.8600e-02, 9.7100e-02, 9.5700e-02, 9.4300e-02, 9.2900e-02, 9.1600e-02, 9.0300e-02, 8.9000e-02, 8.7800e-02, 8.6600e-02, 8.5400e-02, 8.4200e-02, 8.3100e-02, 8.1900e-02, 8.0900e-02, 7.9800e-02, 7.8700e-02, 7.7700e-02, 7.6700e-02, 7.5700e-02, 7.4700e-02, 7.3800e-02, 7.2800e-02, 7.1900e-02, 7.1000e-02, 7.0100e-02, 6.9300e-02, 6.8400e-02, 6.7600e-02, 6.6800e-02, 6.6000e-02, 6.5200e-02, 6.4400e-02, 6.3600e-02, 6.2900e-02, 6.2200e-02, 6.1400e-02, 6.0700e-02, 6.0000e-02, 5.9300e-02, 5.8700e-02, 5.8000e-02, 5.7400e-02, 5.6700e-02, 5.6100e-02, 5.5500e-02, 5.4900e-02, 5.4300e-02, 5.3700e-02, 5.3100e-02, 5.2500e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5400e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3600e-02, 4.3200e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0800e-02, 4.0400e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8900e-02, 3.8500e-02, 3.8200e-02, 3.7800e-02, 3.7500e-02, 3.7100e-02, 3.6800e-02, 3.6400e-02, 3.6100e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4500e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1700e-02, 3.1400e-02, 3.1100e-02, 3.0900e-02, 3.0600e-02, 3.0400e-02, 3.0100e-02, 2.9900e-02, 2.9600e-02, 2.9400e-02, 2.9100e-02, 2.8900e-02}); + } + break; + case 46: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.6000e+01, 4.5803e+01, 4.5231e+01, 4.4332e+01, 4.3172e+01, 4.1825e+01, 4.0359e+01, 3.8831e+01, 3.7289e+01, 3.5766e+01, 3.4288e+01, 3.2872e+01, 3.1529e+01, 3.0266e+01, 2.9085e+01, 2.7987e+01, 2.6969e+01, 2.6029e+01, 2.5162e+01, 2.4363e+01, 2.3626e+01, 2.2946e+01, 2.2316e+01, 2.1732e+01, 2.1187e+01, 2.0676e+01, 2.0195e+01, 1.9740e+01, 1.9305e+01, 1.8889e+01, 1.8488e+01, 1.8099e+01, 1.7721e+01, 1.7350e+01, 1.6987e+01, 1.6629e+01, 1.6276e+01, 1.5927e+01, 1.5582e+01, 1.5241e+01, 1.4904e+01, 1.4570e+01, 1.4239e+01, 1.3913e+01, 1.3591e+01, 1.3274e+01, 1.2962e+01, 1.2655e+01, 1.2353e+01, 1.2058e+01, 1.1769e+01, 1.1487e+01, 1.1211e+01, 1.0943e+01, 1.0682e+01, 1.0429e+01, 1.0184e+01, 9.9462e+00, 9.7164e+00, 9.4945e+00, 9.2805e+00, 9.0744e+00, 8.8761e+00, 8.6854e+00, 8.5024e+00, 8.3268e+00, 8.1585e+00, 7.9973e+00, 7.8430e+00, 7.6954e+00, 7.5544e+00, 7.4196e+00, 7.2909e+00, 7.1681e+00, 7.0508e+00, 6.9388e+00, 6.8320e+00, 6.7300e+00, 6.6326e+00, 6.5396e+00, 6.4508e+00, 6.3659e+00, 6.2847e+00, 6.2070e+00, 6.1326e+00, 6.0613e+00, 5.9929e+00, 5.9272e+00, 5.8640e+00, 5.8031e+00, 5.7444e+00, 5.6877e+00, 5.6329e+00, 5.5799e+00, 5.5284e+00, 5.4784e+00, 5.4298e+00, 5.3823e+00, 5.3360e+00, 5.2908e+00, 5.2465e+00, 5.2031e+00, 5.1604e+00, 5.1183e+00, 5.0770e+00, 5.0362e+00, 4.9959e+00, 4.9561e+00, 4.9167e+00, 4.8776e+00, 4.8388e+00, 4.8004e+00, 4.7622e+00, 4.7243e+00, 4.6865e+00, 4.6488e+00, 4.6113e+00, 4.5740e+00, 4.5368e+00, 4.4998e+00, 4.4629e+00, 4.4260e+00, 4.3891e+00, 4.3523e+00, 4.3157e+00, 4.2792e+00, 4.2428e+00, 4.2064e+00, 4.1701e+00, 4.1337e+00, 4.0974e+00, 4.0613e+00, 4.0254e+00, 3.9896e+00, 3.9539e+00, 3.9183e+00, 3.8826e+00, 3.8470e+00, 3.8116e+00, 3.7764e+00, 3.7415e+00, 3.7068e+00, 3.6722e+00, 3.6377e+00, 3.6032e+00, 3.5688e+00, 3.5346e+00, 3.5008e+00, 3.4673e+00, 3.4341e+00, 3.4012e+00, 3.3683e+00, 3.3356e+00, 3.3029e+00, 3.2704e+00, 3.2383e+00, 3.2066e+00, 3.1753e+00, 3.1444e+00, 3.1138e+00, 3.0833e+00, 3.0528e+00, 3.0225e+00, 2.9924e+00, 2.9627e+00, 2.9335e+00, 2.9049e+00, 2.8766e+00, 2.8487e+00, 2.8210e+00, 2.7933e+00, 2.7657e+00, 2.7383e+00, 2.7112e+00, 2.6846e+00, 2.6586e+00, 2.6332e+00, 2.6082e+00, 2.5835e+00, 2.5589e+00, 2.5344e+00, 2.5099e+00, 2.4856e+00, 2.4616e+00, 2.4381e+00, 2.4153e+00, 2.3930e+00, 2.3712e+00, 2.3498e+00, 2.3285e+00, 2.3073e+00, 2.2861e+00, 2.2649e+00, 2.2439e+00, 2.2233e+00, 2.2032e+00, 2.1838e+00, 2.1649e+00, 2.1466e+00, 2.1285e+00, 2.1106e+00, 2.0928e+00, 2.0748e+00, 2.0568e+00, 2.0389e+00, 2.0213e+00, 2.0042e+00, 1.9877e+00, 1.9718e+00, 1.9564e+00, 1.9414e+00, 1.9267e+00, 1.9120e+00, 1.8973e+00, 1.8824e+00, 1.8674e+00, 1.8524e+00, 1.8377e+00, 1.8235e+00, 1.8099e+00, 1.7969e+00, 1.7844e+00, 1.7723e+00, 1.7605e+00, 1.7487e+00, 1.7369e+00, 1.7249e+00, 1.7126e+00, 1.7002e+00, 1.6879e+00, 1.6759e+00, 1.6644e+00, 1.6535e+00, 1.6432e+00, 1.6334e+00, 1.6240e+00, 1.6147e+00, 1.6056e+00, 1.5963e+00, 1.5868e+00, 1.5769e+00}); + feg = Vctr_cpu({7.5832e+00, 7.5250e+00, 7.3569e+00, 7.0965e+00, 6.7675e+00, 6.3949e+00, 6.0008e+00, 5.6026e+00, 5.2124e+00, 4.8383e+00, 4.4850e+00, 4.1547e+00, 3.8482e+00, 3.5652e+00, 3.3048e+00, 3.0657e+00, 2.8467e+00, 2.6462e+00, 2.4628e+00, 2.2952e+00, 2.1420e+00, 2.0019e+00, 1.8739e+00, 1.7568e+00, 1.6497e+00, 1.5516e+00, 1.4618e+00, 1.3794e+00, 1.3039e+00, 1.2344e+00, 1.1706e+00, 1.1118e+00, 1.0576e+00, 1.0075e+00, 9.6110e-01, 9.1820e-01, 8.7830e-01, 8.4120e-01, 8.0670e-01, 7.7440e-01, 7.4420e-01, 7.1600e-01, 6.8950e-01, 6.6450e-01, 6.4100e-01, 6.1890e-01, 5.9790e-01, 5.7810e-01, 5.5920e-01, 5.4130e-01, 5.2430e-01, 5.0810e-01, 4.9270e-01, 4.7790e-01, 4.6380e-01, 4.5030e-01, 4.3740e-01, 4.2490e-01, 4.1300e-01, 4.0160e-01, 3.9060e-01, 3.8000e-01, 3.6980e-01, 3.6000e-01, 3.5060e-01, 3.4150e-01, 3.3270e-01, 3.2420e-01, 3.1600e-01, 3.0810e-01, 3.0050e-01, 2.9310e-01, 2.8590e-01, 2.7900e-01, 2.7240e-01, 2.6590e-01, 2.5970e-01, 2.5360e-01, 2.4780e-01, 2.4210e-01, 2.3660e-01, 2.3130e-01, 2.2620e-01, 2.2120e-01, 2.1640e-01, 2.1170e-01, 2.0710e-01, 2.0270e-01, 1.9850e-01, 1.9430e-01, 1.9030e-01, 1.8640e-01, 1.8260e-01, 1.7900e-01, 1.7540e-01, 1.7190e-01, 1.6860e-01, 1.6530e-01, 1.6210e-01, 1.5910e-01, 1.5610e-01, 1.5310e-01, 1.5030e-01, 1.4760e-01, 1.4490e-01, 1.4230e-01, 1.3970e-01, 1.3730e-01, 1.3490e-01, 1.3250e-01, 1.3030e-01, 1.2800e-01, 1.2590e-01, 1.2380e-01, 1.2170e-01, 1.1970e-01, 1.1780e-01, 1.1590e-01, 1.1400e-01, 1.1220e-01, 1.1050e-01, 1.0870e-01, 1.0710e-01, 1.0540e-01, 1.0380e-01, 1.0220e-01, 1.0070e-01, 9.9200e-02, 9.7800e-02, 9.6300e-02, 9.4900e-02, 9.3600e-02, 9.2300e-02, 9.0900e-02, 8.9700e-02, 8.8400e-02, 8.7200e-02, 8.6000e-02, 8.4800e-02, 8.3700e-02, 8.2600e-02, 8.1500e-02, 8.0400e-02, 7.9300e-02, 7.8300e-02, 7.7300e-02, 7.6300e-02, 7.5300e-02, 7.4400e-02, 7.3400e-02, 7.2500e-02, 7.1600e-02, 7.0700e-02, 6.9800e-02, 6.9000e-02, 6.8200e-02, 6.7300e-02, 6.6500e-02, 6.5700e-02, 6.5000e-02, 6.4200e-02, 6.3400e-02, 6.2700e-02, 6.2000e-02, 6.1300e-02, 6.0600e-02, 5.9900e-02, 5.9200e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6600e-02, 5.6000e-02, 5.5400e-02, 5.4800e-02, 5.4200e-02, 5.3600e-02, 5.3000e-02, 5.2500e-02, 5.1900e-02, 5.1400e-02, 5.0800e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5400e-02, 4.5000e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1600e-02, 4.1200e-02, 4.0800e-02, 4.0500e-02, 4.0100e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8600e-02, 3.8300e-02, 3.7900e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0800e-02, 3.0500e-02, 3.0300e-02, 3.0000e-02, 2.9800e-02, 2.9500e-02}); + } + break; + case 47: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.7000e+01, 4.6776e+01, 4.6139e+01, 4.5169e+01, 4.3963e+01, 4.2605e+01, 4.1157e+01, 3.9662e+01, 3.8154e+01, 3.6657e+01, 3.5192e+01, 3.3774e+01, 3.2415e+01, 3.1125e+01, 2.9909e+01, 2.8769e+01, 2.7706e+01, 2.6719e+01, 2.5805e+01, 2.4960e+01, 2.4180e+01, 2.3460e+01, 2.2794e+01, 2.2178e+01, 2.1607e+01, 2.1073e+01, 2.0575e+01, 2.0105e+01, 1.9661e+01, 1.9239e+01, 1.8834e+01, 1.8445e+01, 1.8069e+01, 1.7703e+01, 1.7346e+01, 1.6996e+01, 1.6651e+01, 1.6312e+01, 1.5976e+01, 1.5645e+01, 1.5316e+01, 1.4991e+01, 1.4669e+01, 1.4351e+01, 1.4035e+01, 1.3723e+01, 1.3416e+01, 1.3112e+01, 1.2813e+01, 1.2519e+01, 1.2230e+01, 1.1946e+01, 1.1668e+01, 1.1397e+01, 1.1132e+01, 1.0873e+01, 1.0622e+01, 1.0377e+01, 1.0139e+01, 9.9090e+00, 9.6860e+00, 9.4704e+00, 9.2621e+00, 9.0612e+00, 8.8675e+00, 8.6811e+00, 8.5018e+00, 8.3295e+00, 8.1641e+00, 8.0055e+00, 7.8534e+00, 7.7077e+00, 7.5683e+00, 7.4348e+00, 7.3071e+00, 7.1851e+00, 7.0684e+00, 6.9569e+00, 6.8503e+00, 6.7485e+00, 6.6512e+00, 6.5582e+00, 6.4692e+00, 6.3840e+00, 6.3027e+00, 6.2248e+00, 6.1500e+00, 6.0783e+00, 6.0096e+00, 5.9436e+00, 5.8802e+00, 5.8191e+00, 5.7601e+00, 5.7031e+00, 5.6483e+00, 5.5952e+00, 5.5438e+00, 5.4937e+00, 5.4450e+00, 5.3977e+00, 5.3517e+00, 5.3068e+00, 5.2628e+00, 5.2196e+00, 5.1772e+00, 5.1357e+00, 5.0950e+00, 5.0549e+00, 5.0152e+00, 4.9759e+00, 4.9370e+00, 4.8987e+00, 4.8610e+00, 4.8236e+00, 4.7863e+00, 4.7490e+00, 4.7119e+00, 4.6752e+00, 4.6389e+00, 4.6028e+00, 4.5669e+00, 4.5308e+00, 4.4946e+00, 4.4585e+00, 4.4227e+00, 4.3872e+00, 4.3520e+00, 4.3167e+00, 4.2813e+00, 4.2456e+00, 4.2100e+00, 4.1747e+00, 4.1396e+00, 4.1049e+00, 4.0703e+00, 4.0355e+00, 4.0005e+00, 3.9654e+00, 3.9305e+00, 3.8959e+00, 3.8617e+00, 3.8278e+00, 3.7940e+00, 3.7600e+00, 3.7259e+00, 3.6917e+00, 3.6577e+00, 3.6241e+00, 3.5910e+00, 3.5583e+00, 3.5257e+00, 3.4932e+00, 3.4606e+00, 3.4278e+00, 3.3951e+00, 3.3628e+00, 3.3311e+00, 3.2999e+00, 3.2690e+00, 3.2384e+00, 3.2078e+00, 3.1771e+00, 3.1463e+00, 3.1157e+00, 3.0855e+00, 3.0559e+00, 3.0270e+00, 2.9984e+00, 2.9702e+00, 2.9421e+00, 2.9140e+00, 2.8857e+00, 2.8575e+00, 2.8296e+00, 2.8023e+00, 2.7757e+00, 2.7497e+00, 2.7240e+00, 2.6987e+00, 2.6736e+00, 2.6484e+00, 2.6230e+00, 2.5977e+00, 2.5727e+00, 2.5483e+00, 2.5246e+00, 2.5016e+00, 2.4789e+00, 2.4567e+00, 2.4347e+00, 2.4127e+00, 2.3906e+00, 2.3683e+00, 2.3462e+00, 2.3245e+00, 2.3035e+00, 2.2832e+00, 2.2634e+00, 2.2440e+00, 2.2250e+00, 2.2063e+00, 2.1876e+00, 2.1687e+00, 2.1497e+00, 2.1305e+00, 2.1118e+00, 2.0937e+00, 2.0763e+00, 2.0595e+00, 2.0432e+00, 2.0271e+00, 2.0114e+00, 1.9959e+00, 1.9803e+00, 1.9646e+00, 1.9485e+00, 1.9324e+00, 1.9166e+00, 1.9014e+00, 1.8871e+00, 1.8732e+00, 1.8598e+00, 1.8467e+00, 1.8338e+00, 1.8212e+00, 1.8086e+00, 1.7959e+00, 1.7828e+00, 1.7694e+00, 1.7560e+00, 1.7431e+00, 1.7308e+00, 1.7193e+00, 1.7083e+00, 1.6976e+00, 1.6871e+00, 1.6769e+00, 1.6669e+00, 1.6570e+00, 1.6469e+00, 1.6364e+00}); + feg = Vctr_cpu({8.6712e+00, 8.5580e+00, 8.2436e+00, 7.7901e+00, 7.2676e+00, 6.7316e+00, 6.2154e+00, 5.7345e+00, 5.2930e+00, 4.8898e+00, 4.5219e+00, 4.1858e+00, 3.8785e+00, 3.5971e+00, 3.3392e+00, 3.1029e+00, 2.8861e+00, 2.6874e+00, 2.5051e+00, 2.3380e+00, 2.1847e+00, 2.0441e+00, 1.9151e+00, 1.7968e+00, 1.6882e+00, 1.5885e+00, 1.4969e+00, 1.4128e+00, 1.3353e+00, 1.2641e+00, 1.1984e+00, 1.1378e+00, 1.0819e+00, 1.0302e+00, 9.8230e-01, 9.3790e-01, 8.9670e-01, 8.5840e-01, 8.2270e-01, 7.8940e-01, 7.5830e-01, 7.2920e-01, 7.0190e-01, 6.7620e-01, 6.5200e-01, 6.2930e-01, 6.0780e-01, 5.8750e-01, 5.6820e-01, 5.4990e-01, 5.3260e-01, 5.1610e-01, 5.0040e-01, 4.8540e-01, 4.7100e-01, 4.5730e-01, 4.4420e-01, 4.3170e-01, 4.1960e-01, 4.0800e-01, 3.9690e-01, 3.8620e-01, 3.7590e-01, 3.6600e-01, 3.5650e-01, 3.4730e-01, 3.3840e-01, 3.2990e-01, 3.2160e-01, 3.1360e-01, 3.0590e-01, 2.9850e-01, 2.9130e-01, 2.8430e-01, 2.7760e-01, 2.7110e-01, 2.6470e-01, 2.5860e-01, 2.5270e-01, 2.4700e-01, 2.4140e-01, 2.3600e-01, 2.3080e-01, 2.2580e-01, 2.2090e-01, 2.1610e-01, 2.1150e-01, 2.0700e-01, 2.0270e-01, 1.9850e-01, 1.9440e-01, 1.9040e-01, 1.8660e-01, 1.8280e-01, 1.7920e-01, 1.7570e-01, 1.7230e-01, 1.6890e-01, 1.6570e-01, 1.6250e-01, 1.5950e-01, 1.5650e-01, 1.5360e-01, 1.5080e-01, 1.4810e-01, 1.4540e-01, 1.4280e-01, 1.4030e-01, 1.3780e-01, 1.3540e-01, 1.3310e-01, 1.3090e-01, 1.2860e-01, 1.2650e-01, 1.2440e-01, 1.2230e-01, 1.2030e-01, 1.1840e-01, 1.1650e-01, 1.1460e-01, 1.1280e-01, 1.1110e-01, 1.0940e-01, 1.0770e-01, 1.0600e-01, 1.0440e-01, 1.0290e-01, 1.0130e-01, 9.9800e-02, 9.8400e-02, 9.7000e-02, 9.5600e-02, 9.4200e-02, 9.2900e-02, 9.1600e-02, 9.0300e-02, 8.9000e-02, 8.7800e-02, 8.6600e-02, 8.5400e-02, 8.4300e-02, 8.3200e-02, 8.2100e-02, 8.1000e-02, 7.9900e-02, 7.8900e-02, 7.7900e-02, 7.6900e-02, 7.5900e-02, 7.4900e-02, 7.4000e-02, 7.3100e-02, 7.2200e-02, 7.1300e-02, 7.0400e-02, 6.9600e-02, 6.8700e-02, 6.7900e-02, 6.7100e-02, 6.6300e-02, 6.5500e-02, 6.4700e-02, 6.4000e-02, 6.3300e-02, 6.2500e-02, 6.1800e-02, 6.1100e-02, 6.0400e-02, 5.9700e-02, 5.9100e-02, 5.8400e-02, 5.7800e-02, 5.7100e-02, 5.6500e-02, 5.5900e-02, 5.5300e-02, 5.4700e-02, 5.4100e-02, 5.3500e-02, 5.3000e-02, 5.2400e-02, 5.1900e-02, 5.1300e-02, 5.0800e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6400e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.0900e-02, 4.0500e-02, 4.0100e-02, 3.9800e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8300e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5100e-02, 3.4800e-02, 3.4500e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1700e-02, 3.1400e-02, 3.1200e-02, 3.0900e-02, 3.0700e-02, 3.0400e-02, 3.0200e-02}); + } + break; + case 48: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.8000e+01, 4.7762e+01, 4.7084e+01, 4.6059e+01, 4.4797e+01, 4.3394e+01, 4.1922e+01, 4.0425e+01, 3.8929e+01, 3.7452e+01, 3.6007e+01, 3.4603e+01, 3.3250e+01, 3.1956e+01, 3.0724e+01, 2.9561e+01, 2.8467e+01, 2.7444e+01, 2.6491e+01, 2.5605e+01, 2.4783e+01, 2.4023e+01, 2.3319e+01, 2.2667e+01, 2.2063e+01, 2.1501e+01, 2.0978e+01, 2.0488e+01, 2.0027e+01, 1.9592e+01, 1.9179e+01, 1.8784e+01, 1.8405e+01, 1.8040e+01, 1.7685e+01, 1.7339e+01, 1.7000e+01, 1.6668e+01, 1.6340e+01, 1.6017e+01, 1.5698e+01, 1.5382e+01, 1.5069e+01, 1.4758e+01, 1.4451e+01, 1.4146e+01, 1.3845e+01, 1.3547e+01, 1.3252e+01, 1.2961e+01, 1.2675e+01, 1.2393e+01, 1.2115e+01, 1.1843e+01, 1.1576e+01, 1.1314e+01, 1.1059e+01, 1.0809e+01, 1.0566e+01, 1.0330e+01, 1.0100e+01, 9.8762e+00, 9.6597e+00, 9.4499e+00, 9.2471e+00, 9.0511e+00, 8.8619e+00, 8.6795e+00, 8.5038e+00, 8.3347e+00, 8.1721e+00, 8.0159e+00, 7.8660e+00, 7.7221e+00, 7.5841e+00, 7.4519e+00, 7.3253e+00, 7.2040e+00, 7.0879e+00, 6.9768e+00, 6.8706e+00, 6.7688e+00, 6.6715e+00, 6.5784e+00, 6.4893e+00, 6.4040e+00, 6.3223e+00, 6.2440e+00, 6.1690e+00, 6.0970e+00, 6.0279e+00, 5.9615e+00, 5.8976e+00, 5.8363e+00, 5.7772e+00, 5.7201e+00, 5.6648e+00, 5.6114e+00, 5.5599e+00, 5.5099e+00, 5.4614e+00, 5.4141e+00, 5.3679e+00, 5.3230e+00, 5.2793e+00, 5.2367e+00, 5.1947e+00, 5.1535e+00, 5.1129e+00, 5.0731e+00, 5.0341e+00, 4.9957e+00, 4.9577e+00, 4.9199e+00, 4.8825e+00, 4.8455e+00, 4.8091e+00, 4.7731e+00, 4.7373e+00, 4.7014e+00, 4.6656e+00, 4.6300e+00, 4.5947e+00, 4.5599e+00, 4.5252e+00, 4.4906e+00, 4.4558e+00, 4.4208e+00, 4.3859e+00, 4.3514e+00, 4.3173e+00, 4.2833e+00, 4.2494e+00, 4.2151e+00, 4.1807e+00, 4.1462e+00, 4.1120e+00, 4.0782e+00, 4.0448e+00, 4.0115e+00, 3.9780e+00, 3.9442e+00, 3.9102e+00, 3.8763e+00, 3.8428e+00, 3.8098e+00, 3.7772e+00, 3.7447e+00, 3.7121e+00, 3.6793e+00, 3.6462e+00, 3.6132e+00, 3.5805e+00, 3.5485e+00, 3.5170e+00, 3.4859e+00, 3.4547e+00, 3.4233e+00, 3.3918e+00, 3.3601e+00, 3.3287e+00, 3.2977e+00, 3.2675e+00, 3.2378e+00, 3.2086e+00, 3.1793e+00, 3.1499e+00, 3.1203e+00, 3.0906e+00, 3.0611e+00, 3.0321e+00, 3.0038e+00, 2.9763e+00, 2.9493e+00, 2.9224e+00, 2.8955e+00, 2.8684e+00, 2.8413e+00, 2.8141e+00, 2.7872e+00, 2.7609e+00, 2.7354e+00, 2.7107e+00, 2.6865e+00, 2.6624e+00, 2.6383e+00, 2.6141e+00, 2.5897e+00, 2.5654e+00, 2.5412e+00, 2.5175e+00, 2.4946e+00, 2.4726e+00, 2.4512e+00, 2.4302e+00, 2.4092e+00, 2.3880e+00, 2.3668e+00, 2.3455e+00, 2.3242e+00, 2.3031e+00, 2.2824e+00, 2.2625e+00, 2.2436e+00, 2.2253e+00, 2.2075e+00, 2.1896e+00, 2.1715e+00, 2.1533e+00, 2.1351e+00, 2.1169e+00, 2.0987e+00, 2.0808e+00, 2.0634e+00, 2.0468e+00, 2.0312e+00, 2.0162e+00, 2.0014e+00, 1.9865e+00, 1.9714e+00, 1.9561e+00, 1.9409e+00, 1.9256e+00, 1.9104e+00, 1.8952e+00, 1.8804e+00, 1.8665e+00, 1.8534e+00, 1.8411e+00, 1.8292e+00, 1.8172e+00, 1.8049e+00, 1.7924e+00, 1.7799e+00, 1.7673e+00, 1.7548e+00, 1.7421e+00, 1.7296e+00, 1.7174e+00, 1.7059e+00, 1.6954e+00}); + feg = Vctr_cpu({9.2326e+00, 9.1094e+00, 8.7641e+00, 8.2584e+00, 7.6670e+00, 7.0547e+00, 6.4648e+00, 5.9198e+00, 5.4274e+00, 4.9866e+00, 4.5927e+00, 4.2398e+00, 3.9224e+00, 3.6355e+00, 3.3752e+00, 3.1382e+00, 2.9218e+00, 2.7237e+00, 2.5422e+00, 2.3756e+00, 2.2227e+00, 2.0821e+00, 1.9528e+00, 1.8338e+00, 1.7244e+00, 1.6236e+00, 1.5308e+00, 1.4452e+00, 1.3663e+00, 1.2935e+00, 1.2263e+00, 1.1642e+00, 1.1067e+00, 1.0535e+00, 1.0042e+00, 9.5850e-01, 9.1600e-01, 8.7640e-01, 8.3960e-01, 8.0520e-01, 7.7310e-01, 7.4310e-01, 7.1490e-01, 6.8850e-01, 6.6360e-01, 6.4020e-01, 6.1810e-01, 5.9730e-01, 5.7750e-01, 5.5880e-01, 5.4110e-01, 5.2420e-01, 5.0820e-01, 4.9290e-01, 4.7830e-01, 4.6440e-01, 4.5110e-01, 4.3830e-01, 4.2610e-01, 4.1440e-01, 4.0320e-01, 3.9230e-01, 3.8190e-01, 3.7190e-01, 3.6230e-01, 3.5300e-01, 3.4410e-01, 3.3540e-01, 3.2710e-01, 3.1900e-01, 3.1130e-01, 3.0370e-01, 2.9650e-01, 2.8940e-01, 2.8260e-01, 2.7600e-01, 2.6970e-01, 2.6350e-01, 2.5750e-01, 2.5170e-01, 2.4610e-01, 2.4060e-01, 2.3540e-01, 2.3030e-01, 2.2530e-01, 2.2050e-01, 2.1580e-01, 2.1130e-01, 2.0690e-01, 2.0260e-01, 1.9840e-01, 1.9440e-01, 1.9050e-01, 1.8670e-01, 1.8300e-01, 1.7940e-01, 1.7590e-01, 1.7250e-01, 1.6920e-01, 1.6600e-01, 1.6290e-01, 1.5990e-01, 1.5690e-01, 1.5400e-01, 1.5130e-01, 1.4850e-01, 1.4590e-01, 1.4330e-01, 1.4080e-01, 1.3840e-01, 1.3600e-01, 1.3370e-01, 1.3140e-01, 1.2920e-01, 1.2700e-01, 1.2500e-01, 1.2290e-01, 1.2090e-01, 1.1900e-01, 1.1710e-01, 1.1520e-01, 1.1340e-01, 1.1170e-01, 1.1000e-01, 1.0830e-01, 1.0660e-01, 1.0500e-01, 1.0350e-01, 1.0190e-01, 1.0040e-01, 9.9000e-02, 9.7600e-02, 9.6200e-02, 9.4800e-02, 9.3500e-02, 9.2100e-02, 9.0900e-02, 8.9600e-02, 8.8400e-02, 8.7200e-02, 8.6000e-02, 8.4900e-02, 8.3700e-02, 8.2600e-02, 8.1500e-02, 8.0500e-02, 7.9400e-02, 7.8400e-02, 7.7400e-02, 7.6400e-02, 7.5500e-02, 7.4500e-02, 7.3600e-02, 7.2700e-02, 7.1800e-02, 7.1000e-02, 7.0100e-02, 6.9300e-02, 6.8400e-02, 6.7600e-02, 6.6800e-02, 6.6000e-02, 6.5300e-02, 6.4500e-02, 6.3800e-02, 6.3000e-02, 6.2300e-02, 6.1600e-02, 6.0900e-02, 6.0300e-02, 5.9600e-02, 5.8900e-02, 5.8300e-02, 5.7600e-02, 5.7000e-02, 5.6400e-02, 5.5800e-02, 5.5200e-02, 5.4600e-02, 5.4000e-02, 5.3500e-02, 5.2900e-02, 5.2400e-02, 5.1800e-02, 5.1300e-02, 5.0800e-02, 5.0200e-02, 4.9700e-02, 4.9200e-02, 4.8700e-02, 4.8200e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6400e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.1000e-02, 4.0600e-02, 4.0200e-02, 3.9800e-02, 3.9500e-02, 3.9100e-02, 3.8800e-02, 3.8400e-02, 3.8100e-02, 3.7700e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6400e-02, 3.6100e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4300e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1300e-02, 3.1000e-02, 3.0800e-02}); + } + break; + case 49: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.9000e+01, 4.8732e+01, 4.7980e+01, 4.6867e+01, 4.5533e+01, 4.4088e+01, 4.2602e+01, 4.1112e+01, 3.9638e+01, 3.8190e+01, 3.6774e+01, 3.5395e+01, 3.4059e+01, 3.2771e+01, 3.1537e+01, 3.0361e+01, 2.9246e+01, 2.8195e+01, 2.7207e+01, 2.6284e+01, 2.5424e+01, 2.4623e+01, 2.3880e+01, 2.3190e+01, 2.2551e+01, 2.1957e+01, 2.1404e+01, 2.0889e+01, 2.0407e+01, 1.9955e+01, 1.9528e+01, 1.9122e+01, 1.8736e+01, 1.8366e+01, 1.8010e+01, 1.7665e+01, 1.7330e+01, 1.7002e+01, 1.6681e+01, 1.6365e+01, 1.6053e+01, 1.5745e+01, 1.5441e+01, 1.5139e+01, 1.4840e+01, 1.4543e+01, 1.4250e+01, 1.3958e+01, 1.3670e+01, 1.3384e+01, 1.3102e+01, 1.2823e+01, 1.2548e+01, 1.2277e+01, 1.2010e+01, 1.1748e+01, 1.1491e+01, 1.1239e+01, 1.0992e+01, 1.0752e+01, 1.0516e+01, 1.0287e+01, 1.0064e+01, 9.8474e+00, 9.6368e+00, 9.4327e+00, 9.2350e+00, 9.0437e+00, 8.8587e+00, 8.6802e+00, 8.5079e+00, 8.3419e+00, 8.1820e+00, 8.0282e+00, 7.8803e+00, 7.7382e+00, 7.6017e+00, 7.4707e+00, 7.3450e+00, 7.2246e+00, 7.1091e+00, 6.9984e+00, 6.8924e+00, 6.7908e+00, 6.6936e+00, 6.6004e+00, 6.5111e+00, 6.4255e+00, 6.3436e+00, 6.2651e+00, 6.1897e+00, 6.1172e+00, 6.0477e+00, 5.9810e+00, 5.9170e+00, 5.8552e+00, 5.7955e+00, 5.7380e+00, 5.6826e+00, 5.6293e+00, 5.5776e+00, 5.5272e+00, 5.4783e+00, 5.4310e+00, 5.3852e+00, 5.3406e+00, 5.2970e+00, 5.2541e+00, 5.2121e+00, 5.1711e+00, 5.1312e+00, 5.0922e+00, 5.0536e+00, 5.0153e+00, 4.9773e+00, 4.9401e+00, 4.9036e+00, 4.8678e+00, 4.8322e+00, 4.7966e+00, 4.7610e+00, 4.7256e+00, 4.6908e+00, 4.6565e+00, 4.6227e+00, 4.5887e+00, 4.5545e+00, 4.5202e+00, 4.4859e+00, 4.4521e+00, 4.4189e+00, 4.3859e+00, 4.3529e+00, 4.3195e+00, 4.2857e+00, 4.2519e+00, 4.2184e+00, 4.1855e+00, 4.1531e+00, 4.1207e+00, 4.0881e+00, 4.0550e+00, 4.0216e+00, 3.9883e+00, 3.9554e+00, 3.9231e+00, 3.8913e+00, 3.8596e+00, 3.8277e+00, 3.7953e+00, 3.7626e+00, 3.7299e+00, 3.6976e+00, 3.6659e+00, 3.6350e+00, 3.6043e+00, 3.5736e+00, 3.5425e+00, 3.5111e+00, 3.4795e+00, 3.4480e+00, 3.4170e+00, 3.3868e+00, 3.3575e+00, 3.3284e+00, 3.2992e+00, 3.2697e+00, 3.2399e+00, 3.2100e+00, 3.1801e+00, 3.1507e+00, 3.1222e+00, 3.0946e+00, 3.0675e+00, 3.0405e+00, 3.0133e+00, 2.9858e+00, 2.9581e+00, 2.9304e+00, 2.9028e+00, 2.8758e+00, 2.8498e+00, 2.8247e+00, 2.8002e+00, 2.7758e+00, 2.7511e+00, 2.7262e+00, 2.7011e+00, 2.6760e+00, 2.6510e+00, 2.6264e+00, 2.6026e+00, 2.5800e+00, 2.5581e+00, 2.5366e+00, 2.5149e+00, 2.4929e+00, 2.4708e+00, 2.4487e+00, 2.4265e+00, 2.4044e+00, 2.3826e+00, 2.3618e+00, 2.3421e+00, 2.3232e+00, 2.3047e+00, 2.2861e+00, 2.2672e+00, 2.2481e+00, 2.2289e+00, 2.2098e+00, 2.1906e+00, 2.1715e+00, 2.1530e+00, 2.1356e+00, 2.1192e+00, 2.1036e+00, 2.0881e+00, 2.0724e+00, 2.0563e+00, 2.0401e+00, 2.0240e+00, 2.0078e+00, 1.9916e+00, 1.9753e+00, 1.9594e+00, 1.9445e+00, 1.9306e+00, 1.9177e+00, 1.9052e+00, 1.8925e+00, 1.8793e+00, 1.8659e+00, 1.8525e+00, 1.8391e+00, 1.8257e+00, 1.8122e+00, 1.7986e+00, 1.7854e+00, 1.7730e+00, 1.7617e+00}); + feg = Vctr_cpu({1.0424e+01, 1.0248e+01, 9.7632e+00, 9.0737e+00, 8.2971e+00, 7.5239e+00, 6.8061e+00, 6.1644e+00, 5.6014e+00, 5.1105e+00, 4.6819e+00, 4.3058e+00, 3.9733e+00, 3.6773e+00, 3.4119e+00, 3.1723e+00, 2.9549e+00, 2.7568e+00, 2.5757e+00, 2.4096e+00, 2.2571e+00, 2.1168e+00, 1.9875e+00, 1.8683e+00, 1.7584e+00, 1.6569e+00, 1.5632e+00, 1.4766e+00, 1.3966e+00, 1.3225e+00, 1.2540e+00, 1.1906e+00, 1.1317e+00, 1.0772e+00, 1.0266e+00, 9.7950e-01, 9.3580e-01, 8.9510e-01, 8.5710e-01, 8.2160e-01, 7.8850e-01, 7.5760e-01, 7.2850e-01, 7.0130e-01, 6.7570e-01, 6.5160e-01, 6.2890e-01, 6.0750e-01, 5.8720e-01, 5.6800e-01, 5.4990e-01, 5.3260e-01, 5.1620e-01, 5.0060e-01, 4.8580e-01, 4.7160e-01, 4.5800e-01, 4.4510e-01, 4.3270e-01, 4.2080e-01, 4.0940e-01, 3.9840e-01, 3.8790e-01, 3.7780e-01, 3.6800e-01, 3.5860e-01, 3.4960e-01, 3.4090e-01, 3.3240e-01, 3.2430e-01, 3.1640e-01, 3.0890e-01, 3.0150e-01, 2.9440e-01, 2.8760e-01, 2.8090e-01, 2.7450e-01, 2.6820e-01, 2.6220e-01, 2.5630e-01, 2.5070e-01, 2.4510e-01, 2.3980e-01, 2.3460e-01, 2.2960e-01, 2.2470e-01, 2.2000e-01, 2.1540e-01, 2.1090e-01, 2.0660e-01, 2.0240e-01, 1.9830e-01, 1.9430e-01, 1.9050e-01, 1.8670e-01, 1.8310e-01, 1.7950e-01, 1.7610e-01, 1.7270e-01, 1.6950e-01, 1.6630e-01, 1.6320e-01, 1.6020e-01, 1.5730e-01, 1.5440e-01, 1.5160e-01, 1.4890e-01, 1.4630e-01, 1.4380e-01, 1.4130e-01, 1.3880e-01, 1.3650e-01, 1.3420e-01, 1.3190e-01, 1.2970e-01, 1.2760e-01, 1.2550e-01, 1.2350e-01, 1.2150e-01, 1.1950e-01, 1.1760e-01, 1.1580e-01, 1.1400e-01, 1.1220e-01, 1.1050e-01, 1.0880e-01, 1.0720e-01, 1.0560e-01, 1.0400e-01, 1.0250e-01, 1.0100e-01, 9.9600e-02, 9.8100e-02, 9.6700e-02, 9.5400e-02, 9.4000e-02, 9.2700e-02, 9.1400e-02, 9.0200e-02, 8.8900e-02, 8.7700e-02, 8.6600e-02, 8.5400e-02, 8.4300e-02, 8.3200e-02, 8.2100e-02, 8.1000e-02, 8.0000e-02, 7.9000e-02, 7.8000e-02, 7.7000e-02, 7.6000e-02, 7.5100e-02, 7.4200e-02, 7.3300e-02, 7.2400e-02, 7.1500e-02, 7.0600e-02, 6.9800e-02, 6.9000e-02, 6.8100e-02, 6.7300e-02, 6.6600e-02, 6.5800e-02, 6.5000e-02, 6.4300e-02, 6.3600e-02, 6.2800e-02, 6.2100e-02, 6.1400e-02, 6.0800e-02, 6.0100e-02, 5.9400e-02, 5.8800e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6300e-02, 5.5700e-02, 5.5100e-02, 5.4500e-02, 5.3900e-02, 5.3400e-02, 5.2800e-02, 5.2300e-02, 5.1700e-02, 5.1200e-02, 5.0700e-02, 5.0200e-02, 4.9700e-02, 4.9200e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6800e-02, 4.6400e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2500e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0600e-02, 4.0300e-02, 3.9900e-02, 3.9500e-02, 3.9200e-02, 3.8800e-02, 3.8500e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3300e-02, 3.3000e-02, 3.2700e-02, 3.2400e-02, 3.2200e-02, 3.1900e-02, 3.1700e-02, 3.1400e-02}); + } + break; + case 50: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.0000e+01, 4.9721e+01, 4.8934e+01, 4.7765e+01, 4.6361e+01, 4.4848e+01, 4.3308e+01, 4.1786e+01, 4.0302e+01, 3.8860e+01, 3.7462e+01, 3.6106e+01, 3.4793e+01, 3.3525e+01, 3.2302e+01, 3.1130e+01, 3.0010e+01, 2.8945e+01, 2.7937e+01, 2.6987e+01, 2.6095e+01, 2.5260e+01, 2.4481e+01, 2.3755e+01, 2.3080e+01, 2.2452e+01, 2.1867e+01, 2.1323e+01, 2.0815e+01, 2.0339e+01, 1.9893e+01, 1.9472e+01, 1.9073e+01, 1.8694e+01, 1.8331e+01, 1.7983e+01, 1.7646e+01, 1.7320e+01, 1.7002e+01, 1.6690e+01, 1.6384e+01, 1.6083e+01, 1.5786e+01, 1.5492e+01, 1.5201e+01, 1.4913e+01, 1.4627e+01, 1.4343e+01, 1.4062e+01, 1.3783e+01, 1.3506e+01, 1.3232e+01, 1.2962e+01, 1.2694e+01, 1.2430e+01, 1.2169e+01, 1.1913e+01, 1.1660e+01, 1.1412e+01, 1.1169e+01, 1.0931e+01, 1.0698e+01, 1.0471e+01, 1.0249e+01, 1.0033e+01, 9.8219e+00, 9.6172e+00, 9.4184e+00, 9.2255e+00, 9.0387e+00, 8.8579e+00, 8.6830e+00, 8.5140e+00, 8.3510e+00, 8.1937e+00, 8.0422e+00, 7.8962e+00, 7.7559e+00, 7.6209e+00, 7.4911e+00, 7.3664e+00, 7.2467e+00, 7.1319e+00, 7.0216e+00, 6.9158e+00, 6.8144e+00, 6.7172e+00, 6.6240e+00, 6.5346e+00, 6.4487e+00, 6.3664e+00, 6.2876e+00, 6.2119e+00, 6.1392e+00, 6.0692e+00, 6.0019e+00, 5.9374e+00, 5.8754e+00, 5.8155e+00, 5.7577e+00, 5.7018e+00, 5.6479e+00, 5.5960e+00, 5.5458e+00, 5.4969e+00, 5.4493e+00, 5.4030e+00, 5.3582e+00, 5.3147e+00, 5.2724e+00, 5.2308e+00, 5.1899e+00, 5.1497e+00, 5.1105e+00, 5.0724e+00, 5.0350e+00, 4.9980e+00, 4.9612e+00, 4.9247e+00, 4.8887e+00, 4.8535e+00, 4.8190e+00, 4.7849e+00, 4.7507e+00, 4.7164e+00, 4.6821e+00, 4.6481e+00, 4.6149e+00, 4.5821e+00, 4.5496e+00, 4.5169e+00, 4.4838e+00, 4.4505e+00, 4.4174e+00, 4.3848e+00, 4.3528e+00, 4.3211e+00, 4.2893e+00, 4.2571e+00, 4.2244e+00, 4.1915e+00, 4.1590e+00, 4.1271e+00, 4.0957e+00, 4.0646e+00, 4.0333e+00, 4.0016e+00, 3.9693e+00, 3.9369e+00, 3.9047e+00, 3.8732e+00, 3.8423e+00, 3.8119e+00, 3.7815e+00, 3.7506e+00, 3.7193e+00, 3.6876e+00, 3.6559e+00, 3.6246e+00, 3.5943e+00, 3.5646e+00, 3.5353e+00, 3.5060e+00, 3.4763e+00, 3.4461e+00, 3.4155e+00, 3.3849e+00, 3.3548e+00, 3.3257e+00, 3.2974e+00, 3.2697e+00, 3.2420e+00, 3.2142e+00, 3.1859e+00, 3.1572e+00, 3.1282e+00, 3.0995e+00, 3.0715e+00, 3.0446e+00, 3.0186e+00, 2.9930e+00, 2.9675e+00, 2.9418e+00, 2.9157e+00, 2.8892e+00, 2.8625e+00, 2.8359e+00, 2.8100e+00, 2.7851e+00, 2.7614e+00, 2.7383e+00, 2.7153e+00, 2.6923e+00, 2.6690e+00, 2.6455e+00, 2.6215e+00, 2.5974e+00, 2.5734e+00, 2.5503e+00, 2.5284e+00, 2.5075e+00, 2.4872e+00, 2.4672e+00, 2.4470e+00, 2.4266e+00, 2.4060e+00, 2.3850e+00, 2.3637e+00, 2.3424e+00, 2.3217e+00, 2.3020e+00, 2.2836e+00, 2.2660e+00, 2.2489e+00, 2.2317e+00, 2.2143e+00, 2.1969e+00, 2.1792e+00, 2.1612e+00, 2.1428e+00, 2.1243e+00, 2.1063e+00, 2.0894e+00, 2.0736e+00, 2.0589e+00, 2.0447e+00, 2.0304e+00, 2.0159e+00, 2.0014e+00, 1.9867e+00, 1.9718e+00, 1.9566e+00, 1.9409e+00, 1.9252e+00, 1.9101e+00, 1.8960e+00, 1.8832e+00, 1.8714e+00, 1.8599e+00, 1.8483e+00, 1.8365e+00}); + feg = Vctr_cpu({1.0858e+01, 1.0686e+01, 1.0206e+01, 9.5111e+00, 8.7089e+00, 7.8914e+00, 7.1182e+00, 6.4191e+00, 5.8029e+00, 5.2666e+00, 4.8014e+00, 4.3971e+00, 4.0439e+00, 3.7332e+00, 3.4577e+00, 3.2116e+00, 2.9902e+00, 2.7899e+00, 2.6076e+00, 2.4411e+00, 2.2885e+00, 2.1482e+00, 2.0190e+00, 1.8998e+00, 1.7897e+00, 1.6879e+00, 1.5937e+00, 1.5064e+00, 1.4255e+00, 1.3506e+00, 1.2810e+00, 1.2165e+00, 1.1565e+00, 1.1008e+00, 1.0491e+00, 1.0009e+00, 9.5600e-01, 9.1410e-01, 8.7510e-01, 8.3860e-01, 8.0450e-01, 7.7260e-01, 7.4270e-01, 7.1470e-01, 6.8830e-01, 6.6350e-01, 6.4020e-01, 6.1810e-01, 5.9730e-01, 5.7760e-01, 5.5900e-01, 5.4130e-01, 5.2450e-01, 5.0860e-01, 4.9340e-01, 4.7890e-01, 4.6510e-01, 4.5190e-01, 4.3930e-01, 4.2720e-01, 4.1560e-01, 4.0450e-01, 3.9380e-01, 3.8350e-01, 3.7370e-01, 3.6420e-01, 3.5500e-01, 3.4620e-01, 3.3770e-01, 3.2950e-01, 3.2150e-01, 3.1390e-01, 3.0650e-01, 2.9930e-01, 2.9240e-01, 2.8560e-01, 2.7910e-01, 2.7280e-01, 2.6670e-01, 2.6080e-01, 2.5510e-01, 2.4950e-01, 2.4410e-01, 2.3890e-01, 2.3380e-01, 2.2890e-01, 2.2410e-01, 2.1950e-01, 2.1490e-01, 2.1050e-01, 2.0630e-01, 2.0210e-01, 1.9810e-01, 1.9420e-01, 1.9040e-01, 1.8670e-01, 1.8310e-01, 1.7960e-01, 1.7620e-01, 1.7290e-01, 1.6960e-01, 1.6650e-01, 1.6340e-01, 1.6050e-01, 1.5760e-01, 1.5470e-01, 1.5200e-01, 1.4930e-01, 1.4670e-01, 1.4420e-01, 1.4170e-01, 1.3930e-01, 1.3690e-01, 1.3460e-01, 1.3240e-01, 1.3020e-01, 1.2810e-01, 1.2600e-01, 1.2400e-01, 1.2200e-01, 1.2010e-01, 1.1820e-01, 1.1630e-01, 1.1450e-01, 1.1280e-01, 1.1110e-01, 1.0940e-01, 1.0780e-01, 1.0620e-01, 1.0460e-01, 1.0310e-01, 1.0160e-01, 1.0010e-01, 9.8700e-02, 9.7300e-02, 9.5900e-02, 9.4600e-02, 9.3300e-02, 9.2000e-02, 9.0700e-02, 8.9500e-02, 8.8300e-02, 8.7100e-02, 8.6000e-02, 8.4800e-02, 8.3700e-02, 8.2600e-02, 8.1600e-02, 8.0500e-02, 7.9500e-02, 7.8500e-02, 7.7500e-02, 7.6600e-02, 7.5600e-02, 7.4700e-02, 7.3800e-02, 7.2900e-02, 7.2000e-02, 7.1100e-02, 7.0300e-02, 6.9500e-02, 6.8600e-02, 6.7800e-02, 6.7100e-02, 6.6300e-02, 6.5500e-02, 6.4800e-02, 6.4000e-02, 6.3300e-02, 6.2600e-02, 6.1900e-02, 6.1200e-02, 6.0600e-02, 5.9900e-02, 5.9200e-02, 5.8600e-02, 5.8000e-02, 5.7400e-02, 5.6800e-02, 5.6100e-02, 5.5600e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3300e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0600e-02, 5.0100e-02, 4.9600e-02, 4.9100e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0700e-02, 4.0300e-02, 3.9900e-02, 3.9600e-02, 3.9200e-02, 3.8900e-02, 3.8500e-02, 3.8200e-02, 3.7900e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5100e-02, 3.4800e-02, 3.4500e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2300e-02, 3.2000e-02}); + } + break; + case 51: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.1000e+01, 5.0717e+01, 4.9914e+01, 4.8708e+01, 4.7247e+01, 4.5664e+01, 4.4055e+01, 4.2476e+01, 4.0955e+01, 3.9497e+01, 3.8100e+01, 3.6758e+01, 3.5465e+01, 3.4218e+01, 3.3015e+01, 3.1857e+01, 3.0744e+01, 2.9678e+01, 2.8662e+01, 2.7696e+01, 2.6783e+01, 2.5921e+01, 2.5112e+01, 2.4354e+01, 2.3645e+01, 2.2983e+01, 2.2365e+01, 2.1790e+01, 2.1253e+01, 2.0750e+01, 2.0280e+01, 1.9839e+01, 1.9423e+01, 1.9030e+01, 1.8657e+01, 1.8300e+01, 1.7958e+01, 1.7629e+01, 1.7310e+01, 1.7000e+01, 1.6697e+01, 1.6401e+01, 1.6109e+01, 1.5822e+01, 1.5538e+01, 1.5257e+01, 1.4979e+01, 1.4703e+01, 1.4429e+01, 1.4157e+01, 1.3887e+01, 1.3620e+01, 1.3355e+01, 1.3092e+01, 1.2832e+01, 1.2575e+01, 1.2320e+01, 1.2070e+01, 1.1823e+01, 1.1579e+01, 1.1340e+01, 1.1106e+01, 1.0876e+01, 1.0650e+01, 1.0430e+01, 1.0214e+01, 1.0004e+01, 9.7997e+00, 9.6004e+00, 9.4067e+00, 9.2185e+00, 9.0359e+00, 8.8590e+00, 8.6876e+00, 8.5219e+00, 8.3617e+00, 8.2069e+00, 8.0576e+00, 7.9136e+00, 7.7749e+00, 7.6413e+00, 7.5127e+00, 7.3890e+00, 7.2701e+00, 7.1559e+00, 7.0461e+00, 6.9406e+00, 6.8393e+00, 6.7422e+00, 6.6489e+00, 6.5593e+00, 6.4733e+00, 6.3907e+00, 6.3115e+00, 6.2355e+00, 6.1623e+00, 6.0920e+00, 6.0243e+00, 5.9594e+00, 5.8969e+00, 5.8366e+00, 5.7784e+00, 5.7222e+00, 5.6680e+00, 5.6157e+00, 5.5652e+00, 5.5162e+00, 5.4684e+00, 5.4220e+00, 5.3771e+00, 5.3335e+00, 5.2911e+00, 5.2496e+00, 5.2089e+00, 5.1689e+00, 5.1299e+00, 5.0919e+00, 5.0547e+00, 5.0181e+00, 4.9818e+00, 4.9458e+00, 4.9103e+00, 4.8755e+00, 4.8414e+00, 4.8078e+00, 4.7743e+00, 4.7408e+00, 4.7072e+00, 4.6740e+00, 4.6412e+00, 4.6091e+00, 4.5773e+00, 4.5455e+00, 4.5135e+00, 4.4811e+00, 4.4488e+00, 4.4169e+00, 4.3855e+00, 4.3546e+00, 4.3238e+00, 4.2927e+00, 4.2611e+00, 4.2293e+00, 4.1975e+00, 4.1661e+00, 4.1353e+00, 4.1050e+00, 4.0748e+00, 4.0442e+00, 4.0131e+00, 3.9817e+00, 3.9501e+00, 3.9190e+00, 3.8885e+00, 3.8587e+00, 3.8292e+00, 3.7995e+00, 3.7693e+00, 3.7386e+00, 3.7076e+00, 3.6768e+00, 3.6464e+00, 3.6169e+00, 3.5882e+00, 3.5597e+00, 3.5310e+00, 3.5019e+00, 3.4722e+00, 3.4422e+00, 3.4123e+00, 3.3829e+00, 3.3544e+00, 3.3268e+00, 3.2998e+00, 3.2728e+00, 3.2454e+00, 3.2176e+00, 3.1893e+00, 3.1608e+00, 3.1325e+00, 3.1049e+00, 3.0784e+00, 3.0528e+00, 3.0278e+00, 3.0029e+00, 2.9776e+00, 2.9518e+00, 2.9256e+00, 2.8992e+00, 2.8728e+00, 2.8471e+00, 2.8223e+00, 2.7986e+00, 2.7758e+00, 2.7534e+00, 2.7309e+00, 2.7079e+00, 2.6844e+00, 2.6606e+00, 2.6366e+00, 2.6127e+00, 2.5894e+00, 2.5672e+00, 2.5462e+00, 2.5261e+00, 2.5065e+00, 2.4867e+00, 2.4666e+00, 2.4459e+00, 2.4250e+00, 2.4038e+00, 2.3825e+00, 2.3615e+00, 2.3413e+00, 2.3223e+00, 2.3044e+00, 2.2875e+00, 2.2708e+00, 2.2538e+00, 2.2364e+00, 2.2186e+00, 2.2005e+00, 2.1822e+00, 2.1637e+00, 2.1454e+00, 2.1277e+00, 2.1110e+00, 2.0957e+00, 2.0814e+00, 2.0675e+00, 2.0536e+00, 2.0393e+00, 2.0245e+00, 2.0093e+00, 1.9940e+00, 1.9784e+00, 1.9627e+00, 1.9471e+00, 1.9320e+00, 1.9180e+00, 1.9053e+00}); + feg = Vctr_cpu({1.0990e+01, 1.0835e+01, 1.0398e+01, 9.7507e+00, 8.9816e+00, 8.1736e+00, 7.3879e+00, 6.6614e+00, 6.0105e+00, 5.4382e+00, 4.9400e+00, 4.5074e+00, 4.1312e+00, 3.8026e+00, 3.5138e+00, 3.2581e+00, 3.0300e+00, 2.8252e+00, 2.6402e+00, 2.4720e+00, 2.3184e+00, 2.1777e+00, 2.0482e+00, 1.9289e+00, 1.8187e+00, 1.7166e+00, 1.6221e+00, 1.5344e+00, 1.4530e+00, 1.3774e+00, 1.3071e+00, 1.2417e+00, 1.1808e+00, 1.1242e+00, 1.0714e+00, 1.0222e+00, 9.7630e-01, 9.3350e-01, 8.9340e-01, 8.5600e-01, 8.2100e-01, 7.8820e-01, 7.5740e-01, 7.2860e-01, 7.0140e-01, 6.7590e-01, 6.5190e-01, 6.2920e-01, 6.0780e-01, 5.8760e-01, 5.6850e-01, 5.5030e-01, 5.3310e-01, 5.1680e-01, 5.0120e-01, 4.8640e-01, 4.7230e-01, 4.5880e-01, 4.4600e-01, 4.3370e-01, 4.2190e-01, 4.1060e-01, 3.9970e-01, 3.8930e-01, 3.7930e-01, 3.6970e-01, 3.6040e-01, 3.5150e-01, 3.4290e-01, 3.3450e-01, 3.2650e-01, 3.1880e-01, 3.1130e-01, 3.0410e-01, 2.9710e-01, 2.9030e-01, 2.8370e-01, 2.7740e-01, 2.7120e-01, 2.6520e-01, 2.5940e-01, 2.5380e-01, 2.4840e-01, 2.4310e-01, 2.3790e-01, 2.3300e-01, 2.2810e-01, 2.2340e-01, 2.1890e-01, 2.1440e-01, 2.1010e-01, 2.0590e-01, 2.0180e-01, 1.9790e-01, 1.9400e-01, 1.9030e-01, 1.8660e-01, 1.8300e-01, 1.7960e-01, 1.7620e-01, 1.7290e-01, 1.6980e-01, 1.6670e-01, 1.6360e-01, 1.6070e-01, 1.5780e-01, 1.5500e-01, 1.5230e-01, 1.4960e-01, 1.4700e-01, 1.4450e-01, 1.4210e-01, 1.3970e-01, 1.3730e-01, 1.3500e-01, 1.3280e-01, 1.3060e-01, 1.2850e-01, 1.2650e-01, 1.2440e-01, 1.2250e-01, 1.2050e-01, 1.1870e-01, 1.1680e-01, 1.1500e-01, 1.1330e-01, 1.1160e-01, 1.0990e-01, 1.0830e-01, 1.0670e-01, 1.0510e-01, 1.0360e-01, 1.0210e-01, 1.0060e-01, 9.9200e-02, 9.7800e-02, 9.6400e-02, 9.5100e-02, 9.3800e-02, 9.2500e-02, 9.1300e-02, 9.0000e-02, 8.8800e-02, 8.7600e-02, 8.6500e-02, 8.5400e-02, 8.4200e-02, 8.3200e-02, 8.2100e-02, 8.1000e-02, 8.0000e-02, 7.9000e-02, 7.8000e-02, 7.7100e-02, 7.6100e-02, 7.5200e-02, 7.4300e-02, 7.3400e-02, 7.2500e-02, 7.1600e-02, 7.0800e-02, 7.0000e-02, 6.9100e-02, 6.8300e-02, 6.7500e-02, 6.6800e-02, 6.6000e-02, 6.5300e-02, 6.4500e-02, 6.3800e-02, 6.3100e-02, 6.2400e-02, 6.1700e-02, 6.1000e-02, 6.0400e-02, 5.9700e-02, 5.9100e-02, 5.8400e-02, 5.7800e-02, 5.7200e-02, 5.6600e-02, 5.6000e-02, 5.5400e-02, 5.4900e-02, 5.4300e-02, 5.3700e-02, 5.3200e-02, 5.2600e-02, 5.2100e-02, 5.1600e-02, 5.1100e-02, 5.0600e-02, 5.0100e-02, 4.9600e-02, 4.9100e-02, 4.8600e-02, 4.8100e-02, 4.7700e-02, 4.7200e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0300e-02, 4.0000e-02, 3.9600e-02, 3.9300e-02, 3.8900e-02, 3.8600e-02, 3.8300e-02, 3.7900e-02, 3.7600e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5100e-02, 3.4800e-02, 3.4600e-02, 3.4300e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02}); + } + break; + case 52: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.2000e+01, 5.1717e+01, 5.0907e+01, 4.9681e+01, 4.8178e+01, 4.6533e+01, 4.4853e+01, 4.3207e+01, 4.1630e+01, 4.0133e+01, 3.8716e+01, 3.7370e+01, 3.6086e+01, 3.4855e+01, 3.3672e+01, 3.2532e+01, 3.1433e+01, 3.0377e+01, 2.9363e+01, 2.8393e+01, 2.7469e+01, 2.6591e+01, 2.5760e+01, 2.4976e+01, 2.4238e+01, 2.3546e+01, 2.2898e+01, 2.2291e+01, 2.1724e+01, 2.1193e+01, 2.0697e+01, 2.0232e+01, 1.9795e+01, 1.9383e+01, 1.8994e+01, 1.8625e+01, 1.8273e+01, 1.7937e+01, 1.7613e+01, 1.7301e+01, 1.6998e+01, 1.6703e+01, 1.6414e+01, 1.6131e+01, 1.5853e+01, 1.5578e+01, 1.5307e+01, 1.5038e+01, 1.4771e+01, 1.4507e+01, 1.4244e+01, 1.3984e+01, 1.3725e+01, 1.3468e+01, 1.3213e+01, 1.2961e+01, 1.2711e+01, 1.2463e+01, 1.2219e+01, 1.1977e+01, 1.1739e+01, 1.1505e+01, 1.1274e+01, 1.1047e+01, 1.0825e+01, 1.0606e+01, 1.0393e+01, 1.0184e+01, 9.9796e+00, 9.7804e+00, 9.5863e+00, 9.3974e+00, 9.2137e+00, 9.0352e+00, 8.8620e+00, 8.6940e+00, 8.5313e+00, 8.3739e+00, 8.2216e+00, 8.0744e+00, 7.9324e+00, 7.7953e+00, 7.6631e+00, 7.5357e+00, 7.4129e+00, 7.2948e+00, 7.1812e+00, 7.0718e+00, 6.9667e+00, 6.8656e+00, 6.7685e+00, 6.6752e+00, 6.5855e+00, 6.4992e+00, 6.4164e+00, 6.3369e+00, 6.2605e+00, 6.1869e+00, 6.1162e+00, 6.0481e+00, 5.9827e+00, 5.9197e+00, 5.8591e+00, 5.8005e+00, 5.7439e+00, 5.6892e+00, 5.6366e+00, 5.5858e+00, 5.5365e+00, 5.4886e+00, 5.4420e+00, 5.3968e+00, 5.3530e+00, 5.3105e+00, 5.2691e+00, 5.2285e+00, 5.1887e+00, 5.1497e+00, 5.1116e+00, 5.0746e+00, 5.0383e+00, 5.0025e+00, 4.9671e+00, 4.9319e+00, 4.8973e+00, 4.8633e+00, 4.8301e+00, 4.7973e+00, 4.7647e+00, 4.7321e+00, 4.6995e+00, 4.6671e+00, 4.6351e+00, 4.6038e+00, 4.5728e+00, 4.5420e+00, 4.5110e+00, 4.4797e+00, 4.4483e+00, 4.4171e+00, 4.3863e+00, 4.3561e+00, 4.3263e+00, 4.2963e+00, 4.2660e+00, 4.2353e+00, 4.2044e+00, 4.1735e+00, 4.1432e+00, 4.1135e+00, 4.0841e+00, 4.0548e+00, 4.0252e+00, 3.9951e+00, 3.9645e+00, 3.9339e+00, 3.9036e+00, 3.8739e+00, 3.8449e+00, 3.8163e+00, 3.7876e+00, 3.7586e+00, 3.7290e+00, 3.6989e+00, 3.6687e+00, 3.6390e+00, 3.6100e+00, 3.5818e+00, 3.5541e+00, 3.5265e+00, 3.4987e+00, 3.4703e+00, 3.4414e+00, 3.4121e+00, 3.3831e+00, 3.3547e+00, 3.3272e+00, 3.3006e+00, 3.2745e+00, 3.2485e+00, 3.2221e+00, 3.1953e+00, 3.1678e+00, 3.1400e+00, 3.1124e+00, 3.0854e+00, 3.0595e+00, 3.0346e+00, 3.0103e+00, 2.9864e+00, 2.9623e+00, 2.9378e+00, 2.9127e+00, 2.8870e+00, 2.8611e+00, 2.8356e+00, 2.8110e+00, 2.7876e+00, 2.7651e+00, 2.7433e+00, 2.7218e+00, 2.7002e+00, 2.6783e+00, 2.6557e+00, 2.6325e+00, 2.6090e+00, 2.5857e+00, 2.5631e+00, 2.5417e+00, 2.5214e+00, 2.5020e+00, 2.4831e+00, 2.4644e+00, 2.4455e+00, 2.4262e+00, 2.4062e+00, 2.3856e+00, 2.3647e+00, 2.3439e+00, 2.3240e+00, 2.3052e+00, 2.2876e+00, 2.2709e+00, 2.2547e+00, 2.2388e+00, 2.2228e+00, 2.2066e+00, 2.1898e+00, 2.1724e+00, 2.1543e+00, 2.1360e+00, 2.1181e+00, 2.1011e+00, 2.0853e+00, 2.0707e+00, 2.0570e+00, 2.0436e+00, 2.0304e+00, 2.0172e+00, 2.0038e+00, 1.9900e+00}); + feg = Vctr_cpu({1.0990e+01, 1.0853e+01, 1.0460e+01, 9.8675e+00, 9.1484e+00, 8.3740e+00, 7.6021e+00, 6.8719e+00, 6.2051e+00, 5.6102e+00, 5.0869e+00, 4.6299e+00, 4.2319e+00, 3.8848e+00, 3.5809e+00, 3.3134e+00, 3.0765e+00, 2.8652e+00, 2.6755e+00, 2.5041e+00, 2.3485e+00, 2.2064e+00, 2.0761e+00, 1.9563e+00, 1.8457e+00, 1.7434e+00, 1.6486e+00, 1.5606e+00, 1.4788e+00, 1.4027e+00, 1.3319e+00, 1.2659e+00, 1.2044e+00, 1.1469e+00, 1.0934e+00, 1.0433e+00, 9.9650e-01, 9.5280e-01, 9.1190e-01, 8.7360e-01, 8.3770e-01, 8.0410e-01, 7.7250e-01, 7.4290e-01, 7.1500e-01, 6.8880e-01, 6.6410e-01, 6.4080e-01, 6.1880e-01, 5.9800e-01, 5.7830e-01, 5.5970e-01, 5.4200e-01, 5.2530e-01, 5.0940e-01, 4.9420e-01, 4.7980e-01, 4.6600e-01, 4.5280e-01, 4.4030e-01, 4.2830e-01, 4.1670e-01, 4.0570e-01, 3.9510e-01, 3.8500e-01, 3.7520e-01, 3.6580e-01, 3.5670e-01, 3.4800e-01, 3.3960e-01, 3.3150e-01, 3.2360e-01, 3.1610e-01, 3.0870e-01, 3.0170e-01, 2.9480e-01, 2.8820e-01, 2.8180e-01, 2.7550e-01, 2.6950e-01, 2.6370e-01, 2.5800e-01, 2.5250e-01, 2.4720e-01, 2.4200e-01, 2.3690e-01, 2.3210e-01, 2.2730e-01, 2.2270e-01, 2.1820e-01, 2.1380e-01, 2.0960e-01, 2.0550e-01, 2.0150e-01, 1.9760e-01, 1.9380e-01, 1.9010e-01, 1.8650e-01, 1.8300e-01, 1.7950e-01, 1.7620e-01, 1.7300e-01, 1.6980e-01, 1.6680e-01, 1.6380e-01, 1.6090e-01, 1.5800e-01, 1.5520e-01, 1.5250e-01, 1.4990e-01, 1.4730e-01, 1.4480e-01, 1.4240e-01, 1.4000e-01, 1.3770e-01, 1.3540e-01, 1.3320e-01, 1.3110e-01, 1.2900e-01, 1.2690e-01, 1.2490e-01, 1.2290e-01, 1.2100e-01, 1.1910e-01, 1.1730e-01, 1.1550e-01, 1.1380e-01, 1.1210e-01, 1.1040e-01, 1.0880e-01, 1.0720e-01, 1.0560e-01, 1.0410e-01, 1.0260e-01, 1.0110e-01, 9.9700e-02, 9.8300e-02, 9.7000e-02, 9.5600e-02, 9.4300e-02, 9.3000e-02, 9.1800e-02, 9.0500e-02, 8.9300e-02, 8.8200e-02, 8.7000e-02, 8.5900e-02, 8.4800e-02, 8.3700e-02, 8.2600e-02, 8.1600e-02, 8.0500e-02, 7.9500e-02, 7.8500e-02, 7.7600e-02, 7.6600e-02, 7.5700e-02, 7.4800e-02, 7.3900e-02, 7.3000e-02, 7.2100e-02, 7.1300e-02, 7.0400e-02, 6.9600e-02, 6.8800e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5700e-02, 6.5000e-02, 6.4300e-02, 6.3600e-02, 6.2900e-02, 6.2200e-02, 6.1500e-02, 6.0800e-02, 6.0200e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7700e-02, 5.7000e-02, 5.6500e-02, 5.5900e-02, 5.5300e-02, 5.4700e-02, 5.4200e-02, 5.3600e-02, 5.3100e-02, 5.2500e-02, 5.2000e-02, 5.1500e-02, 5.1000e-02, 5.0500e-02, 5.0000e-02, 4.9500e-02, 4.9000e-02, 4.8600e-02, 4.8100e-02, 4.7600e-02, 4.7200e-02, 4.6700e-02, 4.6300e-02, 4.5900e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8600e-02, 3.8300e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6400e-02, 3.6100e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4300e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02}); + } + break; + case 53: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.3000e+01, 5.2718e+01, 5.1909e+01, 5.0672e+01, 4.9140e+01, 4.7445e+01, 4.5700e+01, 4.3982e+01, 4.2339e+01, 4.0788e+01, 3.9333e+01, 3.7966e+01, 3.6676e+01, 3.5450e+01, 3.4279e+01, 3.3156e+01, 3.2075e+01, 3.1033e+01, 3.0030e+01, 2.9065e+01, 2.8140e+01, 2.7255e+01, 2.6411e+01, 2.5610e+01, 2.4850e+01, 2.4133e+01, 2.3458e+01, 2.2823e+01, 2.2227e+01, 2.1668e+01, 2.1144e+01, 2.0653e+01, 2.0192e+01, 1.9759e+01, 1.9351e+01, 1.8965e+01, 1.8599e+01, 1.8252e+01, 1.7919e+01, 1.7601e+01, 1.7294e+01, 1.6997e+01, 1.6708e+01, 1.6427e+01, 1.6151e+01, 1.5880e+01, 1.5614e+01, 1.5351e+01, 1.5091e+01, 1.4833e+01, 1.4578e+01, 1.4324e+01, 1.4072e+01, 1.3822e+01, 1.3573e+01, 1.3327e+01, 1.3082e+01, 1.2839e+01, 1.2598e+01, 1.2360e+01, 1.2125e+01, 1.1892e+01, 1.1662e+01, 1.1436e+01, 1.1213e+01, 1.0993e+01, 1.0778e+01, 1.0566e+01, 1.0359e+01, 1.0156e+01, 9.9576e+00, 9.7638e+00, 9.5747e+00, 9.3904e+00, 9.2109e+00, 9.0363e+00, 8.8667e+00, 8.7020e+00, 8.5423e+00, 8.3875e+00, 8.2376e+00, 8.0926e+00, 7.9523e+00, 7.8169e+00, 7.6861e+00, 7.5598e+00, 7.4381e+00, 7.3207e+00, 7.2077e+00, 7.0988e+00, 6.9940e+00, 6.8931e+00, 6.7960e+00, 6.7027e+00, 6.6129e+00, 6.5266e+00, 6.4435e+00, 6.3636e+00, 6.2867e+00, 6.2128e+00, 6.1417e+00, 6.0733e+00, 6.0074e+00, 5.9438e+00, 5.8826e+00, 5.8237e+00, 5.7668e+00, 5.7119e+00, 5.6588e+00, 5.6074e+00, 5.5576e+00, 5.5095e+00, 5.4629e+00, 5.4178e+00, 5.3738e+00, 5.3308e+00, 5.2890e+00, 5.2483e+00, 5.2088e+00, 5.1702e+00, 5.1325e+00, 5.0953e+00, 5.0587e+00, 5.0227e+00, 4.9876e+00, 4.9533e+00, 4.9195e+00, 4.8862e+00, 4.8530e+00, 4.8201e+00, 4.7874e+00, 4.7553e+00, 4.7237e+00, 4.6927e+00, 4.6619e+00, 4.6310e+00, 4.6000e+00, 4.5690e+00, 4.5382e+00, 4.5079e+00, 4.4781e+00, 4.4486e+00, 4.4191e+00, 4.3893e+00, 4.3593e+00, 4.3291e+00, 4.2990e+00, 4.2693e+00, 4.2401e+00, 4.2113e+00, 4.1826e+00, 4.1536e+00, 4.1241e+00, 4.0943e+00, 4.0644e+00, 4.0348e+00, 4.0057e+00, 3.9772e+00, 3.9491e+00, 3.9209e+00, 3.8923e+00, 3.8632e+00, 3.8337e+00, 3.8041e+00, 3.7748e+00, 3.7462e+00, 3.7183e+00, 3.6908e+00, 3.6635e+00, 3.6359e+00, 3.6077e+00, 3.5790e+00, 3.5500e+00, 3.5211e+00, 3.4929e+00, 3.4655e+00, 3.4388e+00, 3.4126e+00, 3.3865e+00, 3.3601e+00, 3.3331e+00, 3.3054e+00, 3.2775e+00, 3.2498e+00, 3.2227e+00, 3.1965e+00, 3.1713e+00, 3.1466e+00, 3.1223e+00, 3.0979e+00, 3.0729e+00, 3.0473e+00, 3.0211e+00, 2.9948e+00, 2.9689e+00, 2.9438e+00, 2.9198e+00, 2.8967e+00, 2.8743e+00, 2.8522e+00, 2.8300e+00, 2.8074e+00, 2.7841e+00, 2.7601e+00, 2.7358e+00, 2.7118e+00, 2.6886e+00, 2.6664e+00, 2.6453e+00, 2.6250e+00, 2.6054e+00, 2.5859e+00, 2.5663e+00, 2.5461e+00, 2.5252e+00, 2.5036e+00, 2.4817e+00, 2.4601e+00, 2.4393e+00, 2.4196e+00, 2.4010e+00, 2.3833e+00, 2.3663e+00, 2.3496e+00, 2.3330e+00, 2.3159e+00, 2.2981e+00, 2.2794e+00, 2.2602e+00, 2.2409e+00, 2.2221e+00, 2.2042e+00, 2.1875e+00, 2.1718e+00, 2.1569e+00, 2.1427e+00, 2.1288e+00, 2.1150e+00, 2.1009e+00, 2.0861e+00, 2.0704e+00}); + feg = Vctr_cpu({1.0915e+01, 1.0793e+01, 1.0441e+01, 9.9033e+00, 9.2391e+00, 8.5090e+00, 7.7655e+00, 7.0474e+00, 6.3792e+00, 5.7733e+00, 5.2336e+00, 4.7579e+00, 4.3411e+00, 3.9767e+00, 3.6576e+00, 3.3774e+00, 3.1301e+00, 2.9107e+00, 2.7149e+00, 2.5390e+00, 2.3800e+00, 2.2356e+00, 2.1037e+00, 1.9828e+00, 1.8715e+00, 1.7687e+00, 1.6735e+00, 1.5852e+00, 1.5031e+00, 1.4267e+00, 1.3554e+00, 1.2890e+00, 1.2269e+00, 1.1689e+00, 1.1147e+00, 1.0639e+00, 1.0165e+00, 9.7200e-01, 9.3030e-01, 8.9120e-01, 8.5460e-01, 8.2020e-01, 7.8780e-01, 7.5750e-01, 7.2890e-01, 7.0190e-01, 6.7660e-01, 6.5270e-01, 6.3010e-01, 6.0870e-01, 5.8850e-01, 5.6940e-01, 5.5130e-01, 5.3410e-01, 5.1780e-01, 5.0220e-01, 4.8740e-01, 4.7340e-01, 4.5990e-01, 4.4710e-01, 4.3480e-01, 4.2310e-01, 4.1180e-01, 4.0100e-01, 3.9070e-01, 3.8070e-01, 3.7120e-01, 3.6200e-01, 3.5310e-01, 3.4460e-01, 3.3640e-01, 3.2840e-01, 3.2080e-01, 3.1340e-01, 3.0620e-01, 2.9930e-01, 2.9260e-01, 2.8610e-01, 2.7980e-01, 2.7370e-01, 2.6780e-01, 2.6210e-01, 2.5660e-01, 2.5120e-01, 2.4590e-01, 2.4080e-01, 2.3590e-01, 2.3110e-01, 2.2640e-01, 2.2190e-01, 2.1750e-01, 2.1320e-01, 2.0900e-01, 2.0500e-01, 2.0100e-01, 1.9720e-01, 1.9340e-01, 1.8980e-01, 1.8630e-01, 1.8280e-01, 1.7940e-01, 1.7620e-01, 1.7300e-01, 1.6990e-01, 1.6680e-01, 1.6390e-01, 1.6100e-01, 1.5820e-01, 1.5540e-01, 1.5280e-01, 1.5010e-01, 1.4760e-01, 1.4510e-01, 1.4270e-01, 1.4030e-01, 1.3800e-01, 1.3580e-01, 1.3360e-01, 1.3140e-01, 1.2930e-01, 1.2730e-01, 1.2530e-01, 1.2330e-01, 1.2140e-01, 1.1960e-01, 1.1780e-01, 1.1600e-01, 1.1420e-01, 1.1250e-01, 1.1090e-01, 1.0920e-01, 1.0770e-01, 1.0610e-01, 1.0460e-01, 1.0310e-01, 1.0160e-01, 1.0020e-01, 9.8800e-02, 9.7400e-02, 9.6100e-02, 9.4800e-02, 9.3500e-02, 9.2300e-02, 9.1000e-02, 8.9800e-02, 8.8600e-02, 8.7500e-02, 8.6400e-02, 8.5200e-02, 8.4200e-02, 8.3100e-02, 8.2000e-02, 8.1000e-02, 8.0000e-02, 7.9000e-02, 7.8000e-02, 7.7100e-02, 7.6200e-02, 7.5200e-02, 7.4300e-02, 7.3500e-02, 7.2600e-02, 7.1700e-02, 7.0900e-02, 7.0100e-02, 6.9300e-02, 6.8500e-02, 6.7700e-02, 6.6900e-02, 6.6200e-02, 6.5400e-02, 6.4700e-02, 6.4000e-02, 6.3300e-02, 6.2600e-02, 6.1900e-02, 6.1300e-02, 6.0600e-02, 6.0000e-02, 5.9300e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6300e-02, 5.5700e-02, 5.5200e-02, 5.4600e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2400e-02, 5.1900e-02, 5.1400e-02, 5.0900e-02, 5.0400e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8500e-02, 4.8000e-02, 4.7600e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.5800e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8700e-02, 3.8300e-02, 3.8000e-02, 3.7700e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3900e-02}); + } + break; + case 54: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.4000e+01, 5.3721e+01, 5.2917e+01, 5.1677e+01, 5.0125e+01, 4.8391e+01, 4.6588e+01, 4.4802e+01, 4.3087e+01, 4.1473e+01, 3.9966e+01, 3.8562e+01, 3.7250e+01, 3.6017e+01, 3.4850e+01, 3.3737e+01, 3.2670e+01, 3.1645e+01, 3.0656e+01, 2.9703e+01, 2.8784e+01, 2.7900e+01, 2.7053e+01, 2.6242e+01, 2.5469e+01, 2.4734e+01, 2.4037e+01, 2.3378e+01, 2.2757e+01, 2.2171e+01, 2.1621e+01, 2.1104e+01, 2.0618e+01, 2.0161e+01, 1.9731e+01, 1.9325e+01, 1.8943e+01, 1.8580e+01, 1.8235e+01, 1.7906e+01, 1.7592e+01, 1.7289e+01, 1.6997e+01, 1.6714e+01, 1.6438e+01, 1.6169e+01, 1.5906e+01, 1.5647e+01, 1.5391e+01, 1.5139e+01, 1.4889e+01, 1.4642e+01, 1.4397e+01, 1.4153e+01, 1.3911e+01, 1.3671e+01, 1.3432e+01, 1.3195e+01, 1.2959e+01, 1.2725e+01, 1.2494e+01, 1.2264e+01, 1.2037e+01, 1.1812e+01, 1.1591e+01, 1.1372e+01, 1.1156e+01, 1.0944e+01, 1.0735e+01, 1.0530e+01, 1.0329e+01, 1.0131e+01, 9.9384e+00, 9.7497e+00, 9.5653e+00, 9.3854e+00, 9.2100e+00, 9.0392e+00, 8.8731e+00, 8.7115e+00, 8.5547e+00, 8.4025e+00, 8.2549e+00, 8.1119e+00, 7.9735e+00, 7.8396e+00, 7.7102e+00, 7.5851e+00, 7.4643e+00, 7.3478e+00, 7.2354e+00, 7.1270e+00, 7.0225e+00, 6.9218e+00, 6.8248e+00, 6.7315e+00, 6.6416e+00, 6.5551e+00, 6.4717e+00, 6.3915e+00, 6.3144e+00, 6.2401e+00, 6.1686e+00, 6.0997e+00, 6.0333e+00, 5.9693e+00, 5.9077e+00, 5.8483e+00, 5.7910e+00, 5.7355e+00, 5.6819e+00, 5.6302e+00, 5.5801e+00, 5.5318e+00, 5.4849e+00, 5.4393e+00, 5.3949e+00, 5.3518e+00, 5.3100e+00, 5.2693e+00, 5.2298e+00, 5.1911e+00, 5.1531e+00, 5.1159e+00, 5.0795e+00, 5.0439e+00, 5.0091e+00, 4.9750e+00, 4.9414e+00, 4.9081e+00, 4.8751e+00, 4.8426e+00, 4.8106e+00, 4.7792e+00, 4.7482e+00, 4.7176e+00, 4.6870e+00, 4.6564e+00, 4.6259e+00, 4.5956e+00, 4.5658e+00, 4.5365e+00, 4.5075e+00, 4.4784e+00, 4.4493e+00, 4.4199e+00, 4.3904e+00, 4.3611e+00, 4.3322e+00, 4.3037e+00, 4.2755e+00, 4.2474e+00, 4.2190e+00, 4.1903e+00, 4.1613e+00, 4.1322e+00, 4.1034e+00, 4.0751e+00, 4.0473e+00, 4.0197e+00, 3.9921e+00, 3.9641e+00, 3.9357e+00, 3.9069e+00, 3.8781e+00, 3.8496e+00, 3.8216e+00, 3.7943e+00, 3.7673e+00, 3.7404e+00, 3.7132e+00, 3.6855e+00, 3.6573e+00, 3.6289e+00, 3.6007e+00, 3.5730e+00, 3.5460e+00, 3.5196e+00, 3.4937e+00, 3.4678e+00, 3.4416e+00, 3.4149e+00, 3.3876e+00, 3.3601e+00, 3.3327e+00, 3.3059e+00, 3.2799e+00, 3.2548e+00, 3.2303e+00, 3.2059e+00, 3.1815e+00, 3.1565e+00, 3.1310e+00, 3.1050e+00, 3.0788e+00, 3.0530e+00, 3.0279e+00, 3.0038e+00, 2.9806e+00, 2.9581e+00, 2.9358e+00, 2.9134e+00, 2.8905e+00, 2.8670e+00, 2.8430e+00, 2.8186e+00, 2.7945e+00, 2.7710e+00, 2.7486e+00, 2.7272e+00, 2.7068e+00, 2.6868e+00, 2.6670e+00, 2.6469e+00, 2.6263e+00, 2.6050e+00, 2.5832e+00, 2.5610e+00, 2.5391e+00, 2.5179e+00, 2.4977e+00, 2.4788e+00, 2.4607e+00, 2.4434e+00, 2.4263e+00, 2.4090e+00, 2.3914e+00, 2.3730e+00, 2.3540e+00, 2.3344e+00, 2.3146e+00, 2.2953e+00, 2.2768e+00, 2.2595e+00, 2.2434e+00, 2.2282e+00, 2.2136e+00, 2.1993e+00, 2.1848e+00, 2.1700e+00, 2.1546e+00}); + feg = Vctr_cpu({1.0796e+01, 1.0687e+01, 1.0372e+01, 9.8849e+00, 9.2746e+00, 8.5923e+00, 7.8847e+00, 7.1886e+00, 6.5294e+00, 5.9224e+00, 5.3742e+00, 4.8857e+00, 4.4542e+00, 4.0747e+00, 3.7415e+00, 3.4487e+00, 3.1906e+00, 2.9622e+00, 2.7591e+00, 2.5774e+00, 2.4141e+00, 2.2663e+00, 2.1320e+00, 2.0094e+00, 1.8968e+00, 1.7931e+00, 1.6973e+00, 1.6085e+00, 1.5261e+00, 1.4493e+00, 1.3777e+00, 1.3109e+00, 1.2484e+00, 1.1899e+00, 1.1352e+00, 1.0839e+00, 1.0359e+00, 9.9080e-01, 9.4850e-01, 9.0870e-01, 8.7140e-01, 8.3630e-01, 8.0330e-01, 7.7220e-01, 7.4300e-01, 7.1540e-01, 6.8940e-01, 6.6490e-01, 6.4170e-01, 6.1980e-01, 5.9910e-01, 5.7950e-01, 5.6090e-01, 5.4320e-01, 5.2650e-01, 5.1050e-01, 4.9540e-01, 4.8090e-01, 4.6720e-01, 4.5410e-01, 4.4150e-01, 4.2950e-01, 4.1800e-01, 4.0700e-01, 3.9650e-01, 3.8640e-01, 3.7660e-01, 3.6730e-01, 3.5830e-01, 3.4960e-01, 3.4130e-01, 3.3320e-01, 3.2550e-01, 3.1800e-01, 3.1070e-01, 3.0370e-01, 2.9690e-01, 2.9040e-01, 2.8400e-01, 2.7790e-01, 2.7190e-01, 2.6610e-01, 2.6050e-01, 2.5510e-01, 2.4980e-01, 2.4470e-01, 2.3970e-01, 2.3480e-01, 2.3010e-01, 2.2550e-01, 2.2110e-01, 2.1680e-01, 2.1250e-01, 2.0840e-01, 2.0440e-01, 2.0060e-01, 1.9680e-01, 1.9310e-01, 1.8950e-01, 1.8600e-01, 1.8260e-01, 1.7930e-01, 1.7610e-01, 1.7290e-01, 1.6980e-01, 1.6680e-01, 1.6390e-01, 1.6110e-01, 1.5830e-01, 1.5560e-01, 1.5290e-01, 1.5030e-01, 1.4780e-01, 1.4540e-01, 1.4300e-01, 1.4060e-01, 1.3830e-01, 1.3610e-01, 1.3390e-01, 1.3180e-01, 1.2970e-01, 1.2770e-01, 1.2570e-01, 1.2370e-01, 1.2180e-01, 1.2000e-01, 1.1820e-01, 1.1640e-01, 1.1470e-01, 1.1300e-01, 1.1130e-01, 1.0970e-01, 1.0810e-01, 1.0660e-01, 1.0500e-01, 1.0360e-01, 1.0210e-01, 1.0070e-01, 9.9300e-02, 9.7900e-02, 9.6600e-02, 9.5300e-02, 9.4000e-02, 9.2700e-02, 9.1500e-02, 9.0300e-02, 8.9100e-02, 8.8000e-02, 8.6800e-02, 8.5700e-02, 8.4600e-02, 8.3600e-02, 8.2500e-02, 8.1500e-02, 8.0500e-02, 7.9500e-02, 7.8500e-02, 7.7600e-02, 7.6600e-02, 7.5700e-02, 7.4800e-02, 7.3900e-02, 7.3100e-02, 7.2200e-02, 7.1400e-02, 7.0500e-02, 6.9700e-02, 6.8900e-02, 6.8200e-02, 6.7400e-02, 6.6600e-02, 6.5900e-02, 6.5200e-02, 6.4400e-02, 6.3700e-02, 6.3100e-02, 6.2400e-02, 6.1700e-02, 6.1000e-02, 6.0400e-02, 5.9800e-02, 5.9100e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6700e-02, 5.6100e-02, 5.5600e-02, 5.5000e-02, 5.4500e-02, 5.3900e-02, 5.3400e-02, 5.2800e-02, 5.2300e-02, 5.1800e-02, 5.1300e-02, 5.0800e-02, 5.0300e-02, 4.9800e-02, 4.9400e-02, 4.8900e-02, 4.8400e-02, 4.8000e-02, 4.7500e-02, 4.7100e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5400e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8000e-02, 3.7700e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4500e-02}); + } + break; + case 55: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.5000e+01, 5.4589e+01, 5.3530e+01, 5.2138e+01, 5.0602e+01, 4.8977e+01, 4.7290e+01, 4.5578e+01, 4.3888e+01, 4.2258e+01, 4.0712e+01, 3.9261e+01, 3.7903e+01, 3.6633e+01, 3.5439e+01, 3.4312e+01, 3.3241e+01, 3.2218e+01, 3.1236e+01, 3.0291e+01, 2.9381e+01, 2.8505e+01, 2.7660e+01, 2.6849e+01, 2.6071e+01, 2.5327e+01, 2.4617e+01, 2.3942e+01, 2.3301e+01, 2.2695e+01, 2.2122e+01, 2.1581e+01, 2.1071e+01, 2.0591e+01, 2.0139e+01, 1.9712e+01, 1.9310e+01, 1.8929e+01, 1.8569e+01, 1.8227e+01, 1.7900e+01, 1.7588e+01, 1.7289e+01, 1.7001e+01, 1.6722e+01, 1.6451e+01, 1.6188e+01, 1.5930e+01, 1.5677e+01, 1.5428e+01, 1.5183e+01, 1.4941e+01, 1.4701e+01, 1.4463e+01, 1.4227e+01, 1.3993e+01, 1.3760e+01, 1.3529e+01, 1.3299e+01, 1.3071e+01, 1.2844e+01, 1.2619e+01, 1.2395e+01, 1.2174e+01, 1.1955e+01, 1.1738e+01, 1.1523e+01, 1.1312e+01, 1.1103e+01, 1.0898e+01, 1.0695e+01, 1.0496e+01, 1.0301e+01, 1.0109e+01, 9.9211e+00, 9.7374e+00, 9.5581e+00, 9.3823e+00, 9.2104e+00, 9.0433e+00, 8.8810e+00, 8.7228e+00, 8.5683e+00, 8.4182e+00, 8.2732e+00, 8.1328e+00, 7.9963e+00, 7.8634e+00, 7.7349e+00, 7.6114e+00, 7.4922e+00, 7.3766e+00, 7.2642e+00, 7.1558e+00, 7.0519e+00, 6.9522e+00, 6.8557e+00, 6.7618e+00, 6.6711e+00, 6.5844e+00, 6.5014e+00, 6.4216e+00, 6.3441e+00, 6.2687e+00, 6.1961e+00, 6.1269e+00, 6.0607e+00, 5.9969e+00, 5.9348e+00, 5.8741e+00, 5.8156e+00, 5.7599e+00, 5.7064e+00, 5.6548e+00, 5.6047e+00, 5.5553e+00, 5.5071e+00, 5.4610e+00, 5.4169e+00, 5.3741e+00, 5.3326e+00, 5.2919e+00, 5.2512e+00, 5.2116e+00, 5.1736e+00, 5.1370e+00, 5.1011e+00, 5.0662e+00, 5.0316e+00, 4.9967e+00, 4.9623e+00, 4.9292e+00, 4.8971e+00, 4.8654e+00, 4.8342e+00, 4.8036e+00, 4.7726e+00, 4.7411e+00, 4.7102e+00, 4.6806e+00, 4.6514e+00, 4.6222e+00, 4.5934e+00, 4.5650e+00, 4.5360e+00, 4.5061e+00, 4.4768e+00, 4.4487e+00, 4.4209e+00, 4.3928e+00, 4.3649e+00, 4.3376e+00, 4.3099e+00, 4.2811e+00, 4.2521e+00, 4.2240e+00, 4.1969e+00, 4.1696e+00, 4.1420e+00, 4.1148e+00, 4.0880e+00, 4.0606e+00, 4.0321e+00, 4.0033e+00, 3.9756e+00, 3.9489e+00, 3.9221e+00, 3.8949e+00, 3.8679e+00, 3.8415e+00, 3.8150e+00, 3.7873e+00, 3.7588e+00, 3.7307e+00, 3.7040e+00, 3.6779e+00, 3.6516e+00, 3.6250e+00, 3.5988e+00, 3.5732e+00, 3.5473e+00, 3.5203e+00, 3.4924e+00, 3.4649e+00, 3.4388e+00, 3.4137e+00, 3.3885e+00, 3.3630e+00, 3.3377e+00, 3.3130e+00, 3.2887e+00, 3.2635e+00, 3.2372e+00, 3.2104e+00, 3.1843e+00, 3.1599e+00, 3.1363e+00, 3.1126e+00, 3.0887e+00, 3.0651e+00, 3.0421e+00, 3.0194e+00, 2.9961e+00, 2.9717e+00, 2.9464e+00, 2.9216e+00, 2.8983e+00, 2.8763e+00, 2.8547e+00, 2.8330e+00, 2.8113e+00, 2.7901e+00, 2.7695e+00, 2.7489e+00, 2.7274e+00, 2.7049e+00, 2.6817e+00, 2.6588e+00, 2.6376e+00, 2.6177e+00, 2.5984e+00, 2.5791e+00, 2.5599e+00, 2.5411e+00, 2.5228e+00, 2.5048e+00, 2.4863e+00, 2.4667e+00, 2.4462e+00, 2.4252e+00, 2.4050e+00, 2.3865e+00, 2.3693e+00, 2.3525e+00, 2.3359e+00, 2.3195e+00, 2.3034e+00, 2.2878e+00, 2.2725e+00, 2.2567e+00, 2.2400e+00}); + feg = Vctr_cpu({1.6396e+01, 1.5723e+01, 1.4073e+01, 1.2177e+01, 1.0525e+01, 9.2251e+00, 8.2016e+00, 7.3636e+00, 6.6490e+00, 6.0241e+00, 5.4715e+00, 4.9812e+00, 4.5466e+00, 4.1619e+00, 3.8217e+00, 3.5210e+00, 3.2548e+00, 3.0188e+00, 2.8087e+00, 2.6210e+00, 2.4526e+00, 2.3007e+00, 2.1631e+00, 2.0378e+00, 1.9233e+00, 1.8181e+00, 1.7211e+00, 1.6315e+00, 1.5483e+00, 1.4710e+00, 1.3989e+00, 1.3317e+00, 1.2688e+00, 1.2100e+00, 1.1548e+00, 1.1031e+00, 1.0546e+00, 1.0090e+00, 9.6610e-01, 9.2580e-01, 8.8790e-01, 8.5230e-01, 8.1860e-01, 7.8700e-01, 7.5710e-01, 7.2900e-01, 7.0240e-01, 6.7730e-01, 6.5360e-01, 6.3110e-01, 6.0990e-01, 5.8980e-01, 5.7070e-01, 5.5260e-01, 5.3540e-01, 5.1910e-01, 5.0360e-01, 4.8880e-01, 4.7470e-01, 4.6130e-01, 4.4840e-01, 4.3620e-01, 4.2440e-01, 4.1320e-01, 4.0240e-01, 3.9210e-01, 3.8220e-01, 3.7270e-01, 3.6350e-01, 3.5470e-01, 3.4620e-01, 3.3810e-01, 3.3020e-01, 3.2260e-01, 3.1520e-01, 3.0810e-01, 3.0130e-01, 2.9460e-01, 2.8820e-01, 2.8200e-01, 2.7590e-01, 2.7010e-01, 2.6440e-01, 2.5890e-01, 2.5360e-01, 2.4840e-01, 2.4340e-01, 2.3850e-01, 2.3370e-01, 2.2910e-01, 2.2460e-01, 2.2020e-01, 2.1600e-01, 2.1180e-01, 2.0780e-01, 2.0390e-01, 2.0000e-01, 1.9630e-01, 1.9270e-01, 1.8920e-01, 1.8570e-01, 1.8240e-01, 1.7910e-01, 1.7590e-01, 1.7280e-01, 1.6980e-01, 1.6680e-01, 1.6390e-01, 1.6110e-01, 1.5830e-01, 1.5570e-01, 1.5300e-01, 1.5050e-01, 1.4800e-01, 1.4550e-01, 1.4320e-01, 1.4080e-01, 1.3860e-01, 1.3640e-01, 1.3420e-01, 1.3210e-01, 1.3000e-01, 1.2800e-01, 1.2600e-01, 1.2410e-01, 1.2220e-01, 1.2040e-01, 1.1860e-01, 1.1680e-01, 1.1510e-01, 1.1340e-01, 1.1170e-01, 1.1010e-01, 1.0850e-01, 1.0700e-01, 1.0550e-01, 1.0400e-01, 1.0250e-01, 1.0110e-01, 9.9700e-02, 9.8400e-02, 9.7000e-02, 9.5700e-02, 9.4400e-02, 9.3200e-02, 9.2000e-02, 9.0800e-02, 8.9600e-02, 8.8400e-02, 8.7300e-02, 8.6200e-02, 8.5100e-02, 8.4000e-02, 8.3000e-02, 8.1900e-02, 8.0900e-02, 7.9900e-02, 7.9000e-02, 7.8000e-02, 7.7100e-02, 7.6200e-02, 7.5300e-02, 7.4400e-02, 7.3500e-02, 7.2600e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9400e-02, 6.8600e-02, 6.7800e-02, 6.7100e-02, 6.6300e-02, 6.5600e-02, 6.4900e-02, 6.4200e-02, 6.3500e-02, 6.2800e-02, 6.2100e-02, 6.1500e-02, 6.0800e-02, 6.0200e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7700e-02, 5.7100e-02, 5.6500e-02, 5.6000e-02, 5.5400e-02, 5.4900e-02, 5.4300e-02, 5.3800e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0700e-02, 5.0200e-02, 4.9700e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0100e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5400e-02, 3.5100e-02}); + } + break; + case 56: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.6000e+01, 5.5543e+01, 5.4348e+01, 5.2781e+01, 5.1122e+01, 4.9473e+01, 4.7837e+01, 4.6206e+01, 4.4585e+01, 4.2994e+01, 4.1455e+01, 3.9986e+01, 3.8597e+01, 3.7290e+01, 3.6063e+01, 3.4908e+01, 3.3818e+01, 3.2783e+01, 3.1797e+01, 3.0854e+01, 2.9948e+01, 2.9076e+01, 2.8237e+01, 2.7429e+01, 2.6651e+01, 2.5904e+01, 2.5188e+01, 2.4503e+01, 2.3850e+01, 2.3227e+01, 2.2636e+01, 2.2076e+01, 2.1545e+01, 2.1044e+01, 2.0570e+01, 2.0123e+01, 1.9700e+01, 1.9301e+01, 1.8923e+01, 1.8564e+01, 1.8224e+01, 1.7900e+01, 1.7590e+01, 1.7294e+01, 1.7008e+01, 1.6733e+01, 1.6466e+01, 1.6207e+01, 1.5954e+01, 1.5706e+01, 1.5463e+01, 1.5225e+01, 1.4989e+01, 1.4755e+01, 1.4525e+01, 1.4296e+01, 1.4069e+01, 1.3843e+01, 1.3619e+01, 1.3396e+01, 1.3175e+01, 1.2954e+01, 1.2736e+01, 1.2518e+01, 1.2303e+01, 1.2089e+01, 1.1878e+01, 1.1668e+01, 1.1461e+01, 1.1256e+01, 1.1054e+01, 1.0855e+01, 1.0659e+01, 1.0466e+01, 1.0276e+01, 1.0089e+01, 9.9062e+00, 9.7273e+00, 9.5522e+00, 9.3805e+00, 9.2125e+00, 9.0490e+00, 8.8900e+00, 8.7347e+00, 8.5830e+00, 8.4354e+00, 8.2927e+00, 8.1544e+00, 8.0196e+00, 7.8882e+00, 7.7611e+00, 7.6387e+00, 7.5207e+00, 7.4060e+00, 7.2941e+00, 7.1861e+00, 7.0826e+00, 6.9833e+00, 6.8871e+00, 6.7933e+00, 6.7023e+00, 6.6151e+00, 6.5321e+00, 6.4524e+00, 6.3748e+00, 6.2990e+00, 6.2255e+00, 6.1555e+00, 6.0891e+00, 6.0253e+00, 5.9630e+00, 5.9018e+00, 5.8422e+00, 5.7853e+00, 5.7317e+00, 5.6802e+00, 5.6300e+00, 5.5803e+00, 5.5314e+00, 5.4840e+00, 5.4393e+00, 5.3969e+00, 5.3556e+00, 5.3149e+00, 5.2743e+00, 5.2339e+00, 5.1948e+00, 5.1579e+00, 5.1227e+00, 5.0883e+00, 5.0540e+00, 5.0196e+00, 4.9849e+00, 4.9507e+00, 4.9182e+00, 4.8874e+00, 4.8573e+00, 4.8271e+00, 4.7968e+00, 4.7660e+00, 4.7348e+00, 4.7042e+00, 4.6751e+00, 4.6474e+00, 4.6198e+00, 4.5918e+00, 4.5637e+00, 4.5351e+00, 4.5058e+00, 4.4766e+00, 4.4488e+00, 4.4223e+00, 4.3960e+00, 4.3692e+00, 4.3421e+00, 4.3149e+00, 4.2870e+00, 4.2584e+00, 4.2302e+00, 4.2036e+00, 4.1781e+00, 4.1522e+00, 4.1256e+00, 4.0989e+00, 4.0723e+00, 4.0450e+00, 4.0166e+00, 3.9886e+00, 3.9621e+00, 3.9370e+00, 3.9116e+00, 3.8854e+00, 3.8589e+00, 3.8327e+00, 3.8064e+00, 3.7790e+00, 3.7509e+00, 3.7237e+00, 3.6982e+00, 3.6737e+00, 3.6487e+00, 3.6228e+00, 3.5968e+00, 3.5713e+00, 3.5458e+00, 3.5193e+00, 3.4918e+00, 3.4649e+00, 3.4398e+00, 3.4161e+00, 3.3924e+00, 3.3677e+00, 3.3424e+00, 3.3176e+00, 3.2934e+00, 3.2688e+00, 3.2431e+00, 3.2167e+00, 3.1911e+00, 3.1675e+00, 3.1454e+00, 3.1232e+00, 3.1000e+00, 3.0760e+00, 3.0525e+00, 3.0298e+00, 3.0071e+00, 2.9834e+00, 2.9586e+00, 2.9340e+00, 2.9111e+00, 2.8902e+00, 2.8703e+00, 2.8497e+00, 2.8280e+00, 2.8059e+00, 2.7845e+00, 2.7639e+00, 2.7432e+00, 2.7215e+00, 2.6986e+00, 2.6759e+00, 2.6548e+00, 2.6357e+00, 2.6180e+00, 2.6001e+00, 2.5811e+00, 2.5613e+00, 2.5418e+00, 2.5231e+00, 2.5049e+00, 2.4862e+00, 2.4663e+00, 2.4456e+00, 2.4253e+00, 2.4068e+00, 2.3903e+00, 2.3752e+00, 2.3600e+00, 2.3436e+00, 2.3263e+00}); + feg = Vctr_cpu({1.8164e+01, 1.7509e+01, 1.5818e+01, 1.3696e+01, 1.1675e+01, 9.9984e+00, 8.6829e+00, 7.6539e+00, 6.8300e+00, 6.1489e+00, 5.5698e+00, 5.0681e+00, 4.6280e+00, 4.2395e+00, 3.8953e+00, 3.5898e+00, 3.3182e+00, 3.0764e+00, 2.8605e+00, 2.6674e+00, 2.4941e+00, 2.3379e+00, 2.1966e+00, 2.0682e+00, 1.9512e+00, 1.8440e+00, 1.7454e+00, 1.6545e+00, 1.5703e+00, 1.4923e+00, 1.4196e+00, 1.3518e+00, 1.2885e+00, 1.2292e+00, 1.1737e+00, 1.1215e+00, 1.0726e+00, 1.0266e+00, 9.8330e-01, 9.4250e-01, 9.0410e-01, 8.6790e-01, 8.3380e-01, 8.0160e-01, 7.7130e-01, 7.4260e-01, 7.1550e-01, 6.8980e-01, 6.6560e-01, 6.4260e-01, 6.2090e-01, 6.0030e-01, 5.8080e-01, 5.6230e-01, 5.4470e-01, 5.2790e-01, 5.1200e-01, 4.9690e-01, 4.8240e-01, 4.6870e-01, 4.5550e-01, 4.4300e-01, 4.3100e-01, 4.1950e-01, 4.0850e-01, 3.9800e-01, 3.8790e-01, 3.7820e-01, 3.6890e-01, 3.5990e-01, 3.5130e-01, 3.4290e-01, 3.3490e-01, 3.2720e-01, 3.1980e-01, 3.1260e-01, 3.0560e-01, 2.9890e-01, 2.9240e-01, 2.8610e-01, 2.7990e-01, 2.7400e-01, 2.6830e-01, 2.6270e-01, 2.5730e-01, 2.5210e-01, 2.4700e-01, 2.4210e-01, 2.3730e-01, 2.3260e-01, 2.2810e-01, 2.2360e-01, 2.1930e-01, 2.1520e-01, 2.1110e-01, 2.0710e-01, 2.0330e-01, 1.9950e-01, 1.9580e-01, 1.9230e-01, 1.8880e-01, 1.8540e-01, 1.8210e-01, 1.7880e-01, 1.7570e-01, 1.7260e-01, 1.6960e-01, 1.6670e-01, 1.6390e-01, 1.6110e-01, 1.5840e-01, 1.5570e-01, 1.5310e-01, 1.5060e-01, 1.4810e-01, 1.4570e-01, 1.4330e-01, 1.4100e-01, 1.3880e-01, 1.3660e-01, 1.3450e-01, 1.3240e-01, 1.3030e-01, 1.2830e-01, 1.2630e-01, 1.2440e-01, 1.2250e-01, 1.2070e-01, 1.1890e-01, 1.1720e-01, 1.1540e-01, 1.1380e-01, 1.1210e-01, 1.1050e-01, 1.0890e-01, 1.0740e-01, 1.0590e-01, 1.0440e-01, 1.0300e-01, 1.0150e-01, 1.0020e-01, 9.8800e-02, 9.7500e-02, 9.6200e-02, 9.4900e-02, 9.3600e-02, 9.2400e-02, 9.1200e-02, 9.0000e-02, 8.8900e-02, 8.7700e-02, 8.6600e-02, 8.5500e-02, 8.4500e-02, 8.3400e-02, 8.2400e-02, 8.1400e-02, 8.0400e-02, 7.9400e-02, 7.8500e-02, 7.7500e-02, 7.6600e-02, 7.5700e-02, 7.4800e-02, 7.3900e-02, 7.3100e-02, 7.2200e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9000e-02, 6.8200e-02, 6.7500e-02, 6.6700e-02, 6.6000e-02, 6.5300e-02, 6.4600e-02, 6.3900e-02, 6.3200e-02, 6.2500e-02, 6.1900e-02, 6.1200e-02, 6.0600e-02, 6.0000e-02, 5.9300e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6400e-02, 5.5800e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3600e-02, 5.3100e-02, 5.2600e-02, 5.2100e-02, 5.1600e-02, 5.1100e-02, 5.0600e-02, 5.0100e-02, 4.9600e-02, 4.9200e-02, 4.8700e-02, 4.8300e-02, 4.7800e-02, 4.7400e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0100e-02, 3.9700e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02}); + } + break; + case 57: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.7000e+01, 5.6550e+01, 5.5352e+01, 5.3735e+01, 5.1982e+01, 5.0232e+01, 4.8522e+01, 4.6849e+01, 4.5211e+01, 4.3616e+01, 4.2077e+01, 4.0606e+01, 3.9211e+01, 3.7896e+01, 3.6658e+01, 3.5494e+01, 3.4396e+01, 3.3357e+01, 3.2369e+01, 3.1426e+01, 3.0522e+01, 2.9653e+01, 2.8816e+01, 2.8009e+01, 2.7230e+01, 2.6480e+01, 2.5758e+01, 2.5065e+01, 2.4400e+01, 2.3764e+01, 2.3157e+01, 2.2579e+01, 2.2030e+01, 2.1509e+01, 2.1015e+01, 2.0548e+01, 2.0105e+01, 1.9687e+01, 1.9291e+01, 1.8916e+01, 1.8560e+01, 1.8222e+01, 1.7900e+01, 1.7593e+01, 1.7299e+01, 1.7017e+01, 1.6745e+01, 1.6482e+01, 1.6227e+01, 1.5978e+01, 1.5736e+01, 1.5498e+01, 1.5265e+01, 1.5035e+01, 1.4808e+01, 1.4584e+01, 1.4361e+01, 1.4141e+01, 1.3922e+01, 1.3704e+01, 1.3488e+01, 1.3273e+01, 1.3060e+01, 1.2847e+01, 1.2636e+01, 1.2427e+01, 1.2218e+01, 1.2012e+01, 1.1807e+01, 1.1604e+01, 1.1404e+01, 1.1205e+01, 1.1010e+01, 1.0816e+01, 1.0625e+01, 1.0438e+01, 1.0254e+01, 1.0072e+01, 9.8936e+00, 9.7189e+00, 9.5481e+00, 9.3807e+00, 9.2163e+00, 9.0559e+00, 8.8998e+00, 8.7479e+00, 8.5992e+00, 8.4539e+00, 8.3127e+00, 8.1762e+00, 8.0438e+00, 7.9147e+00, 7.7886e+00, 7.6666e+00, 7.5492e+00, 7.4360e+00, 7.3259e+00, 7.2185e+00, 7.1143e+00, 7.0143e+00, 6.9187e+00, 6.8263e+00, 6.7363e+00, 6.6484e+00, 6.5636e+00, 6.4828e+00, 6.4057e+00, 6.3312e+00, 6.2584e+00, 6.1871e+00, 6.1183e+00, 6.0529e+00, 5.9908e+00, 5.9310e+00, 5.8725e+00, 5.8148e+00, 5.7585e+00, 5.7048e+00, 5.6540e+00, 5.6055e+00, 5.5584e+00, 5.5116e+00, 5.4651e+00, 5.4199e+00, 5.3768e+00, 5.3361e+00, 5.2971e+00, 5.2589e+00, 5.2207e+00, 5.1822e+00, 5.1442e+00, 5.1080e+00, 5.0736e+00, 5.0407e+00, 5.0086e+00, 4.9765e+00, 4.9437e+00, 4.9104e+00, 4.8779e+00, 4.8470e+00, 4.8175e+00, 4.7888e+00, 4.7606e+00, 4.7321e+00, 4.7027e+00, 4.6724e+00, 4.6427e+00, 4.6144e+00, 4.5872e+00, 4.5606e+00, 4.5343e+00, 4.5081e+00, 4.4809e+00, 4.4525e+00, 4.4238e+00, 4.3961e+00, 4.3697e+00, 4.3439e+00, 4.3183e+00, 4.2930e+00, 4.2676e+00, 4.2412e+00, 4.2134e+00, 4.1852e+00, 4.1581e+00, 4.1323e+00, 4.1070e+00, 4.0817e+00, 4.0566e+00, 4.0318e+00, 4.0064e+00, 3.9795e+00, 3.9516e+00, 3.9241e+00, 3.8980e+00, 3.8729e+00, 3.8479e+00, 3.8228e+00, 3.7980e+00, 3.7737e+00, 3.7487e+00, 3.7222e+00, 3.6946e+00, 3.6674e+00, 3.6416e+00, 3.6171e+00, 3.5927e+00, 3.5680e+00, 3.5436e+00, 3.5197e+00, 3.4960e+00, 3.4712e+00, 3.4449e+00, 3.4178e+00, 3.3917e+00, 3.3674e+00, 3.3440e+00, 3.3205e+00, 3.2967e+00, 3.2732e+00, 3.2504e+00, 3.2280e+00, 3.2047e+00, 3.1799e+00, 3.1540e+00, 3.1286e+00, 3.1050e+00, 3.0829e+00, 3.0611e+00, 3.0389e+00, 3.0165e+00, 2.9947e+00, 2.9737e+00, 2.9530e+00, 2.9312e+00, 2.9078e+00, 2.8834e+00, 2.8597e+00, 2.8378e+00, 2.8176e+00, 2.7978e+00, 2.7776e+00, 2.7571e+00, 2.7370e+00, 2.7178e+00, 2.6992e+00, 2.6802e+00, 2.6598e+00, 2.6379e+00, 2.6154e+00, 2.5942e+00, 2.5750e+00, 2.5572e+00, 2.5398e+00, 2.5219e+00, 2.5036e+00, 2.4857e+00, 2.4688e+00, 2.4527e+00, 2.4363e+00, 2.4187e+00}); + feg = Vctr_cpu({1.7787e+01, 1.7233e+01, 1.5779e+01, 1.3894e+01, 1.2011e+01, 1.0366e+01, 9.0180e+00, 7.9332e+00, 7.0539e+00, 6.3275e+00, 5.7146e+00, 5.1884e+00, 4.7306e+00, 4.3288e+00, 3.9743e+00, 3.6602e+00, 3.3812e+00, 3.1328e+00, 2.9111e+00, 2.7128e+00, 2.5349e+00, 2.3747e+00, 2.2299e+00, 2.0987e+00, 1.9792e+00, 1.8700e+00, 1.7698e+00, 1.6775e+00, 1.5923e+00, 1.5134e+00, 1.4400e+00, 1.3716e+00, 1.3077e+00, 1.2480e+00, 1.1920e+00, 1.1395e+00, 1.0902e+00, 1.0437e+00, 1.0000e+00, 9.5880e-01, 9.2000e-01, 8.8340e-01, 8.4880e-01, 8.1610e-01, 7.8530e-01, 7.5610e-01, 7.2850e-01, 7.0240e-01, 6.7770e-01, 6.5430e-01, 6.3210e-01, 6.1100e-01, 5.9110e-01, 5.7210e-01, 5.5410e-01, 5.3700e-01, 5.2070e-01, 5.0520e-01, 4.9040e-01, 4.7630e-01, 4.6280e-01, 4.5000e-01, 4.3770e-01, 4.2600e-01, 4.1480e-01, 4.0400e-01, 3.9370e-01, 3.8380e-01, 3.7430e-01, 3.6510e-01, 3.5630e-01, 3.4790e-01, 3.3970e-01, 3.3190e-01, 3.2430e-01, 3.1700e-01, 3.0990e-01, 3.0310e-01, 2.9650e-01, 2.9010e-01, 2.8390e-01, 2.7790e-01, 2.7210e-01, 2.6650e-01, 2.6100e-01, 2.5570e-01, 2.5060e-01, 2.4560e-01, 2.4080e-01, 2.3600e-01, 2.3140e-01, 2.2700e-01, 2.2260e-01, 2.1840e-01, 2.1430e-01, 2.1030e-01, 2.0640e-01, 2.0260e-01, 1.9890e-01, 1.9530e-01, 1.9180e-01, 1.8830e-01, 1.8500e-01, 1.8170e-01, 1.7860e-01, 1.7550e-01, 1.7240e-01, 1.6950e-01, 1.6660e-01, 1.6380e-01, 1.6100e-01, 1.5830e-01, 1.5570e-01, 1.5320e-01, 1.5070e-01, 1.4820e-01, 1.4580e-01, 1.4350e-01, 1.4120e-01, 1.3900e-01, 1.3680e-01, 1.3470e-01, 1.3260e-01, 1.3060e-01, 1.2860e-01, 1.2660e-01, 1.2470e-01, 1.2280e-01, 1.2100e-01, 1.1920e-01, 1.1750e-01, 1.1580e-01, 1.1410e-01, 1.1250e-01, 1.1090e-01, 1.0930e-01, 1.0780e-01, 1.0630e-01, 1.0480e-01, 1.0340e-01, 1.0200e-01, 1.0060e-01, 9.9200e-02, 9.7900e-02, 9.6600e-02, 9.5300e-02, 9.4100e-02, 9.2800e-02, 9.1600e-02, 9.0500e-02, 8.9300e-02, 8.8200e-02, 8.7000e-02, 8.6000e-02, 8.4900e-02, 8.3800e-02, 8.2800e-02, 8.1800e-02, 8.0800e-02, 7.9800e-02, 7.8900e-02, 7.7900e-02, 7.7000e-02, 7.6100e-02, 7.5200e-02, 7.4400e-02, 7.3500e-02, 7.2700e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9400e-02, 6.8700e-02, 6.7900e-02, 6.7200e-02, 6.6400e-02, 6.5700e-02, 6.5000e-02, 6.4300e-02, 6.3600e-02, 6.2900e-02, 6.2300e-02, 6.1600e-02, 6.1000e-02, 6.0400e-02, 5.9700e-02, 5.9100e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6800e-02, 5.6200e-02, 5.5600e-02, 5.5100e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2000e-02, 5.1500e-02, 5.1000e-02, 5.0500e-02, 5.0000e-02, 4.9500e-02, 4.9100e-02, 4.8600e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6300e-02}); + } + break; + case 58: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.8000e+01, 5.7560e+01, 5.6385e+01, 5.4789e+01, 5.3047e+01, 5.1297e+01, 4.9579e+01, 4.7890e+01, 4.6232e+01, 4.4611e+01, 4.3041e+01, 4.1536e+01, 4.0103e+01, 3.8749e+01, 3.7473e+01, 3.6271e+01, 3.5138e+01, 3.4067e+01, 3.3050e+01, 3.2081e+01, 3.1154e+01, 3.0264e+01, 2.9408e+01, 2.8584e+01, 2.7790e+01, 2.7025e+01, 2.6288e+01, 2.5580e+01, 2.4900e+01, 2.4249e+01, 2.3627e+01, 2.3033e+01, 2.2468e+01, 2.1931e+01, 2.1421e+01, 2.0938e+01, 2.0480e+01, 2.0047e+01, 1.9637e+01, 1.9249e+01, 1.8881e+01, 1.8532e+01, 1.8200e+01, 1.7884e+01, 1.7582e+01, 1.7293e+01, 1.7016e+01, 1.6749e+01, 1.6490e+01, 1.6240e+01, 1.5996e+01, 1.5759e+01, 1.5526e+01, 1.5298e+01, 1.5073e+01, 1.4851e+01, 1.4632e+01, 1.4415e+01, 1.4200e+01, 1.3987e+01, 1.3775e+01, 1.3564e+01, 1.3355e+01, 1.3146e+01, 1.2939e+01, 1.2733e+01, 1.2528e+01, 1.2325e+01, 1.2123e+01, 1.1923e+01, 1.1724e+01, 1.1527e+01, 1.1333e+01, 1.1140e+01, 1.0950e+01, 1.0762e+01, 1.0577e+01, 1.0395e+01, 1.0215e+01, 1.0038e+01, 9.8654e+00, 9.6954e+00, 9.5281e+00, 9.3644e+00, 9.2047e+00, 9.0488e+00, 8.8960e+00, 8.7462e+00, 8.6004e+00, 8.4590e+00, 8.3216e+00, 8.1872e+00, 8.0558e+00, 7.9283e+00, 7.8053e+00, 7.6863e+00, 7.5705e+00, 7.4573e+00, 7.3474e+00, 7.2416e+00, 7.1401e+00, 7.0419e+00, 6.9462e+00, 6.8527e+00, 6.7623e+00, 6.6760e+00, 6.5934e+00, 6.5135e+00, 6.4355e+00, 6.3591e+00, 6.2854e+00, 6.2152e+00, 6.1483e+00, 6.0839e+00, 6.0210e+00, 5.9590e+00, 5.8986e+00, 5.8410e+00, 5.7864e+00, 5.7342e+00, 5.6835e+00, 5.6334e+00, 5.5838e+00, 5.5355e+00, 5.4896e+00, 5.4462e+00, 5.4045e+00, 5.3639e+00, 5.3234e+00, 5.2828e+00, 5.2429e+00, 5.2048e+00, 5.1687e+00, 5.1342e+00, 5.1005e+00, 5.0671e+00, 5.0330e+00, 4.9987e+00, 4.9652e+00, 4.9334e+00, 4.9031e+00, 4.8737e+00, 4.8448e+00, 4.8158e+00, 4.7859e+00, 4.7553e+00, 4.7253e+00, 4.6968e+00, 4.6695e+00, 4.6428e+00, 4.6165e+00, 4.5902e+00, 4.5631e+00, 4.5349e+00, 4.5064e+00, 4.4789e+00, 4.4528e+00, 4.4272e+00, 4.4020e+00, 4.3771e+00, 4.3520e+00, 4.3260e+00, 4.2987e+00, 4.2710e+00, 4.2444e+00, 4.2190e+00, 4.1942e+00, 4.1694e+00, 4.1448e+00, 4.1205e+00, 4.0956e+00, 4.0692e+00, 4.0419e+00, 4.0149e+00, 3.9893e+00, 3.9647e+00, 3.9402e+00, 3.9156e+00, 3.8914e+00, 3.8674e+00, 3.8429e+00, 3.8169e+00, 3.7898e+00, 3.7630e+00, 3.7377e+00, 3.7135e+00, 3.6894e+00, 3.6651e+00, 3.6410e+00, 3.6175e+00, 3.5940e+00, 3.5695e+00, 3.5435e+00, 3.5168e+00, 3.4910e+00, 3.4668e+00, 3.4435e+00, 3.4203e+00, 3.3966e+00, 3.3732e+00, 3.3505e+00, 3.3281e+00, 3.3049e+00, 3.2801e+00, 3.2544e+00, 3.2291e+00, 3.2054e+00, 3.1833e+00, 3.1614e+00, 3.1391e+00, 3.1167e+00, 3.0947e+00, 3.0736e+00, 3.0527e+00, 3.0307e+00, 3.0072e+00, 2.9828e+00, 2.9589e+00, 2.9368e+00, 2.9163e+00, 2.8962e+00, 2.8757e+00, 2.8549e+00, 2.8345e+00, 2.8149e+00, 2.7960e+00, 2.7766e+00, 2.7558e+00, 2.7336e+00, 2.7109e+00, 2.6894e+00, 2.6697e+00, 2.6515e+00, 2.6336e+00, 2.6152e+00, 2.5965e+00, 2.5781e+00, 2.5607e+00, 2.5440e+00, 2.5271e+00, 2.5090e+00}); + feg = Vctr_cpu({1.7362e+01, 1.6838e+01, 1.5458e+01, 1.3661e+01, 1.1854e+01, 1.0267e+01, 8.9579e+00, 7.9007e+00, 7.0413e+00, 6.3297e+00, 5.7282e+00, 5.2106e+00, 4.7593e+00, 4.3621e+00, 4.0105e+00, 3.6981e+00, 3.4198e+00, 3.1713e+00, 2.9489e+00, 2.7494e+00, 2.5701e+00, 2.4084e+00, 2.2622e+00, 2.1294e+00, 2.0084e+00, 1.8979e+00, 1.7964e+00, 1.7030e+00, 1.6167e+00, 1.5368e+00, 1.4625e+00, 1.3934e+00, 1.3288e+00, 1.2683e+00, 1.2117e+00, 1.1586e+00, 1.1086e+00, 1.0616e+00, 1.0174e+00, 9.7560e-01, 9.3630e-01, 8.9910e-01, 8.6400e-01, 8.3080e-01, 7.9950e-01, 7.6980e-01, 7.4170e-01, 7.1510e-01, 6.8990e-01, 6.6600e-01, 6.4340e-01, 6.2190e-01, 6.0150e-01, 5.8210e-01, 5.6370e-01, 5.4620e-01, 5.2960e-01, 5.1370e-01, 4.9860e-01, 4.8420e-01, 4.7040e-01, 4.5730e-01, 4.4480e-01, 4.3280e-01, 4.2130e-01, 4.1030e-01, 3.9970e-01, 3.8960e-01, 3.7990e-01, 3.7060e-01, 3.6160e-01, 3.5300e-01, 3.4470e-01, 3.3670e-01, 3.2900e-01, 3.2160e-01, 3.1440e-01, 3.0750e-01, 3.0080e-01, 2.9430e-01, 2.8800e-01, 2.8190e-01, 2.7610e-01, 2.7040e-01, 2.6480e-01, 2.5950e-01, 2.5420e-01, 2.4920e-01, 2.4430e-01, 2.3950e-01, 2.3490e-01, 2.3030e-01, 2.2600e-01, 2.2170e-01, 2.1750e-01, 2.1350e-01, 2.0950e-01, 2.0570e-01, 2.0200e-01, 1.9830e-01, 1.9480e-01, 1.9130e-01, 1.8790e-01, 1.8460e-01, 1.8140e-01, 1.7830e-01, 1.7520e-01, 1.7220e-01, 1.6930e-01, 1.6640e-01, 1.6370e-01, 1.6090e-01, 1.5830e-01, 1.5570e-01, 1.5320e-01, 1.5070e-01, 1.4830e-01, 1.4590e-01, 1.4360e-01, 1.4130e-01, 1.3910e-01, 1.3700e-01, 1.3490e-01, 1.3280e-01, 1.3080e-01, 1.2880e-01, 1.2690e-01, 1.2500e-01, 1.2310e-01, 1.2130e-01, 1.1950e-01, 1.1780e-01, 1.1610e-01, 1.1440e-01, 1.1280e-01, 1.1120e-01, 1.0970e-01, 1.0810e-01, 1.0660e-01, 1.0520e-01, 1.0370e-01, 1.0230e-01, 1.0090e-01, 9.9600e-02, 9.8300e-02, 9.7000e-02, 9.5700e-02, 9.4500e-02, 9.3200e-02, 9.2000e-02, 9.0900e-02, 8.9700e-02, 8.8600e-02, 8.7500e-02, 8.6400e-02, 8.5300e-02, 8.4300e-02, 8.3200e-02, 8.2200e-02, 8.1200e-02, 8.0200e-02, 7.9300e-02, 7.8400e-02, 7.7400e-02, 7.6500e-02, 7.5600e-02, 7.4800e-02, 7.3900e-02, 7.3100e-02, 7.2200e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8300e-02, 6.7600e-02, 6.6800e-02, 6.6100e-02, 6.5400e-02, 6.4700e-02, 6.4000e-02, 6.3300e-02, 6.2700e-02, 6.2000e-02, 6.1400e-02, 6.0700e-02, 6.0100e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7700e-02, 5.7100e-02, 5.6600e-02, 5.6000e-02, 5.5500e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3300e-02, 5.2800e-02, 5.2300e-02, 5.1800e-02, 5.1300e-02, 5.0800e-02, 5.0400e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7200e-02, 4.6800e-02, 4.6400e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3200e-02, 4.2800e-02, 4.2500e-02, 4.2100e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6900e-02}); + } + break; + case 59: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.9000e+01, 5.8572e+01, 5.7440e+01, 5.5923e+01, 5.4278e+01, 5.2615e+01, 5.0950e+01, 4.9278e+01, 4.7601e+01, 4.5939e+01, 4.4313e+01, 4.2744e+01, 4.1246e+01, 3.9826e+01, 3.8486e+01, 3.7224e+01, 3.6034e+01, 3.4909e+01, 3.3842e+01, 3.2826e+01, 3.1856e+01, 3.0927e+01, 3.0036e+01, 2.9179e+01, 2.8355e+01, 2.7562e+01, 2.6801e+01, 2.6070e+01, 2.5369e+01, 2.4698e+01, 2.4058e+01, 2.3448e+01, 2.2866e+01, 2.2314e+01, 2.1791e+01, 2.1294e+01, 2.0824e+01, 2.0379e+01, 1.9958e+01, 1.9560e+01, 1.9182e+01, 1.8824e+01, 1.8485e+01, 1.8162e+01, 1.7854e+01, 1.7559e+01, 1.7277e+01, 1.7007e+01, 1.6745e+01, 1.6493e+01, 1.6248e+01, 1.6010e+01, 1.5777e+01, 1.5549e+01, 1.5325e+01, 1.5105e+01, 1.4888e+01, 1.4674e+01, 1.4461e+01, 1.4251e+01, 1.4042e+01, 1.3834e+01, 1.3628e+01, 1.3423e+01, 1.3219e+01, 1.3016e+01, 1.2814e+01, 1.2614e+01, 1.2415e+01, 1.2217e+01, 1.2020e+01, 1.1825e+01, 1.1632e+01, 1.1441e+01, 1.1251e+01, 1.1064e+01, 1.0879e+01, 1.0697e+01, 1.0517e+01, 1.0339e+01, 1.0165e+01, 9.9932e+00, 9.8245e+00, 9.6584e+00, 9.4958e+00, 9.3370e+00, 9.1817e+00, 9.0290e+00, 8.8793e+00, 8.7336e+00, 8.5921e+00, 8.4541e+00, 8.3189e+00, 8.1866e+00, 8.0583e+00, 7.9343e+00, 7.8142e+00, 7.6968e+00, 7.5820e+00, 7.4705e+00, 7.3632e+00, 7.2600e+00, 7.1600e+00, 7.0621e+00, 6.9665e+00, 6.8743e+00, 6.7860e+00, 6.7014e+00, 6.6193e+00, 6.5390e+00, 6.4605e+00, 6.3847e+00, 6.3125e+00, 6.2436e+00, 6.1770e+00, 6.1119e+00, 6.0478e+00, 5.9855e+00, 5.9261e+00, 5.8697e+00, 5.8156e+00, 5.7630e+00, 5.7111e+00, 5.6598e+00, 5.6100e+00, 5.5627e+00, 5.5178e+00, 5.4746e+00, 5.4324e+00, 5.3906e+00, 5.3489e+00, 5.3079e+00, 5.2688e+00, 5.2318e+00, 5.1963e+00, 5.1615e+00, 5.1270e+00, 5.0924e+00, 5.0575e+00, 5.0235e+00, 4.9912e+00, 4.9605e+00, 4.9305e+00, 4.9009e+00, 4.8714e+00, 4.8414e+00, 4.8109e+00, 4.7808e+00, 4.7521e+00, 4.7249e+00, 4.6981e+00, 4.6714e+00, 4.6448e+00, 4.6180e+00, 4.5903e+00, 4.5621e+00, 4.5348e+00, 4.5089e+00, 4.4839e+00, 4.4587e+00, 4.4335e+00, 4.4085e+00, 4.3831e+00, 4.3567e+00, 4.3296e+00, 4.3032e+00, 4.2782e+00, 4.2541e+00, 4.2297e+00, 4.2051e+00, 4.1806e+00, 4.1562e+00, 4.1310e+00, 4.1046e+00, 4.0780e+00, 4.0527e+00, 4.0287e+00, 4.0050e+00, 3.9808e+00, 3.9563e+00, 3.9322e+00, 3.9082e+00, 3.8834e+00, 3.8574e+00, 3.8310e+00, 3.8057e+00, 3.7820e+00, 3.7588e+00, 3.7351e+00, 3.7109e+00, 3.6869e+00, 3.6634e+00, 3.6398e+00, 3.6150e+00, 3.5891e+00, 3.5633e+00, 3.5390e+00, 3.5162e+00, 3.4937e+00, 3.4706e+00, 3.4469e+00, 3.4236e+00, 3.4009e+00, 3.3782e+00, 3.3546e+00, 3.3298e+00, 3.3045e+00, 3.2804e+00, 3.2581e+00, 3.2369e+00, 3.2153e+00, 3.1930e+00, 3.1703e+00, 3.1483e+00, 3.1270e+00, 3.1056e+00, 3.0832e+00, 3.0595e+00, 3.0355e+00, 3.0126e+00, 2.9916e+00, 2.9719e+00, 2.9522e+00, 2.9316e+00, 2.9105e+00, 2.8898e+00, 2.8700e+00, 2.8505e+00, 2.8305e+00, 2.8092e+00, 2.7869e+00, 2.7648e+00, 2.7440e+00, 2.7253e+00, 2.7077e+00, 2.6899e+00, 2.6713e+00, 2.6523e+00, 2.6336e+00, 2.6157e+00, 2.5983e+00}); + feg = Vctr_cpu({1.6942e+01, 1.6385e+01, 1.4936e+01, 1.3094e+01, 1.1301e+01, 9.7798e+00, 8.5625e+00, 7.5982e+00, 6.8204e+00, 6.1748e+00, 5.6241e+00, 5.1446e+00, 4.7214e+00, 4.3446e+00, 4.0079e+00, 3.7062e+00, 3.4354e+00, 3.1922e+00, 2.9735e+00, 2.7765e+00, 2.5986e+00, 2.4377e+00, 2.2916e+00, 2.1587e+00, 2.0374e+00, 1.9262e+00, 1.8240e+00, 1.7298e+00, 1.6427e+00, 1.5619e+00, 1.4867e+00, 1.4167e+00, 1.3513e+00, 1.2900e+00, 1.2326e+00, 1.1787e+00, 1.1280e+00, 1.0803e+00, 1.0354e+00, 9.9300e-01, 9.5300e-01, 9.1520e-01, 8.7950e-01, 8.4580e-01, 8.1390e-01, 7.8370e-01, 7.5510e-01, 7.2800e-01, 7.0230e-01, 6.7800e-01, 6.5490e-01, 6.3290e-01, 6.1210e-01, 5.9230e-01, 5.7350e-01, 5.5570e-01, 5.3870e-01, 5.2240e-01, 5.0700e-01, 4.9230e-01, 4.7820e-01, 4.6480e-01, 4.5200e-01, 4.3970e-01, 4.2800e-01, 4.1680e-01, 4.0600e-01, 3.9570e-01, 3.8580e-01, 3.7630e-01, 3.6720e-01, 3.5840e-01, 3.4990e-01, 3.4180e-01, 3.3390e-01, 3.2630e-01, 3.1900e-01, 3.1200e-01, 3.0520e-01, 2.9860e-01, 2.9220e-01, 2.8600e-01, 2.8010e-01, 2.7430e-01, 2.6870e-01, 2.6320e-01, 2.5790e-01, 2.5280e-01, 2.4780e-01, 2.4300e-01, 2.3830e-01, 2.3370e-01, 2.2930e-01, 2.2500e-01, 2.2080e-01, 2.1670e-01, 2.1270e-01, 2.0880e-01, 2.0500e-01, 2.0130e-01, 1.9770e-01, 1.9420e-01, 1.9080e-01, 1.8750e-01, 1.8420e-01, 1.8110e-01, 1.7800e-01, 1.7490e-01, 1.7200e-01, 1.6910e-01, 1.6630e-01, 1.6350e-01, 1.6080e-01, 1.5820e-01, 1.5560e-01, 1.5310e-01, 1.5070e-01, 1.4830e-01, 1.4600e-01, 1.4370e-01, 1.4140e-01, 1.3920e-01, 1.3710e-01, 1.3500e-01, 1.3300e-01, 1.3100e-01, 1.2900e-01, 1.2710e-01, 1.2520e-01, 1.2340e-01, 1.2160e-01, 1.1980e-01, 1.1810e-01, 1.1640e-01, 1.1470e-01, 1.1310e-01, 1.1150e-01, 1.1000e-01, 1.0850e-01, 1.0700e-01, 1.0550e-01, 1.0410e-01, 1.0270e-01, 1.0130e-01, 1.0000e-01, 9.8600e-02, 9.7300e-02, 9.6100e-02, 9.4800e-02, 9.3600e-02, 9.2400e-02, 9.1200e-02, 9.0100e-02, 8.9000e-02, 8.7900e-02, 8.6800e-02, 8.5700e-02, 8.4700e-02, 8.3600e-02, 8.2600e-02, 8.1600e-02, 8.0600e-02, 7.9700e-02, 7.8800e-02, 7.7800e-02, 7.6900e-02, 7.6000e-02, 7.5200e-02, 7.4300e-02, 7.3500e-02, 7.2600e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9500e-02, 6.8700e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5100e-02, 6.4400e-02, 6.3700e-02, 6.3100e-02, 6.2400e-02, 6.1800e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6400e-02, 5.5800e-02, 5.5300e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0700e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8900e-02, 4.8400e-02, 4.8000e-02, 4.7600e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5100e-02, 4.4700e-02, 4.4300e-02, 4.3900e-02, 4.3500e-02, 4.3200e-02, 4.2800e-02, 4.2400e-02, 4.2100e-02, 4.1700e-02, 4.1400e-02, 4.1000e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02}); + } + break; + case 60: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.0000e+01, 5.9583e+01, 5.8473e+01, 5.6974e+01, 5.5338e+01, 5.3678e+01, 5.2011e+01, 5.0332e+01, 4.8645e+01, 4.6967e+01, 4.5319e+01, 4.3722e+01, 4.2192e+01, 4.0738e+01, 3.9362e+01, 3.8064e+01, 3.6839e+01, 3.5680e+01, 3.4582e+01, 3.3538e+01, 3.2542e+01, 3.1589e+01, 3.0675e+01, 2.9797e+01, 2.8954e+01, 2.8143e+01, 2.7363e+01, 2.6615e+01, 2.5897e+01, 2.5209e+01, 2.4551e+01, 2.3924e+01, 2.3325e+01, 2.2756e+01, 2.2215e+01, 2.1702e+01, 2.1215e+01, 2.0755e+01, 2.0318e+01, 1.9905e+01, 1.9514e+01, 1.9143e+01, 1.8792e+01, 1.8458e+01, 1.8140e+01, 1.7837e+01, 1.7548e+01, 1.7270e+01, 1.7004e+01, 1.6747e+01, 1.6499e+01, 1.6258e+01, 1.6024e+01, 1.5796e+01, 1.5572e+01, 1.5353e+01, 1.5138e+01, 1.4925e+01, 1.4716e+01, 1.4508e+01, 1.4302e+01, 1.4098e+01, 1.3896e+01, 1.3694e+01, 1.3494e+01, 1.3295e+01, 1.3097e+01, 1.2900e+01, 1.2704e+01, 1.2510e+01, 1.2316e+01, 1.2124e+01, 1.1933e+01, 1.1744e+01, 1.1556e+01, 1.1370e+01, 1.1187e+01, 1.1004e+01, 1.0825e+01, 1.0647e+01, 1.0472e+01, 1.0299e+01, 1.0129e+01, 9.9622e+00, 9.7982e+00, 9.6367e+00, 9.4779e+00, 9.3224e+00, 9.1705e+00, 9.0219e+00, 8.8761e+00, 8.7332e+00, 8.5938e+00, 8.4583e+00, 8.3265e+00, 8.1974e+00, 8.0711e+00, 7.9483e+00, 7.8294e+00, 7.7144e+00, 7.6023e+00, 7.4927e+00, 7.3859e+00, 7.2827e+00, 7.1834e+00, 7.0875e+00, 6.9941e+00, 6.9027e+00, 6.8138e+00, 6.7284e+00, 6.6466e+00, 6.5678e+00, 6.4910e+00, 6.4158e+00, 6.3426e+00, 6.2721e+00, 6.2049e+00, 6.1406e+00, 6.0781e+00, 6.0168e+00, 5.9568e+00, 5.8985e+00, 5.8427e+00, 5.7898e+00, 5.7390e+00, 5.6892e+00, 5.6401e+00, 5.5919e+00, 5.5448e+00, 5.4999e+00, 5.4573e+00, 5.4165e+00, 5.3763e+00, 5.3365e+00, 5.2970e+00, 5.2581e+00, 5.2204e+00, 5.1848e+00, 5.1509e+00, 5.1177e+00, 5.0845e+00, 5.0513e+00, 5.0183e+00, 4.9856e+00, 4.9538e+00, 4.9238e+00, 4.8952e+00, 4.8668e+00, 4.8380e+00, 4.8091e+00, 4.7803e+00, 4.7513e+00, 4.7227e+00, 4.6954e+00, 4.6696e+00, 4.6442e+00, 4.6183e+00, 4.5920e+00, 4.5656e+00, 4.5391e+00, 4.5122e+00, 4.4857e+00, 4.4606e+00, 4.4366e+00, 4.4127e+00, 4.3881e+00, 4.3630e+00, 4.3378e+00, 4.3126e+00, 4.2869e+00, 4.2610e+00, 4.2362e+00, 4.2128e+00, 4.1898e+00, 4.1661e+00, 4.1416e+00, 4.1169e+00, 4.0924e+00, 4.0677e+00, 4.0423e+00, 4.0169e+00, 3.9926e+00, 3.9697e+00, 3.9472e+00, 3.9238e+00, 3.8995e+00, 3.8751e+00, 3.8510e+00, 3.8268e+00, 3.8020e+00, 3.7766e+00, 3.7521e+00, 3.7291e+00, 3.7070e+00, 3.6847e+00, 3.6612e+00, 3.6370e+00, 3.6130e+00, 3.5896e+00, 3.5660e+00, 3.5416e+00, 3.5167e+00, 3.4927e+00, 3.4703e+00, 3.4490e+00, 3.4275e+00, 3.4049e+00, 3.3814e+00, 3.3581e+00, 3.3353e+00, 3.3129e+00, 3.2898e+00, 3.2660e+00, 3.2422e+00, 3.2196e+00, 3.1988e+00, 3.1788e+00, 3.1584e+00, 3.1368e+00, 3.1143e+00, 3.0921e+00, 3.0707e+00, 3.0496e+00, 3.0280e+00, 3.0056e+00, 2.9829e+00, 2.9613e+00, 2.9414e+00, 2.9229e+00, 2.9045e+00, 2.8852e+00, 2.8647e+00, 2.8438e+00, 2.8235e+00, 2.8039e+00, 2.7845e+00, 2.7645e+00, 2.7437e+00, 2.7227e+00, 2.7029e+00, 2.6848e+00}); + feg = Vctr_cpu({1.6488e+01, 1.5973e+01, 1.4622e+01, 1.2877e+01, 1.1157e+01, 9.6835e+00, 8.4981e+00, 7.5555e+00, 6.7939e+00, 6.1616e+00, 5.6219e+00, 5.1515e+00, 4.7356e+00, 4.3646e+00, 4.0321e+00, 3.7334e+00, 3.4646e+00, 3.2225e+00, 3.0042e+00, 2.8070e+00, 2.6287e+00, 2.4671e+00, 2.3202e+00, 2.1863e+00, 2.0640e+00, 1.9519e+00, 1.8488e+00, 1.7537e+00, 1.6658e+00, 1.5842e+00, 1.5083e+00, 1.4376e+00, 1.3715e+00, 1.3097e+00, 1.2517e+00, 1.1972e+00, 1.1460e+00, 1.0978e+00, 1.0523e+00, 1.0095e+00, 9.6900e-01, 9.3070e-01, 8.9460e-01, 8.6040e-01, 8.2800e-01, 7.9730e-01, 7.6830e-01, 7.4070e-01, 7.1460e-01, 6.8980e-01, 6.6630e-01, 6.4400e-01, 6.2280e-01, 6.0260e-01, 5.8340e-01, 5.6520e-01, 5.4780e-01, 5.3130e-01, 5.1550e-01, 5.0040e-01, 4.8610e-01, 4.7240e-01, 4.5930e-01, 4.4680e-01, 4.3480e-01, 4.2330e-01, 4.1230e-01, 4.0180e-01, 3.9170e-01, 3.8200e-01, 3.7270e-01, 3.6370e-01, 3.5510e-01, 3.4680e-01, 3.3880e-01, 3.3110e-01, 3.2360e-01, 3.1650e-01, 3.0950e-01, 3.0280e-01, 2.9630e-01, 2.9010e-01, 2.8400e-01, 2.7810e-01, 2.7250e-01, 2.6690e-01, 2.6160e-01, 2.5640e-01, 2.5140e-01, 2.4650e-01, 2.4170e-01, 2.3710e-01, 2.3260e-01, 2.2820e-01, 2.2390e-01, 2.1980e-01, 2.1580e-01, 2.1180e-01, 2.0800e-01, 2.0430e-01, 2.0070e-01, 1.9710e-01, 1.9370e-01, 1.9030e-01, 1.8700e-01, 1.8380e-01, 1.8070e-01, 1.7760e-01, 1.7460e-01, 1.7170e-01, 1.6890e-01, 1.6610e-01, 1.6340e-01, 1.6070e-01, 1.5810e-01, 1.5560e-01, 1.5310e-01, 1.5070e-01, 1.4830e-01, 1.4600e-01, 1.4370e-01, 1.4150e-01, 1.3930e-01, 1.3720e-01, 1.3510e-01, 1.3310e-01, 1.3110e-01, 1.2920e-01, 1.2730e-01, 1.2540e-01, 1.2360e-01, 1.2180e-01, 1.2010e-01, 1.1830e-01, 1.1670e-01, 1.1500e-01, 1.1340e-01, 1.1180e-01, 1.1030e-01, 1.0880e-01, 1.0730e-01, 1.0580e-01, 1.0440e-01, 1.0300e-01, 1.0170e-01, 1.0030e-01, 9.9000e-02, 9.7700e-02, 9.6400e-02, 9.5200e-02, 9.4000e-02, 9.2800e-02, 9.1600e-02, 9.0500e-02, 8.9300e-02, 8.8200e-02, 8.7100e-02, 8.6100e-02, 8.5000e-02, 8.4000e-02, 8.3000e-02, 8.2000e-02, 8.1000e-02, 8.0100e-02, 7.9100e-02, 7.8200e-02, 7.7300e-02, 7.6400e-02, 7.5600e-02, 7.4700e-02, 7.3900e-02, 7.3000e-02, 7.2200e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6200e-02, 6.5500e-02, 6.4800e-02, 6.4100e-02, 6.3400e-02, 6.2800e-02, 6.2100e-02, 6.1500e-02, 6.0900e-02, 6.0200e-02, 5.9600e-02, 5.9000e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6700e-02, 5.6200e-02, 5.5600e-02, 5.5100e-02, 5.4600e-02, 5.4100e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2000e-02, 5.1500e-02, 5.1100e-02, 5.0600e-02, 5.0100e-02, 4.9700e-02, 4.9200e-02, 4.8800e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4300e-02, 4.3900e-02, 4.3500e-02, 4.3100e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1700e-02, 4.1300e-02, 4.1000e-02, 4.0700e-02, 4.0300e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02}); + } + break; + case 61: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.1000e+01, 6.0591e+01, 5.9499e+01, 5.8020e+01, 5.6398e+01, 5.4744e+01, 5.3078e+01, 5.1396e+01, 4.9701e+01, 4.8009e+01, 4.6342e+01, 4.4721e+01, 4.3161e+01, 4.1675e+01, 4.0265e+01, 3.8931e+01, 3.7671e+01, 3.6479e+01, 3.5349e+01, 3.4275e+01, 3.3252e+01, 3.2273e+01, 3.1335e+01, 3.0436e+01, 2.9571e+01, 2.8740e+01, 2.7942e+01, 2.7175e+01, 2.6438e+01, 2.5733e+01, 2.5057e+01, 2.4412e+01, 2.3796e+01, 2.3209e+01, 2.2651e+01, 2.2120e+01, 2.1617e+01, 2.1140e+01, 2.0688e+01, 2.0260e+01, 1.9854e+01, 1.9470e+01, 1.9105e+01, 1.8760e+01, 1.8431e+01, 1.8119e+01, 1.7821e+01, 1.7536e+01, 1.7263e+01, 1.7001e+01, 1.6748e+01, 1.6504e+01, 1.6267e+01, 1.6037e+01, 1.5813e+01, 1.5594e+01, 1.5379e+01, 1.5168e+01, 1.4960e+01, 1.4754e+01, 1.4551e+01, 1.4350e+01, 1.4151e+01, 1.3953e+01, 1.3756e+01, 1.3561e+01, 1.3367e+01, 1.3173e+01, 1.2981e+01, 1.2790e+01, 1.2600e+01, 1.2410e+01, 1.2222e+01, 1.2036e+01, 1.1850e+01, 1.1666e+01, 1.1483e+01, 1.1303e+01, 1.1124e+01, 1.0947e+01, 1.0772e+01, 1.0599e+01, 1.0429e+01, 1.0261e+01, 1.0096e+01, 9.9323e+00, 9.7724e+00, 9.6154e+00, 9.4608e+00, 9.3087e+00, 9.1597e+00, 9.0144e+00, 8.8724e+00, 8.7331e+00, 8.5963e+00, 8.4626e+00, 8.3330e+00, 8.2070e+00, 8.0839e+00, 7.9632e+00, 7.8452e+00, 7.7310e+00, 7.6207e+00, 7.5138e+00, 7.4093e+00, 7.3069e+00, 7.2073e+00, 7.1114e+00, 7.0193e+00, 6.9301e+00, 6.8431e+00, 6.7578e+00, 6.6748e+00, 6.5950e+00, 6.5188e+00, 6.4454e+00, 6.3739e+00, 6.3039e+00, 6.2353e+00, 6.1690e+00, 6.1058e+00, 6.0456e+00, 5.9873e+00, 5.9302e+00, 5.8741e+00, 5.8190e+00, 5.7659e+00, 5.7155e+00, 5.6675e+00, 5.6210e+00, 5.5753e+00, 5.5302e+00, 5.4855e+00, 5.4420e+00, 5.4007e+00, 5.3616e+00, 5.3238e+00, 5.2866e+00, 5.2497e+00, 5.2130e+00, 5.1765e+00, 5.1410e+00, 5.1075e+00, 5.0756e+00, 5.0445e+00, 5.0135e+00, 4.9826e+00, 4.9517e+00, 4.9205e+00, 4.8899e+00, 4.8608e+00, 4.8332e+00, 4.8063e+00, 4.7792e+00, 4.7522e+00, 4.7250e+00, 4.6975e+00, 4.6695e+00, 4.6423e+00, 4.6167e+00, 4.5921e+00, 4.5676e+00, 4.5427e+00, 4.5177e+00, 4.4927e+00, 4.4671e+00, 4.4409e+00, 4.4151e+00, 4.3907e+00, 4.3674e+00, 4.3442e+00, 4.3204e+00, 4.2964e+00, 4.2725e+00, 4.2483e+00, 4.2233e+00, 4.1978e+00, 4.1730e+00, 4.1497e+00, 4.1272e+00, 4.1045e+00, 4.0810e+00, 4.0573e+00, 4.0339e+00, 4.0103e+00, 3.9858e+00, 3.9606e+00, 3.9358e+00, 3.9125e+00, 3.8903e+00, 3.8682e+00, 3.8452e+00, 3.8217e+00, 3.7984e+00, 3.7754e+00, 3.7520e+00, 3.7277e+00, 3.7027e+00, 3.6784e+00, 3.6557e+00, 3.6341e+00, 3.6125e+00, 3.5899e+00, 3.5668e+00, 3.5439e+00, 3.5215e+00, 3.4990e+00, 3.4756e+00, 3.4513e+00, 3.4271e+00, 3.4043e+00, 3.3830e+00, 3.3625e+00, 3.3414e+00, 3.3193e+00, 3.2969e+00, 3.2750e+00, 3.2536e+00, 3.2321e+00, 3.2097e+00, 3.1864e+00, 3.1631e+00, 3.1411e+00, 3.1207e+00, 3.1015e+00, 3.0820e+00, 3.0615e+00, 3.0403e+00, 3.0194e+00, 2.9992e+00, 2.9793e+00, 2.9590e+00, 2.9377e+00, 2.9156e+00, 2.8939e+00, 2.8735e+00, 2.8549e+00, 2.8375e+00, 2.8198e+00, 2.8011e+00, 2.7816e+00}); + feg = Vctr_cpu({1.6177e+01, 1.5677e+01, 1.4367e+01, 1.2679e+01, 1.1014e+01, 9.5830e+00, 8.4270e+00, 7.5058e+00, 6.7608e+00, 6.1418e+00, 5.6132e+00, 5.1521e+00, 4.7438e+00, 4.3789e+00, 4.0512e+00, 3.7560e+00, 3.4896e+00, 3.2491e+00, 3.0317e+00, 2.8349e+00, 2.6565e+00, 2.4945e+00, 2.3471e+00, 2.2125e+00, 2.0895e+00, 1.9766e+00, 1.8727e+00, 1.7768e+00, 1.6881e+00, 1.6059e+00, 1.5293e+00, 1.4580e+00, 1.3913e+00, 1.3289e+00, 1.2704e+00, 1.2154e+00, 1.1637e+00, 1.1150e+00, 1.0691e+00, 1.0257e+00, 9.8480e-01, 9.4610e-01, 9.0950e-01, 8.7480e-01, 8.4200e-01, 8.1090e-01, 7.8140e-01, 7.5350e-01, 7.2690e-01, 7.0180e-01, 6.7780e-01, 6.5510e-01, 6.3350e-01, 6.1300e-01, 5.9340e-01, 5.7480e-01, 5.5710e-01, 5.4020e-01, 5.2410e-01, 5.0870e-01, 4.9410e-01, 4.8010e-01, 4.6670e-01, 4.5390e-01, 4.4170e-01, 4.3000e-01, 4.1870e-01, 4.0800e-01, 3.9770e-01, 3.8780e-01, 3.7830e-01, 3.6910e-01, 3.6030e-01, 3.5190e-01, 3.4370e-01, 3.3590e-01, 3.2830e-01, 3.2100e-01, 3.1390e-01, 3.0710e-01, 3.0050e-01, 2.9420e-01, 2.8800e-01, 2.8200e-01, 2.7630e-01, 2.7070e-01, 2.6520e-01, 2.6000e-01, 2.5490e-01, 2.4990e-01, 2.4510e-01, 2.4040e-01, 2.3580e-01, 2.3140e-01, 2.2710e-01, 2.2290e-01, 2.1880e-01, 2.1490e-01, 2.1100e-01, 2.0720e-01, 2.0360e-01, 2.0000e-01, 1.9650e-01, 1.9310e-01, 1.8970e-01, 1.8650e-01, 1.8330e-01, 1.8020e-01, 1.7720e-01, 1.7430e-01, 1.7140e-01, 1.6860e-01, 1.6580e-01, 1.6320e-01, 1.6050e-01, 1.5800e-01, 1.5550e-01, 1.5300e-01, 1.5060e-01, 1.4830e-01, 1.4600e-01, 1.4370e-01, 1.4150e-01, 1.3940e-01, 1.3730e-01, 1.3520e-01, 1.3320e-01, 1.3130e-01, 1.2930e-01, 1.2740e-01, 1.2560e-01, 1.2380e-01, 1.2200e-01, 1.2030e-01, 1.1860e-01, 1.1690e-01, 1.1530e-01, 1.1370e-01, 1.1210e-01, 1.1060e-01, 1.0910e-01, 1.0760e-01, 1.0610e-01, 1.0470e-01, 1.0330e-01, 1.0200e-01, 1.0060e-01, 9.9300e-02, 9.8000e-02, 9.6800e-02, 9.5500e-02, 9.4300e-02, 9.3100e-02, 9.2000e-02, 9.0800e-02, 8.9700e-02, 8.8600e-02, 8.7500e-02, 8.6500e-02, 8.5400e-02, 8.4400e-02, 8.3400e-02, 8.2400e-02, 8.1400e-02, 8.0500e-02, 7.9500e-02, 7.8600e-02, 7.7700e-02, 7.6800e-02, 7.5900e-02, 7.5100e-02, 7.4200e-02, 7.3400e-02, 7.2600e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9500e-02, 6.8700e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5100e-02, 6.4500e-02, 6.3800e-02, 6.3100e-02, 6.2500e-02, 6.1900e-02, 6.1200e-02, 6.0600e-02, 6.0000e-02, 5.9400e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7100e-02, 5.6500e-02, 5.6000e-02, 5.5500e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3400e-02, 5.2900e-02, 5.2400e-02, 5.1900e-02, 5.1400e-02, 5.0900e-02, 5.0500e-02, 5.0000e-02, 4.9600e-02, 4.9100e-02, 4.8700e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3100e-02, 4.2700e-02, 4.2400e-02, 4.2000e-02, 4.1700e-02, 4.1300e-02, 4.1000e-02, 4.0600e-02, 4.0300e-02, 4.0000e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8700e-02}); + } + break; + case 62: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.2000e+01, 6.1599e+01, 6.0527e+01, 5.9067e+01, 5.7458e+01, 5.5811e+01, 5.4148e+01, 5.2465e+01, 5.0764e+01, 4.9062e+01, 4.7379e+01, 4.5737e+01, 4.4151e+01, 4.2635e+01, 4.1192e+01, 3.9825e+01, 3.8532e+01, 3.7306e+01, 3.6144e+01, 3.5040e+01, 3.3987e+01, 3.2982e+01, 3.2019e+01, 3.1096e+01, 3.0209e+01, 2.9357e+01, 2.8539e+01, 2.7752e+01, 2.6997e+01, 2.6272e+01, 2.5578e+01, 2.4914e+01, 2.4280e+01, 2.3675e+01, 2.3099e+01, 2.2552e+01, 2.2031e+01, 2.1537e+01, 2.1069e+01, 2.0625e+01, 2.0204e+01, 1.9805e+01, 1.9428e+01, 1.9069e+01, 1.8729e+01, 1.8406e+01, 1.8098e+01, 1.7805e+01, 1.7524e+01, 1.7255e+01, 1.6997e+01, 1.6748e+01, 1.6508e+01, 1.6275e+01, 1.6049e+01, 1.5829e+01, 1.5613e+01, 1.5402e+01, 1.5195e+01, 1.4991e+01, 1.4790e+01, 1.4591e+01, 1.4395e+01, 1.4200e+01, 1.4006e+01, 1.3814e+01, 1.3623e+01, 1.3434e+01, 1.3245e+01, 1.3057e+01, 1.2870e+01, 1.2684e+01, 1.2499e+01, 1.2315e+01, 1.2132e+01, 1.1950e+01, 1.1770e+01, 1.1591e+01, 1.1414e+01, 1.1238e+01, 1.1064e+01, 1.0892e+01, 1.0722e+01, 1.0554e+01, 1.0388e+01, 1.0224e+01, 1.0063e+01, 9.9043e+00, 9.7481e+00, 9.5940e+00, 9.4428e+00, 9.2950e+00, 9.1503e+00, 9.0081e+00, 8.8681e+00, 8.7311e+00, 8.5978e+00, 8.4681e+00, 8.3411e+00, 8.2163e+00, 8.0942e+00, 7.9757e+00, 7.8610e+00, 7.7496e+00, 7.6405e+00, 7.5336e+00, 7.4294e+00, 7.3288e+00, 7.2319e+00, 7.1381e+00, 7.0463e+00, 6.9564e+00, 6.8688e+00, 6.7844e+00, 6.7036e+00, 6.6256e+00, 6.5497e+00, 6.4752e+00, 6.4023e+00, 6.3318e+00, 6.2645e+00, 6.2002e+00, 6.1379e+00, 6.0770e+00, 6.0171e+00, 5.9584e+00, 5.9018e+00, 5.8479e+00, 5.7966e+00, 5.7469e+00, 5.6981e+00, 5.6499e+00, 5.6024e+00, 5.5563e+00, 5.5123e+00, 5.4707e+00, 5.4305e+00, 5.3910e+00, 5.3520e+00, 5.3132e+00, 5.2748e+00, 5.2375e+00, 5.2022e+00, 5.1687e+00, 5.1360e+00, 5.1036e+00, 5.0715e+00, 5.0393e+00, 5.0070e+00, 4.9753e+00, 4.9453e+00, 4.9168e+00, 4.8890e+00, 4.8613e+00, 4.8336e+00, 4.8059e+00, 4.7778e+00, 4.7495e+00, 4.7219e+00, 4.6960e+00, 4.6711e+00, 4.6464e+00, 4.6214e+00, 4.5963e+00, 4.5712e+00, 4.5456e+00, 4.5195e+00, 4.4938e+00, 4.4694e+00, 4.4463e+00, 4.4233e+00, 4.3997e+00, 4.3759e+00, 4.3523e+00, 4.3284e+00, 4.3037e+00, 4.2785e+00, 4.2541e+00, 4.2311e+00, 4.2090e+00, 4.1866e+00, 4.1635e+00, 4.1403e+00, 4.1172e+00, 4.0940e+00, 4.0700e+00, 4.0453e+00, 4.0209e+00, 3.9980e+00, 3.9762e+00, 3.9544e+00, 3.9319e+00, 3.9088e+00, 3.8859e+00, 3.8633e+00, 3.8404e+00, 3.8164e+00, 3.7919e+00, 3.7680e+00, 3.7456e+00, 3.7243e+00, 3.7030e+00, 3.6807e+00, 3.6579e+00, 3.6353e+00, 3.6132e+00, 3.5910e+00, 3.5678e+00, 3.5438e+00, 3.5199e+00, 3.4973e+00, 3.4762e+00, 3.4558e+00, 3.4348e+00, 3.4129e+00, 3.3907e+00, 3.3689e+00, 3.3476e+00, 3.3262e+00, 3.3039e+00, 3.2807e+00, 3.2575e+00, 3.2355e+00, 3.2151e+00, 3.1958e+00, 3.1763e+00, 3.1558e+00, 3.1345e+00, 3.1135e+00, 3.0932e+00, 3.0732e+00, 3.0528e+00, 3.0314e+00, 3.0093e+00, 2.9875e+00, 2.9670e+00, 2.9482e+00, 2.9305e+00, 2.9126e+00, 2.8936e+00, 2.8739e+00}); + feg = Vctr_cpu({1.5835e+01, 1.5357e+01, 1.4103e+01, 1.2480e+01, 1.0871e+01, 9.4802e+00, 8.3527e+00, 7.4520e+00, 6.7227e+00, 6.1165e+00, 5.5988e+00, 5.1470e+00, 4.7465e+00, 4.3880e+00, 4.0653e+00, 3.7740e+00, 3.5105e+00, 3.2720e+00, 3.0559e+00, 2.8599e+00, 2.6818e+00, 2.5198e+00, 2.3721e+00, 2.2371e+00, 2.1135e+00, 2.0000e+00, 1.8955e+00, 1.7990e+00, 1.7097e+00, 1.6268e+00, 1.5497e+00, 1.4778e+00, 1.4106e+00, 1.3477e+00, 1.2886e+00, 1.2332e+00, 1.1810e+00, 1.1318e+00, 1.0855e+00, 1.0417e+00, 1.0003e+00, 9.6120e-01, 9.2420e-01, 8.8910e-01, 8.5590e-01, 8.2440e-01, 7.9450e-01, 7.6610e-01, 7.3920e-01, 7.1360e-01, 6.8930e-01, 6.6620e-01, 6.4430e-01, 6.2330e-01, 6.0340e-01, 5.8450e-01, 5.6640e-01, 5.4920e-01, 5.3280e-01, 5.1710e-01, 5.0220e-01, 4.8790e-01, 4.7420e-01, 4.6120e-01, 4.4870e-01, 4.3670e-01, 4.2530e-01, 4.1430e-01, 4.0380e-01, 3.9370e-01, 3.8400e-01, 3.7460e-01, 3.6570e-01, 3.5700e-01, 3.4870e-01, 3.4070e-01, 3.3300e-01, 3.2560e-01, 3.1840e-01, 3.1150e-01, 3.0480e-01, 2.9830e-01, 2.9200e-01, 2.8600e-01, 2.8010e-01, 2.7440e-01, 2.6890e-01, 2.6360e-01, 2.5840e-01, 2.5340e-01, 2.4850e-01, 2.4370e-01, 2.3910e-01, 2.3460e-01, 2.3030e-01, 2.2600e-01, 2.2190e-01, 2.1790e-01, 2.1400e-01, 2.1010e-01, 2.0640e-01, 2.0280e-01, 1.9930e-01, 1.9580e-01, 1.9250e-01, 1.8920e-01, 1.8600e-01, 1.8290e-01, 1.7980e-01, 1.7680e-01, 1.7390e-01, 1.7110e-01, 1.6830e-01, 1.6560e-01, 1.6290e-01, 1.6030e-01, 1.5780e-01, 1.5530e-01, 1.5290e-01, 1.5050e-01, 1.4820e-01, 1.4590e-01, 1.4370e-01, 1.4150e-01, 1.3940e-01, 1.3730e-01, 1.3530e-01, 1.3330e-01, 1.3140e-01, 1.2940e-01, 1.2760e-01, 1.2570e-01, 1.2390e-01, 1.2220e-01, 1.2050e-01, 1.1880e-01, 1.1710e-01, 1.1550e-01, 1.1390e-01, 1.1240e-01, 1.1080e-01, 1.0930e-01, 1.0790e-01, 1.0640e-01, 1.0500e-01, 1.0360e-01, 1.0230e-01, 1.0090e-01, 9.9600e-02, 9.8400e-02, 9.7100e-02, 9.5900e-02, 9.4700e-02, 9.3500e-02, 9.2300e-02, 9.1200e-02, 9.0000e-02, 8.8900e-02, 8.7900e-02, 8.6800e-02, 8.5800e-02, 8.4700e-02, 8.3700e-02, 8.2700e-02, 8.1800e-02, 8.0800e-02, 7.9900e-02, 7.9000e-02, 7.8100e-02, 7.7200e-02, 7.6300e-02, 7.5400e-02, 7.4600e-02, 7.3800e-02, 7.2900e-02, 7.2100e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6200e-02, 6.5500e-02, 6.4800e-02, 6.4100e-02, 6.3500e-02, 6.2800e-02, 6.2200e-02, 6.1600e-02, 6.1000e-02, 6.0300e-02, 5.9700e-02, 5.9200e-02, 5.8600e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6300e-02, 5.5800e-02, 5.5300e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1300e-02, 5.0800e-02, 5.0300e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8100e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3400e-02, 4.3000e-02, 4.2700e-02, 4.2300e-02, 4.2000e-02, 4.1600e-02, 4.1300e-02, 4.0900e-02, 4.0600e-02, 4.0300e-02, 3.9900e-02, 3.9600e-02, 3.9300e-02}); + } + break; + case 63: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.3000e+01, 6.2607e+01, 6.1554e+01, 6.0113e+01, 5.8517e+01, 5.6878e+01, 5.5218e+01, 5.3535e+01, 5.1832e+01, 5.0121e+01, 4.8424e+01, 4.6762e+01, 4.5153e+01, 4.3609e+01, 4.2136e+01, 4.0736e+01, 3.9410e+01, 3.8152e+01, 3.6958e+01, 3.5824e+01, 3.4742e+01, 3.3710e+01, 3.2721e+01, 3.1774e+01, 3.0864e+01, 2.9991e+01, 2.9151e+01, 2.8344e+01, 2.7570e+01, 2.6826e+01, 2.6113e+01, 2.5431e+01, 2.4778e+01, 2.4155e+01, 2.3561e+01, 2.2995e+01, 2.2457e+01, 2.1946e+01, 2.1461e+01, 2.1001e+01, 2.0565e+01, 2.0151e+01, 1.9759e+01, 1.9388e+01, 1.9035e+01, 1.8700e+01, 1.8382e+01, 1.8079e+01, 1.7789e+01, 1.7513e+01, 1.7248e+01, 1.6993e+01, 1.6748e+01, 1.6512e+01, 1.6282e+01, 1.6060e+01, 1.5843e+01, 1.5632e+01, 1.5425e+01, 1.5221e+01, 1.5021e+01, 1.4824e+01, 1.4629e+01, 1.4437e+01, 1.4246e+01, 1.4057e+01, 1.3869e+01, 1.3682e+01, 1.3496e+01, 1.3312e+01, 1.3128e+01, 1.2945e+01, 1.2764e+01, 1.2583e+01, 1.2403e+01, 1.2224e+01, 1.2046e+01, 1.1869e+01, 1.1694e+01, 1.1520e+01, 1.1347e+01, 1.1176e+01, 1.1007e+01, 1.0840e+01, 1.0674e+01, 1.0510e+01, 1.0348e+01, 1.0189e+01, 1.0032e+01, 9.8766e+00, 9.7239e+00, 9.5743e+00, 9.4276e+00, 9.2830e+00, 9.1405e+00, 9.0008e+00, 8.8645e+00, 8.7316e+00, 8.6012e+00, 8.4730e+00, 8.3472e+00, 8.2249e+00, 8.1063e+00, 7.9908e+00, 7.8776e+00, 7.7664e+00, 7.6579e+00, 7.5530e+00, 7.4517e+00, 7.3533e+00, 7.2571e+00, 7.1627e+00, 7.0706e+00, 6.9818e+00, 6.8965e+00, 6.8141e+00, 6.7338e+00, 6.6549e+00, 6.5778e+00, 6.5031e+00, 6.4316e+00, 6.3631e+00, 6.2968e+00, 6.2319e+00, 6.1682e+00, 6.1057e+00, 6.0455e+00, 5.9880e+00, 5.9332e+00, 5.8801e+00, 5.8280e+00, 5.7767e+00, 5.7262e+00, 5.6771e+00, 5.6303e+00, 5.5859e+00, 5.5430e+00, 5.5011e+00, 5.4596e+00, 5.4186e+00, 5.3780e+00, 5.3386e+00, 5.3014e+00, 5.2660e+00, 5.2315e+00, 5.1974e+00, 5.1637e+00, 5.1300e+00, 5.0963e+00, 5.0634e+00, 5.0322e+00, 5.0026e+00, 4.9738e+00, 4.9451e+00, 4.9165e+00, 4.8880e+00, 4.8592e+00, 4.8302e+00, 4.8022e+00, 4.7756e+00, 4.7503e+00, 4.7252e+00, 4.6999e+00, 4.6746e+00, 4.6492e+00, 4.6235e+00, 4.5972e+00, 4.5715e+00, 4.5471e+00, 4.5239e+00, 4.5009e+00, 4.4775e+00, 4.4539e+00, 4.4303e+00, 4.4066e+00, 4.3821e+00, 4.3572e+00, 4.3331e+00, 4.3103e+00, 4.2885e+00, 4.2664e+00, 4.2437e+00, 4.2208e+00, 4.1981e+00, 4.1752e+00, 4.1516e+00, 4.1273e+00, 4.1033e+00, 4.0808e+00, 4.0594e+00, 4.0380e+00, 4.0158e+00, 3.9932e+00, 3.9707e+00, 3.9485e+00, 3.9259e+00, 3.9023e+00, 3.8783e+00, 3.8548e+00, 3.8327e+00, 3.8118e+00, 3.7908e+00, 3.7689e+00, 3.7464e+00, 3.7242e+00, 3.7024e+00, 3.6804e+00, 3.6576e+00, 3.6340e+00, 3.6104e+00, 3.5880e+00, 3.5671e+00, 3.5469e+00, 3.5262e+00, 3.5045e+00, 3.4824e+00, 3.4608e+00, 3.4397e+00, 3.4184e+00, 3.3963e+00, 3.3733e+00, 3.3502e+00, 3.3283e+00, 3.3080e+00, 3.2887e+00, 3.2692e+00, 3.2487e+00, 3.2275e+00, 3.2065e+00, 3.1862e+00, 3.1662e+00, 3.1458e+00, 3.1243e+00, 3.1022e+00, 3.0804e+00, 3.0598e+00, 3.0409e+00, 3.0230e+00, 3.0049e+00, 2.9858e+00, 2.9659e+00}); + feg = Vctr_cpu({1.5507e+01, 1.5050e+01, 1.3847e+01, 1.2286e+01, 1.0729e+01, 9.3780e+00, 8.2778e+00, 7.3967e+00, 6.6825e+00, 6.0888e+00, 5.5816e+00, 5.1389e+00, 4.7460e+00, 4.3939e+00, 4.0764e+00, 3.7891e+00, 3.5287e+00, 3.2925e+00, 3.0779e+00, 2.8828e+00, 2.7052e+00, 2.5434e+00, 2.3956e+00, 2.2604e+00, 2.1364e+00, 2.0225e+00, 1.9175e+00, 1.8204e+00, 1.7306e+00, 1.6471e+00, 1.5695e+00, 1.4971e+00, 1.4294e+00, 1.3660e+00, 1.3065e+00, 1.2506e+00, 1.1979e+00, 1.1484e+00, 1.1016e+00, 1.0574e+00, 1.0156e+00, 9.7610e-01, 9.3870e-01, 9.0320e-01, 8.6960e-01, 8.3770e-01, 8.0750e-01, 7.7870e-01, 7.5140e-01, 7.2550e-01, 7.0080e-01, 6.7730e-01, 6.5500e-01, 6.3380e-01, 6.1350e-01, 5.9420e-01, 5.7580e-01, 5.5830e-01, 5.4160e-01, 5.2560e-01, 5.1040e-01, 4.9580e-01, 4.8190e-01, 4.6860e-01, 4.5580e-01, 4.4360e-01, 4.3190e-01, 4.2070e-01, 4.1000e-01, 3.9970e-01, 3.8980e-01, 3.8020e-01, 3.7110e-01, 3.6230e-01, 3.5380e-01, 3.4570e-01, 3.3780e-01, 3.3020e-01, 3.2290e-01, 3.1590e-01, 3.0910e-01, 3.0250e-01, 2.9610e-01, 2.8990e-01, 2.8400e-01, 2.7820e-01, 2.7260e-01, 2.6720e-01, 2.6190e-01, 2.5680e-01, 2.5190e-01, 2.4710e-01, 2.4240e-01, 2.3780e-01, 2.3340e-01, 2.2910e-01, 2.2490e-01, 2.2090e-01, 2.1690e-01, 2.1300e-01, 2.0930e-01, 2.0560e-01, 2.0200e-01, 1.9860e-01, 1.9520e-01, 1.9180e-01, 1.8860e-01, 1.8550e-01, 1.8240e-01, 1.7940e-01, 1.7640e-01, 1.7350e-01, 1.7070e-01, 1.6800e-01, 1.6530e-01, 1.6270e-01, 1.6010e-01, 1.5760e-01, 1.5520e-01, 1.5280e-01, 1.5040e-01, 1.4810e-01, 1.4590e-01, 1.4370e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3340e-01, 1.3140e-01, 1.2950e-01, 1.2770e-01, 1.2590e-01, 1.2410e-01, 1.2230e-01, 1.2060e-01, 1.1900e-01, 1.1730e-01, 1.1570e-01, 1.1410e-01, 1.1260e-01, 1.1110e-01, 1.0960e-01, 1.0810e-01, 1.0670e-01, 1.0530e-01, 1.0390e-01, 1.0260e-01, 1.0120e-01, 9.9900e-02, 9.8700e-02, 9.7400e-02, 9.6200e-02, 9.5000e-02, 9.3800e-02, 9.2600e-02, 9.1500e-02, 9.0400e-02, 8.9300e-02, 8.8200e-02, 8.7100e-02, 8.6100e-02, 8.5100e-02, 8.4100e-02, 8.3100e-02, 8.2100e-02, 8.1200e-02, 8.0200e-02, 7.9300e-02, 7.8400e-02, 7.7500e-02, 7.6600e-02, 7.5800e-02, 7.4900e-02, 7.4100e-02, 7.3300e-02, 7.2500e-02, 7.1700e-02, 7.0900e-02, 7.0200e-02, 6.9400e-02, 6.8700e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5200e-02, 6.4500e-02, 6.3800e-02, 6.3200e-02, 6.2500e-02, 6.1900e-02, 6.1300e-02, 6.0700e-02, 6.0100e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7800e-02, 5.7200e-02, 5.6700e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2100e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0200e-02, 4.9700e-02, 4.9300e-02, 4.8900e-02, 4.8400e-02, 4.8000e-02, 4.7600e-02, 4.7200e-02, 4.6800e-02, 4.6400e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4400e-02, 4.4000e-02, 4.3700e-02, 4.3300e-02, 4.3000e-02, 4.2600e-02, 4.2300e-02, 4.1900e-02, 4.1600e-02, 4.1200e-02, 4.0900e-02, 4.0600e-02, 4.0200e-02, 3.9900e-02}); + } + break; + case 64: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.4000e+01, 6.3611e+01, 6.2555e+01, 6.1078e+01, 5.9416e+01, 5.7703e+01, 5.5988e+01, 5.4278e+01, 5.2571e+01, 5.0873e+01, 4.9195e+01, 4.7550e+01, 4.5952e+01, 4.4412e+01, 4.2936e+01, 4.1529e+01, 4.0191e+01, 3.8919e+01, 3.7709e+01, 3.6559e+01, 3.5462e+01, 3.4415e+01, 3.3412e+01, 3.2452e+01, 3.1529e+01, 3.0643e+01, 2.9791e+01, 2.8971e+01, 2.8183e+01, 2.7425e+01, 2.6697e+01, 2.5999e+01, 2.5330e+01, 2.4690e+01, 2.4078e+01, 2.3494e+01, 2.2937e+01, 2.2407e+01, 2.1903e+01, 2.1424e+01, 2.0969e+01, 2.0538e+01, 2.0128e+01, 1.9740e+01, 1.9372e+01, 1.9022e+01, 1.8689e+01, 1.8373e+01, 1.8072e+01, 1.7785e+01, 1.7511e+01, 1.7248e+01, 1.6995e+01, 1.6753e+01, 1.6518e+01, 1.6292e+01, 1.6072e+01, 1.5858e+01, 1.5650e+01, 1.5446e+01, 1.5246e+01, 1.5050e+01, 1.4857e+01, 1.4666e+01, 1.4478e+01, 1.4292e+01, 1.4107e+01, 1.3924e+01, 1.3742e+01, 1.3560e+01, 1.3380e+01, 1.3201e+01, 1.3023e+01, 1.2846e+01, 1.2669e+01, 1.2494e+01, 1.2319e+01, 1.2146e+01, 1.1973e+01, 1.1801e+01, 1.1630e+01, 1.1462e+01, 1.1294e+01, 1.1127e+01, 1.0962e+01, 1.0799e+01, 1.0638e+01, 1.0479e+01, 1.0321e+01, 1.0165e+01, 1.0012e+01, 9.8615e+00, 9.7125e+00, 9.5656e+00, 9.4213e+00, 9.2801e+00, 9.1417e+00, 9.0054e+00, 8.8711e+00, 8.7395e+00, 8.6112e+00, 8.4862e+00, 8.3638e+00, 8.2435e+00, 8.1254e+00, 8.0103e+00, 7.8987e+00, 7.7904e+00, 7.6846e+00, 7.5808e+00, 7.4790e+00, 7.3800e+00, 7.2845e+00, 7.1923e+00, 7.1027e+00, 7.0149e+00, 6.9287e+00, 6.8447e+00, 6.7637e+00, 6.6860e+00, 6.6111e+00, 6.5381e+00, 6.4664e+00, 6.3960e+00, 6.3276e+00, 6.2620e+00, 6.1994e+00, 6.1390e+00, 6.0802e+00, 6.0224e+00, 5.9653e+00, 5.9096e+00, 5.8563e+00, 5.8056e+00, 5.7569e+00, 5.7097e+00, 5.6633e+00, 5.6172e+00, 5.5716e+00, 5.5274e+00, 5.4853e+00, 5.4454e+00, 5.4069e+00, 5.3694e+00, 5.3322e+00, 5.2950e+00, 5.2578e+00, 5.2216e+00, 5.1872e+00, 5.1546e+00, 5.1231e+00, 5.0923e+00, 5.0618e+00, 5.0311e+00, 5.0001e+00, 4.9690e+00, 4.9391e+00, 4.9109e+00, 4.8839e+00, 4.8574e+00, 4.8313e+00, 4.8052e+00, 4.7788e+00, 4.7517e+00, 4.7244e+00, 4.6979e+00, 4.6728e+00, 4.6489e+00, 4.6253e+00, 4.6018e+00, 4.5784e+00, 4.5547e+00, 4.5303e+00, 4.5052e+00, 4.4800e+00, 4.4560e+00, 4.4333e+00, 4.4112e+00, 4.3891e+00, 4.3670e+00, 4.3448e+00, 4.3225e+00, 4.2994e+00, 4.2753e+00, 4.2510e+00, 4.2276e+00, 4.2056e+00, 4.1843e+00, 4.1629e+00, 4.1413e+00, 4.1196e+00, 4.0981e+00, 4.0761e+00, 4.0531e+00, 4.0292e+00, 4.0054e+00, 3.9828e+00, 3.9615e+00, 3.9407e+00, 3.9195e+00, 3.8980e+00, 3.8766e+00, 3.8554e+00, 3.8340e+00, 3.8116e+00, 3.7882e+00, 3.7644e+00, 3.7415e+00, 3.7201e+00, 3.6997e+00, 3.6792e+00, 3.6581e+00, 3.6368e+00, 3.6158e+00, 3.5951e+00, 3.5741e+00, 3.5521e+00, 3.5290e+00, 3.5056e+00, 3.4831e+00, 3.4622e+00, 3.4424e+00, 3.4227e+00, 3.4023e+00, 3.3815e+00, 3.3610e+00, 3.3409e+00, 3.3210e+00, 3.3005e+00, 3.2788e+00, 3.2562e+00, 3.2337e+00, 3.2125e+00, 3.1929e+00, 3.1743e+00, 3.1555e+00, 3.1362e+00, 3.1164e+00, 3.0968e+00, 3.0778e+00, 3.0592e+00}); + feg = Vctr_cpu({1.5276e+01, 1.4884e+01, 1.3835e+01, 1.2431e+01, 1.0972e+01, 9.6455e+00, 8.5224e+00, 7.5979e+00, 6.8382e+00, 6.2059e+00, 5.6696e+00, 5.2062e+00, 4.7996e+00, 4.4385e+00, 4.1153e+00, 3.8244e+00, 3.5615e+00, 3.3234e+00, 3.1073e+00, 2.9109e+00, 2.7321e+00, 2.5690e+00, 2.4201e+00, 2.2838e+00, 2.1587e+00, 2.0438e+00, 1.9379e+00, 1.8401e+00, 1.7495e+00, 1.6654e+00, 1.5872e+00, 1.5143e+00, 1.4461e+00, 1.3823e+00, 1.3225e+00, 1.2662e+00, 1.2133e+00, 1.1634e+00, 1.1164e+00, 1.0719e+00, 1.0299e+00, 9.9010e-01, 9.5240e-01, 9.1660e-01, 8.8270e-01, 8.5060e-01, 8.2000e-01, 7.9100e-01, 7.6330e-01, 7.3710e-01, 7.1210e-01, 6.8830e-01, 6.6570e-01, 6.4410e-01, 6.2350e-01, 6.0390e-01, 5.8520e-01, 5.6740e-01, 5.5040e-01, 5.3410e-01, 5.1860e-01, 5.0380e-01, 4.8960e-01, 4.7600e-01, 4.6300e-01, 4.5050e-01, 4.3860e-01, 4.2720e-01, 4.1620e-01, 4.0570e-01, 3.9560e-01, 3.8590e-01, 3.7660e-01, 3.6760e-01, 3.5900e-01, 3.5060e-01, 3.4260e-01, 3.3490e-01, 3.2750e-01, 3.2030e-01, 3.1330e-01, 3.0660e-01, 3.0020e-01, 2.9390e-01, 2.8780e-01, 2.8200e-01, 2.7630e-01, 2.7080e-01, 2.6540e-01, 2.6030e-01, 2.5520e-01, 2.5040e-01, 2.4560e-01, 2.4100e-01, 2.3650e-01, 2.3220e-01, 2.2790e-01, 2.2380e-01, 2.1980e-01, 2.1590e-01, 2.1210e-01, 2.0840e-01, 2.0480e-01, 2.0130e-01, 1.9780e-01, 1.9450e-01, 1.9120e-01, 1.8800e-01, 1.8490e-01, 1.8180e-01, 1.7890e-01, 1.7600e-01, 1.7310e-01, 1.7040e-01, 1.6770e-01, 1.6500e-01, 1.6240e-01, 1.5990e-01, 1.5740e-01, 1.5500e-01, 1.5260e-01, 1.5030e-01, 1.4800e-01, 1.4580e-01, 1.4360e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3340e-01, 1.3150e-01, 1.2960e-01, 1.2780e-01, 1.2600e-01, 1.2420e-01, 1.2250e-01, 1.2080e-01, 1.1910e-01, 1.1750e-01, 1.1590e-01, 1.1430e-01, 1.1280e-01, 1.1130e-01, 1.0980e-01, 1.0830e-01, 1.0690e-01, 1.0550e-01, 1.0420e-01, 1.0280e-01, 1.0150e-01, 1.0020e-01, 9.8900e-02, 9.7700e-02, 9.6500e-02, 9.5300e-02, 9.4100e-02, 9.2900e-02, 9.1800e-02, 9.0700e-02, 8.9600e-02, 8.8500e-02, 8.7500e-02, 8.6400e-02, 8.5400e-02, 8.4400e-02, 8.3400e-02, 8.2400e-02, 8.1500e-02, 8.0600e-02, 7.9600e-02, 7.8700e-02, 7.7800e-02, 7.7000e-02, 7.6100e-02, 7.5300e-02, 7.4500e-02, 7.3600e-02, 7.2800e-02, 7.2000e-02, 7.1300e-02, 7.0500e-02, 6.9800e-02, 6.9000e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6200e-02, 6.5500e-02, 6.4800e-02, 6.4200e-02, 6.3500e-02, 6.2900e-02, 6.2200e-02, 6.1600e-02, 6.1000e-02, 6.0400e-02, 5.9800e-02, 5.9200e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.7000e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3400e-02, 5.2900e-02, 5.2400e-02, 5.1900e-02, 5.1400e-02, 5.1000e-02, 5.0500e-02, 5.0100e-02, 4.9600e-02, 4.9200e-02, 4.8700e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5100e-02, 4.4700e-02, 4.4300e-02, 4.4000e-02, 4.3600e-02, 4.3200e-02, 4.2900e-02, 4.2500e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1200e-02, 4.0800e-02, 4.0500e-02}); + } + break; + case 65: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.5000e+01, 6.4622e+01, 6.3603e+01, 6.2200e+01, 6.0632e+01, 5.9011e+01, 5.7362e+01, 5.5684e+01, 5.3978e+01, 5.2256e+01, 5.0539e+01, 4.8846e+01, 4.7196e+01, 4.5602e+01, 4.4074e+01, 4.2616e+01, 4.1227e+01, 3.9907e+01, 3.8651e+01, 3.7456e+01, 3.6317e+01, 3.5229e+01, 3.4188e+01, 3.3191e+01, 3.2233e+01, 3.1314e+01, 3.0431e+01, 2.9582e+01, 2.8766e+01, 2.7983e+01, 2.7231e+01, 2.6510e+01, 2.5819e+01, 2.5158e+01, 2.4527e+01, 2.3925e+01, 2.3351e+01, 2.2804e+01, 2.2285e+01, 2.1791e+01, 2.1322e+01, 2.0877e+01, 2.0455e+01, 2.0054e+01, 1.9675e+01, 1.9314e+01, 1.8972e+01, 1.8647e+01, 1.8337e+01, 1.8043e+01, 1.7761e+01, 1.7492e+01, 1.7234e+01, 1.6987e+01, 1.6748e+01, 1.6518e+01, 1.6296e+01, 1.6080e+01, 1.5870e+01, 1.5665e+01, 1.5464e+01, 1.5268e+01, 1.5075e+01, 1.4885e+01, 1.4698e+01, 1.4513e+01, 1.4330e+01, 1.4148e+01, 1.3968e+01, 1.3790e+01, 1.3612e+01, 1.3435e+01, 1.3260e+01, 1.3085e+01, 1.2911e+01, 1.2737e+01, 1.2565e+01, 1.2394e+01, 1.2223e+01, 1.2053e+01, 1.1885e+01, 1.1718e+01, 1.1552e+01, 1.1386e+01, 1.1223e+01, 1.1061e+01, 1.0900e+01, 1.0741e+01, 1.0583e+01, 1.0428e+01, 1.0274e+01, 1.0123e+01, 9.9736e+00, 9.8256e+00, 9.6802e+00, 9.5376e+00, 9.3977e+00, 9.2596e+00, 9.1233e+00, 8.9894e+00, 8.8588e+00, 8.7313e+00, 8.6064e+00, 8.4832e+00, 8.3621e+00, 8.2438e+00, 8.1290e+00, 8.0175e+00, 7.9084e+00, 7.8011e+00, 7.6957e+00, 7.5930e+00, 7.4939e+00, 7.3980e+00, 7.3046e+00, 7.2130e+00, 7.1230e+00, 7.0352e+00, 6.9504e+00, 6.8689e+00, 6.7902e+00, 6.7134e+00, 6.6380e+00, 6.5639e+00, 6.4918e+00, 6.4227e+00, 6.3564e+00, 6.2925e+00, 6.2302e+00, 6.1690e+00, 6.1087e+00, 6.0498e+00, 5.9933e+00, 5.9395e+00, 5.8877e+00, 5.8375e+00, 5.7882e+00, 5.7394e+00, 5.6913e+00, 5.6445e+00, 5.6000e+00, 5.5576e+00, 5.5167e+00, 5.4767e+00, 5.4374e+00, 5.3983e+00, 5.3593e+00, 5.3213e+00, 5.2851e+00, 5.2508e+00, 5.2175e+00, 5.1850e+00, 5.1529e+00, 5.1210e+00, 5.0888e+00, 5.0567e+00, 5.0257e+00, 4.9965e+00, 4.9684e+00, 4.9408e+00, 4.9136e+00, 4.8866e+00, 4.8596e+00, 4.8321e+00, 4.8043e+00, 4.7774e+00, 4.7519e+00, 4.7275e+00, 4.7033e+00, 4.6792e+00, 4.6553e+00, 4.6315e+00, 4.6072e+00, 4.5820e+00, 4.5569e+00, 4.5330e+00, 4.5103e+00, 4.4881e+00, 4.4658e+00, 4.4433e+00, 4.4212e+00, 4.3990e+00, 4.3763e+00, 4.3525e+00, 4.3286e+00, 4.3056e+00, 4.2839e+00, 4.2628e+00, 4.2414e+00, 4.2197e+00, 4.1981e+00, 4.1768e+00, 4.1553e+00, 4.1329e+00, 4.1095e+00, 4.0862e+00, 4.0641e+00, 4.0432e+00, 4.0226e+00, 4.0015e+00, 3.9800e+00, 3.9587e+00, 3.9378e+00, 3.9168e+00, 3.8950e+00, 3.8721e+00, 3.8489e+00, 3.8265e+00, 3.8055e+00, 3.7854e+00, 3.7650e+00, 3.7439e+00, 3.7226e+00, 3.7016e+00, 3.6812e+00, 3.6606e+00, 3.6391e+00, 3.6164e+00, 3.5935e+00, 3.5714e+00, 3.5508e+00, 3.5312e+00, 3.5115e+00, 3.4911e+00, 3.4702e+00, 3.4496e+00, 3.4296e+00, 3.4098e+00, 3.3896e+00, 3.3682e+00, 3.3459e+00, 3.3238e+00, 3.3027e+00, 3.2832e+00, 3.2646e+00, 3.2458e+00, 3.2262e+00, 3.2061e+00, 3.1864e+00, 3.1672e+00, 3.1486e+00}); + feg = Vctr_cpu({1.4910e+01, 1.4486e+01, 1.3370e+01, 1.1914e+01, 1.0453e+01, 9.1739e+00, 8.1248e+00, 7.2807e+00, 6.5950e+00, 6.0248e+00, 5.5378e+00, 5.1125e+00, 4.7347e+00, 4.3954e+00, 4.0884e+00, 3.8097e+00, 3.5561e+00, 3.3249e+00, 3.1141e+00, 2.9217e+00, 2.7459e+00, 2.5851e+00, 2.4378e+00, 2.3027e+00, 2.1784e+00, 2.0639e+00, 1.9583e+00, 1.8605e+00, 1.7698e+00, 1.6855e+00, 1.6070e+00, 1.5338e+00, 1.4652e+00, 1.4010e+00, 1.3407e+00, 1.2840e+00, 1.2306e+00, 1.1803e+00, 1.1328e+00, 1.0879e+00, 1.0454e+00, 1.0051e+00, 9.6700e-01, 9.3090e-01, 8.9650e-01, 8.6390e-01, 8.3300e-01, 8.0360e-01, 7.7560e-01, 7.4890e-01, 7.2360e-01, 6.9940e-01, 6.7650e-01, 6.5450e-01, 6.3370e-01, 6.1370e-01, 5.9470e-01, 5.7660e-01, 5.5930e-01, 5.4270e-01, 5.2690e-01, 5.1180e-01, 4.9740e-01, 4.8350e-01, 4.7030e-01, 4.5760e-01, 4.4540e-01, 4.3380e-01, 4.2260e-01, 4.1190e-01, 4.0160e-01, 3.9170e-01, 3.8220e-01, 3.7310e-01, 3.6430e-01, 3.5580e-01, 3.4760e-01, 3.3980e-01, 3.3220e-01, 3.2490e-01, 3.1780e-01, 3.1100e-01, 3.0440e-01, 2.9800e-01, 2.9190e-01, 2.8590e-01, 2.8010e-01, 2.7450e-01, 2.6910e-01, 2.6380e-01, 2.5870e-01, 2.5380e-01, 2.4900e-01, 2.4430e-01, 2.3970e-01, 2.3530e-01, 2.3100e-01, 2.2690e-01, 2.2280e-01, 2.1880e-01, 2.1500e-01, 2.1120e-01, 2.0760e-01, 2.0400e-01, 2.0050e-01, 1.9710e-01, 1.9380e-01, 1.9060e-01, 1.8740e-01, 1.8440e-01, 1.8140e-01, 1.7840e-01, 1.7560e-01, 1.7270e-01, 1.7000e-01, 1.6730e-01, 1.6470e-01, 1.6220e-01, 1.5960e-01, 1.5720e-01, 1.5480e-01, 1.5240e-01, 1.5020e-01, 1.4790e-01, 1.4570e-01, 1.4360e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3340e-01, 1.3150e-01, 1.2970e-01, 1.2790e-01, 1.2610e-01, 1.2430e-01, 1.2260e-01, 1.2090e-01, 1.1930e-01, 1.1760e-01, 1.1610e-01, 1.1450e-01, 1.1300e-01, 1.1150e-01, 1.1000e-01, 1.0860e-01, 1.0710e-01, 1.0580e-01, 1.0440e-01, 1.0310e-01, 1.0170e-01, 1.0050e-01, 9.9200e-02, 9.8000e-02, 9.6700e-02, 9.5500e-02, 9.4400e-02, 9.3200e-02, 9.2100e-02, 9.1000e-02, 8.9900e-02, 8.8800e-02, 8.7800e-02, 8.6700e-02, 8.5700e-02, 8.4700e-02, 8.3700e-02, 8.2800e-02, 8.1800e-02, 8.0900e-02, 8.0000e-02, 7.9100e-02, 7.8200e-02, 7.7300e-02, 7.6400e-02, 7.5600e-02, 7.4800e-02, 7.4000e-02, 7.3200e-02, 7.2400e-02, 7.1600e-02, 7.0800e-02, 7.0100e-02, 6.9300e-02, 6.8600e-02, 6.7900e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5200e-02, 6.4500e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1300e-02, 6.0700e-02, 6.0100e-02, 5.9600e-02, 5.9000e-02, 5.8400e-02, 5.7900e-02, 5.7300e-02, 5.6800e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1300e-02, 5.0800e-02, 5.0400e-02, 4.9900e-02, 4.9500e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4300e-02, 4.3900e-02, 4.3500e-02, 4.3200e-02, 4.2800e-02, 4.2500e-02, 4.2100e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02}); + } + break; + case 66: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.6000e+01, 6.5629e+01, 6.4628e+01, 6.3242e+01, 6.1689e+01, 6.0077e+01, 5.8434e+01, 5.6760e+01, 5.5055e+01, 5.3331e+01, 5.1605e+01, 4.9900e+01, 4.8233e+01, 4.6618e+01, 4.5066e+01, 4.3580e+01, 4.2163e+01, 4.0813e+01, 3.9528e+01, 3.8303e+01, 3.7135e+01, 3.6020e+01, 3.4952e+01, 3.3929e+01, 3.2947e+01, 3.2004e+01, 3.1098e+01, 3.0227e+01, 2.9390e+01, 2.8586e+01, 2.7814e+01, 2.7073e+01, 2.6363e+01, 2.5683e+01, 2.5033e+01, 2.4412e+01, 2.3819e+01, 2.3254e+01, 2.2717e+01, 2.2206e+01, 2.1720e+01, 2.1258e+01, 2.0820e+01, 2.0405e+01, 2.0010e+01, 1.9636e+01, 1.9281e+01, 1.8944e+01, 1.8623e+01, 1.8317e+01, 1.8026e+01, 1.7749e+01, 1.7483e+01, 1.7228e+01, 1.6984e+01, 1.6749e+01, 1.6521e+01, 1.6302e+01, 1.6089e+01, 1.5882e+01, 1.5680e+01, 1.5483e+01, 1.5289e+01, 1.5100e+01, 1.4913e+01, 1.4729e+01, 1.4547e+01, 1.4368e+01, 1.4190e+01, 1.4014e+01, 1.3838e+01, 1.3665e+01, 1.3492e+01, 1.3320e+01, 1.3149e+01, 1.2978e+01, 1.2809e+01, 1.2640e+01, 1.2472e+01, 1.2305e+01, 1.2139e+01, 1.1974e+01, 1.1810e+01, 1.1646e+01, 1.1484e+01, 1.1324e+01, 1.1165e+01, 1.1007e+01, 1.0850e+01, 1.0694e+01, 1.0541e+01, 1.0390e+01, 1.0240e+01, 1.0092e+01, 9.9455e+00, 9.8020e+00, 9.6608e+00, 9.5213e+00, 9.3833e+00, 9.2476e+00, 9.1149e+00, 8.9852e+00, 8.8578e+00, 8.7321e+00, 8.6082e+00, 8.4870e+00, 8.3692e+00, 8.2544e+00, 8.1420e+00, 8.0313e+00, 7.9225e+00, 7.8163e+00, 7.7135e+00, 7.6139e+00, 7.5167e+00, 7.4213e+00, 7.3275e+00, 7.2358e+00, 7.1472e+00, 7.0618e+00, 6.9791e+00, 6.8985e+00, 6.8192e+00, 6.7413e+00, 6.6654e+00, 6.5925e+00, 6.5225e+00, 6.4549e+00, 6.3889e+00, 6.3241e+00, 6.2603e+00, 6.1980e+00, 6.1381e+00, 6.0809e+00, 6.0260e+00, 5.9725e+00, 5.9201e+00, 5.8684e+00, 5.8173e+00, 5.7678e+00, 5.7205e+00, 5.6754e+00, 5.6319e+00, 5.5895e+00, 5.5477e+00, 5.5063e+00, 5.4651e+00, 5.4250e+00, 5.3868e+00, 5.3505e+00, 5.3154e+00, 5.2811e+00, 5.2473e+00, 5.2138e+00, 5.1801e+00, 5.1466e+00, 5.1143e+00, 5.0837e+00, 5.0544e+00, 5.0257e+00, 4.9974e+00, 4.9695e+00, 4.9416e+00, 4.9132e+00, 4.8847e+00, 4.8571e+00, 4.8310e+00, 4.8059e+00, 4.7812e+00, 4.7566e+00, 4.7323e+00, 4.7081e+00, 4.6834e+00, 4.6580e+00, 4.6328e+00, 4.6086e+00, 4.5858e+00, 4.5635e+00, 4.5411e+00, 4.5186e+00, 4.4965e+00, 4.4744e+00, 4.4516e+00, 4.4280e+00, 4.4042e+00, 4.3814e+00, 4.3599e+00, 4.3389e+00, 4.3178e+00, 4.2963e+00, 4.2749e+00, 4.2539e+00, 4.2327e+00, 4.2105e+00, 4.1875e+00, 4.1645e+00, 4.1427e+00, 4.1221e+00, 4.1018e+00, 4.0811e+00, 4.0600e+00, 4.0390e+00, 4.0184e+00, 3.9978e+00, 3.9763e+00, 3.9538e+00, 3.9310e+00, 3.9090e+00, 3.8883e+00, 3.8685e+00, 3.8484e+00, 3.8277e+00, 3.8067e+00, 3.7861e+00, 3.7659e+00, 3.7456e+00, 3.7244e+00, 3.7021e+00, 3.6795e+00, 3.6577e+00, 3.6373e+00, 3.6180e+00, 3.5985e+00, 3.5783e+00, 3.5576e+00, 3.5372e+00, 3.5174e+00, 3.4978e+00, 3.4777e+00, 3.4565e+00, 3.4345e+00, 3.4125e+00, 3.3916e+00, 3.3722e+00, 3.3536e+00, 3.3349e+00, 3.3153e+00, 3.2954e+00, 3.2757e+00, 3.2566e+00, 3.2379e+00}); + feg = Vctr_cpu({1.4617e+01, 1.4211e+01, 1.3138e+01, 1.1734e+01, 1.0318e+01, 9.0729e+00, 8.0478e+00, 7.2211e+00, 6.5488e+00, 5.9896e+00, 5.5122e+00, 5.0953e+00, 4.7247e+00, 4.3917e+00, 4.0901e+00, 3.8158e+00, 3.5657e+00, 3.3374e+00, 3.1288e+00, 2.9380e+00, 2.7633e+00, 2.6033e+00, 2.4565e+00, 2.3216e+00, 2.1974e+00, 2.0829e+00, 1.9771e+00, 1.8791e+00, 1.7882e+00, 1.7036e+00, 1.6248e+00, 1.5512e+00, 1.4823e+00, 1.4177e+00, 1.3571e+00, 1.3001e+00, 1.2463e+00, 1.1957e+00, 1.1478e+00, 1.1026e+00, 1.0598e+00, 1.0192e+00, 9.8080e-01, 9.4430e-01, 9.0970e-01, 8.7680e-01, 8.4550e-01, 8.1570e-01, 7.8740e-01, 7.6050e-01, 7.3480e-01, 7.1040e-01, 6.8710e-01, 6.6490e-01, 6.4370e-01, 6.2350e-01, 6.0420e-01, 5.8580e-01, 5.6820e-01, 5.5130e-01, 5.3530e-01, 5.1990e-01, 5.0520e-01, 4.9110e-01, 4.7760e-01, 4.6470e-01, 4.5230e-01, 4.4050e-01, 4.2910e-01, 4.1810e-01, 4.0760e-01, 3.9760e-01, 3.8790e-01, 3.7860e-01, 3.6960e-01, 3.6100e-01, 3.5260e-01, 3.4460e-01, 3.3690e-01, 3.2950e-01, 3.2230e-01, 3.1530e-01, 3.0860e-01, 3.0210e-01, 2.9590e-01, 2.8980e-01, 2.8390e-01, 2.7820e-01, 2.7270e-01, 2.6740e-01, 2.6220e-01, 2.5720e-01, 2.5230e-01, 2.4750e-01, 2.4290e-01, 2.3850e-01, 2.3410e-01, 2.2990e-01, 2.2570e-01, 2.2170e-01, 2.1780e-01, 2.1400e-01, 2.1030e-01, 2.0670e-01, 2.0320e-01, 1.9980e-01, 1.9640e-01, 1.9310e-01, 1.9000e-01, 1.8680e-01, 1.8380e-01, 1.8080e-01, 1.7790e-01, 1.7510e-01, 1.7230e-01, 1.6960e-01, 1.6700e-01, 1.6440e-01, 1.6190e-01, 1.5940e-01, 1.5700e-01, 1.5460e-01, 1.5230e-01, 1.5000e-01, 1.4780e-01, 1.4560e-01, 1.4350e-01, 1.4140e-01, 1.3930e-01, 1.3730e-01, 1.3540e-01, 1.3340e-01, 1.3160e-01, 1.2970e-01, 1.2790e-01, 1.2610e-01, 1.2440e-01, 1.2270e-01, 1.2100e-01, 1.1940e-01, 1.1780e-01, 1.1620e-01, 1.1460e-01, 1.1310e-01, 1.1160e-01, 1.1020e-01, 1.0870e-01, 1.0730e-01, 1.0600e-01, 1.0460e-01, 1.0330e-01, 1.0200e-01, 1.0070e-01, 9.9400e-02, 9.8200e-02, 9.7000e-02, 9.5800e-02, 9.4600e-02, 9.3500e-02, 9.2400e-02, 9.1300e-02, 9.0200e-02, 8.9100e-02, 8.8000e-02, 8.7000e-02, 8.6000e-02, 8.5000e-02, 8.4000e-02, 8.3100e-02, 8.2100e-02, 8.1200e-02, 8.0300e-02, 7.9400e-02, 7.8500e-02, 7.7600e-02, 7.6800e-02, 7.5900e-02, 7.5100e-02, 7.4300e-02, 7.3500e-02, 7.2700e-02, 7.1900e-02, 7.1200e-02, 7.0400e-02, 6.9700e-02, 6.8900e-02, 6.8200e-02, 6.7500e-02, 6.6800e-02, 6.6100e-02, 6.5500e-02, 6.4800e-02, 6.4200e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1700e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8700e-02, 5.8200e-02, 5.7600e-02, 5.7100e-02, 5.6500e-02, 5.6000e-02, 5.5500e-02, 5.5000e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2000e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0200e-02, 4.9800e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7200e-02, 4.6800e-02, 4.6400e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4200e-02, 4.3800e-02, 4.3500e-02, 4.3100e-02, 4.2700e-02, 4.2400e-02, 4.2100e-02, 4.1700e-02}); + } + break; + case 67: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.7000e+01, 6.6636e+01, 6.5651e+01, 6.4284e+01, 6.2744e+01, 6.1142e+01, 5.9506e+01, 5.7836e+01, 5.6132e+01, 5.4406e+01, 5.2674e+01, 5.0958e+01, 4.9275e+01, 4.7641e+01, 4.6065e+01, 4.4554e+01, 4.3109e+01, 4.1731e+01, 4.0417e+01, 3.9163e+01, 3.7967e+01, 3.6824e+01, 3.5730e+01, 3.4681e+01, 3.3675e+01, 3.2709e+01, 3.1780e+01, 3.0887e+01, 3.0029e+01, 2.9204e+01, 2.8412e+01, 2.7651e+01, 2.6921e+01, 2.6222e+01, 2.5552e+01, 2.4912e+01, 2.4301e+01, 2.3718e+01, 2.3163e+01, 2.2634e+01, 2.2130e+01, 2.1652e+01, 2.1198e+01, 2.0767e+01, 2.0357e+01, 1.9969e+01, 1.9600e+01, 1.9250e+01, 1.8917e+01, 1.8600e+01, 1.8299e+01, 1.8011e+01, 1.7737e+01, 1.7474e+01, 1.7223e+01, 1.6981e+01, 1.6749e+01, 1.6525e+01, 1.6308e+01, 1.6098e+01, 1.5893e+01, 1.5694e+01, 1.5500e+01, 1.5310e+01, 1.5123e+01, 1.4940e+01, 1.4759e+01, 1.4581e+01, 1.4404e+01, 1.4230e+01, 1.4057e+01, 1.3885e+01, 1.3715e+01, 1.3546e+01, 1.3377e+01, 1.3210e+01, 1.3043e+01, 1.2877e+01, 1.2712e+01, 1.2547e+01, 1.2384e+01, 1.2222e+01, 1.2060e+01, 1.1898e+01, 1.1738e+01, 1.1579e+01, 1.1422e+01, 1.1265e+01, 1.1109e+01, 1.0955e+01, 1.0803e+01, 1.0652e+01, 1.0502e+01, 1.0354e+01, 1.0207e+01, 1.0063e+01, 9.9211e+00, 9.7807e+00, 9.6416e+00, 9.5046e+00, 9.3703e+00, 9.2388e+00, 9.1094e+00, 8.9816e+00, 8.8555e+00, 8.7319e+00, 8.6114e+00, 8.4939e+00, 8.3786e+00, 8.2649e+00, 8.1529e+00, 8.0436e+00, 7.9375e+00, 7.8344e+00, 7.7338e+00, 7.6349e+00, 7.5375e+00, 7.4422e+00, 7.3499e+00, 7.2608e+00, 7.1744e+00, 7.0900e+00, 7.0070e+00, 6.9254e+00, 6.8458e+00, 6.7692e+00, 6.6955e+00, 6.6242e+00, 6.5547e+00, 6.4863e+00, 6.4189e+00, 6.3532e+00, 6.2899e+00, 6.2294e+00, 6.1711e+00, 6.1144e+00, 6.0588e+00, 6.0039e+00, 5.9499e+00, 5.8974e+00, 5.8473e+00, 5.7994e+00, 5.7532e+00, 5.7081e+00, 5.6638e+00, 5.6199e+00, 5.5763e+00, 5.5340e+00, 5.4936e+00, 5.4551e+00, 5.4180e+00, 5.3817e+00, 5.3460e+00, 5.3107e+00, 5.2753e+00, 5.2402e+00, 5.2063e+00, 5.1743e+00, 5.1436e+00, 5.1136e+00, 5.0840e+00, 5.0549e+00, 5.0259e+00, 4.9965e+00, 4.9670e+00, 4.9385e+00, 4.9116e+00, 4.8857e+00, 4.8603e+00, 4.8351e+00, 4.8102e+00, 4.7855e+00, 4.7603e+00, 4.7345e+00, 4.7088e+00, 4.6844e+00, 4.6612e+00, 4.6386e+00, 4.6160e+00, 4.5935e+00, 4.5712e+00, 4.5490e+00, 4.5262e+00, 4.5026e+00, 4.4788e+00, 4.4560e+00, 4.4345e+00, 4.4137e+00, 4.3926e+00, 4.3713e+00, 4.3502e+00, 4.3293e+00, 4.3083e+00, 4.2863e+00, 4.2635e+00, 4.2409e+00, 4.2193e+00, 4.1990e+00, 4.1790e+00, 4.1586e+00, 4.1378e+00, 4.1171e+00, 4.0969e+00, 4.0765e+00, 4.0554e+00, 4.0332e+00, 4.0108e+00, 3.9891e+00, 3.9688e+00, 3.9492e+00, 3.9295e+00, 3.9091e+00, 3.8885e+00, 3.8682e+00, 3.8484e+00, 3.8283e+00, 3.8074e+00, 3.7855e+00, 3.7632e+00, 3.7418e+00, 3.7217e+00, 3.7025e+00, 3.6833e+00, 3.6633e+00, 3.6429e+00, 3.6228e+00, 3.6032e+00, 3.5838e+00, 3.5639e+00, 3.5430e+00, 3.5212e+00, 3.4994e+00, 3.4787e+00, 3.4595e+00, 3.4410e+00, 3.4224e+00, 3.4030e+00, 3.3831e+00, 3.3635e+00, 3.3445e+00, 3.3259e+00}); + feg = Vctr_cpu({1.4334e+01, 1.3944e+01, 1.2913e+01, 1.1558e+01, 1.0186e+01, 8.9737e+00, 7.9719e+00, 7.1621e+00, 6.5027e+00, 5.9542e+00, 5.4859e+00, 5.0770e+00, 4.7136e+00, 4.3866e+00, 4.0902e+00, 3.8202e+00, 3.5737e+00, 3.3483e+00, 3.1419e+00, 2.9528e+00, 2.7794e+00, 2.6203e+00, 2.4741e+00, 2.3395e+00, 2.2155e+00, 2.1010e+00, 1.9951e+00, 1.8970e+00, 1.8058e+00, 1.7210e+00, 1.6419e+00, 1.5680e+00, 1.4988e+00, 1.4339e+00, 1.3730e+00, 1.3157e+00, 1.2617e+00, 1.2107e+00, 1.1625e+00, 1.1170e+00, 1.0739e+00, 1.0330e+00, 9.9430e-01, 9.5750e-01, 9.2260e-01, 8.8940e-01, 8.5780e-01, 8.2780e-01, 7.9920e-01, 7.7190e-01, 7.4600e-01, 7.2120e-01, 6.9770e-01, 6.7520e-01, 6.5370e-01, 6.3320e-01, 6.1360e-01, 5.9490e-01, 5.7700e-01, 5.6000e-01, 5.4360e-01, 5.2800e-01, 5.1300e-01, 4.9870e-01, 4.8500e-01, 4.7190e-01, 4.5930e-01, 4.4720e-01, 4.3560e-01, 4.2440e-01, 4.1380e-01, 4.0350e-01, 3.9360e-01, 3.8410e-01, 3.7500e-01, 3.6620e-01, 3.5770e-01, 3.4960e-01, 3.4170e-01, 3.3410e-01, 3.2680e-01, 3.1970e-01, 3.1290e-01, 3.0630e-01, 2.9990e-01, 2.9370e-01, 2.8780e-01, 2.8200e-01, 2.7640e-01, 2.7090e-01, 2.6570e-01, 2.6060e-01, 2.5560e-01, 2.5080e-01, 2.4610e-01, 2.4160e-01, 2.3720e-01, 2.3290e-01, 2.2870e-01, 2.2460e-01, 2.2070e-01, 2.1680e-01, 2.1310e-01, 2.0940e-01, 2.0590e-01, 2.0240e-01, 1.9900e-01, 1.9570e-01, 1.9250e-01, 1.8930e-01, 1.8620e-01, 1.8320e-01, 1.8030e-01, 1.7740e-01, 1.7460e-01, 1.7190e-01, 1.6920e-01, 1.6660e-01, 1.6410e-01, 1.6150e-01, 1.5910e-01, 1.5670e-01, 1.5440e-01, 1.5210e-01, 1.4980e-01, 1.4760e-01, 1.4550e-01, 1.4330e-01, 1.4130e-01, 1.3930e-01, 1.3730e-01, 1.3530e-01, 1.3340e-01, 1.3160e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2440e-01, 1.2280e-01, 1.2110e-01, 1.1950e-01, 1.1790e-01, 1.1630e-01, 1.1480e-01, 1.1330e-01, 1.1180e-01, 1.1030e-01, 1.0890e-01, 1.0750e-01, 1.0620e-01, 1.0480e-01, 1.0350e-01, 1.0220e-01, 1.0090e-01, 9.9700e-02, 9.8400e-02, 9.7200e-02, 9.6100e-02, 9.4900e-02, 9.3700e-02, 9.2600e-02, 9.1500e-02, 9.0400e-02, 8.9400e-02, 8.8300e-02, 8.7300e-02, 8.6300e-02, 8.5300e-02, 8.4300e-02, 8.3300e-02, 8.2400e-02, 8.1500e-02, 8.0600e-02, 7.9700e-02, 7.8800e-02, 7.7900e-02, 7.7100e-02, 7.6200e-02, 7.5400e-02, 7.4600e-02, 7.3800e-02, 7.3000e-02, 7.2200e-02, 7.1500e-02, 7.0700e-02, 7.0000e-02, 6.9300e-02, 6.8500e-02, 6.7800e-02, 6.7100e-02, 6.6500e-02, 6.5800e-02, 6.5100e-02, 6.4500e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1400e-02, 6.0800e-02, 6.0200e-02, 5.9600e-02, 5.9000e-02, 5.8500e-02, 5.7900e-02, 5.7400e-02, 5.6800e-02, 5.6300e-02, 5.5800e-02, 5.5300e-02, 5.4800e-02, 5.4300e-02, 5.3800e-02, 5.3300e-02, 5.2800e-02, 5.2300e-02, 5.1900e-02, 5.1400e-02, 5.1000e-02, 5.0500e-02, 5.0100e-02, 4.9600e-02, 4.9200e-02, 4.8800e-02, 4.8400e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3400e-02, 4.3000e-02, 4.2700e-02, 4.2300e-02}); + } + break; + case 68: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.8000e+01, 6.7644e+01, 6.6676e+01, 6.5326e+01, 6.3799e+01, 6.2206e+01, 6.0577e+01, 5.8912e+01, 5.7211e+01, 5.5484e+01, 5.3748e+01, 5.2023e+01, 5.0327e+01, 4.8675e+01, 4.7079e+01, 4.5544e+01, 4.4073e+01, 4.2667e+01, 4.1325e+01, 4.0044e+01, 3.8820e+01, 3.7650e+01, 3.6529e+01, 3.5455e+01, 3.4424e+01, 3.3433e+01, 3.2482e+01, 3.1566e+01, 3.0686e+01, 2.9840e+01, 2.9027e+01, 2.8246e+01, 2.7496e+01, 2.6777e+01, 2.6088e+01, 2.5429e+01, 2.4799e+01, 2.4197e+01, 2.3623e+01, 2.3076e+01, 2.2556e+01, 2.2060e+01, 2.1589e+01, 2.1142e+01, 2.0717e+01, 2.0313e+01, 1.9930e+01, 1.9566e+01, 1.9221e+01, 1.8892e+01, 1.8579e+01, 1.8282e+01, 1.7997e+01, 1.7726e+01, 1.7467e+01, 1.7218e+01, 1.6980e+01, 1.6750e+01, 1.6528e+01, 1.6314e+01, 1.6107e+01, 1.5905e+01, 1.5709e+01, 1.5517e+01, 1.5329e+01, 1.5146e+01, 1.4965e+01, 1.4787e+01, 1.4612e+01, 1.4439e+01, 1.4268e+01, 1.4098e+01, 1.3930e+01, 1.3762e+01, 1.3597e+01, 1.3432e+01, 1.3268e+01, 1.3104e+01, 1.2942e+01, 1.2780e+01, 1.2619e+01, 1.2459e+01, 1.2299e+01, 1.2140e+01, 1.1983e+01, 1.1826e+01, 1.1669e+01, 1.1514e+01, 1.1361e+01, 1.1208e+01, 1.1056e+01, 1.0906e+01, 1.0757e+01, 1.0609e+01, 1.0464e+01, 1.0319e+01, 1.0176e+01, 1.0035e+01, 9.8959e+00, 9.7592e+00, 9.6241e+00, 9.4904e+00, 9.3584e+00, 9.2288e+00, 9.1021e+00, 8.9777e+00, 8.8551e+00, 8.7340e+00, 8.6150e+00, 8.4987e+00, 8.3854e+00, 8.2746e+00, 8.1658e+00, 8.0585e+00, 7.9531e+00, 7.8504e+00, 7.7508e+00, 7.6540e+00, 7.5593e+00, 7.4661e+00, 7.3745e+00, 7.2851e+00, 7.1984e+00, 7.1148e+00, 7.0337e+00, 6.9542e+00, 6.8761e+00, 6.7994e+00, 6.7247e+00, 6.6525e+00, 6.5832e+00, 6.5163e+00, 6.4507e+00, 6.3863e+00, 6.3230e+00, 6.2611e+00, 6.2012e+00, 6.1439e+00, 6.0890e+00, 6.0355e+00, 5.9830e+00, 5.9312e+00, 5.8804e+00, 5.8306e+00, 5.7827e+00, 5.7370e+00, 5.6932e+00, 5.6506e+00, 5.6085e+00, 5.5669e+00, 5.5259e+00, 5.4856e+00, 5.4464e+00, 5.4091e+00, 5.3737e+00, 5.3393e+00, 5.3052e+00, 5.2714e+00, 5.2379e+00, 5.2047e+00, 5.1720e+00, 5.1402e+00, 5.1100e+00, 5.0814e+00, 5.0534e+00, 5.0253e+00, 4.9971e+00, 4.9692e+00, 4.9415e+00, 4.9138e+00, 4.8866e+00, 4.8606e+00, 4.8360e+00, 4.8122e+00, 4.7883e+00, 4.7639e+00, 4.7396e+00, 4.7154e+00, 4.6912e+00, 4.6668e+00, 4.6427e+00, 4.6198e+00, 4.5982e+00, 4.5770e+00, 4.5554e+00, 4.5333e+00, 4.5110e+00, 4.4890e+00, 4.4669e+00, 4.4444e+00, 4.4217e+00, 4.3998e+00, 4.3792e+00, 4.3594e+00, 4.3395e+00, 4.3188e+00, 4.2976e+00, 4.2764e+00, 4.2555e+00, 4.2344e+00, 4.2128e+00, 4.1909e+00, 4.1697e+00, 4.1497e+00, 4.1307e+00, 4.1115e+00, 4.0914e+00, 4.0706e+00, 4.0498e+00, 4.0294e+00, 4.0090e+00, 3.9881e+00, 3.9666e+00, 3.9452e+00, 3.9247e+00, 3.9055e+00, 3.8869e+00, 3.8679e+00, 3.8479e+00, 3.8273e+00, 3.8067e+00, 3.7866e+00, 3.7667e+00, 3.7462e+00, 3.7251e+00, 3.7038e+00, 3.6832e+00, 3.6639e+00, 3.6456e+00, 3.6274e+00, 3.6083e+00, 3.5882e+00, 3.5678e+00, 3.5477e+00, 3.5282e+00, 3.5088e+00, 3.4887e+00, 3.4680e+00, 3.4471e+00, 3.4270e+00, 3.4082e+00}); + feg = Vctr_cpu({1.4017e+01, 1.3651e+01, 1.2675e+01, 1.1379e+01, 1.0054e+01, 8.8750e+00, 7.8962e+00, 7.1024e+00, 6.4553e+00, 5.9169e+00, 5.4575e+00, 5.0563e+00, 4.6997e+00, 4.3788e+00, 4.0875e+00, 3.8220e+00, 3.5791e+00, 3.3567e+00, 3.1527e+00, 2.9655e+00, 2.7935e+00, 2.6355e+00, 2.4900e+00, 2.3559e+00, 2.2322e+00, 2.1179e+00, 2.0120e+00, 1.9138e+00, 1.8226e+00, 1.7376e+00, 1.6583e+00, 1.5841e+00, 1.5147e+00, 1.4496e+00, 1.3884e+00, 1.3308e+00, 1.2765e+00, 1.2253e+00, 1.1768e+00, 1.1310e+00, 1.0877e+00, 1.0465e+00, 1.0075e+00, 9.7050e-01, 9.3530e-01, 9.0180e-01, 8.6990e-01, 8.3960e-01, 8.1070e-01, 7.8320e-01, 7.5700e-01, 7.3200e-01, 7.0810e-01, 6.8540e-01, 6.6360e-01, 6.4290e-01, 6.2300e-01, 6.0410e-01, 5.8590e-01, 5.6860e-01, 5.5200e-01, 5.3610e-01, 5.2090e-01, 5.0640e-01, 4.9240e-01, 4.7910e-01, 4.6620e-01, 4.5390e-01, 4.4210e-01, 4.3080e-01, 4.1990e-01, 4.0950e-01, 3.9940e-01, 3.8970e-01, 3.8040e-01, 3.7150e-01, 3.6290e-01, 3.5460e-01, 3.4650e-01, 3.3880e-01, 3.3140e-01, 3.2420e-01, 3.1720e-01, 3.1050e-01, 3.0400e-01, 2.9770e-01, 2.9170e-01, 2.8580e-01, 2.8010e-01, 2.7460e-01, 2.6920e-01, 2.6400e-01, 2.5900e-01, 2.5410e-01, 2.4940e-01, 2.4470e-01, 2.4030e-01, 2.3590e-01, 2.3170e-01, 2.2760e-01, 2.2350e-01, 2.1960e-01, 2.1580e-01, 2.1210e-01, 2.0850e-01, 2.0500e-01, 2.0160e-01, 1.9820e-01, 1.9500e-01, 1.9180e-01, 1.8870e-01, 1.8560e-01, 1.8270e-01, 1.7980e-01, 1.7690e-01, 1.7420e-01, 1.7150e-01, 1.6880e-01, 1.6620e-01, 1.6370e-01, 1.6120e-01, 1.5880e-01, 1.5640e-01, 1.5410e-01, 1.5180e-01, 1.4960e-01, 1.4740e-01, 1.4530e-01, 1.4320e-01, 1.4120e-01, 1.3920e-01, 1.3720e-01, 1.3530e-01, 1.3340e-01, 1.3150e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2280e-01, 1.2120e-01, 1.1960e-01, 1.1800e-01, 1.1640e-01, 1.1490e-01, 1.1340e-01, 1.1190e-01, 1.1050e-01, 1.0910e-01, 1.0770e-01, 1.0630e-01, 1.0500e-01, 1.0370e-01, 1.0240e-01, 1.0110e-01, 9.9900e-02, 9.8700e-02, 9.7500e-02, 9.6300e-02, 9.5100e-02, 9.4000e-02, 9.2900e-02, 9.1800e-02, 9.0700e-02, 8.9600e-02, 8.8600e-02, 8.7600e-02, 8.6500e-02, 8.5600e-02, 8.4600e-02, 8.3600e-02, 8.2700e-02, 8.1800e-02, 8.0800e-02, 8.0000e-02, 7.9100e-02, 7.8200e-02, 7.7400e-02, 7.6500e-02, 7.5700e-02, 7.4900e-02, 7.4100e-02, 7.3300e-02, 7.2500e-02, 7.1800e-02, 7.1000e-02, 7.0300e-02, 6.9500e-02, 6.8800e-02, 6.8100e-02, 6.7400e-02, 6.6800e-02, 6.6100e-02, 6.5400e-02, 6.4800e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1700e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4600e-02, 5.4100e-02, 5.3600e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0800e-02, 5.0300e-02, 4.9900e-02, 4.9500e-02, 4.9100e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5500e-02, 4.5100e-02, 4.4700e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3300e-02, 4.2900e-02}); + } + break; + case 69: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.9000e+01, 6.8650e+01, 6.7698e+01, 6.6365e+01, 6.4852e+01, 6.3269e+01, 6.1647e+01, 5.9988e+01, 5.8290e+01, 5.6563e+01, 5.4823e+01, 5.3090e+01, 5.1382e+01, 4.9714e+01, 4.8097e+01, 4.6540e+01, 4.5044e+01, 4.3613e+01, 4.2244e+01, 4.0935e+01, 3.9684e+01, 3.8487e+01, 3.7340e+01, 3.6240e+01, 3.5185e+01, 3.4171e+01, 3.3196e+01, 3.2259e+01, 3.1357e+01, 3.0490e+01, 2.9656e+01, 2.8854e+01, 2.8084e+01, 2.7346e+01, 2.6638e+01, 2.5959e+01, 2.5310e+01, 2.4690e+01, 2.4098e+01, 2.3532e+01, 2.2994e+01, 2.2481e+01, 2.1993e+01, 2.1529e+01, 2.1088e+01, 2.0670e+01, 2.0272e+01, 1.9894e+01, 1.9535e+01, 1.9193e+01, 1.8869e+01, 1.8560e+01, 1.8266e+01, 1.7985e+01, 1.7717e+01, 1.7460e+01, 1.7214e+01, 1.6978e+01, 1.6751e+01, 1.6532e+01, 1.6320e+01, 1.6115e+01, 1.5916e+01, 1.5722e+01, 1.5533e+01, 1.5348e+01, 1.5167e+01, 1.4989e+01, 1.4815e+01, 1.4642e+01, 1.4472e+01, 1.4304e+01, 1.4137e+01, 1.3972e+01, 1.3808e+01, 1.3646e+01, 1.3484e+01, 1.3323e+01, 1.3163e+01, 1.3004e+01, 1.2845e+01, 1.2688e+01, 1.2530e+01, 1.2374e+01, 1.2219e+01, 1.2064e+01, 1.1910e+01, 1.1757e+01, 1.1604e+01, 1.1454e+01, 1.1303e+01, 1.1154e+01, 1.1006e+01, 1.0859e+01, 1.0714e+01, 1.0570e+01, 1.0428e+01, 1.0286e+01, 1.0147e+01, 1.0010e+01, 9.8742e+00, 9.7397e+00, 9.6067e+00, 9.4760e+00, 9.3479e+00, 9.2220e+00, 9.0976e+00, 8.9747e+00, 8.8537e+00, 8.7352e+00, 8.6196e+00, 8.5064e+00, 8.3949e+00, 8.2850e+00, 8.1769e+00, 8.0713e+00, 7.9687e+00, 7.8689e+00, 7.7710e+00, 7.6747e+00, 7.5799e+00, 7.4871e+00, 7.3972e+00, 7.3102e+00, 7.2257e+00, 7.1428e+00, 7.0613e+00, 6.9812e+00, 6.9031e+00, 6.8275e+00, 6.7548e+00, 6.6844e+00, 6.6155e+00, 6.5478e+00, 6.4812e+00, 6.4161e+00, 6.3530e+00, 6.2925e+00, 6.2344e+00, 6.1779e+00, 6.1223e+00, 6.0676e+00, 6.0139e+00, 5.9613e+00, 5.9106e+00, 5.8622e+00, 5.8158e+00, 5.7706e+00, 5.7260e+00, 5.6820e+00, 5.6387e+00, 5.5961e+00, 5.5548e+00, 5.5153e+00, 5.4778e+00, 5.4415e+00, 5.4055e+00, 5.3698e+00, 5.3346e+00, 5.2998e+00, 5.2654e+00, 5.2321e+00, 5.2005e+00, 5.1705e+00, 5.1411e+00, 5.1118e+00, 5.0825e+00, 5.0534e+00, 5.0247e+00, 4.9960e+00, 4.9678e+00, 4.9410e+00, 4.9156e+00, 4.8910e+00, 4.8664e+00, 4.8414e+00, 4.8164e+00, 4.7917e+00, 4.7670e+00, 4.7422e+00, 4.7177e+00, 4.6944e+00, 4.6725e+00, 4.6510e+00, 4.6292e+00, 4.6069e+00, 4.5845e+00, 4.5623e+00, 4.5401e+00, 4.5176e+00, 4.4949e+00, 4.4730e+00, 4.4524e+00, 4.4327e+00, 4.4128e+00, 4.3922e+00, 4.3711e+00, 4.3501e+00, 4.3294e+00, 4.3085e+00, 4.2870e+00, 4.2654e+00, 4.2444e+00, 4.2247e+00, 4.2058e+00, 4.1869e+00, 4.1671e+00, 4.1466e+00, 4.1261e+00, 4.1059e+00, 4.0858e+00, 4.0653e+00, 4.0441e+00, 4.0230e+00, 4.0028e+00, 3.9839e+00, 3.9656e+00, 3.9469e+00, 3.9272e+00, 3.9069e+00, 3.8867e+00, 3.8669e+00, 3.8472e+00, 3.8271e+00, 3.8063e+00, 3.7853e+00, 3.7650e+00, 3.7459e+00, 3.7279e+00, 3.7099e+00, 3.6911e+00, 3.6713e+00, 3.6511e+00, 3.6313e+00, 3.6120e+00, 3.5927e+00, 3.5729e+00, 3.5524e+00, 3.5318e+00, 3.5118e+00, 3.4932e+00}); + feg = Vctr_cpu({1.3756e+01, 1.3403e+01, 1.2463e+01, 1.1212e+01, 9.9270e+00, 8.7783e+00, 7.8213e+00, 7.0433e+00, 6.4083e+00, 5.8797e+00, 5.4288e+00, 5.0351e+00, 4.6851e+00, 4.3700e+00, 4.0839e+00, 3.8226e+00, 3.5834e+00, 3.3639e+00, 3.1623e+00, 2.9770e+00, 2.8065e+00, 2.6496e+00, 2.5049e+00, 2.3714e+00, 2.2481e+00, 2.1340e+00, 2.0282e+00, 1.9300e+00, 1.8386e+00, 1.7535e+00, 1.6741e+00, 1.5997e+00, 1.5301e+00, 1.4647e+00, 1.4033e+00, 1.3455e+00, 1.2909e+00, 1.2394e+00, 1.1908e+00, 1.1447e+00, 1.1011e+00, 1.0597e+00, 1.0204e+00, 9.8310e-01, 9.4770e-01, 9.1400e-01, 8.8180e-01, 8.5130e-01, 8.2210e-01, 7.9440e-01, 7.6790e-01, 7.4260e-01, 7.1850e-01, 6.9550e-01, 6.7350e-01, 6.5250e-01, 6.3240e-01, 6.1310e-01, 5.9480e-01, 5.7720e-01, 5.6040e-01, 5.4430e-01, 5.2880e-01, 5.1400e-01, 4.9990e-01, 4.8630e-01, 4.7320e-01, 4.6070e-01, 4.4870e-01, 4.3720e-01, 4.2610e-01, 4.1550e-01, 4.0530e-01, 3.9540e-01, 3.8600e-01, 3.7680e-01, 3.6810e-01, 3.5960e-01, 3.5140e-01, 3.4360e-01, 3.3600e-01, 3.2870e-01, 3.2160e-01, 3.1480e-01, 3.0820e-01, 3.0180e-01, 2.9560e-01, 2.8960e-01, 2.8380e-01, 2.7820e-01, 2.7280e-01, 2.6750e-01, 2.6240e-01, 2.5740e-01, 2.5260e-01, 2.4790e-01, 2.4340e-01, 2.3900e-01, 2.3470e-01, 2.3050e-01, 2.2640e-01, 2.2250e-01, 2.1860e-01, 2.1490e-01, 2.1120e-01, 2.0760e-01, 2.0420e-01, 2.0080e-01, 1.9750e-01, 1.9420e-01, 1.9110e-01, 1.8800e-01, 1.8500e-01, 1.8210e-01, 1.7920e-01, 1.7640e-01, 1.7370e-01, 1.7100e-01, 1.6840e-01, 1.6580e-01, 1.6330e-01, 1.6090e-01, 1.5850e-01, 1.5610e-01, 1.5380e-01, 1.5160e-01, 1.4940e-01, 1.4720e-01, 1.4510e-01, 1.4310e-01, 1.4100e-01, 1.3910e-01, 1.3710e-01, 1.3520e-01, 1.3330e-01, 1.3150e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2280e-01, 1.2120e-01, 1.1960e-01, 1.1800e-01, 1.1650e-01, 1.1500e-01, 1.1350e-01, 1.1210e-01, 1.1060e-01, 1.0920e-01, 1.0780e-01, 1.0650e-01, 1.0520e-01, 1.0390e-01, 1.0260e-01, 1.0130e-01, 1.0010e-01, 9.8900e-02, 9.7700e-02, 9.6500e-02, 9.5300e-02, 9.4200e-02, 9.3100e-02, 9.2000e-02, 9.0900e-02, 8.9900e-02, 8.8800e-02, 8.7800e-02, 8.6800e-02, 8.5800e-02, 8.4800e-02, 8.3900e-02, 8.3000e-02, 8.2000e-02, 8.1100e-02, 8.0200e-02, 7.9300e-02, 7.8500e-02, 7.7600e-02, 7.6800e-02, 7.6000e-02, 7.5200e-02, 7.4400e-02, 7.3600e-02, 7.2800e-02, 7.2000e-02, 7.1300e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8400e-02, 6.7700e-02, 6.7100e-02, 6.6400e-02, 6.5700e-02, 6.5100e-02, 6.4400e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1400e-02, 6.0800e-02, 6.0200e-02, 5.9600e-02, 5.9100e-02, 5.8500e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5300e-02, 5.4800e-02, 5.4300e-02, 5.3900e-02, 5.3400e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1500e-02, 5.1100e-02, 5.0600e-02, 5.0200e-02, 4.9800e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4300e-02, 4.3900e-02, 4.3600e-02}); + } + break; + case 70: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.0000e+01, 6.9660e+01, 6.8728e+01, 6.7410e+01, 6.5907e+01, 6.4332e+01, 6.2717e+01, 6.1062e+01, 5.9367e+01, 5.7642e+01, 5.5901e+01, 5.4161e+01, 5.2442e+01, 5.0760e+01, 4.9125e+01, 4.7546e+01, 4.6027e+01, 4.4571e+01, 4.3176e+01, 4.1841e+01, 4.0563e+01, 3.9340e+01, 3.8167e+01, 3.7042e+01, 3.5962e+01, 3.4925e+01, 3.3927e+01, 3.2967e+01, 3.2043e+01, 3.1155e+01, 3.0300e+01, 2.9478e+01, 2.8688e+01, 2.7930e+01, 2.7202e+01, 2.6504e+01, 2.5836e+01, 2.5197e+01, 2.4586e+01, 2.4003e+01, 2.3446e+01, 2.2916e+01, 2.2411e+01, 2.1930e+01, 2.1473e+01, 2.1038e+01, 2.0625e+01, 2.0233e+01, 1.9860e+01, 1.9505e+01, 1.9168e+01, 1.8847e+01, 1.8542e+01, 1.8251e+01, 1.7973e+01, 1.7708e+01, 1.7454e+01, 1.7211e+01, 1.6977e+01, 1.6753e+01, 1.6536e+01, 1.6326e+01, 1.6124e+01, 1.5927e+01, 1.5736e+01, 1.5549e+01, 1.5367e+01, 1.5188e+01, 1.5013e+01, 1.4841e+01, 1.4671e+01, 1.4504e+01, 1.4338e+01, 1.4174e+01, 1.4012e+01, 1.3852e+01, 1.3692e+01, 1.3533e+01, 1.3376e+01, 1.3219e+01, 1.3063e+01, 1.2907e+01, 1.2753e+01, 1.2599e+01, 1.2446e+01, 1.2293e+01, 1.2142e+01, 1.1991e+01, 1.1841e+01, 1.1691e+01, 1.1542e+01, 1.1395e+01, 1.1248e+01, 1.1103e+01, 1.0959e+01, 1.0815e+01, 1.0673e+01, 1.0533e+01, 1.0394e+01, 1.0256e+01, 1.0120e+01, 9.9853e+00, 9.8523e+00, 9.7211e+00, 9.5917e+00, 9.4642e+00, 9.3385e+00, 9.2145e+00, 9.0923e+00, 8.9721e+00, 8.8543e+00, 8.7387e+00, 8.6250e+00, 8.5129e+00, 8.4028e+00, 8.2950e+00, 8.1896e+00, 8.0866e+00, 7.9856e+00, 7.8865e+00, 7.7891e+00, 7.6936e+00, 7.6007e+00, 7.5104e+00, 7.4223e+00, 7.3360e+00, 7.2513e+00, 7.1683e+00, 7.0872e+00, 7.0085e+00, 6.9324e+00, 6.8584e+00, 6.7860e+00, 6.7149e+00, 6.6452e+00, 6.5772e+00, 6.5113e+00, 6.4477e+00, 6.3862e+00, 6.3263e+00, 6.2676e+00, 6.2097e+00, 6.1531e+00, 6.0981e+00, 6.0451e+00, 5.9939e+00, 5.9445e+00, 5.8964e+00, 5.8490e+00, 5.8022e+00, 5.7562e+00, 5.7117e+00, 5.6688e+00, 5.6273e+00, 5.5874e+00, 5.5486e+00, 5.5105e+00, 5.4725e+00, 5.4348e+00, 5.3982e+00, 5.3628e+00, 5.3286e+00, 5.2955e+00, 5.2636e+00, 5.2326e+00, 5.2017e+00, 5.1706e+00, 5.1396e+00, 5.1095e+00, 5.0804e+00, 5.0521e+00, 5.0245e+00, 4.9979e+00, 4.9722e+00, 4.9466e+00, 4.9205e+00, 4.8941e+00, 4.8681e+00, 4.8429e+00, 4.8184e+00, 4.7944e+00, 4.7709e+00, 4.7481e+00, 4.7260e+00, 4.7038e+00, 4.6808e+00, 4.6573e+00, 4.6341e+00, 4.6118e+00, 4.5900e+00, 4.5683e+00, 4.5468e+00, 4.5260e+00, 4.5060e+00, 4.4859e+00, 4.4651e+00, 4.4435e+00, 4.4217e+00, 4.4004e+00, 4.3798e+00, 4.3595e+00, 4.3392e+00, 4.3189e+00, 4.2992e+00, 4.2803e+00, 4.2613e+00, 4.2415e+00, 4.2207e+00, 4.1996e+00, 4.1790e+00, 4.1591e+00, 4.1395e+00, 4.1198e+00, 4.0999e+00, 4.0804e+00, 4.0616e+00, 4.0433e+00, 4.0246e+00, 4.0048e+00, 3.9841e+00, 3.9633e+00, 3.9432e+00, 3.9239e+00, 3.9047e+00, 3.8853e+00, 3.8656e+00, 3.8463e+00, 3.8276e+00, 3.8096e+00, 3.7915e+00, 3.7724e+00, 3.7521e+00, 3.7314e+00, 3.7112e+00, 3.6918e+00, 3.6730e+00, 3.6542e+00, 3.6350e+00, 3.6156e+00, 3.5966e+00, 3.5784e+00}); + feg = Vctr_cpu({1.3347e+01, 1.3033e+01, 1.2182e+01, 1.1021e+01, 9.7961e+00, 8.6818e+00, 7.7468e+00, 6.9852e+00, 6.3620e+00, 5.8423e+00, 5.3991e+00, 5.0128e+00, 4.6693e+00, 4.3597e+00, 4.0784e+00, 3.8216e+00, 3.5860e+00, 3.3695e+00, 3.1703e+00, 2.9870e+00, 2.8181e+00, 2.6623e+00, 2.5186e+00, 2.3858e+00, 2.2629e+00, 2.1491e+00, 2.0435e+00, 1.9453e+00, 1.8540e+00, 1.7688e+00, 1.6892e+00, 1.6147e+00, 1.5449e+00, 1.4794e+00, 1.4177e+00, 1.3597e+00, 1.3049e+00, 1.2532e+00, 1.2043e+00, 1.1581e+00, 1.1142e+00, 1.0726e+00, 1.0331e+00, 9.9560e-01, 9.5990e-01, 9.2590e-01, 8.9350e-01, 8.6270e-01, 8.3340e-01, 8.0530e-01, 7.7860e-01, 7.5310e-01, 7.2870e-01, 7.0550e-01, 6.8320e-01, 6.6200e-01, 6.4160e-01, 6.2220e-01, 6.0360e-01, 5.8580e-01, 5.6870e-01, 5.5240e-01, 5.3670e-01, 5.2170e-01, 5.0730e-01, 4.9350e-01, 4.8030e-01, 4.6760e-01, 4.5540e-01, 4.4370e-01, 4.3240e-01, 4.2160e-01, 4.1120e-01, 4.0120e-01, 3.9150e-01, 3.8220e-01, 3.7330e-01, 3.6470e-01, 3.5640e-01, 3.4840e-01, 3.4070e-01, 3.3320e-01, 3.2600e-01, 3.1910e-01, 3.1240e-01, 3.0590e-01, 2.9960e-01, 2.9350e-01, 2.8760e-01, 2.8190e-01, 2.7640e-01, 2.7100e-01, 2.6580e-01, 2.6080e-01, 2.5590e-01, 2.5110e-01, 2.4650e-01, 2.4200e-01, 2.3770e-01, 2.3340e-01, 2.2930e-01, 2.2530e-01, 2.2140e-01, 2.1760e-01, 2.1390e-01, 2.1030e-01, 2.0670e-01, 2.0330e-01, 2.0000e-01, 1.9670e-01, 1.9350e-01, 1.9040e-01, 1.8740e-01, 1.8440e-01, 1.8150e-01, 1.7870e-01, 1.7590e-01, 1.7320e-01, 1.7060e-01, 1.6800e-01, 1.6540e-01, 1.6300e-01, 1.6050e-01, 1.5820e-01, 1.5580e-01, 1.5360e-01, 1.5140e-01, 1.4920e-01, 1.4700e-01, 1.4500e-01, 1.4290e-01, 1.4090e-01, 1.3890e-01, 1.3700e-01, 1.3510e-01, 1.3330e-01, 1.3140e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2290e-01, 1.2130e-01, 1.1970e-01, 1.1810e-01, 1.1660e-01, 1.1510e-01, 1.1360e-01, 1.1220e-01, 1.1070e-01, 1.0930e-01, 1.0800e-01, 1.0660e-01, 1.0530e-01, 1.0400e-01, 1.0270e-01, 1.0150e-01, 1.0020e-01, 9.9000e-02, 9.7900e-02, 9.6700e-02, 9.5500e-02, 9.4400e-02, 9.3300e-02, 9.2200e-02, 9.1100e-02, 9.0100e-02, 8.9100e-02, 8.8000e-02, 8.7000e-02, 8.6100e-02, 8.5100e-02, 8.4100e-02, 8.3200e-02, 8.2300e-02, 8.1400e-02, 8.0500e-02, 7.9600e-02, 7.8800e-02, 7.7900e-02, 7.7100e-02, 7.6200e-02, 7.5400e-02, 7.4600e-02, 7.3900e-02, 7.3100e-02, 7.2300e-02, 7.1600e-02, 7.0800e-02, 7.0100e-02, 6.9400e-02, 6.8700e-02, 6.8000e-02, 6.7300e-02, 6.6700e-02, 6.6000e-02, 6.5300e-02, 6.4700e-02, 6.4100e-02, 6.3500e-02, 6.2800e-02, 6.2200e-02, 6.1600e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4600e-02, 5.4100e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1800e-02, 5.1300e-02, 5.0900e-02, 5.0500e-02, 5.0000e-02, 4.9600e-02, 4.9200e-02, 4.8800e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6800e-02, 4.6400e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4900e-02, 4.4500e-02, 4.4200e-02}); + } + break; + case 71: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.1000e+01, 7.0660e+01, 6.9718e+01, 6.8363e+01, 6.6794e+01, 6.5146e+01, 6.3476e+01, 6.1794e+01, 6.0099e+01, 5.8392e+01, 5.6680e+01, 5.4972e+01, 5.3280e+01, 5.1618e+01, 4.9997e+01, 4.8424e+01, 4.6904e+01, 4.5442e+01, 4.4037e+01, 4.2689e+01, 4.1396e+01, 4.0157e+01, 3.8968e+01, 3.7828e+01, 3.6731e+01, 3.5678e+01, 3.4664e+01, 3.3689e+01, 3.2750e+01, 3.1846e+01, 3.0976e+01, 3.0139e+01, 2.9332e+01, 2.8557e+01, 2.7813e+01, 2.7098e+01, 2.6412e+01, 2.5755e+01, 2.5126e+01, 2.4524e+01, 2.3949e+01, 2.3400e+01, 2.2876e+01, 2.2377e+01, 2.1901e+01, 2.1449e+01, 2.1018e+01, 2.0608e+01, 2.0219e+01, 1.9849e+01, 1.9496e+01, 1.9161e+01, 1.8842e+01, 1.8538e+01, 1.8249e+01, 1.7972e+01, 1.7709e+01, 1.7456e+01, 1.7214e+01, 1.6982e+01, 1.6758e+01, 1.6543e+01, 1.6335e+01, 1.6134e+01, 1.5939e+01, 1.5749e+01, 1.5565e+01, 1.5384e+01, 1.5208e+01, 1.5036e+01, 1.4866e+01, 1.4699e+01, 1.4534e+01, 1.4372e+01, 1.4211e+01, 1.4052e+01, 1.3894e+01, 1.3738e+01, 1.3583e+01, 1.3429e+01, 1.3275e+01, 1.3123e+01, 1.2971e+01, 1.2820e+01, 1.2669e+01, 1.2519e+01, 1.2370e+01, 1.2222e+01, 1.2074e+01, 1.1926e+01, 1.1780e+01, 1.1634e+01, 1.1490e+01, 1.1346e+01, 1.1203e+01, 1.1061e+01, 1.0920e+01, 1.0781e+01, 1.0642e+01, 1.0505e+01, 1.0369e+01, 1.0235e+01, 1.0101e+01, 9.9698e+00, 9.8399e+00, 9.7117e+00, 9.5849e+00, 9.4598e+00, 9.3364e+00, 9.2150e+00, 9.0956e+00, 8.9781e+00, 8.8623e+00, 8.7483e+00, 8.6360e+00, 8.5259e+00, 8.4182e+00, 8.3127e+00, 8.2090e+00, 8.1069e+00, 8.0066e+00, 7.9084e+00, 7.8127e+00, 7.7194e+00, 7.6281e+00, 7.5385e+00, 7.4504e+00, 7.3641e+00, 7.2799e+00, 7.1982e+00, 7.1189e+00, 7.0415e+00, 6.9655e+00, 6.8909e+00, 6.8178e+00, 6.7466e+00, 6.6777e+00, 6.6111e+00, 6.5465e+00, 6.4832e+00, 6.4209e+00, 6.3597e+00, 6.3000e+00, 6.2422e+00, 6.1865e+00, 6.1327e+00, 6.0805e+00, 6.0293e+00, 5.9788e+00, 5.9289e+00, 5.8803e+00, 5.8334e+00, 5.7882e+00, 5.7448e+00, 5.7027e+00, 5.6615e+00, 5.6207e+00, 5.5801e+00, 5.5402e+00, 5.5015e+00, 5.4644e+00, 5.4287e+00, 5.3942e+00, 5.3608e+00, 5.3278e+00, 5.2948e+00, 5.2617e+00, 5.2291e+00, 5.1976e+00, 5.1673e+00, 5.1382e+00, 5.1099e+00, 5.0825e+00, 5.0556e+00, 5.0284e+00, 5.0008e+00, 4.9731e+00, 4.9462e+00, 4.9204e+00, 4.8954e+00, 4.8711e+00, 4.8475e+00, 4.8246e+00, 4.8017e+00, 4.7783e+00, 4.7542e+00, 4.7301e+00, 4.7066e+00, 4.6840e+00, 4.6620e+00, 4.6406e+00, 4.6195e+00, 4.5991e+00, 4.5788e+00, 4.5581e+00, 4.5365e+00, 4.5143e+00, 4.4923e+00, 4.4712e+00, 4.4508e+00, 4.4308e+00, 4.4109e+00, 4.3914e+00, 4.3724e+00, 4.3536e+00, 4.3341e+00, 4.3136e+00, 4.2925e+00, 4.2715e+00, 4.2512e+00, 4.2317e+00, 4.2125e+00, 4.1933e+00, 4.1743e+00, 4.1557e+00, 4.1376e+00, 4.1192e+00, 4.1000e+00, 4.0796e+00, 4.0588e+00, 4.0384e+00, 4.0188e+00, 3.9999e+00, 3.9811e+00, 3.9623e+00, 3.9435e+00, 3.9251e+00, 3.9073e+00, 3.8894e+00, 3.8708e+00, 3.8509e+00, 3.8303e+00, 3.8098e+00, 3.7903e+00, 3.7715e+00, 3.7531e+00, 3.7346e+00, 3.7159e+00, 3.6974e+00, 3.6794e+00, 3.6619e+00}); + feg = Vctr_cpu({1.3293e+01, 1.3021e+01, 1.2273e+01, 1.1221e+01, 1.0066e+01, 8.9665e+00, 8.0036e+00, 7.1948e+00, 6.5227e+00, 5.9605e+00, 5.4836e+00, 5.0726e+00, 4.7123e+00, 4.3917e+00, 4.1035e+00, 3.8423e+00, 3.6044e+00, 3.3866e+00, 3.1868e+00, 3.0031e+00, 2.8341e+00, 2.6782e+00, 2.5343e+00, 2.4013e+00, 2.2783e+00, 2.1642e+00, 2.0583e+00, 1.9599e+00, 1.8683e+00, 1.7828e+00, 1.7030e+00, 1.6282e+00, 1.5582e+00, 1.4925e+00, 1.4306e+00, 1.3724e+00, 1.3175e+00, 1.2656e+00, 1.2166e+00, 1.1701e+00, 1.1261e+00, 1.0844e+00, 1.0447e+00, 1.0070e+00, 9.7120e-01, 9.3700e-01, 9.0450e-01, 8.7360e-01, 8.4400e-01, 8.1580e-01, 7.8890e-01, 7.6320e-01, 7.3870e-01, 7.1520e-01, 6.9270e-01, 6.7130e-01, 6.5070e-01, 6.3110e-01, 6.1230e-01, 5.9420e-01, 5.7700e-01, 5.6040e-01, 5.4460e-01, 5.2940e-01, 5.1480e-01, 5.0080e-01, 4.8730e-01, 4.7440e-01, 4.6200e-01, 4.5010e-01, 4.3870e-01, 4.2770e-01, 4.1710e-01, 4.0690e-01, 3.9710e-01, 3.8770e-01, 3.7860e-01, 3.6980e-01, 3.6140e-01, 3.5320e-01, 3.4540e-01, 3.3780e-01, 3.3050e-01, 3.2340e-01, 3.1660e-01, 3.1000e-01, 3.0360e-01, 2.9740e-01, 2.9140e-01, 2.8560e-01, 2.8000e-01, 2.7450e-01, 2.6920e-01, 2.6410e-01, 2.5920e-01, 2.5430e-01, 2.4960e-01, 2.4510e-01, 2.4070e-01, 2.3640e-01, 2.3220e-01, 2.2810e-01, 2.2410e-01, 2.2030e-01, 2.1650e-01, 2.1290e-01, 2.0930e-01, 2.0580e-01, 2.0240e-01, 1.9910e-01, 1.9590e-01, 1.9280e-01, 1.8970e-01, 1.8670e-01, 1.8380e-01, 1.8090e-01, 1.7810e-01, 1.7540e-01, 1.7270e-01, 1.7010e-01, 1.6750e-01, 1.6500e-01, 1.6260e-01, 1.6020e-01, 1.5780e-01, 1.5550e-01, 1.5330e-01, 1.5110e-01, 1.4890e-01, 1.4680e-01, 1.4470e-01, 1.4270e-01, 1.4070e-01, 1.3880e-01, 1.3690e-01, 1.3500e-01, 1.3320e-01, 1.3140e-01, 1.2960e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2290e-01, 1.2130e-01, 1.1970e-01, 1.1810e-01, 1.1660e-01, 1.1510e-01, 1.1370e-01, 1.1220e-01, 1.1080e-01, 1.0940e-01, 1.0810e-01, 1.0670e-01, 1.0540e-01, 1.0410e-01, 1.0290e-01, 1.0160e-01, 1.0040e-01, 9.9200e-02, 9.8000e-02, 9.6900e-02, 9.5700e-02, 9.4600e-02, 9.3500e-02, 9.2400e-02, 9.1400e-02, 9.0300e-02, 8.9300e-02, 8.8300e-02, 8.7300e-02, 8.6300e-02, 8.5300e-02, 8.4400e-02, 8.3400e-02, 8.2500e-02, 8.1600e-02, 8.0700e-02, 7.9900e-02, 7.9000e-02, 7.8200e-02, 7.7300e-02, 7.6500e-02, 7.5700e-02, 7.4900e-02, 7.4100e-02, 7.3400e-02, 7.2600e-02, 7.1900e-02, 7.1100e-02, 7.0400e-02, 6.9700e-02, 6.9000e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6300e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3700e-02, 6.3100e-02, 6.2500e-02, 6.1900e-02, 6.1300e-02, 6.0700e-02, 6.0200e-02, 5.9600e-02, 5.9100e-02, 5.8500e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3400e-02, 5.3000e-02, 5.2500e-02, 5.2100e-02, 5.1600e-02, 5.1200e-02, 5.0700e-02, 5.0300e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5900e-02, 4.5500e-02, 4.5100e-02, 4.4800e-02}); + } + break; + case 72: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.2000e+01, 7.1666e+01, 7.0733e+01, 6.9371e+01, 6.7770e+01, 6.6067e+01, 6.4335e+01, 6.2602e+01, 6.0874e+01, 5.9152e+01, 5.7437e+01, 5.5735e+01, 5.4056e+01, 5.2407e+01, 5.0797e+01, 4.9231e+01, 4.7717e+01, 4.6255e+01, 4.4848e+01, 4.3495e+01, 4.2196e+01, 4.0948e+01, 3.9750e+01, 3.8598e+01, 3.7491e+01, 3.6426e+01, 3.5401e+01, 3.4414e+01, 3.3462e+01, 3.2545e+01, 3.1662e+01, 3.0810e+01, 2.9990e+01, 2.9200e+01, 2.8440e+01, 2.7709e+01, 2.7006e+01, 2.6332e+01, 2.5685e+01, 2.5065e+01, 2.4472e+01, 2.3905e+01, 2.3362e+01, 2.2845e+01, 2.2351e+01, 2.1880e+01, 2.1431e+01, 2.1004e+01, 2.0598e+01, 2.0211e+01, 1.9842e+01, 1.9492e+01, 1.9159e+01, 1.8841e+01, 1.8538e+01, 1.8250e+01, 1.7974e+01, 1.7711e+01, 1.7460e+01, 1.7219e+01, 1.6987e+01, 1.6765e+01, 1.6551e+01, 1.6345e+01, 1.6145e+01, 1.5951e+01, 1.5764e+01, 1.5581e+01, 1.5402e+01, 1.5228e+01, 1.5058e+01, 1.4891e+01, 1.4726e+01, 1.4564e+01, 1.4405e+01, 1.4247e+01, 1.4091e+01, 1.3936e+01, 1.3783e+01, 1.3631e+01, 1.3480e+01, 1.3330e+01, 1.3181e+01, 1.3032e+01, 1.2885e+01, 1.2737e+01, 1.2591e+01, 1.2445e+01, 1.2300e+01, 1.2155e+01, 1.2011e+01, 1.1867e+01, 1.1725e+01, 1.1583e+01, 1.1442e+01, 1.1302e+01, 1.1162e+01, 1.1024e+01, 1.0886e+01, 1.0750e+01, 1.0615e+01, 1.0481e+01, 1.0348e+01, 1.0216e+01, 1.0086e+01, 9.9578e+00, 9.8310e+00, 9.7053e+00, 9.5810e+00, 9.4582e+00, 9.3374e+00, 9.2187e+00, 9.1017e+00, 8.9863e+00, 8.8722e+00, 8.7598e+00, 8.6496e+00, 8.5418e+00, 8.4361e+00, 8.3321e+00, 8.2295e+00, 8.1284e+00, 8.0294e+00, 7.9329e+00, 7.8388e+00, 7.7468e+00, 7.6562e+00, 7.5671e+00, 7.4795e+00, 7.3940e+00, 7.3110e+00, 7.2304e+00, 7.1518e+00, 7.0747e+00, 6.9987e+00, 6.9241e+00, 6.8513e+00, 6.7807e+00, 6.7125e+00, 6.6464e+00, 6.5819e+00, 6.5183e+00, 6.4557e+00, 6.3943e+00, 6.3346e+00, 6.2770e+00, 6.2216e+00, 6.1680e+00, 6.1157e+00, 6.0640e+00, 6.0129e+00, 5.9627e+00, 5.9140e+00, 5.8669e+00, 5.8218e+00, 5.7784e+00, 5.7363e+00, 5.6947e+00, 5.6532e+00, 5.6122e+00, 5.5720e+00, 5.5331e+00, 5.4958e+00, 5.4600e+00, 5.4256e+00, 5.3921e+00, 5.3587e+00, 5.3252e+00, 5.2918e+00, 5.2590e+00, 5.2272e+00, 5.1966e+00, 5.1673e+00, 5.1392e+00, 5.1120e+00, 5.0849e+00, 5.0574e+00, 5.0295e+00, 5.0019e+00, 4.9749e+00, 4.9486e+00, 4.9233e+00, 4.8990e+00, 4.8758e+00, 4.8531e+00, 4.8303e+00, 4.8068e+00, 4.7829e+00, 4.7589e+00, 4.7353e+00, 4.7124e+00, 4.6901e+00, 4.6685e+00, 4.6478e+00, 4.6279e+00, 4.6080e+00, 4.5875e+00, 4.5662e+00, 4.5444e+00, 4.5227e+00, 4.5014e+00, 4.4807e+00, 4.4603e+00, 4.4405e+00, 4.4214e+00, 4.4031e+00, 4.3849e+00, 4.3659e+00, 4.3460e+00, 4.3253e+00, 4.3047e+00, 4.2845e+00, 4.2646e+00, 4.2450e+00, 4.2257e+00, 4.2070e+00, 4.1891e+00, 4.1717e+00, 4.1541e+00, 4.1356e+00, 4.1159e+00, 4.0957e+00, 4.0757e+00, 4.0560e+00, 4.0367e+00, 4.0176e+00, 3.9986e+00, 3.9800e+00, 3.9622e+00, 3.9451e+00, 3.9281e+00, 3.9103e+00, 3.8914e+00, 3.8716e+00, 3.8516e+00, 3.8320e+00, 3.8129e+00, 3.7941e+00, 3.7752e+00, 3.7564e+00, 3.7380e+00}); + feg = Vctr_cpu({1.3045e+01, 1.2803e+01, 1.2134e+01, 1.1185e+01, 1.0124e+01, 9.0886e+00, 8.1535e+00, 7.3446e+00, 6.6571e+00, 6.0742e+00, 5.5768e+00, 5.1474e+00, 4.7719e+00, 4.4396e+00, 4.1427e+00, 3.8751e+00, 3.6324e+00, 3.4113e+00, 3.2091e+00, 3.0237e+00, 2.8533e+00, 2.6963e+00, 2.5516e+00, 2.4179e+00, 2.2942e+00, 2.1796e+00, 2.0732e+00, 1.9744e+00, 1.8823e+00, 1.7965e+00, 1.7163e+00, 1.6413e+00, 1.5710e+00, 1.5050e+00, 1.4430e+00, 1.3846e+00, 1.3295e+00, 1.2774e+00, 1.2282e+00, 1.1817e+00, 1.1375e+00, 1.0956e+00, 1.0559e+00, 1.0180e+00, 9.8210e-01, 9.4780e-01, 9.1520e-01, 8.8400e-01, 8.5430e-01, 8.2600e-01, 7.9890e-01, 7.7310e-01, 7.4830e-01, 7.2470e-01, 7.0210e-01, 6.8040e-01, 6.5970e-01, 6.3990e-01, 6.2090e-01, 6.0260e-01, 5.8520e-01, 5.6840e-01, 5.5240e-01, 5.3700e-01, 5.2220e-01, 5.0800e-01, 4.9440e-01, 4.8130e-01, 4.6870e-01, 4.5660e-01, 4.4500e-01, 4.3380e-01, 4.2310e-01, 4.1270e-01, 4.0280e-01, 3.9320e-01, 3.8390e-01, 3.7500e-01, 3.6640e-01, 3.5810e-01, 3.5010e-01, 3.4240e-01, 3.3500e-01, 3.2780e-01, 3.2080e-01, 3.1410e-01, 3.0760e-01, 3.0130e-01, 2.9520e-01, 2.8930e-01, 2.8360e-01, 2.7810e-01, 2.7270e-01, 2.6750e-01, 2.6250e-01, 2.5750e-01, 2.5280e-01, 2.4820e-01, 2.4370e-01, 2.3930e-01, 2.3510e-01, 2.3090e-01, 2.2690e-01, 2.2300e-01, 2.1920e-01, 2.1550e-01, 2.1190e-01, 2.0840e-01, 2.0490e-01, 2.0160e-01, 1.9830e-01, 1.9510e-01, 1.9200e-01, 1.8900e-01, 1.8600e-01, 1.8310e-01, 1.8030e-01, 1.7750e-01, 1.7480e-01, 1.7220e-01, 1.6960e-01, 1.6710e-01, 1.6460e-01, 1.6220e-01, 1.5980e-01, 1.5750e-01, 1.5520e-01, 1.5300e-01, 1.5080e-01, 1.4870e-01, 1.4660e-01, 1.4450e-01, 1.4250e-01, 1.4060e-01, 1.3860e-01, 1.3670e-01, 1.3490e-01, 1.3310e-01, 1.3130e-01, 1.2950e-01, 1.2780e-01, 1.2610e-01, 1.2450e-01, 1.2290e-01, 1.2130e-01, 1.1970e-01, 1.1820e-01, 1.1670e-01, 1.1520e-01, 1.1370e-01, 1.1230e-01, 1.1090e-01, 1.0950e-01, 1.0820e-01, 1.0690e-01, 1.0560e-01, 1.0430e-01, 1.0300e-01, 1.0180e-01, 1.0060e-01, 9.9400e-02, 9.8200e-02, 9.7000e-02, 9.5900e-02, 9.4800e-02, 9.3700e-02, 9.2600e-02, 9.1500e-02, 9.0500e-02, 8.9500e-02, 8.8500e-02, 8.7500e-02, 8.6500e-02, 8.5500e-02, 8.4600e-02, 8.3700e-02, 8.2800e-02, 8.1900e-02, 8.1000e-02, 8.0100e-02, 7.9200e-02, 7.8400e-02, 7.7600e-02, 7.6800e-02, 7.5900e-02, 7.5200e-02, 7.4400e-02, 7.3600e-02, 7.2900e-02, 7.2100e-02, 7.1400e-02, 7.0700e-02, 6.9900e-02, 6.9200e-02, 6.8500e-02, 6.7900e-02, 6.7200e-02, 6.6500e-02, 6.5900e-02, 6.5300e-02, 6.4600e-02, 6.4000e-02, 6.3400e-02, 6.2800e-02, 6.2200e-02, 6.1600e-02, 6.1000e-02, 6.0400e-02, 5.9900e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2800e-02, 5.2300e-02, 5.1900e-02, 5.1400e-02, 5.1000e-02, 5.0500e-02, 5.0100e-02, 4.9700e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5800e-02, 4.5400e-02}); + } + break; + case 73: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.3000e+01, 7.2673e+01, 7.1751e+01, 7.0386e+01, 6.8755e+01, 6.7002e+01, 6.5213e+01, 6.3427e+01, 6.1656e+01, 5.9905e+01, 5.8175e+01, 5.6470e+01, 5.4793e+01, 5.3150e+01, 5.1548e+01, 4.9991e+01, 4.8483e+01, 4.7025e+01, 4.5620e+01, 4.4267e+01, 4.2966e+01, 4.1715e+01, 4.0511e+01, 3.9353e+01, 3.8239e+01, 3.7166e+01, 3.6132e+01, 3.5136e+01, 3.4175e+01, 3.3247e+01, 3.2352e+01, 3.1489e+01, 3.0656e+01, 2.9853e+01, 2.9079e+01, 2.8333e+01, 2.7615e+01, 2.6925e+01, 2.6262e+01, 2.5625e+01, 2.5014e+01, 2.4429e+01, 2.3869e+01, 2.3333e+01, 2.2821e+01, 2.2332e+01, 2.1866e+01, 2.1421e+01, 2.0997e+01, 2.0593e+01, 2.0208e+01, 1.9842e+01, 1.9493e+01, 1.9161e+01, 1.8845e+01, 1.8543e+01, 1.8255e+01, 1.7981e+01, 1.7718e+01, 1.7467e+01, 1.7227e+01, 1.6997e+01, 1.6775e+01, 1.6562e+01, 1.6357e+01, 1.6158e+01, 1.5966e+01, 1.5779e+01, 1.5598e+01, 1.5422e+01, 1.5249e+01, 1.5081e+01, 1.4916e+01, 1.4754e+01, 1.4595e+01, 1.4437e+01, 1.4282e+01, 1.4129e+01, 1.3977e+01, 1.3827e+01, 1.3678e+01, 1.3530e+01, 1.3383e+01, 1.3238e+01, 1.3092e+01, 1.2947e+01, 1.2803e+01, 1.2660e+01, 1.2518e+01, 1.2375e+01, 1.2233e+01, 1.2092e+01, 1.1952e+01, 1.1813e+01, 1.1673e+01, 1.1535e+01, 1.1397e+01, 1.1261e+01, 1.1125e+01, 1.0989e+01, 1.0855e+01, 1.0722e+01, 1.0590e+01, 1.0459e+01, 1.0330e+01, 1.0201e+01, 1.0074e+01, 9.9480e+00, 9.8234e+00, 9.7004e+00, 9.5790e+00, 9.4591e+00, 9.3407e+00, 9.2238e+00, 9.1085e+00, 8.9950e+00, 8.8834e+00, 8.7736e+00, 8.6655e+00, 8.5590e+00, 8.4542e+00, 8.3512e+00, 8.2503e+00, 8.1515e+00, 8.0546e+00, 7.9593e+00, 7.8656e+00, 7.7735e+00, 7.6836e+00, 7.5958e+00, 7.5101e+00, 7.4263e+00, 7.3441e+00, 7.2632e+00, 7.1839e+00, 7.1065e+00, 7.0313e+00, 6.9583e+00, 6.8871e+00, 6.8174e+00, 6.7488e+00, 6.6815e+00, 6.6157e+00, 6.5519e+00, 6.4900e+00, 6.4302e+00, 6.3719e+00, 6.3148e+00, 6.2585e+00, 6.2031e+00, 6.1490e+00, 6.0967e+00, 6.0463e+00, 5.9976e+00, 5.9503e+00, 5.9039e+00, 5.8581e+00, 5.8128e+00, 5.7684e+00, 5.7253e+00, 5.6839e+00, 5.6440e+00, 5.6055e+00, 5.5680e+00, 5.5309e+00, 5.4941e+00, 5.4575e+00, 5.4215e+00, 5.3866e+00, 5.3532e+00, 5.3212e+00, 5.2902e+00, 5.2599e+00, 5.2300e+00, 5.2001e+00, 5.1700e+00, 5.1401e+00, 5.1109e+00, 5.0829e+00, 5.0561e+00, 5.0303e+00, 5.0051e+00, 4.9804e+00, 4.9557e+00, 4.9306e+00, 4.9052e+00, 4.8798e+00, 4.8550e+00, 4.8312e+00, 4.8085e+00, 4.7865e+00, 4.7649e+00, 4.7437e+00, 4.7226e+00, 4.7010e+00, 4.6787e+00, 4.6561e+00, 4.6337e+00, 4.6121e+00, 4.5914e+00, 4.5714e+00, 4.5519e+00, 4.5327e+00, 4.5137e+00, 4.4945e+00, 4.4748e+00, 4.4543e+00, 4.4333e+00, 4.4123e+00, 4.3921e+00, 4.3728e+00, 4.3541e+00, 4.3358e+00, 4.3176e+00, 4.2997e+00, 4.2817e+00, 4.2634e+00, 4.2443e+00, 4.2243e+00, 4.2039e+00, 4.1838e+00, 4.1646e+00, 4.1462e+00, 4.1283e+00, 4.1105e+00, 4.0929e+00, 4.0754e+00, 4.0579e+00, 4.0402e+00, 4.0218e+00, 4.0023e+00, 3.9822e+00, 3.9622e+00, 3.9430e+00, 3.9246e+00, 3.9069e+00, 3.8895e+00, 3.8720e+00, 3.8545e+00, 3.8373e+00, 3.8202e+00}); + feg = Vctr_cpu({1.2738e+01, 1.2532e+01, 1.1958e+01, 1.1122e+01, 1.0159e+01, 9.1870e+00, 8.2829e+00, 7.4816e+00, 6.7877e+00, 6.1909e+00, 5.6769e+00, 5.2314e+00, 4.8418e+00, 4.4977e+00, 4.1912e+00, 3.9160e+00, 3.6674e+00, 3.4418e+00, 3.2361e+00, 3.0479e+00, 2.8753e+00, 2.7166e+00, 2.5705e+00, 2.4357e+00, 2.3110e+00, 2.1955e+00, 2.0885e+00, 1.9890e+00, 1.8964e+00, 1.8101e+00, 1.7295e+00, 1.6541e+00, 1.5835e+00, 1.5172e+00, 1.4549e+00, 1.3963e+00, 1.3410e+00, 1.2888e+00, 1.2395e+00, 1.1927e+00, 1.1485e+00, 1.1065e+00, 1.0666e+00, 1.0286e+00, 9.9250e-01, 9.5820e-01, 9.2540e-01, 8.9410e-01, 8.6430e-01, 8.3580e-01, 8.0860e-01, 7.8260e-01, 7.5780e-01, 7.3400e-01, 7.1120e-01, 6.8940e-01, 6.6850e-01, 6.4850e-01, 6.2930e-01, 6.1090e-01, 5.9330e-01, 5.7630e-01, 5.6010e-01, 5.4450e-01, 5.2960e-01, 5.1520e-01, 5.0140e-01, 4.8810e-01, 4.7540e-01, 4.6310e-01, 4.5130e-01, 4.4000e-01, 4.2910e-01, 4.1860e-01, 4.0840e-01, 3.9870e-01, 3.8930e-01, 3.8020e-01, 3.7150e-01, 3.6310e-01, 3.5490e-01, 3.4710e-01, 3.3950e-01, 3.3220e-01, 3.2510e-01, 3.1830e-01, 3.1170e-01, 3.0530e-01, 2.9910e-01, 2.9310e-01, 2.8730e-01, 2.8170e-01, 2.7620e-01, 2.7090e-01, 2.6580e-01, 2.6080e-01, 2.5600e-01, 2.5130e-01, 2.4670e-01, 2.4230e-01, 2.3800e-01, 2.3380e-01, 2.2970e-01, 2.2570e-01, 2.2190e-01, 2.1810e-01, 2.1450e-01, 2.1090e-01, 2.0740e-01, 2.0400e-01, 2.0070e-01, 1.9750e-01, 1.9430e-01, 1.9130e-01, 1.8830e-01, 1.8530e-01, 1.8250e-01, 1.7970e-01, 1.7690e-01, 1.7430e-01, 1.7160e-01, 1.6910e-01, 1.6660e-01, 1.6410e-01, 1.6170e-01, 1.5940e-01, 1.5710e-01, 1.5490e-01, 1.5270e-01, 1.5050e-01, 1.4840e-01, 1.4630e-01, 1.4430e-01, 1.4230e-01, 1.4040e-01, 1.3850e-01, 1.3660e-01, 1.3470e-01, 1.3290e-01, 1.3120e-01, 1.2940e-01, 1.2770e-01, 1.2610e-01, 1.2440e-01, 1.2280e-01, 1.2120e-01, 1.1970e-01, 1.1820e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1100e-01, 1.0960e-01, 1.0830e-01, 1.0690e-01, 1.0570e-01, 1.0440e-01, 1.0310e-01, 1.0190e-01, 1.0070e-01, 9.9500e-02, 9.8300e-02, 9.7200e-02, 9.6100e-02, 9.5000e-02, 9.3900e-02, 9.2800e-02, 9.1700e-02, 9.0700e-02, 8.9700e-02, 8.8700e-02, 8.7700e-02, 8.6700e-02, 8.5800e-02, 8.4800e-02, 8.3900e-02, 8.3000e-02, 8.2100e-02, 8.1200e-02, 8.0300e-02, 7.9500e-02, 7.8600e-02, 7.7800e-02, 7.7000e-02, 7.6200e-02, 7.5400e-02, 7.4600e-02, 7.3900e-02, 7.3100e-02, 7.2400e-02, 7.1600e-02, 7.0900e-02, 7.0200e-02, 6.9500e-02, 6.8800e-02, 6.8100e-02, 6.7500e-02, 6.6800e-02, 6.6200e-02, 6.5500e-02, 6.4900e-02, 6.4300e-02, 6.3600e-02, 6.3000e-02, 6.2400e-02, 6.1900e-02, 6.1300e-02, 6.0700e-02, 6.0100e-02, 5.9600e-02, 5.9000e-02, 5.8500e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4400e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2600e-02, 5.2100e-02, 5.1700e-02, 5.1200e-02, 5.0800e-02, 5.0400e-02, 4.9900e-02, 4.9500e-02, 4.9100e-02, 4.8700e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6700e-02, 4.6400e-02, 4.6000e-02}); + } + break; + case 74: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.4000e+01, 7.3679e+01, 7.2769e+01, 7.1409e+01, 6.9765e+01, 6.7977e+01, 6.6139e+01, 6.4300e+01, 6.2481e+01, 6.0691e+01, 5.8932e+01, 5.7208e+01, 5.5520e+01, 5.3873e+01, 5.2271e+01, 5.0716e+01, 4.9210e+01, 4.7755e+01, 4.6353e+01, 4.5002e+01, 4.3701e+01, 4.2449e+01, 4.1244e+01, 4.0084e+01, 3.8966e+01, 3.7889e+01, 3.6850e+01, 3.5847e+01, 3.4879e+01, 3.3944e+01, 3.3041e+01, 3.2168e+01, 3.1325e+01, 3.0511e+01, 2.9725e+01, 2.8966e+01, 2.8235e+01, 2.7531e+01, 2.6852e+01, 2.6200e+01, 2.5573e+01, 2.4971e+01, 2.4393e+01, 2.3840e+01, 2.3310e+01, 2.2804e+01, 2.2320e+01, 2.1857e+01, 2.1416e+01, 2.0994e+01, 2.0593e+01, 2.0210e+01, 1.9846e+01, 1.9498e+01, 1.9167e+01, 1.8852e+01, 1.8551e+01, 1.8264e+01, 1.7990e+01, 1.7728e+01, 1.7478e+01, 1.7238e+01, 1.7008e+01, 1.6787e+01, 1.6575e+01, 1.6370e+01, 1.6172e+01, 1.5981e+01, 1.5796e+01, 1.5617e+01, 1.5441e+01, 1.5271e+01, 1.5104e+01, 1.4941e+01, 1.4781e+01, 1.4624e+01, 1.4469e+01, 1.4317e+01, 1.4166e+01, 1.4018e+01, 1.3870e+01, 1.3724e+01, 1.3579e+01, 1.3435e+01, 1.3292e+01, 1.3150e+01, 1.3008e+01, 1.2868e+01, 1.2728e+01, 1.2588e+01, 1.2449e+01, 1.2310e+01, 1.2172e+01, 1.2035e+01, 1.1898e+01, 1.1762e+01, 1.1626e+01, 1.1491e+01, 1.1357e+01, 1.1223e+01, 1.1091e+01, 1.0959e+01, 1.0828e+01, 1.0698e+01, 1.0569e+01, 1.0441e+01, 1.0314e+01, 1.0188e+01, 1.0064e+01, 9.9406e+00, 9.8188e+00, 9.6984e+00, 9.5794e+00, 9.4616e+00, 9.3453e+00, 9.2307e+00, 9.1177e+00, 9.0065e+00, 8.8968e+00, 8.7886e+00, 8.6819e+00, 8.5769e+00, 8.4739e+00, 8.3729e+00, 8.2737e+00, 8.1760e+00, 8.0798e+00, 7.9853e+00, 7.8927e+00, 7.8022e+00, 7.7138e+00, 7.6271e+00, 7.5420e+00, 7.4582e+00, 7.3760e+00, 7.2957e+00, 7.2175e+00, 7.1414e+00, 7.0672e+00, 6.9943e+00, 6.9227e+00, 6.8524e+00, 6.7836e+00, 6.7168e+00, 6.6519e+00, 6.5891e+00, 6.5278e+00, 6.4676e+00, 6.4084e+00, 6.3502e+00, 6.2933e+00, 6.2382e+00, 6.1850e+00, 6.1336e+00, 6.0835e+00, 6.0345e+00, 5.9861e+00, 5.9383e+00, 5.8915e+00, 5.8460e+00, 5.8022e+00, 5.7600e+00, 5.7192e+00, 5.6794e+00, 5.6402e+00, 5.6013e+00, 5.5627e+00, 5.5248e+00, 5.4881e+00, 5.4528e+00, 5.4190e+00, 5.3863e+00, 5.3543e+00, 5.3228e+00, 5.2913e+00, 5.2598e+00, 5.2285e+00, 5.1980e+00, 5.1687e+00, 5.1407e+00, 5.1137e+00, 5.0874e+00, 5.0615e+00, 5.0358e+00, 5.0098e+00, 4.9835e+00, 4.9572e+00, 4.9316e+00, 4.9071e+00, 4.8836e+00, 4.8610e+00, 4.8389e+00, 4.8171e+00, 4.7953e+00, 4.7732e+00, 4.7505e+00, 4.7275e+00, 4.7047e+00, 4.6828e+00, 4.6617e+00, 4.6415e+00, 4.6219e+00, 4.6025e+00, 4.5833e+00, 4.5640e+00, 4.5441e+00, 4.5235e+00, 4.5025e+00, 4.4815e+00, 4.4612e+00, 4.4419e+00, 4.4232e+00, 4.4050e+00, 4.3870e+00, 4.3692e+00, 4.3514e+00, 4.3331e+00, 4.3141e+00, 4.2943e+00, 4.2741e+00, 4.2542e+00, 4.2351e+00, 4.2168e+00, 4.1991e+00, 4.1817e+00, 4.1644e+00, 4.1473e+00, 4.1301e+00, 4.1126e+00, 4.0943e+00, 4.0751e+00, 4.0553e+00, 4.0355e+00, 4.0165e+00, 3.9984e+00, 3.9809e+00, 3.9637e+00, 3.9467e+00, 3.9297e+00, 3.9129e+00, 3.8960e+00}); + feg = Vctr_cpu({1.2480e+01, 1.2296e+01, 1.1780e+01, 1.1022e+01, 1.0136e+01, 9.2256e+00, 8.3616e+00, 7.5806e+00, 6.8924e+00, 6.2923e+00, 5.7701e+00, 5.3144e+00, 4.9143e+00, 4.5605e+00, 4.2454e+00, 3.9629e+00, 3.7082e+00, 3.4775e+00, 3.2676e+00, 3.0760e+00, 2.9006e+00, 2.7397e+00, 2.5916e+00, 2.4552e+00, 2.3291e+00, 2.2125e+00, 2.1045e+00, 2.0041e+00, 1.9108e+00, 1.8239e+00, 1.7428e+00, 1.6669e+00, 1.5959e+00, 1.5293e+00, 1.4667e+00, 1.4078e+00, 1.3522e+00, 1.2998e+00, 1.2503e+00, 1.2035e+00, 1.1590e+00, 1.1169e+00, 1.0769e+00, 1.0388e+00, 1.0026e+00, 9.6820e-01, 9.3530e-01, 9.0390e-01, 8.7400e-01, 8.4540e-01, 8.1810e-01, 7.9190e-01, 7.6690e-01, 7.4300e-01, 7.2010e-01, 6.9810e-01, 6.7710e-01, 6.5690e-01, 6.3760e-01, 6.1900e-01, 6.0120e-01, 5.8420e-01, 5.6780e-01, 5.5200e-01, 5.3690e-01, 5.2230e-01, 5.0840e-01, 4.9490e-01, 4.8200e-01, 4.6960e-01, 4.5760e-01, 4.4610e-01, 4.3510e-01, 4.2440e-01, 4.1410e-01, 4.0420e-01, 3.9470e-01, 3.8550e-01, 3.7660e-01, 3.6800e-01, 3.5980e-01, 3.5180e-01, 3.4410e-01, 3.3670e-01, 3.2950e-01, 3.2250e-01, 3.1580e-01, 3.0930e-01, 3.0300e-01, 2.9690e-01, 2.9100e-01, 2.8530e-01, 2.7970e-01, 2.7440e-01, 2.6910e-01, 2.6410e-01, 2.5920e-01, 2.5440e-01, 2.4980e-01, 2.4530e-01, 2.4090e-01, 2.3670e-01, 2.3250e-01, 2.2850e-01, 2.2460e-01, 2.2080e-01, 2.1710e-01, 2.1340e-01, 2.0990e-01, 2.0650e-01, 2.0310e-01, 1.9990e-01, 1.9670e-01, 1.9350e-01, 1.9050e-01, 1.8750e-01, 1.8460e-01, 1.8180e-01, 1.7900e-01, 1.7630e-01, 1.7370e-01, 1.7110e-01, 1.6860e-01, 1.6610e-01, 1.6370e-01, 1.6130e-01, 1.5900e-01, 1.5670e-01, 1.5450e-01, 1.5230e-01, 1.5020e-01, 1.4810e-01, 1.4610e-01, 1.4410e-01, 1.4210e-01, 1.4020e-01, 1.3830e-01, 1.3640e-01, 1.3460e-01, 1.3280e-01, 1.3110e-01, 1.2930e-01, 1.2770e-01, 1.2600e-01, 1.2440e-01, 1.2280e-01, 1.2120e-01, 1.1970e-01, 1.1820e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1100e-01, 1.0970e-01, 1.0830e-01, 1.0700e-01, 1.0570e-01, 1.0450e-01, 1.0320e-01, 1.0200e-01, 1.0080e-01, 9.9600e-02, 9.8500e-02, 9.7300e-02, 9.6200e-02, 9.5100e-02, 9.4000e-02, 9.3000e-02, 9.1900e-02, 9.0900e-02, 8.9900e-02, 8.8900e-02, 8.7900e-02, 8.6900e-02, 8.6000e-02, 8.5000e-02, 8.4100e-02, 8.3200e-02, 8.2300e-02, 8.1400e-02, 8.0600e-02, 7.9700e-02, 7.8900e-02, 7.8000e-02, 7.7200e-02, 7.6400e-02, 7.5600e-02, 7.4900e-02, 7.4100e-02, 7.3300e-02, 7.2600e-02, 7.1900e-02, 7.1100e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8400e-02, 6.7700e-02, 6.7000e-02, 6.6400e-02, 6.5800e-02, 6.5100e-02, 6.4500e-02, 6.3900e-02, 6.3300e-02, 6.2700e-02, 6.2100e-02, 6.1500e-02, 6.1000e-02, 6.0400e-02, 5.9800e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2800e-02, 5.2400e-02, 5.1900e-02, 5.1500e-02, 5.1000e-02, 5.0600e-02, 5.0200e-02, 4.9800e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02}); + } + break; + case 75: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.5000e+01, 7.4684e+01, 7.3787e+01, 7.2436e+01, 7.0786e+01, 6.8975e+01, 6.7098e+01, 6.5211e+01, 6.3343e+01, 6.1508e+01, 5.9712e+01, 5.7959e+01, 5.6250e+01, 5.4589e+01, 5.2978e+01, 5.1417e+01, 4.9910e+01, 4.8455e+01, 4.7053e+01, 4.5703e+01, 4.4404e+01, 4.3153e+01, 4.1948e+01, 4.0788e+01, 3.9670e+01, 3.8591e+01, 3.7550e+01, 3.6544e+01, 3.5572e+01, 3.4632e+01, 3.3723e+01, 3.2844e+01, 3.1993e+01, 3.1170e+01, 3.0374e+01, 2.9605e+01, 2.8863e+01, 2.8145e+01, 2.7454e+01, 2.6787e+01, 2.6145e+01, 2.5528e+01, 2.4934e+01, 2.4364e+01, 2.3818e+01, 2.3294e+01, 2.2792e+01, 2.2313e+01, 2.1854e+01, 2.1416e+01, 2.0997e+01, 2.0598e+01, 2.0217e+01, 1.9854e+01, 1.9508e+01, 1.9178e+01, 1.8863e+01, 1.8563e+01, 1.8276e+01, 1.8002e+01, 1.7741e+01, 1.7491e+01, 1.7251e+01, 1.7022e+01, 1.6801e+01, 1.6589e+01, 1.6385e+01, 1.6189e+01, 1.5998e+01, 1.5814e+01, 1.5636e+01, 1.5462e+01, 1.5293e+01, 1.5128e+01, 1.4967e+01, 1.4809e+01, 1.4653e+01, 1.4501e+01, 1.4351e+01, 1.4203e+01, 1.4056e+01, 1.3912e+01, 1.3768e+01, 1.3626e+01, 1.3485e+01, 1.3345e+01, 1.3206e+01, 1.3068e+01, 1.2930e+01, 1.2793e+01, 1.2656e+01, 1.2520e+01, 1.2384e+01, 1.2249e+01, 1.2115e+01, 1.1981e+01, 1.1848e+01, 1.1715e+01, 1.1582e+01, 1.1451e+01, 1.1320e+01, 1.1190e+01, 1.1060e+01, 1.0931e+01, 1.0803e+01, 1.0676e+01, 1.0550e+01, 1.0425e+01, 1.0301e+01, 1.0178e+01, 1.0056e+01, 9.9356e+00, 9.8165e+00, 9.6984e+00, 9.5815e+00, 9.4658e+00, 9.3518e+00, 9.2395e+00, 9.1288e+00, 9.0195e+00, 8.9114e+00, 8.8047e+00, 8.6996e+00, 8.5965e+00, 8.4954e+00, 8.3960e+00, 8.2980e+00, 8.2012e+00, 8.1060e+00, 8.0126e+00, 7.9214e+00, 7.8322e+00, 7.7448e+00, 7.6589e+00, 7.5742e+00, 7.4909e+00, 7.4093e+00, 7.3298e+00, 7.2524e+00, 7.1770e+00, 7.1031e+00, 7.0304e+00, 6.9588e+00, 6.8886e+00, 6.8201e+00, 6.7536e+00, 6.6892e+00, 6.6266e+00, 6.5653e+00, 6.5049e+00, 6.4454e+00, 6.3870e+00, 6.3302e+00, 6.2751e+00, 6.2219e+00, 6.1705e+00, 6.1203e+00, 6.0710e+00, 6.0222e+00, 5.9741e+00, 5.9270e+00, 5.8813e+00, 5.8372e+00, 5.7949e+00, 5.7539e+00, 5.7140e+00, 5.6744e+00, 5.6351e+00, 5.5962e+00, 5.5581e+00, 5.5210e+00, 5.4854e+00, 5.4512e+00, 5.4182e+00, 5.3862e+00, 5.3546e+00, 5.3229e+00, 5.2911e+00, 5.2597e+00, 5.2290e+00, 5.1992e+00, 5.1706e+00, 5.1432e+00, 5.1169e+00, 5.0912e+00, 5.0655e+00, 5.0395e+00, 5.0132e+00, 4.9870e+00, 4.9613e+00, 4.9362e+00, 4.9121e+00, 4.8890e+00, 4.8668e+00, 4.8453e+00, 4.8240e+00, 4.8022e+00, 4.7799e+00, 4.7571e+00, 4.7345e+00, 4.7122e+00, 4.6906e+00, 4.6697e+00, 4.6496e+00, 4.6304e+00, 4.6117e+00, 4.5931e+00, 4.5739e+00, 4.5539e+00, 4.5334e+00, 4.5128e+00, 4.4924e+00, 4.4724e+00, 4.4530e+00, 4.4342e+00, 4.4161e+00, 4.3987e+00, 4.3817e+00, 4.3645e+00, 4.3465e+00, 4.3276e+00, 4.3081e+00, 4.2885e+00, 4.2691e+00, 4.2502e+00, 4.2316e+00, 4.2135e+00, 4.1960e+00, 4.1793e+00, 4.1630e+00, 4.1468e+00, 4.1298e+00, 4.1119e+00, 4.0931e+00, 4.0739e+00, 4.0548e+00, 4.0360e+00, 4.0176e+00, 3.9996e+00, 3.9819e+00, 3.9648e+00}); + feg = Vctr_cpu({1.2263e+01, 1.2093e+01, 1.1614e+01, 1.0911e+01, 1.0085e+01, 9.2286e+00, 8.4057e+00, 7.6503e+00, 6.9748e+00, 6.3784e+00, 5.8542e+00, 5.3932e+00, 4.9861e+00, 4.6249e+00, 4.3027e+00, 4.0136e+00, 3.7531e+00, 3.5173e+00, 3.3030e+00, 3.1077e+00, 2.9291e+00, 2.7654e+00, 2.6150e+00, 2.4766e+00, 2.3489e+00, 2.2308e+00, 2.1215e+00, 2.0201e+00, 1.9258e+00, 1.8381e+00, 1.7563e+00, 1.6798e+00, 1.6083e+00, 1.5412e+00, 1.4783e+00, 1.4190e+00, 1.3633e+00, 1.3106e+00, 1.2609e+00, 1.2138e+00, 1.1693e+00, 1.1270e+00, 1.0869e+00, 1.0487e+00, 1.0124e+00, 9.7780e-01, 9.4480e-01, 9.1340e-01, 8.8330e-01, 8.5460e-01, 8.2720e-01, 8.0090e-01, 7.7580e-01, 7.5180e-01, 7.2870e-01, 7.0670e-01, 6.8550e-01, 6.6520e-01, 6.4570e-01, 6.2700e-01, 6.0910e-01, 5.9180e-01, 5.7530e-01, 5.5940e-01, 5.4410e-01, 5.2940e-01, 5.1530e-01, 5.0170e-01, 4.8860e-01, 4.7600e-01, 4.6390e-01, 4.5230e-01, 4.4110e-01, 4.3020e-01, 4.1980e-01, 4.0980e-01, 4.0010e-01, 3.9070e-01, 3.8170e-01, 3.7300e-01, 3.6470e-01, 3.5650e-01, 3.4870e-01, 3.4120e-01, 3.3380e-01, 3.2680e-01, 3.1990e-01, 3.1330e-01, 3.0690e-01, 3.0070e-01, 2.9470e-01, 2.8890e-01, 2.8330e-01, 2.7780e-01, 2.7250e-01, 2.6740e-01, 2.6240e-01, 2.5760e-01, 2.5290e-01, 2.4830e-01, 2.4390e-01, 2.3950e-01, 2.3530e-01, 2.3130e-01, 2.2730e-01, 2.2340e-01, 2.1970e-01, 2.1600e-01, 2.1240e-01, 2.0890e-01, 2.0550e-01, 2.0220e-01, 1.9900e-01, 1.9580e-01, 1.9280e-01, 1.8980e-01, 1.8680e-01, 1.8400e-01, 1.8120e-01, 1.7840e-01, 1.7570e-01, 1.7310e-01, 1.7060e-01, 1.6810e-01, 1.6560e-01, 1.6320e-01, 1.6090e-01, 1.5860e-01, 1.5630e-01, 1.5410e-01, 1.5200e-01, 1.4990e-01, 1.4780e-01, 1.4580e-01, 1.4380e-01, 1.4180e-01, 1.3990e-01, 1.3810e-01, 1.3620e-01, 1.3440e-01, 1.3270e-01, 1.3090e-01, 1.2920e-01, 1.2750e-01, 1.2590e-01, 1.2430e-01, 1.2270e-01, 1.2120e-01, 1.1960e-01, 1.1810e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0970e-01, 1.0840e-01, 1.0710e-01, 1.0580e-01, 1.0460e-01, 1.0330e-01, 1.0210e-01, 1.0090e-01, 9.9700e-02, 9.8600e-02, 9.7500e-02, 9.6300e-02, 9.5200e-02, 9.4200e-02, 9.3100e-02, 9.2100e-02, 9.1000e-02, 9.0000e-02, 8.9000e-02, 8.8000e-02, 8.7100e-02, 8.6100e-02, 8.5200e-02, 8.4300e-02, 8.3400e-02, 8.2500e-02, 8.1600e-02, 8.0800e-02, 7.9900e-02, 7.9100e-02, 7.8200e-02, 7.7400e-02, 7.6600e-02, 7.5900e-02, 7.5100e-02, 7.4300e-02, 7.3600e-02, 7.2800e-02, 7.2100e-02, 7.1400e-02, 7.0700e-02, 7.0000e-02, 6.9300e-02, 6.8600e-02, 6.7900e-02, 6.7300e-02, 6.6600e-02, 6.6000e-02, 6.5400e-02, 6.4800e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2400e-02, 6.1800e-02, 6.1200e-02, 6.0600e-02, 6.0100e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.7900e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1700e-02, 5.1300e-02, 5.0900e-02, 5.0400e-02, 5.0000e-02, 4.9600e-02, 4.9200e-02, 4.8800e-02, 4.8400e-02, 4.8000e-02, 4.7600e-02, 4.7200e-02}); + } + break; + case 76: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.6000e+01, 7.5692e+01, 7.4812e+01, 7.3476e+01, 7.1829e+01, 7.0003e+01, 6.8094e+01, 6.6165e+01, 6.4251e+01, 6.2370e+01, 6.0531e+01, 5.8740e+01, 5.7001e+01, 5.5316e+01, 5.3685e+01, 5.2112e+01, 5.0594e+01, 4.9133e+01, 4.7728e+01, 4.6376e+01, 4.5075e+01, 4.3825e+01, 4.2621e+01, 4.1461e+01, 4.0344e+01, 3.9266e+01, 3.8225e+01, 3.7219e+01, 3.6246e+01, 3.5304e+01, 3.4392e+01, 3.3509e+01, 3.2654e+01, 3.1825e+01, 3.1022e+01, 3.0245e+01, 2.9493e+01, 2.8766e+01, 2.8063e+01, 2.7384e+01, 2.6729e+01, 2.6098e+01, 2.5490e+01, 2.4905e+01, 2.4342e+01, 2.3802e+01, 2.3284e+01, 2.2788e+01, 2.2312e+01, 2.1857e+01, 2.1422e+01, 2.1006e+01, 2.0608e+01, 2.0229e+01, 1.9867e+01, 1.9522e+01, 1.9193e+01, 1.8878e+01, 1.8578e+01, 1.8292e+01, 1.8018e+01, 1.7757e+01, 1.7507e+01, 1.7267e+01, 1.7038e+01, 1.6818e+01, 1.6606e+01, 1.6403e+01, 1.6206e+01, 1.6017e+01, 1.5834e+01, 1.5656e+01, 1.5483e+01, 1.5316e+01, 1.5152e+01, 1.4992e+01, 1.4836e+01, 1.4683e+01, 1.4532e+01, 1.4384e+01, 1.4238e+01, 1.4095e+01, 1.3952e+01, 1.3812e+01, 1.3672e+01, 1.3534e+01, 1.3397e+01, 1.3260e+01, 1.3125e+01, 1.2990e+01, 1.2856e+01, 1.2722e+01, 1.2589e+01, 1.2457e+01, 1.2324e+01, 1.2193e+01, 1.2062e+01, 1.1931e+01, 1.1801e+01, 1.1671e+01, 1.1542e+01, 1.1414e+01, 1.1286e+01, 1.1159e+01, 1.1032e+01, 1.0906e+01, 1.0781e+01, 1.0657e+01, 1.0534e+01, 1.0412e+01, 1.0290e+01, 1.0170e+01, 1.0051e+01, 9.9327e+00, 9.8156e+00, 9.6998e+00, 9.5855e+00, 9.4725e+00, 9.3608e+00, 9.2502e+00, 9.1409e+00, 9.0331e+00, 8.9270e+00, 8.8227e+00, 8.7198e+00, 8.6183e+00, 8.5181e+00, 8.4193e+00, 8.3223e+00, 8.2272e+00, 8.1340e+00, 8.0424e+00, 7.9522e+00, 7.8633e+00, 7.7759e+00, 7.6902e+00, 7.6066e+00, 7.5249e+00, 7.4449e+00, 7.3664e+00, 7.2891e+00, 7.2130e+00, 7.1385e+00, 7.0659e+00, 6.9952e+00, 6.9264e+00, 6.8592e+00, 6.7933e+00, 6.7283e+00, 6.6644e+00, 6.6020e+00, 6.5412e+00, 6.4824e+00, 6.4253e+00, 6.3697e+00, 6.3152e+00, 6.2615e+00, 6.2085e+00, 6.1566e+00, 6.1061e+00, 6.0572e+00, 6.0100e+00, 5.9643e+00, 5.9198e+00, 5.8759e+00, 5.8326e+00, 5.7897e+00, 5.7477e+00, 5.7068e+00, 5.6674e+00, 5.6295e+00, 5.5928e+00, 5.5571e+00, 5.5220e+00, 5.4870e+00, 5.4523e+00, 5.4179e+00, 5.3843e+00, 5.3519e+00, 5.3207e+00, 5.2907e+00, 5.2617e+00, 5.2333e+00, 5.2051e+00, 5.1768e+00, 5.1484e+00, 5.1201e+00, 5.0925e+00, 5.0659e+00, 5.0403e+00, 5.0157e+00, 4.9919e+00, 4.9686e+00, 4.9454e+00, 4.9220e+00, 4.8981e+00, 4.8741e+00, 4.8503e+00, 4.8271e+00, 4.8049e+00, 4.7835e+00, 4.7629e+00, 4.7428e+00, 4.7230e+00, 4.7032e+00, 4.6829e+00, 4.6620e+00, 4.6407e+00, 4.6195e+00, 4.5988e+00, 4.5789e+00, 4.5597e+00, 4.5411e+00, 4.5230e+00, 4.5053e+00, 4.4876e+00, 4.4696e+00, 4.4508e+00, 4.4313e+00, 4.4114e+00, 4.3917e+00, 4.3726e+00, 4.3542e+00, 4.3364e+00, 4.3191e+00, 4.3022e+00, 4.2855e+00, 4.2690e+00, 4.2521e+00, 4.2344e+00, 4.2159e+00, 4.1967e+00, 4.1775e+00, 4.1588e+00, 4.1407e+00, 4.1233e+00, 4.1063e+00, 4.0896e+00, 4.0733e+00, 4.0573e+00, 4.0412e+00}); + feg = Vctr_cpu({1.1952e+01, 1.1801e+01, 1.1374e+01, 1.0739e+01, 9.9826e+00, 9.1866e+00, 8.4096e+00, 7.6859e+00, 7.0300e+00, 6.4439e+00, 5.9236e+00, 5.4623e+00, 5.0524e+00, 4.6869e+00, 4.3597e+00, 4.0657e+00, 3.8003e+00, 3.5600e+00, 3.3415e+00, 3.1425e+00, 2.9606e+00, 2.7939e+00, 2.6410e+00, 2.5002e+00, 2.3705e+00, 2.2507e+00, 2.1399e+00, 2.0372e+00, 1.9418e+00, 1.8530e+00, 1.7704e+00, 1.6932e+00, 1.6210e+00, 1.5534e+00, 1.4899e+00, 1.4303e+00, 1.3742e+00, 1.3212e+00, 1.2713e+00, 1.2240e+00, 1.1792e+00, 1.1368e+00, 1.0965e+00, 1.0582e+00, 1.0218e+00, 9.8710e-01, 9.5400e-01, 9.2250e-01, 8.9230e-01, 8.6350e-01, 8.3600e-01, 8.0970e-01, 7.8450e-01, 7.6030e-01, 7.3720e-01, 7.1500e-01, 6.9370e-01, 6.7330e-01, 6.5370e-01, 6.3480e-01, 6.1680e-01, 5.9940e-01, 5.8270e-01, 5.6670e-01, 5.5120e-01, 5.3640e-01, 5.2210e-01, 5.0840e-01, 4.9520e-01, 4.8250e-01, 4.7020e-01, 4.5840e-01, 4.4700e-01, 4.3610e-01, 4.2550e-01, 4.1530e-01, 4.0550e-01, 3.9600e-01, 3.8690e-01, 3.7810e-01, 3.6950e-01, 3.6130e-01, 3.5340e-01, 3.4570e-01, 3.3830e-01, 3.3110e-01, 3.2410e-01, 3.1740e-01, 3.1090e-01, 3.0460e-01, 2.9850e-01, 2.9260e-01, 2.8690e-01, 2.8130e-01, 2.7600e-01, 2.7070e-01, 2.6570e-01, 2.6080e-01, 2.5600e-01, 2.5130e-01, 2.4680e-01, 2.4250e-01, 2.3820e-01, 2.3400e-01, 2.3000e-01, 2.2610e-01, 2.2230e-01, 2.1860e-01, 2.1490e-01, 2.1140e-01, 2.0800e-01, 2.0460e-01, 2.0130e-01, 1.9810e-01, 1.9500e-01, 1.9200e-01, 1.8900e-01, 1.8610e-01, 1.8330e-01, 1.8050e-01, 1.7780e-01, 1.7520e-01, 1.7260e-01, 1.7000e-01, 1.6760e-01, 1.6510e-01, 1.6280e-01, 1.6050e-01, 1.5820e-01, 1.5600e-01, 1.5380e-01, 1.5160e-01, 1.4960e-01, 1.4750e-01, 1.4550e-01, 1.4350e-01, 1.4160e-01, 1.3970e-01, 1.3790e-01, 1.3600e-01, 1.3420e-01, 1.3250e-01, 1.3080e-01, 1.2910e-01, 1.2740e-01, 1.2580e-01, 1.2420e-01, 1.2260e-01, 1.2110e-01, 1.1960e-01, 1.1810e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0970e-01, 1.0840e-01, 1.0710e-01, 1.0590e-01, 1.0460e-01, 1.0340e-01, 1.0220e-01, 1.0100e-01, 9.9800e-02, 9.8700e-02, 9.7600e-02, 9.6500e-02, 9.5400e-02, 9.4300e-02, 9.3200e-02, 9.2200e-02, 9.1200e-02, 9.0200e-02, 8.9200e-02, 8.8200e-02, 8.7300e-02, 8.6300e-02, 8.5400e-02, 8.4500e-02, 8.3600e-02, 8.2700e-02, 8.1800e-02, 8.1000e-02, 8.0100e-02, 7.9300e-02, 7.8500e-02, 7.7600e-02, 7.6900e-02, 7.6100e-02, 7.5300e-02, 7.4500e-02, 7.3800e-02, 7.3000e-02, 7.2300e-02, 7.1600e-02, 7.0900e-02, 7.0200e-02, 6.9500e-02, 6.8800e-02, 6.8200e-02, 6.7500e-02, 6.6900e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1400e-02, 6.0900e-02, 6.0300e-02, 5.9800e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1500e-02, 5.1100e-02, 5.0700e-02, 5.0300e-02, 4.9800e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02}); + } + break; + case 77: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.7000e+01, 7.6700e+01, 7.5838e+01, 7.4520e+01, 7.2879e+01, 7.1043e+01, 6.9110e+01, 6.7145e+01, 6.5187e+01, 6.3260e+01, 6.1377e+01, 5.9546e+01, 5.7771e+01, 5.6055e+01, 5.4400e+01, 5.2806e+01, 5.1273e+01, 4.9801e+01, 4.8386e+01, 4.7029e+01, 4.5725e+01, 4.4473e+01, 4.3269e+01, 4.2110e+01, 4.0993e+01, 3.9916e+01, 3.8877e+01, 3.7872e+01, 3.6900e+01, 3.5958e+01, 3.5046e+01, 3.4161e+01, 3.3304e+01, 3.2472e+01, 3.1665e+01, 3.0882e+01, 3.0123e+01, 2.9388e+01, 2.8676e+01, 2.7987e+01, 2.7321e+01, 2.6678e+01, 2.6057e+01, 2.5458e+01, 2.4881e+01, 2.4326e+01, 2.3792e+01, 2.3280e+01, 2.2788e+01, 2.2316e+01, 2.1865e+01, 2.1432e+01, 2.1019e+01, 2.0624e+01, 2.0246e+01, 1.9885e+01, 1.9541e+01, 1.9212e+01, 1.8898e+01, 1.8598e+01, 1.8311e+01, 1.8038e+01, 1.7776e+01, 1.7526e+01, 1.7287e+01, 1.7057e+01, 1.6837e+01, 1.6625e+01, 1.6422e+01, 1.6226e+01, 1.6037e+01, 1.5854e+01, 1.5678e+01, 1.5506e+01, 1.5339e+01, 1.5177e+01, 1.5018e+01, 1.4864e+01, 1.4712e+01, 1.4563e+01, 1.4417e+01, 1.4274e+01, 1.4132e+01, 1.3992e+01, 1.3854e+01, 1.3717e+01, 1.3581e+01, 1.3446e+01, 1.3313e+01, 1.3180e+01, 1.3048e+01, 1.2917e+01, 1.2786e+01, 1.2656e+01, 1.2526e+01, 1.2397e+01, 1.2268e+01, 1.2140e+01, 1.2012e+01, 1.1885e+01, 1.1758e+01, 1.1631e+01, 1.1505e+01, 1.1380e+01, 1.1255e+01, 1.1131e+01, 1.1007e+01, 1.0884e+01, 1.0762e+01, 1.0641e+01, 1.0520e+01, 1.0401e+01, 1.0282e+01, 1.0164e+01, 1.0047e+01, 9.9316e+00, 9.8170e+00, 9.7036e+00, 9.5914e+00, 9.4804e+00, 9.3705e+00, 9.2619e+00, 9.1547e+00, 9.0490e+00, 8.9448e+00, 8.8419e+00, 8.7404e+00, 8.6402e+00, 8.5414e+00, 8.4444e+00, 8.3490e+00, 8.2553e+00, 8.1630e+00, 8.0721e+00, 7.9826e+00, 7.8946e+00, 7.8084e+00, 7.7240e+00, 7.6414e+00, 7.5603e+00, 7.4805e+00, 7.4021e+00, 7.3250e+00, 7.2496e+00, 7.1760e+00, 7.1042e+00, 7.0341e+00, 6.9654e+00, 6.8979e+00, 6.8314e+00, 6.7663e+00, 6.7028e+00, 6.6409e+00, 6.5808e+00, 6.5223e+00, 6.4651e+00, 6.4089e+00, 6.3535e+00, 6.2991e+00, 6.2460e+00, 6.1945e+00, 6.1445e+00, 6.0961e+00, 6.0489e+00, 6.0027e+00, 5.9572e+00, 5.9122e+00, 5.8681e+00, 5.8250e+00, 5.7832e+00, 5.7430e+00, 5.7040e+00, 5.6661e+00, 5.6289e+00, 5.5922e+00, 5.5558e+00, 5.5198e+00, 5.4846e+00, 5.4503e+00, 5.4173e+00, 5.3856e+00, 5.3548e+00, 5.3247e+00, 5.2950e+00, 5.2655e+00, 5.2360e+00, 5.2067e+00, 5.1778e+00, 5.1499e+00, 5.1230e+00, 5.0972e+00, 5.0723e+00, 5.0478e+00, 5.0235e+00, 4.9992e+00, 4.9748e+00, 4.9502e+00, 4.9257e+00, 4.9018e+00, 4.8787e+00, 4.8567e+00, 4.8354e+00, 4.8147e+00, 4.7941e+00, 4.7736e+00, 4.7529e+00, 4.7318e+00, 4.7104e+00, 4.6889e+00, 4.6679e+00, 4.6476e+00, 4.6282e+00, 4.6095e+00, 4.5912e+00, 4.5731e+00, 4.5550e+00, 4.5366e+00, 4.5179e+00, 4.4986e+00, 4.4789e+00, 4.4592e+00, 4.4399e+00, 4.4215e+00, 4.4039e+00, 4.3868e+00, 4.3701e+00, 4.3533e+00, 4.3364e+00, 4.3193e+00, 4.3018e+00, 4.2836e+00, 4.2649e+00, 4.2460e+00, 4.2273e+00, 4.2093e+00, 4.1922e+00, 4.1757e+00, 4.1596e+00, 4.1435e+00, 4.1274e+00, 4.1111e+00}); + feg = Vctr_cpu({1.1638e+01, 1.1505e+01, 1.1125e+01, 1.0553e+01, 9.8631e+00, 9.1246e+00, 8.3929e+00, 7.7020e+00, 7.0682e+00, 6.4957e+00, 5.9825e+00, 5.5238e+00, 5.1135e+00, 4.7459e+00, 4.4156e+00, 4.1177e+00, 3.8484e+00, 3.6041e+00, 3.3819e+00, 3.1793e+00, 2.9941e+00, 2.8245e+00, 2.6688e+00, 2.5257e+00, 2.3938e+00, 2.2721e+00, 2.1596e+00, 2.0554e+00, 1.9587e+00, 1.8688e+00, 1.7851e+00, 1.7070e+00, 1.6341e+00, 1.5658e+00, 1.5018e+00, 1.4417e+00, 1.3851e+00, 1.3318e+00, 1.2815e+00, 1.2340e+00, 1.1890e+00, 1.1464e+00, 1.1059e+00, 1.0675e+00, 1.0309e+00, 9.9610e-01, 9.6290e-01, 9.3130e-01, 9.0100e-01, 8.7220e-01, 8.4450e-01, 8.1810e-01, 7.9280e-01, 7.6860e-01, 7.4530e-01, 7.2300e-01, 7.0160e-01, 6.8110e-01, 6.6140e-01, 6.4250e-01, 6.2430e-01, 6.0680e-01, 5.9000e-01, 5.7380e-01, 5.5830e-01, 5.4330e-01, 5.2890e-01, 5.1500e-01, 5.0170e-01, 4.8880e-01, 4.7640e-01, 4.6450e-01, 4.5300e-01, 4.4190e-01, 4.3120e-01, 4.2090e-01, 4.1090e-01, 4.0130e-01, 3.9210e-01, 3.8310e-01, 3.7450e-01, 3.6610e-01, 3.5800e-01, 3.5020e-01, 3.4270e-01, 3.3540e-01, 3.2840e-01, 3.2150e-01, 3.1490e-01, 3.0850e-01, 3.0230e-01, 2.9630e-01, 2.9050e-01, 2.8490e-01, 2.7940e-01, 2.7410e-01, 2.6900e-01, 2.6400e-01, 2.5910e-01, 2.5440e-01, 2.4980e-01, 2.4540e-01, 2.4110e-01, 2.3690e-01, 2.3280e-01, 2.2880e-01, 2.2490e-01, 2.2110e-01, 2.1750e-01, 2.1390e-01, 2.1040e-01, 2.0700e-01, 2.0370e-01, 2.0040e-01, 1.9730e-01, 1.9420e-01, 1.9120e-01, 1.8830e-01, 1.8540e-01, 1.8260e-01, 1.7980e-01, 1.7720e-01, 1.7460e-01, 1.7200e-01, 1.6950e-01, 1.6700e-01, 1.6460e-01, 1.6230e-01, 1.6000e-01, 1.5780e-01, 1.5560e-01, 1.5340e-01, 1.5130e-01, 1.4920e-01, 1.4720e-01, 1.4520e-01, 1.4330e-01, 1.4130e-01, 1.3950e-01, 1.3760e-01, 1.3580e-01, 1.3410e-01, 1.3230e-01, 1.3060e-01, 1.2890e-01, 1.2730e-01, 1.2570e-01, 1.2410e-01, 1.2260e-01, 1.2100e-01, 1.1950e-01, 1.1810e-01, 1.1660e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0980e-01, 1.0850e-01, 1.0720e-01, 1.0590e-01, 1.0470e-01, 1.0350e-01, 1.0230e-01, 1.0110e-01, 9.9900e-02, 9.8800e-02, 9.7700e-02, 9.6600e-02, 9.5500e-02, 9.4400e-02, 9.3400e-02, 9.2300e-02, 9.1300e-02, 9.0300e-02, 8.9300e-02, 8.8400e-02, 8.7400e-02, 8.6500e-02, 8.5600e-02, 8.4600e-02, 8.3700e-02, 8.2900e-02, 8.2000e-02, 8.1100e-02, 8.0300e-02, 7.9500e-02, 7.8700e-02, 7.7800e-02, 7.7100e-02, 7.6300e-02, 7.5500e-02, 7.4700e-02, 7.4000e-02, 7.3300e-02, 7.2500e-02, 7.1800e-02, 7.1100e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8400e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.5800e-02, 6.5200e-02, 6.4600e-02, 6.4000e-02, 6.3400e-02, 6.2800e-02, 6.2200e-02, 6.1700e-02, 6.1100e-02, 6.0600e-02, 6.0000e-02, 5.9500e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1800e-02, 5.1300e-02, 5.0900e-02, 5.0500e-02, 5.0100e-02, 4.9700e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02}); + } + break; + case 78: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.8000e+01, 7.7721e+01, 7.6915e+01, 7.5666e+01, 7.4086e+01, 7.2281e+01, 7.0342e+01, 6.8338e+01, 6.6315e+01, 6.4309e+01, 6.2342e+01, 6.0429e+01, 5.8580e+01, 5.6800e+01, 5.5093e+01, 5.3458e+01, 5.1895e+01, 5.0402e+01, 4.8975e+01, 4.7612e+01, 4.6307e+01, 4.5057e+01, 4.3859e+01, 4.2707e+01, 4.1599e+01, 4.0531e+01, 3.9500e+01, 3.8503e+01, 3.7538e+01, 3.6602e+01, 3.5694e+01, 3.4813e+01, 3.3956e+01, 3.3124e+01, 3.2315e+01, 3.1529e+01, 3.0765e+01, 3.0023e+01, 2.9303e+01, 2.8605e+01, 2.7928e+01, 2.7273e+01, 2.6640e+01, 2.6027e+01, 2.5436e+01, 2.4866e+01, 2.4317e+01, 2.3788e+01, 2.3280e+01, 2.2792e+01, 2.2323e+01, 2.1874e+01, 2.1444e+01, 2.1032e+01, 2.0639e+01, 2.0262e+01, 1.9902e+01, 1.9558e+01, 1.9229e+01, 1.8916e+01, 1.8616e+01, 1.8330e+01, 1.8056e+01, 1.7795e+01, 1.7544e+01, 1.7305e+01, 1.7076e+01, 1.6856e+01, 1.6645e+01, 1.6441e+01, 1.6246e+01, 1.6057e+01, 1.5875e+01, 1.5699e+01, 1.5529e+01, 1.5363e+01, 1.5202e+01, 1.5045e+01, 1.4892e+01, 1.4742e+01, 1.4595e+01, 1.4451e+01, 1.4309e+01, 1.4169e+01, 1.4032e+01, 1.3896e+01, 1.3761e+01, 1.3628e+01, 1.3496e+01, 1.3365e+01, 1.3235e+01, 1.3106e+01, 1.2977e+01, 1.2849e+01, 1.2722e+01, 1.2595e+01, 1.2469e+01, 1.2343e+01, 1.2217e+01, 1.2092e+01, 1.1967e+01, 1.1843e+01, 1.1719e+01, 1.1595e+01, 1.1472e+01, 1.1350e+01, 1.1228e+01, 1.1107e+01, 1.0986e+01, 1.0866e+01, 1.0746e+01, 1.0627e+01, 1.0509e+01, 1.0392e+01, 1.0276e+01, 1.0161e+01, 1.0046e+01, 9.9327e+00, 9.8203e+00, 9.7090e+00, 9.5990e+00, 9.4902e+00, 9.3823e+00, 9.2755e+00, 9.1700e+00, 9.0659e+00, 8.9633e+00, 8.8621e+00, 8.7623e+00, 8.6637e+00, 8.5664e+00, 8.4704e+00, 8.3760e+00, 8.2833e+00, 8.1923e+00, 8.1027e+00, 8.0145e+00, 7.9275e+00, 7.8419e+00, 7.7579e+00, 7.6756e+00, 7.5951e+00, 7.5163e+00, 7.4389e+00, 7.3628e+00, 7.2879e+00, 7.2143e+00, 7.1422e+00, 7.0719e+00, 7.0034e+00, 6.9365e+00, 6.8710e+00, 6.8066e+00, 6.7433e+00, 6.6811e+00, 6.6202e+00, 6.5609e+00, 6.5033e+00, 6.4473e+00, 6.3927e+00, 6.3392e+00, 6.2865e+00, 6.2347e+00, 6.1838e+00, 6.1341e+00, 6.0859e+00, 6.0391e+00, 5.9938e+00, 5.9497e+00, 5.9064e+00, 5.8638e+00, 5.8218e+00, 5.7804e+00, 5.7399e+00, 5.7005e+00, 5.6624e+00, 5.6256e+00, 5.5899e+00, 5.5551e+00, 5.5208e+00, 5.4868e+00, 5.4531e+00, 5.4199e+00, 5.3873e+00, 5.3556e+00, 5.3250e+00, 5.2955e+00, 5.2670e+00, 5.2392e+00, 5.2117e+00, 5.1842e+00, 5.1568e+00, 5.1296e+00, 5.1027e+00, 5.0764e+00, 5.0509e+00, 5.0263e+00, 5.0026e+00, 4.9797e+00, 4.9571e+00, 4.9346e+00, 4.9119e+00, 4.8890e+00, 4.8661e+00, 4.8434e+00, 4.8211e+00, 4.7993e+00, 4.7783e+00, 4.7581e+00, 4.7387e+00, 4.7196e+00, 4.7004e+00, 4.6810e+00, 4.6611e+00, 4.6411e+00, 4.6209e+00, 4.6009e+00, 4.5812e+00, 4.5619e+00, 4.5433e+00, 4.5255e+00, 4.5083e+00, 4.4914e+00, 4.4743e+00, 4.4567e+00, 4.4386e+00, 4.4202e+00, 4.4016e+00, 4.3829e+00, 4.3644e+00, 4.3461e+00, 4.3284e+00, 4.3114e+00, 4.2950e+00, 4.2792e+00, 4.2635e+00, 4.2473e+00, 4.2306e+00, 4.2133e+00, 4.1955e+00, 4.1776e+00}); + feg = Vctr_cpu({1.0807e+01, 1.0699e+01, 1.0392e+01, 9.9291e+00, 9.3676e+00, 8.7597e+00, 8.1455e+00, 7.5513e+00, 6.9915e+00, 6.4725e+00, 5.9960e+00, 5.5608e+00, 5.1643e+00, 4.8036e+00, 4.4755e+00, 4.1769e+00, 3.9049e+00, 3.6568e+00, 3.4304e+00, 3.2235e+00, 3.0341e+00, 2.8605e+00, 2.7012e+00, 2.5548e+00, 2.4200e+00, 2.2957e+00, 2.1809e+00, 2.0747e+00, 1.9763e+00, 1.8850e+00, 1.8001e+00, 1.7209e+00, 1.6471e+00, 1.5780e+00, 1.5134e+00, 1.4527e+00, 1.3957e+00, 1.3420e+00, 1.2914e+00, 1.2436e+00, 1.1984e+00, 1.1556e+00, 1.1150e+00, 1.0764e+00, 1.0397e+00, 1.0048e+00, 9.7150e-01, 9.3980e-01, 9.0950e-01, 8.8050e-01, 8.5280e-01, 8.2630e-01, 8.0090e-01, 7.7660e-01, 7.5330e-01, 7.3090e-01, 7.0940e-01, 6.8880e-01, 6.6900e-01, 6.5000e-01, 6.3170e-01, 6.1410e-01, 5.9720e-01, 5.8090e-01, 5.6520e-01, 5.5010e-01, 5.3560e-01, 5.2160e-01, 5.0810e-01, 4.9510e-01, 4.8260e-01, 4.7050e-01, 4.5890e-01, 4.4770e-01, 4.3690e-01, 4.2640e-01, 4.1630e-01, 4.0660e-01, 3.9720e-01, 3.8810e-01, 3.7940e-01, 3.7090e-01, 3.6270e-01, 3.5480e-01, 3.4720e-01, 3.3980e-01, 3.3260e-01, 3.2570e-01, 3.1900e-01, 3.1250e-01, 3.0620e-01, 3.0010e-01, 2.9420e-01, 2.8850e-01, 2.8290e-01, 2.7750e-01, 2.7230e-01, 2.6720e-01, 2.6230e-01, 2.5750e-01, 2.5290e-01, 2.4840e-01, 2.4400e-01, 2.3970e-01, 2.3550e-01, 2.3150e-01, 2.2760e-01, 2.2370e-01, 2.2000e-01, 2.1640e-01, 2.1280e-01, 2.0940e-01, 2.0600e-01, 2.0280e-01, 1.9960e-01, 1.9640e-01, 1.9340e-01, 1.9040e-01, 1.8750e-01, 1.8470e-01, 1.8190e-01, 1.7920e-01, 1.7650e-01, 1.7400e-01, 1.7140e-01, 1.6890e-01, 1.6650e-01, 1.6410e-01, 1.6180e-01, 1.5960e-01, 1.5730e-01, 1.5520e-01, 1.5300e-01, 1.5090e-01, 1.4890e-01, 1.4690e-01, 1.4490e-01, 1.4300e-01, 1.4110e-01, 1.3920e-01, 1.3740e-01, 1.3560e-01, 1.3390e-01, 1.3210e-01, 1.3040e-01, 1.2880e-01, 1.2720e-01, 1.2560e-01, 1.2400e-01, 1.2250e-01, 1.2090e-01, 1.1950e-01, 1.1800e-01, 1.1660e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0980e-01, 1.0850e-01, 1.0720e-01, 1.0590e-01, 1.0470e-01, 1.0350e-01, 1.0230e-01, 1.0120e-01, 1.0000e-01, 9.8900e-02, 9.7800e-02, 9.6700e-02, 9.5600e-02, 9.4500e-02, 9.3500e-02, 9.2500e-02, 9.1400e-02, 9.0500e-02, 8.9500e-02, 8.8500e-02, 8.7600e-02, 8.6600e-02, 8.5700e-02, 8.4800e-02, 8.3900e-02, 8.3000e-02, 8.2200e-02, 8.1300e-02, 8.0500e-02, 7.9600e-02, 7.8800e-02, 7.8000e-02, 7.7200e-02, 7.6500e-02, 7.5700e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2700e-02, 7.2000e-02, 7.1300e-02, 7.0600e-02, 6.9900e-02, 6.9300e-02, 6.8600e-02, 6.8000e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5400e-02, 6.4800e-02, 6.4200e-02, 6.3600e-02, 6.3000e-02, 6.2500e-02, 6.1900e-02, 6.1300e-02, 6.0800e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0300e-02, 4.9900e-02, 4.9500e-02, 4.9100e-02}); + } + break; + case 79: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.9000e+01, 7.8727e+01, 7.7937e+01, 7.6706e+01, 7.5136e+01, 7.3332e+01, 7.1380e+01, 6.9350e+01, 6.7295e+01, 6.5249e+01, 6.3240e+01, 6.1284e+01, 5.9393e+01, 5.7575e+01, 5.5833e+01, 5.4168e+01, 5.2579e+01, 5.1064e+01, 4.9620e+01, 4.8242e+01, 4.6927e+01, 4.5670e+01, 4.4467e+01, 4.3313e+01, 4.2204e+01, 4.1137e+01, 4.0108e+01, 3.9113e+01, 3.8151e+01, 3.7218e+01, 3.6313e+01, 3.5433e+01, 3.4578e+01, 3.3747e+01, 3.2938e+01, 3.2150e+01, 3.1384e+01, 3.0639e+01, 2.9915e+01, 2.9210e+01, 2.8527e+01, 2.7863e+01, 2.7220e+01, 2.6598e+01, 2.5995e+01, 2.5413e+01, 2.4851e+01, 2.4308e+01, 2.3786e+01, 2.3283e+01, 2.2800e+01, 2.2335e+01, 2.1890e+01, 2.1462e+01, 2.1053e+01, 2.0661e+01, 2.0285e+01, 1.9926e+01, 1.9583e+01, 1.9255e+01, 1.8941e+01, 1.8642e+01, 1.8355e+01, 1.8081e+01, 1.7820e+01, 1.7569e+01, 1.7329e+01, 1.7100e+01, 1.6880e+01, 1.6668e+01, 1.6465e+01, 1.6269e+01, 1.6081e+01, 1.5899e+01, 1.5724e+01, 1.5553e+01, 1.5389e+01, 1.5228e+01, 1.5072e+01, 1.4920e+01, 1.4772e+01, 1.4626e+01, 1.4484e+01, 1.4344e+01, 1.4206e+01, 1.4070e+01, 1.3936e+01, 1.3804e+01, 1.3673e+01, 1.3543e+01, 1.3415e+01, 1.3287e+01, 1.3161e+01, 1.3035e+01, 1.2909e+01, 1.2785e+01, 1.2661e+01, 1.2537e+01, 1.2414e+01, 1.2291e+01, 1.2168e+01, 1.2046e+01, 1.1924e+01, 1.1803e+01, 1.1682e+01, 1.1562e+01, 1.1441e+01, 1.1322e+01, 1.1203e+01, 1.1084e+01, 1.0966e+01, 1.0848e+01, 1.0732e+01, 1.0616e+01, 1.0500e+01, 1.0385e+01, 1.0272e+01, 1.0159e+01, 1.0047e+01, 9.9354e+00, 9.8250e+00, 9.7158e+00, 9.6077e+00, 9.5008e+00, 9.3950e+00, 9.2903e+00, 9.1866e+00, 9.0841e+00, 8.9829e+00, 8.8832e+00, 8.7849e+00, 8.6879e+00, 8.5921e+00, 8.4976e+00, 8.4043e+00, 8.3125e+00, 8.2223e+00, 8.1338e+00, 8.0467e+00, 7.9609e+00, 7.8764e+00, 7.7932e+00, 7.7114e+00, 7.6312e+00, 7.5528e+00, 7.4759e+00, 7.4005e+00, 7.3264e+00, 7.2535e+00, 7.1818e+00, 7.1116e+00, 7.0429e+00, 6.9758e+00, 6.9104e+00, 6.8464e+00, 6.7836e+00, 6.7219e+00, 6.6612e+00, 6.6018e+00, 6.5437e+00, 6.4871e+00, 6.4321e+00, 6.3785e+00, 6.3261e+00, 6.2747e+00, 6.2241e+00, 6.1743e+00, 6.1256e+00, 6.0781e+00, 6.0319e+00, 5.9872e+00, 5.9436e+00, 5.9012e+00, 5.8595e+00, 5.8184e+00, 5.7779e+00, 5.7380e+00, 5.6992e+00, 5.6614e+00, 5.6248e+00, 5.5894e+00, 5.5549e+00, 5.5212e+00, 5.4880e+00, 5.4551e+00, 5.4224e+00, 5.3903e+00, 5.3589e+00, 5.3284e+00, 5.2989e+00, 5.2704e+00, 5.2427e+00, 5.2156e+00, 5.1888e+00, 5.1621e+00, 5.1355e+00, 5.1090e+00, 5.0828e+00, 5.0574e+00, 5.0327e+00, 5.0089e+00, 4.9859e+00, 4.9634e+00, 4.9413e+00, 4.9193e+00, 4.8971e+00, 4.8748e+00, 4.8523e+00, 4.8301e+00, 4.8084e+00, 4.7874e+00, 4.7670e+00, 4.7473e+00, 4.7281e+00, 4.7092e+00, 4.6904e+00, 4.6715e+00, 4.6521e+00, 4.6324e+00, 4.6125e+00, 4.5929e+00, 4.5737e+00, 4.5551e+00, 4.5371e+00, 4.5196e+00, 4.5025e+00, 4.4856e+00, 4.4688e+00, 4.4517e+00, 4.4341e+00, 4.4160e+00, 4.3976e+00, 4.3791e+00, 4.3610e+00, 4.3434e+00, 4.3263e+00, 4.3097e+00, 4.2935e+00, 4.2776e+00, 4.2619e+00, 4.2461e+00}); + feg = Vctr_cpu({1.0553e+01, 1.0456e+01, 1.0181e+01, 9.7617e+00, 9.2469e+00, 8.6826e+00, 8.1057e+00, 7.5412e+00, 7.0038e+00, 6.5009e+00, 6.0352e+00, 5.6068e+00, 5.2140e+00, 4.8547e+00, 4.5263e+00, 4.2263e+00, 3.9522e+00, 3.7017e+00, 3.4725e+00, 3.2627e+00, 3.0705e+00, 2.8942e+00, 2.7322e+00, 2.5834e+00, 2.4463e+00, 2.3199e+00, 2.2032e+00, 2.0952e+00, 1.9953e+00, 1.9025e+00, 1.8163e+00, 1.7360e+00, 1.6612e+00, 1.5913e+00, 1.5259e+00, 1.4645e+00, 1.4069e+00, 1.3528e+00, 1.3017e+00, 1.2535e+00, 1.2080e+00, 1.1649e+00, 1.1241e+00, 1.0853e+00, 1.0484e+00, 1.0134e+00, 9.8000e-01, 9.4810e-01, 9.1770e-01, 8.8860e-01, 8.6080e-01, 8.3430e-01, 8.0880e-01, 7.8440e-01, 7.6100e-01, 7.3850e-01, 7.1700e-01, 6.9630e-01, 6.7640e-01, 6.5720e-01, 6.3890e-01, 6.2120e-01, 6.0410e-01, 5.8780e-01, 5.7200e-01, 5.5680e-01, 5.4210e-01, 5.2800e-01, 5.1450e-01, 5.0140e-01, 4.8870e-01, 4.7650e-01, 4.6480e-01, 4.5340e-01, 4.4250e-01, 4.3190e-01, 4.2170e-01, 4.1190e-01, 4.0240e-01, 3.9320e-01, 3.8430e-01, 3.7570e-01, 3.6740e-01, 3.5940e-01, 3.5160e-01, 3.4410e-01, 3.3690e-01, 3.2980e-01, 3.2300e-01, 3.1640e-01, 3.1010e-01, 3.0390e-01, 2.9790e-01, 2.9210e-01, 2.8640e-01, 2.8100e-01, 2.7570e-01, 2.7050e-01, 2.6550e-01, 2.6060e-01, 2.5590e-01, 2.5130e-01, 2.4690e-01, 2.4260e-01, 2.3830e-01, 2.3420e-01, 2.3020e-01, 2.2640e-01, 2.2260e-01, 2.1890e-01, 2.1530e-01, 2.1180e-01, 2.0840e-01, 2.0510e-01, 2.0180e-01, 1.9870e-01, 1.9560e-01, 1.9260e-01, 1.8960e-01, 1.8680e-01, 1.8400e-01, 1.8120e-01, 1.7850e-01, 1.7590e-01, 1.7340e-01, 1.7080e-01, 1.6840e-01, 1.6600e-01, 1.6360e-01, 1.6140e-01, 1.5910e-01, 1.5690e-01, 1.5470e-01, 1.5260e-01, 1.5060e-01, 1.4850e-01, 1.4650e-01, 1.4460e-01, 1.4270e-01, 1.4080e-01, 1.3900e-01, 1.3720e-01, 1.3540e-01, 1.3360e-01, 1.3190e-01, 1.3030e-01, 1.2860e-01, 1.2700e-01, 1.2540e-01, 1.2390e-01, 1.2240e-01, 1.2090e-01, 1.1940e-01, 1.1790e-01, 1.1650e-01, 1.1510e-01, 1.1370e-01, 1.1240e-01, 1.1110e-01, 1.0980e-01, 1.0850e-01, 1.0720e-01, 1.0600e-01, 1.0470e-01, 1.0350e-01, 1.0240e-01, 1.0120e-01, 1.0010e-01, 9.8900e-02, 9.7800e-02, 9.6700e-02, 9.5700e-02, 9.4600e-02, 9.3600e-02, 9.2600e-02, 9.1600e-02, 9.0600e-02, 8.9600e-02, 8.8600e-02, 8.7700e-02, 8.6800e-02, 8.5800e-02, 8.4900e-02, 8.4100e-02, 8.3200e-02, 8.2300e-02, 8.1500e-02, 8.0600e-02, 7.9800e-02, 7.9000e-02, 7.8200e-02, 7.7400e-02, 7.6600e-02, 7.5900e-02, 7.5100e-02, 7.4400e-02, 7.3700e-02, 7.2900e-02, 7.2200e-02, 7.1500e-02, 7.0800e-02, 7.0200e-02, 6.9500e-02, 6.8800e-02, 6.8200e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3300e-02, 6.2700e-02, 6.2100e-02, 6.1600e-02, 6.1000e-02, 6.0500e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7800e-02, 5.7300e-02, 5.6800e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1800e-02, 5.1400e-02, 5.0900e-02, 5.0500e-02, 5.0100e-02, 4.9700e-02}); + } + break; + case 80: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.0000e+01, 7.9718e+01, 7.8901e+01, 7.7632e+01, 7.6021e+01, 7.4179e+01, 7.2199e+01, 7.0152e+01, 6.8087e+01, 6.6038e+01, 6.4027e+01, 6.2069e+01, 6.0175e+01, 5.8350e+01, 5.6597e+01, 5.4920e+01, 5.3316e+01, 5.1785e+01, 5.0324e+01, 4.8930e+01, 4.7599e+01, 4.6327e+01, 4.5111e+01, 4.3945e+01, 4.2827e+01, 4.1751e+01, 4.0716e+01, 3.9716e+01, 3.8750e+01, 3.7815e+01, 3.6909e+01, 3.6029e+01, 3.5173e+01, 3.4342e+01, 3.3532e+01, 3.2745e+01, 3.1977e+01, 3.1231e+01, 3.0504e+01, 2.9797e+01, 2.9109e+01, 2.8440e+01, 2.7791e+01, 2.7162e+01, 2.6551e+01, 2.5960e+01, 2.5387e+01, 2.4834e+01, 2.4300e+01, 2.3785e+01, 2.3289e+01, 2.2811e+01, 2.2352e+01, 2.1910e+01, 2.1486e+01, 2.1079e+01, 2.0689e+01, 2.0316e+01, 1.9958e+01, 1.9616e+01, 1.9288e+01, 1.8975e+01, 1.8675e+01, 1.8388e+01, 1.8114e+01, 1.7852e+01, 1.7601e+01, 1.7360e+01, 1.7130e+01, 1.6909e+01, 1.6697e+01, 1.6494e+01, 1.6297e+01, 1.6109e+01, 1.5927e+01, 1.5751e+01, 1.5581e+01, 1.5416e+01, 1.5257e+01, 1.5101e+01, 1.4950e+01, 1.4802e+01, 1.4658e+01, 1.4516e+01, 1.4378e+01, 1.4241e+01, 1.4107e+01, 1.3975e+01, 1.3845e+01, 1.3716e+01, 1.3588e+01, 1.3462e+01, 1.3337e+01, 1.3213e+01, 1.3089e+01, 1.2966e+01, 1.2844e+01, 1.2722e+01, 1.2601e+01, 1.2481e+01, 1.2360e+01, 1.2241e+01, 1.2121e+01, 1.2002e+01, 1.1883e+01, 1.1765e+01, 1.1647e+01, 1.1529e+01, 1.1412e+01, 1.1295e+01, 1.1179e+01, 1.1063e+01, 1.0947e+01, 1.0833e+01, 1.0718e+01, 1.0605e+01, 1.0492e+01, 1.0380e+01, 1.0268e+01, 1.0158e+01, 1.0048e+01, 9.9387e+00, 9.8307e+00, 9.7237e+00, 9.6177e+00, 9.5127e+00, 9.4086e+00, 9.3056e+00, 9.2037e+00, 9.1030e+00, 9.0037e+00, 8.9056e+00, 8.8087e+00, 8.7130e+00, 8.6183e+00, 8.5250e+00, 8.4331e+00, 8.3428e+00, 8.2539e+00, 8.1663e+00, 8.0800e+00, 7.9948e+00, 7.9110e+00, 7.8285e+00, 7.7477e+00, 7.6686e+00, 7.5909e+00, 7.5145e+00, 7.4393e+00, 7.3653e+00, 7.2926e+00, 7.2213e+00, 7.1516e+00, 7.0836e+00, 7.0170e+00, 6.9518e+00, 6.8877e+00, 6.8245e+00, 6.7625e+00, 6.7018e+00, 6.6425e+00, 6.5848e+00, 6.5287e+00, 6.4738e+00, 6.4200e+00, 6.3670e+00, 6.3149e+00, 6.2637e+00, 6.2137e+00, 6.1650e+00, 6.1178e+00, 6.0720e+00, 6.0273e+00, 5.9834e+00, 5.9403e+00, 5.8977e+00, 5.8558e+00, 5.8147e+00, 5.7747e+00, 5.7360e+00, 5.6986e+00, 5.6623e+00, 5.6267e+00, 5.5918e+00, 5.5572e+00, 5.5229e+00, 5.4891e+00, 5.4559e+00, 5.4237e+00, 5.3926e+00, 5.3626e+00, 5.3335e+00, 5.3050e+00, 5.2769e+00, 5.2490e+00, 5.2212e+00, 5.1935e+00, 5.1662e+00, 5.1394e+00, 5.1136e+00, 5.0888e+00, 5.0648e+00, 5.0414e+00, 5.0183e+00, 4.9955e+00, 4.9726e+00, 4.9495e+00, 4.9264e+00, 4.9034e+00, 4.8809e+00, 4.8591e+00, 4.8382e+00, 4.8181e+00, 4.7984e+00, 4.7790e+00, 4.7597e+00, 4.7403e+00, 4.7206e+00, 4.7006e+00, 4.6804e+00, 4.6604e+00, 4.6407e+00, 4.6219e+00, 4.6038e+00, 4.5862e+00, 4.5691e+00, 4.5520e+00, 4.5350e+00, 4.5177e+00, 4.5001e+00, 4.4820e+00, 4.4635e+00, 4.4449e+00, 4.4266e+00, 4.4090e+00, 4.3921e+00, 4.3758e+00, 4.3599e+00, 4.3442e+00, 4.3284e+00, 4.3125e+00}); + feg = Vctr_cpu({1.0922e+01, 1.0820e+01, 1.0525e+01, 1.0076e+01, 9.5230e+00, 8.9163e+00, 8.2978e+00, 7.6962e+00, 7.1280e+00, 6.6009e+00, 6.1168e+00, 5.6747e+00, 5.2721e+00, 4.9058e+00, 4.5723e+00, 4.2685e+00, 3.9915e+00, 3.7386e+00, 3.5074e+00, 3.2958e+00, 3.1019e+00, 2.9239e+00, 2.7604e+00, 2.6100e+00, 2.4714e+00, 2.3435e+00, 2.2254e+00, 2.1161e+00, 2.0148e+00, 1.9208e+00, 1.8335e+00, 1.7522e+00, 1.6764e+00, 1.6055e+00, 1.5393e+00, 1.4772e+00, 1.4190e+00, 1.3642e+00, 1.3126e+00, 1.2640e+00, 1.2180e+00, 1.1745e+00, 1.1334e+00, 1.0943e+00, 1.0572e+00, 1.0219e+00, 9.8830e-01, 9.5630e-01, 9.2580e-01, 8.9660e-01, 8.6870e-01, 8.4200e-01, 8.1640e-01, 7.9190e-01, 7.6840e-01, 7.4590e-01, 7.2420e-01, 7.0350e-01, 6.8350e-01, 6.6430e-01, 6.4580e-01, 6.2800e-01, 6.1090e-01, 5.9440e-01, 5.7860e-01, 5.6330e-01, 5.4860e-01, 5.3440e-01, 5.2070e-01, 5.0750e-01, 4.9470e-01, 4.8240e-01, 4.7060e-01, 4.5910e-01, 4.4810e-01, 4.3740e-01, 4.2710e-01, 4.1710e-01, 4.0750e-01, 3.9820e-01, 3.8920e-01, 3.8050e-01, 3.7210e-01, 3.6400e-01, 3.5610e-01, 3.4850e-01, 3.4120e-01, 3.3400e-01, 3.2710e-01, 3.2040e-01, 3.1400e-01, 3.0770e-01, 3.0160e-01, 2.9570e-01, 2.9000e-01, 2.8440e-01, 2.7900e-01, 2.7380e-01, 2.6870e-01, 2.6380e-01, 2.5900e-01, 2.5440e-01, 2.4980e-01, 2.4540e-01, 2.4120e-01, 2.3700e-01, 2.3300e-01, 2.2900e-01, 2.2520e-01, 2.2140e-01, 2.1780e-01, 2.1430e-01, 2.1080e-01, 2.0740e-01, 2.0410e-01, 2.0090e-01, 1.9780e-01, 1.9480e-01, 1.9180e-01, 1.8890e-01, 1.8600e-01, 1.8320e-01, 1.8050e-01, 1.7790e-01, 1.7530e-01, 1.7280e-01, 1.7030e-01, 1.6780e-01, 1.6550e-01, 1.6310e-01, 1.6090e-01, 1.5860e-01, 1.5650e-01, 1.5430e-01, 1.5220e-01, 1.5020e-01, 1.4820e-01, 1.4620e-01, 1.4430e-01, 1.4240e-01, 1.4050e-01, 1.3870e-01, 1.3690e-01, 1.3520e-01, 1.3340e-01, 1.3170e-01, 1.3010e-01, 1.2850e-01, 1.2690e-01, 1.2530e-01, 1.2370e-01, 1.2220e-01, 1.2070e-01, 1.1930e-01, 1.1780e-01, 1.1640e-01, 1.1500e-01, 1.1370e-01, 1.1230e-01, 1.1100e-01, 1.0970e-01, 1.0850e-01, 1.0720e-01, 1.0600e-01, 1.0480e-01, 1.0360e-01, 1.0240e-01, 1.0120e-01, 1.0010e-01, 9.9000e-02, 9.7900e-02, 9.6800e-02, 9.5800e-02, 9.4700e-02, 9.3700e-02, 9.2700e-02, 9.1700e-02, 9.0700e-02, 8.9700e-02, 8.8800e-02, 8.7800e-02, 8.6900e-02, 8.6000e-02, 8.5100e-02, 8.4200e-02, 8.3300e-02, 8.2500e-02, 8.1600e-02, 8.0800e-02, 8.0000e-02, 7.9200e-02, 7.8400e-02, 7.7600e-02, 7.6800e-02, 7.6100e-02, 7.5300e-02, 7.4600e-02, 7.3800e-02, 7.3100e-02, 7.2400e-02, 7.1700e-02, 7.1000e-02, 7.0300e-02, 6.9700e-02, 6.9000e-02, 6.8400e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.5900e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1800e-02, 6.1200e-02, 6.0700e-02, 6.0100e-02, 5.9600e-02, 5.9100e-02, 5.8600e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0300e-02}); + } + break; + case 81: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.1000e+01, 8.0673e+01, 7.9749e+01, 7.8370e+01, 7.6690e+01, 7.4831e+01, 7.2871e+01, 7.0860e+01, 6.8833e+01, 6.6816e+01, 6.4828e+01, 6.2882e+01, 6.0990e+01, 5.9159e+01, 5.7394e+01, 5.5699e+01, 5.4075e+01, 5.2522e+01, 5.1039e+01, 4.9622e+01, 4.8271e+01, 4.6980e+01, 4.5746e+01, 4.4566e+01, 4.3435e+01, 4.2350e+01, 4.1307e+01, 4.0302e+01, 3.9332e+01, 3.8395e+01, 3.7487e+01, 3.6607e+01, 3.5752e+01, 3.4922e+01, 3.4113e+01, 3.3327e+01, 3.2560e+01, 3.1813e+01, 3.1086e+01, 3.0377e+01, 2.9687e+01, 2.9015e+01, 2.8362e+01, 2.7727e+01, 2.7110e+01, 2.6511e+01, 2.5930e+01, 2.5368e+01, 2.4824e+01, 2.4297e+01, 2.3789e+01, 2.3299e+01, 2.2827e+01, 2.2372e+01, 2.1934e+01, 2.1513e+01, 2.1109e+01, 2.0721e+01, 2.0349e+01, 1.9993e+01, 1.9651e+01, 1.9324e+01, 1.9011e+01, 1.8711e+01, 1.8424e+01, 1.8149e+01, 1.7886e+01, 1.7634e+01, 1.7393e+01, 1.7162e+01, 1.6941e+01, 1.6728e+01, 1.6524e+01, 1.6327e+01, 1.6138e+01, 1.5956e+01, 1.5780e+01, 1.5610e+01, 1.5445e+01, 1.5286e+01, 1.5131e+01, 1.4980e+01, 1.4833e+01, 1.4689e+01, 1.4549e+01, 1.4412e+01, 1.4277e+01, 1.4144e+01, 1.4014e+01, 1.3885e+01, 1.3758e+01, 1.3633e+01, 1.3508e+01, 1.3385e+01, 1.3263e+01, 1.3142e+01, 1.3022e+01, 1.2902e+01, 1.2783e+01, 1.2664e+01, 1.2546e+01, 1.2428e+01, 1.2311e+01, 1.2194e+01, 1.2077e+01, 1.1961e+01, 1.1845e+01, 1.1730e+01, 1.1614e+01, 1.1499e+01, 1.1385e+01, 1.1271e+01, 1.1158e+01, 1.1044e+01, 1.0931e+01, 1.0819e+01, 1.0707e+01, 1.0596e+01, 1.0486e+01, 1.0376e+01, 1.0267e+01, 1.0158e+01, 1.0050e+01, 9.9435e+00, 9.8379e+00, 9.7333e+00, 9.6293e+00, 9.5259e+00, 9.4233e+00, 9.3218e+00, 9.2217e+00, 9.1231e+00, 9.0258e+00, 8.9293e+00, 8.8335e+00, 8.7387e+00, 8.6451e+00, 8.5531e+00, 8.4628e+00, 8.3740e+00, 8.2864e+00, 8.1997e+00, 8.1139e+00, 8.0292e+00, 7.9460e+00, 7.8645e+00, 7.7847e+00, 7.7066e+00, 7.6298e+00, 7.5539e+00, 7.4787e+00, 7.4047e+00, 7.3322e+00, 7.2613e+00, 7.1923e+00, 7.1249e+00, 7.0590e+00, 6.9939e+00, 6.9296e+00, 6.8661e+00, 6.8038e+00, 6.7431e+00, 6.6840e+00, 6.6265e+00, 6.5707e+00, 6.5161e+00, 6.4622e+00, 6.4087e+00, 6.3560e+00, 6.3045e+00, 6.2542e+00, 6.2054e+00, 6.1581e+00, 6.1123e+00, 6.0677e+00, 6.0238e+00, 5.9802e+00, 5.9370e+00, 5.8944e+00, 5.8530e+00, 5.8127e+00, 5.7737e+00, 5.7359e+00, 5.6995e+00, 5.6642e+00, 5.6292e+00, 5.5942e+00, 5.5593e+00, 5.5249e+00, 5.4913e+00, 5.4588e+00, 5.4272e+00, 5.3967e+00, 5.3673e+00, 5.3390e+00, 5.3112e+00, 5.2832e+00, 5.2550e+00, 5.2268e+00, 5.1990e+00, 5.1721e+00, 5.1459e+00, 5.1204e+00, 5.0958e+00, 5.0722e+00, 5.0495e+00, 5.0271e+00, 5.0045e+00, 4.9813e+00, 4.9578e+00, 4.9346e+00, 4.9120e+00, 4.8900e+00, 4.8685e+00, 4.8476e+00, 4.8274e+00, 4.8082e+00, 4.7896e+00, 4.7709e+00, 4.7517e+00, 4.7318e+00, 4.7114e+00, 4.6913e+00, 4.6717e+00, 4.6526e+00, 4.6338e+00, 4.6155e+00, 4.5977e+00, 4.5808e+00, 4.5645e+00, 4.5484e+00, 4.5317e+00, 4.5141e+00, 4.4958e+00, 4.4773e+00, 4.4591e+00, 4.4414e+00, 4.4240e+00, 4.4069e+00, 4.3901e+00, 4.3739e+00}); + feg = Vctr_cpu({1.2724e+01, 1.2524e+01, 1.1972e+01, 1.1190e+01, 1.0315e+01, 9.4495e+00, 8.6474e+00, 7.9248e+00, 7.2799e+00, 6.7055e+00, 6.1929e+00, 5.7339e+00, 5.3213e+00, 4.9490e+00, 4.6120e+00, 4.3060e+00, 4.0275e+00, 3.7734e+00, 3.5412e+00, 3.3285e+00, 3.1333e+00, 2.9541e+00, 2.7893e+00, 2.6374e+00, 2.4974e+00, 2.3681e+00, 2.2485e+00, 2.1378e+00, 2.0352e+00, 1.9400e+00, 1.8514e+00, 1.7690e+00, 1.6921e+00, 1.6203e+00, 1.5532e+00, 1.4903e+00, 1.4313e+00, 1.3759e+00, 1.3237e+00, 1.2745e+00, 1.2281e+00, 1.1842e+00, 1.1427e+00, 1.1033e+00, 1.0659e+00, 1.0304e+00, 9.9660e-01, 9.6440e-01, 9.3370e-01, 9.0440e-01, 8.7630e-01, 8.4950e-01, 8.2380e-01, 7.9930e-01, 7.7570e-01, 7.5310e-01, 7.3130e-01, 7.1050e-01, 6.9040e-01, 6.7110e-01, 6.5260e-01, 6.3470e-01, 6.1750e-01, 6.0100e-01, 5.8500e-01, 5.6970e-01, 5.5480e-01, 5.4050e-01, 5.2680e-01, 5.1350e-01, 5.0060e-01, 4.8820e-01, 4.7630e-01, 4.6470e-01, 4.5360e-01, 4.4280e-01, 4.3240e-01, 4.2230e-01, 4.1260e-01, 4.0320e-01, 3.9410e-01, 3.8530e-01, 3.7680e-01, 3.6860e-01, 3.6060e-01, 3.5290e-01, 3.4550e-01, 3.3820e-01, 3.3120e-01, 3.2450e-01, 3.1790e-01, 3.1150e-01, 3.0540e-01, 2.9940e-01, 2.9360e-01, 2.8790e-01, 2.8250e-01, 2.7720e-01, 2.7200e-01, 2.6700e-01, 2.6210e-01, 2.5740e-01, 2.5280e-01, 2.4840e-01, 2.4400e-01, 2.3980e-01, 2.3570e-01, 2.3170e-01, 2.2780e-01, 2.2400e-01, 2.2030e-01, 2.1670e-01, 2.1320e-01, 2.0980e-01, 2.0650e-01, 2.0320e-01, 2.0000e-01, 1.9690e-01, 1.9390e-01, 1.9100e-01, 1.8810e-01, 1.8530e-01, 1.8250e-01, 1.7990e-01, 1.7720e-01, 1.7470e-01, 1.7220e-01, 1.6970e-01, 1.6730e-01, 1.6490e-01, 1.6260e-01, 1.6040e-01, 1.5820e-01, 1.5600e-01, 1.5390e-01, 1.5180e-01, 1.4980e-01, 1.4780e-01, 1.4590e-01, 1.4390e-01, 1.4210e-01, 1.4020e-01, 1.3840e-01, 1.3660e-01, 1.3490e-01, 1.3320e-01, 1.3150e-01, 1.2990e-01, 1.2830e-01, 1.2670e-01, 1.2510e-01, 1.2360e-01, 1.2210e-01, 1.2060e-01, 1.1920e-01, 1.1780e-01, 1.1630e-01, 1.1500e-01, 1.1360e-01, 1.1230e-01, 1.1100e-01, 1.0970e-01, 1.0840e-01, 1.0720e-01, 1.0600e-01, 1.0480e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0010e-01, 9.9000e-02, 9.8000e-02, 9.6900e-02, 9.5800e-02, 9.4800e-02, 9.3800e-02, 9.2700e-02, 9.1800e-02, 9.0800e-02, 8.9800e-02, 8.8900e-02, 8.7900e-02, 8.7000e-02, 8.6100e-02, 8.5200e-02, 8.4300e-02, 8.3500e-02, 8.2600e-02, 8.1800e-02, 8.0900e-02, 8.0100e-02, 7.9300e-02, 7.8500e-02, 7.7800e-02, 7.7000e-02, 7.6200e-02, 7.5500e-02, 7.4700e-02, 7.4000e-02, 7.3300e-02, 7.2600e-02, 7.1900e-02, 7.1200e-02, 7.0500e-02, 6.9900e-02, 6.9200e-02, 6.8600e-02, 6.7900e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5400e-02, 6.4800e-02, 6.4300e-02, 6.3700e-02, 6.3100e-02, 6.2500e-02, 6.2000e-02, 6.1400e-02, 6.0900e-02, 6.0300e-02, 5.9800e-02, 5.9300e-02, 5.8800e-02, 5.8300e-02, 5.7800e-02, 5.7300e-02, 5.6800e-02, 5.6300e-02, 5.5800e-02, 5.5300e-02, 5.4900e-02, 5.4400e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1800e-02, 5.1400e-02, 5.0900e-02}); + } + break; + case 82: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.2000e+01, 8.1664e+01, 8.0713e+01, 7.9283e+01, 7.7537e+01, 7.5609e+01, 7.3595e+01, 7.1554e+01, 6.9518e+01, 6.7508e+01, 6.5535e+01, 6.3607e+01, 6.1731e+01, 5.9912e+01, 5.8154e+01, 5.6459e+01, 5.4829e+01, 5.3265e+01, 5.1767e+01, 5.0334e+01, 4.8965e+01, 4.7655e+01, 4.6404e+01, 4.5206e+01, 4.4060e+01, 4.2961e+01, 4.1906e+01, 4.0891e+01, 3.9914e+01, 3.8970e+01, 3.8058e+01, 3.7175e+01, 3.6319e+01, 3.5487e+01, 3.4678e+01, 3.3892e+01, 3.3126e+01, 3.2379e+01, 3.1652e+01, 3.0942e+01, 3.0251e+01, 2.9578e+01, 2.8922e+01, 2.8283e+01, 2.7662e+01, 2.7058e+01, 2.6471e+01, 2.5901e+01, 2.5349e+01, 2.4813e+01, 2.4295e+01, 2.3795e+01, 2.3311e+01, 2.2844e+01, 2.2394e+01, 2.1960e+01, 2.1543e+01, 2.1142e+01, 2.0756e+01, 2.0386e+01, 2.0031e+01, 1.9690e+01, 1.9364e+01, 1.9051e+01, 1.8751e+01, 1.8463e+01, 1.8188e+01, 1.7925e+01, 1.7672e+01, 1.7431e+01, 1.7199e+01, 1.6976e+01, 1.6763e+01, 1.6558e+01, 1.6361e+01, 1.6171e+01, 1.5988e+01, 1.5812e+01, 1.5641e+01, 1.5477e+01, 1.5317e+01, 1.5162e+01, 1.5012e+01, 1.4865e+01, 1.4722e+01, 1.4583e+01, 1.4446e+01, 1.4313e+01, 1.4181e+01, 1.4052e+01, 1.3925e+01, 1.3800e+01, 1.3676e+01, 1.3553e+01, 1.3432e+01, 1.3312e+01, 1.3193e+01, 1.3075e+01, 1.2958e+01, 1.2841e+01, 1.2724e+01, 1.2609e+01, 1.2493e+01, 1.2379e+01, 1.2264e+01, 1.2150e+01, 1.2036e+01, 1.1923e+01, 1.1810e+01, 1.1697e+01, 1.1585e+01, 1.1472e+01, 1.1360e+01, 1.1248e+01, 1.1138e+01, 1.1027e+01, 1.0917e+01, 1.0807e+01, 1.0698e+01, 1.0588e+01, 1.0480e+01, 1.0373e+01, 1.0267e+01, 1.0161e+01, 1.0055e+01, 9.9498e+00, 9.8456e+00, 9.7426e+00, 9.6409e+00, 9.5401e+00, 9.4400e+00, 9.3403e+00, 9.2413e+00, 9.1434e+00, 9.0470e+00, 8.9522e+00, 8.8588e+00, 8.7663e+00, 8.6745e+00, 8.5833e+00, 8.4931e+00, 8.4044e+00, 8.3174e+00, 8.2323e+00, 8.1486e+00, 8.0659e+00, 7.9839e+00, 7.9027e+00, 7.8224e+00, 7.7437e+00, 7.6668e+00, 7.5919e+00, 7.5186e+00, 7.4464e+00, 7.3751e+00, 7.3045e+00, 7.2346e+00, 7.1659e+00, 7.0988e+00, 7.0338e+00, 6.9706e+00, 6.9089e+00, 6.8482e+00, 6.7882e+00, 6.7288e+00, 6.6700e+00, 6.6123e+00, 6.5560e+00, 6.5017e+00, 6.4492e+00, 6.3982e+00, 6.3482e+00, 6.2987e+00, 6.2498e+00, 6.2013e+00, 6.1534e+00, 6.1065e+00, 6.0611e+00, 6.0175e+00, 5.9756e+00, 5.9348e+00, 5.8948e+00, 5.8551e+00, 5.8158e+00, 5.7767e+00, 5.7379e+00, 5.6998e+00, 5.6629e+00, 5.6277e+00, 5.5941e+00, 5.5616e+00, 5.5297e+00, 5.4981e+00, 5.4667e+00, 5.4354e+00, 5.4041e+00, 5.3730e+00, 5.3424e+00, 5.3129e+00, 5.2850e+00, 5.2585e+00, 5.2329e+00, 5.2076e+00, 5.1825e+00, 5.1573e+00, 5.1322e+00, 5.1069e+00, 5.0814e+00, 5.0560e+00, 5.0314e+00, 5.0080e+00, 4.9860e+00, 4.9651e+00, 4.9446e+00, 4.9242e+00, 4.9036e+00, 4.8829e+00, 4.8621e+00, 4.8410e+00, 4.8195e+00, 4.7979e+00, 4.7768e+00, 4.7568e+00, 4.7381e+00, 4.7205e+00, 4.7033e+00, 4.6860e+00, 4.6685e+00, 4.6508e+00, 4.6330e+00, 4.6148e+00, 4.5961e+00, 4.5770e+00, 4.5577e+00, 4.5389e+00, 4.5213e+00, 4.5049e+00, 4.4894e+00, 4.4742e+00, 4.4589e+00, 4.4431e+00}); + feg = Vctr_cpu({1.3040e+01, 1.2850e+01, 1.2321e+01, 1.1559e+01, 1.0683e+01, 9.7895e+00, 8.9402e+00, 8.1637e+00, 7.4683e+00, 6.8513e+00, 6.3051e+00, 5.8209e+00, 5.3900e+00, 5.0049e+00, 4.6590e+00, 4.3470e+00, 4.0644e+00, 3.8075e+00, 3.5732e+00, 3.3590e+00, 3.1626e+00, 2.9823e+00, 2.8164e+00, 2.6635e+00, 2.5223e+00, 2.3919e+00, 2.2712e+00, 2.1594e+00, 2.0557e+00, 1.9593e+00, 1.8697e+00, 1.7862e+00, 1.7083e+00, 1.6356e+00, 1.5676e+00, 1.5039e+00, 1.4441e+00, 1.3880e+00, 1.3352e+00, 1.2855e+00, 1.2385e+00, 1.1942e+00, 1.1523e+00, 1.1125e+00, 1.0748e+00, 1.0390e+00, 1.0049e+00, 9.7250e-01, 9.4160e-01, 9.1210e-01, 8.8390e-01, 8.5690e-01, 8.3120e-01, 8.0640e-01, 7.8280e-01, 7.6000e-01, 7.3820e-01, 7.1730e-01, 6.9720e-01, 6.7780e-01, 6.5920e-01, 6.4120e-01, 6.2400e-01, 6.0740e-01, 5.9130e-01, 5.7590e-01, 5.6100e-01, 5.4660e-01, 5.3270e-01, 5.1930e-01, 5.0640e-01, 4.9400e-01, 4.8190e-01, 4.7030e-01, 4.5900e-01, 4.4820e-01, 4.3760e-01, 4.2750e-01, 4.1770e-01, 4.0820e-01, 3.9900e-01, 3.9010e-01, 3.8150e-01, 3.7320e-01, 3.6510e-01, 3.5730e-01, 3.4980e-01, 3.4250e-01, 3.3540e-01, 3.2850e-01, 3.2180e-01, 3.1540e-01, 3.0910e-01, 3.0310e-01, 2.9720e-01, 2.9140e-01, 2.8590e-01, 2.8050e-01, 2.7530e-01, 2.7020e-01, 2.6530e-01, 2.6050e-01, 2.5580e-01, 2.5130e-01, 2.4690e-01, 2.4260e-01, 2.3840e-01, 2.3440e-01, 2.3040e-01, 2.2660e-01, 2.2280e-01, 2.1920e-01, 2.1560e-01, 2.1220e-01, 2.0880e-01, 2.0550e-01, 2.0230e-01, 1.9920e-01, 1.9610e-01, 1.9310e-01, 1.9020e-01, 1.8730e-01, 1.8460e-01, 1.8180e-01, 1.7920e-01, 1.7660e-01, 1.7400e-01, 1.7160e-01, 1.6910e-01, 1.6670e-01, 1.6440e-01, 1.6210e-01, 1.5990e-01, 1.5770e-01, 1.5560e-01, 1.5350e-01, 1.5140e-01, 1.4940e-01, 1.4740e-01, 1.4550e-01, 1.4360e-01, 1.4180e-01, 1.3990e-01, 1.3810e-01, 1.3640e-01, 1.3470e-01, 1.3300e-01, 1.3130e-01, 1.2970e-01, 1.2810e-01, 1.2650e-01, 1.2500e-01, 1.2340e-01, 1.2200e-01, 1.2050e-01, 1.1910e-01, 1.1760e-01, 1.1630e-01, 1.1490e-01, 1.1360e-01, 1.1220e-01, 1.1090e-01, 1.0970e-01, 1.0840e-01, 1.0720e-01, 1.0600e-01, 1.0480e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8000e-02, 9.6900e-02, 9.5900e-02, 9.4800e-02, 9.3800e-02, 9.2800e-02, 9.1800e-02, 9.0900e-02, 8.9900e-02, 8.9000e-02, 8.8000e-02, 8.7100e-02, 8.6200e-02, 8.5300e-02, 8.4500e-02, 8.3600e-02, 8.2700e-02, 8.1900e-02, 8.1100e-02, 8.0300e-02, 7.9500e-02, 7.8700e-02, 7.7900e-02, 7.7100e-02, 7.6400e-02, 7.5600e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2800e-02, 7.2100e-02, 7.1400e-02, 7.0700e-02, 7.0000e-02, 6.9400e-02, 6.8700e-02, 6.8100e-02, 6.7500e-02, 6.6900e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3300e-02, 6.2700e-02, 6.2200e-02, 6.1600e-02, 6.1100e-02, 6.0500e-02, 6.0000e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.8000e-02, 5.7500e-02, 5.7000e-02, 5.6500e-02, 5.6000e-02, 5.5500e-02, 5.5100e-02, 5.4600e-02, 5.4200e-02, 5.3700e-02, 5.3300e-02, 5.2800e-02, 5.2400e-02, 5.2000e-02, 5.1600e-02}); + } + break; + case 83: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.3000e+01, 8.2664e+01, 8.1703e+01, 8.0240e+01, 7.8435e+01, 7.6438e+01, 7.4361e+01, 7.2274e+01, 7.0212e+01, 6.8191e+01, 6.6221e+01, 6.4305e+01, 6.2445e+01, 6.0642e+01, 5.8895e+01, 5.7207e+01, 5.5578e+01, 5.4011e+01, 5.2505e+01, 5.1060e+01, 4.9675e+01, 4.8348e+01, 4.7078e+01, 4.5863e+01, 4.4699e+01, 4.3583e+01, 4.2513e+01, 4.1485e+01, 4.0496e+01, 3.9544e+01, 3.8624e+01, 3.7736e+01, 3.6875e+01, 3.6041e+01, 3.5231e+01, 3.4444e+01, 3.3678e+01, 3.2931e+01, 3.2204e+01, 3.1495e+01, 3.0804e+01, 3.0130e+01, 2.9473e+01, 2.8832e+01, 2.8208e+01, 2.7601e+01, 2.7009e+01, 2.6434e+01, 2.5875e+01, 2.5333e+01, 2.4807e+01, 2.4297e+01, 2.3804e+01, 2.3327e+01, 2.2865e+01, 2.2420e+01, 2.1991e+01, 2.1578e+01, 2.1179e+01, 2.0796e+01, 2.0427e+01, 2.0074e+01, 1.9734e+01, 1.9408e+01, 1.9095e+01, 1.8795e+01, 1.8508e+01, 1.8232e+01, 1.7968e+01, 1.7714e+01, 1.7471e+01, 1.7239e+01, 1.7015e+01, 1.6801e+01, 1.6595e+01, 1.6397e+01, 1.6206e+01, 1.6023e+01, 1.5846e+01, 1.5675e+01, 1.5510e+01, 1.5350e+01, 1.5195e+01, 1.5045e+01, 1.4899e+01, 1.4756e+01, 1.4617e+01, 1.4481e+01, 1.4348e+01, 1.4218e+01, 1.4090e+01, 1.3964e+01, 1.3840e+01, 1.3718e+01, 1.3598e+01, 1.3479e+01, 1.3360e+01, 1.3243e+01, 1.3127e+01, 1.3012e+01, 1.2897e+01, 1.2783e+01, 1.2670e+01, 1.2557e+01, 1.2444e+01, 1.2332e+01, 1.2221e+01, 1.2110e+01, 1.1998e+01, 1.1887e+01, 1.1777e+01, 1.1667e+01, 1.1557e+01, 1.1448e+01, 1.1338e+01, 1.1229e+01, 1.1120e+01, 1.1012e+01, 1.0905e+01, 1.0798e+01, 1.0690e+01, 1.0584e+01, 1.0478e+01, 1.0373e+01, 1.0268e+01, 1.0164e+01, 1.0061e+01, 9.9580e+00, 9.8560e+00, 9.7550e+00, 9.6547e+00, 9.5552e+00, 9.4566e+00, 9.3590e+00, 9.2622e+00, 9.1664e+00, 9.0716e+00, 8.9777e+00, 8.8850e+00, 8.7934e+00, 8.7030e+00, 8.6136e+00, 8.5254e+00, 8.4382e+00, 8.3521e+00, 8.2673e+00, 8.1836e+00, 8.1012e+00, 8.0202e+00, 7.9405e+00, 7.8620e+00, 7.7846e+00, 7.7082e+00, 7.6329e+00, 7.5590e+00, 7.4865e+00, 7.4155e+00, 7.3459e+00, 7.2775e+00, 7.2101e+00, 7.1437e+00, 7.0784e+00, 7.0142e+00, 6.9514e+00, 6.8900e+00, 6.8301e+00, 6.7716e+00, 6.7142e+00, 6.6576e+00, 6.6017e+00, 6.5467e+00, 6.4929e+00, 6.4404e+00, 6.3893e+00, 6.3396e+00, 6.2911e+00, 6.2436e+00, 6.1969e+00, 6.1507e+00, 6.1051e+00, 6.0603e+00, 6.0166e+00, 5.9742e+00, 5.9331e+00, 5.8933e+00, 5.8544e+00, 5.8162e+00, 5.7785e+00, 5.7412e+00, 5.7042e+00, 5.6678e+00, 5.6323e+00, 5.5979e+00, 5.5648e+00, 5.5329e+00, 5.5017e+00, 5.4711e+00, 5.4407e+00, 5.4105e+00, 5.3805e+00, 5.3508e+00, 5.3215e+00, 5.2931e+00, 5.2656e+00, 5.2393e+00, 5.2141e+00, 5.1893e+00, 5.1648e+00, 5.1402e+00, 5.1157e+00, 5.0911e+00, 5.0667e+00, 5.0426e+00, 5.0189e+00, 4.9960e+00, 4.9743e+00, 4.9535e+00, 4.9334e+00, 4.9133e+00, 4.8930e+00, 4.8725e+00, 4.8519e+00, 4.8313e+00, 4.8106e+00, 4.7901e+00, 4.7698e+00, 4.7505e+00, 4.7321e+00, 4.7148e+00, 4.6978e+00, 4.6807e+00, 4.6632e+00, 4.6454e+00, 4.6275e+00, 4.6094e+00, 4.5911e+00, 4.5727e+00, 4.5543e+00, 4.5366e+00, 4.5198e+00, 4.5039e+00}); + feg = Vctr_cpu({1.3020e+01, 1.2863e+01, 1.2417e+01, 1.1743e+01, 1.0926e+01, 1.0052e+01, 9.1896e+00, 8.3826e+00, 7.6518e+00, 7.0011e+00, 6.4255e+00, 5.9167e+00, 5.4661e+00, 5.0661e+00, 4.7095e+00, 4.3899e+00, 4.1019e+00, 3.8412e+00, 3.6042e+00, 3.3881e+00, 3.1904e+00, 3.0090e+00, 2.8421e+00, 2.6883e+00, 2.5464e+00, 2.4151e+00, 2.2935e+00, 2.1808e+00, 2.0761e+00, 1.9787e+00, 1.8881e+00, 1.8037e+00, 1.7249e+00, 1.6513e+00, 1.5824e+00, 1.5179e+00, 1.4574e+00, 1.4005e+00, 1.3471e+00, 1.2967e+00, 1.2492e+00, 1.2044e+00, 1.1620e+00, 1.1219e+00, 1.0838e+00, 1.0476e+00, 1.0133e+00, 9.8060e-01, 9.4940e-01, 9.1970e-01, 8.9140e-01, 8.6430e-01, 8.3830e-01, 8.1350e-01, 7.8970e-01, 7.6690e-01, 7.4500e-01, 7.2390e-01, 7.0370e-01, 6.8430e-01, 6.6560e-01, 6.4760e-01, 6.3030e-01, 6.1360e-01, 5.9750e-01, 5.8190e-01, 5.6700e-01, 5.5250e-01, 5.3860e-01, 5.2510e-01, 5.1210e-01, 4.9960e-01, 4.8740e-01, 4.7570e-01, 4.6440e-01, 4.5340e-01, 4.4280e-01, 4.3260e-01, 4.2270e-01, 4.1310e-01, 4.0380e-01, 3.9480e-01, 3.8620e-01, 3.7770e-01, 3.6960e-01, 3.6170e-01, 3.5410e-01, 3.4670e-01, 3.3950e-01, 3.3250e-01, 3.2580e-01, 3.1920e-01, 3.1290e-01, 3.0670e-01, 3.0080e-01, 2.9500e-01, 2.8940e-01, 2.8390e-01, 2.7860e-01, 2.7350e-01, 2.6850e-01, 2.6360e-01, 2.5890e-01, 2.5430e-01, 2.4980e-01, 2.4550e-01, 2.4120e-01, 2.3710e-01, 2.3310e-01, 2.2920e-01, 2.2540e-01, 2.2170e-01, 2.1810e-01, 2.1460e-01, 2.1120e-01, 2.0780e-01, 2.0460e-01, 2.0140e-01, 1.9830e-01, 1.9520e-01, 1.9230e-01, 1.8940e-01, 1.8660e-01, 1.8380e-01, 1.8110e-01, 1.7850e-01, 1.7590e-01, 1.7340e-01, 1.7100e-01, 1.6850e-01, 1.6620e-01, 1.6390e-01, 1.6160e-01, 1.5940e-01, 1.5730e-01, 1.5510e-01, 1.5310e-01, 1.5100e-01, 1.4900e-01, 1.4710e-01, 1.4520e-01, 1.4330e-01, 1.4140e-01, 1.3960e-01, 1.3790e-01, 1.3610e-01, 1.3440e-01, 1.3270e-01, 1.3110e-01, 1.2950e-01, 1.2790e-01, 1.2630e-01, 1.2480e-01, 1.2330e-01, 1.2180e-01, 1.2040e-01, 1.1890e-01, 1.1750e-01, 1.1620e-01, 1.1480e-01, 1.1350e-01, 1.1220e-01, 1.1090e-01, 1.0960e-01, 1.0840e-01, 1.0710e-01, 1.0590e-01, 1.0470e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.5900e-02, 9.4900e-02, 9.3900e-02, 9.2900e-02, 9.1900e-02, 9.0900e-02, 9.0000e-02, 8.9000e-02, 8.8100e-02, 8.7200e-02, 8.6300e-02, 8.5400e-02, 8.4600e-02, 8.3700e-02, 8.2900e-02, 8.2000e-02, 8.1200e-02, 8.0400e-02, 7.9600e-02, 7.8800e-02, 7.8000e-02, 7.7300e-02, 7.6500e-02, 7.5800e-02, 7.5100e-02, 7.4300e-02, 7.3600e-02, 7.2900e-02, 7.2200e-02, 7.1600e-02, 7.0900e-02, 7.0200e-02, 6.9600e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7000e-02, 6.6400e-02, 6.5800e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2400e-02, 6.1800e-02, 6.1300e-02, 6.0700e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5300e-02, 5.4800e-02, 5.4400e-02, 5.3900e-02, 5.3500e-02, 5.3000e-02, 5.2600e-02, 5.2200e-02}); + } + break; + case 84: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.4000e+01, 8.3683e+01, 8.2768e+01, 8.1352e+01, 7.9566e+01, 7.7544e+01, 7.5403e+01, 7.3227e+01, 7.1074e+01, 6.8975e+01, 6.6946e+01, 6.4992e+01, 6.3111e+01, 6.1301e+01, 5.9559e+01, 5.7880e+01, 5.6263e+01, 5.4706e+01, 5.3207e+01, 5.1765e+01, 5.0379e+01, 4.9047e+01, 4.7769e+01, 4.6542e+01, 4.5365e+01, 4.4235e+01, 4.3150e+01, 4.2107e+01, 4.1104e+01, 4.0138e+01, 3.9207e+01, 3.8308e+01, 3.7439e+01, 3.6597e+01, 3.5782e+01, 3.4990e+01, 3.4220e+01, 3.3471e+01, 3.2742e+01, 3.2032e+01, 3.1340e+01, 3.0665e+01, 3.0007e+01, 2.9365e+01, 2.8740e+01, 2.8130e+01, 2.7536e+01, 2.6957e+01, 2.6394e+01, 2.5847e+01, 2.5315e+01, 2.4799e+01, 2.4298e+01, 2.3813e+01, 2.3343e+01, 2.2888e+01, 2.2449e+01, 2.2024e+01, 2.1615e+01, 2.1220e+01, 2.0840e+01, 2.0474e+01, 2.0122e+01, 1.9784e+01, 1.9458e+01, 1.9146e+01, 1.8846e+01, 1.8559e+01, 1.8282e+01, 1.8018e+01, 1.7764e+01, 1.7520e+01, 1.7286e+01, 1.7061e+01, 1.6846e+01, 1.6639e+01, 1.6440e+01, 1.6248e+01, 1.6063e+01, 1.5886e+01, 1.5714e+01, 1.5548e+01, 1.5388e+01, 1.5232e+01, 1.5082e+01, 1.4935e+01, 1.4793e+01, 1.4654e+01, 1.4519e+01, 1.4386e+01, 1.4257e+01, 1.4130e+01, 1.4005e+01, 1.3882e+01, 1.3761e+01, 1.3642e+01, 1.3524e+01, 1.3407e+01, 1.3292e+01, 1.3178e+01, 1.3064e+01, 1.2952e+01, 1.2840e+01, 1.2729e+01, 1.2618e+01, 1.2508e+01, 1.2398e+01, 1.2289e+01, 1.2180e+01, 1.2071e+01, 1.1962e+01, 1.1854e+01, 1.1746e+01, 1.1639e+01, 1.1532e+01, 1.1425e+01, 1.1318e+01, 1.1211e+01, 1.1105e+01, 1.1000e+01, 1.0895e+01, 1.0790e+01, 1.0685e+01, 1.0580e+01, 1.0477e+01, 1.0374e+01, 1.0272e+01, 1.0170e+01, 1.0069e+01, 9.9676e+00, 9.8673e+00, 9.7679e+00, 9.6697e+00, 9.5724e+00, 9.4760e+00, 9.3801e+00, 9.2847e+00, 9.1900e+00, 9.0962e+00, 9.0039e+00, 8.9129e+00, 8.8232e+00, 8.7345e+00, 8.6464e+00, 8.5589e+00, 8.4721e+00, 8.3866e+00, 8.3026e+00, 8.2204e+00, 8.1396e+00, 8.0600e+00, 7.9812e+00, 7.9030e+00, 7.8255e+00, 7.7490e+00, 7.6740e+00, 7.6008e+00, 7.5295e+00, 7.4596e+00, 7.3909e+00, 7.3229e+00, 7.2553e+00, 7.1884e+00, 7.1224e+00, 7.0580e+00, 6.9955e+00, 6.9348e+00, 6.8758e+00, 6.8180e+00, 6.7608e+00, 6.7040e+00, 6.6475e+00, 6.5916e+00, 6.5370e+00, 6.4839e+00, 6.4328e+00, 6.3835e+00, 6.3356e+00, 6.2887e+00, 6.2422e+00, 6.1958e+00, 6.1495e+00, 6.1036e+00, 6.0586e+00, 6.0152e+00, 5.9735e+00, 5.9337e+00, 5.8952e+00, 5.8578e+00, 5.8208e+00, 5.7838e+00, 5.7465e+00, 5.7092e+00, 5.6722e+00, 5.6362e+00, 5.6016e+00, 5.5688e+00, 5.5375e+00, 5.5075e+00, 5.4783e+00, 5.4494e+00, 5.4202e+00, 5.3906e+00, 5.3605e+00, 5.3303e+00, 5.3008e+00, 5.2724e+00, 5.2456e+00, 5.2203e+00, 5.1963e+00, 5.1732e+00, 5.1506e+00, 5.1278e+00, 5.1045e+00, 5.0805e+00, 5.0557e+00, 5.0308e+00, 5.0063e+00, 4.9829e+00, 4.9609e+00, 4.9403e+00, 4.9209e+00, 4.9023e+00, 4.8842e+00, 4.8660e+00, 4.8473e+00, 4.8278e+00, 4.8072e+00, 4.7859e+00, 4.7645e+00, 4.7436e+00, 4.7238e+00, 4.7053e+00, 4.6881e+00, 4.6720e+00, 4.6565e+00, 4.6414e+00, 4.6261e+00, 4.6104e+00, 4.5936e+00, 4.5757e+00}); + feg = Vctr_cpu({1.2261e+01, 1.2141e+01, 1.1796e+01, 1.1268e+01, 1.0613e+01, 9.8886e+00, 9.1451e+00, 8.4190e+00, 7.7342e+00, 7.1032e+00, 6.5306e+00, 6.0158e+00, 5.5550e+00, 5.1434e+00, 4.7753e+00, 4.4455e+00, 4.1490e+00, 3.8816e+00, 3.6395e+00, 3.4194e+00, 3.2187e+00, 3.0351e+00, 2.8666e+00, 2.7115e+00, 2.5686e+00, 2.4364e+00, 2.3141e+00, 2.2006e+00, 2.0952e+00, 1.9972e+00, 1.9059e+00, 1.8207e+00, 1.7412e+00, 1.6669e+00, 1.5973e+00, 1.5321e+00, 1.4709e+00, 1.4134e+00, 1.3593e+00, 1.3084e+00, 1.2603e+00, 1.2150e+00, 1.1721e+00, 1.1315e+00, 1.0930e+00, 1.0565e+00, 1.0219e+00, 9.8890e-01, 9.5740e-01, 9.2750e-01, 8.9890e-01, 8.7160e-01, 8.4550e-01, 8.2050e-01, 7.9660e-01, 7.7360e-01, 7.5160e-01, 7.3050e-01, 7.1020e-01, 6.9060e-01, 6.7180e-01, 6.5380e-01, 6.3640e-01, 6.1960e-01, 6.0340e-01, 5.8780e-01, 5.7280e-01, 5.5830e-01, 5.4420e-01, 5.3070e-01, 5.1760e-01, 5.0500e-01, 4.9280e-01, 4.8100e-01, 4.6960e-01, 4.5860e-01, 4.4790e-01, 4.3760e-01, 4.2760e-01, 4.1790e-01, 4.0860e-01, 3.9950e-01, 3.9080e-01, 3.8230e-01, 3.7400e-01, 3.6610e-01, 3.5830e-01, 3.5080e-01, 3.4360e-01, 3.3650e-01, 3.2970e-01, 3.2310e-01, 3.1670e-01, 3.1050e-01, 3.0440e-01, 2.9850e-01, 2.9280e-01, 2.8730e-01, 2.8190e-01, 2.7670e-01, 2.7160e-01, 2.6670e-01, 2.6190e-01, 2.5730e-01, 2.5270e-01, 2.4830e-01, 2.4400e-01, 2.3990e-01, 2.3580e-01, 2.3180e-01, 2.2800e-01, 2.2420e-01, 2.2060e-01, 2.1700e-01, 2.1350e-01, 2.1010e-01, 2.0680e-01, 2.0360e-01, 2.0050e-01, 1.9740e-01, 1.9440e-01, 1.9150e-01, 1.8860e-01, 1.8580e-01, 1.8310e-01, 1.8040e-01, 1.7780e-01, 1.7530e-01, 1.7280e-01, 1.7040e-01, 1.6800e-01, 1.6560e-01, 1.6340e-01, 1.6110e-01, 1.5890e-01, 1.5680e-01, 1.5470e-01, 1.5260e-01, 1.5060e-01, 1.4860e-01, 1.4670e-01, 1.4480e-01, 1.4290e-01, 1.4110e-01, 1.3930e-01, 1.3760e-01, 1.3580e-01, 1.3410e-01, 1.3250e-01, 1.3080e-01, 1.2920e-01, 1.2770e-01, 1.2610e-01, 1.2460e-01, 1.2310e-01, 1.2170e-01, 1.2020e-01, 1.1880e-01, 1.1740e-01, 1.1600e-01, 1.1470e-01, 1.1340e-01, 1.1210e-01, 1.1080e-01, 1.0950e-01, 1.0830e-01, 1.0710e-01, 1.0590e-01, 1.0470e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.4900e-02, 9.3900e-02, 9.2900e-02, 9.2000e-02, 9.1000e-02, 9.0100e-02, 8.9100e-02, 8.8200e-02, 8.7300e-02, 8.6400e-02, 8.5500e-02, 8.4700e-02, 8.3800e-02, 8.3000e-02, 8.2100e-02, 8.1300e-02, 8.0500e-02, 7.9700e-02, 7.9000e-02, 7.8200e-02, 7.7400e-02, 7.6700e-02, 7.5900e-02, 7.5200e-02, 7.4500e-02, 7.3800e-02, 7.3100e-02, 7.2400e-02, 7.1700e-02, 7.1000e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8400e-02, 6.7800e-02, 6.7200e-02, 6.6600e-02, 6.6000e-02, 6.5400e-02, 6.4800e-02, 6.4200e-02, 6.3700e-02, 6.3100e-02, 6.2600e-02, 6.2000e-02, 6.1500e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5500e-02, 5.5000e-02, 5.4600e-02, 5.4100e-02, 5.3700e-02, 5.3200e-02, 5.2800e-02}); + } + break; + case 85: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.5000e+01, 8.4653e+01, 8.3656e+01, 8.2130e+01, 8.0232e+01, 7.8118e+01, 7.5914e+01, 7.3710e+01, 7.1557e+01, 6.9479e+01, 6.7483e+01, 6.5568e+01, 6.3726e+01, 6.1950e+01, 6.0236e+01, 5.8577e+01, 5.6973e+01, 5.5421e+01, 5.3920e+01, 5.2471e+01, 5.1074e+01, 4.9729e+01, 4.8435e+01, 4.7191e+01, 4.5996e+01, 4.4850e+01, 4.3749e+01, 4.2692e+01, 4.1677e+01, 4.0700e+01, 3.9760e+01, 3.8853e+01, 3.7979e+01, 3.7133e+01, 3.6314e+01, 3.5520e+01, 3.4750e+01, 3.4001e+01, 3.3272e+01, 3.2562e+01, 3.1871e+01, 3.1196e+01, 3.0538e+01, 2.9896e+01, 2.9269e+01, 2.8658e+01, 2.8062e+01, 2.7480e+01, 2.6913e+01, 2.6361e+01, 2.5824e+01, 2.5301e+01, 2.4793e+01, 2.4300e+01, 2.3822e+01, 2.3358e+01, 2.2908e+01, 2.2474e+01, 2.2053e+01, 2.1648e+01, 2.1256e+01, 2.0878e+01, 2.0514e+01, 2.0163e+01, 1.9826e+01, 1.9502e+01, 1.9190e+01, 1.8890e+01, 1.8602e+01, 1.8326e+01, 1.8061e+01, 1.7806e+01, 1.7562e+01, 1.7327e+01, 1.7102e+01, 1.6885e+01, 1.6677e+01, 1.6478e+01, 1.6285e+01, 1.6100e+01, 1.5922e+01, 1.5749e+01, 1.5583e+01, 1.5422e+01, 1.5267e+01, 1.5116e+01, 1.4970e+01, 1.4828e+01, 1.4689e+01, 1.4554e+01, 1.4422e+01, 1.4294e+01, 1.4167e+01, 1.4043e+01, 1.3922e+01, 1.3802e+01, 1.3684e+01, 1.3568e+01, 1.3453e+01, 1.3339e+01, 1.3227e+01, 1.3115e+01, 1.3005e+01, 1.2895e+01, 1.2786e+01, 1.2677e+01, 1.2569e+01, 1.2461e+01, 1.2354e+01, 1.2247e+01, 1.2140e+01, 1.2034e+01, 1.1928e+01, 1.1823e+01, 1.1718e+01, 1.1612e+01, 1.1507e+01, 1.1402e+01, 1.1298e+01, 1.1194e+01, 1.1091e+01, 1.0987e+01, 1.0884e+01, 1.0781e+01, 1.0678e+01, 1.0576e+01, 1.0475e+01, 1.0375e+01, 1.0274e+01, 1.0174e+01, 1.0075e+01, 9.9754e+00, 9.8771e+00, 9.7799e+00, 9.6837e+00, 9.5882e+00, 9.4931e+00, 9.3984e+00, 9.3042e+00, 9.2110e+00, 9.1191e+00, 9.0286e+00, 8.9393e+00, 8.8508e+00, 8.7629e+00, 8.6754e+00, 8.5887e+00, 8.5031e+00, 8.4190e+00, 8.3366e+00, 8.2556e+00, 8.1757e+00, 8.0965e+00, 8.0179e+00, 7.9399e+00, 7.8628e+00, 7.7873e+00, 7.7135e+00, 7.6414e+00, 7.5709e+00, 7.5014e+00, 7.4325e+00, 7.3641e+00, 7.2963e+00, 7.2295e+00, 7.1641e+00, 7.1006e+00, 7.0390e+00, 6.9789e+00, 6.9200e+00, 6.8617e+00, 6.8038e+00, 6.7463e+00, 6.6893e+00, 6.6336e+00, 6.5794e+00, 6.5272e+00, 6.4767e+00, 6.4276e+00, 6.3794e+00, 6.3317e+00, 6.2842e+00, 6.2368e+00, 6.1898e+00, 6.1438e+00, 6.0992e+00, 6.0564e+00, 6.0154e+00, 5.9758e+00, 5.9371e+00, 5.8988e+00, 5.8607e+00, 5.8225e+00, 5.7842e+00, 5.7463e+00, 5.7093e+00, 5.6738e+00, 5.6400e+00, 5.6077e+00, 5.5766e+00, 5.5463e+00, 5.5162e+00, 5.4861e+00, 5.4557e+00, 5.4250e+00, 5.3942e+00, 5.3639e+00, 5.3348e+00, 5.3072e+00, 5.2812e+00, 5.2564e+00, 5.2324e+00, 5.2087e+00, 5.1851e+00, 5.1612e+00, 5.1367e+00, 5.1117e+00, 5.0864e+00, 5.0615e+00, 5.0376e+00, 5.0151e+00, 4.9941e+00, 4.9742e+00, 4.9549e+00, 4.9360e+00, 4.9171e+00, 4.8979e+00, 4.8781e+00, 4.8575e+00, 4.8362e+00, 4.8148e+00, 4.7937e+00, 4.7737e+00, 4.7551e+00, 4.7378e+00, 4.7214e+00, 4.7054e+00, 4.6897e+00, 4.6738e+00, 4.6576e+00, 4.6409e+00}); + feg = Vctr_cpu({1.3447e+01, 1.3296e+01, 1.2865e+01, 1.2212e+01, 1.1412e+01, 1.0542e+01, 9.6645e+00, 8.8231e+00, 8.0436e+00, 7.3378e+00, 6.7078e+00, 6.1499e+00, 5.6575e+00, 5.2229e+00, 4.8384e+00, 4.4970e+00, 4.1924e+00, 3.9194e+00, 3.6734e+00, 3.4505e+00, 3.2479e+00, 3.0627e+00, 2.8930e+00, 2.7370e+00, 2.5930e+00, 2.4600e+00, 2.3368e+00, 2.2224e+00, 2.1161e+00, 2.0171e+00, 1.9249e+00, 1.8388e+00, 1.7584e+00, 1.6832e+00, 1.6128e+00, 1.5467e+00, 1.4848e+00, 1.4266e+00, 1.3718e+00, 1.3202e+00, 1.2716e+00, 1.2257e+00, 1.1823e+00, 1.1412e+00, 1.1023e+00, 1.0655e+00, 1.0304e+00, 9.9710e-01, 9.6540e-01, 9.3520e-01, 9.0640e-01, 8.7890e-01, 8.5260e-01, 8.2750e-01, 8.0340e-01, 7.8030e-01, 7.5820e-01, 7.3700e-01, 7.1650e-01, 6.9690e-01, 6.7810e-01, 6.5990e-01, 6.4240e-01, 6.2560e-01, 6.0930e-01, 5.9370e-01, 5.7850e-01, 5.6400e-01, 5.4990e-01, 5.3630e-01, 5.2310e-01, 5.1040e-01, 4.9820e-01, 4.8630e-01, 4.7480e-01, 4.6370e-01, 4.5300e-01, 4.4260e-01, 4.3250e-01, 4.2280e-01, 4.1330e-01, 4.0420e-01, 3.9530e-01, 3.8680e-01, 3.7850e-01, 3.7040e-01, 3.6260e-01, 3.5500e-01, 3.4770e-01, 3.4060e-01, 3.3370e-01, 3.2700e-01, 3.2050e-01, 3.1420e-01, 3.0800e-01, 3.0210e-01, 2.9630e-01, 2.9070e-01, 2.8530e-01, 2.8000e-01, 2.7480e-01, 2.6990e-01, 2.6500e-01, 2.6030e-01, 2.5570e-01, 2.5120e-01, 2.4690e-01, 2.4260e-01, 2.3850e-01, 2.3450e-01, 2.3060e-01, 2.2680e-01, 2.2310e-01, 2.1950e-01, 2.1590e-01, 2.1250e-01, 2.0910e-01, 2.0590e-01, 2.0270e-01, 1.9960e-01, 1.9650e-01, 1.9360e-01, 1.9070e-01, 1.8790e-01, 1.8510e-01, 1.8240e-01, 1.7980e-01, 1.7720e-01, 1.7470e-01, 1.7220e-01, 1.6980e-01, 1.6740e-01, 1.6510e-01, 1.6280e-01, 1.6060e-01, 1.5850e-01, 1.5630e-01, 1.5420e-01, 1.5220e-01, 1.5020e-01, 1.4830e-01, 1.4630e-01, 1.4440e-01, 1.4260e-01, 1.4080e-01, 1.3900e-01, 1.3730e-01, 1.3560e-01, 1.3390e-01, 1.3220e-01, 1.3060e-01, 1.2900e-01, 1.2750e-01, 1.2590e-01, 1.2440e-01, 1.2300e-01, 1.2150e-01, 1.2010e-01, 1.1870e-01, 1.1730e-01, 1.1590e-01, 1.1460e-01, 1.1330e-01, 1.1200e-01, 1.1070e-01, 1.0950e-01, 1.0830e-01, 1.0700e-01, 1.0590e-01, 1.0470e-01, 1.0350e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8100e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3000e-02, 9.2000e-02, 9.1100e-02, 9.0100e-02, 8.9200e-02, 8.8300e-02, 8.7400e-02, 8.6500e-02, 8.5600e-02, 8.4800e-02, 8.3900e-02, 8.3100e-02, 8.2200e-02, 8.1400e-02, 8.0600e-02, 7.9900e-02, 7.9100e-02, 7.8300e-02, 7.7500e-02, 7.6800e-02, 7.6100e-02, 7.5300e-02, 7.4600e-02, 7.3900e-02, 7.3200e-02, 7.2500e-02, 7.1900e-02, 7.1200e-02, 7.0500e-02, 6.9900e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7400e-02, 6.6800e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3800e-02, 6.3300e-02, 6.2700e-02, 6.2200e-02, 6.1600e-02, 6.1100e-02, 6.0600e-02, 6.0100e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.8000e-02, 5.7600e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5700e-02, 5.5200e-02, 5.4800e-02, 5.4300e-02, 5.3900e-02, 5.3400e-02}); + } + break; + case 86: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.6000e+01, 8.5652e+01, 8.4649e+01, 8.3106e+01, 8.1173e+01, 7.9008e+01, 7.6742e+01, 7.4473e+01, 7.2261e+01, 7.0137e+01, 6.8110e+01, 6.6178e+01, 6.4332e+01, 6.2563e+01, 6.0861e+01, 5.9219e+01, 5.7630e+01, 5.6092e+01, 5.4603e+01, 5.3160e+01, 5.1766e+01, 5.0418e+01, 4.9117e+01, 4.7864e+01, 4.6658e+01, 4.5498e+01, 4.4382e+01, 4.3310e+01, 4.2279e+01, 4.1288e+01, 4.0335e+01, 3.9416e+01, 3.8531e+01, 3.7676e+01, 3.6850e+01, 3.6050e+01, 3.5275e+01, 3.4523e+01, 3.3792e+01, 3.3080e+01, 3.2388e+01, 3.1713e+01, 3.1054e+01, 3.0412e+01, 2.9785e+01, 2.9173e+01, 2.8576e+01, 2.7993e+01, 2.7424e+01, 2.6869e+01, 2.6328e+01, 2.5801e+01, 2.5288e+01, 2.4790e+01, 2.4305e+01, 2.3833e+01, 2.3376e+01, 2.2933e+01, 2.2504e+01, 2.2088e+01, 2.1686e+01, 2.1298e+01, 2.0923e+01, 2.0561e+01, 2.0212e+01, 1.9876e+01, 1.9553e+01, 1.9241e+01, 1.8942e+01, 1.8654e+01, 1.8378e+01, 1.8112e+01, 1.7857e+01, 1.7611e+01, 1.7376e+01, 1.7150e+01, 1.6932e+01, 1.6723e+01, 1.6522e+01, 1.6329e+01, 1.6142e+01, 1.5963e+01, 1.5790e+01, 1.5623e+01, 1.5462e+01, 1.5306e+01, 1.5155e+01, 1.5008e+01, 1.4866e+01, 1.4727e+01, 1.4592e+01, 1.4461e+01, 1.4332e+01, 1.4207e+01, 1.4084e+01, 1.3963e+01, 1.3844e+01, 1.3727e+01, 1.3612e+01, 1.3498e+01, 1.3386e+01, 1.3275e+01, 1.3165e+01, 1.3056e+01, 1.2948e+01, 1.2841e+01, 1.2735e+01, 1.2629e+01, 1.2523e+01, 1.2418e+01, 1.2313e+01, 1.2209e+01, 1.2105e+01, 1.2001e+01, 1.1898e+01, 1.1794e+01, 1.1691e+01, 1.1588e+01, 1.1486e+01, 1.1384e+01, 1.1282e+01, 1.1180e+01, 1.1078e+01, 1.0977e+01, 1.0876e+01, 1.0775e+01, 1.0676e+01, 1.0576e+01, 1.0477e+01, 1.0377e+01, 1.0278e+01, 1.0180e+01, 1.0083e+01, 9.9867e+00, 9.8908e+00, 9.7953e+00, 9.7000e+00, 9.6053e+00, 9.5113e+00, 9.4184e+00, 9.3267e+00, 9.2361e+00, 9.1461e+00, 9.0567e+00, 8.9677e+00, 8.8793e+00, 8.7919e+00, 8.7059e+00, 8.6214e+00, 8.5381e+00, 8.4559e+00, 8.3744e+00, 8.2933e+00, 8.2128e+00, 8.1333e+00, 8.0551e+00, 7.9785e+00, 7.9037e+00, 7.8302e+00, 7.7577e+00, 7.6859e+00, 7.6145e+00, 7.5437e+00, 7.4738e+00, 7.4054e+00, 7.3388e+00, 7.2739e+00, 7.2106e+00, 7.1484e+00, 7.0869e+00, 7.0258e+00, 6.9650e+00, 6.9049e+00, 6.8460e+00, 6.7887e+00, 6.7332e+00, 6.6794e+00, 6.6271e+00, 6.5758e+00, 6.5249e+00, 6.4742e+00, 6.4237e+00, 6.3737e+00, 6.3247e+00, 6.2772e+00, 6.2314e+00, 6.1874e+00, 6.1449e+00, 6.1033e+00, 6.0623e+00, 6.0214e+00, 5.9804e+00, 5.9394e+00, 5.8988e+00, 5.8593e+00, 5.8212e+00, 5.7849e+00, 5.7501e+00, 5.7166e+00, 5.6840e+00, 5.6518e+00, 5.6194e+00, 5.5867e+00, 5.5537e+00, 5.5207e+00, 5.4885e+00, 5.4574e+00, 5.4279e+00, 5.3999e+00, 5.3732e+00, 5.3475e+00, 5.3223e+00, 5.2971e+00, 5.2716e+00, 5.2454e+00, 5.2186e+00, 5.1918e+00, 5.1655e+00, 5.1402e+00, 5.1164e+00, 5.0940e+00, 5.0728e+00, 5.0524e+00, 5.0326e+00, 5.0128e+00, 4.9926e+00, 4.9717e+00, 4.9499e+00, 4.9275e+00, 4.9051e+00, 4.8832e+00, 4.8625e+00, 4.8430e+00, 4.8249e+00, 4.8077e+00, 4.7912e+00, 4.7750e+00, 4.7589e+00, 4.7424e+00, 4.7251e+00, 4.7067e+00}); + feg = Vctr_cpu({1.3471e+01, 1.3331e+01, 1.2930e+01, 1.2315e+01, 1.1553e+01, 1.0711e+01, 9.8477e+00, 9.0082e+00, 8.2203e+00, 7.4995e+00, 6.8508e+00, 6.2733e+00, 5.7621e+00, 5.3106e+00, 4.9115e+00, 4.5580e+00, 4.2437e+00, 3.9629e+00, 3.7109e+00, 3.4835e+00, 3.2774e+00, 3.0898e+00, 2.9181e+00, 2.7606e+00, 2.6156e+00, 2.4816e+00, 2.3576e+00, 2.2425e+00, 2.1355e+00, 2.0359e+00, 1.9430e+00, 1.8563e+00, 1.7752e+00, 1.6993e+00, 1.6281e+00, 1.5614e+00, 1.4988e+00, 1.4399e+00, 1.3845e+00, 1.3323e+00, 1.2831e+00, 1.2367e+00, 1.1928e+00, 1.1513e+00, 1.1119e+00, 1.0746e+00, 1.0392e+00, 1.0056e+00, 9.7360e-01, 9.4310e-01, 9.1400e-01, 8.8630e-01, 8.5980e-01, 8.3450e-01, 8.1020e-01, 7.8700e-01, 7.6470e-01, 7.4330e-01, 7.2280e-01, 7.0310e-01, 6.8410e-01, 6.6590e-01, 6.4830e-01, 6.3140e-01, 6.1510e-01, 5.9930e-01, 5.8410e-01, 5.6950e-01, 5.5530e-01, 5.4170e-01, 5.2850e-01, 5.1570e-01, 5.0340e-01, 4.9140e-01, 4.7990e-01, 4.6870e-01, 4.5790e-01, 4.4740e-01, 4.3730e-01, 4.2750e-01, 4.1800e-01, 4.0880e-01, 3.9990e-01, 3.9120e-01, 3.8280e-01, 3.7470e-01, 3.6680e-01, 3.5920e-01, 3.5180e-01, 3.4460e-01, 3.3760e-01, 3.3080e-01, 3.2420e-01, 3.1790e-01, 3.1170e-01, 3.0570e-01, 2.9980e-01, 2.9410e-01, 2.8860e-01, 2.8330e-01, 2.7810e-01, 2.7300e-01, 2.6810e-01, 2.6330e-01, 2.5860e-01, 2.5410e-01, 2.4970e-01, 2.4540e-01, 2.4120e-01, 2.3720e-01, 2.3320e-01, 2.2930e-01, 2.2560e-01, 2.2190e-01, 2.1830e-01, 2.1490e-01, 2.1150e-01, 2.0820e-01, 2.0490e-01, 2.0180e-01, 1.9870e-01, 1.9570e-01, 1.9280e-01, 1.8990e-01, 1.8710e-01, 1.8440e-01, 1.8170e-01, 1.7910e-01, 1.7650e-01, 1.7400e-01, 1.7160e-01, 1.6920e-01, 1.6680e-01, 1.6460e-01, 1.6230e-01, 1.6010e-01, 1.5800e-01, 1.5590e-01, 1.5380e-01, 1.5180e-01, 1.4980e-01, 1.4790e-01, 1.4600e-01, 1.4410e-01, 1.4230e-01, 1.4050e-01, 1.3870e-01, 1.3700e-01, 1.3530e-01, 1.3360e-01, 1.3200e-01, 1.3040e-01, 1.2880e-01, 1.2720e-01, 1.2570e-01, 1.2420e-01, 1.2280e-01, 1.2130e-01, 1.1990e-01, 1.1850e-01, 1.1710e-01, 1.1580e-01, 1.1450e-01, 1.1320e-01, 1.1190e-01, 1.1060e-01, 1.0940e-01, 1.0820e-01, 1.0700e-01, 1.0580e-01, 1.0460e-01, 1.0350e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8100e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3000e-02, 9.2100e-02, 9.1100e-02, 9.0200e-02, 8.9300e-02, 8.8300e-02, 8.7400e-02, 8.6600e-02, 8.5700e-02, 8.4800e-02, 8.4000e-02, 8.3200e-02, 8.2300e-02, 8.1500e-02, 8.0700e-02, 8.0000e-02, 7.9200e-02, 7.8400e-02, 7.7700e-02, 7.6900e-02, 7.6200e-02, 7.5500e-02, 7.4800e-02, 7.4100e-02, 7.3400e-02, 7.2700e-02, 7.2000e-02, 7.1300e-02, 7.0700e-02, 7.0000e-02, 6.9400e-02, 6.8800e-02, 6.8100e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5700e-02, 6.5200e-02, 6.4600e-02, 6.4000e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1800e-02, 6.1300e-02, 6.0800e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02, 5.7300e-02, 5.6800e-02, 5.6300e-02, 5.5800e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02}); + } + break; + case 87: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.7000e+01, 8.6547e+01, 8.5330e+01, 8.3638e+01, 8.1692e+01, 7.9601e+01, 7.7427e+01, 7.5222e+01, 7.3034e+01, 7.0901e+01, 6.8846e+01, 6.6880e+01, 6.5003e+01, 6.3210e+01, 6.1493e+01, 5.9845e+01, 5.8257e+01, 5.6724e+01, 5.5242e+01, 5.3807e+01, 5.2418e+01, 5.1075e+01, 4.9775e+01, 4.8520e+01, 4.7309e+01, 4.6142e+01, 4.5017e+01, 4.3934e+01, 4.2891e+01, 4.1888e+01, 4.0922e+01, 3.9991e+01, 3.9095e+01, 3.8230e+01, 3.7394e+01, 3.6586e+01, 3.5804e+01, 3.5046e+01, 3.4310e+01, 3.3595e+01, 3.2899e+01, 3.2222e+01, 3.1562e+01, 3.0919e+01, 3.0291e+01, 2.9678e+01, 2.9079e+01, 2.8495e+01, 2.7925e+01, 2.7368e+01, 2.6825e+01, 2.6295e+01, 2.5778e+01, 2.5275e+01, 2.4785e+01, 2.4308e+01, 2.3844e+01, 2.3394e+01, 2.2957e+01, 2.2533e+01, 2.2122e+01, 2.1725e+01, 2.1340e+01, 2.0968e+01, 2.0609e+01, 2.0263e+01, 1.9928e+01, 1.9606e+01, 1.9296e+01, 1.8997e+01, 1.8709e+01, 1.8433e+01, 1.8167e+01, 1.7911e+01, 1.7665e+01, 1.7428e+01, 1.7201e+01, 1.6983e+01, 1.6772e+01, 1.6570e+01, 1.6376e+01, 1.6189e+01, 1.6008e+01, 1.5834e+01, 1.5666e+01, 1.5504e+01, 1.5348e+01, 1.5195e+01, 1.5048e+01, 1.4906e+01, 1.4767e+01, 1.4633e+01, 1.4501e+01, 1.4372e+01, 1.4247e+01, 1.4125e+01, 1.4005e+01, 1.3886e+01, 1.3770e+01, 1.3656e+01, 1.3544e+01, 1.3433e+01, 1.3324e+01, 1.3215e+01, 1.3107e+01, 1.3001e+01, 1.2895e+01, 1.2791e+01, 1.2687e+01, 1.2582e+01, 1.2479e+01, 1.2376e+01, 1.2274e+01, 1.2173e+01, 1.2072e+01, 1.1970e+01, 1.1868e+01, 1.1767e+01, 1.1666e+01, 1.1566e+01, 1.1467e+01, 1.1367e+01, 1.1266e+01, 1.1166e+01, 1.1067e+01, 1.0968e+01, 1.0870e+01, 1.0772e+01, 1.0674e+01, 1.0576e+01, 1.0477e+01, 1.0380e+01, 1.0284e+01, 1.0189e+01, 1.0094e+01, 9.9991e+00, 9.9044e+00, 9.8096e+00, 9.7157e+00, 9.6232e+00, 9.5317e+00, 9.4409e+00, 9.3509e+00, 9.2617e+00, 9.1724e+00, 9.0831e+00, 8.9950e+00, 8.9087e+00, 8.8236e+00, 8.7393e+00, 8.6560e+00, 8.5738e+00, 8.4920e+00, 8.4102e+00, 8.3290e+00, 8.2497e+00, 8.1723e+00, 8.0959e+00, 8.0204e+00, 7.9462e+00, 7.8732e+00, 7.8005e+00, 7.7277e+00, 7.6558e+00, 7.5858e+00, 7.5179e+00, 7.4512e+00, 7.3853e+00, 7.3207e+00, 7.2574e+00, 7.1948e+00, 7.1321e+00, 7.0696e+00, 7.0085e+00, 6.9497e+00, 6.8926e+00, 6.8366e+00, 6.7813e+00, 6.7273e+00, 6.6746e+00, 6.6225e+00, 6.5700e+00, 6.5175e+00, 6.4663e+00, 6.4172e+00, 6.3701e+00, 6.3240e+00, 6.2786e+00, 6.2342e+00, 6.1910e+00, 6.1487e+00, 6.1062e+00, 6.0631e+00, 6.0203e+00, 5.9789e+00, 5.9397e+00, 5.9021e+00, 5.8654e+00, 5.8293e+00, 5.7940e+00, 5.7598e+00, 5.7262e+00, 5.6924e+00, 5.6579e+00, 5.6229e+00, 5.5889e+00, 5.5569e+00, 5.5267e+00, 5.4976e+00, 5.4689e+00, 5.4408e+00, 5.4135e+00, 5.3870e+00, 5.3607e+00, 5.3337e+00, 5.3058e+00, 5.2774e+00, 5.2498e+00, 5.2239e+00, 5.1999e+00, 5.1768e+00, 5.1542e+00, 5.1320e+00, 5.1103e+00, 5.0893e+00, 5.0686e+00, 5.0474e+00, 5.0252e+00, 5.0018e+00, 4.9783e+00, 4.9556e+00, 4.9348e+00, 4.9155e+00, 4.8970e+00, 4.8789e+00, 4.8610e+00, 4.8435e+00, 4.8265e+00, 4.8098e+00, 4.7925e+00, 4.7741e+00}); + feg = Vctr_cpu({1.7903e+01, 1.7362e+01, 1.5989e+01, 1.4304e+01, 1.2705e+01, 1.1334e+01, 1.0183e+01, 9.2046e+00, 8.3564e+00, 7.6110e+00, 6.9518e+00, 6.3676e+00, 5.8497e+00, 5.3906e+00, 4.9834e+00, 4.6217e+00, 4.2995e+00, 4.0117e+00, 3.7535e+00, 3.5210e+00, 3.3107e+00, 3.1196e+00, 2.9452e+00, 2.7855e+00, 2.6387e+00, 2.5034e+00, 2.3783e+00, 2.2622e+00, 2.1545e+00, 2.0541e+00, 1.9606e+00, 1.8732e+00, 1.7915e+00, 1.7150e+00, 1.6433e+00, 1.5760e+00, 1.5127e+00, 1.4533e+00, 1.3973e+00, 1.3446e+00, 1.2948e+00, 1.2479e+00, 1.2035e+00, 1.1615e+00, 1.1217e+00, 1.0840e+00, 1.0482e+00, 1.0142e+00, 9.8190e-01, 9.5110e-01, 9.2170e-01, 8.9370e-01, 8.6700e-01, 8.4150e-01, 8.1700e-01, 7.9360e-01, 7.7120e-01, 7.4970e-01, 7.2900e-01, 7.0920e-01, 6.9010e-01, 6.7180e-01, 6.5410e-01, 6.3710e-01, 6.2070e-01, 6.0490e-01, 5.8960e-01, 5.7490e-01, 5.6070e-01, 5.4700e-01, 5.3370e-01, 5.2090e-01, 5.0850e-01, 4.9650e-01, 4.8490e-01, 4.7360e-01, 4.6280e-01, 4.5220e-01, 4.4200e-01, 4.3210e-01, 4.2260e-01, 4.1330e-01, 4.0430e-01, 3.9560e-01, 3.8710e-01, 3.7890e-01, 3.7100e-01, 3.6330e-01, 3.5580e-01, 3.4850e-01, 3.4150e-01, 3.3460e-01, 3.2800e-01, 3.2160e-01, 3.1530e-01, 3.0920e-01, 3.0330e-01, 2.9760e-01, 2.9200e-01, 2.8660e-01, 2.8130e-01, 2.7620e-01, 2.7120e-01, 2.6630e-01, 2.6160e-01, 2.5700e-01, 2.5260e-01, 2.4820e-01, 2.4400e-01, 2.3990e-01, 2.3580e-01, 2.3190e-01, 2.2810e-01, 2.2440e-01, 2.2080e-01, 2.1730e-01, 2.1380e-01, 2.1050e-01, 2.0720e-01, 2.0400e-01, 2.0090e-01, 1.9780e-01, 1.9480e-01, 1.9190e-01, 1.8910e-01, 1.8630e-01, 1.8360e-01, 1.8100e-01, 1.7840e-01, 1.7590e-01, 1.7340e-01, 1.7100e-01, 1.6860e-01, 1.6630e-01, 1.6400e-01, 1.6180e-01, 1.5960e-01, 1.5750e-01, 1.5540e-01, 1.5340e-01, 1.5140e-01, 1.4940e-01, 1.4750e-01, 1.4560e-01, 1.4370e-01, 1.4190e-01, 1.4010e-01, 1.3840e-01, 1.3670e-01, 1.3500e-01, 1.3330e-01, 1.3170e-01, 1.3010e-01, 1.2860e-01, 1.2700e-01, 1.2550e-01, 1.2400e-01, 1.2260e-01, 1.2120e-01, 1.1970e-01, 1.1840e-01, 1.1700e-01, 1.1570e-01, 1.1440e-01, 1.1310e-01, 1.1180e-01, 1.1050e-01, 1.0930e-01, 1.0810e-01, 1.0690e-01, 1.0570e-01, 1.0460e-01, 1.0350e-01, 1.0230e-01, 1.0120e-01, 1.0020e-01, 9.9100e-02, 9.8100e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3000e-02, 9.2100e-02, 9.1100e-02, 9.0200e-02, 8.9300e-02, 8.8400e-02, 8.7500e-02, 8.6600e-02, 8.5800e-02, 8.4900e-02, 8.4100e-02, 8.3300e-02, 8.2400e-02, 8.1600e-02, 8.0800e-02, 8.0100e-02, 7.9300e-02, 7.8500e-02, 7.7800e-02, 7.7000e-02, 7.6300e-02, 7.5600e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2800e-02, 7.2100e-02, 7.1500e-02, 7.0800e-02, 7.0200e-02, 6.9500e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.5900e-02, 6.5300e-02, 6.4700e-02, 6.4200e-02, 6.3600e-02, 6.3100e-02, 6.2500e-02, 6.2000e-02, 6.1400e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.7000e-02, 5.6500e-02, 5.6000e-02, 5.5600e-02, 5.5100e-02, 5.4700e-02}); + } + break; + case 88: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.8000e+01, 8.7496e+01, 8.6146e+01, 8.4302e+01, 8.2257e+01, 8.0153e+01, 7.8031e+01, 7.5899e+01, 7.3771e+01, 7.1671e+01, 6.9620e+01, 6.7638e+01, 6.5735e+01, 6.3913e+01, 6.2171e+01, 6.0504e+01, 5.8904e+01, 5.7366e+01, 5.5883e+01, 5.4452e+01, 5.3067e+01, 5.1728e+01, 5.0432e+01, 4.9178e+01, 4.7965e+01, 4.6793e+01, 4.5662e+01, 4.4571e+01, 4.3518e+01, 4.2503e+01, 4.1526e+01, 4.0583e+01, 3.9674e+01, 3.8797e+01, 3.7951e+01, 3.7133e+01, 3.6342e+01, 3.5576e+01, 3.4833e+01, 3.4113e+01, 3.3413e+01, 3.2732e+01, 3.2069e+01, 3.1423e+01, 3.0794e+01, 3.0179e+01, 2.9580e+01, 2.8994e+01, 2.8423e+01, 2.7864e+01, 2.7319e+01, 2.6787e+01, 2.6268e+01, 2.5761e+01, 2.5267e+01, 2.4786e+01, 2.4317e+01, 2.3861e+01, 2.3417e+01, 2.2986e+01, 2.2568e+01, 2.2162e+01, 2.1769e+01, 2.1388e+01, 2.1019e+01, 2.0663e+01, 2.0318e+01, 1.9986e+01, 1.9665e+01, 1.9355e+01, 1.9056e+01, 1.8769e+01, 1.8492e+01, 1.8226e+01, 1.7969e+01, 1.7722e+01, 1.7485e+01, 1.7257e+01, 1.7037e+01, 1.6825e+01, 1.6622e+01, 1.6427e+01, 1.6238e+01, 1.6055e+01, 1.5881e+01, 1.5712e+01, 1.5549e+01, 1.5391e+01, 1.5238e+01, 1.5090e+01, 1.4948e+01, 1.4809e+01, 1.4672e+01, 1.4540e+01, 1.4412e+01, 1.4288e+01, 1.4166e+01, 1.4045e+01, 1.3927e+01, 1.3812e+01, 1.3699e+01, 1.3589e+01, 1.3479e+01, 1.3369e+01, 1.3261e+01, 1.3155e+01, 1.3051e+01, 1.2948e+01, 1.2845e+01, 1.2741e+01, 1.2639e+01, 1.2537e+01, 1.2437e+01, 1.2338e+01, 1.2239e+01, 1.2138e+01, 1.2037e+01, 1.1938e+01, 1.1839e+01, 1.1742e+01, 1.1645e+01, 1.1547e+01, 1.1447e+01, 1.1348e+01, 1.1251e+01, 1.1154e+01, 1.1058e+01, 1.0962e+01, 1.0866e+01, 1.0768e+01, 1.0671e+01, 1.0575e+01, 1.0480e+01, 1.0386e+01, 1.0293e+01, 1.0199e+01, 1.0105e+01, 1.0010e+01, 9.9165e+00, 9.8242e+00, 9.7334e+00, 9.6436e+00, 9.5545e+00, 9.4655e+00, 9.3759e+00, 9.2859e+00, 9.1970e+00, 9.1101e+00, 9.0247e+00, 8.9404e+00, 8.8572e+00, 8.7747e+00, 8.6920e+00, 8.6089e+00, 8.5262e+00, 8.4454e+00, 8.3668e+00, 8.2895e+00, 8.2132e+00, 8.1382e+00, 8.0641e+00, 7.9899e+00, 7.9152e+00, 7.8412e+00, 7.7693e+00, 7.6996e+00, 7.6314e+00, 7.5640e+00, 7.4980e+00, 7.4332e+00, 7.3689e+00, 7.3041e+00, 7.2392e+00, 7.1758e+00, 7.1149e+00, 7.0560e+00, 6.9980e+00, 6.9408e+00, 6.8850e+00, 6.8306e+00, 6.7765e+00, 6.7219e+00, 6.6669e+00, 6.6133e+00, 6.5622e+00, 6.5132e+00, 6.4652e+00, 6.4177e+00, 6.3711e+00, 6.3262e+00, 6.2821e+00, 6.2378e+00, 6.1925e+00, 6.1474e+00, 6.1039e+00, 6.0630e+00, 6.0239e+00, 5.9853e+00, 5.9470e+00, 5.9097e+00, 5.8737e+00, 5.8388e+00, 5.8035e+00, 5.7671e+00, 5.7302e+00, 5.6943e+00, 5.6609e+00, 5.6295e+00, 5.5991e+00, 5.5687e+00, 5.5385e+00, 5.5094e+00, 5.4816e+00, 5.4543e+00, 5.4263e+00, 5.3970e+00, 5.3669e+00, 5.3379e+00, 5.3111e+00, 5.2864e+00, 5.2626e+00, 5.2386e+00, 5.2147e+00, 5.1914e+00, 5.1692e+00, 5.1479e+00, 5.1262e+00, 5.1032e+00, 5.0788e+00, 5.0540e+00, 5.0305e+00, 5.0093e+00, 4.9899e+00, 4.9711e+00, 4.9519e+00, 4.9326e+00, 4.9138e+00, 4.8960e+00, 4.8789e+00, 4.8616e+00, 4.8430e+00}); + feg = Vctr_cpu({1.9909e+01, 1.9311e+01, 1.7747e+01, 1.5736e+01, 1.3746e+01, 1.2019e+01, 1.0604e+01, 9.4573e+00, 8.5138e+00, 7.7200e+00, 7.0383e+00, 6.4440e+00, 5.9210e+00, 5.4578e+00, 5.0463e+00, 4.6797e+00, 4.3523e+00, 4.0591e+00, 3.7959e+00, 3.5587e+00, 3.3443e+00, 3.1497e+00, 2.9724e+00, 2.8103e+00, 2.6616e+00, 2.5247e+00, 2.3983e+00, 2.2813e+00, 2.1727e+00, 2.0716e+00, 1.9774e+00, 1.8895e+00, 1.8072e+00, 1.7302e+00, 1.6579e+00, 1.5901e+00, 1.5264e+00, 1.4664e+00, 1.4099e+00, 1.3567e+00, 1.3065e+00, 1.2590e+00, 1.2142e+00, 1.1717e+00, 1.1315e+00, 1.0934e+00, 1.0572e+00, 1.0229e+00, 9.9020e-01, 9.5910e-01, 9.2950e-01, 9.0120e-01, 8.7420e-01, 8.4850e-01, 8.2380e-01, 8.0020e-01, 7.7760e-01, 7.5600e-01, 7.3520e-01, 7.1520e-01, 6.9600e-01, 6.7760e-01, 6.5980e-01, 6.4270e-01, 6.2620e-01, 6.1030e-01, 5.9500e-01, 5.8020e-01, 5.6590e-01, 5.5210e-01, 5.3880e-01, 5.2590e-01, 5.1340e-01, 5.0140e-01, 4.8970e-01, 4.7840e-01, 4.6750e-01, 4.5690e-01, 4.4670e-01, 4.3670e-01, 4.2710e-01, 4.1770e-01, 4.0870e-01, 3.9990e-01, 3.9140e-01, 3.8310e-01, 3.7510e-01, 3.6740e-01, 3.5980e-01, 3.5250e-01, 3.4540e-01, 3.3850e-01, 3.3180e-01, 3.2520e-01, 3.1890e-01, 3.1280e-01, 3.0680e-01, 3.0100e-01, 2.9540e-01, 2.8990e-01, 2.8450e-01, 2.7930e-01, 2.7430e-01, 2.6940e-01, 2.6460e-01, 2.6000e-01, 2.5540e-01, 2.5100e-01, 2.4670e-01, 2.4260e-01, 2.3850e-01, 2.3450e-01, 2.3070e-01, 2.2690e-01, 2.2320e-01, 2.1970e-01, 2.1620e-01, 2.1280e-01, 2.0950e-01, 2.0620e-01, 2.0310e-01, 2.0000e-01, 1.9700e-01, 1.9400e-01, 1.9110e-01, 1.8830e-01, 1.8560e-01, 1.8290e-01, 1.8030e-01, 1.7770e-01, 1.7520e-01, 1.7280e-01, 1.7040e-01, 1.6800e-01, 1.6570e-01, 1.6350e-01, 1.6130e-01, 1.5910e-01, 1.5700e-01, 1.5490e-01, 1.5290e-01, 1.5090e-01, 1.4900e-01, 1.4710e-01, 1.4520e-01, 1.4340e-01, 1.4160e-01, 1.3980e-01, 1.3810e-01, 1.3640e-01, 1.3470e-01, 1.3310e-01, 1.3140e-01, 1.2990e-01, 1.2830e-01, 1.2680e-01, 1.2530e-01, 1.2380e-01, 1.2240e-01, 1.2100e-01, 1.1960e-01, 1.1820e-01, 1.1690e-01, 1.1550e-01, 1.1420e-01, 1.1290e-01, 1.1170e-01, 1.1040e-01, 1.0920e-01, 1.0800e-01, 1.0680e-01, 1.0570e-01, 1.0450e-01, 1.0340e-01, 1.0230e-01, 1.0120e-01, 1.0010e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0200e-02, 8.9300e-02, 8.8400e-02, 8.7600e-02, 8.6700e-02, 8.5800e-02, 8.5000e-02, 8.4100e-02, 8.3300e-02, 8.2500e-02, 8.1700e-02, 8.0900e-02, 8.0100e-02, 7.9400e-02, 7.8600e-02, 7.7900e-02, 7.7100e-02, 7.6400e-02, 7.5700e-02, 7.5000e-02, 7.4300e-02, 7.3600e-02, 7.2900e-02, 7.2300e-02, 7.1600e-02, 7.1000e-02, 7.0300e-02, 6.9700e-02, 6.9000e-02, 6.8400e-02, 6.7800e-02, 6.7200e-02, 6.6600e-02, 6.6000e-02, 6.5500e-02, 6.4900e-02, 6.4300e-02, 6.3800e-02, 6.3200e-02, 6.2700e-02, 6.2100e-02, 6.1600e-02, 6.1100e-02, 6.0600e-02, 6.0100e-02, 5.9600e-02, 5.9100e-02, 5.8600e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5300e-02}); + } + break; + case 89: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.9000e+01, 8.8479e+01, 8.7073e+01, 8.5128e+01, 8.2966e+01, 8.0765e+01, 7.8585e+01, 7.6436e+01, 7.4318e+01, 7.2239e+01, 7.0210e+01, 6.8244e+01, 6.6350e+01, 6.4531e+01, 6.2789e+01, 6.1119e+01, 5.9517e+01, 5.7977e+01, 5.6494e+01, 5.5062e+01, 5.3678e+01, 5.2340e+01, 5.1044e+01, 4.9789e+01, 4.8575e+01, 4.7400e+01, 4.6264e+01, 4.5166e+01, 4.4106e+01, 4.3084e+01, 4.2097e+01, 4.1145e+01, 4.0227e+01, 3.9342e+01, 3.8486e+01, 3.7660e+01, 3.6862e+01, 3.6090e+01, 3.5341e+01, 3.4616e+01, 3.3911e+01, 3.3227e+01, 3.2561e+01, 3.1913e+01, 3.1282e+01, 3.0666e+01, 3.0065e+01, 2.9478e+01, 2.8905e+01, 2.8345e+01, 2.7798e+01, 2.7264e+01, 2.6742e+01, 2.6233e+01, 2.5736e+01, 2.5251e+01, 2.4778e+01, 2.4317e+01, 2.3868e+01, 2.3431e+01, 2.3006e+01, 2.2593e+01, 2.2193e+01, 2.1804e+01, 2.1427e+01, 2.1061e+01, 2.0708e+01, 2.0366e+01, 2.0035e+01, 1.9716e+01, 1.9408e+01, 1.9110e+01, 1.8824e+01, 1.8547e+01, 1.8281e+01, 1.8025e+01, 1.7777e+01, 1.7540e+01, 1.7311e+01, 1.7091e+01, 1.6878e+01, 1.6674e+01, 1.6478e+01, 1.6289e+01, 1.6106e+01, 1.5929e+01, 1.5760e+01, 1.5596e+01, 1.5438e+01, 1.5284e+01, 1.5135e+01, 1.4992e+01, 1.4853e+01, 1.4718e+01, 1.4585e+01, 1.4456e+01, 1.4331e+01, 1.4210e+01, 1.4091e+01, 1.3973e+01, 1.3858e+01, 1.3745e+01, 1.3635e+01, 1.3527e+01, 1.3419e+01, 1.3313e+01, 1.3207e+01, 1.3103e+01, 1.3001e+01, 1.2900e+01, 1.2800e+01, 1.2699e+01, 1.2598e+01, 1.2498e+01, 1.2400e+01, 1.2303e+01, 1.2206e+01, 1.2108e+01, 1.2010e+01, 1.1912e+01, 1.1815e+01, 1.1720e+01, 1.1625e+01, 1.1529e+01, 1.1433e+01, 1.1335e+01, 1.1239e+01, 1.1144e+01, 1.1050e+01, 1.0957e+01, 1.0863e+01, 1.0768e+01, 1.0672e+01, 1.0577e+01, 1.0483e+01, 1.0391e+01, 1.0300e+01, 1.0209e+01, 1.0117e+01, 1.0025e+01, 9.9321e+00, 9.8403e+00, 9.7505e+00, 9.6625e+00, 9.5753e+00, 9.4881e+00, 9.4006e+00, 9.3129e+00, 9.2249e+00, 9.1378e+00, 9.0529e+00, 8.9701e+00, 8.8886e+00, 8.8074e+00, 8.7263e+00, 8.6452e+00, 8.5640e+00, 8.4830e+00, 8.4036e+00, 8.3267e+00, 8.2520e+00, 8.1783e+00, 8.1048e+00, 8.0317e+00, 7.9590e+00, 7.8862e+00, 7.8136e+00, 7.7424e+00, 7.6740e+00, 7.6079e+00, 7.5430e+00, 7.4785e+00, 7.4144e+00, 7.3510e+00, 7.2878e+00, 7.2246e+00, 7.1618e+00, 7.1010e+00, 7.0431e+00, 6.9873e+00, 6.9323e+00, 6.8775e+00, 6.8231e+00, 6.7696e+00, 6.7165e+00, 6.6631e+00, 6.6099e+00, 6.5583e+00, 6.5094e+00, 6.4630e+00, 6.4177e+00, 6.3725e+00, 6.3273e+00, 6.2830e+00, 6.2394e+00, 6.1959e+00, 6.1519e+00, 6.1081e+00, 6.0661e+00, 6.0268e+00, 5.9899e+00, 5.9538e+00, 5.9174e+00, 5.8809e+00, 5.8451e+00, 5.8101e+00, 5.7754e+00, 5.7400e+00, 5.7042e+00, 5.6693e+00, 5.6367e+00, 5.6067e+00, 5.5784e+00, 5.5501e+00, 5.5212e+00, 5.4921e+00, 5.4638e+00, 5.4363e+00, 5.4088e+00, 5.3804e+00, 5.3513e+00, 5.3228e+00, 5.2963e+00, 5.2724e+00, 5.2504e+00, 5.2286e+00, 5.2060e+00, 5.1827e+00, 5.1598e+00, 5.1376e+00, 5.1159e+00, 5.0936e+00, 5.0701e+00, 5.0460e+00, 5.0227e+00, 5.0014e+00, 4.9826e+00, 4.9655e+00, 4.9485e+00, 4.9304e+00, 4.9114e+00}); + feg = Vctr_cpu({2.0495e+01, 1.9937e+01, 1.8450e+01, 1.6474e+01, 1.4441e+01, 1.2614e+01, 1.1079e+01, 9.8190e+00, 8.7848e+00, 7.9241e+00, 7.1954e+00, 6.5688e+00, 6.0234e+00, 5.5444e+00, 5.1211e+00, 4.7452e+00, 4.4103e+00, 4.1107e+00, 3.8420e+00, 3.6000e+00, 3.3815e+00, 3.1834e+00, 3.0031e+00, 2.8384e+00, 2.6876e+00, 2.5489e+00, 2.4209e+00, 2.3026e+00, 2.1928e+00, 2.0907e+00, 1.9957e+00, 1.9069e+00, 1.8239e+00, 1.7462e+00, 1.6733e+00, 1.6049e+00, 1.5406e+00, 1.4800e+00, 1.4230e+00, 1.3692e+00, 1.3185e+00, 1.2705e+00, 1.2252e+00, 1.1823e+00, 1.1417e+00, 1.1031e+00, 1.0666e+00, 1.0318e+00, 9.9880e-01, 9.6740e-01, 9.3750e-01, 9.0890e-01, 8.8170e-01, 8.5570e-01, 8.3080e-01, 8.0700e-01, 7.8420e-01, 7.6240e-01, 7.4140e-01, 7.2130e-01, 7.0200e-01, 6.8340e-01, 6.6550e-01, 6.4830e-01, 6.3170e-01, 6.1580e-01, 6.0040e-01, 5.8550e-01, 5.7110e-01, 5.5730e-01, 5.4390e-01, 5.3090e-01, 5.1840e-01, 5.0630e-01, 4.9450e-01, 4.8320e-01, 4.7220e-01, 4.6150e-01, 4.5120e-01, 4.4120e-01, 4.3150e-01, 4.2210e-01, 4.1300e-01, 4.0420e-01, 3.9560e-01, 3.8730e-01, 3.7920e-01, 3.7140e-01, 3.6380e-01, 3.5640e-01, 3.4920e-01, 3.4220e-01, 3.3550e-01, 3.2890e-01, 3.2250e-01, 3.1630e-01, 3.1030e-01, 3.0440e-01, 2.9870e-01, 2.9310e-01, 2.8770e-01, 2.8250e-01, 2.7740e-01, 2.7240e-01, 2.6760e-01, 2.6290e-01, 2.5830e-01, 2.5390e-01, 2.4950e-01, 2.4530e-01, 2.4120e-01, 2.3710e-01, 2.3320e-01, 2.2940e-01, 2.2570e-01, 2.2210e-01, 2.1850e-01, 2.1510e-01, 2.1170e-01, 2.0850e-01, 2.0530e-01, 2.0210e-01, 1.9910e-01, 1.9610e-01, 1.9320e-01, 1.9030e-01, 1.8760e-01, 1.8480e-01, 1.8220e-01, 1.7960e-01, 1.7710e-01, 1.7460e-01, 1.7210e-01, 1.6980e-01, 1.6740e-01, 1.6520e-01, 1.6290e-01, 1.6080e-01, 1.5860e-01, 1.5650e-01, 1.5450e-01, 1.5250e-01, 1.5050e-01, 1.4860e-01, 1.4670e-01, 1.4480e-01, 1.4300e-01, 1.4120e-01, 1.3950e-01, 1.3780e-01, 1.3610e-01, 1.3440e-01, 1.3280e-01, 1.3120e-01, 1.2960e-01, 1.2810e-01, 1.2660e-01, 1.2510e-01, 1.2360e-01, 1.2220e-01, 1.2080e-01, 1.1940e-01, 1.1800e-01, 1.1670e-01, 1.1540e-01, 1.1410e-01, 1.1280e-01, 1.1160e-01, 1.1030e-01, 1.0910e-01, 1.0790e-01, 1.0680e-01, 1.0560e-01, 1.0450e-01, 1.0340e-01, 1.0230e-01, 1.0120e-01, 1.0010e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7600e-02, 8.6700e-02, 8.5900e-02, 8.5000e-02, 8.4200e-02, 8.3400e-02, 8.2600e-02, 8.1800e-02, 8.1000e-02, 8.0200e-02, 7.9500e-02, 7.8700e-02, 7.8000e-02, 7.7200e-02, 7.6500e-02, 7.5800e-02, 7.5100e-02, 7.4400e-02, 7.3700e-02, 7.3100e-02, 7.2400e-02, 7.1700e-02, 7.1100e-02, 7.0400e-02, 6.9800e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7400e-02, 6.6800e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4500e-02, 6.3900e-02, 6.3400e-02, 6.2800e-02, 6.2300e-02, 6.1800e-02, 6.1200e-02, 6.0700e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7800e-02, 5.7300e-02, 5.6800e-02, 5.6400e-02, 5.5900e-02}); + } + break; + case 90: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.0000e+01, 8.9485e+01, 8.8076e+01, 8.6087e+01, 8.3834e+01, 8.1526e+01, 7.9255e+01, 7.7047e+01, 7.4903e+01, 7.2820e+01, 7.0800e+01, 6.8847e+01, 6.6965e+01, 6.5156e+01, 6.3419e+01, 6.1752e+01, 6.0151e+01, 5.8611e+01, 5.7128e+01, 5.5696e+01, 5.4313e+01, 5.2974e+01, 5.1677e+01, 5.0420e+01, 4.9203e+01, 4.8023e+01, 4.6882e+01, 4.5778e+01, 4.4710e+01, 4.3679e+01, 4.2683e+01, 4.1721e+01, 4.0793e+01, 3.9897e+01, 3.9033e+01, 3.8197e+01, 3.7390e+01, 3.6610e+01, 3.5855e+01, 3.5123e+01, 3.4413e+01, 3.3724e+01, 3.3055e+01, 3.2404e+01, 3.1769e+01, 3.1151e+01, 3.0549e+01, 2.9961e+01, 2.9386e+01, 2.8825e+01, 2.8277e+01, 2.7742e+01, 2.7218e+01, 2.6707e+01, 2.6207e+01, 2.5719e+01, 2.5243e+01, 2.4778e+01, 2.4325e+01, 2.3883e+01, 2.3452e+01, 2.3033e+01, 2.2626e+01, 2.2230e+01, 2.1845e+01, 2.1472e+01, 2.1110e+01, 2.0759e+01, 2.0420e+01, 2.0091e+01, 1.9773e+01, 1.9466e+01, 1.9170e+01, 1.8884e+01, 1.8608e+01, 1.8341e+01, 1.8085e+01, 1.7837e+01, 1.7599e+01, 1.7369e+01, 1.7148e+01, 1.6935e+01, 1.6730e+01, 1.6532e+01, 1.6341e+01, 1.6158e+01, 1.5981e+01, 1.5810e+01, 1.5645e+01, 1.5485e+01, 1.5332e+01, 1.5183e+01, 1.5038e+01, 1.4898e+01, 1.4761e+01, 1.4630e+01, 1.4502e+01, 1.4377e+01, 1.4254e+01, 1.4134e+01, 1.4017e+01, 1.3903e+01, 1.3792e+01, 1.3681e+01, 1.3572e+01, 1.3465e+01, 1.3360e+01, 1.3258e+01, 1.3156e+01, 1.3054e+01, 1.2953e+01, 1.2852e+01, 1.2753e+01, 1.2656e+01, 1.2560e+01, 1.2463e+01, 1.2366e+01, 1.2268e+01, 1.2172e+01, 1.2078e+01, 1.1984e+01, 1.1890e+01, 1.1795e+01, 1.1700e+01, 1.1604e+01, 1.1510e+01, 1.1417e+01, 1.1325e+01, 1.1232e+01, 1.1139e+01, 1.1044e+01, 1.0950e+01, 1.0857e+01, 1.0765e+01, 1.0674e+01, 1.0584e+01, 1.0493e+01, 1.0401e+01, 1.0308e+01, 1.0216e+01, 1.0126e+01, 1.0037e+01, 9.9494e+00, 9.8620e+00, 9.7742e+00, 9.6855e+00, 9.5964e+00, 9.5080e+00, 9.4214e+00, 9.3368e+00, 9.2536e+00, 9.1709e+00, 9.0884e+00, 9.0054e+00, 8.9219e+00, 8.8385e+00, 8.7566e+00, 8.6770e+00, 8.5994e+00, 8.5230e+00, 8.4472e+00, 8.3717e+00, 8.2960e+00, 8.2197e+00, 8.1438e+00, 8.0694e+00, 7.9976e+00, 7.9279e+00, 7.8595e+00, 7.7919e+00, 7.7250e+00, 7.6581e+00, 7.5910e+00, 7.5235e+00, 7.4570e+00, 7.3927e+00, 7.3310e+00, 7.2711e+00, 7.2123e+00, 7.1542e+00, 7.0968e+00, 7.0396e+00, 6.9822e+00, 6.9243e+00, 6.8671e+00, 6.8120e+00, 6.7596e+00, 6.7092e+00, 6.6598e+00, 6.6110e+00, 6.5630e+00, 6.5156e+00, 6.4682e+00, 6.4202e+00, 6.3719e+00, 6.3246e+00, 6.2796e+00, 6.2373e+00, 6.1966e+00, 6.1566e+00, 6.1170e+00, 6.0780e+00, 6.0398e+00, 6.0017e+00, 5.9629e+00, 5.9233e+00, 5.8841e+00, 5.8468e+00, 5.8121e+00, 5.7795e+00, 5.7477e+00, 5.7160e+00, 5.6846e+00, 5.6539e+00, 5.6239e+00, 5.5938e+00, 5.5626e+00, 5.5305e+00, 5.4986e+00, 5.4684e+00, 5.4408e+00, 5.4153e+00, 5.3906e+00, 5.3657e+00, 5.3407e+00, 5.3163e+00, 5.2926e+00, 5.2692e+00, 5.2450e+00, 5.2194e+00, 5.1930e+00, 5.1671e+00, 5.1432e+00, 5.1218e+00, 5.1021e+00, 5.0829e+00, 5.0632e+00, 5.0432e+00, 5.0236e+00, 5.0048e+00, 4.9863e+00}); + feg = Vctr_cpu({2.0189e+01, 1.9712e+01, 1.8420e+01, 1.6652e+01, 1.4758e+01, 1.2980e+01, 1.1430e+01, 1.0123e+01, 9.0334e+00, 8.1221e+00, 7.3523e+00, 6.6944e+00, 6.1257e+00, 5.6295e+00, 5.1934e+00, 4.8077e+00, 4.4650e+00, 4.1592e+00, 3.8852e+00, 3.6388e+00, 3.4165e+00, 3.2152e+00, 3.0321e+00, 2.8652e+00, 2.7123e+00, 2.5719e+00, 2.4425e+00, 2.3230e+00, 2.2121e+00, 2.1092e+00, 2.0133e+00, 1.9238e+00, 1.8402e+00, 1.7618e+00, 1.6884e+00, 1.6194e+00, 1.5545e+00, 1.4934e+00, 1.4359e+00, 1.3816e+00, 1.3304e+00, 1.2820e+00, 1.2362e+00, 1.1929e+00, 1.1518e+00, 1.1129e+00, 1.0759e+00, 1.0408e+00, 1.0074e+00, 9.7570e-01, 9.4540e-01, 9.1660e-01, 8.8910e-01, 8.6290e-01, 8.3780e-01, 8.1370e-01, 7.9080e-01, 7.6870e-01, 7.4760e-01, 7.2730e-01, 7.0790e-01, 6.8920e-01, 6.7120e-01, 6.5390e-01, 6.3720e-01, 6.2110e-01, 6.0560e-01, 5.9070e-01, 5.7620e-01, 5.6230e-01, 5.4880e-01, 5.3580e-01, 5.2320e-01, 5.1100e-01, 4.9930e-01, 4.8780e-01, 4.7680e-01, 4.6610e-01, 4.5570e-01, 4.4570e-01, 4.3590e-01, 4.2640e-01, 4.1730e-01, 4.0840e-01, 3.9980e-01, 3.9140e-01, 3.8320e-01, 3.7530e-01, 3.6770e-01, 3.6020e-01, 3.5300e-01, 3.4600e-01, 3.3920e-01, 3.3250e-01, 3.2610e-01, 3.1980e-01, 3.1370e-01, 3.0780e-01, 3.0200e-01, 2.9640e-01, 2.9100e-01, 2.8570e-01, 2.8050e-01, 2.7550e-01, 2.7060e-01, 2.6580e-01, 2.6120e-01, 2.5670e-01, 2.5230e-01, 2.4800e-01, 2.4380e-01, 2.3980e-01, 2.3580e-01, 2.3200e-01, 2.2820e-01, 2.2450e-01, 2.2090e-01, 2.1740e-01, 2.1400e-01, 2.1070e-01, 2.0750e-01, 2.0430e-01, 2.0120e-01, 1.9820e-01, 1.9520e-01, 1.9240e-01, 1.8950e-01, 1.8680e-01, 1.8410e-01, 1.8150e-01, 1.7890e-01, 1.7640e-01, 1.7390e-01, 1.7150e-01, 1.6920e-01, 1.6690e-01, 1.6460e-01, 1.6240e-01, 1.6020e-01, 1.5810e-01, 1.5610e-01, 1.5400e-01, 1.5200e-01, 1.5010e-01, 1.4820e-01, 1.4630e-01, 1.4440e-01, 1.4260e-01, 1.4090e-01, 1.3910e-01, 1.3740e-01, 1.3580e-01, 1.3410e-01, 1.3250e-01, 1.3090e-01, 1.2940e-01, 1.2780e-01, 1.2630e-01, 1.2490e-01, 1.2340e-01, 1.2200e-01, 1.2060e-01, 1.1920e-01, 1.1790e-01, 1.1650e-01, 1.1520e-01, 1.1400e-01, 1.1270e-01, 1.1140e-01, 1.1020e-01, 1.0900e-01, 1.0780e-01, 1.0670e-01, 1.0550e-01, 1.0440e-01, 1.0330e-01, 1.0220e-01, 1.0110e-01, 1.0010e-01, 9.9000e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7600e-02, 8.6800e-02, 8.5900e-02, 8.5100e-02, 8.4300e-02, 8.3500e-02, 8.2700e-02, 8.1900e-02, 8.1100e-02, 8.0300e-02, 7.9500e-02, 7.8800e-02, 7.8100e-02, 7.7300e-02, 7.6600e-02, 7.5900e-02, 7.5200e-02, 7.4500e-02, 7.3800e-02, 7.3200e-02, 7.2500e-02, 7.1800e-02, 7.1200e-02, 7.0600e-02, 6.9900e-02, 6.9300e-02, 6.8700e-02, 6.8100e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5700e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3500e-02, 6.3000e-02, 6.2400e-02, 6.1900e-02, 6.1400e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.7000e-02, 5.6500e-02}); + } + break; + case 91: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.1000e+01, 9.0503e+01, 8.9145e+01, 8.7234e+01, 8.5062e+01, 8.2810e+01, 8.0553e+01, 7.8315e+01, 7.6106e+01, 7.3937e+01, 7.1822e+01, 6.9774e+01, 6.7804e+01, 6.5918e+01, 6.4115e+01, 6.2395e+01, 6.0752e+01, 5.9181e+01, 5.7674e+01, 5.6226e+01, 5.4833e+01, 5.3488e+01, 5.2189e+01, 5.0933e+01, 4.9718e+01, 4.8543e+01, 4.7405e+01, 4.6305e+01, 4.5242e+01, 4.4214e+01, 4.3220e+01, 4.2261e+01, 4.1334e+01, 4.0439e+01, 3.9574e+01, 3.8739e+01, 3.7930e+01, 3.7148e+01, 3.6391e+01, 3.5657e+01, 3.4945e+01, 3.4254e+01, 3.3582e+01, 3.2928e+01, 3.2291e+01, 3.1670e+01, 3.1064e+01, 3.0473e+01, 2.9895e+01, 2.9331e+01, 2.8779e+01, 2.8240e+01, 2.7712e+01, 2.7197e+01, 2.6692e+01, 2.6199e+01, 2.5718e+01, 2.5247e+01, 2.4788e+01, 2.4340e+01, 2.3903e+01, 2.3477e+01, 2.3062e+01, 2.2659e+01, 2.2266e+01, 2.1885e+01, 2.1514e+01, 2.1154e+01, 2.0806e+01, 2.0468e+01, 2.0141e+01, 1.9825e+01, 1.9519e+01, 1.9223e+01, 1.8937e+01, 1.8661e+01, 1.8395e+01, 1.8139e+01, 1.7891e+01, 1.7652e+01, 1.7422e+01, 1.7201e+01, 1.6987e+01, 1.6781e+01, 1.6582e+01, 1.6391e+01, 1.6207e+01, 1.6029e+01, 1.5857e+01, 1.5691e+01, 1.5531e+01, 1.5377e+01, 1.5227e+01, 1.5082e+01, 1.4941e+01, 1.4805e+01, 1.4673e+01, 1.4544e+01, 1.4418e+01, 1.4295e+01, 1.4176e+01, 1.4060e+01, 1.3947e+01, 1.3835e+01, 1.3724e+01, 1.3616e+01, 1.3510e+01, 1.3406e+01, 1.3304e+01, 1.3202e+01, 1.3101e+01, 1.3001e+01, 1.2902e+01, 1.2806e+01, 1.2710e+01, 1.2614e+01, 1.2518e+01, 1.2422e+01, 1.2327e+01, 1.2233e+01, 1.2141e+01, 1.2048e+01, 1.1955e+01, 1.1861e+01, 1.1767e+01, 1.1674e+01, 1.1583e+01, 1.1492e+01, 1.1401e+01, 1.1309e+01, 1.1216e+01, 1.1123e+01, 1.1032e+01, 1.0941e+01, 1.0852e+01, 1.0762e+01, 1.0673e+01, 1.0582e+01, 1.0491e+01, 1.0400e+01, 1.0310e+01, 1.0223e+01, 1.0135e+01, 1.0049e+01, 9.9614e+00, 9.8735e+00, 9.7851e+00, 9.6972e+00, 9.6111e+00, 9.5267e+00, 9.4434e+00, 9.3606e+00, 9.2779e+00, 9.1950e+00, 9.1115e+00, 9.0281e+00, 8.9460e+00, 8.8661e+00, 8.7879e+00, 8.7107e+00, 8.6340e+00, 8.5577e+00, 8.4813e+00, 8.4045e+00, 8.3279e+00, 8.2528e+00, 8.1800e+00, 8.1092e+00, 8.0393e+00, 7.9702e+00, 7.9018e+00, 7.8338e+00, 7.7655e+00, 7.6969e+00, 7.6292e+00, 7.5637e+00, 7.5005e+00, 7.4389e+00, 7.3782e+00, 7.3181e+00, 7.2589e+00, 7.2002e+00, 7.1413e+00, 7.0820e+00, 7.0234e+00, 6.9668e+00, 6.9127e+00, 6.8605e+00, 6.8090e+00, 6.7581e+00, 6.7079e+00, 6.6587e+00, 6.6097e+00, 6.5601e+00, 6.5103e+00, 6.4615e+00, 6.4150e+00, 6.3709e+00, 6.3283e+00, 6.2863e+00, 6.2445e+00, 6.2035e+00, 6.1635e+00, 6.1238e+00, 6.0835e+00, 6.0425e+00, 6.0020e+00, 5.9632e+00, 5.9270e+00, 5.8927e+00, 5.8592e+00, 5.8256e+00, 5.7923e+00, 5.7599e+00, 5.7283e+00, 5.6968e+00, 5.6644e+00, 5.6312e+00, 5.5982e+00, 5.5668e+00, 5.5380e+00, 5.5111e+00, 5.4849e+00, 5.4585e+00, 5.4321e+00, 5.4062e+00, 5.3812e+00, 5.3566e+00, 5.3314e+00, 5.3050e+00, 5.2778e+00, 5.2512e+00, 5.2264e+00, 5.2040e+00, 5.1833e+00, 5.1630e+00, 5.1422e+00, 5.1212e+00, 5.1006e+00, 5.0808e+00, 5.0614e+00}); + feg = Vctr_cpu({1.9518e+01, 1.9039e+01, 1.7754e+01, 1.6024e+01, 1.4211e+01, 1.2545e+01, 1.1113e+01, 9.9133e+00, 8.9118e+00, 8.0669e+00, 7.3442e+00, 6.7176e+00, 6.1685e+00, 5.6835e+00, 5.2527e+00, 4.8684e+00, 4.5246e+00, 4.2162e+00, 3.9388e+00, 3.6887e+00, 3.4625e+00, 3.2573e+00, 3.0707e+00, 2.9004e+00, 2.7445e+00, 2.6014e+00, 2.4695e+00, 2.3478e+00, 2.2350e+00, 2.1304e+00, 2.0330e+00, 1.9422e+00, 1.8573e+00, 1.7779e+00, 1.7035e+00, 1.6337e+00, 1.5681e+00, 1.5063e+00, 1.4482e+00, 1.3934e+00, 1.3416e+00, 1.2927e+00, 1.2465e+00, 1.2027e+00, 1.1613e+00, 1.1220e+00, 1.0847e+00, 1.0493e+00, 1.0156e+00, 9.8360e-01, 9.5310e-01, 9.2400e-01, 8.9630e-01, 8.6980e-01, 8.4450e-01, 8.2030e-01, 7.9720e-01, 7.7500e-01, 7.5370e-01, 7.3330e-01, 7.1370e-01, 6.9490e-01, 6.7680e-01, 6.5940e-01, 6.4260e-01, 6.2640e-01, 6.1090e-01, 5.9580e-01, 5.8130e-01, 5.6730e-01, 5.5380e-01, 5.4070e-01, 5.2800e-01, 5.1580e-01, 5.0390e-01, 4.9250e-01, 4.8140e-01, 4.7060e-01, 4.6020e-01, 4.5010e-01, 4.4020e-01, 4.3070e-01, 4.2150e-01, 4.1260e-01, 4.0390e-01, 3.9540e-01, 3.8730e-01, 3.7930e-01, 3.7160e-01, 3.6410e-01, 3.5680e-01, 3.4970e-01, 3.4280e-01, 3.3610e-01, 3.2960e-01, 3.2330e-01, 3.1720e-01, 3.1120e-01, 3.0540e-01, 2.9970e-01, 2.9420e-01, 2.8880e-01, 2.8360e-01, 2.7850e-01, 2.7360e-01, 2.6880e-01, 2.6410e-01, 2.5950e-01, 2.5510e-01, 2.5080e-01, 2.4650e-01, 2.4240e-01, 2.3840e-01, 2.3450e-01, 2.3070e-01, 2.2700e-01, 2.2330e-01, 2.1980e-01, 2.1640e-01, 2.1300e-01, 2.0970e-01, 2.0650e-01, 2.0340e-01, 2.0030e-01, 1.9730e-01, 1.9440e-01, 1.9160e-01, 1.8880e-01, 1.8600e-01, 1.8340e-01, 1.8080e-01, 1.7820e-01, 1.7580e-01, 1.7330e-01, 1.7090e-01, 1.6860e-01, 1.6630e-01, 1.6410e-01, 1.6190e-01, 1.5970e-01, 1.5760e-01, 1.5560e-01, 1.5360e-01, 1.5160e-01, 1.4970e-01, 1.4780e-01, 1.4590e-01, 1.4410e-01, 1.4230e-01, 1.4050e-01, 1.3880e-01, 1.3710e-01, 1.3550e-01, 1.3380e-01, 1.3220e-01, 1.3070e-01, 1.2910e-01, 1.2760e-01, 1.2610e-01, 1.2460e-01, 1.2320e-01, 1.2180e-01, 1.2040e-01, 1.1900e-01, 1.1770e-01, 1.1640e-01, 1.1510e-01, 1.1380e-01, 1.1260e-01, 1.1130e-01, 1.1010e-01, 1.0890e-01, 1.0770e-01, 1.0660e-01, 1.0540e-01, 1.0430e-01, 1.0320e-01, 1.0210e-01, 1.0110e-01, 1.0000e-01, 9.9000e-02, 9.8000e-02, 9.6900e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6800e-02, 8.6000e-02, 8.5100e-02, 8.4300e-02, 8.3500e-02, 8.2700e-02, 8.1900e-02, 8.1100e-02, 8.0400e-02, 7.9600e-02, 7.8900e-02, 7.8100e-02, 7.7400e-02, 7.6700e-02, 7.6000e-02, 7.5300e-02, 7.4600e-02, 7.3900e-02, 7.3300e-02, 7.2600e-02, 7.1900e-02, 7.1300e-02, 7.0700e-02, 7.0000e-02, 6.9400e-02, 6.8800e-02, 6.8200e-02, 6.7600e-02, 6.7000e-02, 6.6400e-02, 6.5900e-02, 6.5300e-02, 6.4700e-02, 6.4200e-02, 6.3600e-02, 6.3100e-02, 6.2600e-02, 6.2100e-02, 6.1500e-02, 6.1000e-02, 6.0500e-02, 6.0000e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02}); + } + break; + case 92: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.2000e+01, 9.1514e+01, 9.0180e+01, 8.8289e+01, 8.6123e+01, 8.3860e+01, 8.1581e+01, 7.9312e+01, 7.7066e+01, 7.4858e+01, 7.2701e+01, 7.0611e+01, 6.8598e+01, 6.6671e+01, 6.4830e+01, 6.3075e+01, 6.1402e+01, 5.9805e+01, 5.8277e+01, 5.6812e+01, 5.5405e+01, 5.4051e+01, 5.2745e+01, 5.1485e+01, 5.0266e+01, 4.9089e+01, 4.7950e+01, 4.6848e+01, 4.5784e+01, 4.4754e+01, 4.3759e+01, 4.2798e+01, 4.1869e+01, 4.0971e+01, 4.0104e+01, 3.9265e+01, 3.8454e+01, 3.7669e+01, 3.6908e+01, 3.6171e+01, 3.5456e+01, 3.4762e+01, 3.4087e+01, 3.3431e+01, 3.2792e+01, 3.2169e+01, 3.1561e+01, 3.0968e+01, 3.0388e+01, 2.9822e+01, 2.9268e+01, 2.8726e+01, 2.8196e+01, 2.7678e+01, 2.7171e+01, 2.6674e+01, 2.6189e+01, 2.5715e+01, 2.5251e+01, 2.4798e+01, 2.4356e+01, 2.3924e+01, 2.3504e+01, 2.3093e+01, 2.2694e+01, 2.2305e+01, 2.1927e+01, 2.1560e+01, 2.1203e+01, 2.0857e+01, 2.0521e+01, 2.0196e+01, 1.9881e+01, 1.9576e+01, 1.9281e+01, 1.8996e+01, 1.8721e+01, 1.8455e+01, 1.8198e+01, 1.7950e+01, 1.7711e+01, 1.7480e+01, 1.7258e+01, 1.7044e+01, 1.6837e+01, 1.6637e+01, 1.6445e+01, 1.6261e+01, 1.6082e+01, 1.5909e+01, 1.5742e+01, 1.5581e+01, 1.5426e+01, 1.5275e+01, 1.5129e+01, 1.4987e+01, 1.4851e+01, 1.4718e+01, 1.4589e+01, 1.4463e+01, 1.4340e+01, 1.4220e+01, 1.4104e+01, 1.3991e+01, 1.3880e+01, 1.3770e+01, 1.3661e+01, 1.3556e+01, 1.3453e+01, 1.3351e+01, 1.3251e+01, 1.3151e+01, 1.3051e+01, 1.2954e+01, 1.2858e+01, 1.2763e+01, 1.2669e+01, 1.2574e+01, 1.2480e+01, 1.2386e+01, 1.2293e+01, 1.2202e+01, 1.2111e+01, 1.2020e+01, 1.1928e+01, 1.1836e+01, 1.1744e+01, 1.1654e+01, 1.1565e+01, 1.1476e+01, 1.1386e+01, 1.1296e+01, 1.1205e+01, 1.1114e+01, 1.1024e+01, 1.0936e+01, 1.0849e+01, 1.0761e+01, 1.0672e+01, 1.0583e+01, 1.0494e+01, 1.0405e+01, 1.0317e+01, 1.0232e+01, 1.0146e+01, 1.0060e+01, 9.9746e+00, 9.8880e+00, 9.8012e+00, 9.7151e+00, 9.6306e+00, 9.5479e+00, 9.4661e+00, 9.3845e+00, 9.3028e+00, 9.2209e+00, 9.1387e+00, 9.0567e+00, 8.9760e+00, 8.8973e+00, 8.8204e+00, 8.7443e+00, 8.6685e+00, 8.5928e+00, 8.5172e+00, 8.4414e+00, 8.3659e+00, 8.2916e+00, 8.2195e+00, 8.1496e+00, 8.0807e+00, 8.0122e+00, 7.9440e+00, 7.8762e+00, 7.8086e+00, 7.7409e+00, 7.6738e+00, 7.6085e+00, 7.5455e+00, 7.4846e+00, 7.4245e+00, 7.3647e+00, 7.3053e+00, 7.2465e+00, 7.1880e+00, 7.1294e+00, 7.0711e+00, 7.0143e+00, 6.9599e+00, 6.9079e+00, 6.8569e+00, 6.8063e+00, 6.7558e+00, 6.7060e+00, 6.6568e+00, 6.6077e+00, 6.5584e+00, 6.5095e+00, 6.4623e+00, 6.4175e+00, 6.3750e+00, 6.3334e+00, 6.2918e+00, 6.2503e+00, 6.2094e+00, 6.1692e+00, 6.1292e+00, 6.0888e+00, 6.0483e+00, 6.0088e+00, 5.9714e+00, 5.9365e+00, 5.9032e+00, 5.8702e+00, 5.8368e+00, 5.8035e+00, 5.7709e+00, 5.7389e+00, 5.7069e+00, 5.6744e+00, 5.6415e+00, 5.6093e+00, 5.5790e+00, 5.5512e+00, 5.5251e+00, 5.4994e+00, 5.4733e+00, 5.4468e+00, 5.4205e+00, 5.3950e+00, 5.3699e+00, 5.3443e+00, 5.3179e+00, 5.2911e+00, 5.2652e+00, 5.2412e+00, 5.2195e+00, 5.1995e+00, 5.1797e+00, 5.1592e+00, 5.1381e+00}); + feg = Vctr_cpu({1.9069e+01, 1.8622e+01, 1.7420e+01, 1.5790e+01, 1.4066e+01, 1.2468e+01, 1.1083e+01, 9.9160e+00, 8.9354e+00, 8.1043e+00, 7.3904e+00, 6.7693e+00, 6.2232e+00, 5.7394e+00, 5.3083e+00, 4.9228e+00, 4.5770e+00, 4.2660e+00, 3.9858e+00, 3.7326e+00, 3.5034e+00, 3.2953e+00, 3.1058e+00, 2.9329e+00, 2.7746e+00, 2.6292e+00, 2.4953e+00, 2.3718e+00, 2.2574e+00, 2.1513e+00, 2.0526e+00, 1.9606e+00, 1.8747e+00, 1.7944e+00, 1.7191e+00, 1.6485e+00, 1.5822e+00, 1.5198e+00, 1.4610e+00, 1.4056e+00, 1.3533e+00, 1.3039e+00, 1.2572e+00, 1.2130e+00, 1.1711e+00, 1.1314e+00, 1.0938e+00, 1.0580e+00, 1.0240e+00, 9.9170e-01, 9.6090e-01, 9.3160e-01, 9.0360e-01, 8.7690e-01, 8.5140e-01, 8.2700e-01, 8.0360e-01, 7.8130e-01, 7.5980e-01, 7.3930e-01, 7.1950e-01, 7.0060e-01, 6.8240e-01, 6.6480e-01, 6.4790e-01, 6.3170e-01, 6.1600e-01, 6.0090e-01, 5.8630e-01, 5.7220e-01, 5.5860e-01, 5.4550e-01, 5.3270e-01, 5.2040e-01, 5.0850e-01, 4.9700e-01, 4.8580e-01, 4.7500e-01, 4.6450e-01, 4.5440e-01, 4.4450e-01, 4.3490e-01, 4.2570e-01, 4.1670e-01, 4.0790e-01, 3.9940e-01, 3.9120e-01, 3.8320e-01, 3.7540e-01, 3.6790e-01, 3.6050e-01, 3.5340e-01, 3.4640e-01, 3.3970e-01, 3.3310e-01, 3.2680e-01, 3.2060e-01, 3.1450e-01, 3.0870e-01, 3.0290e-01, 2.9740e-01, 2.9200e-01, 2.8670e-01, 2.8160e-01, 2.7660e-01, 2.7170e-01, 2.6700e-01, 2.6240e-01, 2.5790e-01, 2.5350e-01, 2.4920e-01, 2.4510e-01, 2.4100e-01, 2.3710e-01, 2.3320e-01, 2.2940e-01, 2.2580e-01, 2.2220e-01, 2.1870e-01, 2.1530e-01, 2.1200e-01, 2.0870e-01, 2.0550e-01, 2.0240e-01, 1.9940e-01, 1.9650e-01, 1.9360e-01, 1.9080e-01, 1.8800e-01, 1.8530e-01, 1.8270e-01, 1.8010e-01, 1.7760e-01, 1.7510e-01, 1.7270e-01, 1.7030e-01, 1.6800e-01, 1.6570e-01, 1.6350e-01, 1.6140e-01, 1.5920e-01, 1.5720e-01, 1.5510e-01, 1.5310e-01, 1.5120e-01, 1.4920e-01, 1.4740e-01, 1.4550e-01, 1.4370e-01, 1.4190e-01, 1.4020e-01, 1.3850e-01, 1.3680e-01, 1.3510e-01, 1.3350e-01, 1.3190e-01, 1.3040e-01, 1.2890e-01, 1.2740e-01, 1.2590e-01, 1.2440e-01, 1.2300e-01, 1.2160e-01, 1.2020e-01, 1.1890e-01, 1.1750e-01, 1.1620e-01, 1.1490e-01, 1.1370e-01, 1.1240e-01, 1.1120e-01, 1.1000e-01, 1.0880e-01, 1.0760e-01, 1.0650e-01, 1.0540e-01, 1.0420e-01, 1.0320e-01, 1.0210e-01, 1.0100e-01, 1.0000e-01, 9.8900e-02, 9.7900e-02, 9.6900e-02, 9.5900e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2800e-02, 8.2000e-02, 8.1200e-02, 8.0400e-02, 7.9700e-02, 7.8900e-02, 7.8200e-02, 7.7500e-02, 7.6800e-02, 7.6100e-02, 7.5400e-02, 7.4700e-02, 7.4000e-02, 7.3400e-02, 7.2700e-02, 7.2000e-02, 7.1400e-02, 7.0800e-02, 7.0100e-02, 6.9500e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7100e-02, 6.6600e-02, 6.6000e-02, 6.5400e-02, 6.4900e-02, 6.4300e-02, 6.3800e-02, 6.3200e-02, 6.2700e-02, 6.2200e-02, 6.1700e-02, 6.1200e-02, 6.0700e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02}); + } + break; + case 93: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.3000e+01, 9.2523e+01, 9.1210e+01, 8.9337e+01, 8.7178e+01, 8.4910e+01, 8.2614e+01, 8.0321e+01, 7.8046e+01, 7.5803e+01, 7.3608e+01, 7.1476e+01, 6.9421e+01, 6.7452e+01, 6.5571e+01, 6.3779e+01, 6.2071e+01, 6.0444e+01, 5.8891e+01, 5.7406e+01, 5.5982e+01, 5.4615e+01, 5.3299e+01, 5.2031e+01, 5.0807e+01, 4.9626e+01, 4.8484e+01, 4.7381e+01, 4.6315e+01, 4.5284e+01, 4.4288e+01, 4.3325e+01, 4.2394e+01, 4.1494e+01, 4.0624e+01, 3.9783e+01, 3.8970e+01, 3.8182e+01, 3.7419e+01, 3.6680e+01, 3.5962e+01, 3.5266e+01, 3.4589e+01, 3.3930e+01, 3.3289e+01, 3.2664e+01, 3.2054e+01, 3.1459e+01, 3.0877e+01, 3.0309e+01, 2.9753e+01, 2.9210e+01, 2.8678e+01, 2.8157e+01, 2.7647e+01, 2.7148e+01, 2.6660e+01, 2.6182e+01, 2.5714e+01, 2.5257e+01, 2.4811e+01, 2.4374e+01, 2.3948e+01, 2.3532e+01, 2.3126e+01, 2.2731e+01, 2.2346e+01, 2.1971e+01, 2.1607e+01, 2.1253e+01, 2.0909e+01, 2.0576e+01, 2.0252e+01, 1.9939e+01, 1.9635e+01, 1.9341e+01, 1.9056e+01, 1.8781e+01, 1.8515e+01, 1.8259e+01, 1.8010e+01, 1.7771e+01, 1.7540e+01, 1.7317e+01, 1.7102e+01, 1.6894e+01, 1.6694e+01, 1.6502e+01, 1.6315e+01, 1.6135e+01, 1.5961e+01, 1.5794e+01, 1.5633e+01, 1.5476e+01, 1.5324e+01, 1.5177e+01, 1.5036e+01, 1.4899e+01, 1.4765e+01, 1.4635e+01, 1.4508e+01, 1.4386e+01, 1.4266e+01, 1.4150e+01, 1.4036e+01, 1.3924e+01, 1.3814e+01, 1.3707e+01, 1.3603e+01, 1.3500e+01, 1.3399e+01, 1.3298e+01, 1.3198e+01, 1.3101e+01, 1.3005e+01, 1.2910e+01, 1.2816e+01, 1.2722e+01, 1.2628e+01, 1.2535e+01, 1.2444e+01, 1.2353e+01, 1.2264e+01, 1.2174e+01, 1.2083e+01, 1.1992e+01, 1.1902e+01, 1.1813e+01, 1.1725e+01, 1.1637e+01, 1.1549e+01, 1.1460e+01, 1.1371e+01, 1.1282e+01, 1.1194e+01, 1.1107e+01, 1.1021e+01, 1.0934e+01, 1.0847e+01, 1.0759e+01, 1.0671e+01, 1.0583e+01, 1.0497e+01, 1.0412e+01, 1.0328e+01, 1.0243e+01, 1.0158e+01, 1.0072e+01, 9.9861e+00, 9.9006e+00, 9.8167e+00, 9.7344e+00, 9.6530e+00, 9.5718e+00, 9.4903e+00, 9.4086e+00, 9.3265e+00, 9.2446e+00, 9.1638e+00, 9.0850e+00, 9.0078e+00, 8.9315e+00, 8.8552e+00, 8.7791e+00, 8.7030e+00, 8.6267e+00, 8.5506e+00, 8.4756e+00, 8.4028e+00, 8.3319e+00, 8.2622e+00, 8.1927e+00, 8.1235e+00, 8.0547e+00, 7.9859e+00, 7.9171e+00, 7.8489e+00, 7.7823e+00, 7.7181e+00, 7.6557e+00, 7.5942e+00, 7.5330e+00, 7.4722e+00, 7.4119e+00, 7.3518e+00, 7.2917e+00, 7.2320e+00, 7.1736e+00, 7.1177e+00, 7.0639e+00, 7.0113e+00, 6.9589e+00, 6.9068e+00, 6.8553e+00, 6.8044e+00, 6.7536e+00, 6.7026e+00, 6.6521e+00, 6.6032e+00, 6.5567e+00, 6.5124e+00, 6.4690e+00, 6.4257e+00, 6.3825e+00, 6.3399e+00, 6.2980e+00, 6.2563e+00, 6.2143e+00, 6.1722e+00, 6.1311e+00, 6.0921e+00, 6.0556e+00, 6.0206e+00, 5.9859e+00, 5.9510e+00, 5.9161e+00, 5.8819e+00, 5.8484e+00, 5.8149e+00, 5.7810e+00, 5.7467e+00, 5.7132e+00, 5.6815e+00, 5.6522e+00, 5.6247e+00, 5.5976e+00, 5.5702e+00, 5.5424e+00, 5.5149e+00, 5.4881e+00, 5.4617e+00, 5.4350e+00, 5.4075e+00, 5.3797e+00, 5.3527e+00, 5.3277e+00, 5.3049e+00, 5.2838e+00, 5.2629e+00, 5.2414e+00, 5.2193e+00}); + feg = Vctr_cpu({1.8704e+01, 1.8281e+01, 1.7141e+01, 1.5587e+01, 1.3935e+01, 1.2393e+01, 1.1048e+01, 9.9085e+00, 8.9475e+00, 8.1302e+00, 7.4261e+00, 6.8118e+00, 6.2702e+00, 5.7890e+00, 5.3590e+00, 4.9733e+00, 4.6265e+00, 4.3138e+00, 4.0314e+00, 3.7757e+00, 3.5439e+00, 3.3332e+00, 3.1411e+00, 2.9657e+00, 2.8051e+00, 2.6575e+00, 2.5217e+00, 2.3963e+00, 2.2803e+00, 2.1727e+00, 2.0727e+00, 1.9795e+00, 1.8925e+00, 1.8112e+00, 1.7350e+00, 1.6636e+00, 1.5965e+00, 1.5334e+00, 1.4740e+00, 1.4180e+00, 1.3651e+00, 1.3152e+00, 1.2680e+00, 1.2234e+00, 1.1811e+00, 1.1410e+00, 1.1030e+00, 1.0668e+00, 1.0325e+00, 9.9990e-01, 9.6880e-01, 9.3920e-01, 9.1090e-01, 8.8400e-01, 8.5820e-01, 8.3360e-01, 8.1010e-01, 7.8750e-01, 7.6590e-01, 7.4520e-01, 7.2530e-01, 7.0620e-01, 6.8790e-01, 6.7020e-01, 6.5330e-01, 6.3690e-01, 6.2110e-01, 6.0590e-01, 5.9120e-01, 5.7710e-01, 5.6340e-01, 5.5020e-01, 5.3740e-01, 5.2500e-01, 5.1300e-01, 5.0150e-01, 4.9020e-01, 4.7940e-01, 4.6880e-01, 4.5860e-01, 4.4870e-01, 4.3910e-01, 4.2980e-01, 4.2070e-01, 4.1190e-01, 4.0340e-01, 3.9510e-01, 3.8700e-01, 3.7920e-01, 3.7160e-01, 3.6420e-01, 3.5700e-01, 3.5000e-01, 3.4320e-01, 3.3660e-01, 3.3020e-01, 3.2400e-01, 3.1790e-01, 3.1190e-01, 3.0620e-01, 3.0060e-01, 2.9510e-01, 2.8980e-01, 2.8460e-01, 2.7960e-01, 2.7470e-01, 2.6990e-01, 2.6520e-01, 2.6070e-01, 2.5620e-01, 2.5190e-01, 2.4770e-01, 2.4360e-01, 2.3960e-01, 2.3570e-01, 2.3190e-01, 2.2820e-01, 2.2460e-01, 2.2100e-01, 2.1760e-01, 2.1420e-01, 2.1090e-01, 2.0770e-01, 2.0460e-01, 2.0150e-01, 1.9850e-01, 1.9560e-01, 1.9280e-01, 1.9000e-01, 1.8720e-01, 1.8460e-01, 1.8200e-01, 1.7940e-01, 1.7690e-01, 1.7450e-01, 1.7210e-01, 1.6970e-01, 1.6740e-01, 1.6520e-01, 1.6300e-01, 1.6090e-01, 1.5870e-01, 1.5670e-01, 1.5470e-01, 1.5270e-01, 1.5070e-01, 1.4880e-01, 1.4700e-01, 1.4510e-01, 1.4330e-01, 1.4160e-01, 1.3980e-01, 1.3810e-01, 1.3650e-01, 1.3480e-01, 1.3320e-01, 1.3170e-01, 1.3010e-01, 1.2860e-01, 1.2710e-01, 1.2560e-01, 1.2420e-01, 1.2280e-01, 1.2140e-01, 1.2000e-01, 1.1870e-01, 1.1740e-01, 1.1610e-01, 1.1480e-01, 1.1350e-01, 1.1230e-01, 1.1110e-01, 1.0990e-01, 1.0870e-01, 1.0750e-01, 1.0640e-01, 1.0530e-01, 1.0420e-01, 1.0310e-01, 1.0200e-01, 1.0090e-01, 9.9900e-02, 9.8900e-02, 9.7900e-02, 9.6900e-02, 9.5900e-02, 9.4900e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2800e-02, 8.2000e-02, 8.1200e-02, 8.0500e-02, 7.9700e-02, 7.9000e-02, 7.8300e-02, 7.7600e-02, 7.6900e-02, 7.6200e-02, 7.5500e-02, 7.4800e-02, 7.4100e-02, 7.3400e-02, 7.2800e-02, 7.2100e-02, 7.1500e-02, 7.0900e-02, 7.0300e-02, 6.9600e-02, 6.9000e-02, 6.8400e-02, 6.7800e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5500e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3400e-02, 6.2800e-02, 6.2300e-02, 6.1800e-02, 6.1300e-02, 6.0800e-02, 6.0300e-02, 5.9800e-02, 5.9300e-02, 5.8800e-02, 5.8400e-02}); + } + break; + case 94: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.4000e+01, 9.3539e+01, 9.2276e+01, 9.0480e+01, 8.8405e+01, 8.6199e+01, 8.3929e+01, 8.1623e+01, 7.9302e+01, 7.6991e+01, 7.4718e+01, 7.2505e+01, 7.0371e+01, 6.8327e+01, 6.6379e+01, 6.4526e+01, 6.2767e+01, 6.1094e+01, 5.9503e+01, 5.7986e+01, 5.6536e+01, 5.5148e+01, 5.3816e+01, 5.2537e+01, 5.1305e+01, 5.0118e+01, 4.8973e+01, 4.7868e+01, 4.6802e+01, 4.5772e+01, 4.4777e+01, 4.3816e+01, 4.2888e+01, 4.1990e+01, 4.1123e+01, 4.0283e+01, 3.9471e+01, 3.8685e+01, 3.7923e+01, 3.7184e+01, 3.6467e+01, 3.5771e+01, 3.5093e+01, 3.4434e+01, 3.3792e+01, 3.3167e+01, 3.2556e+01, 3.1959e+01, 3.1377e+01, 3.0807e+01, 3.0249e+01, 2.9703e+01, 2.9169e+01, 2.8645e+01, 2.8132e+01, 2.7630e+01, 2.7138e+01, 2.6656e+01, 2.6185e+01, 2.5723e+01, 2.5271e+01, 2.4829e+01, 2.4398e+01, 2.3976e+01, 2.3564e+01, 2.3162e+01, 2.2770e+01, 2.2388e+01, 2.2017e+01, 2.1655e+01, 2.1303e+01, 2.0961e+01, 2.0629e+01, 2.0307e+01, 1.9995e+01, 1.9692e+01, 1.9399e+01, 1.9115e+01, 1.8840e+01, 1.8574e+01, 1.8318e+01, 1.8070e+01, 1.7830e+01, 1.7598e+01, 1.7375e+01, 1.7160e+01, 1.6952e+01, 1.6751e+01, 1.6556e+01, 1.6369e+01, 1.6189e+01, 1.6015e+01, 1.5847e+01, 1.5683e+01, 1.5526e+01, 1.5374e+01, 1.5227e+01, 1.5085e+01, 1.4946e+01, 1.4811e+01, 1.4681e+01, 1.4555e+01, 1.4432e+01, 1.4312e+01, 1.4195e+01, 1.4080e+01, 1.3969e+01, 1.3860e+01, 1.3754e+01, 1.3649e+01, 1.3545e+01, 1.3443e+01, 1.3344e+01, 1.3247e+01, 1.3151e+01, 1.3055e+01, 1.2960e+01, 1.2865e+01, 1.2772e+01, 1.2681e+01, 1.2591e+01, 1.2501e+01, 1.2411e+01, 1.2320e+01, 1.2230e+01, 1.2141e+01, 1.2054e+01, 1.1967e+01, 1.1880e+01, 1.1793e+01, 1.1704e+01, 1.1616e+01, 1.1529e+01, 1.1443e+01, 1.1357e+01, 1.1272e+01, 1.1186e+01, 1.1100e+01, 1.1012e+01, 1.0925e+01, 1.0840e+01, 1.0755e+01, 1.0671e+01, 1.0587e+01, 1.0503e+01, 1.0418e+01, 1.0332e+01, 1.0247e+01, 1.0163e+01, 1.0080e+01, 9.9985e+00, 9.9168e+00, 9.8353e+00, 9.7534e+00, 9.6709e+00, 9.5883e+00, 9.5068e+00, 9.4270e+00, 9.3484e+00, 9.2704e+00, 9.1928e+00, 9.1156e+00, 9.0382e+00, 8.9604e+00, 8.8827e+00, 8.8062e+00, 8.7316e+00, 8.6584e+00, 8.5860e+00, 8.5141e+00, 8.4428e+00, 8.3720e+00, 8.3009e+00, 8.2296e+00, 8.1590e+00, 8.0902e+00, 8.0234e+00, 7.9579e+00, 7.8929e+00, 7.8286e+00, 7.7651e+00, 7.7022e+00, 7.6392e+00, 7.5759e+00, 7.5132e+00, 7.4523e+00, 7.3936e+00, 7.3364e+00, 7.2799e+00, 7.2238e+00, 7.1686e+00, 7.1143e+00, 7.0603e+00, 7.0061e+00, 6.9517e+00, 6.8982e+00, 6.8468e+00, 6.7975e+00, 6.7496e+00, 6.7022e+00, 6.6550e+00, 6.6088e+00, 6.5635e+00, 6.5187e+00, 6.4735e+00, 6.4280e+00, 6.3829e+00, 6.3395e+00, 6.2983e+00, 6.2589e+00, 6.2202e+00, 6.1816e+00, 6.1433e+00, 6.1060e+00, 6.0695e+00, 6.0333e+00, 5.9966e+00, 5.9593e+00, 5.9224e+00, 5.8870e+00, 5.8538e+00, 5.8225e+00, 5.7918e+00, 5.7610e+00, 5.7304e+00, 5.7004e+00, 5.6713e+00, 5.6427e+00, 5.6138e+00, 5.5840e+00, 5.5537e+00, 5.5240e+00, 5.4960e+00, 5.4702e+00, 5.4460e+00, 5.4221e+00, 5.3980e+00, 5.3738e+00, 5.3501e+00, 5.3272e+00, 5.3048e+00}); + feg = Vctr_cpu({1.8085e+01, 1.7654e+01, 1.6506e+01, 1.4976e+01, 1.3392e+01, 1.1949e+01, 1.0712e+01, 9.6730e+00, 8.7947e+00, 8.0412e+00, 7.3839e+00, 6.8027e+00, 6.2836e+00, 5.8172e+00, 5.3965e+00, 5.0162e+00, 4.6721e+00, 4.3602e+00, 4.0772e+00, 3.8203e+00, 3.5866e+00, 3.3737e+00, 3.1793e+00, 3.0015e+00, 2.8385e+00, 2.6887e+00, 2.5507e+00, 2.4233e+00, 2.3053e+00, 2.1960e+00, 2.0944e+00, 1.9997e+00, 1.9114e+00, 1.8289e+00, 1.7516e+00, 1.6792e+00, 1.6112e+00, 1.5473e+00, 1.4871e+00, 1.4304e+00, 1.3770e+00, 1.3265e+00, 1.2788e+00, 1.2336e+00, 1.1909e+00, 1.1504e+00, 1.1120e+00, 1.0755e+00, 1.0408e+00, 1.0079e+00, 9.7650e-01, 9.4660e-01, 9.1810e-01, 8.9100e-01, 8.6500e-01, 8.4020e-01, 8.1650e-01, 7.9370e-01, 7.7200e-01, 7.5110e-01, 7.3110e-01, 7.1190e-01, 6.9340e-01, 6.7560e-01, 6.5850e-01, 6.4200e-01, 6.2620e-01, 6.1090e-01, 5.9610e-01, 5.8190e-01, 5.6810e-01, 5.5480e-01, 5.4200e-01, 5.2960e-01, 5.1750e-01, 5.0590e-01, 4.9460e-01, 4.8370e-01, 4.7310e-01, 4.6280e-01, 4.5280e-01, 4.4320e-01, 4.3380e-01, 4.2470e-01, 4.1590e-01, 4.0730e-01, 3.9890e-01, 3.9080e-01, 3.8300e-01, 3.7530e-01, 3.6790e-01, 3.6060e-01, 3.5360e-01, 3.4680e-01, 3.4010e-01, 3.3360e-01, 3.2730e-01, 3.2120e-01, 3.1520e-01, 3.0940e-01, 3.0370e-01, 2.9820e-01, 2.9290e-01, 2.8760e-01, 2.8250e-01, 2.7760e-01, 2.7280e-01, 2.6800e-01, 2.6350e-01, 2.5900e-01, 2.5460e-01, 2.5040e-01, 2.4620e-01, 2.4220e-01, 2.3820e-01, 2.3440e-01, 2.3060e-01, 2.2700e-01, 2.2340e-01, 2.1990e-01, 2.1650e-01, 2.1320e-01, 2.0990e-01, 2.0670e-01, 2.0360e-01, 2.0060e-01, 1.9770e-01, 1.9480e-01, 1.9190e-01, 1.8920e-01, 1.8650e-01, 1.8380e-01, 1.8130e-01, 1.7870e-01, 1.7620e-01, 1.7380e-01, 1.7150e-01, 1.6910e-01, 1.6690e-01, 1.6470e-01, 1.6250e-01, 1.6030e-01, 1.5830e-01, 1.5620e-01, 1.5420e-01, 1.5220e-01, 1.5030e-01, 1.4840e-01, 1.4660e-01, 1.4480e-01, 1.4300e-01, 1.4120e-01, 1.3950e-01, 1.3780e-01, 1.3620e-01, 1.3450e-01, 1.3300e-01, 1.3140e-01, 1.2990e-01, 1.2830e-01, 1.2690e-01, 1.2540e-01, 1.2400e-01, 1.2260e-01, 1.2120e-01, 1.1980e-01, 1.1850e-01, 1.1720e-01, 1.1590e-01, 1.1460e-01, 1.1340e-01, 1.1210e-01, 1.1090e-01, 1.0970e-01, 1.0860e-01, 1.0740e-01, 1.0630e-01, 1.0520e-01, 1.0410e-01, 1.0300e-01, 1.0190e-01, 1.0090e-01, 9.9800e-02, 9.8800e-02, 9.7800e-02, 9.6800e-02, 9.5900e-02, 9.4900e-02, 9.4000e-02, 9.3000e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2800e-02, 8.2100e-02, 8.1300e-02, 8.0500e-02, 7.9800e-02, 7.9100e-02, 7.8300e-02, 7.7600e-02, 7.6900e-02, 7.6200e-02, 7.5500e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2900e-02, 7.2200e-02, 7.1600e-02, 7.1000e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8500e-02, 6.7900e-02, 6.7400e-02, 6.6800e-02, 6.6200e-02, 6.5700e-02, 6.5100e-02, 6.4600e-02, 6.4000e-02, 6.3500e-02, 6.3000e-02, 6.2400e-02, 6.1900e-02, 6.1400e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.9000e-02}); + } + break; + case 95: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.5000e+01, 9.4548e+01, 9.3306e+01, 9.1533e+01, 8.9472e+01, 8.7271e+01, 8.4996e+01, 8.2677e+01, 8.0336e+01, 7.7999e+01, 7.5694e+01, 7.3444e+01, 7.1269e+01, 6.9183e+01, 6.7191e+01, 6.5296e+01, 6.3496e+01, 6.1787e+01, 6.0162e+01, 5.8615e+01, 5.7140e+01, 5.5731e+01, 5.4381e+01, 5.3086e+01, 5.1842e+01, 5.0645e+01, 4.9493e+01, 4.8382e+01, 4.7311e+01, 4.6277e+01, 4.5279e+01, 4.4316e+01, 4.3385e+01, 4.2486e+01, 4.1617e+01, 4.0776e+01, 3.9963e+01, 3.9175e+01, 3.8412e+01, 3.7672e+01, 3.6954e+01, 3.6257e+01, 3.5578e+01, 3.4919e+01, 3.4276e+01, 3.3649e+01, 3.3038e+01, 3.2441e+01, 3.1857e+01, 3.1287e+01, 3.0728e+01, 3.0181e+01, 2.9645e+01, 2.9121e+01, 2.8606e+01, 2.8102e+01, 2.7608e+01, 2.7124e+01, 2.6650e+01, 2.6185e+01, 2.5730e+01, 2.5284e+01, 2.4848e+01, 2.4422e+01, 2.4005e+01, 2.3598e+01, 2.3200e+01, 2.2812e+01, 2.2434e+01, 2.2065e+01, 2.1706e+01, 2.1357e+01, 2.1018e+01, 2.0687e+01, 2.0367e+01, 2.0056e+01, 1.9755e+01, 1.9462e+01, 1.9178e+01, 1.8904e+01, 1.8639e+01, 1.8383e+01, 1.8134e+01, 1.7894e+01, 1.7662e+01, 1.7439e+01, 1.7222e+01, 1.7013e+01, 1.6811e+01, 1.6617e+01, 1.6429e+01, 1.6248e+01, 1.6072e+01, 1.5902e+01, 1.5739e+01, 1.5581e+01, 1.5428e+01, 1.5279e+01, 1.5135e+01, 1.4996e+01, 1.4862e+01, 1.4732e+01, 1.4604e+01, 1.4480e+01, 1.4359e+01, 1.4242e+01, 1.4128e+01, 1.4017e+01, 1.3908e+01, 1.3800e+01, 1.3695e+01, 1.3592e+01, 1.3492e+01, 1.3394e+01, 1.3296e+01, 1.3199e+01, 1.3103e+01, 1.3009e+01, 1.2917e+01, 1.2826e+01, 1.2736e+01, 1.2646e+01, 1.2555e+01, 1.2466e+01, 1.2377e+01, 1.2290e+01, 1.2204e+01, 1.2117e+01, 1.2031e+01, 1.1944e+01, 1.1857e+01, 1.1770e+01, 1.1685e+01, 1.1601e+01, 1.1517e+01, 1.1432e+01, 1.1347e+01, 1.1261e+01, 1.1175e+01, 1.1091e+01, 1.1007e+01, 1.0924e+01, 1.0841e+01, 1.0758e+01, 1.0674e+01, 1.0589e+01, 1.0505e+01, 1.0422e+01, 1.0340e+01, 1.0258e+01, 1.0177e+01, 1.0096e+01, 1.0015e+01, 9.9324e+00, 9.8501e+00, 9.7688e+00, 9.6890e+00, 9.6100e+00, 9.5318e+00, 9.4541e+00, 9.3766e+00, 9.2987e+00, 9.2201e+00, 9.1419e+00, 9.0649e+00, 8.9894e+00, 8.9151e+00, 8.8415e+00, 8.7687e+00, 8.6966e+00, 8.6245e+00, 8.5518e+00, 8.4790e+00, 8.4072e+00, 8.3372e+00, 8.2687e+00, 8.2012e+00, 8.1344e+00, 8.0686e+00, 8.0036e+00, 7.9387e+00, 7.8735e+00, 7.8080e+00, 7.7436e+00, 7.6811e+00, 7.6203e+00, 7.5606e+00, 7.5015e+00, 7.4434e+00, 7.3864e+00, 7.3300e+00, 7.2735e+00, 7.2165e+00, 7.1598e+00, 7.1044e+00, 7.0512e+00, 6.9995e+00, 6.9487e+00, 6.8984e+00, 6.8491e+00, 6.8009e+00, 6.7536e+00, 6.7062e+00, 6.6581e+00, 6.6099e+00, 6.5628e+00, 6.5177e+00, 6.4745e+00, 6.4323e+00, 6.3906e+00, 6.3494e+00, 6.3092e+00, 6.2702e+00, 6.2318e+00, 6.1930e+00, 6.1534e+00, 6.1137e+00, 6.0749e+00, 6.0381e+00, 6.0033e+00, 5.9694e+00, 5.9359e+00, 5.9027e+00, 5.8702e+00, 5.8388e+00, 5.8083e+00, 5.7777e+00, 5.7463e+00, 5.7141e+00, 5.6819e+00, 5.6509e+00, 5.6221e+00, 5.5949e+00, 5.5684e+00, 5.5420e+00, 5.5157e+00, 5.4901e+00, 5.4655e+00, 5.4417e+00, 5.4179e+00, 5.3932e+00}); + feg = Vctr_cpu({1.7721e+01, 1.7310e+01, 1.6215e+01, 1.4752e+01, 1.3231e+01, 1.1839e+01, 1.0641e+01, 9.6306e+00, 8.7740e+00, 8.0373e+00, 7.3931e+00, 6.8221e+00, 6.3107e+00, 5.8500e+00, 5.4332e+00, 5.0554e+00, 4.7125e+00, 4.4009e+00, 4.1175e+00, 3.8596e+00, 3.6245e+00, 3.4099e+00, 3.2138e+00, 3.0341e+00, 2.8692e+00, 2.7176e+00, 2.5779e+00, 2.4488e+00, 2.3293e+00, 2.2185e+00, 2.1155e+00, 2.0197e+00, 1.9302e+00, 1.8466e+00, 1.7684e+00, 1.6951e+00, 1.6262e+00, 1.5615e+00, 1.5007e+00, 1.4433e+00, 1.3893e+00, 1.3382e+00, 1.2900e+00, 1.2443e+00, 1.2011e+00, 1.1602e+00, 1.1213e+00, 1.0845e+00, 1.0495e+00, 1.0162e+00, 9.8450e-01, 9.5430e-01, 9.2550e-01, 8.9810e-01, 8.7190e-01, 8.4690e-01, 8.2290e-01, 8.0000e-01, 7.7810e-01, 7.5700e-01, 7.3680e-01, 7.1750e-01, 6.9890e-01, 6.8100e-01, 6.6370e-01, 6.4720e-01, 6.3120e-01, 6.1580e-01, 6.0100e-01, 5.8660e-01, 5.7280e-01, 5.5940e-01, 5.4650e-01, 5.3400e-01, 5.2190e-01, 5.1020e-01, 4.9890e-01, 4.8790e-01, 4.7720e-01, 4.6690e-01, 4.5690e-01, 4.4720e-01, 4.3780e-01, 4.2860e-01, 4.1970e-01, 4.1110e-01, 4.0270e-01, 3.9460e-01, 3.8660e-01, 3.7890e-01, 3.7150e-01, 3.6420e-01, 3.5710e-01, 3.5020e-01, 3.4350e-01, 3.3700e-01, 3.3060e-01, 3.2450e-01, 3.1840e-01, 3.1260e-01, 3.0690e-01, 3.0130e-01, 2.9590e-01, 2.9060e-01, 2.8550e-01, 2.8050e-01, 2.7560e-01, 2.7090e-01, 2.6620e-01, 2.6170e-01, 2.5730e-01, 2.5300e-01, 2.4880e-01, 2.4470e-01, 2.4070e-01, 2.3690e-01, 2.3310e-01, 2.2940e-01, 2.2570e-01, 2.2220e-01, 2.1880e-01, 2.1540e-01, 2.1210e-01, 2.0890e-01, 2.0580e-01, 2.0270e-01, 1.9970e-01, 1.9680e-01, 1.9390e-01, 1.9110e-01, 1.8840e-01, 1.8570e-01, 1.8310e-01, 1.8050e-01, 1.7800e-01, 1.7560e-01, 1.7320e-01, 1.7090e-01, 1.6860e-01, 1.6630e-01, 1.6410e-01, 1.6190e-01, 1.5980e-01, 1.5780e-01, 1.5570e-01, 1.5370e-01, 1.5180e-01, 1.4990e-01, 1.4800e-01, 1.4620e-01, 1.4440e-01, 1.4260e-01, 1.4090e-01, 1.3920e-01, 1.3750e-01, 1.3590e-01, 1.3420e-01, 1.3270e-01, 1.3110e-01, 1.2960e-01, 1.2810e-01, 1.2660e-01, 1.2520e-01, 1.2370e-01, 1.2240e-01, 1.2100e-01, 1.1960e-01, 1.1830e-01, 1.1700e-01, 1.1570e-01, 1.1450e-01, 1.1320e-01, 1.1200e-01, 1.1080e-01, 1.0960e-01, 1.0840e-01, 1.0730e-01, 1.0620e-01, 1.0510e-01, 1.0400e-01, 1.0290e-01, 1.0180e-01, 1.0080e-01, 9.9800e-02, 9.8800e-02, 9.7800e-02, 9.6800e-02, 9.5800e-02, 9.4900e-02, 9.3900e-02, 9.3000e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2900e-02, 8.2100e-02, 8.1300e-02, 8.0600e-02, 7.9800e-02, 7.9100e-02, 7.8400e-02, 7.7700e-02, 7.7000e-02, 7.6300e-02, 7.5600e-02, 7.4900e-02, 7.4300e-02, 7.3600e-02, 7.3000e-02, 7.2300e-02, 7.1700e-02, 7.1100e-02, 7.0400e-02, 6.9800e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5800e-02, 6.5200e-02, 6.4700e-02, 6.4100e-02, 6.3600e-02, 6.3100e-02, 6.2600e-02, 6.2000e-02, 6.1500e-02, 6.1000e-02, 6.0500e-02, 6.0100e-02, 5.9600e-02}); + } + break; + case 96: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.6000e+01, 9.5550e+01, 9.4301e+01, 9.2492e+01, 9.0372e+01, 8.8109e+01, 8.5789e+01, 8.3450e+01, 8.1108e+01, 7.8782e+01, 7.6489e+01, 7.4247e+01, 7.2074e+01, 6.9980e+01, 6.7975e+01, 6.6061e+01, 6.4239e+01, 6.2505e+01, 6.0855e+01, 5.9285e+01, 5.7788e+01, 5.6358e+01, 5.4991e+01, 5.3681e+01, 5.2423e+01, 5.1214e+01, 5.0051e+01, 4.8931e+01, 4.7852e+01, 4.6810e+01, 4.5805e+01, 4.4835e+01, 4.3898e+01, 4.2993e+01, 4.2119e+01, 4.1273e+01, 4.0454e+01, 3.9662e+01, 3.8895e+01, 3.8151e+01, 3.7429e+01, 3.6729e+01, 3.6048e+01, 3.5386e+01, 3.4742e+01, 3.4113e+01, 3.3501e+01, 3.2903e+01, 3.2318e+01, 3.1747e+01, 3.1188e+01, 3.0641e+01, 3.0105e+01, 2.9580e+01, 2.9065e+01, 2.8560e+01, 2.8066e+01, 2.7580e+01, 2.7105e+01, 2.6638e+01, 2.6181e+01, 2.5733e+01, 2.5294e+01, 2.4865e+01, 2.4444e+01, 2.4033e+01, 2.3631e+01, 2.3238e+01, 2.2855e+01, 2.2481e+01, 2.2116e+01, 2.1760e+01, 2.1414e+01, 2.1077e+01, 2.0749e+01, 2.0431e+01, 2.0121e+01, 1.9821e+01, 1.9530e+01, 1.9247e+01, 1.8974e+01, 1.8708e+01, 1.8451e+01, 1.8203e+01, 1.7963e+01, 1.7731e+01, 1.7506e+01, 1.7289e+01, 1.7080e+01, 1.6877e+01, 1.6682e+01, 1.6492e+01, 1.6310e+01, 1.6133e+01, 1.5963e+01, 1.5798e+01, 1.5639e+01, 1.5484e+01, 1.5335e+01, 1.5191e+01, 1.5051e+01, 1.4915e+01, 1.4783e+01, 1.4655e+01, 1.4531e+01, 1.4411e+01, 1.4293e+01, 1.4178e+01, 1.4065e+01, 1.3956e+01, 1.3849e+01, 1.3745e+01, 1.3643e+01, 1.3542e+01, 1.3442e+01, 1.3344e+01, 1.3249e+01, 1.3155e+01, 1.3063e+01, 1.2971e+01, 1.2879e+01, 1.2788e+01, 1.2699e+01, 1.2611e+01, 1.2524e+01, 1.2438e+01, 1.2351e+01, 1.2264e+01, 1.2177e+01, 1.2092e+01, 1.2008e+01, 1.1924e+01, 1.1841e+01, 1.1757e+01, 1.1672e+01, 1.1587e+01, 1.1503e+01, 1.1420e+01, 1.1338e+01, 1.1256e+01, 1.1174e+01, 1.1091e+01, 1.1007e+01, 1.0923e+01, 1.0841e+01, 1.0759e+01, 1.0678e+01, 1.0598e+01, 1.0517e+01, 1.0435e+01, 1.0353e+01, 1.0271e+01, 1.0189e+01, 1.0109e+01, 1.0030e+01, 9.9516e+00, 9.8732e+00, 9.7942e+00, 9.7149e+00, 9.6354e+00, 9.5562e+00, 9.4778e+00, 9.4011e+00, 9.3259e+00, 9.2513e+00, 9.1766e+00, 9.1016e+00, 9.0265e+00, 8.9515e+00, 8.8767e+00, 8.8028e+00, 8.7305e+00, 8.6600e+00, 8.5907e+00, 8.5217e+00, 8.4524e+00, 8.3832e+00, 8.3143e+00, 8.2456e+00, 8.1772e+00, 8.1100e+00, 8.0447e+00, 7.9813e+00, 7.9191e+00, 7.8571e+00, 7.7951e+00, 7.7332e+00, 7.6717e+00, 7.6106e+00, 7.5499e+00, 7.4899e+00, 7.4316e+00, 7.3754e+00, 7.3210e+00, 7.2672e+00, 7.2134e+00, 7.1595e+00, 7.1060e+00, 7.0532e+00, 7.0007e+00, 6.9485e+00, 6.8970e+00, 6.8472e+00, 6.7996e+00, 6.7538e+00, 6.7087e+00, 6.6635e+00, 6.6181e+00, 6.5730e+00, 6.5286e+00, 6.4847e+00, 6.4410e+00, 6.3975e+00, 6.3550e+00, 6.3145e+00, 6.2761e+00, 6.2392e+00, 6.2026e+00, 6.1656e+00, 6.1284e+00, 6.0915e+00, 6.0553e+00, 6.0197e+00, 5.9840e+00, 5.9484e+00, 5.9133e+00, 5.8799e+00, 5.8486e+00, 5.8191e+00, 5.7903e+00, 5.7612e+00, 5.7314e+00, 5.7015e+00, 5.6720e+00, 5.6433e+00, 5.6148e+00, 5.5862e+00, 5.5574e+00, 5.5291e+00, 5.5022e+00, 5.4775e+00}); + feg = Vctr_cpu({1.7598e+01, 1.7241e+01, 1.6269e+01, 1.4926e+01, 1.3470e+01, 1.2087e+01, 1.0861e+01, 9.8082e+00, 8.9103e+00, 8.1401e+00, 7.4716e+00, 6.8842e+00, 6.3627e+00, 5.8958e+00, 5.4754e+00, 5.0955e+00, 4.7511e+00, 4.4383e+00, 4.1538e+00, 3.8946e+00, 3.6582e+00, 3.4422e+00, 3.2446e+00, 3.0635e+00, 2.8971e+00, 2.7440e+00, 2.6029e+00, 2.4725e+00, 2.3518e+00, 2.2398e+00, 2.1357e+00, 2.0388e+00, 1.9484e+00, 1.8639e+00, 1.7849e+00, 1.7108e+00, 1.6412e+00, 1.5759e+00, 1.5144e+00, 1.4565e+00, 1.4018e+00, 1.3502e+00, 1.3015e+00, 1.2553e+00, 1.2117e+00, 1.1703e+00, 1.1311e+00, 1.0938e+00, 1.0584e+00, 1.0248e+00, 9.9280e-01, 9.6230e-01, 9.3320e-01, 9.0550e-01, 8.7900e-01, 8.5370e-01, 8.2960e-01, 8.0640e-01, 7.8430e-01, 7.6300e-01, 7.4270e-01, 7.2310e-01, 7.0440e-01, 6.8630e-01, 6.6900e-01, 6.5230e-01, 6.3620e-01, 6.2070e-01, 6.0580e-01, 5.9130e-01, 5.7740e-01, 5.6400e-01, 5.5100e-01, 5.3840e-01, 5.2620e-01, 5.1450e-01, 5.0310e-01, 4.9200e-01, 4.8130e-01, 4.7090e-01, 4.6090e-01, 4.5110e-01, 4.4160e-01, 4.3240e-01, 4.2350e-01, 4.1480e-01, 4.0640e-01, 3.9820e-01, 3.9030e-01, 3.8250e-01, 3.7500e-01, 3.6770e-01, 3.6050e-01, 3.5360e-01, 3.4690e-01, 3.4030e-01, 3.3390e-01, 3.2770e-01, 3.2160e-01, 3.1570e-01, 3.1000e-01, 3.0440e-01, 2.9890e-01, 2.9360e-01, 2.8840e-01, 2.8340e-01, 2.7850e-01, 2.7370e-01, 2.6900e-01, 2.6440e-01, 2.6000e-01, 2.5560e-01, 2.5140e-01, 2.4730e-01, 2.4330e-01, 2.3930e-01, 2.3550e-01, 2.3180e-01, 2.2810e-01, 2.2450e-01, 2.2100e-01, 2.1760e-01, 2.1430e-01, 2.1110e-01, 2.0790e-01, 2.0480e-01, 2.0180e-01, 1.9880e-01, 1.9590e-01, 1.9310e-01, 1.9030e-01, 1.8760e-01, 1.8500e-01, 1.8240e-01, 1.7980e-01, 1.7740e-01, 1.7490e-01, 1.7260e-01, 1.7020e-01, 1.6800e-01, 1.6570e-01, 1.6350e-01, 1.6140e-01, 1.5930e-01, 1.5730e-01, 1.5530e-01, 1.5330e-01, 1.5130e-01, 1.4940e-01, 1.4760e-01, 1.4580e-01, 1.4400e-01, 1.4220e-01, 1.4050e-01, 1.3880e-01, 1.3720e-01, 1.3550e-01, 1.3390e-01, 1.3240e-01, 1.3080e-01, 1.2930e-01, 1.2780e-01, 1.2640e-01, 1.2490e-01, 1.2350e-01, 1.2210e-01, 1.2080e-01, 1.1940e-01, 1.1810e-01, 1.1680e-01, 1.1550e-01, 1.1430e-01, 1.1310e-01, 1.1180e-01, 1.1060e-01, 1.0950e-01, 1.0830e-01, 1.0720e-01, 1.0610e-01, 1.0500e-01, 1.0390e-01, 1.0280e-01, 1.0180e-01, 1.0070e-01, 9.9700e-02, 9.8700e-02, 9.7700e-02, 9.6700e-02, 9.5800e-02, 9.4800e-02, 9.3900e-02, 9.3000e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2100e-02, 8.1400e-02, 8.0600e-02, 7.9900e-02, 7.9200e-02, 7.8400e-02, 7.7700e-02, 7.7000e-02, 7.6300e-02, 7.5700e-02, 7.5000e-02, 7.4300e-02, 7.3700e-02, 7.3000e-02, 7.2400e-02, 7.1800e-02, 7.1100e-02, 7.0500e-02, 6.9900e-02, 6.9300e-02, 6.8700e-02, 6.8100e-02, 6.7600e-02, 6.7000e-02, 6.6400e-02, 6.5900e-02, 6.5300e-02, 6.4800e-02, 6.4200e-02, 6.3700e-02, 6.3200e-02, 6.2700e-02, 6.2200e-02, 6.1700e-02, 6.1200e-02, 6.0700e-02, 6.0200e-02}); + } + break; + case 97: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.7000e+01, 9.6557e+01, 9.5325e+01, 9.3536e+01, 9.1430e+01, 8.9174e+01, 8.6853e+01, 8.4505e+01, 8.2149e+01, 7.9802e+01, 7.7483e+01, 7.5210e+01, 7.3001e+01, 7.0869e+01, 6.8823e+01, 6.6868e+01, 6.5006e+01, 6.3233e+01, 6.1548e+01, 5.9945e+01, 5.8418e+01, 5.6962e+01, 5.5572e+01, 5.4242e+01, 5.2968e+01, 5.1746e+01, 5.0572e+01, 4.9442e+01, 4.8355e+01, 4.7308e+01, 4.6298e+01, 4.5324e+01, 4.4384e+01, 4.3476e+01, 4.2599e+01, 4.1751e+01, 4.0931e+01, 4.0138e+01, 3.9369e+01, 3.8625e+01, 3.7902e+01, 3.7201e+01, 3.6520e+01, 3.5857e+01, 3.5212e+01, 3.4583e+01, 3.3970e+01, 3.3372e+01, 3.2787e+01, 3.2215e+01, 3.1656e+01, 3.1108e+01, 3.0572e+01, 3.0046e+01, 2.9530e+01, 2.9025e+01, 2.8529e+01, 2.8042e+01, 2.7564e+01, 2.7096e+01, 2.6637e+01, 2.6186e+01, 2.5744e+01, 2.5311e+01, 2.4887e+01, 2.4472e+01, 2.4065e+01, 2.3668e+01, 2.3279e+01, 2.2899e+01, 2.2529e+01, 2.2167e+01, 2.1814e+01, 2.1470e+01, 2.1136e+01, 2.0810e+01, 2.0493e+01, 2.0185e+01, 1.9886e+01, 1.9595e+01, 1.9314e+01, 1.9041e+01, 1.8776e+01, 1.8519e+01, 1.8271e+01, 1.8031e+01, 1.7798e+01, 1.7573e+01, 1.7355e+01, 1.7145e+01, 1.6942e+01, 1.6745e+01, 1.6555e+01, 1.6371e+01, 1.6194e+01, 1.6023e+01, 1.5857e+01, 1.5697e+01, 1.5541e+01, 1.5391e+01, 1.5246e+01, 1.5106e+01, 1.4969e+01, 1.4836e+01, 1.4707e+01, 1.4582e+01, 1.4461e+01, 1.4343e+01, 1.4228e+01, 1.4115e+01, 1.4005e+01, 1.3898e+01, 1.3794e+01, 1.3692e+01, 1.3591e+01, 1.3492e+01, 1.3394e+01, 1.3298e+01, 1.3205e+01, 1.3113e+01, 1.3022e+01, 1.2932e+01, 1.2842e+01, 1.2752e+01, 1.2664e+01, 1.2578e+01, 1.2493e+01, 1.2409e+01, 1.2324e+01, 1.2238e+01, 1.2153e+01, 1.2069e+01, 1.1986e+01, 1.1904e+01, 1.1822e+01, 1.1740e+01, 1.1658e+01, 1.1574e+01, 1.1491e+01, 1.1409e+01, 1.1328e+01, 1.1248e+01, 1.1168e+01, 1.1087e+01, 1.1006e+01, 1.0924e+01, 1.0842e+01, 1.0761e+01, 1.0681e+01, 1.0602e+01, 1.0523e+01, 1.0444e+01, 1.0364e+01, 1.0284e+01, 1.0203e+01, 1.0123e+01, 1.0044e+01, 9.9670e+00, 9.8901e+00, 9.8136e+00, 9.7370e+00, 9.6598e+00, 9.5818e+00, 9.5040e+00, 9.4272e+00, 9.3519e+00, 9.2777e+00, 9.2044e+00, 9.1316e+00, 9.0593e+00, 8.9866e+00, 8.9133e+00, 8.8398e+00, 8.7671e+00, 8.6959e+00, 8.6262e+00, 8.5577e+00, 8.4899e+00, 8.4230e+00, 8.3565e+00, 8.2900e+00, 8.2229e+00, 8.1556e+00, 8.0891e+00, 8.0244e+00, 7.9614e+00, 7.8996e+00, 7.8386e+00, 7.7784e+00, 7.7192e+00, 7.6603e+00, 7.6012e+00, 7.5415e+00, 7.4821e+00, 7.4239e+00, 7.3676e+00, 7.3130e+00, 7.2595e+00, 7.2066e+00, 7.1547e+00, 7.1037e+00, 7.0534e+00, 7.0028e+00, 6.9517e+00, 6.9004e+00, 6.8501e+00, 6.8017e+00, 6.7552e+00, 6.7099e+00, 6.6652e+00, 6.6212e+00, 6.5782e+00, 6.5362e+00, 6.4945e+00, 6.4525e+00, 6.4098e+00, 6.3670e+00, 6.3251e+00, 6.2851e+00, 6.2470e+00, 6.2101e+00, 6.1737e+00, 6.1377e+00, 6.1025e+00, 6.0683e+00, 6.0349e+00, 6.0014e+00, 5.9671e+00, 5.9320e+00, 5.8970e+00, 5.8634e+00, 5.8317e+00, 5.8016e+00, 5.7725e+00, 5.7436e+00, 5.7150e+00, 5.6870e+00, 5.6600e+00, 5.6338e+00, 5.6075e+00, 5.5805e+00}); + feg = Vctr_cpu({1.7325e+01, 1.6979e+01, 1.6038e+01, 1.4739e+01, 1.3331e+01, 1.1988e+01, 1.0794e+01, 9.7652e+00, 8.8861e+00, 8.1306e+00, 7.4739e+00, 6.8961e+00, 6.3821e+00, 5.9211e+00, 5.5051e+00, 5.1283e+00, 4.7859e+00, 4.4742e+00, 4.1901e+00, 3.9307e+00, 3.6936e+00, 3.4766e+00, 3.2777e+00, 3.0952e+00, 2.9273e+00, 2.7727e+00, 2.6301e+00, 2.4982e+00, 2.3760e+00, 2.2627e+00, 2.1573e+00, 2.0592e+00, 1.9677e+00, 1.8821e+00, 1.8021e+00, 1.7271e+00, 1.6567e+00, 1.5906e+00, 1.5283e+00, 1.4697e+00, 1.4144e+00, 1.3622e+00, 1.3129e+00, 1.2663e+00, 1.2222e+00, 1.1803e+00, 1.1407e+00, 1.1030e+00, 1.0673e+00, 1.0333e+00, 1.0009e+00, 9.7010e-01, 9.4070e-01, 9.1280e-01, 8.8600e-01, 8.6050e-01, 8.3610e-01, 8.1280e-01, 7.9040e-01, 7.6900e-01, 7.4850e-01, 7.2880e-01, 7.0980e-01, 6.9170e-01, 6.7420e-01, 6.5740e-01, 6.4120e-01, 6.2560e-01, 6.1050e-01, 5.9600e-01, 5.8200e-01, 5.6850e-01, 5.5540e-01, 5.4280e-01, 5.3050e-01, 5.1870e-01, 5.0720e-01, 4.9610e-01, 4.8540e-01, 4.7490e-01, 4.6480e-01, 4.5500e-01, 4.4550e-01, 4.3630e-01, 4.2730e-01, 4.1860e-01, 4.1010e-01, 4.0180e-01, 3.9380e-01, 3.8610e-01, 3.7850e-01, 3.7110e-01, 3.6400e-01, 3.5700e-01, 3.5020e-01, 3.4360e-01, 3.3720e-01, 3.3090e-01, 3.2480e-01, 3.1890e-01, 3.1310e-01, 3.0740e-01, 3.0190e-01, 2.9660e-01, 2.9140e-01, 2.8630e-01, 2.8130e-01, 2.7650e-01, 2.7170e-01, 2.6710e-01, 2.6270e-01, 2.5830e-01, 2.5400e-01, 2.4980e-01, 2.4580e-01, 2.4180e-01, 2.3790e-01, 2.3410e-01, 2.3050e-01, 2.2680e-01, 2.2330e-01, 2.1990e-01, 2.1650e-01, 2.1320e-01, 2.1000e-01, 2.0690e-01, 2.0380e-01, 2.0080e-01, 1.9790e-01, 1.9510e-01, 1.9230e-01, 1.8950e-01, 1.8680e-01, 1.8420e-01, 1.8170e-01, 1.7910e-01, 1.7670e-01, 1.7430e-01, 1.7190e-01, 1.6960e-01, 1.6740e-01, 1.6520e-01, 1.6300e-01, 1.6090e-01, 1.5880e-01, 1.5680e-01, 1.5480e-01, 1.5280e-01, 1.5090e-01, 1.4900e-01, 1.4720e-01, 1.4540e-01, 1.4360e-01, 1.4190e-01, 1.4010e-01, 1.3850e-01, 1.3680e-01, 1.3520e-01, 1.3360e-01, 1.3210e-01, 1.3050e-01, 1.2900e-01, 1.2760e-01, 1.2610e-01, 1.2470e-01, 1.2330e-01, 1.2190e-01, 1.2060e-01, 1.1920e-01, 1.1790e-01, 1.1660e-01, 1.1540e-01, 1.1410e-01, 1.1290e-01, 1.1170e-01, 1.1050e-01, 1.0930e-01, 1.0820e-01, 1.0710e-01, 1.0590e-01, 1.0480e-01, 1.0380e-01, 1.0270e-01, 1.0170e-01, 1.0060e-01, 9.9600e-02, 9.8600e-02, 9.7600e-02, 9.6700e-02, 9.5700e-02, 9.4800e-02, 9.3800e-02, 9.2900e-02, 9.2000e-02, 9.1100e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2100e-02, 8.1400e-02, 8.0700e-02, 7.9900e-02, 7.9200e-02, 7.8500e-02, 7.7800e-02, 7.7100e-02, 7.6400e-02, 7.5700e-02, 7.5000e-02, 7.4400e-02, 7.3700e-02, 7.3100e-02, 7.2500e-02, 7.1800e-02, 7.1200e-02, 7.0600e-02, 7.0000e-02, 6.9400e-02, 6.8800e-02, 6.8200e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.6000e-02, 6.5400e-02, 6.4900e-02, 6.4300e-02, 6.3800e-02, 6.3300e-02, 6.2800e-02, 6.2300e-02, 6.1800e-02, 6.1300e-02, 6.0800e-02}); + } + break; + case 98: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.8000e+01, 9.7574e+01, 9.6393e+01, 9.4684e+01, 9.2668e+01, 9.0488e+01, 8.8211e+01, 8.5870e+01, 8.3487e+01, 8.1090e+01, 7.8706e+01, 7.6361e+01, 7.4077e+01, 7.1872e+01, 6.9757e+01, 6.7738e+01, 6.5816e+01, 6.3990e+01, 6.2255e+01, 6.0609e+01, 5.9043e+01, 5.7554e+01, 5.6134e+01, 5.4780e+01, 5.3485e+01, 5.2245e+01, 5.1057e+01, 4.9916e+01, 4.8821e+01, 4.7767e+01, 4.6753e+01, 4.5776e+01, 4.4835e+01, 4.3926e+01, 4.3050e+01, 4.2203e+01, 4.1385e+01, 4.0593e+01, 3.9827e+01, 3.9084e+01, 3.8364e+01, 3.7664e+01, 3.6985e+01, 3.6324e+01, 3.5681e+01, 3.5054e+01, 3.4442e+01, 3.3845e+01, 3.3261e+01, 3.2690e+01, 3.2131e+01, 3.1583e+01, 3.1047e+01, 3.0520e+01, 3.0004e+01, 2.9497e+01, 2.9000e+01, 2.8512e+01, 2.8032e+01, 2.7561e+01, 2.7099e+01, 2.6646e+01, 2.6201e+01, 2.5764e+01, 2.5336e+01, 2.4916e+01, 2.4505e+01, 2.4103e+01, 2.3709e+01, 2.3323e+01, 2.2947e+01, 2.2579e+01, 2.2220e+01, 2.1869e+01, 2.1528e+01, 2.1195e+01, 2.0871e+01, 2.0555e+01, 2.0248e+01, 1.9950e+01, 1.9660e+01, 1.9380e+01, 1.9107e+01, 1.8842e+01, 1.8585e+01, 1.8337e+01, 1.8097e+01, 1.7864e+01, 1.7638e+01, 1.7420e+01, 1.7209e+01, 1.7006e+01, 1.6808e+01, 1.6617e+01, 1.6433e+01, 1.6255e+01, 1.6083e+01, 1.5916e+01, 1.5754e+01, 1.5598e+01, 1.5447e+01, 1.5301e+01, 1.5160e+01, 1.5022e+01, 1.4889e+01, 1.4759e+01, 1.4633e+01, 1.4512e+01, 1.4394e+01, 1.4278e+01, 1.4164e+01, 1.4054e+01, 1.3947e+01, 1.3842e+01, 1.3740e+01, 1.3640e+01, 1.3540e+01, 1.3443e+01, 1.3347e+01, 1.3254e+01, 1.3162e+01, 1.3072e+01, 1.2982e+01, 1.2893e+01, 1.2804e+01, 1.2717e+01, 1.2632e+01, 1.2547e+01, 1.2463e+01, 1.2380e+01, 1.2295e+01, 1.2211e+01, 1.2128e+01, 1.2046e+01, 1.1966e+01, 1.1885e+01, 1.1804e+01, 1.1723e+01, 1.1641e+01, 1.1559e+01, 1.1479e+01, 1.1399e+01, 1.1320e+01, 1.1241e+01, 1.1162e+01, 1.1082e+01, 1.1001e+01, 1.0920e+01, 1.0841e+01, 1.0762e+01, 1.0684e+01, 1.0607e+01, 1.0529e+01, 1.0450e+01, 1.0371e+01, 1.0292e+01, 1.0213e+01, 1.0136e+01, 1.0059e+01, 9.9834e+00, 9.9075e+00, 9.8317e+00, 9.7555e+00, 9.6788e+00, 9.6020e+00, 9.5261e+00, 9.4516e+00, 9.3782e+00, 9.3054e+00, 9.2330e+00, 9.1608e+00, 9.0887e+00, 9.0164e+00, 8.9437e+00, 8.8714e+00, 8.8006e+00, 8.7314e+00, 8.6632e+00, 8.5955e+00, 8.5282e+00, 8.4615e+00, 8.3952e+00, 8.3286e+00, 8.2618e+00, 8.1955e+00, 8.1306e+00, 8.0675e+00, 8.0058e+00, 7.9446e+00, 7.8839e+00, 7.8238e+00, 7.7645e+00, 7.7054e+00, 7.6460e+00, 7.5866e+00, 7.5279e+00, 7.4711e+00, 7.4161e+00, 7.3624e+00, 7.3091e+00, 7.2562e+00, 7.2040e+00, 7.1527e+00, 7.1018e+00, 7.0508e+00, 6.9994e+00, 6.9485e+00, 6.8992e+00, 6.8519e+00, 6.8061e+00, 6.7611e+00, 6.7163e+00, 6.6719e+00, 6.6284e+00, 6.5857e+00, 6.5434e+00, 6.5007e+00, 6.4576e+00, 6.4150e+00, 6.3738e+00, 6.3347e+00, 6.2972e+00, 6.2604e+00, 6.2238e+00, 6.1873e+00, 6.1516e+00, 6.1167e+00, 6.0824e+00, 6.0480e+00, 6.0129e+00, 5.9776e+00, 5.9430e+00, 5.9099e+00, 5.8789e+00, 5.8493e+00, 5.8202e+00, 5.7910e+00, 5.7619e+00, 5.7333e+00, 5.7056e+00, 5.6784e+00}); + feg = Vctr_cpu({1.6678e+01, 1.6328e+01, 1.5385e+01, 1.4109e+01, 1.2761e+01, 1.1507e+01, 1.0413e+01, 9.4801e+00, 8.6835e+00, 7.9944e+00, 7.3886e+00, 6.8484e+00, 6.3618e+00, 5.9203e+00, 5.5180e+00, 5.1505e+00, 4.8143e+00, 4.5065e+00, 4.2247e+00, 3.9664e+00, 3.7295e+00, 3.5121e+00, 3.3124e+00, 3.1287e+00, 2.9595e+00, 2.8034e+00, 2.6592e+00, 2.5258e+00, 2.4021e+00, 2.2873e+00, 2.1805e+00, 2.0810e+00, 1.9882e+00, 1.9015e+00, 1.8203e+00, 1.7442e+00, 1.6728e+00, 1.6058e+00, 1.5427e+00, 1.4833e+00, 1.4273e+00, 1.3745e+00, 1.3245e+00, 1.2773e+00, 1.2327e+00, 1.1903e+00, 1.1502e+00, 1.1122e+00, 1.0760e+00, 1.0416e+00, 1.0090e+00, 9.7780e-01, 9.4820e-01, 9.1990e-01, 8.9290e-01, 8.6720e-01, 8.4260e-01, 8.1900e-01, 7.9650e-01, 7.7490e-01, 7.5420e-01, 7.3430e-01, 7.1530e-01, 6.9690e-01, 6.7930e-01, 6.6240e-01, 6.4610e-01, 6.3040e-01, 6.1520e-01, 6.0060e-01, 5.8650e-01, 5.7290e-01, 5.5980e-01, 5.4710e-01, 5.3480e-01, 5.2290e-01, 5.1140e-01, 5.0020e-01, 4.8940e-01, 4.7890e-01, 4.6870e-01, 4.5890e-01, 4.4930e-01, 4.4000e-01, 4.3100e-01, 4.2220e-01, 4.1370e-01, 4.0540e-01, 3.9740e-01, 3.8960e-01, 3.8190e-01, 3.7450e-01, 3.6730e-01, 3.6030e-01, 3.5350e-01, 3.4690e-01, 3.4040e-01, 3.3410e-01, 3.2790e-01, 3.2200e-01, 3.1610e-01, 3.1040e-01, 3.0490e-01, 2.9950e-01, 2.9430e-01, 2.8910e-01, 2.8410e-01, 2.7920e-01, 2.7450e-01, 2.6980e-01, 2.6530e-01, 2.6090e-01, 2.5660e-01, 2.5240e-01, 2.4830e-01, 2.4430e-01, 2.4040e-01, 2.3650e-01, 2.3280e-01, 2.2920e-01, 2.2560e-01, 2.2210e-01, 2.1870e-01, 2.1540e-01, 2.1220e-01, 2.0900e-01, 2.0590e-01, 2.0290e-01, 1.9990e-01, 1.9700e-01, 1.9420e-01, 1.9140e-01, 1.8870e-01, 1.8610e-01, 1.8350e-01, 1.8090e-01, 1.7850e-01, 1.7600e-01, 1.7370e-01, 1.7130e-01, 1.6900e-01, 1.6680e-01, 1.6460e-01, 1.6250e-01, 1.6040e-01, 1.5830e-01, 1.5630e-01, 1.5430e-01, 1.5240e-01, 1.5050e-01, 1.4860e-01, 1.4680e-01, 1.4500e-01, 1.4320e-01, 1.4150e-01, 1.3980e-01, 1.3810e-01, 1.3650e-01, 1.3490e-01, 1.3330e-01, 1.3180e-01, 1.3030e-01, 1.2880e-01, 1.2730e-01, 1.2590e-01, 1.2440e-01, 1.2310e-01, 1.2170e-01, 1.2030e-01, 1.1900e-01, 1.1770e-01, 1.1640e-01, 1.1520e-01, 1.1390e-01, 1.1270e-01, 1.1150e-01, 1.1040e-01, 1.0920e-01, 1.0810e-01, 1.0690e-01, 1.0580e-01, 1.0470e-01, 1.0370e-01, 1.0260e-01, 1.0160e-01, 1.0060e-01, 9.9500e-02, 9.8600e-02, 9.7600e-02, 9.6600e-02, 9.5700e-02, 9.4700e-02, 9.3800e-02, 9.2900e-02, 9.2000e-02, 9.1100e-02, 9.0200e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 7.9900e-02, 7.9200e-02, 7.8500e-02, 7.7800e-02, 7.7100e-02, 7.6400e-02, 7.5800e-02, 7.5100e-02, 7.4400e-02, 7.3800e-02, 7.3200e-02, 7.2500e-02, 7.1900e-02, 7.1300e-02, 7.0700e-02, 7.0100e-02, 6.9500e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7200e-02, 6.6600e-02, 6.6100e-02, 6.5500e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3400e-02, 6.2900e-02, 6.2400e-02, 6.1900e-02, 6.1400e-02}); + } + break; + case 99: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.9000e+01, 9.8582e+01, 9.7420e+01, 9.5732e+01, 9.3733e+01, 9.1562e+01, 8.9287e+01, 8.6943e+01, 8.4552e+01, 8.2140e+01, 7.9734e+01, 7.7362e+01, 7.5047e+01, 7.2807e+01, 7.0653e+01, 6.8594e+01, 6.6631e+01, 6.4765e+01, 6.2993e+01, 6.1310e+01, 5.9711e+01, 5.8191e+01, 5.6744e+01, 5.5365e+01, 5.4048e+01, 5.2790e+01, 5.1586e+01, 5.0431e+01, 4.9324e+01, 4.8260e+01, 4.7238e+01, 4.6254e+01, 4.5307e+01, 4.4394e+01, 4.3514e+01, 4.2664e+01, 4.1843e+01, 4.1050e+01, 4.0282e+01, 3.9538e+01, 3.8817e+01, 3.8117e+01, 3.7437e+01, 3.6776e+01, 3.6133e+01, 3.5506e+01, 3.4895e+01, 3.4298e+01, 3.3715e+01, 3.3144e+01, 3.2586e+01, 3.2039e+01, 3.1502e+01, 3.0976e+01, 3.0460e+01, 2.9953e+01, 2.9456e+01, 2.8967e+01, 2.8487e+01, 2.8015e+01, 2.7552e+01, 2.7097e+01, 2.6650e+01, 2.6211e+01, 2.5780e+01, 2.5358e+01, 2.4943e+01, 2.4537e+01, 2.4139e+01, 2.3749e+01, 2.3368e+01, 2.2995e+01, 2.2631e+01, 2.2274e+01, 2.1927e+01, 2.1587e+01, 2.1257e+01, 2.0934e+01, 2.0621e+01, 2.0315e+01, 2.0018e+01, 1.9730e+01, 1.9449e+01, 1.9177e+01, 1.8913e+01, 1.8657e+01, 1.8408e+01, 1.8168e+01, 1.7934e+01, 1.7708e+01, 1.7490e+01, 1.7279e+01, 1.7074e+01, 1.6875e+01, 1.6684e+01, 1.6499e+01, 1.6320e+01, 1.6146e+01, 1.5978e+01, 1.5816e+01, 1.5659e+01, 1.5507e+01, 1.5360e+01, 1.5217e+01, 1.5079e+01, 1.4944e+01, 1.4814e+01, 1.4688e+01, 1.4566e+01, 1.4446e+01, 1.4329e+01, 1.4216e+01, 1.4105e+01, 1.3998e+01, 1.3894e+01, 1.3791e+01, 1.3690e+01, 1.3590e+01, 1.3493e+01, 1.3398e+01, 1.3306e+01, 1.3214e+01, 1.3123e+01, 1.3033e+01, 1.2944e+01, 1.2857e+01, 1.2771e+01, 1.2687e+01, 1.2603e+01, 1.2519e+01, 1.2435e+01, 1.2352e+01, 1.2270e+01, 1.2189e+01, 1.2108e+01, 1.2029e+01, 1.1949e+01, 1.1868e+01, 1.1787e+01, 1.1707e+01, 1.1627e+01, 1.1549e+01, 1.1471e+01, 1.1393e+01, 1.1315e+01, 1.1236e+01, 1.1157e+01, 1.1078e+01, 1.0999e+01, 1.0922e+01, 1.0845e+01, 1.0768e+01, 1.0692e+01, 1.0614e+01, 1.0536e+01, 1.0458e+01, 1.0380e+01, 1.0304e+01, 1.0228e+01, 1.0153e+01, 1.0078e+01, 1.0003e+01, 9.9274e+00, 9.8514e+00, 9.7752e+00, 9.6998e+00, 9.6258e+00, 9.5528e+00, 9.4803e+00, 9.4081e+00, 9.3362e+00, 9.2643e+00, 9.1920e+00, 9.1194e+00, 9.0472e+00, 8.9763e+00, 8.9069e+00, 8.8385e+00, 8.7706e+00, 8.7030e+00, 8.6360e+00, 8.5692e+00, 8.5022e+00, 8.4349e+00, 8.3680e+00, 8.3025e+00, 8.2388e+00, 8.1763e+00, 8.1143e+00, 8.0528e+00, 7.9919e+00, 7.9316e+00, 7.8716e+00, 7.8113e+00, 7.7509e+00, 7.6913e+00, 7.6334e+00, 7.5773e+00, 7.5223e+00, 7.4679e+00, 7.4138e+00, 7.3604e+00, 7.3078e+00, 7.2557e+00, 7.2033e+00, 7.1507e+00, 7.0986e+00, 7.0480e+00, 6.9993e+00, 6.9521e+00, 6.9056e+00, 6.8594e+00, 6.8137e+00, 6.7687e+00, 6.7246e+00, 6.6808e+00, 6.6367e+00, 6.5923e+00, 6.5483e+00, 6.5057e+00, 6.4652e+00, 6.4262e+00, 6.3880e+00, 6.3499e+00, 6.3120e+00, 6.2748e+00, 6.2385e+00, 6.2028e+00, 6.1670e+00, 6.1306e+00, 6.0940e+00, 6.0580e+00, 6.0236e+00, 5.9912e+00, 5.9603e+00, 5.9298e+00, 5.8993e+00, 5.8689e+00, 5.8390e+00, 5.8100e+00, 5.7816e+00}); + feg = Vctr_cpu({1.6357e+01, 1.6023e+01, 1.5125e+01, 1.3903e+01, 1.2606e+01, 1.1393e+01, 1.0331e+01, 9.4226e+00, 8.6449e+00, 7.9709e+00, 7.3775e+00, 6.8478e+00, 6.3697e+00, 5.9351e+00, 5.5383e+00, 5.1750e+00, 4.8419e+00, 4.5363e+00, 4.2557e+00, 3.9980e+00, 3.7613e+00, 3.5436e+00, 3.3433e+00, 3.1587e+00, 2.9885e+00, 2.8313e+00, 2.6859e+00, 2.5513e+00, 2.4264e+00, 2.3104e+00, 2.2024e+00, 2.1018e+00, 2.0079e+00, 1.9202e+00, 1.8380e+00, 1.7611e+00, 1.6889e+00, 1.6210e+00, 1.5572e+00, 1.4971e+00, 1.4404e+00, 1.3869e+00, 1.3364e+00, 1.2887e+00, 1.2435e+00, 1.2007e+00, 1.1601e+00, 1.1216e+00, 1.0851e+00, 1.0503e+00, 1.0173e+00, 9.8590e-01, 9.5590e-01, 9.2730e-01, 9.0010e-01, 8.7410e-01, 8.4920e-01, 8.2540e-01, 8.0270e-01, 7.8090e-01, 7.6000e-01, 7.4000e-01, 7.2080e-01, 7.0230e-01, 6.8450e-01, 6.6750e-01, 6.5100e-01, 6.3520e-01, 6.2000e-01, 6.0530e-01, 5.9110e-01, 5.7740e-01, 5.6410e-01, 5.5130e-01, 5.3900e-01, 5.2700e-01, 5.1540e-01, 5.0420e-01, 4.9330e-01, 4.8280e-01, 4.7260e-01, 4.6270e-01, 4.5300e-01, 4.4370e-01, 4.3460e-01, 4.2580e-01, 4.1730e-01, 4.0900e-01, 4.0090e-01, 3.9300e-01, 3.8540e-01, 3.7790e-01, 3.7070e-01, 3.6360e-01, 3.5670e-01, 3.5010e-01, 3.4350e-01, 3.3720e-01, 3.3100e-01, 3.2500e-01, 3.1910e-01, 3.1340e-01, 3.0790e-01, 3.0240e-01, 2.9710e-01, 2.9200e-01, 2.8690e-01, 2.8200e-01, 2.7720e-01, 2.7250e-01, 2.6800e-01, 2.6350e-01, 2.5920e-01, 2.5490e-01, 2.5080e-01, 2.4670e-01, 2.4280e-01, 2.3890e-01, 2.3520e-01, 2.3150e-01, 2.2790e-01, 2.2440e-01, 2.2090e-01, 2.1760e-01, 2.1430e-01, 2.1110e-01, 2.0800e-01, 2.0490e-01, 2.0190e-01, 1.9900e-01, 1.9610e-01, 1.9340e-01, 1.9060e-01, 1.8790e-01, 1.8530e-01, 1.8270e-01, 1.8020e-01, 1.7780e-01, 1.7540e-01, 1.7300e-01, 1.7070e-01, 1.6840e-01, 1.6620e-01, 1.6410e-01, 1.6190e-01, 1.5980e-01, 1.5780e-01, 1.5580e-01, 1.5380e-01, 1.5190e-01, 1.5000e-01, 1.4820e-01, 1.4640e-01, 1.4460e-01, 1.4280e-01, 1.4110e-01, 1.3940e-01, 1.3780e-01, 1.3620e-01, 1.3460e-01, 1.3300e-01, 1.3150e-01, 1.3000e-01, 1.2850e-01, 1.2700e-01, 1.2560e-01, 1.2420e-01, 1.2280e-01, 1.2150e-01, 1.2010e-01, 1.1880e-01, 1.1750e-01, 1.1620e-01, 1.1500e-01, 1.1380e-01, 1.1260e-01, 1.1140e-01, 1.1020e-01, 1.0910e-01, 1.0790e-01, 1.0680e-01, 1.0570e-01, 1.0460e-01, 1.0360e-01, 1.0250e-01, 1.0150e-01, 1.0050e-01, 9.9500e-02, 9.8500e-02, 9.7500e-02, 9.6500e-02, 9.5600e-02, 9.4700e-02, 9.3700e-02, 9.2800e-02, 9.2000e-02, 9.1100e-02, 9.0200e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8500e-02, 7.7800e-02, 7.7200e-02, 7.6500e-02, 7.5800e-02, 7.5100e-02, 7.4500e-02, 7.3900e-02, 7.3200e-02, 7.2600e-02, 7.2000e-02, 7.1300e-02, 7.0700e-02, 7.0100e-02, 6.9500e-02, 6.9000e-02, 6.8400e-02, 6.7800e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5600e-02, 6.5100e-02, 6.4500e-02, 6.4000e-02, 6.3500e-02, 6.3000e-02, 6.2500e-02, 6.2000e-02}); + } + break; + case 100: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0000e+02, 9.9590e+01, 9.8448e+01, 9.6782e+01, 9.4800e+01, 9.2640e+01, 9.0370e+01, 8.8025e+01, 8.5628e+01, 8.3204e+01, 8.0782e+01, 7.8386e+01, 7.6043e+01, 7.3769e+01, 7.1578e+01, 6.9480e+01, 6.7477e+01, 6.5571e+01, 6.3759e+01, 6.2038e+01, 6.0404e+01, 5.8851e+01, 5.7373e+01, 5.5967e+01, 5.4626e+01, 5.3346e+01, 5.2122e+01, 5.0951e+01, 4.9830e+01, 4.8754e+01, 4.7721e+01, 4.6729e+01, 4.5775e+01, 4.4856e+01, 4.3970e+01, 4.3117e+01, 4.2293e+01, 4.1496e+01, 4.0727e+01, 3.9981e+01, 3.9260e+01, 3.8559e+01, 3.7879e+01, 3.7219e+01, 3.6575e+01, 3.5949e+01, 3.5339e+01, 3.4742e+01, 3.4160e+01, 3.3590e+01, 3.3033e+01, 3.2486e+01, 3.1951e+01, 3.1426e+01, 3.0910e+01, 3.0404e+01, 2.9907e+01, 2.9418e+01, 2.8938e+01, 2.8466e+01, 2.8002e+01, 2.7546e+01, 2.7097e+01, 2.6657e+01, 2.6224e+01, 2.5799e+01, 2.5382e+01, 2.4973e+01, 2.4572e+01, 2.4178e+01, 2.3793e+01, 2.3415e+01, 2.3046e+01, 2.2684e+01, 2.2331e+01, 2.1986e+01, 2.1649e+01, 2.1321e+01, 2.1001e+01, 2.0688e+01, 2.0384e+01, 2.0089e+01, 1.9801e+01, 1.9521e+01, 1.9250e+01, 1.8986e+01, 1.8730e+01, 1.8482e+01, 1.8241e+01, 1.8007e+01, 1.7781e+01, 1.7562e+01, 1.7350e+01, 1.7144e+01, 1.6945e+01, 1.6753e+01, 1.6567e+01, 1.6387e+01, 1.6212e+01, 1.6043e+01, 1.5880e+01, 1.5722e+01, 1.5570e+01, 1.5421e+01, 1.5277e+01, 1.5137e+01, 1.5002e+01, 1.4872e+01, 1.4745e+01, 1.4621e+01, 1.4501e+01, 1.4383e+01, 1.4270e+01, 1.4159e+01, 1.4052e+01, 1.3946e+01, 1.3842e+01, 1.3740e+01, 1.3641e+01, 1.3545e+01, 1.3450e+01, 1.3358e+01, 1.3266e+01, 1.3175e+01, 1.3085e+01, 1.2997e+01, 1.2911e+01, 1.2826e+01, 1.2742e+01, 1.2658e+01, 1.2574e+01, 1.2491e+01, 1.2409e+01, 1.2328e+01, 1.2249e+01, 1.2169e+01, 1.2090e+01, 1.2011e+01, 1.1931e+01, 1.1851e+01, 1.1773e+01, 1.1695e+01, 1.1618e+01, 1.1541e+01, 1.1464e+01, 1.1386e+01, 1.1308e+01, 1.1230e+01, 1.1153e+01, 1.1077e+01, 1.1001e+01, 1.0926e+01, 1.0850e+01, 1.0774e+01, 1.0697e+01, 1.0620e+01, 1.0543e+01, 1.0468e+01, 1.0393e+01, 1.0319e+01, 1.0245e+01, 1.0170e+01, 1.0096e+01, 1.0020e+01, 9.9449e+00, 9.8701e+00, 9.7967e+00, 9.7242e+00, 9.6522e+00, 9.5804e+00, 9.5089e+00, 9.4373e+00, 9.3653e+00, 9.2929e+00, 9.2209e+00, 9.1501e+00, 9.0807e+00, 9.0123e+00, 8.9442e+00, 8.8766e+00, 8.8093e+00, 8.7422e+00, 8.6749e+00, 8.6073e+00, 8.5401e+00, 8.4742e+00, 8.4099e+00, 8.3468e+00, 8.2843e+00, 8.2221e+00, 8.1605e+00, 8.0995e+00, 8.0387e+00, 7.9776e+00, 7.9164e+00, 7.8559e+00, 7.7971e+00, 7.7400e+00, 7.6840e+00, 7.6285e+00, 7.5734e+00, 7.5189e+00, 7.4652e+00, 7.4119e+00, 7.3583e+00, 7.3046e+00, 7.2513e+00, 7.1995e+00, 7.1495e+00, 7.1010e+00, 7.0532e+00, 7.0057e+00, 6.9586e+00, 6.9124e+00, 6.8669e+00, 6.8217e+00, 6.7762e+00, 6.7305e+00, 6.6852e+00, 6.6413e+00, 6.5993e+00, 6.5589e+00, 6.5192e+00, 6.4797e+00, 6.4405e+00, 6.4019e+00, 6.3642e+00, 6.3271e+00, 6.2899e+00, 6.2522e+00, 6.2143e+00, 6.1770e+00, 6.1413e+00, 6.1076e+00, 6.0752e+00, 6.0433e+00, 6.0115e+00, 5.9798e+00, 5.9487e+00, 5.9184e+00, 5.8886e+00}); + feg = Vctr_cpu({1.6028e+01, 1.5712e+01, 1.4857e+01, 1.3691e+01, 1.2445e+01, 1.1274e+01, 1.0244e+01, 9.3586e+00, 8.5994e+00, 7.9403e+00, 7.3594e+00, 6.8402e+00, 6.3710e+00, 5.9438e+00, 5.5529e+00, 5.1944e+00, 4.8650e+00, 4.5620e+00, 4.2834e+00, 4.0269e+00, 3.7907e+00, 3.5732e+00, 3.3726e+00, 3.1875e+00, 3.0166e+00, 2.8585e+00, 2.7122e+00, 2.5765e+00, 2.4505e+00, 2.3334e+00, 2.2244e+00, 2.1227e+00, 2.0278e+00, 1.9391e+00, 1.8560e+00, 1.7782e+00, 1.7051e+00, 1.6365e+00, 1.5719e+00, 1.5111e+00, 1.4537e+00, 1.3996e+00, 1.3485e+00, 1.3002e+00, 1.2545e+00, 1.2112e+00, 1.1702e+00, 1.1313e+00, 1.0943e+00, 1.0592e+00, 1.0258e+00, 9.9400e-01, 9.6370e-01, 9.3480e-01, 9.0730e-01, 8.8100e-01, 8.5590e-01, 8.3190e-01, 8.0890e-01, 7.8690e-01, 7.6590e-01, 7.4560e-01, 7.2630e-01, 7.0760e-01, 6.8970e-01, 6.7250e-01, 6.5600e-01, 6.4000e-01, 6.2470e-01, 6.0990e-01, 5.9560e-01, 5.8180e-01, 5.6850e-01, 5.5560e-01, 5.4310e-01, 5.3110e-01, 5.1950e-01, 5.0820e-01, 4.9720e-01, 4.8660e-01, 4.7640e-01, 4.6640e-01, 4.5670e-01, 4.4740e-01, 4.3820e-01, 4.2940e-01, 4.2080e-01, 4.1240e-01, 4.0430e-01, 3.9640e-01, 3.8870e-01, 3.8120e-01, 3.7390e-01, 3.6680e-01, 3.5990e-01, 3.5320e-01, 3.4670e-01, 3.4030e-01, 3.3410e-01, 3.2800e-01, 3.2210e-01, 3.1640e-01, 3.1080e-01, 3.0530e-01, 3.0000e-01, 2.9480e-01, 2.8970e-01, 2.8470e-01, 2.7990e-01, 2.7520e-01, 2.7060e-01, 2.6610e-01, 2.6170e-01, 2.5740e-01, 2.5330e-01, 2.4920e-01, 2.4520e-01, 2.4130e-01, 2.3750e-01, 2.3380e-01, 2.3020e-01, 2.2660e-01, 2.2320e-01, 2.1980e-01, 2.1650e-01, 2.1320e-01, 2.1010e-01, 2.0700e-01, 2.0390e-01, 2.0100e-01, 1.9810e-01, 1.9530e-01, 1.9250e-01, 1.8980e-01, 1.8710e-01, 1.8450e-01, 1.8200e-01, 1.7950e-01, 1.7710e-01, 1.7470e-01, 1.7240e-01, 1.7010e-01, 1.6780e-01, 1.6570e-01, 1.6350e-01, 1.6140e-01, 1.5930e-01, 1.5730e-01, 1.5530e-01, 1.5340e-01, 1.5150e-01, 1.4960e-01, 1.4780e-01, 1.4600e-01, 1.4420e-01, 1.4250e-01, 1.4080e-01, 1.3910e-01, 1.3750e-01, 1.3580e-01, 1.3430e-01, 1.3270e-01, 1.3120e-01, 1.2970e-01, 1.2820e-01, 1.2680e-01, 1.2540e-01, 1.2400e-01, 1.2260e-01, 1.2120e-01, 1.1990e-01, 1.1860e-01, 1.1730e-01, 1.1610e-01, 1.1480e-01, 1.1360e-01, 1.1240e-01, 1.1120e-01, 1.1010e-01, 1.0890e-01, 1.0780e-01, 1.0670e-01, 1.0560e-01, 1.0450e-01, 1.0340e-01, 1.0240e-01, 1.0140e-01, 1.0040e-01, 9.9400e-02, 9.8400e-02, 9.7400e-02, 9.6500e-02, 9.5500e-02, 9.4600e-02, 9.3700e-02, 9.2800e-02, 9.1900e-02, 9.1000e-02, 9.0200e-02, 8.9300e-02, 8.8500e-02, 8.7700e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7200e-02, 7.6500e-02, 7.5800e-02, 7.5200e-02, 7.4500e-02, 7.3900e-02, 7.3300e-02, 7.2600e-02, 7.2000e-02, 7.1400e-02, 7.0800e-02, 7.0200e-02, 6.9600e-02, 6.9000e-02, 6.8500e-02, 6.7900e-02, 6.7300e-02, 6.6800e-02, 6.6200e-02, 6.5700e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3600e-02, 6.3100e-02, 6.2600e-02}); + } + break; + case 101: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0100e+02, 1.0060e+02, 9.9474e+01, 9.7830e+01, 9.5865e+01, 9.3715e+01, 9.1450e+01, 8.9105e+01, 8.6703e+01, 8.4269e+01, 8.1830e+01, 7.9413e+01, 7.7042e+01, 7.4737e+01, 7.2511e+01, 7.0375e+01, 6.8334e+01, 6.6388e+01, 6.4537e+01, 6.2779e+01, 6.1109e+01, 5.9523e+01, 5.8014e+01, 5.6580e+01, 5.5213e+01, 5.3910e+01, 5.2667e+01, 5.1478e+01, 5.0341e+01, 4.9252e+01, 4.8208e+01, 4.7205e+01, 4.6242e+01, 4.5317e+01, 4.4425e+01, 4.3567e+01, 4.2739e+01, 4.1940e+01, 4.1167e+01, 4.0420e+01, 3.9697e+01, 3.8996e+01, 3.8315e+01, 3.7654e+01, 3.7011e+01, 3.6385e+01, 3.5775e+01, 3.5180e+01, 3.4598e+01, 3.4029e+01, 3.3473e+01, 3.2928e+01, 3.2393e+01, 3.1869e+01, 3.1354e+01, 3.0849e+01, 3.0352e+01, 2.9864e+01, 2.9384e+01, 2.8911e+01, 2.8447e+01, 2.7991e+01, 2.7541e+01, 2.7100e+01, 2.6666e+01, 2.6239e+01, 2.5820e+01, 2.5408e+01, 2.5004e+01, 2.4607e+01, 2.4218e+01, 2.3837e+01, 2.3463e+01, 2.3097e+01, 2.2739e+01, 2.2389e+01, 2.2047e+01, 2.1712e+01, 2.1386e+01, 2.1067e+01, 2.0757e+01, 2.0455e+01, 2.0160e+01, 1.9873e+01, 1.9594e+01, 1.9323e+01, 1.9060e+01, 1.8804e+01, 1.8556e+01, 1.8315e+01, 1.8081e+01, 1.7855e+01, 1.7636e+01, 1.7422e+01, 1.7216e+01, 1.7017e+01, 1.6824e+01, 1.6637e+01, 1.6455e+01, 1.6280e+01, 1.6110e+01, 1.5946e+01, 1.5787e+01, 1.5633e+01, 1.5483e+01, 1.5338e+01, 1.5198e+01, 1.5063e+01, 1.4931e+01, 1.4803e+01, 1.4678e+01, 1.4556e+01, 1.4439e+01, 1.4325e+01, 1.4214e+01, 1.4105e+01, 1.3999e+01, 1.3894e+01, 1.3793e+01, 1.3694e+01, 1.3598e+01, 1.3503e+01, 1.3410e+01, 1.3317e+01, 1.3226e+01, 1.3137e+01, 1.3050e+01, 1.2965e+01, 1.2880e+01, 1.2796e+01, 1.2712e+01, 1.2629e+01, 1.2547e+01, 1.2466e+01, 1.2387e+01, 1.2308e+01, 1.2229e+01, 1.2150e+01, 1.2071e+01, 1.1992e+01, 1.1915e+01, 1.1838e+01, 1.1762e+01, 1.1686e+01, 1.1610e+01, 1.1533e+01, 1.1456e+01, 1.1379e+01, 1.1303e+01, 1.1228e+01, 1.1153e+01, 1.1079e+01, 1.1005e+01, 1.0929e+01, 1.0854e+01, 1.0777e+01, 1.0702e+01, 1.0628e+01, 1.0554e+01, 1.0481e+01, 1.0408e+01, 1.0334e+01, 1.0260e+01, 1.0186e+01, 1.0111e+01, 1.0037e+01, 9.9646e+00, 9.8927e+00, 9.8214e+00, 9.7502e+00, 9.6791e+00, 9.6079e+00, 9.5363e+00, 9.4643e+00, 9.3926e+00, 9.3221e+00, 9.2529e+00, 9.1846e+00, 9.1166e+00, 9.0490e+00, 8.9817e+00, 8.9145e+00, 8.8470e+00, 8.7793e+00, 8.7119e+00, 8.6457e+00, 8.5810e+00, 8.5175e+00, 8.4545e+00, 8.3919e+00, 8.3297e+00, 8.2681e+00, 8.2066e+00, 8.1449e+00, 8.0830e+00, 8.0218e+00, 7.9622e+00, 7.9042e+00, 7.8474e+00, 7.7909e+00, 7.7349e+00, 7.6795e+00, 7.6247e+00, 7.5704e+00, 7.5158e+00, 7.4610e+00, 7.4067e+00, 7.3537e+00, 7.3025e+00, 7.2528e+00, 7.2038e+00, 7.1551e+00, 7.1068e+00, 7.0593e+00, 7.0125e+00, 6.9660e+00, 6.9193e+00, 6.8723e+00, 6.8257e+00, 6.7805e+00, 6.7372e+00, 6.6954e+00, 6.6543e+00, 6.6135e+00, 6.5729e+00, 6.5330e+00, 6.4939e+00, 6.4554e+00, 6.4168e+00, 6.3778e+00, 6.3386e+00, 6.3001e+00, 6.2631e+00, 6.2280e+00, 6.1942e+00, 6.1610e+00, 6.1279e+00, 6.0948e+00, 6.0624e+00, 6.0308e+00, 5.9998e+00}); + feg = Vctr_cpu({1.5723e+01, 1.5421e+01, 1.4606e+01, 1.3489e+01, 1.2291e+01, 1.1159e+01, 1.0158e+01, 9.2959e+00, 8.5543e+00, 7.9097e+00, 7.3408e+00, 6.8317e+00, 6.3710e+00, 5.9510e+00, 5.5660e+00, 5.2122e+00, 4.8864e+00, 4.5862e+00, 4.3095e+00, 4.0543e+00, 3.8189e+00, 3.6016e+00, 3.4010e+00, 3.2155e+00, 3.0440e+00, 2.8852e+00, 2.7380e+00, 2.6014e+00, 2.4744e+00, 2.3563e+00, 2.2463e+00, 2.1436e+00, 2.0477e+00, 1.9581e+00, 1.8741e+00, 1.7954e+00, 1.7215e+00, 1.6520e+00, 1.5867e+00, 1.5252e+00, 1.4672e+00, 1.4125e+00, 1.3608e+00, 1.3119e+00, 1.2657e+00, 1.2219e+00, 1.1804e+00, 1.1410e+00, 1.1036e+00, 1.0681e+00, 1.0343e+00, 1.0022e+00, 9.7160e-01, 9.4240e-01, 9.1460e-01, 8.8810e-01, 8.6270e-01, 8.3840e-01, 8.1520e-01, 7.9300e-01, 7.7180e-01, 7.5140e-01, 7.3180e-01, 7.1300e-01, 6.9500e-01, 6.7760e-01, 6.6090e-01, 6.4480e-01, 6.2940e-01, 6.1440e-01, 6.0010e-01, 5.8620e-01, 5.7280e-01, 5.5980e-01, 5.4730e-01, 5.3520e-01, 5.2340e-01, 5.1210e-01, 5.0110e-01, 4.9050e-01, 4.8010e-01, 4.7010e-01, 4.6040e-01, 4.5100e-01, 4.4180e-01, 4.3290e-01, 4.2430e-01, 4.1590e-01, 4.0770e-01, 3.9970e-01, 3.9200e-01, 3.8450e-01, 3.7720e-01, 3.7000e-01, 3.6310e-01, 3.5630e-01, 3.4980e-01, 3.4340e-01, 3.3710e-01, 3.3100e-01, 3.2510e-01, 3.1930e-01, 3.1360e-01, 3.0810e-01, 3.0280e-01, 2.9750e-01, 2.9240e-01, 2.8740e-01, 2.8260e-01, 2.7780e-01, 2.7320e-01, 2.6870e-01, 2.6430e-01, 2.5990e-01, 2.5570e-01, 2.5160e-01, 2.4760e-01, 2.4370e-01, 2.3980e-01, 2.3610e-01, 2.3240e-01, 2.2880e-01, 2.2540e-01, 2.2190e-01, 2.1860e-01, 2.1530e-01, 2.1210e-01, 2.0900e-01, 2.0600e-01, 2.0300e-01, 2.0010e-01, 1.9720e-01, 1.9440e-01, 1.9170e-01, 1.8900e-01, 1.8640e-01, 1.8380e-01, 1.8130e-01, 1.7880e-01, 1.7640e-01, 1.7410e-01, 1.7170e-01, 1.6950e-01, 1.6730e-01, 1.6510e-01, 1.6300e-01, 1.6090e-01, 1.5880e-01, 1.5680e-01, 1.5480e-01, 1.5290e-01, 1.5100e-01, 1.4920e-01, 1.4730e-01, 1.4560e-01, 1.4380e-01, 1.4210e-01, 1.4040e-01, 1.3870e-01, 1.3710e-01, 1.3550e-01, 1.3390e-01, 1.3240e-01, 1.3090e-01, 1.2940e-01, 1.2790e-01, 1.2650e-01, 1.2510e-01, 1.2370e-01, 1.2230e-01, 1.2100e-01, 1.1970e-01, 1.1840e-01, 1.1710e-01, 1.1590e-01, 1.1460e-01, 1.1340e-01, 1.1220e-01, 1.1110e-01, 1.0990e-01, 1.0880e-01, 1.0760e-01, 1.0650e-01, 1.0550e-01, 1.0440e-01, 1.0330e-01, 1.0230e-01, 1.0130e-01, 1.0030e-01, 9.9300e-02, 9.8300e-02, 9.7300e-02, 9.6400e-02, 9.5500e-02, 9.4500e-02, 9.3600e-02, 9.2700e-02, 9.1900e-02, 9.1000e-02, 9.0100e-02, 8.9300e-02, 8.8500e-02, 8.7600e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7200e-02, 7.6500e-02, 7.5900e-02, 7.5200e-02, 7.4600e-02, 7.3900e-02, 7.3300e-02, 7.2700e-02, 7.2100e-02, 7.1500e-02, 7.0900e-02, 7.0300e-02, 6.9700e-02, 6.9100e-02, 6.8500e-02, 6.8000e-02, 6.7400e-02, 6.6800e-02, 6.6300e-02, 6.5800e-02, 6.5200e-02, 6.4700e-02, 6.4200e-02, 6.3700e-02, 6.3200e-02}); + } + break; + case 102: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0200e+02, 1.0161e+02, 1.0050e+02, 9.8878e+01, 9.6930e+01, 9.4791e+01, 9.2532e+01, 9.0188e+01, 8.7783e+01, 8.5340e+01, 8.2888e+01, 8.0451e+01, 7.8055e+01, 7.5720e+01, 7.3461e+01, 7.1289e+01, 6.9209e+01, 6.7225e+01, 6.5336e+01, 6.3540e+01, 6.1833e+01, 6.0212e+01, 5.8672e+01, 5.7208e+01, 5.5814e+01, 5.4486e+01, 5.3221e+01, 5.2013e+01, 5.0858e+01, 4.9754e+01, 4.8697e+01, 4.7683e+01, 4.6710e+01, 4.5776e+01, 4.4878e+01, 4.4013e+01, 4.3181e+01, 4.2377e+01, 4.1602e+01, 4.0852e+01, 4.0127e+01, 3.9425e+01, 3.8744e+01, 3.8082e+01, 3.7439e+01, 3.6814e+01, 3.6204e+01, 3.5609e+01, 3.5029e+01, 3.4461e+01, 3.3906e+01, 3.3361e+01, 3.2828e+01, 3.2305e+01, 3.1791e+01, 3.1287e+01, 3.0791e+01, 3.0304e+01, 2.9824e+01, 2.9352e+01, 2.8888e+01, 2.8432e+01, 2.7982e+01, 2.7540e+01, 2.7105e+01, 2.6677e+01, 2.6256e+01, 2.5842e+01, 2.5436e+01, 2.5036e+01, 2.4644e+01, 2.4259e+01, 2.3882e+01, 2.3512e+01, 2.3150e+01, 2.2795e+01, 2.2448e+01, 2.2108e+01, 2.1776e+01, 2.1452e+01, 2.1136e+01, 2.0827e+01, 2.0526e+01, 2.0233e+01, 1.9947e+01, 1.9669e+01, 1.9398e+01, 1.9136e+01, 1.8880e+01, 1.8632e+01, 1.8391e+01, 1.8157e+01, 1.7930e+01, 1.7710e+01, 1.7497e+01, 1.7291e+01, 1.7090e+01, 1.6896e+01, 1.6708e+01, 1.6526e+01, 1.6350e+01, 1.6179e+01, 1.6013e+01, 1.5853e+01, 1.5698e+01, 1.5548e+01, 1.5403e+01, 1.5261e+01, 1.5124e+01, 1.4991e+01, 1.4862e+01, 1.4737e+01, 1.4616e+01, 1.4497e+01, 1.4381e+01, 1.4269e+01, 1.4159e+01, 1.4054e+01, 1.3950e+01, 1.3848e+01, 1.3748e+01, 1.3650e+01, 1.3555e+01, 1.3462e+01, 1.3371e+01, 1.3281e+01, 1.3192e+01, 1.3104e+01, 1.3017e+01, 1.2932e+01, 1.2849e+01, 1.2767e+01, 1.2686e+01, 1.2605e+01, 1.2524e+01, 1.2444e+01, 1.2364e+01, 1.2286e+01, 1.2209e+01, 1.2133e+01, 1.2056e+01, 1.1979e+01, 1.1902e+01, 1.1826e+01, 1.1749e+01, 1.1675e+01, 1.1600e+01, 1.1527e+01, 1.1452e+01, 1.1377e+01, 1.1302e+01, 1.1227e+01, 1.1152e+01, 1.1078e+01, 1.1005e+01, 1.0933e+01, 1.0860e+01, 1.0786e+01, 1.0713e+01, 1.0639e+01, 1.0565e+01, 1.0491e+01, 1.0418e+01, 1.0347e+01, 1.0276e+01, 1.0204e+01, 1.0132e+01, 1.0060e+01, 9.9875e+00, 9.9152e+00, 9.8432e+00, 9.7723e+00, 9.7026e+00, 9.6336e+00, 9.5645e+00, 9.4952e+00, 9.4257e+00, 9.3563e+00, 9.2869e+00, 9.2176e+00, 9.1490e+00, 9.0817e+00, 9.0157e+00, 8.9505e+00, 8.8853e+00, 8.8199e+00, 8.7546e+00, 8.6895e+00, 8.6247e+00, 8.5601e+00, 8.4959e+00, 8.4329e+00, 8.3715e+00, 8.3113e+00, 8.2516e+00, 8.1918e+00, 8.1320e+00, 8.0725e+00, 8.0135e+00, 7.9548e+00, 7.8963e+00, 7.8384e+00, 7.7817e+00, 7.7268e+00, 7.6733e+00, 7.6203e+00, 7.5673e+00, 7.5142e+00, 7.4615e+00, 7.4094e+00, 7.3579e+00, 7.3065e+00, 7.2554e+00, 7.2052e+00, 7.1565e+00, 7.1096e+00, 7.0639e+00, 7.0185e+00, 6.9730e+00, 6.9275e+00, 6.8823e+00, 6.8380e+00, 6.7941e+00, 6.7505e+00, 6.7070e+00, 6.6641e+00, 6.6226e+00, 6.5828e+00, 6.5446e+00, 6.5070e+00, 6.4694e+00, 6.4315e+00, 6.3936e+00, 6.3563e+00, 6.3198e+00, 6.2837e+00, 6.2477e+00, 6.2117e+00, 6.1762e+00, 6.1421e+00, 6.1097e+00}); + feg = Vctr_cpu({1.5397e+01, 1.5114e+01, 1.4345e+01, 1.3284e+01, 1.2135e+01, 1.1043e+01, 1.0071e+01, 9.2310e+00, 8.5067e+00, 7.8761e+00, 7.3189e+00, 6.8198e+00, 6.3676e+00, 5.9548e+00, 5.5758e+00, 5.2268e+00, 4.9050e+00, 4.6079e+00, 4.3334e+00, 4.0798e+00, 3.8453e+00, 3.6286e+00, 3.4281e+00, 3.2425e+00, 3.0706e+00, 2.9112e+00, 2.7632e+00, 2.6258e+00, 2.4980e+00, 2.3790e+00, 2.2680e+00, 2.1644e+00, 2.0676e+00, 1.9771e+00, 1.8922e+00, 1.8127e+00, 1.7380e+00, 1.6678e+00, 1.6017e+00, 1.5395e+00, 1.4808e+00, 1.4255e+00, 1.3732e+00, 1.3238e+00, 1.2770e+00, 1.2327e+00, 1.1907e+00, 1.1509e+00, 1.1131e+00, 1.0772e+00, 1.0430e+00, 1.0105e+00, 9.7960e-01, 9.5010e-01, 9.2200e-01, 8.9520e-01, 8.6950e-01, 8.4500e-01, 8.2160e-01, 7.9920e-01, 7.7770e-01, 7.5710e-01, 7.3740e-01, 7.1840e-01, 7.0020e-01, 6.8270e-01, 6.6590e-01, 6.4970e-01, 6.3410e-01, 6.1900e-01, 6.0450e-01, 5.9060e-01, 5.7710e-01, 5.6400e-01, 5.5140e-01, 5.3920e-01, 5.2740e-01, 5.1600e-01, 5.0490e-01, 4.9420e-01, 4.8380e-01, 4.7380e-01, 4.6400e-01, 4.5450e-01, 4.4530e-01, 4.3640e-01, 4.2770e-01, 4.1920e-01, 4.1100e-01, 4.0300e-01, 3.9530e-01, 3.8770e-01, 3.8040e-01, 3.7320e-01, 3.6620e-01, 3.5940e-01, 3.5280e-01, 3.4640e-01, 3.4010e-01, 3.3400e-01, 3.2800e-01, 3.2220e-01, 3.1650e-01, 3.1100e-01, 3.0550e-01, 3.0030e-01, 2.9510e-01, 2.9010e-01, 2.8520e-01, 2.8040e-01, 2.7580e-01, 2.7120e-01, 2.6680e-01, 2.6240e-01, 2.5820e-01, 2.5400e-01, 2.5000e-01, 2.4600e-01, 2.4220e-01, 2.3840e-01, 2.3470e-01, 2.3110e-01, 2.2760e-01, 2.2410e-01, 2.2070e-01, 2.1740e-01, 2.1420e-01, 2.1110e-01, 2.0800e-01, 2.0500e-01, 2.0200e-01, 1.9910e-01, 1.9630e-01, 1.9350e-01, 1.9080e-01, 1.8820e-01, 1.8560e-01, 1.8300e-01, 1.8060e-01, 1.7810e-01, 1.7570e-01, 1.7340e-01, 1.7110e-01, 1.6890e-01, 1.6670e-01, 1.6450e-01, 1.6240e-01, 1.6030e-01, 1.5830e-01, 1.5630e-01, 1.5440e-01, 1.5250e-01, 1.5060e-01, 1.4870e-01, 1.4690e-01, 1.4520e-01, 1.4340e-01, 1.4170e-01, 1.4000e-01, 1.3840e-01, 1.3680e-01, 1.3520e-01, 1.3360e-01, 1.3210e-01, 1.3060e-01, 1.2910e-01, 1.2770e-01, 1.2620e-01, 1.2480e-01, 1.2350e-01, 1.2210e-01, 1.2080e-01, 1.1950e-01, 1.1820e-01, 1.1690e-01, 1.1570e-01, 1.1440e-01, 1.1320e-01, 1.1210e-01, 1.1090e-01, 1.0970e-01, 1.0860e-01, 1.0750e-01, 1.0640e-01, 1.0530e-01, 1.0430e-01, 1.0320e-01, 1.0220e-01, 1.0120e-01, 1.0020e-01, 9.9200e-02, 9.8200e-02, 9.7300e-02, 9.6300e-02, 9.5400e-02, 9.4500e-02, 9.3600e-02, 9.2700e-02, 9.1800e-02, 9.0900e-02, 9.0100e-02, 8.9300e-02, 8.8400e-02, 8.7600e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7200e-02, 7.6600e-02, 7.5900e-02, 7.5300e-02, 7.4600e-02, 7.4000e-02, 7.3300e-02, 7.2700e-02, 7.2100e-02, 7.1500e-02, 7.0900e-02, 7.0300e-02, 6.9700e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7500e-02, 6.6900e-02, 6.6400e-02, 6.5800e-02, 6.5300e-02, 6.4800e-02, 6.4300e-02, 6.3800e-02}); + } + break; + case 103: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0300e+02, 1.0259e+02, 1.0146e+02, 9.9776e+01, 9.7763e+01, 9.5565e+01, 9.3270e+01, 9.0917e+01, 8.8527e+01, 8.6115e+01, 8.3699e+01, 8.1297e+01, 7.8928e+01, 7.6609e+01, 7.4355e+01, 7.2178e+01, 7.0084e+01, 6.8078e+01, 6.6163e+01, 6.4338e+01, 6.2601e+01, 6.0949e+01, 5.9378e+01, 5.7884e+01, 5.6463e+01, 5.5110e+01, 5.3820e+01, 5.2591e+01, 5.1416e+01, 5.0294e+01, 4.9221e+01, 4.8193e+01, 4.7207e+01, 4.6261e+01, 4.5353e+01, 4.4479e+01, 4.3638e+01, 4.2828e+01, 4.2046e+01, 4.1291e+01, 4.0561e+01, 3.9855e+01, 3.9170e+01, 3.8506e+01, 3.7860e+01, 3.7233e+01, 3.6622e+01, 3.6026e+01, 3.5445e+01, 3.4877e+01, 3.4322e+01, 3.3779e+01, 3.3246e+01, 3.2724e+01, 3.2211e+01, 3.1708e+01, 3.1213e+01, 3.0727e+01, 3.0248e+01, 2.9778e+01, 2.9314e+01, 2.8858e+01, 2.8409e+01, 2.7968e+01, 2.7532e+01, 2.7104e+01, 2.6683e+01, 2.6268e+01, 2.5861e+01, 2.5460e+01, 2.5066e+01, 2.4679e+01, 2.4299e+01, 2.3927e+01, 2.3561e+01, 2.3203e+01, 2.2852e+01, 2.2508e+01, 2.2171e+01, 2.1842e+01, 2.1520e+01, 2.1206e+01, 2.0900e+01, 2.0601e+01, 2.0309e+01, 2.0024e+01, 1.9747e+01, 1.9478e+01, 1.9216e+01, 1.8960e+01, 1.8712e+01, 1.8472e+01, 1.8238e+01, 1.8011e+01, 1.7790e+01, 1.7576e+01, 1.7369e+01, 1.7169e+01, 1.6974e+01, 1.6785e+01, 1.6602e+01, 1.6424e+01, 1.6253e+01, 1.6087e+01, 1.5925e+01, 1.5769e+01, 1.5617e+01, 1.5470e+01, 1.5328e+01, 1.5190e+01, 1.5056e+01, 1.4926e+01, 1.4799e+01, 1.4676e+01, 1.4557e+01, 1.4442e+01, 1.4329e+01, 1.4219e+01, 1.4111e+01, 1.4006e+01, 1.3904e+01, 1.3804e+01, 1.3707e+01, 1.3612e+01, 1.3518e+01, 1.3425e+01, 1.3334e+01, 1.3246e+01, 1.3159e+01, 1.3074e+01, 1.2990e+01, 1.2906e+01, 1.2823e+01, 1.2741e+01, 1.2660e+01, 1.2581e+01, 1.2503e+01, 1.2426e+01, 1.2348e+01, 1.2271e+01, 1.2193e+01, 1.2116e+01, 1.2041e+01, 1.1966e+01, 1.1893e+01, 1.1819e+01, 1.1745e+01, 1.1670e+01, 1.1595e+01, 1.1520e+01, 1.1447e+01, 1.1374e+01, 1.1303e+01, 1.1231e+01, 1.1158e+01, 1.1085e+01, 1.1012e+01, 1.0938e+01, 1.0865e+01, 1.0793e+01, 1.0722e+01, 1.0651e+01, 1.0581e+01, 1.0509e+01, 1.0438e+01, 1.0365e+01, 1.0293e+01, 1.0221e+01, 1.0150e+01, 1.0080e+01, 1.0011e+01, 9.9421e+00, 9.8728e+00, 9.8032e+00, 9.7331e+00, 9.6627e+00, 9.5924e+00, 9.5231e+00, 9.4552e+00, 9.3885e+00, 9.3223e+00, 9.2560e+00, 9.1897e+00, 9.1234e+00, 9.0568e+00, 8.9899e+00, 8.9232e+00, 8.8573e+00, 8.7931e+00, 8.7303e+00, 8.6683e+00, 8.6065e+00, 8.5447e+00, 8.4831e+00, 8.4217e+00, 8.3601e+00, 8.2983e+00, 8.2370e+00, 8.1768e+00, 8.1183e+00, 8.0614e+00, 8.0053e+00, 7.9494e+00, 7.8936e+00, 7.8381e+00, 7.7830e+00, 7.7280e+00, 7.6728e+00, 7.6177e+00, 7.5635e+00, 7.5109e+00, 7.4602e+00, 7.4107e+00, 7.3618e+00, 7.3129e+00, 7.2642e+00, 7.2160e+00, 7.1683e+00, 7.1207e+00, 7.0729e+00, 7.0252e+00, 6.9782e+00, 6.9328e+00, 6.8894e+00, 6.8474e+00, 6.8060e+00, 6.7647e+00, 6.7234e+00, 6.6825e+00, 6.6422e+00, 6.6023e+00, 6.5624e+00, 6.5222e+00, 6.4821e+00, 6.4429e+00, 6.4053e+00, 6.3697e+00, 6.3355e+00, 6.3017e+00, 6.2679e+00, 6.2339e+00}); + feg = Vctr_cpu({1.5837e+01, 1.5556e+01, 1.4789e+01, 1.3716e+01, 1.2535e+01, 1.1388e+01, 1.0350e+01, 9.4431e+00, 8.6599e+00, 7.9825e+00, 7.3910e+00, 6.8685e+00, 6.4014e+00, 5.9799e+00, 5.5965e+00, 5.2458e+00, 4.9238e+00, 4.6273e+00, 4.3538e+00, 4.1012e+00, 3.8676e+00, 3.6515e+00, 3.4513e+00, 3.2659e+00, 3.0939e+00, 2.9342e+00, 2.7859e+00, 2.6480e+00, 2.5196e+00, 2.3999e+00, 2.2882e+00, 2.1840e+00, 2.0864e+00, 1.9952e+00, 1.9096e+00, 1.8294e+00, 1.7540e+00, 1.6831e+00, 1.6165e+00, 1.5536e+00, 1.4944e+00, 1.4385e+00, 1.3857e+00, 1.3357e+00, 1.2885e+00, 1.2437e+00, 1.2013e+00, 1.1610e+00, 1.1228e+00, 1.0865e+00, 1.0520e+00, 1.0191e+00, 9.8790e-01, 9.5800e-01, 9.2960e-01, 9.0250e-01, 8.7660e-01, 8.5180e-01, 8.2820e-01, 8.0550e-01, 7.8380e-01, 7.6300e-01, 7.4310e-01, 7.2390e-01, 7.0560e-01, 6.8790e-01, 6.7090e-01, 6.5460e-01, 6.3880e-01, 6.2370e-01, 6.0910e-01, 5.9500e-01, 5.8140e-01, 5.6820e-01, 5.5550e-01, 5.4320e-01, 5.3140e-01, 5.1990e-01, 5.0880e-01, 4.9800e-01, 4.8750e-01, 4.7740e-01, 4.6760e-01, 4.5800e-01, 4.4880e-01, 4.3980e-01, 4.3110e-01, 4.2260e-01, 4.1430e-01, 4.0630e-01, 3.9850e-01, 3.9090e-01, 3.8350e-01, 3.7630e-01, 3.6930e-01, 3.6250e-01, 3.5580e-01, 3.4930e-01, 3.4300e-01, 3.3690e-01, 3.3090e-01, 3.2500e-01, 3.1930e-01, 3.1370e-01, 3.0830e-01, 3.0300e-01, 2.9780e-01, 2.9280e-01, 2.8780e-01, 2.8300e-01, 2.7830e-01, 2.7370e-01, 2.6930e-01, 2.6490e-01, 2.6060e-01, 2.5640e-01, 2.5230e-01, 2.4840e-01, 2.4450e-01, 2.4070e-01, 2.3690e-01, 2.3330e-01, 2.2970e-01, 2.2630e-01, 2.2290e-01, 2.1950e-01, 2.1630e-01, 2.1310e-01, 2.1000e-01, 2.0690e-01, 2.0400e-01, 2.0100e-01, 1.9820e-01, 1.9540e-01, 1.9270e-01, 1.9000e-01, 1.8740e-01, 1.8480e-01, 1.8230e-01, 1.7980e-01, 1.7740e-01, 1.7510e-01, 1.7270e-01, 1.7050e-01, 1.6830e-01, 1.6610e-01, 1.6390e-01, 1.6180e-01, 1.5980e-01, 1.5780e-01, 1.5580e-01, 1.5390e-01, 1.5200e-01, 1.5010e-01, 1.4830e-01, 1.4650e-01, 1.4470e-01, 1.4300e-01, 1.4130e-01, 1.3970e-01, 1.3800e-01, 1.3640e-01, 1.3490e-01, 1.3330e-01, 1.3180e-01, 1.3030e-01, 1.2880e-01, 1.2740e-01, 1.2600e-01, 1.2460e-01, 1.2320e-01, 1.2190e-01, 1.2050e-01, 1.1920e-01, 1.1800e-01, 1.1670e-01, 1.1550e-01, 1.1430e-01, 1.1310e-01, 1.1190e-01, 1.1070e-01, 1.0960e-01, 1.0850e-01, 1.0730e-01, 1.0630e-01, 1.0520e-01, 1.0410e-01, 1.0310e-01, 1.0210e-01, 1.0110e-01, 1.0010e-01, 9.9100e-02, 9.8100e-02, 9.7200e-02, 9.6200e-02, 9.5300e-02, 9.4400e-02, 9.3500e-02, 9.2600e-02, 9.1700e-02, 9.0900e-02, 9.0000e-02, 8.9200e-02, 8.8400e-02, 8.7600e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7300e-02, 7.6600e-02, 7.5900e-02, 7.5300e-02, 7.4600e-02, 7.4000e-02, 7.3400e-02, 7.2800e-02, 7.2200e-02, 7.1500e-02, 7.1000e-02, 7.0400e-02, 6.9800e-02, 6.9200e-02, 6.8600e-02, 6.8100e-02, 6.7500e-02, 6.7000e-02, 6.6400e-02, 6.5900e-02, 6.5400e-02, 6.4800e-02, 6.4300e-02}); + } + break; + } + } + + void load_fxeg_lobato(const dt_int32 Z, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + + } + }; + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/fxeg_tabulated_data.hpp b/src - Copy (2)/fxeg_tabulated_data.hpp new file mode 100755 index 00000000..bb38d253 --- /dev/null +++ b/src - Copy (2)/fxeg_tabulated_data.hpp @@ -0,0 +1,24540 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef FXEG_TABULATED_DATA_H +#define FXEG_TABULATED_DATA_H + +#ifdef _MSC_VER +#pragma once +#endif// _MSC_VER + +#include "math.cuh" +#include "types.cuh" + +class fxeg_Tabulated_Data{ + public: + void ReadTabData(int Z_i, int Type_i, int dng_i, int &n_o, double *g_o, double *g2_o, double *fx_o, double *fe_o) + { + + switch(Type_i) + { + case 0: + { + fxegActaCrys(Z_i); + } + break; + case 1: + { + fxegRez(Z_i); + } + break; + case 2: + { + fxegKirkland(Z_i); + } + break; + case 3: + { + fxegLobato(Z_i); + } + break; + } + + if(dng_i == 0 ) + { + dng_i = 1; + } + + int i = 0, j = 0; + + while (j0) + { + feg[i] = (Z-fxg[i])/(mt::c_2Pi2a0*g2[i]); + } + } + + g.resize(ng); + g2.resize(ng); + fxg.resize(ng); + feg.resize(ng); + } + + void fxegLobato(int Z) + { + + } + + mt::Vector g; + mt::Vector g2; + mt::Vector feg; + mt::Vector fxg; +}; + +#endif \ No newline at end of file diff --git a/src - Copy (2)/gpu_detail.cuh b/src - Copy (2)/gpu_detail.cuh new file mode 100755 index 00000000..f7aa42ec --- /dev/null +++ b/src - Copy (2)/gpu_detail.cuh @@ -0,0 +1,720 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +// #if defined __CUDACC__ && !defined GPU_DETAIL_H +#ifndef GPU_DETAIL_H + #define GPU_DETAIL_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "fcns_elem.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_detail.cuh" + + #include + #include + #include + + namespace gpu_cg = cooperative_groups; + + namespace mt + { + /* shared memory arrays */ + namespace gpu_detail + { + // Utility class used to avoid linker errors with extern + // unsized shared memory arrays with templated type + template + struct SharedMemory + { + __device__ inline operator T *() + { + extern __shared__ int __smem[]; + return (T *)__smem; + } + + __device__ inline operator const T *() const + { + extern __shared__ int __smem[]; + return (T *)__smem; + } + }; + + // specialize for double to avoid unaligned memory + // access compile errors + template<> + struct SharedMemory + { + __device__ inline operator double *() + { + extern __shared__ double __smem_d[]; + return (double *)__smem_d; + } + + __device__ inline operator const double *() const + { + extern __shared__ double __smem_d[]; + return (double *)__smem_d; + } + }; + } + + /* macros reduce */ + namespace gpu_detail + { + #define GPU_BLK_REDUCE(sum, tid, sdata, bid, gdata_o) \ + { \ + /* each thread puts its local sum into shared memory */ \ + sdata[tid] = sum; \ + cta.sync(); \ + \ + /* do reduction in shared mem */ \ + if ((blocksize >= 512) && (tid < 256)) \ + { \ + sdata[tid] = sum = sum + sdata[tid + 256]; \ + } \ + cta.sync(); \ + \ + if ((blocksize >= 256) && (tid < 128)) \ + { \ + sdata[tid] = sum = sum + sdata[tid + 128]; \ + } \ + cta.sync(); \ + \ + if ((blocksize >= 128) && (tid < 64)) \ + { \ + sdata[tid] = sum = sum + sdata[tid + 64]; \ + } \ + cta.sync(); \ + \ + gpu_cg::thread_block_tile<32> tile32 = gpu_cg::tiled_partition<32>(cta); \ + \ + if (cta.thread_rank() < 32) \ + { \ + /* Fetch final intermediate sum from 2nd warp */ \ + if (blocksize >= 64) \ + { \ + sum += sdata[tid + 32]; \ + } \ + /* Reduce final warp using shuffle */ \ + for (int offset = tile32.size()/2; offset > 0; offset /= 2) \ + { \ + sum += tile32.shfl_down(sum, offset); \ + } \ + } \ + \ + if (cta.thread_rank() == 0) \ + { \ + gdata_o[bid] = sum; \ + } \ + } + } + + /* atomicAdd - double */ + namespace gpu_detail + { + #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ < 600 + __device__ __forceinline__ + double atomicAdd(double *address, double val) + { + unsigned long long int* address_as_ull = (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + + do + { + assumed = old; + old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val +__longlong_as_double(assumed))); + } while (assumed != old); + + return __longlong_as_double(old); + } + #endif + } + + /* remainder summation */ + namespace gpu_detail + { + template + __global__ void fcn_sum_rem(pVctr_gpu_32 mx_i) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + T *sdata = SharedMemory(); + + dt_uint32 tid = threadIdx.x; + dt_uint32 blocksize = blockDim.x; + + KS sum = mx_i[tid]; + + GPU_BLK_REDUCE(sum, tid, sdata, 0, mx_i); + } + + template + enable_if_vctr_gpu> + fcn_sum_rem_gpu(TVctr& mx_i) + { + using T = Value_type; + int threads = mx_i.size(); + int smemSize = (threads <= 32) ? 2 * threads * sizeof(T) : threads * sizeof(T); + fcn_sum_rem<<>>(mx_i.ptr_32()); + T sum = 0; + cudaMemcpy(&sum, mx_i.data(), sizeof(T), cudaMemcpyDeviceToHost); + + return sum; + } + + template + enable_if_vctr_gpu> + fcn_sum_rem_cpu(TVctr& mx_i) + { + using T = Value_type; + + Vctr_cpu mx(mx_i); + KS sum(0); + + for (dt_int32 ik=0; ik + __global__ void fcn_fftsft_1d(iGrid_1d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_1DC(igrid.nx_h, cgpu_detail::fcn_fftsft_1d(ix, igrid, mx_io.m_data)); + } + + /* shift matrix respect to ny_h */ + template + __global__ void fcn_fftsft_bc_2d(iGrid_2d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny_h, cgpu_detail::fcn_fftsft_bc_2d(ix, iy, igrid, mx_io.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + __global__ void fcn_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_fftsft_2d(ix, iy, igrid, mx_io.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + __global__ void fcn_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_fftsft_2d(ix, iy, igrid, mx_i.m_data, mx_o.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + __global__ void fcn_fftsft_3d(iGrid_3d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_3DC(igrid.nx_h, igrid.ny_h, igrid.nz_h, cgpu_detail::fcn_fftsft_3d(ix, iy, iz, igrid, mx_io.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + __global__ void fcn_fftsft_3d(iGrid_3d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + FOR_LOOP_3DC(igrid.nx_h, igrid.ny_h, igrid.nz_h, cgpu_detail::fcn_fftsft_3d(ix, iy, iz, igrid, mx_i.m_data, mx_o.m_data)); + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + __global__ void fcn_add_sc_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_fftsft_2d(ix, iy, igrid, mx_i.m_data, w, mx_o.m_data)); + } + + /* add, scale, square and shift */ + template + __global__ void fcn_add_sc_norm_2_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, U w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_fftsft_2d(ix, iy, igrid, mx_i.m_data, w, mx_o.m_data)); + } + + /***************************************************************************************/ + /* assign and crop */ + template + __global__ void fcn_assign_crop_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_assign_crop_2d(ix, iy, igrid, mx_i.m_data, iregion, mx_o.m_data)); + } + + /* assign, crop and shift */ + template + __global__ void fcn_assign_crop_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_assign_crop_fftsft_2d(ix, iy, igrid, mx_i.m_data, iregion, mx_o.m_data)); + } + + /* add, scale, crop and shift */ + template + __global__ void fcn_add_sc_crop_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_crop_fftsft_2d(ix, iy, igrid, mx_i.m_data, iregion, w, mx_o.m_data)); + } + + /* add, scale, square, crop and shift */ + template + __global__ void fcn_add_sc_norm_2_crop_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, U w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_crop_fftsft_2d(ix, iy, igrid, mx_i.m_data, iregion, w, mx_o.m_data)); + } + } + + /* transpose - element wise matrix op vector */ + namespace gpu_detail + { + /* transpose */ + template + __global__ void fcn_trs_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d(ix, iy, igrid, mx_i.m_data, mx_o.m_data)); + } + + /***************************************************************************************/ + /* element wise addition: matrix + vector row */ + template + __global__ void fcn_ew_add_mx_vctr_row(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_row(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /* element wise addition: matrix + vector col */ + template + __global__ void fcn_ew_add_mx_vctr_col(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_col(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /***************************************************************************************/ + /* element wise subtraction: matrix - vector row */ + template + __global__ void fcn_ew_sub_mx_vctr_row(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_row(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /* element wise subtraction: matrix - vector col */ + template + __global__ void fcn_ew_sub_mx_vctr_col(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_col(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /***************************************************************************************/ + /* element wise multiplication matrix X vector row */ + template + __global__ void fcn_ew_mult_mx_vctr_row(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_row(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /* element wise multiplication matrix X vector col */ + template + __global__ void fcn_ew_mult_mx_vctr_col(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_col(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + } + + /* aperture functions */ + namespace gpu_detail + { + template + __global__ void fcn_fermi_aperture(Grid_2d grid, T g2_cut, T alpha, T w, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fermi_aperture(ix, iy, grid, g2_cut, alpha, w, mx_io.m_data)); + } + + template + __global__ void fcn_hard_aperture(Grid_2d grid, T g2_cut, T w, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_hard_aperture(ix, iy, grid, g2_cut, w, mx_io.m_data)); + } + } + + /* phase shifts real space*/ + namespace gpu_detail + { + // phase factor 1d + template + __global__ void fcn_rs_exp_factor_1d(Grid_1d grid, pVctr_gpu_32 psi_i, T gx, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_rs_exp_factor_1d(ix, grid, psi_i.m_data, gx, w, psi_o.m_data)); + } + + // phase factor 2d by col + template + __global__ void fcn_rs_exp_factor_2d_bc(Grid_2d grid, pVctr_gpu_32 psi_i, T alpha, pVctr_gpu_32 gy, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d_bc(ix, iy, grid, psi_i.m_data, alpha, gy, w, psi_o.m_data)); + } + + // phase factor 2d + template + __global__ void fcn_rs_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d(ix, iy, grid, psi_i.m_data, g, w, psi_o.m_data)); + } + + // phase factor 2d multipositions + template + __global__ void fcn_rs_mul_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, pVctr_gpu_32> g, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_mul_exp_factor_2d(ix, iy, grid, psi_i.m_data, g.m_data, g.m_size, w, psi_o.m_data)); + } + } + + /* phase shifts fourier space*/ + namespace gpu_detail + { + // phase factor 1d + template + __global__ void fcn_fs_exp_factor_1d(Grid_1d grid, pVctr_gpu_32 psi_i, T rx, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_fs_exp_factor_1d(ix, grid, psi_i.m_data, rx, w, psi_o.m_data)); + } + + // phase factor 2d by col + template + __global__ void fcn_fs_exp_factor_2d_bc(Grid_2d grid, pVctr_gpu_32 psi_i, T alpha, pVctr_gpu_32 ry, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d_bc(ix, iy, grid, psi_i.m_data, alpha, ry, w, psi_o.m_data)); + } + + // phase factor 2d + template + __global__ void fcn_fs_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d r, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d(ix, iy, grid, psi_i.m_data, r, w, psi_o.m_data)); + } + + // phase factor 2d multi-positions + template + __global__ void fcn_fs_mul_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, pVctr_gpu_32> r, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_mul_exp_factor_2d(ix, iy, grid, psi_i.m_data, r.m_data, r.m_size, w, psi_o.m_data)); + } + } + + /* gradient */ + namespace gpu_detail + { + template + __global__ void fcn_grad_x(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 dmx_x) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_grad_x(ix, iy, igrid, mx_i.m_data, dmx_x.m_data)); + } + + template + __global__ void fcn_grad_y(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 dmx_y) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_grad_y(ix, iy, igrid, mx_i.m_data, dmx_y.m_data)); + } + + template + __global__ void fcn_grad(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 dmx_x, pVctr_gpu_32 dmx_y) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_grad(ix, iy, igrid, mx_i.m_data, dmx_x.m_data, dmx_y.m_data)); + } + } + + /* function multiplication fourier space */ + namespace gpu_detail + { + #define FCN_MULT_FS_FCN_GPU_DET(FN, FCN, POW, DIM) \ + template \ + __global__ void fcn_mult_fs_##FN##_##DIM##d(Grid_##DIM##d grid, FCN fcn, T w, pVctr_gpu_32 mx_io) \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_mult_fs_fcn_g##POW##_##DIM##d(IDX_ND(DIM), grid, fcn, w, mx_io.m_data)) \ + } + + /* gaussian */ + FCN_MULT_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 1); // fcn_mult_fs_gauss_1d + FCN_MULT_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 2); // fcn_mult_fs_gauss_2d + FCN_MULT_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 3); // fcn_mult_fs_gauss_3d + + /* exponential */ + FCN_MULT_FS_FCN_GPU_DET(exp, Fcn_Exp, , 1); // fcn_mult_fs_exp_1d + FCN_MULT_FS_FCN_GPU_DET(exp, Fcn_Exp, , 2); // fcn_mult_fs_exp_2d + FCN_MULT_FS_FCN_GPU_DET(exp, Fcn_Exp, , 3); // fcn_mult_fs_exp_3d + + /* fermi */ + FCN_MULT_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 1); // fcn_mult_fs_fermi_1d + FCN_MULT_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 2); // fcn_mult_fs_fermi_2d + FCN_MULT_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 3); // fcn_mult_fs_fermi_3d + + /* butterworth */ + FCN_MULT_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 1); // fcn_mult_fs_butwth_1d + FCN_MULT_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 2); // fcn_mult_fs_butwth_2d + FCN_MULT_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 3); // fcn_mult_fs_butwth_3d + + /* hann */ + FCN_MULT_FS_FCN_GPU_DET(hann, Fcn_Hann, , 1); // fcn_mult_fs_hann_1d + FCN_MULT_FS_FCN_GPU_DET(hann, Fcn_Hann, , 2); // fcn_mult_fs_hann_2d + FCN_MULT_FS_FCN_GPU_DET(hann, Fcn_Hann, , 3); // fcn_mult_fs_hann_3d + } + + /* deconvolution */ + namespace gpu_detail + { + #define FCN_DCV_FS_FCN_GPU_DET(FN, FCN, POW, DIM) \ + template \ + __global__ void fcn_dcv_fs_##FN##_##DIM##d(Grid_##DIM##d grid, FCN fcn, T psnr, T w, pVctr_gpu_32 mx_io) \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_dcv_fs_fcn_g##POW##_##DIM##d(IDX_ND(DIM), grid, fcn, psnr, w, mx_io.m_data)) \ + } + + /* gaussian */ + FCN_DCV_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 1); // fcn_dcv_fs_gauss_1d + FCN_DCV_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 2); // fcn_dcv_fs_gauss_2d + FCN_DCV_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 3); // fcn_dcv_fs_gauss_3d + + /* exponential */ + FCN_DCV_FS_FCN_GPU_DET(exp, Fcn_Exp, , 1); // fcn_dcv_fs_exp_1d + FCN_DCV_FS_FCN_GPU_DET(exp, Fcn_Exp, , 2); // fcn_dcv_fs_exp_2d + FCN_DCV_FS_FCN_GPU_DET(exp, Fcn_Exp, , 3); // fcn_dcv_fs_exp_3d + + /* fermi */ + FCN_DCV_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 1); // fcn_dcv_fs_fermi_1d + FCN_DCV_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 2); // fcn_dcv_fs_fermi_2d + FCN_DCV_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 3); // fcn_dcv_fs_fermi_3d + + /* butterworth */ + FCN_DCV_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 1); // fcn_dcv_fs_butwth_1d + FCN_DCV_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 2); // fcn_dcv_fs_butwth_2d + FCN_DCV_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 3); // fcn_dcv_fs_butwth_3d + + /* hann */ + FCN_DCV_FS_FCN_GPU_DET(hann, Fcn_Hann, , 1); // fcn_dcv_fs_hann_1d + FCN_DCV_FS_FCN_GPU_DET(hann, Fcn_Hann, , 2); // fcn_dcv_fs_hann_2d + FCN_DCV_FS_FCN_GPU_DET(hann, Fcn_Hann, , 3); // fcn_dcv_fs_hann_3d + } + + /* window functions */ + namespace gpu_detail + { + #define FCN_WD_FCN_GPU_DET(FN, FCN, DIM) \ + template \ + __global__ void fcn_wd_##FN##_##DIM##d(Grid_##DIM##d grid, FCN fcn, pVctr_gpu_32 mx_o) \ + { \ + if (sft) \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_sft_##DIM##d(IDX_ND(DIM), grid, fcn, mx_o.m_data)) \ + } \ + else \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_##DIM##d(IDX_ND(DIM), grid, fcn, mx_o.m_data)) \ + } \ + } + + FCN_WD_FCN_GPU_DET(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + FCN_WD_FCN_GPU_DET(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + FCN_WD_FCN_GPU_DET(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + FCN_WD_FCN_GPU_DET(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + FCN_WD_FCN_GPU_DET(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + FCN_WD_FCN_GPU_DET(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + FCN_WD_FCN_GPU_DET(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + FCN_WD_FCN_GPU_DET(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + FCN_WD_FCN_GPU_DET(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + FCN_WD_FCN_GPU_DET(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + FCN_WD_FCN_GPU_DET(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + FCN_WD_FCN_GPU_DET(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + FCN_WD_FCN_GPU_DET(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + FCN_WD_FCN_GPU_DET(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + FCN_WD_FCN_GPU_DET(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d + } + + /* phase correlation */ + namespace gpu_detail + { + /****************** pcf data processing real space *******************/ + template + __global__ void fcn_rs_pcf_1d_dp(Grid_1d grid, pVctr_gpu_32 mx_i, + Wd_Butwth_1d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_rs_pcf_1d_dp(ix, grid, mx_i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_rs_pcf_2d_dp(Grid_2d grid, pVctr_gpu_32 mx_i, + Wd_Butwth_2d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_pcf_2d_dp(ix, iy, grid, mx_i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_rs_pcf_3d_dp(Grid_3d grid, pVctr_gpu_32 mx_i, + Wd_Butwth_3d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_3DC(grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_rs_pcf_2d_dp(ix, iy, iz, grid, mx_i.m_data, wd, w, mx_o.m_data)); + } + + /***************** pcf data processing fourier space *****************/ + template + __global__ void fcn_fs_pcf_1d_dp(Grid_1d grid, pVctr_gpu_32 mx_1i, pVctr_gpu_32 mx_2i, + Wd_Gauss_1d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_fs_pcf_1d_dp(ix, grid, mx_1i.m_data, mx_2i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_fs_pcf_2d_dp(Grid_2d grid, pVctr_gpu_32 mx_1i, pVctr_gpu_32 mx_2i, + Wd_Gauss_2d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_pcf_2d_dp(ix, iy, grid, mx_1i.m_data, mx_2i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_fs_pcf_3d_dp(Grid_3d grid, pVctr_gpu_32 mx_1i, pVctr_gpu_32 mx_2i, + Wd_Gauss_3d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_3DC(grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_fs_pcf_2d_dp(ix, iy, iz, grid, mx_1i.m_data, mx_2i.m_data, wd, w, mx_o.m_data)); + } + } + + /* optical flow */ + namespace gpu_detail + { + template + __global__ void fcn_opt_flow(iGrid_2d igrid, pVctr_gpu_32 mx_s, pVctr_gpu_32 mx_m, + T alpha, pVctr_gpu_32 dphi_x, pVctr_gpu_32 dphi_y) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_opt_flow(ix, iy, igrid, mx_s.m_data, mx_m.m_data, alpha, dphi_x.m_data, dphi_y.m_data)); + } + } + + /* bilinear interpolation */ + namespace gpu_detail + { + template + __global__ void fcn_intrpl_bl_rg_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, + pVctr_gpu_32 vrx, pVctr_gpu_32 vry, T bg, pVctr_gpu_32 mx_o) + { + FOR_LOOP_1DC(vrx.m_size, cgpu_detail::fcn_intrpl_bl_rg_2d(ix, grid_i, mx_i.m_data, vrx.m_data, vry.m_data, bg, mx_o.m_data)); + } + } + + // namespace gpu_detail + // { + // // scan noise xy + // template + // __global__ void sd_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, pVctr_gpu_32 dx_i, pVctr_gpu_32 dy_i, T bg, pVctr_gpu_32 mx_o) + // { + // (dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_i.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_i.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::sd_2d(ix, iy, grid_i, mx_i, dx_i, dy_i, bg, mx_o); + // } + // } + // } + + // template + // __global__ void sd_nr_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, pVctr_gpu_32 dx_i, pVctr_gpu_32 dy_i, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_i.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_i.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::sd_nr_2d(ix, iy, grid_i, mx_i, dx_i, dy_i, mx_o); + // } + // } + // } + + // // scaling xy + // template + // __global__ void sc_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, T fxy, Grid_2d grid_o, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_o.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_o.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::sc_2d(ix, iy, grid_i, mx_i, fxy, grid_o, mx_o); + // } + // } + // } + + // // rotate, scale and shift xy + // template + // __global__ void rot_sca_sft_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, T theta, R_2d p0, + // T fx, T fy, R_2d ps, T bg, Grid_2d grid_o, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_o.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_o.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::rot_sca_sft_2d(ix, iy, grid_i, mx_i, theta, p0, fx, fy, ps, bg, grid_o, mx_o); + // } + // } + // } + + // // 2d general affine transformation + // template + // __global__ void at_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, Mx_2x2 A, R_2d txy, T bg, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_i.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_i.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::at_2d(ix, iy, grid_i, mx_i, A, txy, bg, mx_o); + // } + // } + // } + + // // x-shear and y-scaling + // template + // __global__ void shx_scy(Grid_2d grid_i, pVctr_gpu_32 mx_i, T fx, T fy, T bg, Grid_2d grid_o, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_o.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_o.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::shx_scy(ix, iy, grid_i, mx_i, fx, fy, bg, grid_o, mx_o); + // } + // } + // } + + // } + } + +#endif diff --git a/src - Copy (2)/gpu_detail_mt.cuh b/src - Copy (2)/gpu_detail_mt.cuh new file mode 100755 index 00000000..b797415e --- /dev/null +++ b/src - Copy (2)/gpu_detail_mt.cuh @@ -0,0 +1,332 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +// #if defined __CUDACC__ && !defined GPU_DETAIL_MT_H +#ifndef GPU_DETAIL_MT_H + #define GPU_DETAIL_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "type_traits_mt.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "quad_data.cuh" + #include "cgpu_detail_mt.cuh" + #include "gpu_detail.cuh" + + #include + #include + #include + #include + + namespace gpu_cg = cooperative_groups; + + namespace mt + { + /* atomic functions */ + namespace gpu_detail_mt + { + /************************** pFcn_clnl_3_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, pLNL_Coef_gpu coef, pVctr_gpu_32 fx, pFcn_clnl_3_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, pLNL_Coef_gpu coef, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_3_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /************************** pFcn_clnl_4_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T c, pLNL_Coef_gpu coef, pVctr_gpu_32 fx, pFcn_clnl_4_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], c, coef.cl, coef.cnl); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T c, pLNL_Coef_gpu coef, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_4_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], c, coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /************************** pFcn_clnl_6_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx, pFcn_clnl_6_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T z_0, T z_e, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_6_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + + /************************** pFcn_clnl_8_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T z_0, T z_e, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx, pFcn_clnl_8_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T z_0, T z_e, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_8_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + } // gpu_detail + + /* detector integration */ + namespace gpu_detail_mt + { + /* integration over a detector ring */ + template + __global__ void fcn_int_det_ring(Grid_2d grid, T g2_min, T g2_max, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_ring(ix, iy, grid, g2_min, g2_max, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + /* norm_2 integration over a detector ring */ + template + __global__ void fcn_int_det_ring_norm_2(Grid_2d grid, T g2_min, T g2_max, pVctr_gpu_32 mx_i, pVctr_gpu_32> mx_o) + { + using U_r = Value_type_r; + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U_r *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U_r(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_ring_norm_2(ix, iy, grid, g2_min, g2_max, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + /* integration over a detector with sensitivity */ + template + __global__ void fcn_int_det_sen(Grid_2d grid, pVctr_gpu_32 sen_i, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_sen(ix, iy, grid, sen_i.m_data, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + /* norm_2 integration over a detector with sensitivity */ + template + __global__ void fcn_int_det_sen_norm_2(Grid_2d grid, pVctr_gpu_32> sen_i, pVctr_gpu_32 mx_i, pVctr_gpu_32> mx_o) + { + using U_r = Value_type_r; + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U_r *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U_r(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_sen_norm_2(ix, iy, grid, sen_i.m_data, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + } + + /* wave propagation */ + namespace gpu_detail_mt + { + /* propagate */ + template + __global__ void fcn_fs_propagate(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g_0, T w_g2, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate(ix, iy, grid, psi_i.m_data, g_0, w_g2, w, psi_o.m_data)); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + __global__ void fcn_fs_propagate_bw_f(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g_0, T w_g2, T g2_cut, T alpha, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_f(ix, iy, grid, psi_i.m_data, g_0, w_g2, g2_cut, alpha, w, psi_o.m_data)); + } + + /* propagate and bandwith limit using a hard aperture */ + template + __global__ void fcn_fs_propagate_bw_h(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g_0, T w_g2, T g2_cut, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_h(ix, iy, grid, psi_i.m_data, g_0, w_g2, g2_cut, w, psi_o.m_data)); + } + } + + /* probe - ctf - pctf */ + namespace gpu_detail_mt + { + /* Convergent incident wave in Fourier space */ + template + __global__ void fcn_fs_probe(Grid_2d grid, Lens lens, R_2d r, R_2d gu, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_probe(ix, iy, grid, lens, r, gu, psi_o.m_data)); + } + + /* apply coherent transfer function */ + template + __global__ void fcn_fs_apply_ctf(Grid_2d grid, pVctr_gpu_32 psi_i, Lens lens, R_2d gu, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_apply_ctf(ix, iy, grid, psi_i.m_data, lens, gu, psi_o.m_data)); + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + __global__ void fcn_fs_apply_pctf(iGrid_2d grid, pVctr_gpu_32 psi_i, Lens lens, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_apply_pctf(ix, iy, grid, psi_i.m_data, lens, psi_o.m_data)); + } + } + + /* transmission function */ + namespace gpu_detail_mt + { + template + __global__ void fcn_trans_fcn(iGrid_1d igrid, pVctr_gpu_32 vzp_i, const T& w, pVctr_gpu_32 tfcn_o) + { + FOR_LOOP_1DC(igrid.nx, cgpu_detail_mt::fcn_trans_fcn(ix, igrid, vzp_i.m_data, w, tfcn_o.m_data)); + } + } + + /* eels */ + namespace gpu_detail_mt + { + template + __global__ void fcn_eels_lorentz_norm_factor(Grid_2d grid, T gc2, T ge2, pVctr_gpu_32 mx_o) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + T *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = T(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_lorentz_norm_factor(ix, iy, grid, gc2, ge2, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + template + __global__ void fcn_eels_w_xyz(Grid_2d grid, EELS eels, + pVctr_gpu_32 w_x, pVctr_gpu_32 w_y, pVctr_gpu_32 w_z) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_xyz(ix, iy, grid, eels, w_x.m_data, w_y.m_data, w_z.m_data)); + } + + template + __global__ void fcn_eels_w_x(Grid_2d grid, EELS eels, pVctr_gpu_32 w_x) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_x(ix, iy, grid, eels, w_x.m_data)); + } + + template + __global__ void fcn_eels_w_y(Grid_2d grid, EELS eels, pVctr_gpu_32 w_y) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_y(ix, iy, grid, eels, w_y.m_data)); + } + + template + __global__ void fcn_eels_w_z(Grid_2d grid, EELS eels, pVctr_gpu_32 w_z) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_z(ix, iy, grid, eels, w_z.m_data)); + } + + template + __global__ void fcn_eels_w_mn1(Grid_2d grid, EELS eels, pVctr_gpu_32 w_mn1) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mn1(ix, iy, grid, eels, w_mn1.m_data)); + } + + template + __global__ void fcn_eels_w_mp1(Grid_2d grid, EELS eels, pVctr_gpu_32 w_mp1) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mp1(ix, iy, grid, eels, w_mp1.m_data)); + } + } + } + +#endif diff --git a/src - Copy (2)/gpu_fcns.cuh b/src - Copy (2)/gpu_fcns.cuh new file mode 100755 index 00000000..5e57c5fc --- /dev/null +++ b/src - Copy (2)/gpu_fcns.cuh @@ -0,0 +1,1338 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +// #if defined __CUDACC__ && !defined GPU_FCNS_H +#ifndef GPU_FCNS_H + #define GPU_FCNS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_fcns.cuh" + #include "grid.cuh" + #include "gpu_detail.cuh" + + /* vector functions */ + namespace mt + { + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_assign_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_real()); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_assign_max_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_max_real(M_v, M_v)); + } + + template + enable_if_cvctr_and_rvctr + fcn_assign_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + if (M_v>0) + { + fcn_assign_max_real(mx_i, T(0), mx_o, pstream); + } + else + { + fcn_assign_real(mx_i, mx_o, pstream); + } + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_assign_abs_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_abs_real()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_assign_abs(TVctr_c& mx_i, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_abs()); + } + + /***************************************************************************************/ + template + enable_if_vctr_gpu + fcn_fill(TVctr& mx_io, Value_type val, Stream_gpu* pstream = nullptr) + { + thrust::fill(mx_io.begin(), mx_io.end(), val); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_scale(const Value_type& w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::scale(w_i)); + } + + template + enable_if_vctr_gpu + fcn_scale(const Value_type& w_i, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_io.begin(), mx_io.end(), mx_io.begin(), cgpu_fctr::scale(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_norm_2(TVctr_1& mx_i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::norm_2()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::scale_norm_2(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_sub(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::sub()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add(TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale(Value_type w1_i, TVctr_1& mx_1i, + Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add_scale_i(w1_i, w2_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add_scale(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_norm_2(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add_norm_2_i()); + + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_norm_2(TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add_norm_2()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale_norm_2(Value_type w1_i, TVctr_1& mx_1i, + Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add_scale_norm_2_i(w1_i, w2_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add_scale_norm_2(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_mult(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::mult()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_mult(TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::mult()); + } + + /***************************************************************************************/ + template + enable_if_vctr_gpu + fcn_div_sft(Value_type mx_sft, Value_type mx_div, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_io.begin(), mx_io.end(), mx_io.begin(), cgpu_fctr::div_sft(mx_sft, mx_div)); + } + + /***************************************************************************************/ + template + enable_if_vctr_gpu> + fcn_sum(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + return thrust::reduce(mx_i.begin(), mx_i.end()); + } + + template + enable_if_vctr_gpu> + fcn_sum_norm_2(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::norm_2(), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu> + fcn_sum_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::norm_2_sft(x_sft), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_cvctr_gpu> + fcn_sum_max_real(TVctr& mx_i, Value_type_r v_min, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::assign_max_real(v_min, T_r(0)), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_cvctr_gpu> + fcn_sum_abs_real(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::assign_abs_real(), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu> + fcn_sum_abs(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::assign_abs(), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu> + fcn_sum_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::abs_sft(), T_r(0), cgpu_fctr::add()); + } + + /***************************************************************************************/ + /* calculate mean */ + template + enable_if_vctr_gpu> + fcn_mean(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum(mx_i, pstream)/T(mx_i.size()); + } + + /* calculate mean of the norm square */ + template + enable_if_vctr_gpu> + fcn_mean_norm_2(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2(mx_i, pstream)/T_r(mx_i.size()); + } + + /* calculate mean of the shifted norm square */ + template + enable_if_vctr_gpu> + fcn_mean_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + template + enable_if_cvctr_gpu> + fcn_mean_max_real(TVctr& mx_i, Value_type_r v_min, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_max_real(mx_i, v_min, pstream)/T(mx_i.size()); + } + + template + enable_if_cvctr_gpu> + fcn_mean_abs_real(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_abs_real(mx_i, pstream)/T(mx_i.size()); + } + + template + enable_if_vctr_gpu> + fcn_mean_abs(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_abs(mx_i, pstream)/T_r(mx_i.size()); + } + + template + enable_if_vctr_gpu> + fcn_mean_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_abs_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + /***************************************************************************************/ + /* calculate mean and variance */ + template + enable_if_vctr_gpu + fcn_mean_var(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_var, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + x_mean = fcn_mean(mx_i, pstream); + x_var = fcn_mean_norm_2_sft(mx_i, x_mean, pstream); + } + + /* calculate mean and standard deviation */ + template + enable_if_vctr_gpu + fcn_mean_std(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_std, Stream_gpu* pstream = nullptr) + { + fcn_mean_var(mx_i, x_mean, x_std, pstream); + x_std = sqrt(x_std); + } + + // mean and first absolute moment + template + enable_if_vctr_gpu + fcn_mean_moment_1a(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_ma1, Stream_gpu* pstream = nullptr) + { + x_mean = fcn_mean(mx_i, pstream); + x_ma1 = fcn_mean_abs_sft(mx_i, x_mean, pstream); + } + + /* variance */ + template + enable_if_vctr_gpu> + fcn_variance(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_var; + fcn_mean_var(mx_i, x_mean, x_var, pstream); + + return x_var; + } + + /* standard deviation */ + template + enable_if_vctr_gpu> + fcn_std(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + auto x_var = fcn_variance(mx_i, pstream); + + return sqrt(x_var); + } + + // first absolute moment + template + enable_if_vctr_gpu> + fcn_moment_1a(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_ma1; + fcn_mean_moment_1a(mx_i, x_mean, x_ma1, pstream); + + return x_ma1; + } + + /***************************************************************************************/ + /* minimum element of a vector */ + template + enable_if_vctr_gpu> + fcn_min_element(const TVctr& x, Stream_gpu* pstream = nullptr) + { + return *thrust::min_element(x.begin(), x.end()); + } + + /* maximum element of a vector */ + template + enable_if_vctr_gpu> + fcn_max_element(const TVctr& x, Stream_gpu* pstream = nullptr) + { + return *thrust::max_element(x.begin(), x.end()); + } + + /* minimum and maximum element of a vector */ + template + enable_if_vctr_gpu + fcn_minmax_element(const TVctr& x, Value_type& x_min, Value_type& x_max, Stream_gpu* pstream = nullptr) + { + auto x_min_max = thrust::minmax_element(x.begin(), x.end()); + x_min = *(x_min_max.first); + x_max = *(x_min_max.second); + } + } + + /* add - assign - crop - norm_2 - fftsft */ + namespace mt + { + /* shift matrix respect to nx_h */ + template + enable_if_vctr_gpu + fcn_fftsft_1d(TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_1d(); + + gpu_detail::fcn_fftsft_1d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to ny_h */ + template + enable_if_vctr_gpu + fcn_fftsft_bc_2d(TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + gpu_detail::fcn_fftsft_bc_2d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_2d(TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + gpu_detail::fcn_fftsft_2d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_2d(TVctr& mx_i, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_fftsft_2d<<>>(igrid, mx_i.ptr_32(), mx_o.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_3d( TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_3d(); + + gpu_detail::fcn_fftsft_3d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_3d(TVctr& mx_i, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_3d(); + + gpu_detail::fcn_fftsft_3d<<>>(igrid, mx_i.ptr_32(), mx_o.ptr_32()); + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + enable_if_vctr_gpu + fcn_add_sc_fftsft_2d(TVctr& mx_i, Value_type w, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_fftsft_2d<<>>(igrid, mx_i.ptr_32(), w, mx_o.ptr_32()); + } + + /* add, scale, square and shift */ + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_sc_norm_2_fftsft_2d(TVctr_1& mx_i, Value_type w, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_norm_2_fftsft_2d<<>>(igrid, mx_i.ptr_32(), w, mx_o.ptr_32()); + } + + /***************************************************************************************/ + /* assign and crop */ + template + enable_if_vctr_gpu + fcn_assign_crop_2d(TVctr& mx_i, TVctr& mx_o, iRegion_Rect_2d& iregion, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_assign_crop_2d<<>>(igrid, mx_i.ptr_32(), iregion, mx_o.ptr_32()); + } + + /* assign, crop and shift */ + template + enable_if_vctr_gpu + fcn_assign_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_assign_crop_fftsft_2d<<>>(igrid, mx_i.ptr_32(), iregion, mx_o.ptr_32()); + } + + /* add, scale, crop and shift */ + template + enable_if_vctr_gpu + fcn_add_sc_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_crop_fftsft_2d<<>>(igrid, mx_i.ptr_32(), iregion, w, mx_o.ptr_32()); + } + + /* add, scale, square, crop and shift */ + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_sc_norm_2_crop_fftsft_2d(TVctr_1& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_norm_2_crop_fftsft_2d<<>>(igrid, mx_i.ptr_32(), iregion, w, mx_o.ptr_32()); + } + } + + /* transpose - element wise matrix op vector */ + namespace mt + { + /* transpose */ + template + enable_if_vctr_gpu>> + fcn_trs_2d(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + Vctr_gpu mx_t(mx_i.shape_2d_trs()); + gpu_detail::fcn_trs_2d<<>>(igrid, mx_i.ptr_32(), mx_t.ptr_32()); + + return mx_t; + } + + /* transpose */ + template + enable_if_vctr_gpu + fcn_trs_2d(TVctr& mx_i, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + if (&mx_i != &mx_o) + { + gpu_detail::fcn_trs_2d<<>>(igrid, mx_i.ptr_32(), mx_o.ptr_32()); + } + else + { + Vctr_gpu mx_t(mx_i.shape_2d_trs()); + gpu_detail::fcn_trs_2d<<>>(igrid, mx_i.ptr_32(), mx_t.ptr_32()); + mx_t.cpy_to_gpu_ptr(mx_o.m_data, mx_o.size()); + } + } + + /* element wise addition: matrix + vector*/ + template + enable_if_vctr_gpu + fcn_ew_add_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + gpu_detail::fcn_ew_add_mx_vctr_col<<>>(igrid, vctr, mx_io.ptr_32()); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + gpu_detail::fcn_ew_add_mx_vctr_row<<>>(igrid, vctr, mx_io.ptr_32()); + } + } + + /* element wise subtraction: matrix - vector */ + template + enable_if_vctr_gpu + fcn_ew_sub_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + gpu_detail::fcn_ew_sub_mx_vctr_col<<>>(igrid, vctr, mx_io.ptr_32()); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + gpu_detail::fcn_ew_sub_mx_vctr_row<<>>(igrid, vctr, mx_io.ptr_32()); + } + } + + /* element wise multiplication matrix X vector */ + template + enable_if_vctr_gpu + fcn_ew_mult_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + gpu_detail::fcn_ew_mult_mx_vctr_col<<>>(igrid, vctr, mx_io.ptr_32()); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + gpu_detail::fcn_ew_mult_mx_vctr_row<<>>(igrid, vctr, mx_io.ptr_32()); + } + } + } + + /* aperture functions */ + namespace mt + { + template + enable_if_vctr_gpu + fcn_fermi_aperture(Grid_2d& grid, T g2_cut, T alpha, T w, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fermi_aperture<<>>(grid, g2_cut, alpha, w, mx_io.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_hard_aperture(Grid_2d& grid, T g2_cut, T w, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_hard_aperture<<>>(grid, g2_cut, w, mx_io.ptr_32()); + } + } + + /* phase shifts real space*/ + namespace mt + { + template + enable_if_vctr_gpu + fcn_rs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T gx, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_exp_factor_1d<<>>(grid, psi_i.ptr_32(), gx, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &gy, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_exp_factor_2d_bc<<>>(grid, alpha, psi_i.ptr_32(), gy.ptr_32(), w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_rs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d g, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_exp_factor_2d<<>>(grid, psi_i.ptr_32(), g, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& g, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_mul_exp_factor_2d<<>>(grid, psi_i.ptr_32(), g.ptr_32(), w, psi_o.ptr_32()); + } + } + + /* phase shifts fourier space */ + namespace mt + { + template + enable_if_vctr_gpu + fcn_fs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T rx, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_exp_factor_1d<<>>(grid, psi_i.ptr_32(), rx, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_fs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &ry, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_exp_factor_2d_bc<<>>(grid, alpha, psi_i.ptr_32(), ry.ptr_32(), w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_fs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d r, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_exp_factor_2d<<>>(grid, psi_i.ptr_32(), r, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_fs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& r, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_mul_exp_factor_2d<<>>(grid, psi_i.ptr_32(), r.ptr_32(), w, psi_o.ptr_32()); + } + } + + /* gradient */ + namespace mt + { + template + enable_if_vctr_gpu + fcn_grad_x(TVctr& mx_i, TVctr& dmx_x, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_grad_x<<>>(igrid, mx_i.ptr_32(), dmx_x.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_grad_y(TVctr& mx_i, TVctr& dmx_y, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_grad_y<<>>(igrid, mx_i.ptr_32(), dmx_y.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_grad(TVctr& mx_i, TVctr& dmx_x, TVctr& dmx_y, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_grad<<>>(igrid, mx_i.ptr_32(), dmx_x.ptr_32(), dmx_y.ptr_32()); + } + } + + /* function multiplication fourier space */ + namespace mt + { + #define FCN_MULT_FS_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_vctr_gpu \ + fcn_mult_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, T w, TVctr_c& mx_io, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + gpu_detail::fcn_mult_fs_##FN##_##DIM##d<<>>(grid, fcn, w, mx_io.ptr_32()); \ + } + + /* gaussian */ + FCN_MULT_FS_FCN_GPU(gauss, Fcn_Gauss, 1); // fcn_mult_fs_gauss_1d + FCN_MULT_FS_FCN_GPU(gauss, Fcn_Gauss, 2); // fcn_mult_fs_gauss_2d + FCN_MULT_FS_FCN_GPU(gauss, Fcn_Gauss, 3); // fcn_mult_fs_gauss_3d + + /* exponential */ + FCN_MULT_FS_FCN_GPU(exp, Fcn_Exp, 1); // fcn_mult_fs_exp_1d + FCN_MULT_FS_FCN_GPU(exp, Fcn_Exp, 2); // fcn_mult_fs_exp_2d + FCN_MULT_FS_FCN_GPU(exp, Fcn_Exp, 3); // fcn_mult_fs_exp_3d + + /* fermi */ + FCN_MULT_FS_FCN_GPU(fermi, Fcn_Fermi, 1); // fcn_mult_fs_fermi_1d + FCN_MULT_FS_FCN_GPU(fermi, Fcn_Fermi, 2); // fcn_mult_fs_fermi_2d + FCN_MULT_FS_FCN_GPU(fermi, Fcn_Fermi, 3); // fcn_mult_fs_fermi_3d + + /* butterworth */ + FCN_MULT_FS_FCN_GPU(butwth, Fcn_Butwth, 1); // fcn_mult_fs_butwth_1d + FCN_MULT_FS_FCN_GPU(butwth, Fcn_Butwth, 2); // fcn_mult_fs_butwth_2d + FCN_MULT_FS_FCN_GPU(butwth, Fcn_Butwth, 3); // fcn_mult_fs_butwth_3d + + /* hann */ + FCN_MULT_FS_FCN_GPU(hann, Fcn_Hann, 1); // fcn_mult_fs_hann_1d + FCN_MULT_FS_FCN_GPU(hann, Fcn_Hann, 2); // fcn_mult_fs_hann_2d + FCN_MULT_FS_FCN_GPU(hann, Fcn_Hann, 3); // fcn_mult_fs_hann_3d + } + + /* convolution */ + namespace mt + { + #define FCN_CV_FS_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_cvctr_gpu \ + fcn_cv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_gpu& fft, FCN& fcn, TVctr_c& mx_io, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + fcn_mult_fs_##FN##_##DIM##d(grid, fcn, w, mx_io, pstream); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_CV_FS_FCN_GPU(gauss, Fcn_Gauss, 1); // fcn_cv_fs_gauss_1d + FCN_CV_FS_FCN_GPU(gauss, Fcn_Gauss, 2); // fcn_cv_fs_gauss_2d + FCN_CV_FS_FCN_GPU(gauss, Fcn_Gauss, 3); // fcn_cv_fs_gauss_3d + + /* exponential convolution */ + FCN_CV_FS_FCN_GPU(exp, Fcn_Exp, 1); // fcn_cv_fs_exp_1d + FCN_CV_FS_FCN_GPU(exp, Fcn_Exp, 2); // fcn_cv_fs_exp_2d + FCN_CV_FS_FCN_GPU(exp, Fcn_Exp, 3); // fcn_cv_fs_exp_3d + + /* fermi convolution */ + FCN_CV_FS_FCN_GPU(fermi, Fcn_Fermi, 1); // fcn_cv_fs_fermi_1d + FCN_CV_FS_FCN_GPU(fermi, Fcn_Fermi, 2); // fcn_cv_fs_fermi_2d + FCN_CV_FS_FCN_GPU(fermi, Fcn_Fermi, 3); // fcn_cv_fs_fermi_3d + + /* butterworth convolution */ + FCN_CV_FS_FCN_GPU(butwth, Fcn_Butwth, 1); // fcn_cv_fs_butwth_1d + FCN_CV_FS_FCN_GPU(butwth, Fcn_Butwth, 2); // fcn_cv_fs_butwth_2d + FCN_CV_FS_FCN_GPU(butwth, Fcn_Butwth, 3); // fcn_cv_fs_butwth_3d + + /* hann convolution */ + FCN_CV_FS_FCN_GPU(hann, Fcn_Hann, 1); // fcn_cv_fs_hann_1d + FCN_CV_FS_FCN_GPU(hann, Fcn_Hann, 2); // fcn_cv_fs_hann_2d + FCN_CV_FS_FCN_GPU(hann, Fcn_Hann, 3); // fcn_cv_fs_hann_3d + } + + /* deconvolution */ + namespace mt + { + #define FCN_DCV_FS_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_cvctr_gpu \ + fcn_dcv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_gpu& fft, FCN& fcn, T psnr, TVctr_c& mx_io, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + gpu_detail::fcn_dcv_fs_##FN##_##DIM##d<<>>(grid, fcn, psnr, w, mx_io.ptr_32()); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_DCV_FS_FCN_GPU(gauss, Fcn_Gauss, 1); // fcn_dcv_fs_gauss_1d + FCN_DCV_FS_FCN_GPU(gauss, Fcn_Gauss, 2); // fcn_dcv_fs_gauss_2d + FCN_DCV_FS_FCN_GPU(gauss, Fcn_Gauss, 3); // fcn_dcv_fs_gauss_3d + + /* exponential convolution */ + FCN_DCV_FS_FCN_GPU(exp, Fcn_Exp, 1); // fcn_dcv_fs_exp_1d + FCN_DCV_FS_FCN_GPU(exp, Fcn_Exp, 2); // fcn_dcv_fs_exp_2d + FCN_DCV_FS_FCN_GPU(exp, Fcn_Exp, 3); // fcn_dcv_fs_exp_3d + + /* fermi convolution */ + FCN_DCV_FS_FCN_GPU(fermi, Fcn_Fermi, 1); // fcn_dcv_fs_fermi_1d + FCN_DCV_FS_FCN_GPU(fermi, Fcn_Fermi, 2); // fcn_dcv_fs_fermi_2d + FCN_DCV_FS_FCN_GPU(fermi, Fcn_Fermi, 3); // fcn_dcv_fs_fermi_3d + + /* butterworth convolution */ + FCN_DCV_FS_FCN_GPU(butwth, Fcn_Butwth, 1); // fcn_dcv_fs_butwth_1d + FCN_DCV_FS_FCN_GPU(butwth, Fcn_Butwth, 2); // fcn_dcv_fs_butwth_2d + FCN_DCV_FS_FCN_GPU(butwth, Fcn_Butwth, 3); // fcn_dcv_fs_butwth_3d + + /* hann convolution */ + FCN_DCV_FS_FCN_GPU(hann, Fcn_Hann, 1); // fcn_dcv_fs_hann_1d + FCN_DCV_FS_FCN_GPU(hann, Fcn_Hann, 2); // fcn_dcv_fs_hann_2d + FCN_DCV_FS_FCN_GPU(hann, Fcn_Hann, 3); // fcn_dcv_fs_hann_3d + } + + /* window functions */ + namespace mt + { + #define FCN_WD_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_vctr_gpu \ + fcn_wd_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, dt_bool sft, TVctr& mx_o, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + if (sft) \ + { \ + gpu_detail::fcn_wd_##FN##_##DIM##d<<>>(grid, fcn, mx_o.ptr_32()); \ + } \ + else \ + { \ + gpu_detail::fcn_wd_##FN##_##DIM##d<<>>(grid, fcn, mx_o.ptr_32()); \ + } \ + } + + FCN_WD_FCN_GPU(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + FCN_WD_FCN_GPU(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + FCN_WD_FCN_GPU(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + FCN_WD_FCN_GPU(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + FCN_WD_FCN_GPU(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + FCN_WD_FCN_GPU(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + FCN_WD_FCN_GPU(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + FCN_WD_FCN_GPU(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + FCN_WD_FCN_GPU(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + FCN_WD_FCN_GPU(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + FCN_WD_FCN_GPU(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + FCN_WD_FCN_GPU(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + FCN_WD_FCN_GPU(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + FCN_WD_FCN_GPU(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + FCN_WD_FCN_GPU(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d + } + + /* phase correlation */ + namespace mt + { + /****************** pcf data processing real space *******************/ + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Butwth_1d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_pcf_1d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Butwth_2d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_pcf_2d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Butwth_3d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_pcf_3d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + /***************** pcf data processing fourier space *****************/ + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Gauss_1d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_pcf_1d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Gauss_2d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_pcf_2d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Gauss_3d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_pcf_3d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + } + + /* optical flow */ + namespace mt + { + template + enable_if_vctr_gpu + fcn_opt_flow(TVctr& mx_s, TVctr& mx_m, T alpha, TVctr& dphi_x, TVctr& dphi_y, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto igrid = mx_s.igrid_2d(); + + gpu_detail::fcn_opt_flow<<>>(igrid, mx_s.ptr_32(), mx_m.ptr_32(), alpha, dphi_x.ptr_32(), dphi_y.ptr_32()); + } + } + + /* bilinear interpolation */ + namespace mt + { + template + enable_if_vctr_gpu + fcn_intrpl_bl_rg_2d(Grid_2d& grid, TVctr& mx_i, TVctr& vx, TVctr& vy, T bg, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_intrpl_bl_rg_2d<<>>(grid, mx_i.ptr_32(), vx.ptr_32(), vy.ptr_32(), bg, mx_o.ptr_32()); + } + } + + namespace mt + { + // /***************************************************************************************/ + // template + // enable_if_vctr_gpu> + // atom_cost_function(Grid_2d& grid, const Atom_Sa>& atom_Ip, TVctr_r& mx_i) + // { + // TVctr_r sum_v(1); + + // D_Grid_Blk d_grid_blk; + // d_grid_blk.grid = dim3(); + // d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + + // gpu_detail::atom_cost_function<<>>(grid_2d, atom_Ip, mx_i.ptr_32(), sum_v); + // return sum_v[0]; + // } + + // template + // enable_if_vctr_gpu + // subtract_atom(Grid_2d& grid, Vctr>, edev_cpu>& atom_Ip, TVctr_r& mx_i) + // { + // if (stream.n_stream_act<= 0) + // { + // return; + // } + + // for(auto istm = 0; istm < stream.n_stream_act; istm++) + // { + // D_Grid_Blk d_grid_blk; + // d_grid_blk.grid = dim3(); + // d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + + // gpu_detail::subtract_atom<<>>(grid_2d, atom_Ip[istm], mx_i); + // } + // } + + // // Linear projected potential: V and zV + // template + // enable_if_device + // linear_Vz(eAtomic_Pot_Parm_Typ atomic_pot_parm_typ, TQ1 &qz, TVAtom &vatom) + // { + // using TAtom = Value_type; + + // if (stream.n_stream_act<= 0) + // { + // return; + // } + + // auto str_linear_Vz = [](cudaStream_t &stream, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, TQ1 &qz, TAtom &atom) + // { + // if (atom.charge == 0) + // { + // switch(atomic_pot_parm_typ) + // { + // case eappt_doyle_0_4: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_peng_0_4: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_peng_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_kirkland_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_weickenmeier_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_lobato_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // } + // } + // else + // { + // switch(atomic_pot_parm_typ) + // { + // case eappt_doyle_0_4: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_peng_0_4: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_peng_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_kirkland_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_weickenmeier_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // case eappt_lobato_0_12: + // gpu_detail::linear_Vz<<>>(qz, atom); + // break; + // } + // } + // }; + + // for(auto istm = 0; istm < stream.n_stream_act; istm++) + // { + // str_linear_Vz(stream[istm], atomic_pot_parm_typ, qz, vatom[istm]); + // } + // } + + // // Get local interpolation coefficients + // template + // enable_if_device + // fcn_vd_2_coef_poly3(TVAtom &vatom) + // { + // using TAtom = Value_type; + + // if (stream.n_stream_act<= 0) + // { + // return; + // } + + // for(auto istm = 0; istm < stream.n_stream_act; istm++) + // { + // gpu_detail::fcn_vd_2_coef_poly3<<>>(vatom[istm]); + // } + // } + // + // template + // typename std::enable_if::value + // && is_cfloat>::value && !std::is_same, Value_type>::value, void>::type + // cpy_to_host(Stream& stream, TVctr_i &mx_i, TVctr_o &mx_o, + // Vctr, edev_cpu> *M_i_h = nullptr) + // { + // Vctr, edev_cpu> M_h; + // M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // // data transfer from GPU to CPU + // M_i_h->assign(mx_i.begin(), mx_i.end()); + + // // copy data from CPU to CPU + // cpy_to_host(stream, *M_i_h, mx_o.ptr_32()); + // } + + // template + // typename std::enable_if::value + // && (!is_cfloat>::value || std::is_same, Value_type>::value), void>::type + // cpy_to_host(Stream& stream, TVctr_i &mx_i, TVctr_o &mx_o, + // Vctr, edev_cpu> *M_i_h = nullptr) + // { + // mx_o.assign(mx_i.begin(), mx_i.end()); + // } + + // template + // enable_if_vctr_gpu_and_vctr_cpu + // add_sc_to_host(Stream& stream, Value_type w_i, + // TVctr_i &mx_i, TVctr_o &mx_o, Vctr, edev_cpu> *M_i_h = nullptr) + // { + // Vctr, edev_cpu> M_h; + // M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // // data transfer from GPU to CPU + // M_i_h->assign(mx_i.begin(), mx_i.end()); + + // // add and scale + // mt::add_sc_to_host(stream, w_i, *M_i_h, mx_o.ptr_32()); + // } + + // template + // enable_if_vctr_gpu_and_vctr_cpu + // add_sc_square_to_host(Stream& stream, Value_type w_i, + // TVctr_i &mx_i, TVctr_o &mx_o, Vctr, edev_cpu> *M_i_h = nullptr) + // { + // Vctr, edev_cpu> M_h; + // M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // // data transfer from GPU to CPU + // M_i_h->assign(mx_i.begin(), mx_i.end()); + + // mt::add_sc_square_to_host(stream, w_i, *M_i_h, mx_o.ptr_32()); + // } + + // template + // enable_if_vctr_gpu_and_vctr_cpu + // add_sc_m2psi_psi_to_host(Stream& stream, Value_type w_i, + // TVctr_c_i &psi_i, TVctr_r_o &m2psi_o, TVctr_c_o &psi_o, Vctr, edev_cpu> *psi_i_h = nullptr) + // { + // Vctr, edev_cpu> M_h; + // psi_i_h = (psi_i_h == nullptr)?&M_h:psi_i_h; + + // // data transfer from GPU to CPU + // psi_i_h->assign(psi_i.begin(), psi_i.end()); + + // mt::add_sc_m2psi_psi_to_host(stream, w_i, *psi_i_h, m2psi_o, psi_o); + // } + // /***************************************************************************************/ + // // find peak position 1d + // template + // enable_if_vctr_gpu> + // fit_max_pos_1d(TGrid& grid_1d, TVctr& Im, Value_type p_i, + // Value_type sigma_i, Value_type radius_i) + // { + // using T = Value_type; + + // Vctr Im_h = Im; + // return fit_max_pos_1d(grid_1d, Im_h, p_i, sigma_i, radius_i); + // } + + // inline + // D_Grid_Blk d_grid_blk(dt_int32 nx, dt_int32 ny, dt_int32 gpu_device, dt_int32 n_thread) + // { + // dt_int32 n_SMs; + // cudaDeviceGetAttribute(&n_SMs, cudaDevAttrMultiProcessorCount, gpu_device); + + // dt_int32 n_thr_SMs; + // cudaDeviceGetAttribute(&n_thr_SMs, cudaDevAttrMaxThreadsPerMultiProcessor, gpu_device); + + // dt_int32 n_thr_blk; + // cudaDeviceGetAttribute(&n_thr_blk, cudaDevAttrMaxThreadsPerBlock, gpu_device); + + // dt_int32 tnr_nxy = c_thr_2d_x*c_thr_2d_y; + // dt_int32 blk_max = 8*max(1, n_thr_SMs/(tnr_nxy*n_thread))*n_SMs; + // dt_int32 blk_x = (ny+c_thr_2d_x-1)/c_thr_2d_x; + // dt_int32 blk_y = (nx+c_thr_2d_y-1)/c_thr_2d_y; + // dt_float64 f = sqrt(dt_float64(blk_max)/dt_float64(blk_x*blk_y)); + // blk_x = max(c_blk_x, static_cast(f*blk_x)); + // blk_y = max(c_blk_y, static_cast(f*blk_y)); + + // D_Grid_Blk d_grid_blk; + // d_grid_blk.grid = dim3(blk_x, blk_y); + // d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + + // return d_grid_blk; + // } + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/gpu_fcns_mt.cuh b/src - Copy (2)/gpu_fcns_mt.cuh new file mode 100755 index 00000000..578086a4 --- /dev/null +++ b/src - Copy (2)/gpu_fcns_mt.cuh @@ -0,0 +1,376 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef GPU_FCNS_MT_H + #define GPU_FCNS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "types.cuh" + #include "type_traits_mt.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_stream.cuh" + #include "gpu_detail_mt.cuh" + + /* atomic functions */ + namespace mt + { + /*********************************** pFcn_clnl_3_x **********************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx, pFcn_clnl_3_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_3_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, fx1, fx2, fcn); + } + + /********************************* pFcn_clnl_4_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& c, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx, pFcn_clnl_4_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, c, coef, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& c, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_4_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, c, coef, fx1, fx2, fcn); + } + + /********************************* pFcn_clnl_6_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx, pFcn_clnl_6_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, quad, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_6_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, quad, fx1, fx2, fcn); + } + + /********************************* pFcn_clnl_8_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx, pFcn_clnl_8_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, z_0, z_e, coef, quad, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_8_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, z_0, z_e, coef, quad, fx1, fx2, fcn); + } + } + + /* detector integration */ + namespace mt + { + template + enable_if_vctr_gpu> + fcn_int_det_ring(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + TVctr sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_ring<<>>(grid, g2_min, g2_max, mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu> + fcn_int_det_ring_norm_2(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + Vctr_gpu sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_ring_norm_2<<>>(grid, g2_min, g2_max, mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu> + fcn_int_det_sen(Grid_2d& grid, TVctr& sen_i, TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + TVctr sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_sen<<>>(grid, sen_i.ptr_32(), mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu_and_vctr_gpu> + fcn_int_det_sen_norm_2(Grid_2d& grid, TVctr_1& sen_i, TVctr_2& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + Vctr_gpu sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_sen_norm_2<<>>(grid, sen_i.ptr_32(), mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + } + + /* wave propagation */ + namespace mt + { + /* propagate */ + template + enable_if_vctr_gpu + fcn_fs_propagate(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail_mt::fcn_fs_propagate<<>>(grid, psi_i.ptr_32(), g_0, w_g2, w, psi_o.ptr_32()); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + enable_if_vctr_gpu + fcn_fs_propagate_bw_f(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T alpha, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail_mt::fcn_fs_propagate_bw_f<<>>(grid, psi_i.ptr_32(), g_0, w_g2, g2_cut, alpha, w, psi_o.ptr_32()); + } + + /* propagate and bandwith limit using a hard aperture */ + template + enable_if_vctr_gpu + fcn_fs_propagate_bw_h(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail_mt::fcn_fs_propagate_bw_h<<>>(grid, psi_i.ptr_32(), g_0, w_g2, g2_cut, w, psi_o.ptr_32()); + } + } + + /* probe - ctf - pctf */ + namespace mt + { + template + enable_if_vctr_gpu + fcn_fs_probe(Grid_2d& grid, Lens& lens, R_2d r, R_2d gu, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + gpu_detail_mt::fcn_fs_probe<<>>(grid, lens, r, gu, psi_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_fs_probe<<>>(grid, lens, r, gu, psi_o.ptr_32()); + } + + auto tot_intensity = fcn_sum_norm_2(psi_o, pstream); + auto sc_fctr = ::sqrt(T(1)/tot_intensity); + + fcn_scale(sc_fctr, psi_o, pstream); + } + + template + enable_if_vctr_gpu + fcn_fs_apply_ctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, R_2d gu, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + gpu_detail_mt::fcn_fs_apply_ctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_fs_apply_ctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + enable_if_vctr_gpu + fcn_fs_apply_pctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + gpu_detail_mt::fcn_fs_apply_pctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_fs_apply_pctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + } + } + + /* transmission function */ + namespace mt + { + template + enable_if_vctr_gpu_and_vctr_gpu + transmission_fcn(eElec_Spec_Interact_Mod esim, TVctr_1& vzp_i, T w, TVctr_2& tfcn_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + iGrid_1d igrid(vzp_i.size()); + + if (esim==eesim_weak_phase_object) + { + gpu_detail_mt::fcn_trans_fcn<<>>(igrid, vzp_i.ptr_32(), w, tfcn_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_trans_fcn<<>>(igrid, vzp_i.ptr_32(), w, tfcn_o.ptr_32()); + } + } + } + + /* eels */ + namespace mt + { + template + T fcn_eels_lorentz_norm_factor_gpu(Grid_2d& grid, EELS& eels, Stream_gpu* pstream = nullptr) + { + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + Vctr_gpu sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_eels_lorentz_norm_factor<<>>(grid, eels.gc2, eels.ge2, sum_v.ptr_32()); + + return ::sqrt(eels.occ)/gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu + fcn_eels_w_xyz(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_x, TVctr_c& w_y, TVctr_c& w_z, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_xyz<<>>(grid, eels, w_x.ptr_32(), w_y.ptr_32(), w_z.ptr_32()); + + fft.inverse(w_x); + fft.inverse(w_y); + fft.inverse(w_z); + } + + template + enable_if_vctr_gpu + fcn_eels_w_x(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_x, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_x<<>>(grid, eels, w_x.ptr_32()); + + fft.inverse(w_x); + } + + template + enable_if_vctr_gpu + fcn_eels_w_y(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_y, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_y<<>>(grid, eels, w_y.ptr_32()); + + fft.inverse(w_y); + } + + template + enable_if_vctr_gpu + fcn_eels_w_z(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_z, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_z<<>>(grid, eels, w_z.ptr_32()); + + fft.inverse(w_z); + } + + template + enable_if_vctr_gpu + fcn_eels_w_mn1(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_mn1, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_mn1<<>>(grid, eels, w_mn1.ptr_32()); + + fft.inverse(w_mn1); + } + + template + enable_if_vctr_gpu + fcn_eels_w_mp1(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_mp1, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_mp1<<>>(grid, eels, w_mp1.ptr_32()); + + fft.inverse(w_mp1); + } + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/grid.cuh b/src - Copy (2)/grid.cuh new file mode 100755 index 00000000..c2618f03 --- /dev/null +++ b/src - Copy (2)/grid.cuh @@ -0,0 +1,3410 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef GRID_H + #define GRID_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_fcns_gen.cuh" + #include "igrid.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "region.cuh" + #include "cgpu_vctr.cuh" + + /***************************************************************************************/ + /*************************************** grid ******************************************/ + /***************************************************************************************/ + namespace mt + { + template class Grid_sxd; + + template + using Grid_xd = Grid_sxd; + + /* 1d */ + template + using Grid_1d_st = Grid_sxd; + + template + using Grid_1d = Grid_sxd; + + template + using Grid_1d_64 = Grid_sxd; + + /* 2d */ + template + using Grid_2d_st = Grid_sxd; + + template + using Grid_2d = Grid_sxd; + + template + using Grid_2d_64 = Grid_sxd; + + /* 3d */ + template + using Grid_3d_st = Grid_sxd; + + template + using Grid_3d = Grid_sxd; + + template + using Grid_3d_64 = Grid_sxd; + } + + /*template specialization 1d */ + namespace mt + { + template + class Grid_sxd: public iGrid_sxd + { + public: + using value_type = T; + using size_type = ST; + + T bs_x; // simulation box size along x direction (Angstroms) + + T rx_0; // reference coordinate system along x + + dt_bool pbc_x; // peridic boundary condition along x + + dt_bool bwl; // band-width limit + + T sli_thick; // slice thicknes + + T drx; // x-sampling in real space + + T dgx; // x-sampling in reciprocal space + + /************************************* constructors ************************************/ + CGPU_EXEC + Grid_sxd(): iGrid_sxd(), bs_x(0), rx_0(0), pbc_x(true), + bwl(false), sli_thick(0), drx(0), dgx(0) {} + + Grid_sxd(const ST& nx) + { + set_in_data(nx); + } + + template + Grid_sxd(const U& bs_x, const SU& nx) + { + set_in_data(bs_x, nx); + } + + template + Grid_sxd(const U& bs_x, const SU& nx, const U& rx_0, + dt_bool pbc_x = true, dt_bool bwl = false, U sli_thick = 0.5) + { + set_in_data(bs_x, nx, rx_0, pbc_x, bwl, sli_thick); + } + + /* copy constructor */ + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /* converting constructor */ + template + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + bs_x = grid.bs_x; + rx_0 = grid.rx_0; + pbc_x = grid.pbc_x; + bwl = grid.bwl; + sli_thick = grid.sli_thick; + + drx = grid.drx; + dgx = grid.dgx; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + bs_x = T(grid.bs_x); + rx_0 = T(grid.rx_0); + pbc_x = grid.pbc_x; + bwl = grid.bwl; + sli_thick = T(grid.sli_thick); + + drx = T(grid.drx); + dgx = T(grid.dgx); + + return *this; + } + + template + CGPU_EXEC + void assign(const Grid_sxd& grid) + { + *this = grid; + } + + /************************ user define conversion operators ****************************/ + operator iRegion_Rect_xd() const + { + return {ST(0), this->nx}; + } + + /***************************************************************************************/ + void set_in_data(const ST& nx) + { + set_in_data(T(nx), nx, T(0)); + } + + template + void set_in_data(const U& bs_x, const SU& nx) + { + set_in_data(T(bs_x), ST(nx), T(0)); + } + + template + void set_in_data(const U& bs_x, const SU& nx, + const U& rx_0, dt_bool pbc_x = true, dt_bool bwl = false, U sli_thick = 0.5) + { + this->set_size(nx); + + this->bs_x = T(bs_x); + this->rx_0 = T(rx_0); + this->pbc_x = pbc_x; + this->bwl = bwl; + this->sli_thick = T(sli_thick); + + set_dep_var(); + } + + void set_dep_var() + { + drx = mt::fcn_div(bs_x, this->nx); + dgx = mt::fcn_div(T(1), bs_x); + } + + CGPU_EXEC + void set_r_0(const T& rx_0) + { + this->rx_0 = rx_0; + } + + /***************************************************************************************/ + CGPU_EXEC + T nx_r() const + { + return T(this->nx); + } + + CGPU_EXEC + T size_r() const + { + return T(this->size()); + } + + T isize_r() const + { + return T(1)/size_r(); + } + + /***************************************************************************************/ + CGPU_EXEC + T bs_x_h() const + { + return T(0.5)*bs_x; + } + + CGPU_EXEC + T bs_h() const + { + return bs_x_h(); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx_c() const + { + return rx_0 + bs_x_h(); + } + + CGPU_EXEC + T rv_c() const + { + return rx_c(); + } + + /***************************************************************************************/ + // maximum frequency + CGPU_EXEC + T g_max() const + { + return gx_back(); + } + + // maximum square frequency + CGPU_EXEC + T g2_max() const + { + return ::square(g_max()); + } + + // maximum allowed frequency + CGPU_EXEC + T gl_max() const + { + return g_max()*T(2.0/3.0); + } + + // maximum square allowed frequency + CGPU_EXEC + T gl2_max() const + { + return ::square(gl_max()); + } + + /***************************************************************************************/ + /****************************** Fourier space positions ********************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix) const + { + return T(this->igx(ix))*dgx; + } + + CGPU_EXEC + T gx2(const ST& ix) const + { + return ::square(gx(ix)); + } + + CGPU_EXEC + T g2(const ST& ix) const + { + return gx2(ix); + } + + CGPU_EXEC + T g(const ST& ix) const + { + return ::fabs(gx(ix)); + } + + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix, const T& gx_0) const + { + return gx(ix) - gx_0; + } + + CGPU_EXEC + T gx2(const ST& ix, const T& gx_0) const + { + return ::square(gx(ix, gx_0)); + } + + CGPU_EXEC + T g2(const ST& ix, const T& gx_0) const + { + return gx2(ix, gx_0); + } + + CGPU_EXEC + T g(const ST& ix, const T& gx_0) const + { + return ::fabs(gx(ix, gx_0)); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + T gx_sft(const ST& ix) const + { + return T(this->igx_sft(ix))*dgx; + } + + CGPU_EXEC + T gx2_sft(const ST& ix) const + { + return ::square(gx_sft(ix)); + } + + CGPU_EXEC + T g2_sft(const ST& ix) const + { + return gx2_sft(ix); + } + + CGPU_EXEC + T g_sft(const ST& ix) const + { + return ::fabs(gx_sft(ix)); + } + + /***************************************************************************************/ + CGPU_EXEC + T gx_sft(const ST& ix, const T& gx_0) const + { + return gx_sft(ix) - gx_0; + } + + CGPU_EXEC + T gx2_sft(const ST& ix, const T& gx_0) const + { + return ::square(gx_sft(ix, gx_0)); + } + + CGPU_EXEC + T g2_sft(const ST& ix, const T& gx_0) const + { + return gx2_sft(ix, gx_0); + } + + CGPU_EXEC + T g_sft(const ST& ix, const T& gx_0) const + { + return ::fabs(gx_sft(ix, gx_0)); + } + + /***************************************************************************************/ + /******************************** real space positions *********************************/ + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix) const + { + return T(this->irx(ix))*drx + rx_0; + } + + CGPU_EXEC + T rx2(const ST& ix) const + { + return ::square(rx(ix)); + } + + CGPU_EXEC + T r2(const ST& ix) const + { + return rx2(ix); + } + + CGPU_EXEC + T r(const ST& ix) const + { + return ::fabs(rx(ix)); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix, const T& x0) const + { + return rx(ix) - x0; + } + + CGPU_EXEC + T rx2(const ST& ix, const T& x0) const + { + return ::square(rx(ix, x0)); + } + + CGPU_EXEC + T r2(const ST& ix, const T& x0) const + { + return rx2(ix, x0); + } + + CGPU_EXEC + T r(const ST& ix, const T& x0) const + { + return ::fabs(rx(ix, x0)); + } + + /***************************************************************************************/ + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix) const + { + return T(this->irx_sft(ix))*drx + rx_0; + } + + CGPU_EXEC + T rx2_sft(const ST& ix) const + { + return ::square(rx_sft(ix)); + } + + CGPU_EXEC + T r2_sft(const ST& ix) const + { + return rx2_sft(ix); + } + + CGPU_EXEC + T r_sft(const ST& ix) const + { + return ::fabs(rx_sft(ix)); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix, const T& x0) const + { + return rx_sft(ix) - x0; + } + + CGPU_EXEC + T rx2_sft(const ST& ix, const T& x0) const + { + return ::square(rx_sft(ix, x0)); + } + + CGPU_EXEC + T r2_sft(const ST& ix, const T& x0) const + { + return rx2_sft(ix, x0); + } + + CGPU_EXEC + T r_sft(const ST& ix, const T& x0) const + { + return ::fabs(rx_sft(ix, x0)); + } + + /***************************************************************************************/ + /******************************* from position to index ********************************/ + /***************************************************************************************/ + template + void ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_n); + } + + template + void ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_e); + ix_e += ix_0; + } + + /************ fds = floor/division by pixel size ************/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fd(const T& x) const + { + return fcn_cfloor(x/drx); + } + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfd(const T& x) const + { + return fcn_set_bound(rx_2_irx_fd(x), ST(0), this->nx-1); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cd(const T& x) const + { + return fcn_cceil(x/drx); + } + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcd(const T& x) const + { + return fcn_set_bound(rx_2_irx_cd(x), ST(0), this->nx-1); + } + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fds(const T& x) const + { + return fcn_cfloor((x - rx_0)/drx); + } + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfds(const T& x) const + { + return fcn_set_bound(rx_2_irx_fds(x), ST(0), this->nx-1); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cds(const T& x) const + { + return fcn_cceil((x - rx_0)/drx); + } + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcds(const T& x) const + { + return fcn_set_bound(rx_2_irx_cds(x), ST(0), this->nx-1); + } + + /************ From position to index by searching ***********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_b(const T& x, ST ix_min=0, ST ix_max=0) const + { + if (ix_min == ix_max) + { + ix_min = ST(0); + ix_max = this->nx-1; + } + + return fcn_r_2_ir_b_by_fcn(rx, ix_min, ix_max); + } + + /***************************************************************************************/ + /********************************** check bounds ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_front(), rx_back()); + } + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_front(), rx_back()); + } + + /***************************************************************************************/ + /************************************ set bounds ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + T set_bound_x(const T& x) const + { + return fcn_set_bound(x, rx_front(), rx_back()); + } + + /***************************************************************************************/ + /*********************************** front/back ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx_front() const + { + return gx(ST(0)); + } + + CGPU_EXEC + T gx_back() const + { + return gx(this->nx-1); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx_front() const + { + return rx(ST(0)); + } + + CGPU_EXEC + T rx_back() const + { + return rx(this->nx-1); + } + + /***************************************************************************************/ + /************************************** factors ****************************************/ + /***************************************************************************************/ + // ! calculate fermi low-pass filter alpha parameter + CGPU_EXEC + T fermi_lpf_alpha() const + { + return fcn_fermi_lpf_alpha(gl_max(), T(0.25), T(1e-02)); + } + + CGPU_EXEC + T factor_2pi_rx_ctr(const T& x) const + { + return fcn_n_2pi_sft(x, bs_x_h()); + } + + CPU_EXEC + Vctr factor_2pi_rv_ctr(const Vctr& rv) const + { + Vctr rv_o(rv.size()); + + for(auto ik = 0; ik iregion_rect(const T& r, const T& radius) const + { + return {rx_2_irx_bfds(r - radius), rx_2_irx_bcds(r + radius)}; + } + }; + } + + /* template specialization 2d */ + namespace mt + { + template + class Grid_sxd: public iGrid_sxd + { + public: + using value_type = T; + using size_type = ST; + + T bs_x; // simulation box size along x direction (Angstroms) + T bs_y; // simulation box size along y direction (Angstroms) + + T rx_0; // reference coordinate system along x + T ry_0; // reference coordinate system along y + + dt_bool pbc_x; // peridic boundary condition along x + dt_bool pbc_y; // peridic boundary condition along y + + dt_bool bwl; // band-width limit + + T sli_thick; // slice thicknes + + T drx; // x-sampling in real space + T dry; // y-sampling in real space + + T dgx; // x-sampling in reciprocal space + T dgy; // y-sampling in reciprocal space + + /************************************* constructors ************************************/ + Grid_sxd(): iGrid_sxd(), bs_x(0), bs_y(0), + rx_0(0), ry_0(0), pbc_x(true), pbc_y(true), bwl(false), sli_thick(0), + drx(0), dry(0), dgx(0), dgy(0) {} + + Grid_sxd(const ST& nx, const ST& ny) + { + set_in_data(nx, ny); + } + + template + Grid_sxd(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny) + { + set_in_data(bs_x, bs_y, nx, ny); + } + + template + Grid_sxd(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny, const U& rx_0, const U& ry_0, + dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool bwl = false, U sli_thick = 0.5) + { + set_in_data(bs_x, bs_y, nx, ny, rx_0, ry_0, pbc_x, pbc_y, bwl, sli_thick); + } + + /* copy constructor */ + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /* converting constructor */ + template + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + bs_x = grid.bs_x; + bs_y = grid.bs_y; + rx_0 = grid.rx_0; + ry_0 = grid.ry_0; + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + bwl = grid.bwl; + sli_thick = grid.sli_thick; + + drx = grid.drx; + dry = grid.dry; + dgx = grid.dgx; + dgy = grid.dgy; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + bs_x = T(grid.bs_x); + bs_y = T(grid.bs_y); + rx_0 = T(grid.rx_0); + ry_0 = T(grid.ry_0); + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + bwl = grid.bwl; + sli_thick = T(grid.sli_thick); + + drx = T(grid.drx); + dry = T(grid.dry); + dgx = T(grid.dgx); + dgy = T(grid.dgy); + + return *this; + } + + template + CGPU_EXEC + void assign(const Grid_sxd& grid) + { + *this = grid; + } + + /************************** user define conversion operators ***************************/ + operator iRegion_Rect_xd() const + { + return {ST(0), this->nx, ST(0), this->ny}; + } + + /***************************************************************************************/ + void set_in_data(const ST& nx, const ST& ny) + { + set_in_data(T(nx), T(ny), nx, ny, T(0), T(0)); + } + + template + void set_in_data(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny) + { + set_in_data(T(bs_x), T(bs_y), ST(nx), ST(ny), T(0), T(0)); + } + + template + void set_in_data(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny, + const U& rx_0, const U& ry_0, dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool bwl = false, U sli_thick = 0.5) + { + this->set_size(nx, ny); + + this->bs_x = T(bs_x); + this->bs_y = T(bs_y); + this->rx_0 = T(rx_0); + this->ry_0 = T(ry_0); + this->pbc_x = pbc_x; + this->pbc_y = pbc_y; + this->bwl = bwl; + this->sli_thick = T(sli_thick); + + set_dep_var(); + } + + void set_dep_var() + { + drx = mt::fcn_div(bs_x, this->nx); + dry = mt::fcn_div(bs_y, this->ny); + dgx = mt::fcn_div(T(1), bs_x); + dgy = mt::fcn_div(T(1), bs_y); + } + + CGPU_EXEC + void set_r_0(const T& rx_0, const T& ry_0) + { + this->rx_0 = rx_0; + this->ry_0 = ry_0; + } + + CGPU_EXEC + void set_r_0(const R_2d& r_0) + { + set_r_0(r_0.x, r_0.y); + } + + /***************************************************************************************/ + CGPU_EXEC + T nx_r() const + { + return T(this->nx); + } + + CGPU_EXEC + T ny_r() const + { + return T(this->ny); + } + + CGPU_EXEC + T size_r() const + { + return T(this->size()); + } + + T isize_r() const + { + return T(1)/size_r(); + } + + /***************************************************************************************/ + CGPU_EXEC + T bs_x_h() const + { + return T(0.5)*bs_x; + } + + CGPU_EXEC + T bs_y_h() const + { + return T(0.5)*bs_y; + } + + CGPU_EXEC + R_2d bs_h() const + { + return {bs_x_h(), bs_y_h()}; + } + + /***************************************************************************************/ + CGPU_EXEC + T bs_min() const + { + return ::fmin(bs_x, bs_y); + } + + CGPU_EXEC + T bs_max() const + { + return ::fmax(bs_x, bs_y); + } + + CGPU_EXEC + T bs_h_min() const + { + return T(0.5)*bs_min(); + } + + CGPU_EXEC + T bs_h_max() const + { + return T(0.5)*bs_max(); + } + + CGPU_EXEC + T rx_c() const + { + return rx_0 + bs_x_h(); + } + + CGPU_EXEC + T ry_c() const + { + return ry_0 + bs_y_h(); + } + + CGPU_EXEC + R_2d rv_c() const + { + return {rx_c(), ry_c()}; + } + + /***************************************************************************************/ + // maximum frequency + CGPU_EXEC + T g_max() const + { + return ::fmin(gx_back(), gy_back()); + } + + // maximum square frequency + CGPU_EXEC + T g2_max() const + { + return ::square(g_max()); + } + + // maximum allowed frequency + CGPU_EXEC + T gl_max() const + { + return g_max()*T(2.0/3.0); + } + + // maximum square allowed frequency + CGPU_EXEC + T gl2_max() const + { + return ::square(gl_max()); + } + + CGPU_EXEC + T r_0_min() const + { + return ::fmin(rx_0, ry_0); + } + + CGPU_EXEC + T dr_min() const + { + return ::fmin(drx, dry); + } + + CGPU_EXEC + T dg_min() const + { + return ::fmin(dgx, dgy); + } + + /***************************************************************************************/ + /***************************** Fourier space positions *********************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix) const + { + return T(this->igx(ix))*dgx; + } + + CGPU_EXEC + T gy(const ST& iy) const + { + return T(this->igy(iy))*dgy; + } + + CGPU_EXEC + R_2d gv(const ST& ix, const ST& iy) const + { + return {gx(ix), gy(iy)}; + } + + CGPU_EXEC + T gx2(const ST& ix) const + { + return ::square(gx(ix)); + } + + CGPU_EXEC + T gy2(const ST& iy) const + { + return ::square(gy(iy)); + } + + CGPU_EXEC + T g2(const ST& ix, const ST& iy) const + { + return gx2(ix) + gy2(iy); + } + + CGPU_EXEC + T g(const ST& ix, const ST& iy) const + { + return ::sqrt(g2(ix, iy)); + } + + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix, const T& gx_0) const + { + return gx(ix) - gx_0; + } + + CGPU_EXEC + T gy(const ST& iy, const T& gy_0) const + { + return gy(iy) - gy_0; + } + + CGPU_EXEC + R_2d gv(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return {gx(ix, gx_0), gy(iy, gy_0)}; + } + + CGPU_EXEC + R_2d gv(const ST& ix, const ST& iy, const R_2d& g_0) const + { + return gv(ix, iy, g_0.x, g_0.y); + } + + CGPU_EXEC + T gx2(const ST& ix, const T& gx_0) const + { + return ::square(gx(ix, gx_0)); + } + + CGPU_EXEC + T gy2(const ST& iy, const T& gy_0) const + { + return ::square(gy(iy, gy_0)); + } + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return gx2(ix, gx_0) + gy2(iy, gy_0); + } + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const R_2d& g0) const + { + return gx2(ix, iy, g0.x, g0.y); + } + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return ::sqrt(g2(ix, iy, gx_0, gy_0)); + } + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const R_2d& g0) const + { + return ::sqrt(g2(ix, iy, g0)); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + T gx_sft(const ST& ix) const + { + return T(this->igx_sft(ix))*dgx; + } + + CGPU_EXEC + T gy_sft(const ST& iy) const + { + return T(this->igy_sft(iy))*dgy; + } + + CGPU_EXEC + R_2d gv_sft(const ST& ix, const ST& iy) const + { + return {gx_sft(ix), gy_sft(iy)}; + } + + CGPU_EXEC + T gx2_sft(const ST& ix) const + { + return ::square(gx_sft(ix)); + } + + CGPU_EXEC + T gy2_sft(const ST& iy) const + { + return ::square(gy_sft(iy)); + } + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy) const + { + return gx2_sft(ix) + gy2_sft(iy); + } + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy) const + { + return ::sqrt(g2_sft(ix, iy)); + } + + /***************************************************************************************/ + CGPU_EXEC + T gx_sft(const ST& ix, const T& gx_0) const + { + return gx_sft(ix) - gx_0; + } + + CGPU_EXEC + T gy_sft(const ST& iy, const T& gy_0) const + { + return gy_sft(iy) - gy_0; + } + + CGPU_EXEC + R_2d gv_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return {gx_sft(ix, gx_0), gy_sft(iy, gy_0)}; + } + + CGPU_EXEC + R_2d gv_sft(const ST& ix, const ST& iy, const R_2d& g_0) const + { + return gv_sft(ix, iy, g_0.x, g_0.y); + } + + CGPU_EXEC + T gx2_sft(const ST& ix, const T& gx_0) const + { + return ::square(gx_sft(ix, gx_0)); + } + + CGPU_EXEC + T gy2_sft(const ST& iy, const T& gy_0) const + { + return ::square(gy_sft(iy, gy_0)); + } + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return gx2_sft(ix, gx_0) + gy2_sft(iy, gy_0); + } + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const R_2d& g0) const + { + return g2_sft(ix, iy, g0.z, g0.y); + } + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return ::sqrt(g2_sft(ix, iy, gx_0, gy_0)); + } + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const R_2d& g0) const + { + return ::sqrt(g2_sft(ix, iy, g0)); + } + + /***************************************************************************************/ + /******************************* real space positions **********************************/ + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix) const + { + return T(this->irx(ix))*drx + rx_0; + } + + CGPU_EXEC + T ry(const ST& iy) const + { + return T(this->iry(iy))*dry + ry_0; + } + + CGPU_EXEC + R_2d rv(const ST& ix, const ST& iy) const + { + return {rx(ix), ry(iy)}; + } + + CGPU_EXEC + T rx2(const ST& ix) const + { + return ::square(rx(ix)); + } + + CGPU_EXEC + T ry2(const ST& iy) const + { + return ::square(ry(iy)); + } + + CGPU_EXEC + T r2(const ST& ix, const ST& iy) const + { + return rx2(ix) + ry2(iy); + } + + CGPU_EXEC + T r(const ST& ix, const ST& iy) const + { + return ::sqrt(r2(ix, iy)); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix, const T& x0) const + { + return rx(ix) - x0; + } + + CGPU_EXEC + T ry(const ST& iy, const T& y0) const + { + return ry(iy) - y0; + } + + CGPU_EXEC + R_2d rv(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return {rx(ix, x0), ry(iy, y0)}; + } + + CGPU_EXEC + R_2d rv(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return rv(ix, iy, r_0.x, r_0.y); + } + + CGPU_EXEC + T rx2(const ST& ix, const T& x0) const + { + return ::square(rx(ix, x0)); + } + + CGPU_EXEC + T ry2(const ST& iy, const T& y0) const + { + return ::square(ry(iy, y0)); + } + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return rx2(ix, x0) + ry2(iy, y0); + } + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return r2(ix, iy, r_0.x, r_0.y); + } + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return ::sqrt(r2(ix, iy, x0, y0)); + } + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return ::sqrt(r2(ix, iy, r_0)); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + T rx_sft(const ST& ix) const + { + return T(this->irx_sft(ix))*drx + rx_0; + } + + CGPU_EXEC + T ry_sft(const ST& iy) const + { + return T(this->iry_sft(iy))*dry + ry_0; + } + + CGPU_EXEC + R_2d rv_sft(const ST& ix, const ST& iy) const + { + return {rx_sft(ix), ry_sft(iy)}; + } + + CGPU_EXEC + T rx2_sft(const ST& ix) const + { + return ::square(rx_sft(ix)); + } + + CGPU_EXEC + T ry2_sft(const ST& iy) const + { + return ::square(ry_sft(iy)); + } + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy) const + { + return rx2_sft(ix) + ry2_sft(iy); + } + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy) const + { + return ::sqrt(r2_sft(ix, iy)); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix, const T& x0) const + { + return rx_sft(ix) - x0; + } + + CGPU_EXEC + T ry_sft(const ST& iy, const T& y0) const + { + return ry_sft(iy) - y0; + } + + CGPU_EXEC + R_2d rv_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return {rx_sft(ix, x0), ry_sft(iy, y0)}; + } + + CGPU_EXEC + R_2d rv_sft(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return rv_sft(ix, iy, r_0.x, r_0.y); + } + + CGPU_EXEC + T rx2_sft(const ST& ix, const T& x0) const + { + return ::square(rx_sft(ix, x0)); + } + + CGPU_EXEC + T ry2_sft(const ST& iy, const T& y0) const + { + return ::square(ry_sft(iy, y0)); + } + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return rx2_sft(ix, x0) + ry2_sft(iy, y0); + } + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return r2_sft(ix, iy, r_0.x, r_0.y); + } + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return ::sqrt(r2_sft(ix, iy, x0, y0)); + } + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return ::sqrt(r2_sft(ix, iy, r_0)); + } + + /***************************************************************************************/ + /***************************** from position to index **********************************/ + /***************************************************************************************/ + template + void ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_n); + } + + template + void iy_0_iy_n(const T& y, const T& y_max, SU& iy_0, SU& iy_n) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_n); + } + + template + void ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_e); + ix_e += ix_0; + } + + template + void iy_0_iy_e(const T& y, const T& y_max, SU& iy_0, SU& iy_e) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_e); + iy_e += iy_0; + } + + /************ fds = floor/division by pixel size ************/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fd(const T& x) const + { + return fcn_cfloor(x/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fd(const T& y) const + { + return fcn_cfloor(y/dry); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_fd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_fd(x), ry_2_iry_fd(y)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fd_dr_min(const T& x) const + { + return fcn_cfloor(x/dr_min()); + } + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfd(const T& x) const + { + return fcn_set_bound(rx_2_irx_fd(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfd(const T& y) const + { + return fcn_set_bound(ry_2_iry_fd(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bfd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bfd(x), ry_2_iry_bfd(y)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cd(const T& x) const + { + return fcn_cceil(x/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cd(const T& y) const + { + return fcn_cceil(y/dry); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_cd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_cd(x), ry_2_iry_cd(y)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cd_dr_min(const T& x) const + { + return static_cast(::ceil(x/dr_min())); + } + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcd(const T& x) const + { + return fcn_set_bound(rx_2_irx_cd(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcd(const T& y) const + { + return fcn_set_bound(ry_2_iry_cd(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bcd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bcd(x), ry_2_iry_bcd(y)); + } + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fds(const T& x) const + { + return fcn_cfloor((x - rx_0)/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fds(const T& y) const + { + return fcn_cfloor((y - ry_0)/dry); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_fds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_fds(x), ry_2_iry_fds(y)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fds_dr_min(const T& x) const + { + return fcn_cfloor((x - r_0_min())/dr_min()); + } + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfds(const T& x) const + { + return fcn_set_bound(rx_2_irx_fds(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfds(const T& y) const + { + return fcn_set_bound(ry_2_iry_fds(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bfds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bfds(x), ry_2_iry_bfds(y)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cds(const T& x) const + { + return fcn_cceil((x - rx_0)/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cds(const T& y) const + { + return fcn_cceil((y - ry_0)/dry); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_cds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_cds(x), ry_2_iry_cds(y)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cds_dr_min(const T& x) const + { + return fcn_cceil((x - r_0_min())/dr_min()); + } + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcds(const T& x) const + { + return fcn_set_bound(rx_2_irx_cds(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcds(const T& y) const + { + return fcn_set_bound(ry_2_iry_cds(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bcds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bcds(x), ry_2_iry_bcds(y)); + } + + /************ From position to index by searching ***********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_b(const T& x, ST ix_min=0, ST ix_max=0) const + { + if (ix_min == ix_max) + { + ix_min = ST(0); + ix_max = this->nx-1; + } + + return fcn_r_2_ir_b_by_fcn(rx, ix_min, ix_max); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_b(const T& y, ST iy_min=0, ST iy_max=0) const + { + if (iy_min == iy_max) + { + iy_min = ST(0); + iy_max = this->ny-1; + } + + return fcn_r_2_ir_b_by_fcn(ry, iy_min, iy_max); + } + + /***************************************************************************************/ + /********************************** check bounds ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_front(), rx_back()); + } + + CGPU_EXEC + dt_bool chk_bound_y(const T& y) const + { + return fcn_chk_bound(y, ry_front(), ry_back()); + } + + CGPU_EXEC + dt_bool chk_bound(const R_2d& r) const + { + return chk_bound_x(r.x) && chk_bound_y(r.y); + } + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_front(), rx_back()); + } + + CGPU_EXEC + dt_bool chk_bound_y_eps(const T& y) const + { + return fcn_chk_bound_eps(y, ry_front(), ry_back()); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const R_2d& r) const + { + return chk_bound_x_eps(r.x) && chk_bound_y_eps(r.y); + } + + /***************************************************************************************/ + /*********************************** set bounds ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T set_bound_x(const T& x) const + { + return fcn_set_bound(x, rx_front(), rx_back()); + } + + CGPU_EXEC + T set_bound_y(const T& y) const + { + return fcn_set_bound(y, ry_front(), ry_back()); + } + + CGPU_EXEC + R_2d set_bound(const R_2d& r) const + { + return {set_bound_x(r.x), set_bound_y(r.y)}; + } + + /***************************************************************************************/ + /************************************ front/back ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx_front() const + { + return gx(ST(0)); + } + + CGPU_EXEC + T gx_back() const + { + return gx(this->nx-1); + } + + CGPU_EXEC + T gy_front() const + { + return gy(ST(0)); + } + + CGPU_EXEC + T gy_back() const + { + return gy(this->ny-1); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx_front() const + { + return rx(ST(0)); + } + + CGPU_EXEC + T rx_back() const + { + return rx(this->nx-1); + } + + CGPU_EXEC + T ry_front() const + { + return ry(ST(0)); + } + + CGPU_EXEC + T ry_back() const + { + return ry(this->ny-1); + } + + /***************************************************************************************/ + /*********************************** factors *******************************************/ + // ! calculate fermi low-pass filter alpha parameter + CGPU_EXEC + T fermi_lpf_alpha() const + { + return fcn_fermi_lpf_alpha(gl_max(), T(0.25), T(1e-02)); + } + + CGPU_EXEC + T factor_2pi_rx_ctr(const T& x) const + { + return fcn_n_2pi_sft(x, bs_x_h()); + } + + CGPU_EXEC + T factor_2pi_ry_ctr(const T& y) const + { + return fcn_n_2pi_sft(y, bs_y_h()); + } + + CGPU_EXEC + R_2d factor_2pi_rv_ctr(const R_2d& r) const + { + return {factor_2pi_rx_ctr(r.x), factor_2pi_ry_ctr(r.y)}; + } + + CPU_EXEC + Vctr, edev_cpu> factor_2pi_rv_ctr(const Vctr, edev_cpu>& rv) const + { + Vctr, edev_cpu> rv_o(rv.size()); + + for(auto ik = 0; ik iregion_rect(const R_2d& r, const T& radius) const + { + return {rx_2_irx_bfds(r.x - radius), rx_2_irx_bcds(r.x + radius), ry_2_iry_bfds(r.y - radius), ry_2_iry_bcds(r.y + radius)}; + } + + iRegion_Rect_xd iregion_rect(const R_2d& r, const T& f0, const T& a, const T& b, const T& c) + { + const T d = log(f0); + const T dd = c*c-T(4)*a*b; + + const T radius_x = ::sqrt(T(4)*b*d/dd); + const T radius_y = ::sqrt(T(4)*a*d/dd); + + return {rx_2_irx_bfds(r.x - radius_x), rx_2_irx_bcds(r.x + radius_x), ry_2_iry_bfds(r.y - radius_y), ry_2_iry_bcds(r.y + radius_y)}; + } + }; + } + + /* template specialization n3d */ + namespace mt + { + template + class Grid_sxd: public iGrid_sxd + { + public: + using value_type = T; + using size_type = ST; + + T bs_x; // simulation box size along x direction (Angstroms) + T bs_y; // simulation box size along y direction (Angstroms) + T bs_z; // simulation box size along z direction (Angstroms) + + T rx_0; // reference coordinate system along x + T ry_0; // reference coordinate system along y + T rz_0; // reference coordinate system along z + + dt_bool pbc_x; // peridic boundary condition along x + dt_bool pbc_y; // peridic boundary condition along y + dt_bool pbc_z; // peridic boundary condition along z + + dt_bool bwl; // band-width limit + + T sli_thick; // slice thicknes + + T drx; // x-sampling in real space + T dry; // y-sampling in real space + T drz; // z-sampling in real space + + T dgx; // x-sampling in reciprocal space + T dgy; // y-sampling in reciprocal space + T dgz; // z-sampling in reciprocal space + + /************************************* constructors ************************************/ + Grid_sxd(): iGrid_sxd(), bs_x(0), bs_y(0), bs_z(0), + rx_0(0), ry_0(0), rz_0(0), pbc_x(true), pbc_y(true), pbc_z(true), bwl(false), sli_thick(0), + drx(0), dry(0), drz(0), dgx(0), dgy(0), dgz(0){} + + Grid_sxd(const ST& nx, const ST& ny, const ST& nz) + { + set_in_data(nx, ny, nz); + } + + template + Grid_sxd(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const ST& nz) + { + set_in_data(bs_x, bs_y, bs_z, nx, ny, nz); + } + + template + Grid_sxd(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz, + const U& rx_0, const U& ry_0, const U& rz_0, dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool pbc_z = true, dt_bool bwl = false, U sli_thick = 0.5) + { + set_in_data(bs_x, bs_y, bs_z, nx, ny, nz, rx_0, ry_0, rz_0, pbc_x, pbc_y, pbc_z, bwl, sli_thick); + } + + /* copy constructor */ + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /* converting constructor */ + template + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + bs_x = grid.bs_x; + bs_y = grid.bs_y; + bs_z = grid.bs_z; + rx_0 = grid.rx_0; + ry_0 = grid.ry_0; + rz_0 = grid.rz_0; + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + pbc_z = grid.pbc_z; + bwl = grid.bwl; + sli_thick = grid.sli_thick; + + drx = grid.drx; + dry = grid.dry; + drz = grid.drz; + dgx = grid.dgx; + dgy = grid.dgy; + dgz = grid.dgz; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + bs_x = T(grid.bs_x); + bs_y = T(grid.bs_y); + bs_z = T(grid.bs_z); + rx_0 = T(grid.rx_0); + ry_0 = T(grid.ry_0); + rz_0 = T(grid.rz_0); + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + pbc_z = grid.pbc_z; + bwl = grid.bwl; + sli_thick = T(grid.sli_thick); + + drx = T(grid.drx); + dry = T(grid.dry); + drz = T(grid.drz); + dgx = T(grid.dgx); + dgy = T(grid.dgy); + dgz = T(grid.dgz); + + return *this; + } + + template + CGPU_EXEC + void assign(const Grid_sxd& grid) + { + *this = grid; + } + + /**************** user define conversion operators *******************/ + operator iRegion_Rect_xd() const + { + return {ST(0), this->nx, ST(0), this->ny, ST(0), this->nz}; + } + + /***************************************************************************************/ + void set_in_data(const ST& nx, const ST& ny, const ST& nz) + { + set_in_data(T(nx), T(ny), T(nz), nx, ny, nz, T(0), T(0), T(0)); + } + + template + void set_in_data(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz) + { + set_in_data(T(bs_x), T(bs_y), T(bs_z), ST(nx), ST(ny), ST(nz), T(0), T(0), T(0)); + } + + template + void set_in_data(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz, + const U& rx_0, const U& ry_0, const U& rz_0, dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool pbc_z = true, dt_bool bwl = false, U sli_thick = 0.5) + { + this->set_size(nx, ny, nz); + + this->bs_x = T(bs_x); + this->bs_y = T(bs_y); + this->bs_z = T(bs_z); + this->rx_0 = T(rx_0); + this->ry_0 = T(ry_0); + this->rz_0 = T(rz_0); + this->pbc_x = pbc_x; + this->pbc_y = pbc_y; + this->pbc_z = pbc_z; + this->bwl = bwl; + this->sli_thick = T(sli_thick); + + set_dep_var(); + } + + void set_dep_var() + { + drx = mt::fcn_div(bs_x, this->nx); + dry = mt::fcn_div(bs_y, this->ny); + drz = mt::fcn_div(bs_z, this->nz); + dgx = mt::fcn_div(T(1), bs_x); + dgy = mt::fcn_div(T(1), bs_y); + dgz = mt::fcn_div(T(1), bs_z); + } + + CGPU_EXEC + void set_r_0(const T& rx_0, const T& ry_0, const T& rz_0) + { + this->rx_0 = rx_0; + this->ry_0 = ry_0; + this->rz_0 = rz_0; + } + + CGPU_EXEC + void set_r_0(const R_3d& r_0) + { + set_r_0(r_0.x, r_0.y, r_0.z); + } + + /***************************************************************************************/ + CGPU_EXEC + T nx_r() const + { + return T(this->nx); + } + + CGPU_EXEC + T ny_r() const + { + return T(this->ny); + } + + CGPU_EXEC + T nz_r() const + { + return T(this->nz); + } + + CGPU_EXEC + T size_r() const + { + return T(this->size()); + } + + T isize_r() const + { + return T(1)/size_r(); + } + + /***************************************************************************************/ + CGPU_EXEC + T bs_x_h() const + { + return T(0.5)*bs_x; + } + + CGPU_EXEC + T bs_y_h() const + { + return T(0.5)*bs_y; + } + + CGPU_EXEC + T bs_z_h() const + { + return T(0.5)*bs_z; + } + + CGPU_EXEC + R_3d bs_h() const + { + return {bs_x_h(), bs_y_h(), bs_z_h()}; + } + + /***************************************************************************************/ + CGPU_EXEC + T bs_min() const + { + return ::fmin(bs_x, ::fmin(bs_y, bs_z)); + } + + CGPU_EXEC + T bs_max() const + { + return ::fmax(bs_x, ::fmax(bs_y, bs_z)); + } + + CGPU_EXEC + T bs_h_min() const + { + return T(0.5)*bs_min(); + } + + CGPU_EXEC + T bs_h_max() const + { + return T(0.5)*bs_max(); + } + + CGPU_EXEC + T rx_c() const + { + return rx_0 + bs_x_h(); + } + + CGPU_EXEC + T ry_c() const + { + return ry_0 + bs_y_h(); + } + + CGPU_EXEC + T rz_c() const + { + return rz_0 + bs_z_h(); + } + + CGPU_EXEC + R_3d rv_c() const + { + return {rx_c(), ry_c(), rz_c()}; + } + + /***************************************************************************************/ + // maximum frequency + CGPU_EXEC + T g_max() const + { + return ::fmin(gx_back(), ::fmin(gy_back(), gz_back())); + } + + // maximum square frequency + CGPU_EXEC + T g2_max() const + { + return ::square(g_max()); + } + + // maximum allowed frequency + CGPU_EXEC + T gl_max() const + { + return g_max()*T(2.0/3.0); + } + + // maximum square allowed frequency + CGPU_EXEC + T gl2_max() const + { + return ::square(gl_max()); + } + + CGPU_EXEC + T r_0_min() const + { + return ::fmin(rx_0, ::fmin(ry_0, rz_0)); + } + + CGPU_EXEC + T dr_min() const + { + return ::fmin(drx, ::fmin(dry, drz)); + } + + CGPU_EXEC + T dg_min() const + { + return ::fmin(dgx, ::fmin(dgy, dgz)); + } + + /***************************************************************************************/ + /********************** Fourier space positions **********************/ + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix) const + { + return T(this->igx(ix))*dgx; + } + + CGPU_EXEC + T gy(const ST& iy) const + { + return T(this->igy(iy))*dgy; + } + + CGPU_EXEC + T gz(const ST& iz) const + { + return T(this->igz(iz))*dgz; + } + + CGPU_EXEC + R_3d gv(const ST& ix, const ST& iy, const ST& iz) const + { + return {gx(ix), gy(iy), gz(iz)}; + } + + CGPU_EXEC + T gx2(const ST& ix) const + { + return ::square(gx(ix)); + } + + CGPU_EXEC + T gy2(const ST& iy) const + { + return ::square(gy(iy)); + } + + CGPU_EXEC + T gz2(const ST& iz) const + { + return ::square(gz(iz)); + } + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const ST& iz) const + { + return gx2(ix) + gy2(iy) + gz2(iz); + } + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(g2(ix, iy, iz)); + } + + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix, const T& gx_0) const + { + return gx(ix) - gx_0; + } + + CGPU_EXEC + T gy(const ST& iy, const T& gy_0) const + { + return gy(iy) - gy_0; + } + + CGPU_EXEC + T gz(const ST& iz, const T& gz_0) const + { + return gz(iz) - gz_0; + } + + CGPU_EXEC + R_3d gv(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return {gx(ix, gx_0), gy(iy, gy_0), gz(iz, gz_0)}; + } + + CGPU_EXEC + R_3d gv(const ST& ix, const ST& iy, const ST& iz, const R_3d& g_0) const + { + return gv(ix, iy, iz, g_0.x, g_0.y, g_0.z); + } + + CGPU_EXEC + T gx2(const ST& ix, const T& gx_0) const + { + return ::square(gx(ix, gx_0)); + } + + CGPU_EXEC + T gy2(const ST& iy, const T& gy_0) const + { + return ::square(gy(iy, gy_0)); + } + + CGPU_EXEC + T gz2(const ST& iz, const T& gz_0) const + { + return ::square(gz(iz, gz_0)); + } + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return gx2(ix, gx_0) + gy2(iy, gy_0) + gz2(iz, gz_0); + } + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return g2(ix, iy, iz, g0.x, g0.y, g0.z); + } + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return ::sqrt(g2(ix, iy, iz, gx_0, gy_0, gz_0)); + } + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return ::sqrt(g2(ix, iy, iz, g0)); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + T gx_sft(const ST& ix) const + { + return T(this->igx_sft(ix))*dgx; + } + + CGPU_EXEC + T gy_sft(const ST& iy) const + { + return T(this->igy_sft(iy))*dgy; + } + + CGPU_EXEC + T gz_sft(const ST& iz) const + { + return T(this->igz_sft(iz))*dgz; + } + + CGPU_EXEC + R_3d gv_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return {gx_sft(ix), gy_sft(iy), gz_sft(iz)}; + } + + CGPU_EXEC + T gx2_sft(const ST& ix) const + { + return ::square(gx_sft(ix)); + } + + CGPU_EXEC + T gy2_sft(const ST& iy) const + { + return ::square(gy_sft(iy)); + } + + CGPU_EXEC + T gz2_sft(const ST& iz) const + { + return ::square(gz_sft(iz)); + } + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return gx2_sft(ix) + gy2_sft(iy) + gz2_sft(iz); + } + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(g2_sft(ix, iy, iz)); + } + + /***************************************************************************************/ + CGPU_EXEC + T gx_sft(const ST& ix, const T& gx_0) const + { + return gx_sft(ix) - gx_0; + } + + CGPU_EXEC + T gy_sft(const ST& iy, const T& gy_0) const + { + return gy_sft(iy) - gy_0; + } + + CGPU_EXEC + T gz_sft(const ST& iz, const T& gz_0) const + { + return gz_sft(iz) - gz_0; + } + + CGPU_EXEC + R_3d gv_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return {gx_sft(ix, gx_0), gy_sft(iy, gy_0), gz_sft(iz, gz_0)}; + } + + CGPU_EXEC + R_3d gv_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g_0) const + { + return gv_sft(ix, iy, iz, g_0.x, g_0.y, g_0.z); + } + + CGPU_EXEC + T gx2_sft(const ST& ix, const T& gx_0) const + { + return ::square(gx_sft(ix, gx_0)); + } + + CGPU_EXEC + T gy2_sft(const ST& iy, const T& gy_0) const + { + return ::square(gy_sft(iy, gy_0)); + } + + CGPU_EXEC + T gz2_sft(const ST& iz, const T& gz_0) const + { + return ::square(gz_sft(iz, gz_0)); + } + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return gx2_sft(ix, gx_0) + gy2_sft(iy, gy_0) + gz2_sft(iz, gz_0); + } + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return g2_sft(ix, iy, iz, g0.x, g0.y, g0.z); + } + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return ::sqrt(g2_sft(ix, iy, iz, gx_0, gy_0, gz_0)); + } + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return ::sqrt(g2_sft(ix, iy, iz, g0)); + } + + /***************************************************************************************/ + /************************ real space positions ***********************/ + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix) const + { + return T(this->irx(ix))*drx + rx_0; + } + + CGPU_EXEC + T ry(const ST& iy) const + { + return T(this->iry(iy))*dry + ry_0; + } + + CGPU_EXEC + T rz(const ST& iz) const + { + return T(this->irz(iz))*drz + rz_0; + } + + CGPU_EXEC + R_3d rv(const ST& ix, const ST& iy, const ST& iz) const + { + return {rx(ix), ry(iy), rz(iz)}; + } + + CGPU_EXEC + T rx2(const ST& ix) const + { + return ::square(rx(ix)); + } + + CGPU_EXEC + T ry2(const ST& iy) const + { + return ::square(ry(iy)); + } + + CGPU_EXEC + T rz2(const ST& iz) const + { + return ::square(rz(iz)); + } + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const ST& iz) const + { + return rx2(ix) + ry2(iy) + rz2(iz); + } + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(r2(ix, iy, iz)); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix, const T& x0) const + { + return rx(ix) - x0; + } + + CGPU_EXEC + T ry(const ST& iy, const T& y0) const + { + return ry(iy) - y0; + } + + CGPU_EXEC + T rz(const ST& iz, const T& z0) const + { + return rz(iz) - z0; + } + + CGPU_EXEC + R_3d rv(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return {rx(ix, x0), ry(iy, y0), rz(iz, z0)}; + } + + CGPU_EXEC + R_3d rv(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return rv(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + CGPU_EXEC + T rx2(const ST& ix, const T& x0) const + { + return ::square(rx(ix, x0)); + } + + CGPU_EXEC + T ry2(const ST& iy, const T& y0) const + { + return ::square(ry(iy, y0)); + } + + CGPU_EXEC + T rz2(const ST& iz, const T& z0) const + { + return ::square(rz(iz, z0)); + } + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return rx2(ix, x0) + ry2(iy, y0) + rz2(iz, z0); + } + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return r2(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return ::sqrt(r2(ix, iy, iz, x0, y0, z0)); + } + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return ::sqrt(r2(ix, iy, iz, r_0)); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + T rx_sft(const ST& ix) const + { + return T(this->irx_sft(ix))*drx + rx_0; + } + + CGPU_EXEC + T ry_sft(const ST& iy) const + { + return T(this->iry_sft(iy))*dry + ry_0; + } + + CGPU_EXEC + T rz_sft(const ST& iz) const + { + return T(this->irz_sft(iz))*drz + rz_0; + } + + CGPU_EXEC + R_3d rv_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return {rx_sft(ix), ry_sft(iy), rz_sft(iz)}; + } + + CGPU_EXEC + T rx2_sft(const ST& ix) const + { + return ::square(rx_sft(ix)); + } + + CGPU_EXEC + T ry2_sft(const ST& iy) const + { + return ::square(ry_sft(iy)); + } + + CGPU_EXEC + T rz2_sft(const ST& iz) const + { + return ::square(rz_sft(iz)); + } + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return rx2_sft(ix) + ry2_sft(iy) + rz2_sft(iz); + } + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(r2_sft(ix, iy, iz)); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix, const T& x0) const + { + return rx_sft(ix) - x0; + } + + CGPU_EXEC + T ry_sft(const ST& iy, const T& y0) const + { + return ry_sft(iy) - y0; + } + + CGPU_EXEC + T rz_sft(const ST& iz, const T& z0) const + { + return rz_sft(iz) - z0; + } + + CGPU_EXEC + R_3d rv_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return {rx_sft(ix, x0), ry_sft(iy, y0), rz_sft(iz, z0)}; + } + + CGPU_EXEC + R_3d rv_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return rv_sft(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + CGPU_EXEC + T rx2_sft(const ST& ix, const T& x0) const + { + return ::square(rx_sft(ix, x0)); + } + + CGPU_EXEC + T ry2_sft(const ST& iy, const T& y0) const + { + return ::square(ry_sft(iy, y0)); + } + + CGPU_EXEC + T rz2_sft(const ST& iz, const T& z0) const + { + return ::square(rz_sft(iz, z0)); + } + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return rx2_sft(ix, x0) + ry2_sft(iy, y0) + rz2_sft(iz, z0); + } + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return r2_sft(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return ::sqrt(r2_sft(ix, iy, iz, x0, y0, z0)); + } + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return ::sqrt(r2_sft(ix, iy, iz, r_0)); + } + + /***************************************************************************************/ + /******************** from position to index *************************/ + /***************************************************************************************/ + template + void ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_n); + } + + template + void iy_0_iy_n(const T& y, const T& y_max, SU& iy_0, SU& iy_n) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_n); + } + + template + void iz_0_iz_n(const T& z, const T& z_max, SU& iz_0, SU& iz_n) const + { + fcn_get_idx_0_idx_n(z, z_max, drz, pbc_z, this->nz-1, iz_0, iz_n); + } + + template + void ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_e); + ix_e += ix_0; + } + + template + void iy_0_iy_e(const T& y, const T& y_max, SU& iy_0, SU& iy_e) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_e); + iy_e += iy_0; + } + + template + void iz_0_iz_e(const T& z, const T& z_max, SU& iz_0, SU& iz_e) const + { + fcn_get_idx_0_idx_n(z, z_max, drz, pbc_z, this->nz-1, iz_0, iz_e); + iz_e += iz_0; + } + + /*************** fds = floor/division by pixel size ******************/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fd(const T& x) const + { + return fcn_cfloor(x/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fd(const T& y) const + { + return fcn_cfloor(y/dry); + } + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_fd(const T& z) const + { + return fcn_cfloor(z/drz); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_fd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_fd(x), ry_2_iry_fd(y), rz_2_irz_fd(z)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fd_dr_min(const T& x) const + { + return fcn_cfloor(x/dr_min()); + } + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfd(const T& x) const + { + return fcn_set_bound(rx_2_irx_fd(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfd(const T& y) const + { + return fcn_set_bound(ry_2_iry_fd(y), ST(0), this->ny-1); + } + + // locate z-> irz + CGPU_EXEC + ST rz_2_irz_bfd(const T& z) const + { + return fcn_set_bound(rz_2_irz_fd(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bfd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bfd(x), ry_2_iry_bfd(y), rz_2_irz_bfd(z)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cd(const T& x) const + { + return fcn_cceil(x/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cd(const T& y) const + { + return fcn_cceil(y/dry); + } + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_cd(const T& z) const + { + return fcn_cceil(z/drz); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_cd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_cd(x), ry_2_iry_cd(y), rz_2_irz_cd(z)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cd_dr_min(const T& x) const + { + return static_cast(::ceil(x/dr_min())); + } + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcd(const T& x) const + { + return fcn_set_bound(rx_2_irx_cd(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcd(const T& y) const + { + return fcn_set_bound(ry_2_iry_cd(y), ST(0), this->ny-1); + } + + // locate z -> iry + CGPU_EXEC + ST rz_2_irz_bcd(const T& z) const + { + return fcn_set_bound(rz_2_irz_cd(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bcd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bcd(x), ry_2_iry_bcd(y), rz_2_irz_bcd(z)); + } + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fds(const T& x) const + { + return fcn_cfloor((x - rx_0)/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fds(const T& y) const + { + return fcn_cfloor((y - ry_0)/dry); + } + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_fds(const T& z) const + { + return fcn_cfloor((z - rz_0)/drz); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_fds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_fds(x), ry_2_iry_fds(y), rz_2_irz_fds(z)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fds_dr_min(const T& x) const + { + return fcn_cfloor((x - r_0_min())/dr_min()); + } + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfds(const T& x) const + { + return fcn_set_bound(rx_2_irx_fds(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfds(const T& y) const + { + return fcn_set_bound(ry_2_iry_fds(y), ST(0), this->ny-1); + } + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_bfds(const T& z) const + { + return fcn_set_bound(rz_2_irz_fds(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bfds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bfds(x), ry_2_iry_bfds(y), rz_2_irz_bfds(z)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cds(const T& x) const + { + return fcn_cceil((x - rx_0)/drx); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cds(const T& y) const + { + return fcn_cceil((y - ry_0)/dry); + } + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_cds(const T& z) const + { + return fcn_cceil((z - rz_0)/drz); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_cds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_cds(x), ry_2_iry_cds(y), rz_2_irz_cds(z)); + } + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cds_dr_min(const T& x) const + { + return fcn_cceil((x - r_0_min())/dr_min()); + } + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcds(const T& x) const + { + return fcn_set_bound(rx_2_irx_cds(x), ST(0), this->nx-1); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcds(const T& y) const + { + return fcn_set_bound(ry_2_iry_cds(y), ST(0), this->ny-1); + } + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_bcds(const T& z) const + { + return fcn_set_bound(rz_2_irz_cds(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bcds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bcds(x), ry_2_iry_bcds(y), rz_2_irz_bcds(z)); + } + + /************ From position to index by searching ***********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_b(const T& x, ST ix_min=0, ST ix_max=0) const + { + if (ix_min == ix_max) + { + ix_min = ST(0); + ix_max = this->nx-1; + } + + return fcn_r_2_ir_b_by_fcn(rx, ix_min, ix_max); + } + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_b(const T& y, ST iy_min=0, ST iy_max=0) const + { + if (iy_min == iy_max) + { + iy_min = ST(0); + iy_max = this->ny-1; + } + + return fcn_r_2_ir_b_by_fcn(ry, iy_min, iy_max); + } + + // locate z-> irz + CGPU_EXEC + ST rz_2_irz_b(const T& z, ST iz_min=0, ST iz_max=0) const + { + if (iz_min == iz_max) + { + iz_min = ST(0); + iz_max = this->nz-1; + } + + return fcn_r_2_ir_b_by_fcn(rz, iz_min, iz_max); + } + + /***************************************************************************************/ + /********************************* check bounds ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_front(), rx_back()); + } + + CGPU_EXEC + dt_bool chk_bound_y(const T& y) const + { + return fcn_chk_bound(y, ry_front(), ry_back()); + } + + CGPU_EXEC + dt_bool chk_bound_z(const T& z) const + { + return fcn_chk_bound(z, rz_front(), rz_back()); + } + + CGPU_EXEC + dt_bool chk_bound(const R_3d& r) const + { + return chk_bound_x(r.x) && chk_bound_y(r.y) && chk_bound_z(r.z); + } + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_front(), rx_back()); + } + + CGPU_EXEC + dt_bool chk_bound_y_eps(const T& y) const + { + return fcn_chk_bound_eps(y, ry_front(), ry_back()); + } + + CGPU_EXEC + dt_bool chk_bound_z_eps(const T& z) const + { + return fcn_chk_bound_eps(z, rz_front(), rz_back()); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const R_3d& r) const + { + return chk_bound_x_eps(r.x) && chk_bound_y_eps(r.y) && chk_bound_z_eps(r.z); + } + + /***************************************************************************************/ + /*********************************** set bounds ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T set_bound_x(const T& x) const + { + return fcn_set_bound(x, rx_front(), rx_back()); + } + + CGPU_EXEC + T set_bound_y(const T& y) const + { + return fcn_set_bound(y, ry_front(), ry_back()); + } + + CGPU_EXEC + T set_bound_z(const T& z) const + { + return fcn_set_bound(z, rz_front(), rz_back()); + } + + CGPU_EXEC + R_3d set_bound(const R_3d& r) const + { + return {set_bound_x(r.x), set_bound_y(r.y), set_bound_z(r.z)}; + } + + /***************************************************************************************/ + /*********************************** front/back ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx_front() const + { + return gx(ST(0)); + } + + CGPU_EXEC + T gx_back() const + { + return gx(this->nx-1); + } + + CGPU_EXEC + T gy_front() const + { + return gy(ST(0)); + } + + CGPU_EXEC + T gy_back() const + { + return gy(this->ny-1); + } + + CGPU_EXEC + T gz_front() const + { + return gz(ST(0)); + } + + CGPU_EXEC + T gz_back() const + { + return gz(this->nz-1); + } + + /***************************************************************************************/ + CGPU_EXEC + T rx_front() const + { + return rx(ST(0)); + } + + CGPU_EXEC + T rx_back() const + { + return rx(this->nx-1); + } + + CGPU_EXEC + T ry_front() const + { + return ry(ST(0)); + } + + CGPU_EXEC + T ry_back() const + { + return ry(this->ny-1); + } + + CGPU_EXEC + T rz_front() const + { + return rz(ST(0)); + } + + CGPU_EXEC + T rz_back() const + { + return rz(this->nz-1); + } + + /***************************************************************************************/ + /************************************* factors *****************************************/ + /***************************************************************************************/ + // ! calculate fermi low-pass filter alpha parameter + CGPU_EXEC + T fermi_lpf_alpha() const + { + return fcn_fermi_lpf_alpha(gl_max(), T(0.25), T(1e-02)); + } + + CGPU_EXEC + T factor_2pi_rx_ctr(const T& x) const + { + return fcn_n_2pi_sft(x, bs_x_h()); + } + + CGPU_EXEC + T factor_2pi_ry_ctr(const T& y) const + { + return fcn_n_2pi_sft(y, bs_y_h()); + } + + CGPU_EXEC + T factor_2pi_rz_ctr(const T& z) const + { + return fcn_n_2pi_sft(z, bs_z_h()); + } + + CGPU_EXEC + R_3d factor_2pi_rv_ctr(const R_3d& r) const + { + return {factor_2pi_rx_ctr(r.x), factor_2pi_ry_ctr(r.y), factor_2pi_rz_ctr(r.z)}; + } + + CPU_EXEC + Vctr, edev_cpu> factor_2pi_rv_ctr(const Vctr, edev_cpu>& rv) const + { + Vctr, edev_cpu> rv_o(rv.size()); + + for(auto ik = 0; ik iregion_rect(const R_3d& r, const T& radius) const + { + return {rx_2_irx_bfds(r.x - radius), rx_2_irx_bcds(r.x + radius), ry_2_iry_bfds(r.y - radius), + ry_2_iry_bcds(r.y + radius), rz_2_irz_bfds(r.z - radius), rz_2_irz_bcds(r.z + radius)}; + } + + iRegion_Rect_xd iregion_rect(const R_3d& r, const T& f0, const T& a, const T& b, const T& c) + { + const T d = log(f0); + const T dd = c*c-T(4)*a*b; + + const T radius_x = ::sqrt(T(4)*b*d/dd); + const T radius_y = ::sqrt(T(4)*a*d/dd); + const T radius_z = ::sqrt(T(4)*a*d/dd); + + return {nrx_2_irx_bfds(r.x - radius_x), rx_2_irx_bcds(r.x + radius_x), ry_2_iry_bfds(r.y - radius_y), + ry_2_iry_bcds(r.y + radius_y), rz_2_irz_bfds(r.z - radius_z), rz_2_irz_bcds(r.z + radius_z)}; + } + }; + } + + /* traits */ + namespace mt + { + template + struct is_grid_1d: std::integral_constant>::value> {}; + + template + struct is_grid_2d: std::integral_constant>::value> {}; + + template + struct is_grid_3d: std::integral_constant>::value> {}; + + template + struct is_grid: std::integral_constant::value && is_grid_2d::value && is_grid_3d::value> {}; + + /***************************************************************************************/ + template + struct is_grid_1d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_1d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + template + struct is_grid_2d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_2d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + template + struct is_grid_3d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_3d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + template + struct is_grid_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_grid_1d_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_1d_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + template + struct is_grid_2d_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_2d_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + template + struct is_grid_3d_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_3d_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + template + struct is_grid_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_grid_1d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_1d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_2d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_2d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_3d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_3d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_nd_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_nd_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_grid_1d_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_1d_and_cvctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_2d_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_2d_and_cvctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_3d_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_3d_and_cvctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_nd_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_nd_and_cvctr_gpu = typename std::enable_if::value, V>::type; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/host_device_classes.cuh b/src - Copy (2)/host_device_classes.cuh new file mode 100755 index 00000000..9828001d --- /dev/null +++ b/src - Copy (2)/host_device_classes.cuh @@ -0,0 +1,2796 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef HOST_DEVICE_CLASSES_H +#define HOST_DEVICE_CLASSES_H + +#include "math.cuh" +#include "types.cuh" +#include "traits.cuh" +#include "stream.cuh" +#include "fft.cuh" +#include "random.cuh" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +#include "host_device_functions.cuh" +#include "host_functions.hpp" + +#ifdef __CUDACC__ + #include "device_functions.cuh" +#endif +namespace mt +{ + /**************** Gaussian Conv ***************/ + template + class Gauss_Cv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Cv_1d():fft_1d(nullptr){} + + Gauss_Cv_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, TVector_c &Im) + { + fft1_shift(grid_1d, Im); + fft_1d->forward(Im); + + gauss_cv_1d(sigma_r, Im); + + fft_1d->inverse(Im); + fft1_shift(grid_1d, Im); + } + + void operator()(T sigma_r, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_1d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + for (auto ix = 0; ix < grid_1d.nx; ix++) + { + host_device_detail::gauss_cv_1d, TVector_c>(ix, grid_1d, alpha, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_1d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_1d.cuda_grid(); + device_detail::gauss_cv_1d, typename TVector_c::value_type><<>>(grid_1d, alpha, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Cv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Cv_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Gauss_Cv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVector_c &Im) + { + fft2_sft_bc(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, Im); + + fft_2d->inverse(Im); + fft2_sft_bc(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vector gauss_vector_1d(T alpha) + { + TVector_r fg; + fg.reserve(grid_2d.ny); + + for (auto iy=0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_shift(iy))/grid_2d.ny_r(); + fg.push_back(v); + } + return fg; + } + + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_2d_bc(T sigma_r, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::vector_col_x_matrix, TVector_r, TVector_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_2d_bc(T sigma_r, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha); + TVector_r fg = fg_h; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::vector_col_x_matrix, typename TVector_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Cv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Cv_2d():stream(nullptr), fft_2d(nullptr){} + + Gauss_Cv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVector_c &Im) + { + fft2_shift(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d(sigma_r, Im); + + fft_2d->inverse(Im); + fft2_shift(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_2d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::gauss_cv_2d, TVector_c>, grid_2d, alpha, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_2d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::gauss_cv_2d, typename TVector_c::value_type><<>>(grid_2d, alpha, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /**************** Gaussian Deconv ***************/ + template + class Gauss_Dcv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Dcv_1d():fft_1d(nullptr){} + + Gauss_Dcv_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, T PSNR, TVector_c &Im) + { + fft1_shift(grid_1d, Im); + fft_1d->forward(Im); + + gauss_dcv_1d(sigma_r, PSNR, Im); + + fft_1d->inverse(Im); + fft1_shift(grid_1d, Im); + } + + void operator()(T sigma_r, T PSNR, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_dcv_1d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + for (auto ix = 0; ix < grid_1d.nx; ix++) + { + host_device_detail::gauss_dcv_1d, TVector_c>(ix, grid_1d, alpha, PSNR, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_dcv_1d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_1d.cuda_grid(); + device_detail::gauss_dcv_1d, typename TVector_c::value_type><<>>(grid_1d, alpha, PSNR, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Dcv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Dcv_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Gauss_Dcv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVector_c &Im) + { + fft2_sft_bc(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fft2_sft_bc(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vector gauss_vector_1d(T alpha, T PSNR) + { + TVector_r fg; + fg.reserve(grid_2d.ny); + + for (auto iy=0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_shift(iy)); + fg.push_back(v/((v*v+PSNR)*grid_2d.ny_r())); + } + return fg; + } + + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_2d_bc(T sigma_r, T PSNR, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha, PSNR); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::vector_col_x_matrix, TVector_r, TVector_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_2d_bc(T sigma_r, T PSNR, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha, PSNR); + TVector_r fg = fg_h; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::vector_col_x_matrix, typename TVector_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Dcv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Dcv_2d():stream(nullptr), fft_2d(nullptr){} + + Gauss_Dcv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVector_c &Im) + { + fft2_shift(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_dcv_2d(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fft2_shift(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_dcv_2d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::gauss_dcv_2d, TVector_c>, grid_2d, alpha, PSNR, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_dcv_2d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::gauss_dcv_2d, typename TVector_c::value_type><<>>(grid_2d, alpha, PSNR, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /****************Gauss_Spt***************/ + template + class Gauss_Spt + { + public: + using T_r = T; + using TVector_r = Vector; + + using size_type = std::size_t; + + static const eDevice device = dev; + + Gauss_Spt(): input_gauss_spt(nullptr), stream(nullptr), n_atoms_p(512){} + + void set_input_data(Input_Gauss_Spt *input_gauss_spt_i, Stream *stream_i) + { + input_gauss_spt = input_gauss_spt_i; + stream = stream_i; + + n_atoms_p = (device==e_host)?(stream->size()):512; + + if(device==e_host) + { + int nv = input_gauss_spt->get_nv(); + stream_data.resize(n_atoms_p); + for(auto i = 0; i + enable_if_dev_host + operator()(TVector_r &Im) + { + auto gauss_eval = [](Stream &stream, Grid_2d &grid_2d, + Vector, e_host> &gauss, TVector_r &M_o) + { + if(stream.n_act_stream<= 0) + { + return; + } + + for(auto istream = 0; istream < stream.n_act_stream-1; istream++) + { + stream[istream] = std::thread(std::bind(host_detail::gauss_eval, std::ref(stream), std::ref(grid_2d), std::ref(gauss[istream]), std::ref(M_o))); + } + + host_detail::gauss_eval(stream, grid_2d, gauss[stream.n_act_stream-1], M_o); + + stream.synchronize(); + }; + + mt::fill(*stream, Im, 0.0); + + int iatom_0 = 0; + int iatom_e = input_gauss_spt->atoms.size()-1; + + int iatoms = iatom_0; + while (iatoms <= iatom_e) + { + stream->set_n_act_stream(iatom_e-iatoms+1); + set_gauss_sp(iatoms, stream->n_act_stream, gauss_sp); + + gauss_eval(*stream, input_gauss_spt->grid_2d, gauss_sp, Im); + iatoms += stream->n_act_stream; + } + + stream->synchronize(); + } + + /***********************Device***********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector_r &Im) + { + auto get_eval_cubic_poly_gridBT = [](int natoms)->Grid_BT + { + Grid_BT grid_bt; + grid_bt.Blk = dim3(natoms, 1, 1); + grid_bt.Thr = dim3(c_thrnxny, c_thrnxny, 1); + + return grid_bt; + }; + + mt::fill(*stream, Im, 0.0); + + int iatom_0 = 0; + int iatom_e = input_gauss_spt->atoms.size()-1; + + int iatoms = iatom_0; + while (iatoms <= iatom_e) + { + int n_atoms = min(n_atoms_p, iatom_e-iatoms+1); + set_gauss_sp(iatoms, n_atoms, gauss_sp); + + auto grid_bt = get_eval_cubic_poly_gridBT(n_atoms); + device_detail::gauss_eval<<>>(input_gauss_spt->grid_2d, gauss_sp, Im); + + iatoms += n_atoms; + } + } + #endif + + Input_Gauss_Spt *input_gauss_spt; + Stream *stream; + private: + int n_atoms_p; + + struct Stream_Data + { + using value_type = T; + using size_type = std::size_t; + + static const eDevice device = e_host; + + size_type size() const + { + return iv.size(); + } + + void resize(const size_type &new_size) + { + iv.resize(new_size); + v.resize(new_size); + } + + Vector, e_host> iv; + Vector, e_host> v; + }; + + void set_gauss_sp(int iatoms, int n_atoms_p, Vector, dev> &gauss_sp) + { + for(auto istream = 0; istream < n_atoms_p; istream++) + { + gauss_sp_h[istream].x = input_gauss_spt->atoms.x[iatoms]; + gauss_sp_h[istream].y = input_gauss_spt->atoms.y[iatoms]; + gauss_sp_h[istream].a = input_gauss_spt->atoms.a[iatoms]; + gauss_sp_h[istream].alpha = input_gauss_spt->alpha(iatoms); + auto R_max = input_gauss_spt->R_max(iatoms); + auto R2_max = R_max*R_max; + gauss_sp_h[istream].R2_tap = pow(0.85*R_max, 2); + gauss_sp_h[istream].tap_cf = c_i2Pi/(R2_max-gauss_sp_h[istream].R2_tap); + gauss_sp_h[istream].R2_max = R2_max; + gauss_sp_h[istream].set_ix0_ixn(input_gauss_spt->grid_2d, R_max); + gauss_sp_h[istream].set_iy0_iyn(input_gauss_spt->grid_2d, R_max); + if(device==e_host) + { + gauss_sp_h[istream].iv = raw_pointer_cast(stream_data.iv[istream].data()); + gauss_sp_h[istream].v = raw_pointer_cast(stream_data.v[istream].data()); + } + iatoms++; + } + thrust::copy(gauss_sp_h.begin(), gauss_sp_h.end(), gauss_sp.begin()); + } + + Stream_Data stream_data; + Vector, e_host> gauss_sp_h; + Vector, dev> gauss_sp; + }; + + /****************affine transformations***************/ + template + class Sc_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Sc_2d(): stream(nullptr){} + + Sc_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T sxy, TVector &M_o) + { + if(isEqual(sxy, T(1))) + { + M_o = M_i; + } + + int nx_o = get_new_size(grid_2d.nx, sxy); + int ny_o = get_new_size(grid_2d.ny, sxy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::sc_2d, TVector>, grid_2d, M_i, sxy, grid_2d_o, M_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, T sxy, TVector &M_o) + { + if(isEqual(sxy, T(1))) + { + M_o = M_i; + } + + int nx_o = max(int(floor(grid_2d.nx*sxy)), 1); + int ny_o = max(int(floor(grid_2d.ny*sxy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + auto grid_bt = grid_2d_o.cuda_grid(); + device_detail::sc_2d, typename TVector::value_type><<>>(grid_2d, M_i, sxy, grid_2d_o, M_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Rot_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Rot_2d(): stream(nullptr){} + + Rot_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T theta, r2d p0, TVector &M_o) + { + if(isZero(theta)) + { + M_o = M_i; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::rot_2d, TVector>, grid_2d, M_i, theta, p0, bg, grid_2d_o, M_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, T theta, r2d p0, TVector &M_o) + { + if(isZero(theta)) + { + M_o = M_i; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + auto grid_bt = grid_2d_o.cuda_grid(); + device_detail::rot_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, bg, grid_2d_o, M_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Rot_Sca_sft_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Rot_Sca_sft_2d():stream(nullptr){} + + Rot_Sca_sft_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) + { + // calculate background + T bg = mean(*stream, M_i); + + int nx_o = get_new_size(grid_2d.nx, sx); + int ny_o = get_new_size(grid_2d.ny, sy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) + { + // calculate background + T bg = mean(*stream, M_i); + + int nx_o = max(int(floor(grid_2d.nx*sx)), 1); + int ny_o = max(int(floor(grid_2d.ny*sy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + auto grid_bt = grid_2d_o.cuda_grid(); + device_detail::rot_sca_sft_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Data_Aug_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Data_Aug_2d():stream(nullptr){} + + Data_Aug_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, T sim, + int nx_o, int ny_o, TVector &M_o) + { + // calculate maximum + auto M_max = *thrust::max_element(M_i.begin(), M_i.end()); + + // calculate background + auto g_max = grid_2d.gx_last(); + auto g_min = 0.9*g_max; + //T bg = sum_over_Det(*stream, grid_2d, g_min, g_max, M_i); + + T bg = 0.6*mean(*stream, M_i); + + T Rx_0 = p0.x*sx-(nx_o/2)*grid_2d.dRx; + T Ry_0 = p0.y*sy-(ny_o/2)*grid_2d.dRy; + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + grid_2d_o.set_R_0(Rx_0, Ry_0); + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); + + normalized_data(M_o, M_max); + + // add Poisson noise + M_o = add_poiss_nois(*stream, M_o, sim); + + M_max = *thrust::max_element(M_o.begin(), M_o.end()); + normalized_data(M_o, M_max); + } + + protected: + void normalized_data(TVector &M, T M_max) + { + std::for_each(M.begin(), M.end(), [M_max](T &v){ v = (v>0)?v/M_max:0;}); + } + + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Shx_Scy + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Shx_Scy():stream(nullptr){} + + Shx_Scy(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + template + enable_if_dev_host + operator()(TVector &M_i, r2d af, TVector &M_o) + { + if(isZero(af.x) && isEqual(af.y, T(1))) + { + M_o = M_i; + } + + TVector M_o_t; + TVector *pM_o = &M_o; + + if (M_i.data() == M_o.data()) + { + M_o_t.resize(M_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::shx_scy, TVector>, grid_2d, M_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (M_i.data() == M_o.data()) + { + M_o.assign(pM_o->begin(), pM_o->end()); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, r2d af, TVector &M_o) + { + if(isZero(af.x) && isEqual(af.y, T(1))) + { + M_o = M_i; + } + + TVector M_o_t; + TVector *pM_o = &M_o; + + if (M_i.data() == M_o.data()) + { + M_o_t.resize(M_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::shx_scy, typename TVector::value_type><<>>(grid_2d, M_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (M_i.data() == M_o.data()) + { + M_o.assign(pM_o->begin(), pM_o->end()); + } + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + /**********************shift*************************/ + template + class Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Sft_1d():fft_1d(nullptr){} + + Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx); + } + + void operator()(T xs, TVector_c &Im) + { + fft1_shift(grid_1d, Im); + fft_1d->forward(Im); + exp_g_factor_1d(grid_1d, -c_2Pi*xs, Im, Im); + fft_1d->inverse(Im); + fft1_shift(grid_1d, Im); + } + + void operator()(T xs, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + T Im_min = min_element(Im); + + this->operator()(xs, Im_c); + assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_1d->cleanup(); + } + + protected: + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Sft_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T alpha, TVector_r ys, TVector_c &Im) + { + fft2_sft_bc(*stream, grid_2d, Im); + fft_2d->forward(Im); + exp_g_factor_2d_bc(*stream, grid_2d, -c_2Pi*alpha, ys, Im, Im); + fft_2d->inverse(Im); + fft2_sft_bc(*stream, grid_2d, Im); + } + + void operator()(T alpha, TVector_r ys, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + T Im_min = min_element(Im); + + this->operator()(alpha, ys, Im_c); + assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Sft_2d():stream(nullptr), fft_2d(nullptr){} + + Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(r2d p, TVector_c &Im) + { + fft2_shift(*stream, grid_2d, Im); + fft_2d->forward(Im); + exp_g_factor_2d(*stream, grid_2d, -c_2Pi*p.x, -c_2Pi*p.y, Im, Im); + fft_2d->inverse(Im); + fft2_shift(*stream, grid_2d, Im); + } + + void operator()(r2d p, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + T Im_min = min_element(Im); + + this->operator()(p, Im_c); + assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /******************phase correlation*****************/ + template + class Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Pcf_1d(): fft_1d(nullptr){} + + Pcf_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + + Prime_Num pn; + + int nx = pn(2*grid_1d.nx-1, eDST_Greater_Than); + + grid_1d_e.set_input_data(nx, grid_1d.dRx*nx); + + M_r_c.resize(grid_1d_e.nx); + M_s_c.resize(grid_1d_e.nx); + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + fft_1d_e.create_plan_1d(grid_1d_e.nx, 1); + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Border_1d bd, bool b_pv, TVector_r &M_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVector_c &pcf = M_s_c; + + // shift matrix + fft1_shift(grid_1d_e, M_r_c); + fft1_shift(grid_1d_e, M_s_c); + + // fft_1d_e + fft_1d_e.forward(M_r_c); + fft_1d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + + fft_1d_e.inverse(pcf); + + // shift pcf + fft1_shift(grid_1d_e, pcf); + + int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + this->assign_real(pcf, ix_s, M_o, b_pv); + } + + void cleanup() + { + fft_1d->destroy_plan(); + fft_1d_e.cleanup(); + } + + protected: + + void assign_real(TVector_c &M_i, int ix_s, TVector_r &M_o, bool b_pos = false) + { + auto first = M_i.begin() + ix_s; + auto last = first + grid_1d.nx; + + if(b_pos) + { + thrust::transform(first, last, M_o.begin(), functor::assign_max_real(0)); + } + else + { + thrust::transform(first, last, M_o.begin(), functor::assign_real()); + } + } + + /************************Host************************/ + template + enable_if_dev_host + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Butterworth_1d bw_1d(bd, bd.radius_ptl(p), 32); + + for (auto ix = 0; ix < grid_1d.nx; ix++) + { + host_device_detail::pcf_1d_pp(ix, ix_s, grid_1d, bw_1d, M_i, M_o); + } + } + + template + enable_if_dev_host + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_1d gs_1d(0, sigma_g); + + for (auto ix = 0; ix < grid_1d_e.nx; ix++) + { + host_device_detail::pcf_1d_gaussian(ix, grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + } + + /***********************Device***********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Butterworth_1d bw_1d(bd, bd.radius_ptl(p), 32); + + auto grid_bt = grid_1d.cuda_grid(); + device_detail::pcf_1d_pp, typename TVector_c::value_type><<>>(ix_s, grid_1d, bw_1d, M_i, M_o); + } + + template + enable_if_dev_device + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_1d gs_1d(0, sigma_g); + + auto grid_bt = grid_1d_e.cuda_grid(); + device_detail::pcf_1d_gaussian, typename TVector_c::value_type><<>>(grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + #endif + + TVector_c M_r_c; + TVector_c M_s_c; + + FFT *fft_1d; + Grid_1d grid_1d; + + private: + FFT fft_1d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Pcf_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Pcf_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + grid_1d.set_input_data(grid_2d.ny, grid_2d.ly); + + Prime_Num pn; + + int ny = pn(2*grid_2d.ny-1, eDST_Greater_Than); + + grid_2d_e.set_input_data(grid_2d.nx, ny, grid_2d.lx, grid_2d.dRy*ny); + grid_1d_e.set_input_data(grid_2d_e.ny, grid_2d_e.ly); + + M_r_c.resize(grid_2d_e.nxy()); + M_s_c.resize(grid_2d_e.nxy()); + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d_e.create_plan_1d_batch(grid_2d_e.ny, grid_2d_e.nx, stream->size()); + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Border_1d bd, bool b_pv, TVector_r &M_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVector_c &pcf = M_s_c; + + // shift matrix + fft2_sft_bc(*stream, grid_2d_e, M_r_c); + fft2_sft_bc(*stream, grid_2d_e, M_s_c); + + // fft_2d + fft_2d_e.forward(M_r_c); + fft_2d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + fft_2d_e.inverse(pcf); + + // shift pcf + fft2_sft_bc(*stream, grid_2d_e, pcf); + + int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + this->assign_real(pcf, iy_s, M_o, b_pv); + } + + void cleanup() + { + fft_2d->destroy_plan(); + fft_2d_e.cleanup(); + } + + protected: + + TVector_r gauss_vector_1d(Grid_1d &grid_1d, T sigma_g, bool b_norm = false) + { + Gauss_1d gs_1d(0, sigma_g); + + TVector_r fg; + fg.reserve(grid_1d.nx); + + for (auto ix=0; ix < grid_1d.nx; ix++) + { + T g2 = grid_1d.g2_shift(ix); + T v = gs_1d(g2); + fg.push_back(v); + } + return fg; + } + + /************************Host************************/ + template + enable_if_dev_host + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh = func_butterworth_1d(grid_1d, bd.radius_ptl(p), 32, false, bd); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::pcf_2d_bc_pp, TVector_r, TVector_c>, iy_s, grid_2d, grid_2d_e, M_i, fh, M_o); + } + + template + enable_if_dev_host + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + auto fg = gauss_vector_1d(grid_1d_e, sigma_g); + + stream->set_n_act_stream(grid_2d_e.nx); + stream->set_grid(grid_2d_e.nx, grid_2d_e.ny); + stream->exec_matrix(host_device_detail::pcf_2d_bc_gaussian, TVector_r, TVector_c>, grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_dev_host + assign_real(TVector_c &M_i, int iy_s, TVector_r &M_o, bool b_pos = false) + { + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + int ixy_i = grid_2d_e.ind_col(ix, iy+iy_s); + int ixy_o = grid_2d.ind_col(ix, iy); + auto v = M_i[ixy_i].real(); + M_o[ixy_o] = (!b_pos || (v>0))?v:0; + } + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh_h = func_butterworth_1d>(grid_1d, bd.radius_ptl(p), 32, false, bd); + TVector_r fh = fh_h; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_bc_pp, typename TVector_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, M_i, fh, M_o); + } + + template + enable_if_dev_device + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + auto fg_h = gauss_vector_1d(grid_1d_e, sigma_g); + TVector_r fg = fg_h; + + auto grid_bt = grid_2d_e.cuda_grid(); + device_detail::pcf_2d_bc_gaussian, typename TVector_c::value_type><<>>(grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_dev_device + assign_real(TVector_c &M_i, int iy_s, TVector_r &M_o, bool b_pos = false) + { + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_bc_assign_real, typename TVector_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, M_i, M_o, b_pos); + } + #endif + + Vector M_r_c; + Vector M_s_c; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + Grid_1d grid_1d; + + private: + FFT fft_2d_e; + Grid_2d grid_2d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Pcf_2d():stream(nullptr), fft_2d(nullptr){} + + Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + + M_r_c.resize(grid_2d.nxy()); + M_s_c.resize(grid_2d.nxy()); + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Border_2d bd, bool b_pv, TVector_r &M_o) + { + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVector_c &pcf = M_s_c; + + // shift matrix + fft2_shift(*stream, grid_2d, M_r_c); + fft2_shift(*stream, grid_2d, M_s_c); + + // fft_2d + fft_2d->forward(M_r_c); + fft_2d->forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + fft_2d->inverse(pcf); + + // shift pcf + fft2_shift(*stream, grid_2d, pcf); + + T pv = (b_pv)?1:-1; + assign_real(pcf, M_o, pv); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + /************************Host************************/ + template + enable_if_dev_host + preprocessing(TVector_r &M_i, T p, Border_2d &bd, TVector_c &M_o) + { + Butterworth_2d bw_2d(bd, bd.radius_ptl(p), 32); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::pcf_2d_pp, TVector_r, TVector_c>, grid_2d, bw_2d, M_i, M_o); + } + + template + enable_if_dev_host + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_2d gs_2d(0, 0, sigma_g); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::pcf_2d_gaussian, TVector_c>, grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + preprocessing(TVector_r &M_i, T p, Border_2d &bd, TVector_c &M_o) + { + Butterworth_2d bw_2d(bd, bd.radius_ptl(p), 32); + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_pp, typename TVector_c::value_type><<>>(grid_2d, bw_2d, M_i, M_o); + } + + template + enable_if_dev_device + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_2d gs_2d(0, 0, sigma_g); + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_gaussian, typename TVector_c::value_type><<< grid_bt.Blk, grid_bt.Thr >>>(grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + #endif + + Vector M_r_c; + Vector M_s_c; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /********************find shift**********************/ + template + class Fd_Sft_1d: public Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Fd_Sft_1d(): Pcf_1d(){} + + Fd_Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i): Pcf_1d() + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + Pcf_1d::set_input_data(fft_1d_i, grid_1d_i); + sft_1d.set_input_data(fft_1d_i, grid_1d_i); + } + + T operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, T dx, + Border_1d bd, int nit_pcf) + { + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.dRx, 0.9*sigma_r); + + TVector_r M = M_s; + TVector_r pcf(M.size()); + + if(nonZero(dx)) + { + sft_1d(dx, M); + } + + for (auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); + + // get maximun position + T x_c = host_device_detail::max_pos_1d(this->grid_1d, pcf); + + if(it==nit_pcf-1) + { + x_c = fit_max_pos_1d(this->grid_1d, pcf, x_c, sigma_r, radius); + } + + T dx_t = -(x_c - this->grid_1d.lxh()); + + if(it sft_1d; + }; + + template + class Fd_Sft_2d_BC: public Pcf_2d_BC + { + public: + using TB = std::pair; + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + using TVector_rh = Vector; + using TVector_ch = Vector; + + Fd_Sft_2d_BC(): Pcf_2d_BC() {} + + Fd_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Pcf_2d_BC() + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + Pcf_2d_BC::set_input_data(stream_i, fft_2d_i, grid_2d_i); + gauss_cv_2d_bc.set_input_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d_bc.set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + TVector_rh operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, TVector_rh dx, + Border_2d bd_2d, int nit_pcf) + { + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.dRx, 0.9*sigma_r); + Border_1d bd_1d(bd_2d.ly, bd_2d.yb_0, bd_2d.yb_e); + Peaks peaks(this->grid_1d, &bd_1d); + + TVector_r M_r = M_r_i; + TVector_r M_s = M_s_i; + TVector_r pcf(M_r.size()); + + // Gaussian filter + gauss_cv_2d_bc(sigma_r, M_r); + gauss_cv_2d_bc(sigma_r, M_s); + + const int ix_0 = this->grid_2d.ceil_dRx(bd_2d.x_0()); + const int ix_e = this->grid_2d.floor_dRx(bd_2d.x_e()); + + bool dx_s = false; + for(auto ix=0; ixgrid_1d.nx, T(0)); + + for (auto it=0; it::operator()(M_r, M_s, p, sigma_g, bd_1d, false, pcf); + + // get maximum distance + T d_max = (it==0)?peaks.get_d_max_0(ix_0, ix_e, pcf):peaks.get_d_max(ix_0, ix_e, dx_t); + d_max = ::fmax(sigma_r, d_max); + + for(auto ix=ix_0; ixgrid_1d.nx, pcf.begin()+(ix+1)*this->grid_1d.nx); + + auto py = peaks.find(ix, M_r, M_s, y, d_max); + if(it==nit_pcf-1) + { + py = fit_max_pos_1d(this->grid_1d, y, py, sigma_r, radius); + } + dx_t[ix] = -(py - this->grid_1d.lxh()); + dx[ix] += dx_t[ix]; + } + + // shift by column + if(it gauss_cv_2d_bc; + Sft_2d_BC sft_2d_bc; + + private: + struct Peaks + { + public: + using TVector_ih = Vector; + + Peaks(): y_c(0), bd_1d(nullptr){} + + Peaks(Grid_1d &grid_1d_i, Border_1d *bd_1d_i) + { + set_input_data(grid_1d_i, bd_1d_i); + } + + inline + void set_input_data(Grid_1d &grid_1d_i, Border_1d *bd_1d_i) + { + grid_1d = grid_1d_i; + bd_1d = bd_1d_i; + fft_1d.create_plan_1d(grid_1d.nx, 1); + sft_1d.set_input_data(&fft_1d, grid_1d); + + ix_pk.resize(grid_1d.nx); + x_pk.resize(grid_1d.nx); + y_pk.resize(grid_1d.nx); + } + + T get_d_max_0(int ix_0, int ix_e, TVector_r &pcf) + { + T x_c = grid_1d.lxh(); + TVector_rh dx; + dx.reserve(grid_1d.nx); + + for(auto ix=ix_0; ixdx_max); }); + dx.resize(std::distance(dx.begin(), it)); + + T dx_std = sqrt(variance(dx)); + T d_max = max_element(dx) + 2*dx_std; + + return ::fmax(10*grid_1d.dRx, d_max); + } + + T get_d_max(int ix_0, int ix_e, TVector_rh &dx) + { + TVector_rh dx_h(dx.begin()+ix_0, dx.begin()+ix_e); + return ::fmax(10*grid_1d.dRx, 3*sqrt(variance(dx_h))); + } + + T find(int icol, TVector_r &M_r, TVector_r &M_s, TVector_rh &y, T d_max) + { + const T x_c = grid_1d.lxh(); + y_c = y[grid_1d.nxh]; + + // find peaks + fd_peaks(y); + + // remove peaks + remove_peaks(x_c-d_max, x_c+d_max); + + // return if x_pk is empty + if(empty()) + { + return x_c; + } + + // return if there is only one element + if(size() == 1) + { + return x_pk.front(); + } + + const int ix_max = idx_y_max(); + const int ix_clt = idx_x_clt(); + + // return if closest position is equal to maximum intensity position + // and the maximum intensity is greater than the second maximum intensity + if(fabs(x_pk[ix_max]-x_pk[ix_clt])<1) + { + T y_thr = 0.61*y_pk[ix_max]; + for(auto ix=0; ix grid_1d; + Border_1d *bd_1d; + + FFT fft_1d; + Sft_1d sft_1d; + + T y_c; + + bool empty() const + { + return ix_pk.empty(); + } + + int size() const + { + return ix_pk.size(); + } + + int idx_y_max() const + { + int idx_max = (std::max_element(y_pk.begin(), y_pk.end())-y_pk.begin()); + + return idx_max; + } + + int idx_x_clt() const + { + T x_c = grid_1d.lxh(); + + int idx_clt = 0; + if(x_pk.size()>1) + { + idx_clt = std::min_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)1) + { + idx_clt = std::max_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)y_thr) + { + if((y[ix-1] bd_l = *bd_1d; + bd_l.xb_0 = max(bd_l.xb_0, d_fht); + bd_l.xb_e = max(bd_l.xb_e, d_fht); + + // get indexes + const int ix_0 = grid_1d.ceil_dRx(bd_l.x_0()); + const int ix_e = grid_1d.floor_dRx(bd_l.x_e()); + + // get reference data + TVector_rh yr_b(M_r.begin()+(icol-1)*grid_1d.nx, M_r.begin()+icol*grid_1d.nx); + TVector_rh yr(M_r.begin()+icol*grid_1d.nx, M_r.begin()+(icol+1)*grid_1d.nx); + TVector_rh yr_n(M_r.begin()+(icol+1)*grid_1d.nx, M_r.begin()+(icol+2)*grid_1d.nx); + + // get shifted data + TVector_rh ys_0(M_s.begin()+icol*grid_1d.nx, M_s.begin()+(icol+1)*grid_1d.nx); + + TVector_rh chi2_pk(size()); + + for(auto ix_pk=0; ix_pk + class Fd_Sft_2d: public Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Fd_Sft_2d(): Pcf_2d(){} + + Fd_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Pcf_2d() + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + Pcf_2d::set_input_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d.set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + r2d operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, r2d dr, + Border_2d bd, int nit_pcf) + { + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 0.9*sigma_r); + + TVector_r M = M_s; + TVector_r pcf(M.size()); + + if(nonZero(dr)) + { + sft_2d(dr, M); + } + + for (auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); + + // get maximun position + r2d r_c = host_device_detail::max_pos_2d(this->grid_2d, pcf); + + if(it==nit_pcf-1) + { + r_c = fit_max_pos_2d(this->grid_2d, pcf, r_c, sigma_r, radius); + } + + r2d dr_t = -(r_c - r2d(this->grid_2d.lxh(), this->grid_2d.lyh())); + + if(it sft_2d; + }; + + /*******************Corrrect shift*******************/ + template + class Crt_Sft_1d: public Fd_Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Crt_Sft_1d(): Fd_Sft_1d(){} + + Crt_Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i): + Fd_Sft_1d(fft_1d_i, grid_1d_i){} + + T operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, + Border_1d bd, int nit_pcf) + { + T dx = 0; + dx = Fd_Sft_1d::operator()(M_r_i, M_s_io, p, sigma_g, dx, bd, nit_pcf); + this->sft_1d(dx, M_s_io); + + return dx; + } + }; + + template + class Crt_Sft_2d_BC: public Fd_Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + using TVector_rh = Vector; + using TVector_ch = Vector; + + Crt_Sft_2d_BC(): Fd_Sft_2d_BC(){} + + Crt_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): + Fd_Sft_2d_BC(stream_i, fft_2d_i, grid_2d_i){} + + TVector_rh operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, + Border_2d bd, int nit_pcf) + { + TVector_rh dr(this->grid_2d.ny, T(0)); + dr = Fd_Sft_2d_BC::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d_bc(1, dr, M_s_io); + + return dr; + } + }; + + template + class Crt_Sft_2d: public Fd_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Crt_Sft_2d(): Fd_Sft_2d(){} + + Crt_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): + Fd_Sft_2d(stream_i, fft_2d_i, grid_2d_i){} + + r2d operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, + Border_2d bd, int nit_pcf) + { + r2d dr(0, 0); + dr = Fd_Sft_2d::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d(dr, M_s_io); + + return dr; + } + }; + + /****************calculate Chi^2*****************/ + template + class Chi2_Pcf_2d: public Crt_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Chi2_Pcf_2d(): Crt_Sft_2d(){} + + Chi2_Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Crt_Sft_2d() + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + Crt_Sft_2d::set_input_data(stream_i, fft_2d_i, grid_2d_i); + shx_scy.set_input_data(this->stream, this->grid_2d); + } + + T operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, + r2d af, Border_2d bd, int nit_pcf, r2d &ds) + { + TVector_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVector_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, true, pcf); + + // cost function + return mean(*(this->stream), pcf); + } + + T operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, + r2d af, Border_2d bd, int nit_pcf, r2d &ds, Vector &coef) + { + TVector_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVector_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, true, pcf); + + // cost function + auto chi2 = mean(*(this->stream), pcf); + + // get maximun position + r2d r_c = host_device_detail::max_pos_2d(this->grid_2d, pcf); + + // fitting + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 1.5*sigma_r); + Vector pcf_h = pcf; + coef = fit_ellipt_gauss_2d(this->grid_2d, pcf_h, r_c, sigma_r, radius); + coef[0] = ds.x + this->grid_2d.lxh(); + coef[1] = ds.y + this->grid_2d.lyh(); + + return chi2; + } + + protected: + Shx_Scy shx_scy; + }; + + template + class NM_Shx_Scy: public Chi2_Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + NM_Shx_Scy():Chi2_Pcf_2d(), nit_pcf(2){} + + NM_Shx_Scy(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): + Chi2_Pcf_2d(stream_i, fft_2d_i, grid_2d_i), nit_pcf(2){} + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Vector, e_host> &spx, Border_2d bd, int nit_nm) + { + int ic = 1; + + T d_pix_min = this->grid_2d.dg_min(); + T d_min = 0.05*d_pix_min; + T alpha = 1.0; + T beta = 0.5; + T gamma = 2.0; + + for(auto it=0; it ds_r(0, 0); + auto chi2_r = chi2_pcf(M_r, M_s, p, sigma_g, x_r, bd, nit_pcf, ds_r); + + if(chi2_r ds_e(0, 0); + auto chi2_e = chi2_pcf(M_r, M_s, p, sigma_g, x_e, bd, nit_pcf, ds_e); + if(chi2_e(x_e, ds_e, chi2_e); + } + else + { + spx[2] = Afp_2(x_r, ds_r, chi2_r); + } + } + else if(chi2_r(x_r, ds_r, chi2_r); + } + else if(chi2_r ds_rc(0, 0); + auto chi2_rc = chi2_pcf(M_r, M_s, p, sigma_g, x_rc, bd, nit_pcf, ds_rc); + if(chi2_rc(x_rc, ds_rc, chi2_rc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + else + { + auto x_wc = x_m + beta*(x_w-x_m); + r2d ds_wc(0, 0); + auto chi2_wc = chi2_pcf(M_r, M_s, p, sigma_g, x_wc, bd, nit_pcf, ds_wc); + if(chi2_wc(x_wc, ds_wc, chi2_wc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + } + + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d &af, Border_2d bd, r2d &ds, int nit_nm) + { + auto spx = set_simplex(M_r, M_s, p, sigma_g, af, ds, bd, nit_nm); + this->operator()(M_r, M_s, p, sigma_g, spx, bd, nit_nm); + + af = spx[0].f; + ds = spx[0].ds; + + // // shear and scaling + // shx_scy(M_s, af, M_s); + // // correct shift + // ds = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds, bd, nit_pcf); + } + + protected: + r2d x_af(const r2d &af, const r2d &r) + { + return r2d(r.x+af.x*r.y, af.y*r.y); + } + + r2d x_iaf(const r2d &af, const r2d &r) + { + return r2d(r.x-af.x*r.y/af.y, r.y/af.y); + } + + Vector, e_host> set_simplex(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d x_0, r2d ds_0, Border_2d &bd, int nit_nm) + { + // global shift + if(isZero(ds_0)) + { + ds_0 = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds_0, bd, nit_pcf); + bd.set_bd(ds_0); + } + + TVector_r M_s_t = M_s; + this->sft_2d(x_iaf(x_0, ds_0), M_s_t); + + // determine coefficients + Vector coef(6); + chi2_pcf(M_r, M_s_t, p, sigma_g, x_0, bd, nit_pcf, ds_0, coef); + + // calculate dd0 + T ff = coef[4]/coef[3]; + ff = (ff<1)?1/ff:ff; + ff = ::fmax(1.05, ff); + + T dd0 = sqrt(1.354e-04*pow(ff-1, 2)+6.622e-4*(ff-1)); + dd0 = ::fmax(dd0, this->grid_2d.dg_min()); + + T sin_t = sin(coef[5]); + T cos_t = cos(coef[5]); + + T sigma_x = pow(cos_t/coef[3], 2)+pow(sin_t/coef[4], 2); + sigma_x = sqrt(1/sigma_x); + + T sigma_y = pow(sin_t/coef[3], 2)+pow(cos_t/coef[4], 2); + sigma_y = sqrt(1/sigma_y); + + T theta = atan2(sigma_y, sigma_x); + + r2d u(dd0*cos(theta), dd0*sin(theta)); + r2d v(-u.y, u.x); + + // set simplex + Vector, e_host> spx(3); + + spx[0].f = x_0; + spx[0].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[0].f, bd, nit_pcf, spx[0].ds); + + spx[1].f = x_0+u; + spx[1].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[1].f, bd, nit_pcf, spx[1].ds); + + spx[2].f = x_0+v; + spx[2].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[2].f, bd, nit_pcf, spx[2].ds); + + // sort simplex + sort(spx); + + return spx; + } + + T chi2_pcf(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d af, Border_2d &bd, int nit_pcf, r2d &ds) + { + return Chi2_Pcf_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, ds); + } + + T chi2_pcf(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d af, Border_2d &bd, int nit_pcf, r2d &ds, Vector &coef) + { + return Chi2_Pcf_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, ds, coef); + } + + void sort(Vector, e_host> &spx) + { + std::sort(spx.begin(), spx.end(), [](const Afp_2 &x, const Afp_2 &y){ return x.chi2, e_host> &spx) + { + auto r0 = spx[0].f; + + r2d dr = spx[1].f - r0; + T d_max = dr.module(); + for(auto i=2; i dr = spx[i].f - r0; + d_max = ::fmax(d_max, dr.module()); + } + return d_max; + } + + T min_length(Vector, e_host> &spx) + { + auto r0 = spx[0].f; + r2d dr = spx[1].f - r0; + T d_min = dr.module(); + for(auto i=2; i dr = spx[i].f - r0; + d_min = ::fmin(d_min, dr.module()); + } + return d_min; + } + + r2d best_centroid(Vector, e_host> &spx) + { + r2d r_c(0, 0); + for(auto i=0; i, e_host> &spx, Border_2d &bd, int nit_pcf) + { + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.module(); + auto mp13 = p13.module(); + auto mp_max = ::fmax(mp12, mp13); + + T theta = angle(p12, p13); + + T theta_min = 10; + T theta_0 = theta_min*c_Pi/180; + T theta_e = c_Pi-theta_min*c_Pi/180; + + bool b_m = (mp12theta_e)||b_m) + { + if(b_m && (mp12(-u.y, u.x); + r2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[1] = Afp_2(x_o, ds_o, chi2_o); + } + else + { + T m = max_length(spx); + auto u = p12/module(p12); + auto x_o = spx[0].f + mp_max*r2d(-u.y, u.x); + r2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[2] = Afp_2(x_o, ds_o, chi2_o); + } + + sort(spx); + } + } + + void contract_simplex(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Vector, e_host> &spx, Border_2d &bd, int nit_pcf) + { + T ff = 0.5; + + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.module(); + auto mp13 = p13.module(); + + if(mp12(-u.y, u.x); + r2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[2] = Afp_2(x_c, ds_c, chi2_c); + } + else + { + auto u = p13/mp13; + auto x_c = spx[0].f + ff*mp12*r2d(-u.y, u.x); + r2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[1] = Afp_2(x_c, ds_c, chi2_c); + } + + sort(spx); + } + + int nit_pcf; + }; + +} // namespace mt + +#endif \ No newline at end of file diff --git a/src - Copy (2)/igrid.cuh b/src - Copy (2)/igrid.cuh new file mode 100755 index 00000000..7fa796a2 --- /dev/null +++ b/src - Copy (2)/igrid.cuh @@ -0,0 +1,978 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef IGRID_H + #define IGRID_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "cgpu_fcns_gen.cuh" + + /* macro gpu grid-block */ + namespace mt + { + #define FCNS_GPU_GRID_BLK_IGRID_1D \ + dim3 d_blk_size() \ + { \ + return fcn_cdb_size(); \ + } \ + \ + dim3 d_grid_size(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + auto grid = fcn_cdg_size(this->m_size); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_size(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + return D_Grid_Blk(d_grid_size(d_grid_max), d_blk_size()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_blk() \ + { \ + return fcn_cdb_1d(); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + auto grid = fcn_cdg_1d(this->nx); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + return D_Grid_Blk(d_grid(d_grid_max), d_blk()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_h(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + auto grid = fcn_cdg_1d(this->nx_h); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(128, 1, 1)) \ + { \ + return D_Grid_Blk(d_grid_h(d_grid_max), d_blk()); \ + } + + #define FCNS_GPU_GRID_BLK_IGRID_2D \ + dim3 d_blk() \ + { \ + return fcn_cdb_2d(); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid(const dim3 d_grid_max = dim3(64, 64, 0)) \ + { \ + auto grid = fcn_cdg_2d(this->ny, this->nx); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + return D_Grid_Blk(d_grid(d_grid_max), d_blk()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_h(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + auto grid = fcn_cdg_2d(this->ny_h, this->nx_h); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + return D_Grid_Blk(d_grid_h(d_grid_max), d_blk()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_d0_h(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + auto grid = fcn_cdg_2d(this->ny_h, this->nx); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_d0_h(const dim3 d_grid_max = dim3(64, 64, 1)) \ + { \ + return D_Grid_Blk(d_grid_d0_h(d_grid_max), d_blk()); \ + } + + #define FCNS_GPU_GRID_BLK_IGRID_3D \ + dim3 d_blk() \ + { \ + return fcn_cdb_3d(); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + auto grid = fcn_cdg_3d(this->ny, this->nx, this->nz); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + return D_Grid_Blk(d_grid(d_grid_max), d_blk()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_h(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + auto grid = fcn_cdg_3d(this->ny_h, this->nx_h, this->nz_h); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + return D_Grid_Blk(d_grid_h(d_grid_max), d_blk()); \ + } \ + \ + /***************************************************************************************/ \ + dim3 d_grid_d0_h(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + auto grid = fcn_cdg_3d(this->ny_h, this->nx, this->nz); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; \ + \ + return grid; \ + } \ + \ + D_Grid_Blk d_grid_blk_d0_h(const dim3 d_grid_max = dim3(64, 64, 64)) \ + { \ + return D_Grid_Blk(d_grid_d0_h(d_grid_max), d_blk()); \ + } + } + + /***************************************************************************************/ + /*************************************** igrid *****************************************/ + /***************************************************************************************/ + namespace mt + { + template class iGrid_sxd; + + template + using iGrid_xd = iGrid_sxd; + + /* 1d */ + template + using iGrid_1d_st = iGrid_sxd; + + using iGrid_1d = iGrid_sxd; + + using iGrid_1d_64 = iGrid_sxd; + + /* 2d */ + template + using iGrid_2d_st = iGrid_sxd; + + using iGrid_2d = iGrid_sxd; + + using iGrid_2d_64 = iGrid_sxd; + + /* 3d */ + template + using iGrid_3d_st = iGrid_sxd; + + using iGrid_3d = iGrid_sxd; + + using iGrid_3d_64 = iGrid_sxd; + } + + /* template specialization 1d */ + namespace mt + { + template + class iGrid_sxd + { + public: + ST nx; // number of pixels in x direction + ST nx_h; // half number of pixels in x direction + + /************************************* constructors ************************************/ + CGPU_EXEC + iGrid_sxd(): nx(0), nx_h(0) {} + + iGrid_sxd(const ST& nx): nx(nx), nx_h(nx/ST(2)) {} + + /* copy constructor */ + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /* converting constructor */ + template + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid) + { + if (this != &grid) + { + nx = grid.nx; + nx_h = grid.nx_h; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid) + { + nx = ST(grid.nx); + nx_h = ST(grid.nx_h); + + return *this; + } + + template + CGPU_EXEC + void assign(const iGrid_sxd& grid) + { + *this = grid; + } + + /***************************************************************************************/ + void set_size(const ST& nx) + { + this->nx = nx; + this->nx_h = nx/ST(2); + } + + CGPU_EXEC + void clear() + { + nx = 0; + nx_h = 0; + } + + CGPU_EXEC + virtual ST size() const + { + return nx; + } + + template + CGPU_EXEC + SU nx_cast() const + { + return SU(nx); + } + + template + CGPU_EXEC + SU size_cast() const + { + return SU(size()); + } + + template + CGPU_EXEC + SU isize_cast() const + { + return SU(1)/size_cast(); + } + + dt_shape_st shape() const + { + return {nx, ST(1), ST(1), ST(1)}; + } + + /***************************************************************************************/ + /********************** apply boundary conditions to indices ***************************/ + /*********** https:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn *************/ + /***************************************************************************************/ + CGPU_EXEC + ST ind_x_pbc(const ST& ix) const + { + return fcn_ind_pbc(ix, nx); + } + + CGPU_EXEC + ST ind_x_bd(const ST& ix) const + { + return fcn_set_bound(ix, ST(0), nx-ST(1)); + } + + CGPU_EXEC + void ind_pbc(ST& ix) const + { + ix = ind_x_pbc(ix); + } + + /***************************************************************************************/ + /***************************** subindices -> linear indices ****************************/ + /***************************************************************************************/ + CGPU_EXEC + ST operator()(const ST& ix) const + { + return ix; + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix) const + { + return ix; + } + + CGPU_EXEC + ST sub_2_ind_bd(const ST& ix) const + { + return sub_2_ind(ind_x_bd(ix)); + } + + CGPU_EXEC + ST sub_2_ind_pbc(const ST& ix) const + { + return ind_x_pbc(ix); + } + + CGPU_EXEC + ST sub_2_ind_irv_sft_pbc(ST ix) const + { + ind_pbc(ix); + irx_sft(ix); + + return sub_2_ind(ix); + } + + /***************************************************************************************/ + /**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub(const ST& ind, ST& ix) const + { + ix = ind; + } + + /***************************************************************************************/ + /****************************** Fourier space indices **********************************/ + /***************************************************************************************/ + CGPU_EXEC + ST igx(const ST& ix) const + { + return ix-nx_h; + } + /**************************************** shift ****************************************/ + CGPU_EXEC + ST igx_sft(const ST& ix) const + { + return (ix + class iGrid_sxd: public iGrid_sxd + { + public: + ST ny; // number of pixels in y direction + ST ny_h; // half number of pixels in y direction + + /************************************* constructors ************************************/ + CGPU_EXEC + iGrid_sxd(): iGrid_sxd(), ny(0), ny_h(0) {} + + iGrid_sxd(const ST& nx, const ST& ny): iGrid_sxd(nx), ny(ny), ny_h(ny/ST(2)) {} + + /* copy constructor */ + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /* converting constructor */ + template + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + ny = grid.ny; + ny_h = grid.ny_h; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + ny = ST(grid.ny); + ny_h = ST(grid.ny_h); + + return *this; + } + + template + CGPU_EXEC + void assign(const iGrid_sxd& grid) + { + *this = grid; + } + + /***************************************************************************************/ + void set_size(const ST& nx, const ST& ny) + { + iGrid_sxd::set_size(nx); + + this->ny = ny; + this->ny_h = ny/ST(2); + } + + CGPU_EXEC + void clear() + { + iGrid_sxd::clear(); + ny = 0; + ny_h = 0; + } + + CGPU_EXEC + virtual ST size() const + { + return this->nx*ny; + } + + template + CGPU_EXEC + SU ny_cast() const + { + return SU(ny); + } + + dt_shape_st shape() const + { + return {ny, this->nx, ST(1), ST(1)}; + } + + /***************************************************************************************/ + /*********************** apply boundary conditions to indices **************************/ + /*nnhttps:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn */ + /***************************************************************************************/ + CGPU_EXEC + ST ind_y_pbc(const ST& iy) const + { + return fcn_ind_pbc(iy, ny); + } + + CGPU_EXEC + ST ind_y_bd(const ST& iy) const + { + return fcn_set_bound(iy, ST(0), ny-ST(1)); + } + + CGPU_EXEC + void ind_pbc(ST& ix, ST& iy) const + { + ix = this->ind_x_pbc(ix); + iy = ind_y_pbc(iy); + } + + /***************************************************************************************/ + /**************************** subindices -> linear indices *****************************/ + /***************************************************************************************/ + CGPU_EXEC + ST operator()(const ST& ix, const ST& iy) const + { + return iy + ix*ny; + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy) const + { + return iy + ix*ny; + } + + CGPU_EXEC + ST sub_2_ind_bd(const ST& ix, const ST& iy) const + { + return sub_2_ind(this->ind_x_bd(ix), ind_y_bd(iy)); + } + + CGPU_EXEC + ST sub_2_ind_pbc(const ST& ix, const ST& iy) const + { + return ind_y_pbc(iy) + this->ind_x_pbc(ix)*ny; + } + + CGPU_EXEC + ST sub_2_ind_irv_sft_pbc(ST ix, ST iy) const + { + ind_pbc(ix, iy); + irv_sft(ix, iy); + + return sub_2_ind(ix, iy); + } + + /***************************************************************************************/ + /**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub(const ST& ind, ST& ix, ST& iy) const + { + ix = ind/ny; + iy = ind - ix*ny; + } + + /***************************************************************************************/ + /******************* subindices to linear indices using 2nd dimension ******************/ + /***************************************************************************************/ + CGPU_EXEC + ST sub_2_ind_by_d2(const ST& ix, const ST& iy) const + { + return iy*this->nx + ix; + } + + CGPU_EXEC + ST sub_2_ind_by_d2_pbc(const ST& ix, const ST& iy) const + { + return ind_y_pbc(iy)*this->nx + this->ind_x_pbc(ix); + } + + /***************************************************************************************/ + /****************** linear indices-> subindices using 2nd dimension ********************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub_by_d2(const ST& ind, ST& ix, ST& iy) const + { + iy = ind/this->nx; + ix = ind - iy*this->nx; + } + + /***************************************************************************************/ + /******************************* Fourier space indices *********************************/ + /***************************************************************************************/ + CGPU_EXEC + ST igy(const ST& iy) const + { + return iy - ny_h; + } + + CGPU_EXEC + void igv(ST& ix, ST& iy) const + { + ix = this->igx(ix); + iy = igy(iy); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + ST igy_sft(const ST& iy) const + { + return (iyigx_sft(ix); + iy = igy_sft(iy); + } + + /***************************************************************************************/ + /******************************* real space indices ************************************/ + /***************************************************************************************/ + CGPU_EXEC + ST iry(const ST& iy) const + { + return iy; + } + + CGPU_EXEC + void irv(ST& ix, ST& iy) const + { + ix = this->irx(ix); + iy = iry(iy); + } + /***************************************** shift ***************************************/ + CGPU_EXEC + ST iry_sft(const ST& iy) const + { + return (iyirx_sft(ix); + iy = iry_sft(iy); + } + + #ifdef __CUDACC__ + FCNS_GPU_GRID_BLK_IGRID_2D; + #endif + }; + } + + /* template specialization 3d */ + namespace mt + { + template + class iGrid_sxd: public iGrid_sxd + { + public: + ST nz; // number of pixels in z direction + ST nz_h; // half number of pixels in z direction + + /************************************* constructors ************************************/ + CGPU_EXEC + iGrid_sxd(): iGrid_sxd(), nz(0), nz_h(0) {} + + iGrid_sxd(const ST& nx, const ST& ny, const ST& nz): iGrid_sxd(nx, ny), nz(nz), nz_h(nz/ST(2)) {} + + + /* copy constructor */ + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /* converting constructor */ + template + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + nz = grid.nz; + nz_h = grid.nz_h; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid) + { + iGrid_sxd::operator=(grid); + nz = ST(grid.nz); + nz_h = ST(grid.nz_h); + + return *this; + } + + template + CGPU_EXEC + void assign(const iGrid_sxd& grid) + { + *this = grid; + } + + /***************************************************************************************/ + void set_size(const ST& nx, const ST& ny, const ST& nz) + { + iGrid_sxd::set_size(nx, ny); + + this->nz = nz; + this->nz_h = nz/ST(2); + } + + CGPU_EXEC + void clear() + { + iGrid_sxd::clear(); + nz = 0; + nz_h = 0; + } + + CGPU_EXEC + virtual ST size() const + { + return this->nx*this->ny*nz; + } + + template + CGPU_EXEC + SU nz_cast() const + { + return SU(nz); + } + + dt_shape_st shape() const + { + return {this->ny, this->nx, nz, ST(1)}; + } + + /***************************************************************************************/ + /************************* apply boundary conditions to indices ************************/ + /*nnhttps:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn */ + /***************************************************************************************/ + CGPU_EXEC + ST ind_z_pbc(const ST& iz) const + { + return fcn_ind_pbc(iz, nz); + } + + CGPU_EXEC + ST ind_z_bd(const ST& iz) const + { + return fcn_set_bound(iz, ST(0), nz-ST(1)); + } + + CGPU_EXEC + void ind_pbc(ST& ix, ST& iy, ST& iz) const + { + ix = ind_x_pbc(ix); + iy = ind_y_pbc(iy); + iz = ind_z_pbc(iz); + } + + /***************************************************************************************/ + /**************************** subindices -> linear indices *****************************/ + /***************************************************************************************/ + CGPU_EXEC + ST operator()(const ST& ix, const ST& iy, const ST& iz) const + { + return iy + ix*this->ny + iz*this->ny*this->nx; + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy, const ST& iz) const + { + return iy + ix*this->ny + iz*this->ny*this->nx; + } + + CGPU_EXEC + ST sub_2_ind_bd(const ST& ix, const ST& iy, const ST& iz) const + { + return sub_2_ind(this->ind_x_bd(ix), this->ind_y_bd(iy), ind_z_bd(iz)); + } + + CGPU_EXEC + ST sub_2_ind_pbc(const ST& ix, const ST& iy, const ST& iz) const + { + return this->ind_y_pbc(iy) + this->ind_x_pbc(ix)*this->ny + ind_z_pbc(iz)*this->ny*this->nx; + } + + CGPU_EXEC + ST sub_2_ind_irv_sft_pbc(ST ix, ST iy, ST iz) const + { + ind_pbc(ix, iy, iz); + irv_sft(ix, iy, iz); + + return sub_2_ind(ix, iy, iz); + } + + /***************************************************************************************/ + //**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub(const ST& ind, ST& ix, ST& iy, ST& iz) const + { + iz = ind/(this->ny*this->nx); + iy = ind - iz*this->ny*this->nx; + ix = iy/this->ny; + iy = iy - ix*this->ny; + } + + /***************************************************************************************/ + /******************* subindices to linear indices using 2nd dimension ******************/ + /***************************************************************************************/ + CGPU_EXEC + ST sub_2_ind_by_d2(const ST& ix, const ST& iy, const ST& iz) const + { + return iy*this->nx + ix + iz*this->ny*this->nx; + } + + CGPU_EXEC + ST sub_2_ind_by_d2_pbc(const ST& ix, const ST& iy, const ST& iz) const + { + return this->ind_y_pbc(iy)*this->nx + this->ind_x_pbc(ix) + ind_z_pbc(iz)*this->ny*this->nx; + } + + /***************************************************************************************/ + /****************** linear indices-> subindices using 2nd dimension ********************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub_by_d2(const ST& ind, ST& ix, ST& iy, ST& iz) const + { + iz = ind/(this->ny*this->nx); + ix = ind - iz*this->ny*this->nx; + iy = ix/this->nx; + ix = ix - iy*this->nx; + } + + /***************************************************************************************/ + /****************************** Fourier space indices **********************************/ + /***************************************************************************************/ + CGPU_EXEC + ST igz(const ST& iz) const + { + return iz - nz_h; + } + + CGPU_EXEC + void igv(ST& ix, ST& iy, ST& iz) const + { + ix = this->igx(ix); + iy = this->igy(iy); + iz = igz(iz); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + ST igz_sft(const ST& iz) const + { + return (izigx_sft(ix); + iy = this->igy_sft(iy); + iz = igz_sft(iz); + } + + /***************************************************************************************/ + /******************************* real space indices ************************************/ + /***************************************************************************************/ + CGPU_EXEC + ST irz(const ST& iz) const + { + return iz; + } + + CGPU_EXEC + void irv(ST& ix, ST& iy, ST& iz) const + { + ix = this->irx(ix); + iy = this->iry(iy); + iz = irz(iz); + } + + /************************************* shift *******************************************/ + CGPU_EXEC + ST irz_sft(const ST& iz) const + { + return (izirx_sft(ix); + iy = this->iry_sft(iy); + iz = irz_sft(iz); + } + + #ifdef __CUDACC__ + FCNS_GPU_GRID_BLK_IGRID_3D + #endif + }; + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/in_classes.cuh b/src - Copy (2)/in_classes.cuh new file mode 100755 index 00000000..2f5c8ef2 --- /dev/null +++ b/src - Copy (2)/in_classes.cuh @@ -0,0 +1,66 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef IN_CLASSES_H + #define IN_CLASSES_H + + #include + + #include "math.cuh" + #include "types.cuh" + #include "particles.cuh" + #include "cgpu_info.cuh" + #include "cgpu_vctr.cuh" + #include "grid.cuh" + + /***************************************************************************************/ + /***************************** Input particle superposition ****************************/ + /***************************************************************************************/ + namespace mt + { + template class In_Spt_Ptc_xd; + + template + using In_Spt_Ptc_2d = In_Spt_Ptc_xd; + } + + namespace mt + { + template + class In_Spt_Ptc_xd + { + public: + using value_type = T; + + T scf_radius; + Grid_xd grid; + Ptc_2d_2 ptc; + + In_Spt_Ptc_xd(): scf_radius(3.5) {}; + + Ptc_s_fcn_xd ptc_s_fcn(const dt_int32& iptc, const T& tap_ftr) + { + const auto r_max = scf_radius*ptc.c_2[iptc]; + const auto r_tap = tap_ftr*r_max; + + return {ptc.get_pos(iptc), ptc.c_1[iptc], ptc.c_2[iptc], r_tap, r_max, grid}; + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/incident_wave.cuh b/src - Copy (2)/incident_wave.cuh new file mode 100755 index 00000000..72dc4ce3 --- /dev/null +++ b/src - Copy (2)/incident_wave.cuh @@ -0,0 +1,130 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef INCIDENT_WAVE_H + #define INCIDENT_WAVE_H + + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "in_classes.cuh" + #include "output_multem.hpp" + #include "cpu_fcns.hpp" + #include "gpu_fcns.cuh" + + namespace mt + { + template + class Incident_Wave{ + public: + using T_r = T; + using T_c = complex; + + static const eDev device = Dev; + + Incident_Wave(): multem_in_parm(nullptr), stream(nullptr), fft_2d(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + multem_in_parm = multem_in_parm_i; + stream = stream_i; + fft_2d = fft2_i; + + if (multem_in_parm->is_user_define_wave()) + { + fpsi_0.assign(multem_in_parm->iw_psi.begin(), multem_in_parm->iw_psi.end()); + mt::fcn_fftsft_2d(*stream, multem_in_parm->grid_2d, fpsi_0); + fft_2d->forward(fpsi_0); + } + else if (multem_in_parm->is_convergent_wave()) + { + fpsi_0.resize(multem_in_parm->grid_2d.size()); + } + } + + void operator()(Vctr& psi, R_2d gu, Beam_Pos_2d& beam_pos_2d, T_r z_init=0) + { + switch(multem_in_parm->iw_type) + { + case eiwt_plane_wave: + { + mt::fill(*stream, psi, T_c(1.0, 0.0)); + } + break; + case eiwt_convergent_wave: + { + auto f_0 = multem_in_parm->cond_lens.c_10; + auto f_s = f_0 - (multem_in_parm->cond_lens.zero_def_plane-z_init); + multem_in_parm->cond_lens.set_defocus(f_s); + + mt::fill(*stream, psi, T_c(0)); + auto R = multem_in_parm->grid_2d.factor_2pi_rv_ctr(beam_pos_2d.p); + + for(auto ib=0; ibgrid_2d, multem_in_parm->cond_lens, R[ib], gu, fpsi_0); + mt::add(*stream, fpsi_0, psi); + } + fft_2d->inverse(psi); + + multem_in_parm->cond_lens.set_defocus(f_0); + } + break; + case eiwt_user_def_Wave: + { + // we need to include defocus + auto f_s = -(multem_in_parm->cond_lens.zero_def_plane-z_init); + + auto R = multem_in_parm->grid_2d.factor_2pi_rv_ctr(beam_pos_2d.p); + + mt::fcn_mul_exp_g_factor_2d(*stream, multem_in_parm->grid_2d, R, fpsi_0, psi); + + fft_2d->inverse(psi); + } + break; + } + } + + template + void operator()(const eSpace &space, TOutput_multislice &output_multem) + { + Vctr psi(multem_in_parm->grid_2d.size()); + this->operator()(psi, multem_in_parm->gu_0(), multem_in_parm->beam_pos_2d); + + if (space == esp_fourier) + { + fft_2d->forward(psi); + mt::fcn_scale(*stream, multem_in_parm->grid_2d.isize_r(), psi); + } + + mt::fcn_assign_crop_fftsft_2d(multem_in_parm->grid_2d, psi, multem_in_parm->output_area, output_multem.psi_0(0, 0)); + } + + private: + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + + Vctr fpsi_0; + }; + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/input_tomography.cuh b/src - Copy (2)/input_tomography.cuh new file mode 100755 index 00000000..96adb13a --- /dev/null +++ b/src - Copy (2)/input_tomography.cuh @@ -0,0 +1,179 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef INPUT_TOMOGRAPHY_H +#define INPUT_TOMOGRAPHY_H + +#include +#include + +#include "math.cuh" +#include "types.cuh" +#include "memory_info.cuh" +#include "lin_alg_def.cuh" + +#include "atom_data.hpp" +#include "host_device_functions.cuh" +#include "host_functions.hpp" +#include "device_functions.cuh" + +namespace mt +{ + bool is_gpu_available(); + + template + class Input_Tomography + { + public: + using value_type = T; + + ePrecision precision; + eDevice device; // eP_float = 1, eP_double = 2 + int cpu_nthread; // Number of threads + int gpu_device; // GPU device + int gpu_nstream; // Number of streams + + r3d spec_rot_u0; // unitary vector + r3d spec_rot_center_p; // rotation point + + int nstream; + Grid_2d grid_2d; // grid_bt information + + T r0_min; + T rTemp; + + eInput_Atoms input_atoms; + Atom_Data_Sa atoms; + + int Z; + Vector r; + Vector fr; + + Vector angle; + Vector, e_host> image; + + Input_Tomography(): precision(eP_double), device(e_host), cpu_nthread(4), + gpu_device(0), gpu_nstream(8), spec_rot_u0(1, 0, 0), spec_rot_center_p(1, 0, 0), + nstream(0), r0_min(0.75), rTemp(0.8), input_atoms(eIA_no), Z(0){}; + + void validate_parameters() + { + cpu_nthread = max(1, cpu_nthread); + gpu_nstream = max(1, gpu_nstream); + nstream = (is_host())?cpu_nthread:gpu_nstream; + + if(!is_float() && !is_double()) + precision = eP_float; + + if(!is_host() && !is_device()) + device = e_host; + + set_device(); + + spec_rot_u0.normalized(); + + if(!is_input_atoms()) + { + T lxyz = ::fmax(grid_2d.lx, grid_2d.ly); + r3d r_min(0, 0, 0); + r3d r_max(lxyz, lxyz, lxyz); + atoms.set_range(Z, r_min, r_max); + } + + if(r0_min<= 0) + { + r0_min = 0.75; + } + + if((rTemp<= 0)||(rTemp>= 1)) + { + rTemp = 0.8; + } + + } + + bool is_input_atoms() const + { + return input_atoms == mt::eIA_yes; + } + + bool is_host() const + { + return device == mt::e_host; + } + + bool is_device() const + { + return device == mt::e_device; + } + + void set_device() + { + if(is_device()) + { + if(!is_gpu_available()) + { + device = mt::e_host; + } + else + { + auto ngpu = number_of_gpu_available(); + gpu_device = min(max(0, gpu_device), ngpu-1); + cudaSetDevice(gpu_device); + } + } + else + { + device = mt::e_host; + } + } + + bool is_float() const + { + return precision == mt::eP_float; + } + + bool is_double() const + { + return precision == mt::eP_double; + } + + bool is_float_host() const + { + return is_float() && is_host(); + } + + bool is_double_host() const + { + return is_double() && is_host(); + } + + bool is_float_device() const + { + return is_float() && is_device(); + } + + bool is_double_device() const + { + return is_double() && is_device(); + } + }; + +} // namespace mt + +#endif \ No newline at end of file diff --git a/src - Copy (2)/intrpl_coef.cuh b/src - Copy (2)/intrpl_coef.cuh new file mode 100755 index 00000000..3423ff07 --- /dev/null +++ b/src - Copy (2)/intrpl_coef.cuh @@ -0,0 +1,903 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef INTRPL_COEF_H + #define INTRPL_COEF_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + #include + + #include "const_enum.cuh" + #include "type_traits_gen.cuh" + #include "math.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "cgpu_fcns_gen.cuh" + #include "cgpu_vctr.cuh" + #include "grid.cuh" + + /***************************************************************************************/ + /************************* linear and non-linear coefficients **************************/ + /***************************************************************************************/ + namespace mt + { + template class LNL_Coef; + + template + class pLNL_Coef + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ cl; // linear coefficient + T* __restrict__ cnl; // non-linear coefficient + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pLNL_Coef(): cl(nullptr), cnl(nullptr), m_size(0) {} + + CGPU_EXEC + pLNL_Coef(T* cl, T* cnl, const size_type& size): cl(cl), cnl(cnl), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pLNL_Coef(const pLNL_Coef& pcoef_lnl) + { + *this = pcoef_lnl; + } + + // ! constructor from LNL_Coef + explicit pLNL_Coef(const LNL_Coef& coef_lnl) + { + *this = coef_lnl; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pLNL_Coef& operator=(const pLNL_Coef& pcoef_lnl) + { + if (this != &pcoef_lnl) + { + cl = pcoef_lnl.cl; + cnl = pcoef_lnl.cnl; + m_size = pcoef_lnl.m_size; + } + + return *this; + } + + // ! Assignment operator: LNL_Coef -> pLNL_Coef + CPU_EXEC + pLNL_Coef& operator=(const LNL_Coef& coef_lnl) + { + cl = coef_lnl.cl.data(); + cnl = coef_lnl.cnl.data(); + m_size = size_type(coef_lnl.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pLNL_Coef_cpu = pLNL_Coef; + + template + using pLNL_Coef_gpu = pLNL_Coef; + + /***************************************************************************************/ + template + class LNL_Coef + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr cl; + mutable Vctr cnl; + + /************************************* constructors ************************************/ + LNL_Coef() {} + + LNL_Coef(const Vctr_cpu& cl, const Vctr_cpu& cnl): + cl(cl), cnl(cnl){} + + LNL_Coef(const dt_init_list_f64& cl, const dt_init_list_f64& cnl): + cl(cl), cnl(cnl) {} + + LNL_Coef(const size_type& new_size) + { + resize(new_size); + } + + LNL_Coef(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + LNL_Coef(const LNL_Coef& coef_lnl) + { + *this = coef_lnl; + } + + /* converting constructor */ + template + LNL_Coef(const LNL_Coef& coef_lnl) + { + *this = coef_lnl; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + LNL_Coef& operator=(const LNL_Coef& coef_lnl) + { + this->assign(coef_lnl); + + return *this; + } + + /* converting assignment operator */ + template + LNL_Coef& operator=(const LNL_Coef& coef_lnl) + { + this->assign(coef_lnl); + + return *this; + } + + template + void assign(const LNL_Coef& coef_lnl) + { + cl.assign(coef_lnl.cl); + cnl.assign(coef_lnl.cnl); + } + + /**************** user define conversion operators *******************/ + pLNL_Coef ptr() const + { + return pLNL_Coef(*this); + } + + // ! user define conversion for pointer + operator pLNL_Coef() const + { + return pLNL_Coef(*this); + } + + void fill(const T& val_l, const T& val_nl) + { + cl.fill(val_l); + cnl.fill(val_nl); + } + + size_type size() const + { + return size_type(cl.size()); + } + + void clear() + { + cl.clear(); + cnl.clear(); + } + + void reserve(const size_type& new_size) + { + cl.reserve(new_size); + cnl.reserve(new_size); + } + + void resize(const size_type& new_size) + { + cl.resize(new_size); + cnl.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + cl.resize(new_size, value); + cnl.resize(new_size, value); + } + + void shrink_to_fit() + { + cl.shrink_to_fit(); + cnl.shrink_to_fit(); + } + }; + + template + using LNL_Coef_cpu = LNL_Coef; + + template + using LNL_Coef_gpu = LNL_Coef; + } + + /***************************************************************************************/ + /*************************** linear polynomial coefficients ****************************/ + /***************************************************************************************/ + namespace mt + { + template class Poly_Coef_1d; + + template + class pPoly_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ c0; + T* __restrict__ c1; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pPoly_Coef_1d(): c0(nullptr), c1(nullptr), m_size(0) {} + + CGPU_EXEC + pPoly_Coef_1d(T* c0, T* c1, const size_type& size): c0(c0), c1(c1), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pPoly_Coef_1d(const pPoly_Coef_1d& pcoef_poly1) + { + *this = pcoef_poly1; + } + + // ! constructor from Poly_Coef_1d + explicit pPoly_Coef_1d(const Poly_Coef_1d& coef_poly1) + { + *this = coef_poly1; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pPoly_Coef_1d& operator=(const pPoly_Coef_1d& pcoef_poly1) + { + if (this != &pcoef_poly1) + { + c0 = pcoef_poly1.c0; + c1 = pcoef_poly1.c1; + m_size = pcoef_poly1.m_size; + } + + return *this; + } + + // ! Assignment operator: Poly_Coef_1d -> pPoly_Coef_1d + CPU_EXEC + pPoly_Coef_1d& operator=(const Poly_Coef_1d& coef_poly1) + { + c0 = coef_poly1.c0.data(); + c1 = coef_poly1.c1.data(); + m_size = size_type(coef_poly1.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pPoly_Coef_1d_cpu = pPoly_Coef_1d; + + template + using pPoly_Coef_1d_gpu = pPoly_Coef_1d; + + /***************************************************************************************/ + template + class Poly_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr c0; + mutable Vctr c1; + + /************************************* constructors ************************************/ + Poly_Coef_1d() {} + + Poly_Coef_1d(const Vctr_cpu& c0, const Vctr_cpu& c1): + c0(c0), c1(c1){} + + Poly_Coef_1d(const dt_init_list_f64& c0, const dt_init_list_f64& c1): + c0(c0), c1(c1) {} + + Poly_Coef_1d(const size_type& new_size) + { + resize(new_size); + } + + Poly_Coef_1d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Poly_Coef_1d(const Poly_Coef_1d& coef_poly1) + { + *this = coef_poly1; + } + + /* converting constructor */ + template + Poly_Coef_1d(const Poly_Coef_1d& coef_poly1) + { + *this = coef_poly1; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Poly_Coef_1d& operator=(const Poly_Coef_1d& coef_poly1) + { + this->assign(coef_poly1); + + return *this; + } + + /* converting assignment operator */ + template + Poly_Coef_1d& operator=(const Poly_Coef_1d& coef_poly1) + { + this->assign(coef_poly1); + + return *this; + } + + template + void assign(const Poly_Coef_1d& coef_poly1) + { + c0.assign(coef_poly1.c0); + c1.assign(coef_poly1.c1); + } + + /**************** user define conversion operators *******************/ + pPoly_Coef_1d ptr() const + { + return pPoly_Coef_1d(*this); + } + + // ! user define conversion for pointer Vctr + operator pPoly_Coef_1d() const + { + return pPoly_Coef_1d(*this); + } + + void fill(const T& val_c0, const T& val_c1) + { + c0.fill(val_c0); + c1.fill(val_c1); + } + + size_type size() const + { + return c0.size(); + } + + void clear() + { + c0.clear(); + c1.clear(); + } + + void reserve(const size_type& new_size) + { + c0.reserve(new_size); + c1.reserve(new_size); + } + + void resize(const size_type& new_size) + { + c0.resize(new_size); + c1.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + c0.resize(new_size, value); + c1.resize(new_size, value); + } + + void shrink_to_fit() + { + c0.shrink_to_fit(); + c1.shrink_to_fit(); + } + }; + + template + using Poly_Coef_1d_cpu = Poly_Coef_1d; + + template + using Poly_Coef_1d_gpu = Poly_Coef_1d; + } + + /***************************************************************************************/ + /************************* quadratic polynomial coefficients ***************************/ + /***************************************************************************************/ + namespace mt + { + template class Poly_Coef_2d; + + template + class pPoly_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ c0; + T* __restrict__ c1; + T* __restrict__ c2; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pPoly_Coef_2d(): c0(nullptr), c1(nullptr), c2(nullptr), m_size(0) {} + + CGPU_EXEC + pPoly_Coef_2d(T* c0, T* c1, T* c2, const size_type& size): c0(c0), c1(c1), c2(c2), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pPoly_Coef_2d(const pPoly_Coef_2d& pcoef_poly2) + { + *this = pcoef_poly2; + } + + // ! constructor from Poly_Coef_2d + explicit pPoly_Coef_2d(const Poly_Coef_2d& coef_poly2) + { + *this = coef_poly2; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pPoly_Coef_2d& operator=(const pPoly_Coef_2d& pcoef_poly2) + { + if (this != &pcoef_poly2) + { + c0 = pcoef_poly2.c0; + c1 = pcoef_poly2.c1; + c2 = pcoef_poly2.c2; + m_size = pcoef_poly2.m_size; + } + + return *this; + } + + // ! Assignment operator: Poly_Coef_2d -> pPoly_Coef_2d + CPU_EXEC + pPoly_Coef_2d& operator=(const Poly_Coef_2d& coef_poly2) + { + c0 = coef_poly2.c0.data(); + c1 = coef_poly2.c1.data(); + c2 = coef_poly2.c2.data(); + m_size = size_type(coef_poly2.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pPoly_Coef_2d_cpu = pPoly_Coef_2d; + + template + using pPoly_Coef_2d_gpu = pPoly_Coef_2d; + + /***************************************************************************************/ + template + class Poly_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr c0; + mutable Vctr c1; + mutable Vctr c2; + + /************************************* constructors ************************************/ + Poly_Coef_2d() {} + + Poly_Coef_2d(const Vctr_cpu& c0, const Vctr_cpu& c1, const Vctr_cpu& c2): + c0(c0), c1(c1), c2(c2){} + + Poly_Coef_2d(const dt_init_list_f64& c0, const dt_init_list_f64& c1, const dt_init_list_f64& c2): + c0(c0), c1(c1), c2(c2) {} + + Poly_Coef_2d(const size_type& new_size) + { + resize(new_size); + } + + Poly_Coef_2d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Poly_Coef_2d(const Poly_Coef_2d& coef_poly2) + { + *this = coef_poly2; + } + + /* converting constructor */ + template + Poly_Coef_2d(const Poly_Coef_2d& coef_poly2) + { + *this = coef_poly2; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Poly_Coef_2d& operator=(const Poly_Coef_2d& coef_poly2) + { + this->assign(coef_poly2); + + return *this; + } + + /* converting assignment operator */ + template + Poly_Coef_2d& operator=(const Poly_Coef_2d& coef_poly2) + { + this->assign(coef_poly2); + + return *this; + } + + template + void assign(const Poly_Coef_2d& coef_poly2) + { + c0.assign(coef_poly2.c0); + c1.assign(coef_poly2.c1); + c2.assign(coef_poly2.c2); + } + + /**************** user define conversion operators *******************/ + pPoly_Coef_2d ptr() const + { + return pPoly_Coef_2d(*this); + } + + // ! user define conversion for pointer Vctr + operator pPoly_Coef_2d() const + { + return pPoly_Coef_2d(*this); + } + + void fill(const T& val_c0, const T& val_c1, const T& val_c2) + { + c0.fill(val_c0); + c1.fill(val_c1); + c2.fill(val_c2); + } + + size_type size() const + { + return c0.size(); + } + + void clear() + { + c0.clear(); + c1.clear(); + c2.clear(); + } + + void reserve(const size_type& new_size) + { + c0.reserve(new_size); + c1.reserve(new_size); + c2.reserve(new_size); + } + + void resize(const size_type& new_size) + { + c0.resize(new_size); + c1.resize(new_size); + c2.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + c0.resize(new_size, value); + c1.resize(new_size, value); + c2.resize(new_size, value); + } + + void shrink_to_fit() + { + c0.shrink_to_fit(); + c1.shrink_to_fit(); + c2.shrink_to_fit(); + } + }; + + template + using Poly_Coef_2d_cpu = Poly_Coef_2d; + + template + using Poly_Coef_2d_gpu = Poly_Coef_2d; + } + + /***************************************************************************************/ + /************************** cubic interpolation coefficients ***************************/ + /***************************************************************************************/ + namespace mt + { + template class Poly_Coef_3d; + + template + class pPoly_Coef_3d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ c0; + T* __restrict__ c1; + T* __restrict__ c2; + T* __restrict__ c3; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pPoly_Coef_3d(): c0(nullptr), c1(nullptr), c2(nullptr), c3(nullptr), m_size(0) {} + + CGPU_EXEC + pPoly_Coef_3d(T* c0, T* c1, T* c2, T* c3, const size_type& size): c0(c0), c1(c1), c2(c2), c3(c3), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pPoly_Coef_3d(const pPoly_Coef_3d& pcoef_poly3) + { + *this = pcoef_poly3; + } + + // ! constructor from Poly_Coef_3d + explicit pPoly_Coef_3d(const Poly_Coef_3d& coef_poly3) + { + *this = coef_poly3; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pPoly_Coef_3d& operator=(const pPoly_Coef_3d& pcoef_poly3) + { + if (this != &pcoef_poly3) + { + c0 = pcoef_poly3.c0; + c1 = pcoef_poly3.c1; + c2 = pcoef_poly3.c2; + c3 = pcoef_poly3.c3; + m_size = pcoef_poly3.m_size; + } + + return *this; + } + + // ! Assignment operator: Poly_Coef_3d -> pPoly_Coef_3d + CPU_EXEC + pPoly_Coef_3d& operator=(const Poly_Coef_3d& coef_poly3) + { + c0 = coef_poly3.c0.data(); + c1 = coef_poly3.c1.data(); + c2 = coef_poly3.c2.data(); + c3 = coef_poly3.c3.data(); + m_size = size_type(coef_poly3.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pPoly_Coef_3d_cpu = pPoly_Coef_3d; + + template + using pPoly_Coef_3d_gpu = pPoly_Coef_3d; + + /***************************************************************************************/ + template + class Poly_Coef_3d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr c0; + mutable Vctr c1; + mutable Vctr c2; + mutable Vctr c3; + + /************************************* constructors ************************************/ + Poly_Coef_3d() {} + + Poly_Coef_3d(const Vctr_cpu& c0, const Vctr_cpu& c1, const Vctr_cpu& c2, const Vctr_cpu& c3): + c0(c0), c1(c1), c2(c2), c3(c3){} + + Poly_Coef_3d(const dt_init_list_f64& c0, const dt_init_list_f64& c1, const dt_init_list_f64& c2, const dt_init_list_f64& c3): + c0(c0), c1(c1), c2(c2), c3(c3) {} + + Poly_Coef_3d(const size_type& new_size) + { + resize(new_size); + } + + Poly_Coef_3d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Poly_Coef_3d(const Poly_Coef_3d& coef_poly3) + { + *this = coef_poly3; + } + + /* converting constructor */ + template + Poly_Coef_3d(const Poly_Coef_3d& coef_poly3) + { + *this = coef_poly3; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Poly_Coef_3d& operator=(const Poly_Coef_3d& coef_poly3) + { + this->assign(coef_poly3); + + return *this; + } + + /* converting assignment operator */ + template + Poly_Coef_3d& operator=(const Poly_Coef_3d& coef_poly3) + { + this->assign(coef_poly3); + + return *this; + } + + template + void assign(const Poly_Coef_3d& coef_poly3) + { + c0.assign(coef_poly3.c0); + c1.assign(coef_poly3.c1); + c2.assign(coef_poly3.c2); + c3.assign(coef_poly3.c3); + } + + /**************** user define conversion operators *******************/ + pPoly_Coef_3d ptr() const + { + return pPoly_Coef_3d(*this); + } + + // ! user define conversion for pointer Vctr + operator pPoly_Coef_3d() const + { + return pPoly_Coef_3d(*this); + } + + void fill(const T& val_c0, const T& val_c1, const T& val_c2, const T& val_c3) + { + c0.fill(val_c0); + c1.fill(val_c1); + c2.fill(val_c2); + c3.fill(val_c3); + } + + size_type size() const + { + return c0.size(); + } + + void clear() + { + c0.clear(); + c1.clear(); + c2.clear(); + c3.clear(); + } + + void reserve(const size_type& new_size) + { + c0.reserve(new_size); + c1.reserve(new_size); + c2.reserve(new_size); + c3.reserve(new_size); + } + + void resize(const size_type& new_size) + { + c0.resize(new_size); + c1.resize(new_size); + c2.resize(new_size); + c3.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + c0.resize(new_size, value); + c1.resize(new_size, value); + c2.resize(new_size, value); + c3.resize(new_size, value); + } + + void shrink_to_fit() + { + c0.shrink_to_fit(); + c1.shrink_to_fit(); + c2.shrink_to_fit(); + c3.shrink_to_fit(); + } + }; + + template + using Poly_Coef_3d_cpu = Poly_Coef_3d; + + template + using Poly_Coef_3d_gpu = Poly_Coef_3d; + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/ithread_rect.cuh b/src - Copy (2)/ithread_rect.cuh new file mode 100755 index 00000000..a7fa6d52 --- /dev/null +++ b/src - Copy (2)/ithread_rect.cuh @@ -0,0 +1,562 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ITHREAD_RECT_H + #define ITHREAD_RECT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + + /***************************************************************************************/ + /********************** iThread_Rect template forward declaration **********************/ + /***************************************************************************************/ + namespace mt + { + template class iThread_Rect_sxd; + + template + using iThread_Rect_xd = iThread_Rect_sxd; + + /* 1d */ + template + using iThread_Rect_1d_st = iThread_Rect_sxd; + + using iThread_Rect_1d = iThread_Rect_sxd; + + using iThread_Rect_1d_64 = iThread_Rect_sxd; + + /* 2d */ + template + using iThread_Rect_2d_st = iThread_Rect_sxd; + + using iThread_Rect_2d = iThread_Rect_sxd; + + using iThread_Rect_2d_64 = iThread_Rect_sxd; + + /* 3d */ + template + using iThread_Rect_3d_st = iThread_Rect_sxd; + + using iThread_Rect_3d = iThread_Rect_sxd; + + using iThread_Rect_3d_64 = iThread_Rect_sxd; + } + + /* template specialization 1d */ + namespace mt + { + template + class iThread_Rect_sxd + { + public: + using size_type = ST; + + ST ind_0; // initial linear index + ST ind_e; // final linear index + + ST ix_0; // x initial index + ST ix_e; // x final index + + dt_int32 istm; // stream number + + /************************************* constructors ************************************/ + iThread_Rect_sxd(): ix_0(0), ix_e(0), ind_0(0), ind_e(0), istm(0) {} + + iThread_Rect_sxd(const dt_init_list_int32& list): istm(0) + { + auto ptr = list.begin(); + + ix_0 = ptr[0]; + ix_e = ptr[1]; + + ind_0 = ST(0); + ind_e = size(); + } + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e): ix_0(ix_0), ix_e(ix_e), istm(0) + { + ind_0 = ST(0); + ind_e = size(); + } + + iThread_Rect_sxd(const ST& nx): ix_0(0), ix_e(nx), istm(0) + { + ind_0 = ST(0); + ind_e = size(); + } + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& ind_0, const ST& ind_e) + : ix_0(ix_0), ix_e(ix_e), ind_0(ind_0), ind_e(ind_e), istm(0) {} + + /* copy constructor */ + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /* converting constructor */ + template + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + ix_0 = ithread.ix_0; + ix_e = ithread.ix_e; + + ind_0 = ithread.ind_0; + ind_e = ithread.ind_e; + + istm = ithread.istm; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + ix_0 = ST(ithread.ix_0); + ix_e = ST(ithread.ix_e); + + ind_0 = ST(ithread.ind_0); + ind_e = ST(ithread.ind_e); + + istm = ithread.istm; + } + + return *this; + } + + template + CGPU_EXEC + void assign(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /***************************************************************************************/ + CGPU_EXEC + void clear() + { + ix_0 = ST(0); + ix_e = ST(0); + + ind_0 = ST(0); + ind_e = ST(0); + + istm = 0; + } + + CGPU_EXEC + ST nx() const + { + return ix_e - ix_0; + } + + CGPU_EXEC + ST size() const + { + return nx(); + } + + CGPU_EXEC + dt_bool chk_bound_ix(const ST& ix) const + { + return fcn_chk_bound(ix, ix_0, ix_e); + } + + CGPU_EXEC + dt_bool chk_bound(const ST& ix) const + { + return chk_bound_ix(ix); + } + + CGPU_EXEC + void apply_bound_ix(const ST& ix_0, const ST& ix_e) + { + this->ix_0 = fcn_set_bound(this->ix_0, ix_0, ix_e); + this->ix_e = fcn_set_bound(this->ix_e, ix_0, ix_e); + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix) const + { + return ix-ix_0; + } + + CGPU_EXEC + void set_ind(const ST& ind_0, const ST& ind_e) + { + this->ind_0 = ind_0; + this->ind_e = ind_e; + } + + void set_ind_asc_order() + { + if (ix_0>ix_e) + { + std::swap(ix_0, ix_e); + } + } + + }; + } + + /* template specialization 2d */ + namespace mt + { + template + class iThread_Rect_sxd: public iThread_Rect_sxd + { + public: + using size_type = ST; + + ST iy_0; // y initial index + ST iy_e; // y final index + + /************************************* constructors ************************************/ + iThread_Rect_sxd(): iThread_Rect_sxd(), iy_0(0), iy_e(0) {} + + iThread_Rect_sxd(const dt_init_list_int32& list) + { + auto ptr = list.begin(); + + this->ix_0 = ptr[0]; + this->ix_e = ptr[1]; + this->iy_0 = ptr[2]; + this->iy_e = ptr[3]; + + this->istm = 0; + + this->ind_0 = ST(0); + this->ind_e = size(); + } + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e) + : iThread_Rect_sxd(ix_0, ix_e), iy_0(iy_0), iy_e(iy_e) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + iThread_Rect_sxd(const ST& nx, const ST& ny) + : iThread_Rect_sxd(nx), iy_0(0), iy_e(ny) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& ind_0, const ST& ind_e) + : iThread_Rect_sxd(ix_0, ix_e, ind_0, ind_e), iy_0(iy_0), iy_e(iy_e) {} + + /* copy constructor */ + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /* converting constructor */ + template + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iy_0 = ithread.iy_0; + iy_e = ithread.iy_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iy_0 = ST(ithread.iy_0); + iy_e = ST(ithread.iy_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /***************************************************************************************/ + CGPU_EXEC + void clear() + { + iThread_Rect_sxd::clear(); + + iy_0 = ST(0); + iy_e = ST(0); + } + + + CGPU_EXEC + ST ny() const + { + return iy_e - iy_0; + } + + CGPU_EXEC + ST size() const + { + return iThread_Rect_sxd::size()*ny(); + } + + + CGPU_EXEC + dt_bool chk_bound_iy(const ST& iy) const + { + return fcn_chk_bound(iy, iy_0, iy_e); + } + + CGPU_EXEC + dt_bool chk_bound(const ST& ix, const ST& iy) const + { + return this->chk_bound_ix(ix) && chk_bound_iy(iy); + } + + CGPU_EXEC + void apply_bound_iy(const ST& iy_0, const ST& iy_e) + { + this->iy_0 = fcn_set_bound(this->iy_0, iy_0, iy_e); + this->iy_e = fcn_set_bound(this->iy_e, iy_0, iy_e); + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy) const + { + return (iy-iy_0) + (ix-this->ix_0)*ny(); + } + + void set_ind_asc_order() + { + iThread_Rect_sxd::set_ind_asc_order(); + + if (iy_0>iy_e) + { + std::swap(iy_0, iy_e); + } + } + + }; + } + + /* template specialization 3d */ + namespace mt + { + template + class iThread_Rect_sxd: public iThread_Rect_sxd + { + public: + using size_type = ST; + + ST iz_0; // z initial index + ST iz_e; // z final index + + /************************************* constructors ************************************/ + iThread_Rect_sxd(): iThread_Rect_sxd(), iz_0(0), iz_e(0) {} + + iThread_Rect_sxd(const dt_init_list_int32& list) + { + auto ptr = list.begin(); + + this->ix_0 = ptr[0]; + this->ix_e = ptr[1]; + this->iy_0 = ptr[2]; + this->iy_e = ptr[3]; + this->iz_0 = ptr[4]; + this->iz_e = ptr[5]; + + this->istm = 0; + + this->ind_0 = ST(0); + this->ind_e = size(); + } + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& iz_0, const ST& iz_e) + : iThread_Rect_sxd(ix_0, ix_e, iy_0, iy_e), iz_0(iz_0), iz_e(iz_e) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + iThread_Rect_sxd(const ST& nx, const ST& ny, const ST& nz) + : iThread_Rect_sxd(nx, ny), iz_0(0), iz_e(nz) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& iz_0, const ST& iz_e, const ST& ind_0, const ST& ind_e) + : iThread_Rect_sxd(ix_0, ix_e, iy_0, iy_e, ind_0, ind_e), iz_0(iz_0), iz_e(iz_e) {} + + /* copy constructor */ + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /* converting constructor */ + template + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iz_0 = ithread.iz_0; + iz_e = ithread.iz_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iz_0 = ST(ithread.iz_0); + iz_e = ST(ithread.iz_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /***************************************************************************************/ + CGPU_EXEC + void clear() + { + iThread_Rect_sxd::clear(); + + iz_0 = ST(0); + iz_e = ST(0); + } + + CGPU_EXEC + ST nz() const + { + return iz_e - iz_0; + } + + CGPU_EXEC + ST size() const + { + return iThread_Rect_sxd::size()*nz(); + } + + CGPU_EXEC + dt_bool chk_bound_iz(const ST& iz) const + { + return fcn_chk_bound(iz, iz_0, iz_e); + } + + CGPU_EXEC + dt_bool chk_bound(const ST& ix, const ST& iy, const ST& iz) const + { + return this->chk_bound_ix(ix) && this->chk_bound_iy(iy) && chk_bound_iz(iz); + } + + CGPU_EXEC + void apply_bound_iz(const ST& iz_0, const ST& iz_e) + { + this->iz_0 = fcn_set_bound(this->iz_0, iz_0, iz_e); + this->iz_e = fcn_set_bound(this->iz_e, iz_0, iz_e); + } + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy, const ST& iz) const + { + return (iy-this->iy_0) + (ix-this->ix_0)*this->ny_s() + (iz-iz_0)*this->ny()*this->nx(); + } + + void set_ind_asc_order() + { + iThread_Rect_sxd::set_ind_asc_order(); + + if (iz_0>iz_e) + { + std::swap(iz_0, iz_e); + } + } + + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/kahan_sum.cuh b/src - Copy (2)/kahan_sum.cuh new file mode 100755 index 00000000..50dd8ec8 --- /dev/null +++ b/src - Copy (2)/kahan_sum.cuh @@ -0,0 +1,275 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef KAHAN_SUM_H + #define KAHAN_SUM_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "macros.cuh" + + namespace mt + { + /***************************************************************************************/ + /**************************** Kahan summation algorithm ********************************/ + /* https:// en.wikipedia.org/wiki/Kahan_summation_algorithmnnn */ + /***************************************************************************************/ + template + class KS + { + public: + using value_type = T; + + T m_sum; + T m_error; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + KS(): m_sum(0), m_error(0) {} + + /* Copy constructor */ + CGPU_EXEC + KS(const T& sum, T error=0): m_sum(sum), m_error(error) {} + + /* Copy constructor */ + CGPU_EXEC + KS(const KS& ks) + { + *this = ks; + } + + /* Move constructor */ + CGPU_EXEC + KS(KS&& ks) + { + *this = std::move(ks); + } + + /* converting copy constructor */ + template + CGPU_EXEC + KS(const KS& ks) + { + *this = ks; + } + + /******************************** assignment operators *********************************/ + // ! constructor from r + CGPU_EXEC + KS& operator=(const T& r) + { + m_sum = r; + m_error = 0; + + return *this; + } + + /* copy assignment operator */ + CGPU_EXEC + KS& operator=(const KS& ks) + { + m_sum = ks.m_sum; + m_error = ks.m_error; + + return *this; + } + + /* Move assignment operator */ + CGPU_EXEC + KS& operator=(KS&& ks) + { + m_sum = std::move(ks.m_sum); + m_error = std::move(ks.m_error); + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + KS& operator=(const KS& ks) + { + m_sum = T(ks.m_sum); + m_error = T(ks.m_error); + + return *this; + } + + // user define conversion + CGPU_EXEC + T operator()() + { + return m_sum; + } + + + // user define conversion + CGPU_EXEC + operator T() + { + return m_sum; + } + + /******************* Compound assignment operators *******************/ + CGPU_EXEC + KS& operator+=(T r) + { + this->add(r); + + return *this; + } + + CGPU_EXEC + KS& operator+=(const KS& r) + { + this->add(r.m_sum); + + return *this; + } + + CGPU_EXEC + KS& operator-=(T r) + { + this->add(-r); + + return *this; + } + + CGPU_EXEC + KS& operator-=(const KS& r) + { + this->add(-r.m_sum); + + return *this; + } + + CGPU_EXEC + KS& operator/=(T r) + { + *this = *this/r; + + return *this; + } + + CGPU_EXEC + KS& operator/=(const KS& r) + { + *this = *this/r; + + return *this; + } + + CGPU_EXEC + void add(T r) + { + r = r - m_error; + T t = m_sum + r; // m_sum is big, r small, so low-order digits of r are lost. + m_error = (t-m_sum)-r; // (t - m_sum) cancels the high-order part of r;subtracting r recovers negative (low part of r) + m_sum = t; // Algebraically, m_error should always be zero. Beware overly-aggressive optimizing compilers! + + // Next time around, the lost low part will be added to y in a fresh attempt + } + }; + + /******************** Unitary arithmetic operators ********************/ + template + CGPU_EXEC + KS operator-(const KS& r) + { + return {-r.m_sum, r.m_error}; + } + + template + CGPU_EXEC + KS operator+(const KS& lhs, const KS& rhs) + { + KS ks(lhs); + ks += rhs; + return ks; + } + + template + CGPU_EXEC + KS operator+(const KS& lhs, const T& rhs) + { + KS ks(lhs); + ks += rhs; + return ks; + } + + template + CGPU_EXEC + KS operator+(const T& lhs, const KS& rhs) + { + KS ks(lhs); + ks += rhs; + return ks; + } + + template + CGPU_EXEC + KS operator-(const KS& lhs, const KS& rhs) + { + KS ks(lhs); + ks -= rhs; + return ks; + } + + template + CGPU_EXEC + KS operator-(const KS& lhs, const T& rhs) + { + KS ks(lhs); + ks -= rhs; + return ks; + } + + template + CGPU_EXEC + KS operator-(const T& lhs, const KS& rhs) + { + KS ks(lhs); + ks -= rhs; + return ks; + } + + template + CGPU_EXEC + T operator/(const KS& lhs, const KS& rhs) + { + return lhs.m_sum/rhs.m_sum; + } + + template + CGPU_EXEC + T operator/(const KS& lhs, const T& rhs) + { + return lhs.m_sum/rhs; + } + + template + CGPU_EXEC + T operator/(const T& lhs, const KS& rhs) + { + return lhs/rhs.m_sum; + } + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/lapack.hpp b/src - Copy (2)/lapack.hpp new file mode 100755 index 00000000..c05663a2 --- /dev/null +++ b/src - Copy (2)/lapack.hpp @@ -0,0 +1,812 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef LAPACK_H + #define LAPACK_H + + #ifdef _MSC_VER + #pragma once + #endif + + #if defined(_WIN32) && defined(MATLAB_BLAS_LAPACK) + #define ssyevr_ ssyevr + #define dsyevr_ dsyevr + #define sgesv_ sgesv + #define dgesv_ dgesv + #define sgels_ sgels + #define dgels_ dgels + #define sgelsd_ sgelsd + #define dgelsd_ dgelsd + #endif + + #include "macros.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "types.cuh" + #include "cgpu_vctr.cuh" + + namespace lapack + { + extern "C" void ssyevr_( + const char* jobz, + const char* range, + const char* uplo, + const MTL_BL_INT* n, + dt_float32* a, + const MTL_BL_INT* lda, + const dt_float32* vl, + const dt_float32* vu, + const MTL_BL_INT* il, + const MTL_BL_INT* iu, + const dt_float32* abstol, + MTL_BL_INT* m, + dt_float32* w, + dt_float32* z, + const MTL_BL_INT* ldz, + MTL_BL_INT* isuppz, + dt_float32* work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + const MTL_BL_INT* liwork, + MTL_BL_INT* info + ); + + extern "C" void dsyevr_( + const char* jobz, + const char* range, + const char* uplo, + const MTL_BL_INT* n, + dt_float64* a, + const MTL_BL_INT* lda, + const dt_float64* vl, + const dt_float64* vu, + const MTL_BL_INT* il, + const MTL_BL_INT* iu, + const dt_float64* abstol, + MTL_BL_INT* m, + dt_float64* w, + dt_float64* z, + const MTL_BL_INT* ldz, + MTL_BL_INT* isuppz, + dt_float64* work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + const MTL_BL_INT* liwork, + MTL_BL_INT* info + ); + + extern "C" void sgesv_( + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float32* a, + const MTL_BL_INT* lda, + MTL_BL_INT* ipiv, + dt_float32* b, + const MTL_BL_INT* ldb, + MTL_BL_INT* info + ); + + extern "C" void dgesv_( + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float64* a, + const MTL_BL_INT* lda, + MTL_BL_INT* ipiv, + dt_float64* b, + const MTL_BL_INT* ldb, + MTL_BL_INT* info + ); + + extern "C" void sgels_( + const char *trans, + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float32 *a, + const MTL_BL_INT* lda, + dt_float32 *b, + const MTL_BL_INT* ldb, + dt_float32 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* info + ); + + extern "C" void dgels_( + const char *trans, + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float64 *a, + const MTL_BL_INT* lda, + dt_float64 *b, + const MTL_BL_INT* ldb, + dt_float64 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* info + ); + + extern "C" void sgelsd_( + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + const dt_float32 *a, + const MTL_BL_INT* lda, + dt_float32 *b, + const MTL_BL_INT* ldb, + dt_float32 *s, + const dt_float32 *rcond, + MTL_BL_INT* rank, + dt_float32 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + MTL_BL_INT* info + ); + + extern "C" void dgelsd_( + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + const dt_float64 *a, + const MTL_BL_INT* lda, + dt_float64 *b, + const MTL_BL_INT* ldb, + dt_float64 *s, + const dt_float64 *rcond, + MTL_BL_INT* rank, + dt_float64 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + MTL_BL_INT* info + ); + + /* computes eigenvalue of a real symmetric matrix A */ + template + struct EIGR + { + public: + using value_type = T; + + const mt::eDev device; + + EIGR(): jobz('N'), range('I'), uplo('U'), n(0), lda(0), vl(0), vu(0), + il(1), iu(1), abstol(0), m(0), ldz(0), lwork(0), liwork(0), info(0), device(mt::edev_cpu) {} + + EIGR(MTL_BL_INT n_i): jobz('N'), range('I'), uplo('U'), n(n_i), lda(0), vl(0), vu(0), + il(1), iu(1), abstol(0), m(0), ldz(0), lwork(0), liwork(0), info(0), device(mt::edev_cpu) + { + init(n_i); + } + + // get eigenvalues + T operator()(T* AS, MTL_BL_INT idx=1) + { + il = max(1, idx); + iu = min(n, idx); + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + return w[0]; + } + + // get min eigenvalue + T eig_min(T* AS) + { + il = 1; + iu = 1; + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + return w[0]; + } + + // get max eigenvalue + T eig_max(T* AS) + { + il = n; + iu = n; + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + return w[0]; + } + + // get max eigenvalue + void eig_min_max(T* AS, T& eig_min, T& eig_max) + { + il = 1; + iu = n; + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + eig_min = w[0]; + eig_max = w[n-1]; + } + + void init(MTL_BL_INT n_i) + { + n = n_i; + lda = n; + vl = 0.0; + vu = 0.0; + il = 1; + iu = 1; + abstol = -1; + ldz = n; + + // (n*n-n)/2+n + MS.resize(n*n); + w.resize(n); + z.resize(n*n); + isuppz.resize(2*n); + + // query optimal size of work array + lwork = -1; + liwork = -1; + T work_query = 0; + MTL_BL_INT iwork_query = 0; + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), &work_query, lwork, &iwork_query, liwork, info); + + // set arrays + lwork = max(1, MTL_BL_INT(work_query)); + work.resize(lwork); + + liwork = max(1, iwork_query); + iwork.resize(liwork); + } + + private: + void syevr_c(const char &jobz, const char &range, const char &uplo, const MTL_BL_INT& n, dt_float32 *a, + const MTL_BL_INT& lda, const dt_float32 &vl, const dt_float32 &vu, const MTL_BL_INT& il, const MTL_BL_INT& iu, + const dt_float32 &abstol, MTL_BL_INT& m, dt_float32 *w, dt_float32 *z, const MTL_BL_INT& ldz, MTL_BL_INT* isuppz, dt_float32 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, const MTL_BL_INT& liwork, MTL_BL_INT& info) + { + ssyevr_(&jobz, &range, &uplo, &n, a, &lda, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info); + } + + void syevr_c(const char &jobz, const char &range, const char &uplo, const MTL_BL_INT& n, dt_float64 *a, + const MTL_BL_INT& lda, const dt_float64 &vl, const dt_float64 &vu, const MTL_BL_INT& il, const MTL_BL_INT& iu, + const dt_float64 &abstol, MTL_BL_INT& m, dt_float64 *w, dt_float64 *z, const MTL_BL_INT& ldz, MTL_BL_INT* isuppz, dt_float64 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, const MTL_BL_INT& liwork, MTL_BL_INT& info) + { + dsyevr_(&jobz, &range, &uplo, &n, a, &lda, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info); + } + + char jobz; + char range; + char uplo; + mt::Vctr_cpu MS; + MTL_BL_INT n; + MTL_BL_INT lda; + T vl; + T vu; + MTL_BL_INT il; + MTL_BL_INT iu; + T abstol; + MTL_BL_INT m; + mt::Vctr_cpu w; + mt::Vctr_cpu z; + MTL_BL_INT ldz; + mt::Vctr_cpu isuppz; + mt::Vctr_cpu work; + MTL_BL_INT lwork; + mt::Vctr_cpu iwork; + MTL_BL_INT liwork; + MTL_BL_INT info; + }; + + /* Fast least square fitting */ + template + struct LSF_1 + { + public: + using value_type = T; + + const mt::eDev device; + + LSF_1(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, T* b, T* x) + { + using TVctr = mt::Vctr_cpu; + + // get ATA + TVctr M; + M.reserve(A_cols*A_cols); + + for(auto ir=0; ir ipiv(n); + + gesv_c(n, nrhs, M.data(), lda, ipiv.data(), y.data(), ldb, info); + std::copy(y.begin(), y.end(), x); + } + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, T* b, T* x, T lambda, T* D, T* G) + { + using TVctr = mt::Vctr_cpu; + + // get ATA + TVctr M; + M.reserve(A_cols*A_cols); + + for(auto ir=0; ir ipiv(n); + + gesv_c(n, nrhs, M.data(), lda, ipiv.data(), y.data(), ldb, info); + std::copy(y.begin(), y.end(), x); + } + + private: + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float32 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + sgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float64 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + dgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + mt::Vctr_cpu ipiv; + mt::Vctr_cpu M; + mt::Vctr_cpu y; + }; + + /* RQ minimum-norm solution */ + template + struct MNS_QR + { + public: + using value_type = T; + + const mt::eDev device; + + MNS_QR(): trans('N'), info(0), lwork(-1), m(0), n(0), device(mt::edev_cpu) {} + + MNS_QR(MTL_BL_INT A_rows, MTL_BL_INT A_cols): trans('N'), info(0), lwork(-1), m(A_rows), n(A_cols), device(mt::edev_cpu) + { + init(A_rows, A_cols); + } + + void operator()(T* A, T* b, T* x) + { + MTL_BL_INT nrhs = 1; + MTL_BL_INT lda = n; + MTL_BL_INT ldb = n; + + std::copy(A, A+m*n, M.begin()); + std::copy(b, b+n, y.begin()); + + // perform minimum-norm solution + gels_c(trans, m, n, nrhs, M.data(), lda, y.data(), ldb, work.data(), lwork, info); + std::copy(y.begin(), y.end(), x); + } + + T operator()(T* A, T* b, T* x, T lambda) + { + MTL_BL_INT nrhs = 1; + MTL_BL_INT lda = n; + MTL_BL_INT ldb = n; + + std::copy(A, A+m*n, M.begin()); + std::copy(b, b+n, y.begin()); + + // get lambda and get maximum gradient + T G_max = 0; + for(auto ic=0; ic(1, MTL_BL_INT(work_query)); + work.resize(lwork); + } + + private: + void gels_c(const char &trans, const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, + const MTL_BL_INT& lda, dt_float32 *b, const MTL_BL_INT& ldb, dt_float32 *work, const MTL_BL_INT& lwork, MTL_BL_INT& info) + { + sgels_(&trans, &m, &n, &nrhs, a, &lda, b, &ldb, work, &lwork, &info); + } + + void gels_c(const char &trans, const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, + const MTL_BL_INT& lda, dt_float64 *b, const MTL_BL_INT& ldb, dt_float64 *work, const MTL_BL_INT& lwork, MTL_BL_INT& info) + { + dgels_(&trans, &m, &n, &nrhs, a, &lda, b, &ldb, work, &lwork, &info); + } + + const char trans; + MTL_BL_INT info; + MTL_BL_INT lwork; + MTL_BL_INT m; + MTL_BL_INT n; + mt::Vctr_cpu work; + + mt::Vctr_cpu M; + mt::Vctr_cpu y; + }; + + /* SVD minimum-norm solution */ + template + struct MNS_SVD + { + public: + using value_type = T; + + const mt::eDev device; + + MNS_SVD(): rcond(-1), info(0), rank(0), lwork(-1), m(0), n(0), device(mt::edev_cpu) {} + MNS_SVD(MTL_BL_INT A_rows, MTL_BL_INT A_cols): rcond(-1), info(0), rank(0), lwork(-1), m(A_rows), n(A_cols), device(mt::edev_cpu) + { + init(A_rows, A_cols); + } + + void operator()(T* A, T* b, T* x) + { + std::copy(A, A+m*n, M.begin()); + std::copy(b, b+n, y.begin()); + + // perform minimum-norm solution + gelsd_c(m, n, nrhs, M.data(), lda, y.data(), ldb, S.data(), rcond, rank, work.data(), lwork, iwork.data(), info); + std::copy(y.begin(), y.end(), x); + } + + void init(MTL_BL_INT A_rows, MTL_BL_INT A_cols) + { + m = A_rows; + n = A_cols; + + nrhs = 1; + lda = n; + ldb = n; + + S.resize(n); + M.resize(m*n); + y.resize(n); + + // query optimal size of work array + lwork = -1; + T work_query = 0; + MTL_BL_INT iwork_query = 0; + gelsd_c(m, n, nrhs, M.data(), lda, y.data(), ldb, S.data(), rcond, rank, &work_query, lwork, &iwork_query, info); + + // set arrays + lwork = max(1000, MTL_BL_INT(work_query)); + work.resize(lwork); + + liwork = max(1, iwork_query); + iwork.resize(liwork); + } + + private: + void gelsd_c(const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, const MTL_BL_INT& lda, + dt_float32 *b, const MTL_BL_INT& ldb, dt_float32 *s, const dt_float32 &rcond, MTL_BL_INT& rank, dt_float32 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, MTL_BL_INT& info) + { + sgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work, &lwork, iwork, &info); + } + + void gelsd_c(const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, const MTL_BL_INT& lda, + dt_float64 *b, const MTL_BL_INT& ldb, dt_float64 *s, const dt_float64 &rcond, MTL_BL_INT& rank, dt_float64 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, MTL_BL_INT& info) + { + dgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work, &lwork, iwork, &info); + } + + MTL_BL_INT m; + MTL_BL_INT n; + MTL_BL_INT nrhs; + MTL_BL_INT lda; + MTL_BL_INT ldb; + T rcond; + MTL_BL_INT info; + MTL_BL_INT rank; + MTL_BL_INT liwork; + MTL_BL_INT lwork; + mt::Vctr_cpu iwork; + mt::Vctr_cpu work; + mt::Vctr_cpu S; + + mt::Vctr_cpu M; + mt::Vctr_cpu y; + }; + + /* The program computes the solution to the system of linear + equations with a square matrix A and multiple right-hand + sides B, where A is the coefficient matrix and b is the + right-hand side matrix: + */ + + template + struct GESV + { + public: + using value_type = T; + + const mt::eDev device; + + GESV(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_n, T* A, MTL_BL_INT b_cols, T* b, T* x) + { + MTL_BL_INT n = A_n; + MTL_BL_INT nrhs = b_cols; + MTL_BL_INT lda = n; + MTL_BL_INT ldb = n; + MTL_BL_INT info = 0; + + std::copy(b, b+n, x); + ipiv.resize(n); + + gesv_c(n, nrhs, A, lda, ipiv.data(), x, ldb, info); + } + + private: + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float32 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + sgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float64 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + dgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + mt::Vctr_cpu ipiv; + }; + + /* The program solves overdetermined or underdetermined real + linear systems involving an M-by-N matrix A, or its trs, + using a QR or LQ factorization of A. It is assumed that A has full rank. + */ + template + struct GELS + { + public: + using value_type = T; + + const mt::eDev device; + + GELS(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, MTL_BL_INT b_cols, T* b, T* x) + { + const char trans = 'N'; + MTL_BL_INT m = A_rows; + MTL_BL_INT n = A_cols; + MTL_BL_INT nrhs = b_cols; + MTL_BL_INT lda = A_rows; + MTL_BL_INT ldb = max(b_cols, max(m, n)); + MTL_BL_INT min_mn = min(m, n); + T rcond = -1; + MTL_BL_INT info = 0; + + mt::Vctr bv(b, b+m*b_cols); + + // query optimal size of work array + MTL_BL_INT lwork = -1; + T work_query= 0; + gels_c(trans, m, n, nrhs, A, lda, bv.data(), ldb, &work_query, lwork, info); + + // set arrays + lwork = max(1, MTL_BL_INT(work_query)); + work.resize(lwork); + + // perform minimum-norm solution + gels_c(trans, m, n, nrhs, A, lda, bv.data(), ldb, work.data(), lwork, info); + + for(auto ix = 0; ix work; + }; + + /* The program solves overdetermined or underdetermined real + linear systems involving an M-by-N matrix A, or its trs, + using the singular value decomposition (SVD) of A. A is an m-by-n matrix which may be rank-deficient. + */ + template + struct GELSD + { + public: + using value_type = T; + + const mt::eDev device; + + GELSD(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, MTL_BL_INT b_cols, T* b, T* x) + { + MTL_BL_INT m = A_rows; + MTL_BL_INT n = A_cols; + MTL_BL_INT nrhs = b_cols; + MTL_BL_INT lda = A_rows; + MTL_BL_INT ldb = max(b_cols, max(m, n)); + MTL_BL_INT min_mn = min(m, n); + MTL_BL_INT rank = 0; + T rcond = -1; + MTL_BL_INT info = 0; + + mt::Vctr bv(b, b+m*b_cols); + S.resize(min_mn); + + // query optimal size of work array + MTL_BL_INT lwork = -1; + T work_query= 0; + MTL_BL_INT iwork_query= 0; + gelsd_c(m, n, nrhs, A, lda, bv.data(), ldb, S.data(), rcond, rank, &work_query, lwork, &iwork_query, info); + + // set arrays + lwork = max(1, MTL_BL_INT(work_query)); + work.resize(lwork); + + MTL_BL_INT liwork = max(1, iwork_query); + iwork.resize(liwork); + + // perform minimum-norm solution + gelsd_c(m, n, nrhs, A, lda, bv.data(), ldb, S.data(), rcond, rank, work.data(), lwork, iwork.data(), info); + + for(auto ix= 0; ix iwork; + mt::Vctr work; + mt::Vctr S; + }; +} // namespace lapack + +#endif \ No newline at end of file diff --git a/src - Copy (2)/lens.cuh b/src - Copy (2)/lens.cuh new file mode 100755 index 00000000..d594c65b --- /dev/null +++ b/src - Copy (2)/lens.cuh @@ -0,0 +1,634 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef LENS_H + #define LENS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "cgpu_fcns_gen.cuh" + #include "grid.cuh" + + namespace mt + { + /****************************** lens *********************************/ + template + class Lens + { + public: + using value_type = T; + + dt_int32 m; // Momentum of the vortex + + T c_10; // Defocus (Å) + T c_12; // 2-fold astigmatism (Å) + T phi_12; // Azimuthal angle of 2-fold astigmatism (rad) + + T c_21; // Axial coma (Å) + T phi_21; // Azimuthal angle of axial coma (rad) + T c_23; // 3-fold astigmatism (Å) + T phi_23; // Azimuthal angle of 3-fold astigmatism (rad) + + T c_30; // 3rd order spherical aberration (Å) + T c_32; // Axial star aberration (Å) + T phi_32; // Azimuthal angle of axial star aberration (rad) + T c_34; // 4-fold astigmatism (Å) + T phi_34; // Azimuthal angle of 4-fold astigmatism (rad) + + T c_41; // 4th order axial coma (Å) + T phi_41; // Azimuthal angle of 4th order axial coma (rad) + T c_43; // 3-lobe aberration (Å) + T phi_43; // Azimuthal angle of 3-lobe aberration (rad) + T c_45; // 5-fold astigmatism (Å) + T phi_45; // Azimuthal angle of 5-fold astigmatism (rad) + + T c_50; // 5th order spherical aberration (Å) + T c_52; // 5th order axial star aberration (Å) + T phi_52; // Azimuthal angle of 5th order axial star aberration (rad) + T c_54; // 5th order rosette aberration (Å) + T phi_54; // Azimuthal angle of 5th order rosette aberration (rad) + T c_56; // 6-fold astigmatism (Å) + T phi_56; // Azimuthal angle of 6-fold astigmatism (rad) + + T inner_aper_ang; // Inner aperture (rad); + T outer_aper_ang; // Outer aperture (rad); + + T tp_inc_a; // Height proportion of a normalized Gaussian [0, 1] + T tp_inc_sigma; // standard deviation of the defocus spread function for the Gaussian component: + T tp_inc_beta; // standard deviation of the defocus spread function for the exponential component: + dt_int32 tp_inc_npts; // number of integration points of the defocus spread function + + T tp_inc_iehwgd; // e^-1 half-width value of the Gaussian distribution + + T spt_inc_a; // Height proportion of a normalized Gaussian [0, 1] + T spt_inc_sigma; // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + T spt_inc_beta; // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + dt_int32 spt_inc_rad_npts; // number of radial integration points + dt_int32 spt_inc_azm_npts; // number of azimuth integration points + + T spt_inc_iehwgd; // e^-1 half-width value of the Gaussian distribution + T spt_inc_theta_c; // divergence semi-angle (rad) + + eZero_Def_Typ zero_def_typ;// Defocus type: ezdt_first = 1, ezdt_middle = 2, ezdt_last = 3, ezdt_user_def = 4 + T zero_def_plane; // plane + + T lambda; // wavelength(Angstrom) + + T c_c_10; // -pi*c_10*lambda + T c_c_12; // -pi*c_12*lambda + + T c_c_21; // -2*pi*c_21*lambda^2/3 + T c_c_23; // -2*pi*c_23*lambda^2/3 + + T c_c_30; // -pi*c_30*lambda^3/2 + T c_c_32; // -pi*c_32*lambda^3/2 + T c_c_34; // -pi*c_34*lambda^3/2 + + T c_c_41; // -2*pi*c_41*lambda^4/5 + T c_c_43; // -2*pi*c_43*lambda^4/5 + T c_c_45; // -2*pi*c_45*lambda^4/5 + + T c_c_50; // -pi*c_50*lambda^5/3 + T c_c_52; // -pi*c_52*lambda^5/3 + T c_c_54; // -pi*c_54*lambda^5/3 + T c_c_56; // -pi*c_56*lambda^5/3 + + T g2_inner; // inner_aper_ang/lambda + T g2_outer; // outer_aper_ang/lambda + + dt_int32 ngxs; // number of source sampling points x + dt_int32 ngys; // number of source sampling points y + T dgxs; // source sampling m_size; + T dgys; // source sampling m_size; + T g2_maxs; // q maximum square; + + /************************************* constructors ************************************/ + Lens(): m(0), c_10(0), c_12(0), phi_12(0), c_21(0), phi_21(0), c_23(0), phi_23(0), + c_30(0), c_32(0), phi_32(0), c_34(0), phi_34(0), + c_41(0), phi_41(0), c_43(0), phi_43(0), c_45(0), phi_45(0), + c_50(0), c_52(0), phi_52(0), c_54(0), phi_54(0), c_56(0), phi_56(0), + inner_aper_ang(0), outer_aper_ang(0), tp_inc_a(1.0), tp_inc_sigma(0), tp_inc_beta(0), tp_inc_npts(0), tp_inc_iehwgd(0), + spt_inc_a(1.0), spt_inc_sigma(0), spt_inc_beta(0), spt_inc_rad_npts(0), spt_inc_azm_npts(0), spt_inc_iehwgd(0), spt_inc_theta_c(0), + zero_def_typ(ezdt_last), zero_def_plane(0), lambda(0), g2_inner(0), g2_outer(0), ngxs(0), ngys(0), dgxs(0), dgys(0), g2_maxs(0), + c_c_10(0), c_c_12(0), c_c_21(0), c_c_23(0), c_c_30(0), c_c_32(0), c_c_34(0), c_c_41(0), + c_c_43(0), c_c_45(0), c_c_50(0), c_c_52(0), c_c_54(0), c_c_56(0) {} + + /* copy constructor */ + CGPU_EXEC + Lens(const Lens& lens): Lens() + { + *this = lens; + } + + /* converting constructor */ + template + CGPU_EXEC + Lens(const Lens& lens): Lens() + { + *this = lens; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Lens& operator=(const Lens& lens) + { + if (this != &lens) + { + m = lens.m; + + c_10 = lens.c_10; + c_12 = lens.c_12; + phi_12 = lens.phi_12; + + c_21 = lens.c_21; + phi_21 = lens.phi_21; + c_23 = lens.c_23; + phi_23 = lens.phi_23; + + c_30 = lens.c_30; + c_32 = lens.c_32; + phi_32 = lens.phi_32; + c_34 = lens.c_34; + phi_34 = lens.phi_34; + + c_41 = lens.c_41; + phi_41 = lens.phi_41; + c_43 = lens.c_43; + phi_43 = lens.phi_43; + c_45 = lens.c_45; + phi_45 = lens.phi_45; + + c_50 = lens.c_50; + c_52 = lens.c_52; + phi_52 = lens.phi_52; + c_54 = lens.c_54; + phi_54 = lens.phi_54; + c_56 = lens.c_56; + phi_56 = lens.phi_56; + + inner_aper_ang = lens.inner_aper_ang; + outer_aper_ang = lens.outer_aper_ang; + + tp_inc_a = lens.tp_inc_a; + tp_inc_sigma = lens.tp_inc_sigma; + tp_inc_beta = lens.tp_inc_beta; + tp_inc_npts = lens.tp_inc_npts; + tp_inc_iehwgd = lens.tp_inc_iehwgd; + + spt_inc_a = lens.spt_inc_a; + spt_inc_sigma = lens.spt_inc_sigma; + spt_inc_beta = lens.spt_inc_beta; + spt_inc_rad_npts = lens.spt_inc_rad_npts; + spt_inc_azm_npts = lens.spt_inc_azm_npts; + + spt_inc_iehwgd = lens.spt_inc_iehwgd; + spt_inc_theta_c = lens.spt_inc_theta_c; + + zero_def_typ = lens.zero_def_typ; + zero_def_plane = lens.zero_def_plane; + + lambda = lens.lambda; + + c_c_10 = lens.c_c_10; + c_c_12 = lens.c_c_12; + + c_c_21 = lens.c_c_21; + c_c_23 = lens.c_c_23; + + c_c_30 = lens.c_c_30; + c_c_32 = lens.c_c_32; + c_c_34 = lens.c_c_34; + + c_c_41 = lens.c_c_41; + c_c_43 = lens.c_c_43; + c_c_45 = lens.c_c_45; + + c_c_50 = lens.c_c_50; + c_c_52 = lens.c_c_52; + c_c_54 = lens.c_c_54; + c_c_56 = lens.c_c_56; + + g2_inner = lens.g2_inner; + g2_outer = lens.g2_outer; + + ngxs = lens.ngxs; + ngys = lens.ngys; + + dgxs = lens.dgxs; + dgys = lens.dgys; + g2_maxs = lens.g2_outers; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Lens& operator=(const Lens& lens) + { + m = lens.m; + + c_10 = T(lens.c_10); + c_12 = T(lens.c_12); + phi_12 = T(lens.phi_12); + + c_21 = T(lens.c_21); + phi_21 = T(lens.phi_21); + c_23 = T(lens.c_23); + phi_23 = T(lens.phi_23); + + c_30 = T(lens.c_30); + c_32 = T(lens.c_32); + phi_32 = T(lens.phi_32); + c_34 = T(lens.c_34); + phi_34 = T(lens.phi_34); + + c_41 = T(lens.c_41); + phi_41 = T(lens.phi_41); + c_43 = T(lens.c_43); + phi_43 = T(lens.phi_43); + c_45 = T(lens.c_45); + phi_45 = T(lens.phi_45); + + c_50 = T(lens.c_50); + c_52 = T(lens.c_52); + phi_52 = T(lens.phi_52); + c_54 = T(lens.c_54); + phi_54 = T(lens.phi_54); + c_56 = T(lens.c_56); + phi_56 = T(lens.phi_56); + + inner_aper_ang = T(lens.inner_aper_ang); + outer_aper_ang = T(lens.outer_aper_ang); + + tp_inc_a = T(lens.tp_inc_a); + tp_inc_sigma = T(lens.tp_inc_sigma); + tp_inc_beta = T(lens.tp_inc_beta); + tp_inc_npts = lens.tp_inc_npts; + tp_inc_iehwgd = lens.tp_inc_iehwgd; + + spt_inc_a = T(lens.spt_inc_a); + spt_inc_sigma = T(lens.spt_inc_sigma); + spt_inc_beta = T(lens.spt_inc_beta); + spt_inc_rad_npts = lens.spt_inc_rad_npts; + spt_inc_azm_npts = lens.spt_inc_azm_npts; + + spt_inc_iehwgd = T(lens.spt_inc_iehwgd); + spt_inc_theta_c = T(lens.spt_inc_theta_c); + + zero_def_typ = lens.zero_def_typ; + zero_def_plane = T(lens.zero_def_plane); + + lambda = T(lens.lambda); + + c_c_10 = T(lens.c_c_10); + c_c_12 = T(lens.c_c_12); + + c_c_21 = T(lens.c_c_21); + c_c_23 = T(lens.c_c_23); + + c_c_30 = T(lens.c_c_30); + c_c_32 = T(lens.c_c_32); + c_c_34 = T(lens.c_c_34); + + c_c_41 = T(lens.c_c_41); + c_c_43 = T(lens.c_c_43); + c_c_45 = T(lens.c_c_45); + + c_c_50 = T(lens.c_c_50); + c_c_52 = T(lens.c_c_52); + c_c_54 = T(lens.c_c_54); + c_c_56 = T(lens.c_c_56); + + g2_inner = T(lens.g2_inner); + g2_outer = T(lens.g2_outer); + + ngxs = lens.ngxs; + ngys = lens.ngys; + + dgxs = T(lens.dgxs); + dgys = T(lens.dgys); + g2_maxs = T(lens.g2_outers); + + return *this; + } + + template + void assign(const Lens& lens) + { + *this = lens; + } + + /***************************************************************************************/ + void set_dep_var(const T& E_0, const Grid_2d& grid) + { + lambda = fcn_lambda(E_0); + + c_c_10 = fcn_is_zero(c_10)?T(0):-c_pi*c_10*lambda; + c_c_12 = fcn_is_zero(c_12)?T(0):-c_pi*c_12*lambda; + + c_c_21 = fcn_is_zero(c_21)?T(0):-T(2)*c_pi*c_21*pow(lambda, 2)/T(3); + c_c_23 = fcn_is_zero(c_23)?T(0):-T(2)*c_pi*c_23*pow(lambda, 2)/T(3); + + c_c_30 = fcn_is_zero(c_30)?T(0):-c_pi*c_30*pow(lambda, 3)/T(2); + c_c_32 = fcn_is_zero(c_32)?T(0):-c_pi*c_32*pow(lambda, 3)/T(2); + c_c_34 = fcn_is_zero(c_34)?T(0):-c_pi*c_34*pow(lambda, 3)/T(2); + + c_c_41 = fcn_is_zero(c_41)?T(0):-T(2)*c_pi*c_41*pow(lambda, 4)/T(5); + c_c_43 = fcn_is_zero(c_43)?T(0):-T(2)*c_pi*c_43*pow(lambda, 4)/T(5); + c_c_45 = fcn_is_zero(c_45)?T(0):-T(2)*c_pi*c_45*pow(lambda, 4)/T(5); + + c_c_50 = fcn_is_zero(c_50)?T(0):-c_pi*c_50*pow(lambda, 5)/T(3); + c_c_52 = fcn_is_zero(c_52)?T(0):-c_pi*c_52*pow(lambda, 5)/T(3); + c_c_54 = fcn_is_zero(c_54)?T(0):-c_pi*c_54*pow(lambda, 5)/T(3); + c_c_56 = fcn_is_zero(c_56)?T(0):-c_pi*c_56*pow(lambda, 5)/T(3); + + g2_inner = (inner_aper_ang < epsilon_abs())?T(0):pow(rad_2_rangs(inner_aper_ang), 2); + g2_outer = (outer_aper_ang < epsilon_abs())?T(2)*grid.g2_max():pow(rad_2_rangs(outer_aper_ang), 2); + + tp_inc_a = max(T(0), min(T(1), tp_inc_a)); + set_tp_inc_sigma(tp_inc_sigma); + tp_inc_beta = max(T(0), tp_inc_beta); + tp_inc_npts = max(1, tp_inc_npts); + + spt_inc_a = max(T(0), min(T(1), spt_inc_a)); + set_spt_inc_sigma(spt_inc_sigma); + spt_inc_beta = max(T(0), spt_inc_beta); + spt_inc_rad_npts = max(1, spt_inc_rad_npts); + spt_inc_azm_npts = max(1, spt_inc_azm_npts); + + T gmaxs = T(3.5)*spt_inc_sigma; + g2_maxs = gmaxs*gmaxs; + T dgs = gmaxs/static_cast(spt_inc_rad_npts); + + dt_int32 n = (dgs(::floor(grid.dgx/dgs)+1):1; + ngxs = static_cast(::floor(n*gmaxs/grid.dgx)) + 1; + dgxs = gmaxs/ngxs; + + n = (dgs(::floor(grid.dgy/dgs)+1):1; + ngys = static_cast(::floor(n*gmaxs/grid.dgy)) + 1; + dgys = gmaxs/ngys; + } + + CGPU_EXEC + T rad_2_rangs(const T& theta) const + { + return sin(theta)/lambda; + } + + void set_tp_inc_sigma(const T& ti_sigma) + { + tp_inc_sigma = max(T(0), ti_sigma); + tp_inc_iehwgd = c_2i2*tp_inc_sigma; + } + + void set_spt_inc_sigma(const T& si_sigma) + { + spt_inc_sigma = max(T(0), si_sigma); + spt_inc_iehwgd = c_2i2*spt_inc_sigma; + spt_inc_theta_c = asin(spt_inc_iehwgd*lambda); + } + + void set_defocus(const T& c_10) + { + this->c_10 = c_10; + c_c_10 = (fcn_is_zero(c_10))?T(0):-c_pi*c_10*lambda; + } + + T get_zero_def_plane(const T& z_min, const T& z_max) const + { + switch(zero_def_typ) + { + case ezdt_first: + { + return z_min; + } + case ezdt_middle: + { + return T(0.5)*(z_min + z_max); + } + case ezdt_last: + { + return z_max; + } + default: + { + return zero_def_plane; + } + } + }; + + dt_bool is_zdt_first() const + { + return mt::is_zdt_first(zero_def_typ); + } + + dt_bool is_zdt_middle() const + { + return mt::is_zdt_first(zero_def_typ); + } + + dt_bool is_zdt_last() const + { + return mt::is_zdt_first(zero_def_typ); + } + + dt_bool is_zdt_user_def() const + { + return mt::is_zdt_first(zero_def_typ); + } + + T gxs(const dt_int32& ix) const + { + return static_cast(ix)*dgxs; + } + T gys(const dt_int32& iy) const + { + return static_cast(iy)*dgys; + } + T g2s(const dt_int32& ix, const dt_int32& iy) const + { + T gxi = gxs(ix); + T gyi = gys(iy); + + return gxi*gxi + gyi*gyi; + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T tp_inc_sigma_2() const + { + return ::square(tp_inc_sigma); + } + + CGPU_EXEC_INL + T tp_inc_beta_2() const + { + return ::square(tp_inc_beta); + } + + CGPU_EXEC_INL + T spt_inc_sigma_2() const + { + return ::square(spt_inc_sigma); + } + + CGPU_EXEC_INL + T spt_inc_beta_2() const + { + return ::square(spt_inc_beta); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + dt_bool is_phi_required() const + { + auto bb = fcn_is_nzero(m)||fcn_is_nzero(c_12)||fcn_is_nzero(c_21)||fcn_is_nzero(c_23)||fcn_is_nzero(c_32)||fcn_is_nzero(c_34); + bb = bb||fcn_is_nzero(c_41)||fcn_is_nzero(c_43)||fcn_is_nzero(c_45)||fcn_is_nzero(c_52)||fcn_is_nzero(c_54)||fcn_is_nzero(c_56); + + return bb; + } + + CGPU_EXEC_INL + T eval_m(const T& phi) const + { + return T(m)*phi; + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_10(const T& g2) const + { + return c_c_10*g2; + } + + CGPU_EXEC_INL + T eval_c_12(const T& g2, const T& phi) const + { + return c_c_12*g2*sin(T(2)*(phi-phi_12)); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_21(const T& g3, const T& phi) const + { + return c_c_21*g3*sin(phi-phi_21); + } + + CGPU_EXEC_INL + T eval_c_23(const T& g3, const T& phi) const + { + return c_c_23*g3*sin(T(3)*(phi-phi_23)); + } + + CGPU_EXEC_INL + T eval_c_21_c_23(const T& g3, const T& phi) const + { + return eval_c_21(g3, phi) + eval_c_23(g3, phi); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_30(const T& g4) const + { + return c_c_30*g4; + } + + CGPU_EXEC_INL + T eval_c_32(const T& g4, const T& phi) const + { + return c_c_32*g4*sin(T(2)*(phi-phi_32)); + } + + CGPU_EXEC_INL + T eval_c_34(const T& g4, const T& phi) const + { + return c_c_34*g4*sin(T(4)*(phi-phi_34)); + } + + CGPU_EXEC_INL + T eval_c_32_c_34(const T& g4, const T& phi) const + { + return eval_c_32(g4, phi) + eval_c_34(g4, phi); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_41(const T& g5, const T& phi) const + { + return c_c_41*g5*sin(phi-phi_41); + } + + CGPU_EXEC_INL + T eval_c_43(const T& g5, const T& phi) const + { + return c_c_43*g5*sin(T(3)*(phi-phi_43)); + } + + CGPU_EXEC_INL + T eval_c_45(const T& g5, const T& phi) const + { + return c_c_45*g5*sin(T(5)*(phi-phi_45)); + } + + CGPU_EXEC_INL + T eval_c_41_c_43_c_45(const T& g5, const T& phi) const + { + return eval_c_41(g5, phi) + eval_c_43(g5, phi) + eval_c_45(g5, phi); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_50(const T& g6) const + { + return c_c_50*g6; + } + + CGPU_EXEC_INL + T eval_c_52(const T& g6, const T& phi) const + { + return c_c_52*g6*sin(T(2)*(phi-phi_52)); + } + + CGPU_EXEC_INL + T eval_c_54(const T& g6, const T& phi) const + { + return c_c_54*g6*sin(T(4)*(phi-phi_54)); + } + + CGPU_EXEC_INL + T eval_c_56(const T& g6, const T& phi) const + { + return c_c_56*g6*sin(T(6)*(phi-phi_56)); + } + + CGPU_EXEC_INL + T eval_c_52_c_54_c_56(const T& g6, const T& phi) const + { + return eval_c_52(g6, phi) + eval_c_54(g6, phi) + eval_c_56(g6, phi); + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/libblas.lib b/src - Copy (2)/libblas.lib new file mode 100755 index 00000000..88344bd0 Binary files /dev/null and b/src - Copy (2)/libblas.lib differ diff --git a/src/libfftw3-3.lib b/src - Copy (2)/libfftw3-3.lib old mode 100644 new mode 100755 similarity index 100% rename from src/libfftw3-3.lib rename to src - Copy (2)/libfftw3-3.lib diff --git a/src/libfftw3f-3.lib b/src - Copy (2)/libfftw3f-3.lib old mode 100644 new mode 100755 similarity index 100% rename from src/libfftw3f-3.lib rename to src - Copy (2)/libfftw3f-3.lib diff --git a/src - Copy (2)/liblapack.lib b/src - Copy (2)/liblapack.lib new file mode 100755 index 00000000..60cd33ae Binary files /dev/null and b/src - Copy (2)/liblapack.lib differ diff --git a/src - Copy (2)/macros.cuh b/src - Copy (2)/macros.cuh new file mode 100755 index 00000000..cd42b637 --- /dev/null +++ b/src - Copy (2)/macros.cuh @@ -0,0 +1,266 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ +//#define __CUDACC__ +#ifndef MACROS_H + #define MACROS_H + + #ifdef _MSC_VER + #pragma once + #endif + + // https:// github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks, -tips, -and-idioms + + #define EVAL(...) __VA_ARGS__ + + #define PCAT2(a, ...) a ## __VA_ARGS__ + #define CAT2(a, ...) PCAT2(a, __VA_ARGS__) + #define CAT2_2(a, ...) CAT2(a, __VA_ARGS__) + + #define PCAT3(a, b, ...) a ## b ## __VA_ARGS__ + #define CAT3(a, b, ...) PCAT3(a, b, __VA_ARGS__) + #define CAT3_2(a, b, ...) CAT3(a, b, __VA_ARGS__) + + /***************************************************************************************/ + #define IIF_1(t, ...) t + #define IIF_0(t, ...) __VA_ARGS__ + #define IIF(c) PCAT2(IIF_, c) + + /***************************************************************************************/ + #define CHECK_N(x, n, ...) n + #define CHECK(...) CHECK_N(__VA_ARGS__, 0) + #define IS_1 x, 1 + #define IS_ONE(x) CHECK(CAT2(IS_, x)) + + /***************************************************************************************/ + #define REPV_1(N) N + #define REPV_2(N) REPV_1(N), N + #define REPV_3(N) REPV_2(N), N + #define REPV_4(N) REPV_3(N), N + #define REPV_5(N) REPV_4(N), N + #define REPV_6(N) REPV_5(N), N + #define REPV_7(N) REPV_6(N), N + #define REPV_8(N) REPV_7(N), N + #define REPV_9(N) REPV_8(N), N + #define REPV(V, N) CAT2(REPV_, N(V)) + + /***************************************************************************************/ + #define IDX_1D ix + #define IDX_2D ix, iy + #define IDX_3D ix, iy, iz + #define IDX_ND(DIM) CAT3(IDX_, DIM, D) + + /***************************************************************************************/ + #define IDX_CDEF_1D const dt_int32& ix + #define IDX_CDEF_2D const dt_int32& ix, const dt_int32& iy + #define IDX_CDEF_3D const dt_int32& ix, const dt_int32& iy, const dt_int32& iz + #define IDX_CDEF_ND(DIM) CAT3(IDX_CDEF_, DIM, D) + + /***************************************************************************************/ + #define F_SHAPE_1D(G) G.nx + #define F_SHAPE_2D(G) G.nx, G.ny + #define F_SHAPE_3D(G) G.nx, G.ny, G.nz + #define F_SHAPE_ND(G, DIM) F_SHAPE_##DIM##D(G) + + /***************************************************************************************/ + #define EDIM(DIM) edim_##DIM + + /***************************************************************************************/ + + // macro for int definition for blas and lapack + #ifdef MATLAB_BLAS_LAPACK + #define MTL_BL_INT ptrdiff_t + #else + #define MTL_BL_INT dt_int32 + #endif + + #define PASTER(pre, x, y) pre ## _ ## x ## _ ## y + #define EVAL_PASTE(pre, x, y) PASTER(pre, x, y) + #define EVAL_2_PASTE(pre, x, y) EVAL_PASTE(pre, x, y) + + #define INC(X, K) EVAL_PASTE(INC, K, X) + #define DEC(X, K) EVAL_PASTE(DEC, K, X) + + #define INC_1_0 1 + #define INC_1_1 2 + #define INC_1_2 3 + #define INC_1_3 4 + #define INC_1_4 5 + #define INC_1_5 6 + #define INC_1_6 7 + #define INC_1_7 8 + #define INC_1_8 9 + #define INC_1_9 10 + #define INC_1_10 11 + #define INC_1_11 12 + #define INC_1_12 13 + #define INC_1_13 14 + #define INC_1_14 15 + #define INC_1_15 16 + + #define INC_2_0 2 + #define INC_2_1 3 + #define INC_2_2 4 + #define INC_2_3 5 + #define INC_2_4 6 + #define INC_2_5 7 + #define INC_2_6 8 + #define INC_2_7 9 + #define INC_2_8 10 + #define INC_2_9 11 + #define INC_2_10 12 + #define INC_2_11 13 + #define INC_2_12 14 + #define INC_2_13 15 + #define INC_2_14 16 + #define INC_2_15 17 + + #define INC_3_0 3 + #define INC_3_1 4 + #define INC_3_2 5 + #define INC_3_3 6 + #define INC_3_4 7 + #define INC_3_5 8 + #define INC_3_6 9 + #define INC_3_7 10 + #define INC_3_8 11 + #define INC_3_9 12 + #define INC_3_10 13 + #define INC_3_11 14 + #define INC_3_12 15 + #define INC_3_13 16 + #define INC_3_14 17 + #define INC_3_15 18 + + #define DEC_1_0 0 + #define DEC_1_1 0 + #define DEC_1_2 1 + #define DEC_1_3 2 + #define DEC_1_4 3 + #define DEC_1_5 4 + #define DEC_1_6 5 + #define DEC_1_7 6 + #define DEC_1_8 7 + #define DEC_1_9 8 + #define DEC_1_10 9 + #define DEC_1_11 10 + #define DEC_1_12 12 + #define DEC_1_13 13 + #define DEC_1_14 14 + #define DEC_1_15 15 + + #define DEC_2_0 0 + #define DEC_2_1 0 + #define DEC_2_2 0 + #define DEC_2_3 1 + #define DEC_2_4 2 + #define DEC_2_5 3 + #define DEC_2_6 4 + #define DEC_2_7 5 + #define DEC_2_8 6 + #define DEC_2_9 7 + #define DEC_2_10 8 + #define DEC_2_11 9 + #define DEC_2_12 10 + #define DEC_2_13 12 + #define DEC_2_14 13 + #define DEC_2_15 14 + + #define DEC_3_0 0 + #define DEC_3_1 0 + #define DEC_3_2 0 + #define DEC_3_3 0 + #define DEC_3_4 1 + #define DEC_3_5 2 + #define DEC_3_6 3 + #define DEC_3_7 4 + #define DEC_3_8 5 + #define DEC_3_9 6 + #define DEC_3_10 7 + #define DEC_3_11 8 + #define DEC_3_12 9 + #define DEC_3_13 10 + #define DEC_3_14 11 + #define DEC_3_15 12 + + #ifdef __CUDACC__ + #include + + #define CPU_EXEC __host__ + #define CPU_EXEC_INL __host__ inline + + #define GPU_EXEC __device__ + #define GPU_EXEC_INL __device__ inline + + #define CGPU_EXEC __host__ __device__ + #define CGPU_EXEC_INL __host__ __device__ inline + + #define FORCE_INLINE __forceinline__ + + #define FOR_IX_1DC(nx) for(dt_int32 ix = threadIdx.x + blockIdx.x*blockDim.x; ix < nx; ix += blockDim.x*gridDim.x) + + #define FOR_IX_2DC(nx) for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < nx; ix += blockDim.y*gridDim.y) + #define FOR_IY_2DC(ny) for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < ny; iy += blockDim.x*gridDim.x) + + #define FOR_LOOP_1DC(nx, fcn) \ + for(dt_int32 ix = threadIdx.x + blockIdx.x*blockDim.x; ix < nx; ix += blockDim.x*gridDim.x) \ + { \ + fcn; \ + } + + #define FOR_LOOP_2DC(nx, ny, fcn) \ + for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < nx; ix += blockDim.y*gridDim.y) \ + { \ + for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < ny; iy += blockDim.x*gridDim.x) \ + { \ + fcn; \ + } \ + } + + //check out for(dt_int32 iz = blockIdx.z*blockDim.z + threadIdx.z; iz < nz; iz += blockDim.z*gridDim.z) + #define FOR_LOOP_3DC(nx, ny, nz, fcn) \ + { \ + dt_int32 iz = threadIdx.z; \ + for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < nx; ix += blockDim.y*gridDim.y) \ + { \ + for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < ny; iy += blockDim.x*gridDim.x) \ + { \ + fcn; \ + } \ + } \ + } + + #define FOR_LOOP_NDC(DIM, ...) CAT3(FOR_LOOP_, DIM, DC)(__VA_ARGS__) + + #else + #define CPU_EXEC + #define CPU_EXEC_INL inline + + #define GPU_EXEC + #define GPU_EXEC_INL inline + + #define CGPU_EXEC + #define CGPU_EXEC_INL inline + + #define FORCE_INLINE inline + + #ifdef _MSC_VER + #define __restrict__ __restrict + #endif + #endif + +#endif \ No newline at end of file diff --git a/src - Copy (2)/math.cuh b/src - Copy (2)/math.cuh new file mode 100755 index 00000000..caa5faa7 --- /dev/null +++ b/src - Copy (2)/math.cuh @@ -0,0 +1,667 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MATH_H + #define MATH_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "macros.cuh" + #include "const_enum.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + using thrust::complex; + // using thrust::norm; + using thrust::polar; + using thrust::arg; + using thrust::abs; + + template + CGPU_EXEC_INL + T bessel_j0(const T& x) + { + return j0(x); + } + + template + CGPU_EXEC_INL + T bessel_j1(const T& x) + { + return j1(x); + } + + template + CGPU_EXEC_INL + T bessel_jn(const dt_int32& n, const T& x) + { + return jn(n, x); + } + + template + CGPU_EXEC_INL + T bessel_y0(const T& x) + { + return y0(x); + } + + template + CGPU_EXEC_INL + T bessel_y1(const T& x) + { + return y1(x); + } + + template + CGPU_EXEC_INL + T bessel_yn(const dt_int32& n, const T& x) + { + return yn(n, x); + } + + template + CGPU_EXEC_INL + T norm_2(const thrust::complex& z) + { + return thrust::norm(z); + } + + template + CGPU_EXEC_INL + T norm(const thrust::complex& z) + { + return thrust::abs(z); + } + #else + #include + #include + using std::complex; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + using std::cos; + using std::sin; + using std::tan; + using std::acos; + using std::asin; + using std::atan; + using std::atan2; + using std::cosh; + using std::sinh; + using std::tanh; + using std::acosh; + using std::asinh; + using std::atanh; + // using std::norm; + using std::polar; + using std::arg; + using std::abs; + + template + inline void sincos(const T& x, T* sptr, T* cptr) + { + *sptr = sin(x); + *cptr = cos(x); + } + + template + inline T cospi(const T& x) + { + returncos(mt::c_pi*x); + } + + template + inline T sinpi(const T& x) + { + return sin(mt::c_pi*x); + } + + template + inline void sincospi(const T& x, T* sptr, T* cptr) + { + *sptr = sin(mt::c_pi*x); + *cptr = cos(mt::c_pi*x); + } + + using std::exp; + using std::exp2; + + template + inline T exp10(const T& x) + { + return std::pow(static_cast(10), x); + } + + using std::expm1; + using std::frexp; + using std::log; + using std::log2; + using std::log10; + using std::ilogb; + using std::log1p; + using std::logb; + using std::modf; + using std::pow; + using std::sqrt; + + template + inline T rsqrt(const T& x) + { + return T(1)/std::sqrt(x); + } + + using std::cbrt; + using std::hypot; + + template + inline T rhypot(const T& x, const T& y) + { + return T(1)/std::hypot(x, y); + } + + using std::erf; + using std::erfc; + using std::tgamma; + using std::lgamma; + using std::ceil; + using std::floor; + using std::trunc; + using std::round; + using std::lround; + using std::llround; + using std::rint; + using std::lrint; + using std::llrint; + + using std::remainder; + using std::copysign; + using std::fdim; + using std::fmax; + using std::fmin; + using std::fabs; + using std::fma; + using std::fmod; + + template + inline T bessel_j0(const T& x) + { + // host code + T ax, z; + T xx, y, ans, ans1, ans2; + + if ((ax =fabs(x)) < 8.0) + { + y =x*x; + ans1 = 57568490574.0+y*(-13362590354.0+y*(651619640.7 + +y*(-11214424.18+y*(77392.33017+y*(-184.9052456))))); + ans2 = 57568490411.0+y*(1029532985.0+y*(9494680.718 + +y*(59272.64853+y*(267.8532712+y*1.0)))); + ans =ans1/ans2; + } + else + { + z = 8.0/ax; + y =z*z; + xx =ax-0.785398164; + ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 + +y*(-0.2073370639e-5+y*0.2093887211e-6))); + ans2 = -0.1562499995e-1+y*(0.1430488765e-3 + +y*(-0.6911147651e-5+y*(0.7621095161e-6 + -y*0.934935152e-7))); + ans =sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); + } + return ans; + } + + template + inline T bessel_j1(const T& x) + { + T ax, z; + T xx, y, ans, ans1, ans2; + + if ((ax =fabs(x)) < 8.0) + { + y =x*x; + ans1 =x*(72362614232.0+y*(-7895059235.0+y*(242396853.1 + +y*(-2972611.439+y*(15704.48260+y*(-30.16036606)))))); + ans2 = 144725228442.0+y*(2300535178.0+y*(18583304.74 + +y*(99447.43394+y*(376.9991397+y*1.0)))); + ans =ans1/ans2; + } + else + { + z = 8.0/ax; + y =z*z; + xx =ax-2.356194491; + ans1 = 1.0+y*(0.183105e-2+y*(-0.3516396496e-4 + +y*(0.2457520174e-5+y*(-0.240337019e-6)))); + ans2 = 0.04687499995+y*(-0.2002690873e-3 + +y*(0.8449199096e-5+y*(-0.88228987e-6 + +y*0.105787412e-6))); + ans =sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); + if (x < 0.0) + { + ans = -ans; + } + } + return ans; + } + + template + inline T bessel_jn(const dt_int32& n, const T& x) + { + const T ACC = 40.0; + const T BIGNO = 1.0e10; + const T BIGNI = 1.0e-10; + + dt_int32 j, jsum, m; + T ax, bj, bjm, bjp, sum, tox, ans; + + ax =fabs(x); + if (n == 0) + { + return( bessel_j0(ax) ); + } + if (n == 1) + { + return( bessel_j1(ax) ); + } + + if (ax == 0.0) + { + return 0.0; + } + else if (ax > (T) n) + { + tox = 2.0/ax; + bjm =bessel_j0(ax); + bj =bessel_j1(ax); + for(j = 1; j0; j--) + { + bjm = j*tox*bj-bjp; + bjp = bj; + bj = bjm; + if (fabs(bj) > BIGNO) + { + bj *= BIGNI; + bjp *= BIGNI; + ans *= BIGNI; + sum *= BIGNI; + } + if (jsum) + { + sum += bj; + } + jsum =!jsum; + if (j == n) + { + ans =bjp; + } + } + sum = 2.0*sum-bj; + ans /= sum; + } + return x < (0.0 && n%2 == 1)?-ans:ans; + } + + template + inline T bessel_y0(const T& x) + { + T z; + T xx, y, ans, ans1, ans2; + + if (x < 8.0) + { + y =x*x; + ans1 = -2957821389.0+y*(7062834065.0+y*(-512359803.6 + +y*(10879881.29+y*(-86327.92757+y*228.4622733)))); + ans2 = 40076544269.0+y*(745249964.8+y*(7189466.438 + +y*(47447.26470+y*(226.1030244+y*1.0)))); + ans = (ans1/ans2)+0.636619772*bessel_j0(x)*log(x); + } + else + { + z = 8.0/x; + y =z*z; + xx =x-0.785398164; + ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 + +y*(-0.2073370639e-5+y*0.2093887211e-6))); + ans2 = -0.1562499995e-1+y*(0.1430488765e-3 + +y*(-0.6911147651e-5+y*(0.7621095161e-6 + +y*(-0.934945152e-7)))); + ans =sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); + } + return ans; + } + + template + inline T bessel_y1(const T& x) + { + T z; + T xx, y, ans, ans1, ans2; + + if (x < 8.0) + { + y =x*x; + ans1 =x*(-0.4900604943e13+y*(0.1275274390e13 + +y*(-0.5153438139e11+y*(0.7349264551e9 + +y*(-0.4237922726e7+y*0.8511937935e4))))); + ans2 = 0.2499580570e14+y*(0.4244419664e12 + +y*(0.3733650367e10+y*(0.2245904002e8 + +y*(0.1020426050e6+y*(0.3549632885e3+y))))); + ans = (ans1/ans2)+0.636619772*(bessel_j1(x)*log(x)-1.0/x); + } + else + { + z = 8.0/x; + y =z*z; + xx =x-2.356194491; + ans1 = 1.0+y*(0.183105e-2+y*(-0.3516396496e-4 + +y*(0.2457520174e-5+y*(-0.240337019e-6)))); + ans2 = 0.04687499995+y*(-0.2002690873e-3 + +y*(0.8449199096e-5+y*(-0.88228987e-6 + +y*0.105787412e-6))); + ans =sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); + } + return ans; + } + + template + inline T bessel_yn(const dt_int32& n, const T& x) + { + dt_int32 j; + T by, bym, byp, tox; + + if (n == 0) + { + return( bessel_y0(x) ); + } + if (n == 1) + { + return( bessel_y1(x) ); + } + + tox = 2.0/x; + by =bessel_y1(x); + bym =bessel_y0(x); + for(j = 1; j + CGPU_EXEC_INL + T square(const T& x) + { + return x*x; + } + + template + CGPU_EXEC_INL + T norm_2(const std::complex& z) + { + return std::norm(z); + } + + template + CGPU_EXEC_INL + T norm(const std::complex& z) + { + return std::abs(z); + } + + // #ifndef __APPLE__ + template + CGPU_EXEC_INL + T norm_2(const T& x) + { + return x*x; + } + + template + CGPU_EXEC_INL + T norm(const T& x) + { + return abs(x); + } + + // #endif + + template + CGPU_EXEC_INL + complex euler(const T& x) + { + T sptr, cptr; + sincos(x, &sptr, &cptr); + return complex(cptr, sptr); + } + + template + CGPU_EXEC_INL + T bessel_i0(const T& x) + { + T ax, ans; + T y; + + if ((ax =fabs(x)) < 3.75) + { + y =x/3.75, y =y*y; + ans = 1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 + +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); + } + else + { + y = 3.75/ax; + ans = (exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 + +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 + +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 + +y*0.392377e-2)))))))); + } + return ans; + } + + template + CGPU_EXEC_INL + T bessel_i1(const T& x) + { + T ax, ans; + T y; + + if ((ax =fabs(x)) < 3.75) + { + y =x/3.75, y =y*y; + ans =ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934 + +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3)))))); + } + else + { + y = 3.75/ax; + ans = 0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1 + -y*0.420059e-2)); + ans = 0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2 + +y*(0.163801e-2+y*(-0.1031555e-1+y*ans)))); + ans *= (exp(ax)/sqrt(ax)); + } + return (x < 0.0)?-ans:ans; + } + + template + CGPU_EXEC_INL + T bessel_in(const dt_int32& n, const T& x) + { + const T ACC = 40.0; + const T BIGNO = 1.0e10; + const T BIGNI = 1.0e-10; + + dt_int32 j; + T bi, bim, bip, tox, ans; + + if (n == 0) + { + return( bessel_i0(x) ); + } + if (n == 1) + { + return( bessel_i1(x) ); + } + + if (x == 0.0) + { + return 0.0; + } + else + { + tox = 2.0/fabs(x); + bip =ans = 0.0; + bi = 1.0; + for(j = 2*(n+(dt_int32)sqrt(ACC*n)); j>0; j--) + { + bim =bip+j*tox*bi; + bip =bi; + bi =bim; + if (fabs(bi) > BIGNO) + { + ans *= BIGNI; + bi *= BIGNI; + bip *= BIGNI; + } + if (j == n) + { + ans =bip; + } + } + ans *= bessel_i0(x)/bi; + return (x < 0.0 && n%2 == 1)?-ans:ans; + } + } + + template + CGPU_EXEC_INL + T bessel_k0(const T& x) + { + T y, ans; + + if (x <= 2.0) + { + y =x*x/4.0; + ans = (-log(x/2.0)*bessel_i0(x))+(-0.57721566+y*(0.42278420 + +y*(0.23069756+y*(0.3488590e-1+y*(0.262698e-2 + +y*(0.10750e-3+y*0.74e-5)))))); + } + else + { + y = 2.0/x; + ans = (exp(-x)/sqrt(x))*(1.25331414+y*(-0.7832358e-1 + +y*(0.2189568e-1+y*(-0.1062446e-1+y*(0.587872e-2 + +y*(-0.251540e-2+y*0.53208e-3)))))); + } + return ans; + } + + template + CGPU_EXEC_INL + T bessel_k1(const T& x) + { + T y, ans; + + if (x <= 2.0) + { + y =x*x/4.0; + ans = (log(x/2.0)*bessel_i1(x))+(1.0/x)*(1.0+y*(0.15443144 + +y*(-0.67278579+y*(-0.18156897+y*(-0.1919402e-1 + +y*(-0.110404e-2+y*(-0.4686e-4))))))); + } + else + { + y = 2.0/x; + ans = (exp(-x)/sqrt(x))*(1.25331414+y*(0.23498619 + +y*(-0.3655620e-1+y*(0.1504268e-1+y*(-0.780353e-2 + +y*(0.325614e-2+y*(-0.68245e-3))))))); + } + return ans; + } + + template + CGPU_EXEC_INL + T bessel_kn(const dt_int32& n, const T& x) + { + dt_int32 j; + T bk, bkm, bkp, tox; + + if (n == 0) + { + return( bessel_k0(x) ); + } + if (n == 1) + { + return( bessel_k1(x) ); + } + + tox = 2.0/x; + bkm =bessel_k0(x); + bk =bessel_k1(x); + for(j = 1; j + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MATLAB_MEX_H + #define MATLAB_MEX_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + + #include "const_enum.cuh" + #include "type_traits_gen.cuh" + #include "math.cuh" + #include "memcpy.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_info.cuh" + + #include + + template + mt::enable_if_real + mex_print(T* ptr, dt_int32 n) + { + for(auto ik = 0; ik + mt::enable_if_real + mex_print(const mt::pVctr_cpu_64& vector) + { + for(auto ik = 0; ik + mt::enable_if_cmplx + mex_print(const mt::pVctr_cpu_64& vector) + { + for(auto ik = 0; ik 0)?static_cast(dim[0]):0; + } + + CPU_EXEC_INL + dt_uint32 mex_get_s1(const mxArray* mxA) + { + auto n_dim = mxGetNumberOfDimensions(mxA); + auto dim = mxGetDimensions(mxA); + + return (n_dim>1)?static_cast(dim[1]):0; + } + + CPU_EXEC_INL + dt_uint32 mex_get_s2(const mxArray* mxA) + { + auto n_dim = mxGetNumberOfDimensions(mxA); + auto dim = mxGetDimensions(mxA); + + return (n_dim>2)?static_cast(dim[2]):0; + } + + CPU_EXEC_INL + dt_uint32 mex_get_s3(const mxArray* mxA) + { + auto n_dim = mxGetNumberOfDimensions(mxA); + auto dim = mxGetDimensions(mxA); + + return (n_dim>3)?static_cast(dim[3]):0; + } + + CPU_EXEC_INL + dt_shape mex_get_mx_shape(const mxArray* mxA) + { + auto n_dim = min(mwSize(4), mxGetNumberOfDimensions(mxA)); + auto dim = mxGetDimensions(mxA); + + dt_shape shape{1, 1, 1, 1}; + + for (auto ik = 0; ik mex_get_mx_shape_uint64(const mxArray* mxA) + { + auto n_dim = min(mwSize(4), mxGetNumberOfDimensions(mxA)); + auto dim = mxGetDimensions(mxA); + + dt_shape_st shape{1, 1, 1, 1}; + + for (auto ik = 0; ik + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return mt::pVctr_cpu_64(); + } + + /***************************************************************************************/ + /************************************ get real data ************************************/ + /***************************************************************************************/ + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetInt8s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetUint8s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetInt16s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetUint16s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetInt32s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetUint32s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetInt64s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetUint64s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetSingles(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetDoubles(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + /***************************************************************************************/ + /********************************** get complex data ***********************************/ + /***************************************************************************************/ + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexInt8s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexUint8s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexInt16s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexUint16s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexInt32s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexUint32s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexInt64s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexUint64s(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexSingles(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + template <> + mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) + { + return {reinterpret_cast(mxGetComplexDoubles(mxA)), mex_get_mx_shape_uint64(mxA)}; + } + + /***************************************************************************************/ + /*********************************** read data type ************************************/ + /***************************************************************************************/ + eData_Typ mex_get_data_type(const mxArray* mxA) + { + auto category = mxGetClassID(mxA); + + if (mxIsComplex(mxA)) + { + switch (category) + { + case mxINT8_CLASS: + { + return edt_cint8; + } + case mxUINT8_CLASS: + { + return edt_cuint8; + } + case mxINT16_CLASS: + { + return edt_cint16; + } + case mxUINT16_CLASS: + { + return edt_cuint16; + } + case mxINT32_CLASS: + { + return edt_cint32; + } + case mxUINT32_CLASS: + { + return edt_cuint32; + } + case mxINT64_CLASS: + { + return edt_cint64; + } + case mxUINT64_CLASS: + { + return edt_cuint64; + } + case mxSINGLE_CLASS: + { + return edt_cfloat32; + } + case mxDOUBLE_CLASS: + { + return edt_cfloat64; + } + } + } + else + { + switch (category) + { + case mxLOGICAL_CLASS: + { + return edt_bool; + } + case mxINT8_CLASS: + { + return edt_int8; + } + case mxUINT8_CLASS: + { + return edt_uint8; + } + case mxINT16_CLASS: + { + return edt_int16; + } + case mxUINT16_CLASS: + { + return edt_uint16; + } + case mxINT32_CLASS: + { + return edt_int32; + } + case mxUINT32_CLASS: + { + return edt_uint32; + } + case mxINT64_CLASS: + { + return edt_int64; + } + case mxUINT64_CLASS: + { + return edt_uint64; + } + case mxSINGLE_CLASS: + { + return edt_float32; + } + case mxDOUBLE_CLASS: + { + return edt_float64; + } + } + } + + return edt_none; + } + + eData_Typ mex_get_data_type_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_data_type(mxGetField(mxA, idx, field_name)); + + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return edt_none; + } + } + + eData_Typ mex_get_data_type_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_data_type_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + /********************** Vector: template for reading matlab data ***********************/ + /***************************************************************************************/ + template + mt::Vctr_cpu mex_get_vctr(const mxArray* mxA) + { + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_bool: + { + return mex_get_pvctr(mxA); + } + case edt_int8: + { + return mex_get_pvctr(mxA); + } + case edt_uint8: + { + return mex_get_pvctr(mxA); + } + case edt_int16: + { + return mex_get_pvctr(mxA); + } + case edt_uint16: + { + return mex_get_pvctr(mxA); + } + case edt_int32: + { + return mex_get_pvctr(mxA); + } + case edt_uint32: + { + return mex_get_pvctr(mxA); + } + case edt_int64: + { + return mex_get_pvctr(mxA); + } + case edt_uint64: + { + return mex_get_pvctr(mxA); + } + case edt_float32: + { + return mex_get_pvctr(mxA); + } + case edt_float64: + { + return mex_get_pvctr(mxA); + } + } + + return mt::Vctr_cpu(); + } + + template + mt::Vctr_r_2d_cpu mex_get_vctr_r_2d(const mxArray* mxA) + { + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_bool: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + } + + return mt::Vctr_cpu(); + } + + template + mt::Vctr_r_3d_cpu mex_get_vctr_r_3d(const mxArray* mxA) + { + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_bool: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + } + + return mt::Vctr_cpu(); + } + + /***************************************************************************************/ + /********************************** get dimensions *************************************/ + /***************************************************************************************/ + mt::Vctr_cpu mex_get_vctr_shape(const mxArray* mxA) + { + return mex_get_vctr(mxA); + } + + dt_shape mex_get_shape(const mxArray* mxA) + { + auto dim = mex_get_vctr(mxA); // nx, ny, nz + auto n_dim = min(4, dim.size_32()); + + dt_shape shape{1, 1, 1, 1}; + + for (auto ik = 0; ik(std::round(mxGetScalar(mxA))); + return data > 0; + } + + /***************************************************************************************/ + /*********************************** get enumeration ***********************************/ + /***************************************************************************************/ + template + T mex_get_enum(const mxArray* mxA) + { + auto data = static_cast(std::round(mxGetScalar(mxA))); + return static_cast(data); + } + + /***************************************************************************************/ + /************************************ get number ***************************************/ + /***************************************************************************************/ + template + T mex_get_num(const mxArray* mxA) + { + auto data = static_cast(std::round(mxGetScalar(mxA))); + return static_cast(data); + } + + template <> + dt_int32 mex_get_num(const mxArray* mxA) + { + return static_cast(std::round(mxGetScalar(mxA))); + } + + template <> + dt_float32 mex_get_num(const mxArray* mxA) + { + return static_cast(mxGetScalar(mxA)); + } + + template <> + dt_float64 mex_get_num(const mxArray* mxA) + { + return mxGetScalar(mxA); + } + + dt_cfloat64 mex_get_cmplx_num(const mxArray* mxA) + { + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_cint8: + { + auto r = mxGetComplexInt8s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint8: + { + auto r = mxGetComplexUint8s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cint16: + { + auto r = mxGetComplexInt16s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint16: + { + auto r = mxGetComplexUint16s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cint32: + { + auto r = mxGetComplexInt32s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint32: + { + auto r = mxGetComplexUint32s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cint64: + { + auto r = mxGetComplexInt64s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint64: + { + auto r = mxGetComplexUint64s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cfloat32: + { + auto r = mxGetComplexSingles(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cfloat64: + { + auto r = mxGetComplexDoubles(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + default: + { + return {mxGetScalar(mxA), dt_float64(0)}; + } + } + + return {dt_float64(0), dt_float64(0)}; + } + + template <> + dt_cfloat32 mex_get_num(const mxArray* mxA) + { + auto num = mex_get_cmplx_num(mxA); + + return {dt_float32(num.real()), dt_float32(num.imag())}; + } + + template <> + dt_cfloat64 mex_get_num(const mxArray* mxA) + { + auto num = mex_get_cmplx_num(mxA); + + return {num.real(), num.imag()}; + } + + /***************************************************************************************/ + /******************************** get r_2d/r_3d data ***********************************/ + /***************************************************************************************/ + template + mt::R_2d mex_get_r_2d(const mxArray* mxA, mt::R_2d r_0 = mt::R_2d(0, 0)) + { + if (mxA!=nullptr) + { + auto pvctr = mex_get_vctr(mxA); + return (pvctr.size()>=2)?mt::R_2d(pvctr.data()):r_0; + } + else + { + return r_0; + } + } + + template + mt::R_3d mex_get_r_3d(const mxArray* mxA, mt::R_3d r_0 = mt::R_3d(0, 0, 0)) + { + if (mxA!=nullptr) + { + auto vctr = mex_get_vctr(mxA); + return (vctr.size()>=3)?mt::R_3d(vctr.data()):r_0; + } + else + { + return r_0; + } + } + + /***************************************************************************************/ + /******************************** get repeat r_2d/r_3d ********************************/ + /***************************************************************************************/ + template + mt::R_2d mex_get_r_2d_rep(const mxArray* mxA) + { + const auto vctr = mex_get_vctr(mxA); + const auto n_vctr = vctr.size_32(); + + if (n_vctr<1) + return {1, 1}; + else if (n_vctr<2) + return {vctr[0], vctr[0]}; + else + return {vctr[0], vctr[1]}; + } + + template + mt::R_3d mex_get_r_3d_rep(const mxArray* mxA) + { + const auto vctr = mex_get_vctr(mxA); + const auto n_vctr = vctr.size_32(); + + if (n_vctr<1) + return {1, 1}; + else if (n_vctr<2) + return {vctr[0], vctr[0], vctr[0]}; + else if (n_vctr<3) + return {vctr[0], vctr[1], vctr[1]}; + else + return {vctr[0], vctr[1], vctr[2]}; + } + + /***************************************************************************************/ + /*********************************** get box size **************************************/ + /***************************************************************************************/ + template + mt::R_3d mex_get_r_3d_bs(const mxArray* mxA, mt::R_3d f) + { + return mex_get_r_3d_rep(mxA)*f; + } + + template + mt::R_3d mex_get_r_3d_bs(const mxArray* mxA, mt::Vctr_cpu& f) + { + return mex_get_r_3d_bs(mxA, mt::R_3d(f.m_data, f.size_32())); + } + + template + mt::R_3d mex_get_r_3d_bs(const mxArray* mxA, const dt_shape_st& shape) + { + return mex_get_r_3d_bs(mxA, mt::R_3d(shape[1], shape[0], shape[2])); + } + + /***************************************************************************************/ + /************************************ get r center *************************************/ + /***************************************************************************************/ + template + mt::R_3d mex_get_r_3d_r_c(const mxArray* mxA, mt::R_3d r_c_0 = mt::R_3d(0, 0, 0)) + { + const auto vctr = mex_get_vctr(mxA); + const dt_int32 n_vctr = vctr.size_32(); + mt::R_3d r = r_c_0; + + if (n_vctr<2) + r = mt::R_3d(vctr[0], vctr[0], vctr[0]); + else if (n_vctr<3) + r = mt::R_3d(vctr[0], vctr[1], vctr[1]); + else if (n_vctr<3) + r = mt::R_3d(vctr[0], vctr[1], vctr[2]); + + return r; + } + + /***************************************************************************************/ + /********************************** get data by field **********************************/ + /***************************************************************************************/ + template + mt::pVctr_cpu_64 mex_get_pvctr_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_pvctr(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_pvctr(nullptr); + } + } + + template + mt::pVctr_cpu_64 mex_get_pvctr_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_pvctr_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + template + mt::Vctr_cpu mex_get_vctr_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_vctr(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_vctr(nullptr); + } + } + + template + mt::Vctr_cpu mex_get_vctr_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_pvctr_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + template + mt::Vctr_r_2d_cpu mex_get_vctr_r_2d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_vctr_r_2d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_vctr_r_2d(nullptr); + } + } + + template + mt::Vctr_r_2d_cpu mex_get_vctr_r_2d_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_vctr_r_2d_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + template + mt::Vctr_r_3d_cpu mex_get_vctr_r_3d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_vctr_r_3d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_vctr_r_3d(nullptr); + } + } + + template + mt::Vctr_r_3d_cpu mex_get_vctr_r_3d_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_vctr_r_3d_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + dt_bool mex_get_bool_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, idx, field_name)) + { + return mex_get_bool(mxGetField(mxA, idx, field_name)); + } + else + { + return false; + } + } + + dt_bool mex_get_bool_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_bool_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + template + T mex_get_enum_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, idx, field_name)) + { + return mex_get_enum(mxGetField(mxA, idx, field_name)); + } + else + { + return T(0); + } + } + + template + T mex_get_enum_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_enum_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + template + T mex_get_num_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, idx, field_name)) + { + return mex_get_num(mxGetField(mxA, idx, field_name)); + } + else + { + return T(0); + } + } + + template + T mex_get_num_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_num_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + template + mt::R_2d mex_get_r_2d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name, mt::R_2d r_d = mt::R_2d(0, 0)) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_2d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_2d(nullptr); + } + } + + template + mt::R_2d mex_get_r_2d_from_field(const mxArray* mxA, const char *field_name, mt::R_2d r_d = mt::R_2d(0, 0)) + { + return mex_get_r_2d_from_field(mxA, 0, field_name, r_d); + } + + /***************************************************************************************/ + template + mt::R_3d mex_get_r_3d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name, mt::R_3d r_d = mt::R_3d(0, 0, 0)) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_3d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_3d(nullptr); + } + } + + template + mt::R_3d mex_get_r_3d_from_field(const mxArray* mxA, const char *field_name, mt::R_3d r_d = mt::R_3d(0, 0, 0)) + { + return mex_get_r_3d_from_field(mxA, 0, field_name, r_d); + } + + /***************************************************************************************/ + template + mt::R_2d mex_get_r_2d_rep_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_2d_rep(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_2d_rep(nullptr); + } + } + + template + mt::R_2d mex_get_r_2d_rep_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_r_2d_rep_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + template + mt::R_3d mex_get_r_3d_rep_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) + { + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_3d_rep(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_3d_rep(nullptr); + } + } + + template + mt::R_3d mex_get_r_3d_rep_from_field(const mxArray* mxA, const char *field_name) + { + return mex_get_r_3d_rep_from_field(mxA, 0, field_name); + } + + /***************************************************************************************/ + /************************ template for creation of matlab data *************************/ + /***************************************************************************************/ + template + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + return mt::pVctr_cpu_64(mex_data); + } + + /***************************************************************************************/ + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT8_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT8_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT16_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT16_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT32_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT32_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT64_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT64_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxSINGLE_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxDOUBLE_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); + } + + /***************************************************************************************/ + /******************************* create complex data ***********************************/ + /***************************************************************************************/ + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT8_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT8_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT16_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT16_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT32_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT32_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT64_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT64_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxSINGLE_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template <> + mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) + { + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxDOUBLE_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); + } + + template + mt::pVctr_cpu_64 mex_create_num(mxArray*& mex_data) + { + return mex_create_pVctr({1, 1}, mex_data); + } + + /***************************************************************************************/ + /**************************** create number/r_2d/r_3d data *****************************/ + /***************************************************************************************/ + template + mt::pVctr_cpu_64 mex_create_r_2d(mxArray*& mex_data) + { + return mex_create_pVctr({2, 1}, mex_data); + } + + template + mt::pVctr_cpu_64 mex_create_r_3d(mxArray*& mex_data) + { + return mex_create_pVctr({3, 1}, mex_data); + } + + /***************************************************************************************/ + template + mt::enable_if_number> + mex_create_set_pVctr(mxArray*& mex_data, const mt::pVctr_cpu_64& vctr) + { + auto pdata = mex_create_pVctr(vctr.shape(), mex_data); + mt::memcpy_cpu_cpu(pdata.data(), vctr.data(), vctr.size()); + + return pdata; + } + + template + mt::enable_if_r_2d> + mex_create_set_pVctr(mxArray*& mex_data, const mt::pVctr_cpu_64& vctr) + { + auto pdata = mex_create_pVctr({vctr.size(), 2}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr.data(), vctr.size()); + + return pdata; + } + + template + mt::enable_if_r_3d> + mex_create_set_pVctr(mxArray*& mex_data, const mt::pVctr_cpu_64& vctr) + { + auto pdata = mex_create_pVctr({vctr.size(), 3}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr.data(), vctr.size()); + + return pdata; + } + + template + mt::pVctr_cpu_64 mex_create_set_pVctr(mxArray*& mex_data, const mt::Vctr_r_2d& vctr_r_2d) + { + auto pdata = mex_create_pVctr({vctr_r_2d.size(), 2}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr_r_2d.data(), vctr_r_2d.size()); + + return pdata; + } + + template + mt::pVctr_cpu_64 mex_create_set_pVctr(mxArray*& mex_data, const mt::Vctr_r_3d& vctr_r_3d) + { + auto pdata = mex_create_pVctr({vctr_r_3d.size(), 3}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr_r_3d.data(), vctr_r_3d.size()); + + return pdata; + } + + template + mt::pVctr_cpu_64 mex_create_set_num(mxArray*& mex_data, const U& val) + { + auto pval = mex_create_num(mex_data); + pval[0] = T(val); + + return pval; + } + + /***************************************************************************************/ + template + mt::pVctr_cpu_64 mex_create_pVctr_field(dt_shape_64 shape, mxArray*& mex_data, const dt_int32& idx, const char *field_name) + { + mxArray* mxfield = nullptr; + auto pfield = mex_create_pVctr(shape, mxfield); + mxSetField(mex_data, idx, field_name, mxfield); + + return pfield; + } + + template + mt::pVctr_cpu_64 mex_create_pVctr_field(dt_shape_64 shape, mxArray*& mex_data, const char *field_name) + { + return mex_create_pVctr_field(shape, mex_data, 0, field_name); + } + + template + mt::pVctr_cpu_64 mex_create_num_field(mxArray*& mex_data, const dt_int32& idx, const char *field_name) + { + return mex_create_pVctr_field({1, 1}, mex_data, 0, field_name); + } + + template + mt::pVctr_cpu_64 mex_create_num_field(mxArray*& mex_data, const char *field_name) + { + return mex_create_num_field(mex_data, 0, field_name); + } + + /***************************************************************************************/ + template + mt::pVctr_cpu_64 mex_create_set_pVctr_field(mxArray*& mex_data, const dt_int32& idx, const char *field_name, const mt::pVctr_cpu_64& field_value) + { + auto pdata = mex_create_pVctr_field(field_value.shape(), mex_data, idx, field_name); + mt::memcpy_cpu_cpu(pdata.data(), field_value.data(), field_value.size()); + + return pdata; + } + + template + mt::pVctr_cpu_64 mex_create_set_pVctr_field(mxArray*& mex_data, const char *field_name, const mt::pVctr_cpu_64& field_value) + { + return mex_create_set_pVctr_field(mex_data, 0, field_name, field_value); + } + + template + mt::pVctr_cpu_64 mex_create_set_num_field(mxArray*& mex_data, const dt_int32& idx, const char *field_name, const U& field_value) + { + auto pdata = mex_create_num_field(mex_data, idx, field_name); + pdata[0] = field_value; + + return pdata; + } + + template + mt::pVctr_cpu_64 mex_create_set_num_field(mxArray*& mex_data, const char *field_name, const U& field_value) + { + return mex_create_set_num_field(mex_data, 0, field_name, field_value); + } + + /***************************************************************************************/ + /********************************** run mexFunction ************************************/ + /***************************************************************************************/ + #define MEX_RUN_FCN_INT(FCN, idx) \ + { \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + } \ + } \ + } + + #define MEX_RUN_FCN_FLOAT(FCN, idx) \ + { \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxSINGLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxDOUBLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + default: \ + { \ + mexPrintf("Error: Input data must be floating point\n"); \ + } \ + break; \ + } \ + } \ + } + + #define MEX_RUN_FCN_FLOAT_OUT(FCN, idx) \ + { \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxSINGLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + default: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + } \ + } \ + } + + #define MEX_RUN_FCN_REAL(FCN, idx) \ + { \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxSINGLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxDOUBLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + } \ + } \ + } + + + /***************************************************************************************/ + /**************************** mex system configuration *********************************/ + /***************************************************************************************/ + dt_bool mex_is_system_config(const mxArray* mxA) + { + return mxIsStruct(mxA) && mex_field_exist(mxA, "device") && mex_field_exist(mxA, "precision"); + } + + mt::System_Config mex_read_system_config(const mxArray* mex_in) + { + mt::System_Config system_config; + + if (mex_is_system_config(mex_in)) + { + system_config.device = mex_get_num_from_field(mex_in, "device"); + system_config.precision = mex_get_num_from_field(mex_in, "precision"); + // system_config.cpu_n_proc = 1; + system_config.cpu_n_proc = mex_get_num_from_field(mex_in, "cpu_n_proc"); + system_config.cpu_n_thread = mex_get_num_from_field(mex_in, "cpu_n_thread"); + + auto gpu_device = mex_get_pvctr_from_field(mex_in, "gpu_device"); + system_config.gpu_device.assign(gpu_device.begin(), gpu_device.end()); + system_config.gpu_n_stream = 1; + // system_config.gpu_n_stream = mex_get_num_from_field(mex_in, "gpu_n_stream"); + system_config.idx_0 = 1; + + system_config.set_dep_var(); + } + else + { + system_config.cpu_n_thread = 1; + system_config.idx_0 = 0; + } + + return system_config; + } + + mt::System_Config mex_read_set_system_config(const mxArray* mex_in) + { + auto system_config = mex_read_system_config(mex_in); + + if (system_config.is_gpu()) + { + system_config.set_gpu(); + } + + return system_config; + } + + /***************************************************************************************/ + /*************** this option set the output type using the in data ******************/ + /***************************************************************************************/ + #define MEX_RUN_FCN_INT_SYS_CONF_IN_TYP(FCN, idx_0) \ + { \ + auto bb_system_config = mex_is_system_config(prhs[0]); \ + auto idx = (bb_system_config)?idx_0+1:idx_0; \ + MEX_RUN_FCN_INT(FCN, idx); \ + } + + #define MEX_RUN_FCN_FLOAT_SYS_CONF_IN_TYP(FCN, idx_0) \ + { \ + auto bb_system_config = mex_is_system_config(prhs[0]); \ + auto idx = (bb_system_config)?idx_0+1:idx_0; \ + MEX_RUN_FCN_FLOAT(FCN, idx); \ + } + + #define MEX_RUN_FCN_REAL_SYS_CONF_IN_TYP(FCN, idx_0) \ + { \ + auto bb_system_config = mex_is_system_config(prhs[0]); \ + auto idx = (bb_system_config)?idx_0+1:idx_0; \ + MEX_RUN_FCN_REAL(FCN, idx); \ + } + + /***************************************************************************************/ + /************ this option set the output type using system configuration ***************/ + /***************************************************************************************/ + #define MEX_RUN_FCN_DEV(system_config, FCN, T) \ + if (system_config.is_cpu()) \ + { \ + FCNsystem_config, (nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_gpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } + +#ifdef __CUDACC__ + #define MEX_RUN_FCN_FLOAT_SYS_CONF(FCN, idx_0) \ + { \ + auto system_config = mex_read_set_system_config(prhs[idx_0]); \ + \ + if (system_config.is_float32_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float64_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float32_gpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float64_gpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + } +#else + #define MEX_RUN_FCN_FLOAT_SYS_CONF(FCN, idx_0) \ + { \ + auto system_config = mex_read_set_system_config(prhs[idx_0]); \ + \ + if (system_config.is_float32_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float64_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + } + #endif + +#endif \ No newline at end of file diff --git a/src - Copy (2)/matlab_multem_io.cuh b/src - Copy (2)/matlab_multem_io.cuh new file mode 100755 index 00000000..0f75a67c --- /dev/null +++ b/src - Copy (2)/matlab_multem_io.cuh @@ -0,0 +1,358 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MATLAB_MULTEM_IO_H + #define MATLAB_MULTEM_IO_H + + #include + #include + #include + + #include "types_mt.cuh" + #include "type_traits_gen.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "rot_in_parm.hpp" + #include "atomic_vib.hpp" + #include "beam_pos_2d.hpp" + #include "scan_pat.hpp" + #include "spec_slic_in_parm.hpp" + #include "lens.cuh" + #include "particles.cuh" + + #include + #include "matlab_mex.cuh" + + /************************ read beam positions *************************/ + template + void mex_read_beam_pos(const mxArray* mex_array, mt::Beam_Pos_2d& beam_pos) + { + auto pbeam_pos = mex_get_pvctr_from_field(mex_array, "beam_pos"); + beam_pos.set_in_data(pbeam_pos); + } + + /************************ read user define wave ************************/ + template + void mex_read_user_define_wave(const mxArray* mex_array, mt::Vctr_cpu& psi) + { + auto ppsi = mex_get_pvctr_from_field(mex_array, "iw_psi"); + psi.assign(ppsi); + } + + /*********************** read specimen thickness ***********************/ + template + void mex_read_spec_thick(const mxArray* mex_array, mt::Vctr_cpu& thick) + { + auto pthick = mex_get_pvctr_from_field(mex_array, "thick"); + thick.assign(pthick); + } + + /************************** read output area ***************************/ + void mex_read_output_area(const mxArray* mex_array, mt::iThread_Rect_2d& output_area) + { + const auto ip_0 = mex_get_vctr_from_field(mex_array, "output_area_ip_0"); + const auto ip_e = mex_get_vctr_from_field(mex_array, "output_area_ip_e"); + + output_area.ix_0 = static_cast(ip_0[0])-1; + output_area.iy_0 = static_cast(ip_0[1])-1; + output_area.ix_e = static_cast(ip_e[0])-1; + output_area.iy_e = static_cast(ip_e[1])-1; + } + + /********************** atomic vibration model ************************/ + void mex_read_atomic_vib(const mxArray* mex_array, mt::Atomic_Vib& atomic_vib) + { + atomic_vib.model = mex_get_enum_from_field(mex_array, "atomic_vib_mod"); + atomic_vib.coh_contrib = mex_get_bool_from_field(mex_array, "atomic_vib_coh_contrib"); + atomic_vib.sgl_conf = mex_get_bool_from_field(mex_array, "atomic_vib_sgl_conf"); + atomic_vib.nconf = mex_get_num_from_field(mex_array, "atomic_vib_nconf"); + atomic_vib.dim = mex_get_r_3d_from_field(mex_array, "atomic_vib_dim", mt::R_3d(1, 1, 0)); + atomic_vib.seed = mex_get_num_from_field(mex_array, "atomic_vib_seed"); + + atomic_vib.set_dep_var(); + } + + /****************************** read atoms *****************************/ + template + void mex_read_atoms(const mxArray* mex_array, mt::R_3d bs, dt_bool pbc_xy, dt_bool b_statistic, mt::Ptc_Atom& atoms) + { + auto patoms = mex_get_pvctr_from_field(mex_array, "spec_atoms"); + + atoms.set_ptc(patoms, bs, pbc_xy, b_statistic); + } + + //template + //void mex_read_atoms(const mxArray* mex_array, T bs_x, T bs_y, T bs_z, T sli_thick, mt::Ptc_Atom& atoms) + //{ + // auto patoms = mex_get_pvctr_from_field(mex_array, "spec_atoms"); + // + // auto ct_na = mex_get_num_from_field(mex_array, "spec_cryst_na"); + // auto ct_nb = mex_get_num_from_field(mex_array, "spec_cryst_nb"); + // auto ct_nc = mex_get_num_from_field(mex_array, "spec_cryst_nc"); + // auto ct_a = mex_get_num_from_field(mex_array, "spec_cryst_a"); + // auto ct_b = mex_get_num_from_field(mex_array, "spec_cryst_b"); + // auto ct_c = mex_get_num_from_field(mex_array, "spec_cryst_c"); + // auto ct_x0 = mex_get_num_from_field(mex_array, "spec_cryst_x0"); + // auto ct_y0 = mex_get_num_from_field(mex_array, "spec_cryst_y0"); + // + // auto mex_spec_amorp = mxGetField(mex_array, 0, "spec_amorp"); + // mt::Vctr_Spec_Lay_Info spec_lay_info(mxGetN(mex_spec_amorp)); + // for(auto ik = 0; ik < spec_lay_info.size(); ik++) + // { + // spec_lay_info[ik].z_0 = mex_get_num_from_field(mex_spec_amorp, ik, "z_0"); + // spec_lay_info[ik].z_e = mex_get_num_from_field(mex_spec_amorp, ik, "z_e"); + // spec_lay_info[ik].sli_thick = mex_get_num_from_field(mex_spec_amorp, ik, "sli_thick"); + // } + // + // atoms.set_xtl_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); + // atoms.set_amorphous_parameters(spec_lay_info); + // atoms.set_ptc(patoms, bs, sli_thick); + //} + + /*********************** read rotation parameters *********************/ + template + void mex_read_rot_in_parm(const mxArray* mex_array, mt::Rot_In_Parm& rot_in_parm) + { + rot_in_parm.theta = mex_get_num_from_field(mex_array, "spec_rot_theta")*mt::c_deg_2_rad; + rot_in_parm.u_0 = mex_get_r_3d_from_field(mex_array, "spec_rot_u_0", mt::R_3d(0, 0, 1)); + rot_in_parm.ctr_type = mex_get_enum_from_field(mex_array, "spec_rot_ctr_typ"); + rot_in_parm.ctr_p = mex_get_r_3d_from_field(mex_array, "spec_rot_ctr_p", mt::R_3d(0, 0, 0)); + + rot_in_parm.set_dep_var(); + } + + /*************************** specimen slicing *************************/ + template + void mex_read_spec_sli_in_parm(const mxArray* mex_array, mt::Vctr_Spec_Slic_In_Parm& spec_slic_in_parm) + { + auto mex_spec_slic = mxGetField(mex_array, 0, "spec_slic"); + + spec_slic_in_parm.resize(mex_get_s0(mex_spec_slic)); + for(auto ik = 0; ik < spec_slic_in_parm.size(); ik++) + { + spec_slic_in_parm[ik].typ = mex_get_enum_from_field(mex_spec_slic, ik, "typ"); + spec_slic_in_parm[ik].sli_thick = mex_get_num_from_field(mex_spec_slic, ik, "sli_thick"); + spec_slic_in_parm[ik].sel_typ = mex_get_enum_from_field(mex_spec_slic, ik, "sel_typ"); + spec_slic_in_parm[ik].sel_tag = mex_get_num_from_field(mex_spec_slic, ik, "sel_tag"); + spec_slic_in_parm[ik].sel_Z = mex_get_num_from_field(mex_spec_slic, ik, "sel_Z"); + spec_slic_in_parm[ik].sel_z_lim = mex_get_r_2d_from_field(mex_spec_slic, ik, "sel_z_lim"); + auto pz_plns = mex_get_pvctr_from_field(mex_array, ik, "z_plns"); + spec_slic_in_parm[ik].z_plns.assign(pz_plns); + } + } + + /************************ read condenser lens *************************/ + template + void mex_read_cond_lens(const mxArray* mex_array, mt::Lens& cond_lens) + { + cond_lens.m = mex_get_num_from_field(mex_array, "cond_lens_m"); // momentum of the vortex + cond_lens.c_10 = mex_get_num_from_field(mex_array, "cond_lens_c_10"); // defocus (Angstrom) + cond_lens.c_12 = mex_get_num_from_field(mex_array, "cond_lens_c_12"); // 2-fold astigmatism (Angstrom) + cond_lens.phi_12 = mex_get_num_from_field(mex_array, "cond_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) + + cond_lens.c_21 = mex_get_num_from_field(mex_array, "cond_lens_c_21"); // Axial coma (Angstrom) + cond_lens.phi_21 = mex_get_num_from_field(mex_array, "cond_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) + cond_lens.c_23 = mex_get_num_from_field(mex_array, "cond_lens_c_23"); // 3-fold astigmatism (Angstrom) + cond_lens.phi_23 = mex_get_num_from_field(mex_array, "cond_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) + + cond_lens.c_30 = mex_get_num_from_field(mex_array, "cond_lens_c_30")*mt::c_mm_2_angs; // 3rd order spherical aberration (mm-->Angstrom) + cond_lens.c_32 = mex_get_num_from_field(mex_array, "cond_lens_c_32"); // Axial star aberration (Angstrom) + cond_lens.phi_32 = mex_get_num_from_field(mex_array, "cond_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) + cond_lens.c_34 = mex_get_num_from_field(mex_array, "cond_lens_c_34"); // 4-fold astigmatism (Angstrom) + cond_lens.phi_34 = mex_get_num_from_field(mex_array, "cond_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) + + cond_lens.c_41 = mex_get_num_from_field(mex_array, "cond_lens_c_41"); // 4th order axial coma (Angstrom) + cond_lens.phi_41 = mex_get_num_from_field(mex_array, "cond_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) + cond_lens.c_43 = mex_get_num_from_field(mex_array, "cond_lens_c_43"); // 3-lobe aberration (Angstrom) + cond_lens.phi_43 = mex_get_num_from_field(mex_array, "cond_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) + cond_lens.c_45 = mex_get_num_from_field(mex_array, "cond_lens_c_45"); // 5-fold astigmatism (Angstrom) + cond_lens.phi_45 = mex_get_num_from_field(mex_array, "cond_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) + + cond_lens.c_50 = mex_get_num_from_field(mex_array, "cond_lens_c_50")*mt::c_mm_2_angs; // 5th order spherical aberration (mm-->Angstrom) + cond_lens.c_52 = mex_get_num_from_field(mex_array, "cond_lens_c_52"); // 5th order axial star aberration (Angstrom) + cond_lens.phi_52 = mex_get_num_from_field(mex_array, "cond_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) + cond_lens.c_54 = mex_get_num_from_field(mex_array, "cond_lens_c_54"); // 5th order rosette aberration (Angstrom) + cond_lens.phi_54 = mex_get_num_from_field(mex_array, "cond_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) + cond_lens.c_56 = mex_get_num_from_field(mex_array, "cond_lens_c_56"); // 6-fold astigmatism (Angstrom) + cond_lens.phi_56 = mex_get_num_from_field(mex_array, "cond_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) + + cond_lens.inner_aper_ang = mex_get_num_from_field(mex_array, "cond_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) + cond_lens.outer_aper_ang = mex_get_num_from_field(mex_array, "cond_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) + + /********************* defocus spread function ********************/ + cond_lens.tp_inc_a = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + cond_lens.tp_inc_sigma = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.tp_inc_beta = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.tp_inc_npts = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_npts"); // number of integration points + + /***************** source size broadening function *****************/ + cond_lens.spt_inc_a = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + cond_lens.spt_inc_sigma = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.spt_inc_beta = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.spt_inc_rad_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_rad_npts"); // number of radial integration points + cond_lens.spt_inc_azm_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_azm_npts"); // number of azimuth integration points + + /********************* zero defocus reference ********************/ /********************* zero defocus reference ********************/ + cond_lens.zero_def_typ = mex_get_enum_from_field(mex_array, "cond_lens_zero_def_typ"); // Zero defocus type + cond_lens.zero_def_plane = mex_get_num_from_field(mex_array, "cond_lens_zero_def_plane"); // Zero defocus position + } + + /************************* read objective lens ************************/ + template + void mex_read_obj_lens(const mxArray* mex_array, mt::Lens& obj_lens) + { + obj_lens.m = mex_get_num_from_field(mex_array, "obj_lens_m"); // momentum of the vortex + obj_lens.c_10 = mex_get_num_from_field(mex_array, "obj_lens_c_10"); // defocus (Angstrom) + obj_lens.c_12 = mex_get_num_from_field(mex_array, "obj_lens_c_12"); // 2-fold astigmatism (Angstrom) + obj_lens.phi_12 = mex_get_num_from_field(mex_array, "obj_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) + + obj_lens.c_21 = mex_get_num_from_field(mex_array, "obj_lens_c_21"); // Axial coma (Angstrom) + obj_lens.phi_21 = mex_get_num_from_field(mex_array, "obj_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) + obj_lens.c_23 = mex_get_num_from_field(mex_array, "obj_lens_c_23"); // 3-fold astigmatism (Angstrom) + obj_lens.phi_23 = mex_get_num_from_field(mex_array, "obj_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) + + obj_lens.c_30 = mex_get_num_from_field(mex_array, "obj_lens_c_30")*mt::c_mm_2_angs; // 3rd order spherical aberration (mm-->Angstrom) + obj_lens.c_32 = mex_get_num_from_field(mex_array, "obj_lens_c_32"); // Axial star aberration (Angstrom) + obj_lens.phi_32 = mex_get_num_from_field(mex_array, "obj_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) + obj_lens.c_34 = mex_get_num_from_field(mex_array, "obj_lens_c_34"); // 4-fold astigmatism (Angstrom) + obj_lens.phi_34 = mex_get_num_from_field(mex_array, "obj_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) + + obj_lens.c_41 = mex_get_num_from_field(mex_array, "obj_lens_c_41"); // 4th order axial coma (Angstrom) + obj_lens.phi_41 = mex_get_num_from_field(mex_array, "obj_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) + obj_lens.c_43 = mex_get_num_from_field(mex_array, "obj_lens_c_43"); // 3-lobe aberration (Angstrom) + obj_lens.phi_43 = mex_get_num_from_field(mex_array, "obj_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) + obj_lens.c_45 = mex_get_num_from_field(mex_array, "obj_lens_c_45"); // 5-fold astigmatism (Angstrom) + obj_lens.phi_45 = mex_get_num_from_field(mex_array, "obj_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) + + obj_lens.c_50 = mex_get_num_from_field(mex_array, "obj_lens_c_50")*mt::c_mm_2_angs; // 5th order spherical aberration (mm-->Angstrom) + obj_lens.c_52 = mex_get_num_from_field(mex_array, "obj_lens_c_52"); // 5th order axial star aberration (Angstrom) + obj_lens.phi_52 = mex_get_num_from_field(mex_array, "obj_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) + obj_lens.c_54 = mex_get_num_from_field(mex_array, "obj_lens_c_54"); // 5th order rosette aberration (Angstrom) + obj_lens.phi_54 = mex_get_num_from_field(mex_array, "obj_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration(degrees-->rad) + obj_lens.c_56 = mex_get_num_from_field(mex_array, "obj_lens_c_56"); // 6-fold astigmatism (Angstrom) + obj_lens.phi_56 = mex_get_num_from_field(mex_array, "obj_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) + + obj_lens.inner_aper_ang = mex_get_num_from_field(mex_array, "obj_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) + obj_lens.outer_aper_ang = mex_get_num_from_field(mex_array, "obj_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) + + /********************* defocus spread function ********************/ + obj_lens.tp_inc_a = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + obj_lens.tp_inc_sigma = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.tp_inc_beta = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.tp_inc_npts = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_npts"); // number of integration points + + /********************* source spread function *********************/ + obj_lens.spt_inc_a = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + obj_lens.spt_inc_sigma = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.spt_inc_beta = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.spt_inc_rad_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_rad_npts"); // number of radial integration points + obj_lens.spt_inc_azm_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_azm_npts"); // number of azimuth integration points + + /********************* zero defocus reference ********************/ + obj_lens.zero_def_typ = mex_get_num_from_field(mex_array, "obj_lens_zero_def_typ"); // Zero defocus type + obj_lens.zero_def_plane = mex_get_num_from_field(mex_array, "obj_lens_zero_def_plane"); // Zero defocus position + } + + /*************************** read scanning ****************************/ + template + void mex_read_scan_pat(const mxArray* mex_array, mt::Scan_Pat& scan_pat) + { + scan_pat.typ = mex_get_enum_from_field(mex_array, "scan_pat_typ"); + scan_pat.pbc = mex_get_bool_from_field(mex_array, "scan_pat_pbc"); + scan_pat.spxs = mex_get_bool_from_field(mex_array, "scan_pat_spxs"); + scan_pat.nsp = mex_get_r_2d_rep_from_field(mex_array, "scan_pat_nsp"); + scan_pat.r_0 = mex_get_r_2d_from_field(mex_array, "scan_pat_r_0"); + scan_pat.r_e = mex_get_r_2d_from_field(mex_array, "scan_pat_r_e"); + + if (scan_pat.is_scan_pat_user_def()) + { + scan_pat.r = mex_get_vctr_r_2d_from_field(mex_array, "scan_pat_r"); + } + + scan_pat.set_dep_var(); + } + + /***************************** read detector ***************************/ + template + void mex_read_detector(const mxArray* mex_array, T E_0, mt::Detector& detector) + { + T lambda = mt::fcn_lambda(E_0); + mxArray* mex_detector = mxGetField(mex_array, 0, "detector"); + detector.type = mex_get_enum_from_field(mex_detector, "type"); + + switch (detector.type) + { + case mt::edt_circular: + { + mex_detector = mxGetField(mex_detector, 0, "cir"); + dt_int32 ndetector = mex_get_MxN(mex_detector); + if (ndetector > 0) + { + detector.resize(ndetector); + for(auto i = 0; i < detector.size(); i++) + { + auto inner_ang = mex_get_num_from_field(mex_detector, i, "inner_ang")*mt::c_mrad_2_rad; + detector.g_inner[i] = sin(inner_ang)/lambda; + auto outer_ang = mex_get_num_from_field(mex_detector, i, "outer_ang")*mt::c_mrad_2_rad; + detector.g_outer[i] = sin(outer_ang)/lambda; + } + } + } + break; + case mt::edt_radial: + { + mex_detector = mxGetField(mex_detector, 0, "radial"); + dt_int32 ndetector = mxGetN(mex_detector); + if (ndetector > 0) + { + detector.resize(ndetector); + for(auto i = 0; i < detector.size(); i++) + { + // auto x = mex_get_pvctr_from_field(mex_detector, i, "x"); + // mt::assign(x, detector.x[i]); + // mt::fcn_scale(detector.x[i], 1.0/lambda); + + auto fx = mex_get_pvctr_from_field(mex_detector, i, "fx"); + mt::assign(fx, detector.fx[i]); + } + } + } + break; + case mt::edt_matrix: + { + mex_detector = mxGetField(mex_detector, 0, "matrix"); + dt_int32 ndetector = mxGetN(mex_detector); + if (ndetector > 0) + { + detector.resize(ndetector); + for(auto i = 0; i < detector.size(); i++) + { + // auto R = mex_get_pvctr_from_field(mex_detector, i, "x"); + // mt::assign(R, detector.R[i]); + // mt::fcn_scale(detector.R[i], 1.0/lambda); + // mt::fcn_fftsft_2d(grid_2d, detector.R[i]); + + auto fR = mex_get_pvctr_from_field(mex_detector, i, "fR"); + mt::assign(fR, detector.fR[i]); + } + } + } + break; + } + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/memcpy.cuh b/src - Copy (2)/memcpy.cuh new file mode 100755 index 00000000..f0ae7514 --- /dev/null +++ b/src - Copy (2)/memcpy.cuh @@ -0,0 +1,342 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is destroy software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MEMCPY_H + #define MEMCPY_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + + #ifdef __CUDACC__ + #include + #include + #endif + + /* gpu data cast */ + namespace mt + { + namespace gpu_detail + { + #ifdef __CUDACC__ + template + __global__ void fcn_data_typ_cast(Td* data_dst, Ts* data_src, dt_int32 n_data) + { + FOR_IX_1DC(n_data) + { + data_dst[ix] = Td(data_src[ix]); + } + } + + template + __global__ void fcn_real_gpu_gpu(Td* data_dst, Ts* data_src, dt_int32 n_data) + { + FOR_IX_1DC(n_data) + { + data_dst[ix] = Td(data_src[ix].real()); + } + } + + template + __global__ void fcn_imag_gpu_gpu(Td* data_dst, Ts* data_src, dt_int32 n_data) + { + FOR_IX_1DC(n_data) + { + data_dst[ix] = Td(data_src[ix].imag()); + } + } + #endif + } + } + + /* data copy */ + namespace mt + { + /******************************* (dst, src): cpu -> cpu ********************************/ + template + void memcpy_cpu_cpu(Td* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + pcpu_dst[ik] = Td(pcpu_src[ik]); + } + } + + #ifdef __CUDACC__ + /******************************* (dst, src): gpu -> cpu ********************************/ + template + enable_if_same_decay + memcpy_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + cudaMemcpy(pcpu_dst, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + } + + template + enable_if_diff_decay + memcpy_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + if (pcpu_jk == nullptr) + { + Ts* pcpu_t = new Ts[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_cpu_cpu(pcpu_dst, pcpu_t, n_size); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_cpu_cpu(pcpu_dst, pcpu_jk, n_size); + } + } + + /******************************* (dst, src): gpu -> gpu ********************************/ + // (dst, src): gpu -> gpu + template + enable_if_same_decay + memcpy_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(Td)); + cudaMemcpy(pgpu_dst, pgpu_src, size_bytes, cudaMemcpyDeviceToDevice); + } + + template + enable_if_diff_decay + memcpy_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + // dt_int32 numSMs; + // cudaDeviceGetAttribute(&numSMs, cudaDevAttrMultiProcessorCount, devId); + + auto grid = fcn_cdg_1d(n_size); + grid.x = min(128, grid.x); + + gpu_detail::fcn_data_typ_cast<<>>(pgpu_dst, pgpu_src, dt_int32(n_size)); + } + + /******************************* (dst, src): cpu -> gpu ********************************/ + template + enable_if_same_decay + memcpy_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + cudaMemcpy(pgpu_dst, pcpu_src, size_bytes, cudaMemcpyHostToDevice); + } + + template + enable_if_diff_decay + memcpy_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + if (pcpu_jk == nullptr) + { + Td* pcpu_t = new Td[n_size]; + memcpy_cpu_cpu(pcpu_t, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_cpu_cpu(pcpu_jk, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + + #endif + + } + + /* complex real data copy */ + namespace mt + { + // (dst, src): cpu -> cpu + template + enable_if_cmplx + memcpy_real_cpu_cpu(Td* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pcpu_src) + return; + + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + pcpu_dst[ik] = Td(pcpu_src[ik].real()); + } + } + + #ifdef __CUDACC__ + // (dst, src): gpu -> cpu + template + enable_if_cmplx + memcpy_real_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pgpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + if (pcpu_jk == nullptr) + { + Ts* pcpu_t = new Ts[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_real_cpu_cpu(pcpu_dst, pcpu_t, n_size); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_real_cpu_cpu(pcpu_dst, pcpu_jk, n_size); + } + } + + // (dst, src): gpu -> gpu + template + enable_if_cmplx + memcpy_real_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pgpu_src) + return; + + auto grid = fcn_cdg_1d(n_size); + grid.x = min(128, grid.x); + + gpu_detail::fcn_real_gpu_gpu<<>>(pgpu_dst, pgpu_src, dt_int32(n_size)); + } + + // (dst, src): cpu -> gpu + template + enable_if_cmplx + memcpy_real_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pcpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + if (pcpu_jk == nullptr) + { + Td* pcpu_t = new Td[n_size]; + memcpy_real_cpu_cpu(pcpu_t, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_real_cpu_cpu(pcpu_jk, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + + #endif + + } + + /* complex imag data copy */ + namespace mt + { + // (dst, src): cpu -> cpu + template + enable_if_cmplx + memcpy_imag_cpu_cpu(Td* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pcpu_src) + return; + + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + pcpu_dst[ik] = Td(pcpu_src[ik].imag()); + } + } + + #ifdef __CUDACC__ + // (dst, src): gpu -> cpu + template + enable_if_cmplx + memcpy_imag_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pgpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + if (pcpu_jk == nullptr) + { + Ts* pcpu_t = new Ts[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_imag_cpu_cpu(pcpu_dst, pcpu_t, n_size); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_imag_cpu_cpu(pcpu_dst, pcpu_jk, n_size); + } + } + + // (dst, src): gpu -> gpu + template + enable_if_cmplx + memcpy_imag_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pgpu_src) + return; + + auto grid = fcn_cdg_1d(n_size); + grid.x = min(128, grid.x); + + gpu_detail::fcn_imag_gpu_gpu<<>>(pgpu_dst, pgpu_src, dt_int32(n_size)); + } + + // (dst, src): cpu -> gpu + template + enable_if_cmplx + memcpy_imag_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pcpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + if (pcpu_jk == nullptr) + { + Td* pcpu_t = new Td[n_size]; + memcpy_imag_cpu_cpu(pcpu_t, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_imag_cpu_cpu(pcpu_jk, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + + #endif + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/microscope_effects.cuh b/src - Copy (2)/microscope_effects.cuh new file mode 100755 index 00000000..fd0ee715 --- /dev/null +++ b/src - Copy (2)/microscope_effects.cuh @@ -0,0 +1,194 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MICROSCOPE_EFFECTS_H +#define MICROSCOPE_EFFECTS_H + +#include "math.cuh" +#include "types.cuh" +#include "cpu_fcns.hpp" +#include "gpu_fcns.cuh" +#include "cgpu_fcns.cuh" +#include "quad_data.cuh" + +namespace mt +{ + template + class Microscope_Effects + { + public: + using T_r = T; + using T_c = complex; + + Microscope_Effects(): multem_in_parm(nullptr), stream(nullptr), fft_2d(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + multem_in_parm = multem_in_parm_i; + stream = stream_i; + fft_2d = fft2_i; + + psi.resize(multem_in_parm->grid_2d.size()); + + if ((multem_in_parm->illum_mod == eim_coherent)||(multem_in_parm->illum_mod == eim_partial_coherent)) + { + return; + } + + // Load quadratures + obj_lens_temporal_spatial_quadratures(multem_in_parm->obj_lens, qt, qs); + } + + void operator()(Vctr& fpsi, Vctr& m2psi_tot) + { + switch(multem_in_parm->illum_mod) + { + case eim_coherent: + { + CTF_TEM(multem_in_parm->illum_inc, fpsi, m2psi_tot); + } + break; + case eim_partial_coherent: + { + PCTF_LI_WPO_TEM(multem_in_parm->illum_inc, fpsi, m2psi_tot); + } + break; + case eim_trans_cross_coef: + { + + } + break; + case eim_full_integration: + { + num_int_TEM(multem_in_parm->illum_inc, fpsi, m2psi_tot); + } + break; + } + } + + template + void operator()(TOutput_multislice &output_multem) + { + Vctr psi(multem_in_parm->iw_psi.begin(), multem_in_parm->iw_psi.end()); + mt::fcn_fftsft_2d(*stream, multem_in_parm->grid_2d, psi); + fft_2d->forward(psi); + mt::fcn_scale(*stream, multem_in_parm->grid_2d.isize_r(), psi); + + Vctr m2psi_tot(multem_in_parm->grid_2d.size()); + this->operator()(psi, m2psi_tot); + mt::cpy_to_host(output_multem.stream, m2psi_tot, output_multem.m2psi_tot[0]); + } + + private: + void CTF_TEM(const eIllum_Inc &illum_inc, Vctr& fpsi, Vctr& m2psi_tot) + { + mt::fcn_apply_ctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, 0, 0, fpsi, psi); + fft_2d->inverse(psi); + mt::square(*stream, psi, m2psi_tot); + } + + void PCTF_LI_WPO_TEM(const eIllum_Inc &illum_inc, Vctr& fpsi, Vctr& m2psi_tot) + { + T_r tp_inc_sigma = multem_in_parm->obj_lens.tp_inc_sigma; + T_r spt_inc_sigma = multem_in_parm->obj_lens.spt_inc_sigma; + + switch(illum_inc) + { + case eii_temporal: // Temporal + { + multem_in_parm->obj_lens.set_spt_inc_sigma(0); + } + break; + case etst_spatial: // Spatial + { + multem_in_parm->obj_lens.set_tp_inc_sigma(0); + } + break; + } + + mt::fcn_apply_pctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, fpsi, psi); + fft_2d->inverse(psi); + mt::square(*stream, psi, m2psi_tot); + + multem_in_parm->obj_lens.set_tp_inc_sigma(tp_inc_sigma); + multem_in_parm->obj_lens.set_spt_inc_sigma(spt_inc_sigma); + } + + void num_int_TEM(const eIllum_Inc &illum_inc, Vctr& fpsi, Vctr& m2psi_tot) + { + T_r c_10_0 = multem_in_parm->obj_lens.c_10; + + fill(*stream, m2psi_tot, 0.0); + switch(illum_inc) + { + case 1: // Temporal and Spatial + { + for(auto i = 0; iobj_lens.tp_inc_iehwgd*qt.x[j]+c_10_0; + multem_in_parm->obj_lens.set_defocus(c_10); + + mt::fcn_apply_ctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, qs.x[i], qs.y[i], fpsi, psi); + fft_2d->inverse(psi); + mt::add_scale_norm_2(*stream, qs.w[i]*qt.w[j], psi, m2psi_tot); + } + } + } + break; + case 2: // Temporal + { + for(auto j = 0; jobj_lens.tp_inc_iehwgd*qt.x[j]+c_10_0; + multem_in_parm->obj_lens.set_defocus(c_10); + + mt::fcn_apply_ctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, 0.0, 0.0, fpsi, psi); + fft_2d->inverse(psi); + mt::add_scale_norm_2(*stream, qt.w[j], psi, m2psi_tot); + } + } + break; + case 3: // Spatial + { + for(auto i = 0; igrid_2d, multem_in_parm->obj_lens, qs.x[i], qs.y[i], fpsi, psi); + fft_2d->inverse(psi); + mt::add_scale_norm_2(*stream, qs.w[i], psi, m2psi_tot); + } + } + } + + multem_in_parm->obj_lens.set_defocus(c_10_0); + } + + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + + Vctr psi; + + Quad_Coef_1d qt; + Quad_Coef_2d qs; + }; + +} + +#endif \ No newline at end of file diff --git a/src - Copy (2)/multem_in_parm.cuh b/src - Copy (2)/multem_in_parm.cuh new file mode 100755 index 00000000..bacee169 --- /dev/null +++ b/src - Copy (2)/multem_in_parm.cuh @@ -0,0 +1,1016 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MULTEM_IN_PARM_H + #define MULTEM_IN_PARM_H + + #include + + #include "math.cuh" + #include "types_mt.cuh" + #include "particles.cuh" + #include "atomic_vib.hpp" + #include "rot_in_parm.hpp" + #include "spec_slic_in_parm.hpp" + #include "beam_pos_2d.hpp" + #include "scan_pat.hpp" + #include "lens.cuh" + #include "cgpu_info.cuh" + #include "cgpu_vctr.cuh" + + /* multem */ + namespace mt + { + dt_bool is_gpu_avbl(); + + dt_int32 gpu_n_avbl(); + + template + class EELS; + + /**************************** Input multem *****************************/ + template + struct Spec_Slic; + + template + class Multem_In_Parm + { + public: + using value_type = T; + + System_Config system_config; // System information + + eElec_Spec_Interact_Mod elec_spec_interact_mod; // eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 + eAtomic_Pot_Parm_Typ atomic_pot_parm_typ; // potential type: 1: doyle(0-4), 2: Peng(0-4), 3: peng(0-12), 4: Kirkland(0-12), 5:Weickenmeier(0-12) adn 6: Lobato(0-12) + + Atomic_Vib atomic_vib; // phonon parameters + + Ptc_Atom atoms; // atoms + dt_bool is_xtl; // is a crystalline specimen? + + Rot_In_Parm rot_in_parm; // specimen rotation parameters + + Vctr_Spec_Slic_In_Parm spec_slic_in_parm; // specimen slicing input parameters + + eSim_Thick_Typ thick_type; // estt_whole_spec = 1, estt_through_thick = 2, estt_through_slices = 3 + Vctr_cpu thick; // Array of thicknesses + + Grid_2d grid_2d; // grid information + + iThread_Rect_2d output_area; // Output region information + + eEM_Sim_Typ em_sim_typ; // 11: STEM, 12: ISTEM, 21: cbed, 22: cbei, 31: ED, 32: hrtem, 41: ped, 42: hci, ... 51: EW Fourier, 52: EW real + + eIncident_Wave_Typ iw_type; // 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto + Vctr_cpu> iw_psi; // user define incident wave + + Beam_Pos_2d beam_pos_2d; // in beam positions + + T E_0; // Acceleration volatage in KeV + T lambda; // lambda + T theta; // incident tilt (in spherical coordinates) (rad) + T phi; // incident tilt (in spherical coordinates) (rad) + + eIllum_Mod illum_mod; // 1: coherent mode, 2: Partial coherente mode, 2: transmission cross coefficient, 2: full integration + eIllum_Inc illum_inc; // 1: Spatial and temporal, 2: Temporal, 3: Spatial + + Lens cond_lens; // Condenser lens + Lens obj_lens; // Objective lens + + Scan_Pat scanning; // Scan_Pat + + Detector detector; // STEM Detectors + + EELS eels_fr; // EELS + + eOperation_Mode operation_mode; // eOM_Normal = 1, eOM_Advanced = 2 + dt_bool slice_storage; // true, false + dt_bool reverse_multislice; // reverse multislice (true, false) + dt_int32 mul_sign; // tem_simulation sign + + T Vrl; // atomic potential cut-off + dt_int32 nR; // number of d_grid_blk points + + dt_int32 nrot; // Total number of rotations + + eLens_Var_Typ cdl_var_type; // eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 + Vctr_cpu cdl_var; // Array of thicknesses + + Beam_Pos_2d beam_pos; // beam positions + + dt_int32 islice; + dt_bool dp_Shift; // Shift diffraction pattern + + Multem_In_Parm(): system_config(), elec_spec_interact_mod(eesim_multislice), + atomic_pot_parm_typ(eappt_lobato_0_12), atomic_vib(), atoms(), rot_in_parm(), spec_slic_in_parm(), + thick_type(estt_whole_spec), thick(), grid_2d(), output_area(), output_area(), + iw_type(), iw_psi(), beam_pos_2d(), illum_mod(eim_partial_coherent), illum_inc(eii_temporal_spatial), em_sim_typ(eemst_ewrs), + operation_mode(eOM_Normal), slice_storage(false), reverse_multislice(false), + mul_sign(1), E_0(300), lambda(0), theta(0), phi(0), nrot(1), Vrl(c_vr_min), nR(c_nR), iw_type(eiwt_plane_wave), + is_xtl(false), islice(0), dp_Shift(false) {}; + + Multem_In_Parm(const Multem_In_Parm& multem_in_parm) + { + assign(multem_in_parm); + } + + template + void assign(TIn_Multislice &multem_in_parm) + { + system_config = multem_in_parm.system_config; + + elec_spec_interact_mod = multem_in_parm.elec_spec_interact_mod; + atomic_pot_parm_typ = multem_in_parm.atomic_pot_parm_typ; + + operation_mode = multem_in_parm.operation_mode; + slice_storage = multem_in_parm.slice_storage; + reverse_multislice = multem_in_parm.reverse_multislice; + mul_sign = multem_in_parm.mul_sign; + Vrl = multem_in_parm.Vrl; + nR = multem_in_parm.nR; + + atomic_vib = multem_in_parm.atomic_vib; + + atoms = multem_in_parm.atoms; + is_xtl = multem_in_parm.is_xtl; + + rot_in_parm = multem_in_parm.rot_in_parm; + + thick_type = multem_in_parm.thick_type; + thick = multem_in_parm.thick; + + spec_slic_typ = multem_in_parm.spec_slic_typ; + + grid_2d = multem_in_parm.grid_2d; + + em_sim_typ = multem_in_parm.em_sim_typ; + + iw_type = multem_in_parm.iw_type; + iw_psi = multem_in_parm.iw_psi; + + beam_pos_2d = multem_in_parm.beam_pos_2d; + + E_0 = multem_in_parm.E_0; + theta = multem_in_parm.theta; + phi = multem_in_parm.phi; + nrot = multem_in_parm.nrot; + + illum_mod = multem_in_parm.illum_mod; + illum_inc = multem_in_parm.illum_inc; + + cond_lens = multem_in_parm.cond_lens; + obj_lens = multem_in_parm.obj_lens; + + scanning = multem_in_parm.scanning; + detector = multem_in_parm.detector; + + eels_fr = multem_in_parm.eels_fr; + + cdl_var_type = multem_in_parm.cdl_var_type; + cdl_var = multem_in_parm.cdl_var; + + beam_pos = multem_in_parm.beam_pos; + + islice = multem_in_parm.islice; + dp_Shift = multem_in_parm.dp_Shift; + } + + template + Multem_In_Parm& operator=(const TIn_Multislice &multem_in_parm) + { + assign(multem_in_parm); + return *this; + } + + void set_dep_var() + { + atomic_vib.set_dep_var(); + + rot_in_parm.set_dep_var(); + + islice = max(0, islice); + + if (fcn_is_zero(Vrl)) + { + Vrl = c_vr_min; + } + + if (fcn_is_zero(nR)) + { + nR = c_nR; + } + + dp_Shift = (is_PED())?true:false; + + /************************ incident beam ****************************/ + if ((is_plane_wave()) || (is_scanning() && !scanning.is_scan_pat_user_def())) + { + beam_pos_2d.resize(1); + } + + beam_pos = beam_pos_2d; + + /************************** Scanning *******************************/ + if (is_scanning()) + { + if (scanning.is_scan_pat_user_def()) + { + scanning.R = beam_pos_2d.p; + } + } + else + { + scanning.set_default(); + } + + scanning.set_grid(); + + /***************************************************************************************/ + lambda = fcn_lambda(E_0); + + // multislice sign + mul_sign = (reverse_multislice)?-1:1; + + theta = set_incident_angle(theta); + nrot = max(1, nrot); + if (!is_PED_HCTEM()) + { + nrot = 1; + } + + if (is_EELS_EFTEM()) + { + atomic_vib.coh_contrib = false; + elec_spec_interact_mod = mt::eesim_multislice; + illum_mod = eim_coherent; + + auto coll_angle_max = fcn_rangs_2_rad(E_0, 2*grid_2d.g_max()); + auto coll_angle = (fcn_is_zero(eels_fr.coll_angle)||(eels_fr.coll_angle<0))?coll_angle_max:eels_fr.coll_angle; + eels_fr.set_coll_angle(coll_angle); + + if (is_EFTEMRS()) + { + obj_lens.inner_aper_ang = 0; + obj_lens.outer_aper_ang = eels_fr.coll_angle; + obj_lens.set_in_data(E_0, grid_2d); + } + } + + if (is_EWFS_EWRS()) + { + atomic_vib.coh_contrib = true; + illum_mod = eim_coherent; + } + + // It will be changed when you include spatial incoherences (beta) + if (is_CBED_CBEI() && !is_illu_mod_full_integration()) + { + illum_mod = eim_coherent; + } + + slice_storage = is_slice_storage(); + + if (!is_multislice()) + { + islice = 0; + spec_slic_typ = esst_plns_proj; + if (is_sim_through_slices()) + { + thick_type = estt_through_thick; + } + slice_storage = slice_storage || !is_sim_whole_spec(); + } + + if (is_spec_slic_by_dz_sub() && is_sim_through_thick()) + { + thick_type = estt_whole_spec; + } + + if (!is_spec_slic_by_dz_sub()) + { + atomic_vib.dim_z = false; + } + + if (is_spec_rot_active()) + { + thick_type = estt_whole_spec; + // get geometric center + if (rot_in_parm.is_geometric_center()) + { + rot_in_parm.center_p = R_3d(atoms.x_mean, atoms.y_mean, atoms.z_mean); + } + // rotate atoms + rotate_atoms(atoms, rot_in_parm.theta, rot_in_parm.u0, rot_in_parm.center_p); + // get statistic + atoms.get_statistic(); + // reset theta + rot_in_parm.theta = 0; + } + + // match slicing with the require thickness + Spec_Slic slicing; + slicing.match_thickness(spec_slic_typ, atoms, thick_type, thick); + + // remove atoms outside the thickness range + T ee_z = 0.1; + T z_e = thick.back() + ee_z; + + if (atoms.z_max > z_e) + { + T z_0 = atoms.z_min - ee_z; + remove_atoms_outside_z_range(atoms, z_0, z_e); + // get statistic + atoms.get_statistic(); + } + + /************* verify lenses parameters **************/ + + if (fcn_is_zero(cond_lens.spt_inc_sigma)) + { + illum_inc = eii_temporal; + } + + if (!is_illu_mod_full_integration()) + { + cond_lens.spt_inc_rad_npts = 1; + cond_lens.spt_inc_azm_npts = 1; + cond_lens.tp_inc_npts = 1; + + obj_lens.spt_inc_rad_npts = 1; + obj_lens.spt_inc_azm_npts = 1; + obj_lens.tp_inc_npts = 1; + } + + if (is_incoh_temporal()) + { + cond_lens.spt_inc_rad_npts = 1; + cond_lens.spt_inc_azm_npts = 1; + + obj_lens.spt_inc_rad_npts = 1; + obj_lens.spt_inc_azm_npts = 1; + } + else if (is_incoh_spatial()) + { + cond_lens.tp_inc_npts = 1; + obj_lens.tp_inc_npts = 1; + } + + // set condenser lens parameters + cond_lens.set_in_data(E_0, grid_2d); + if (atoms.empty()) + { + cond_lens.zero_def_plane = 0; + } + else + { + cond_lens.zero_def_plane = cond_lens.get_zero_def_plane(atoms.z_min, atoms.z_max); + } + + cond_lens.zero_def_typ = ezdt_user_def; + + // set objetive lens parameters + obj_lens.set_in_data(E_0, grid_2d); + + // validate output area + validate_output_area(); + } + + /***************************************************************************************/ + void set_reverse_multislice(dt_bool rm) + { + reverse_multislice = rm; + mul_sign = (reverse_multislice)?-1:1; + } + + /***************************************************************************************/ + inline + dt_int32 number_pn_conf() + { + return atomic_vib.number_conf(); + } + + dt_int32 number_of_beams() + { + return (is_scanning())?scanning.size():beam_pos.size(); + } + + dt_bool is_multi_beam() + { + return number_of_beams() > 1; + } + + Vctr, edev_cpu> extract_beam_pos(dt_int32 idx, dt_int32 n_idx) + { + dt_int32 n_beams_tot = number_of_beams(); + dt_int32 n_beams = (n_beams_tot+n_idx-1)/n_idx; + + dt_int32 ix_0 = idx*n_beams; + dt_int32 ix_e = min(ix_0+n_beams, n_beams_tot); + + auto it_0 = (is_scanning())?scanning.R.begin():beam_pos.p.begin(); + return Vctr, edev_cpu>(it_0+ix_0, it_0+ix_e); + } + + void validate_output_area() + { + if ((is_STEM() || is_STEM_EELS())) + { + if (scanning.is_scan_pat_user_def()) + { + output_area.ix_0 = 0; + output_area.ix_e = scanning.R.size(); + + output_area.iy_0 = 0; + output_area.iy_e = 1; + } + else + { + output_area.ix_0 = 0; + output_area.ix_e = scanning.nx; + + output_area.iy_0 = 0; + output_area.iy_e = scanning.ny; + } + } + else + { + if (output_area.ix_0==output_area.ix_e) + { + output_area.ix_0 = 0; + output_area.ix_e = grid_2d.nx; + } + + if (output_area.iy_0==output_area.iy_e) + { + output_area.iy_0 = 0; + output_area.iy_e = grid_2d.ny; + } + + output_area.set_ind_asc_order(); + output_area.apply_bound_ix(0, grid_2d.nx); + output_area.apply_bound_iy(0, grid_2d.ny); + } + + output_area.ind_0 = 0; + output_area.ind_e = output_area.size(); + } + + void set_iscan_beam_position() + { + // beam_pos_2d.resize(beam_pos_2d_i.size()); + // for(auto is = 0; is < beam_pos_2d_i.size(); is++) + // { + // auto idx = beam_pos_2d_i.idx[is]; + // beam_pos_2d[is] = R_2d(scanning.x[idx], scanning.y[idx]); + // } + } + + /***************************************************************************************/ + dt_bool is_spec_rot_active() const + { + return rot_in_parm.is_rot_active(); + } + + /***************************************************************************************/ + T Rx_exp_factor() + { + return 0; + // return grid_2d.factor_2pi_rx_ctr(beam_x); + } + + T Ry_exp_factor() + { + return 0; + // return grid_2d.factor_2pi_ry_ctr(beam_y); + } + + T set_incident_angle(const T& theta) const + { + T n = ::round(sin(theta)/(lambda*grid_2d.dg_min())); + return (fcn_is_zero(theta))?0:asin(n*lambda*grid_2d.dg_min()); + } + + T get_phonon_rot_weight() const + { + return 1.0/static_cast(number_pn_conf()*nrot); + } + + void set_phi(const dt_int32& irot) + { + phi = (irot == 0)?0.0:(c_2pi*static_cast(irot))/static_cast(nrot); + } + + inline + T get_propagator_factor(const T& z) const + { + return (-mul_sign*c_pi*lambda*z); + } + + T Vr_factor() const + { + return (mul_sign*fcn_transf_exp_factor(E_0, theta)); + } + + T gx_0() const + { + return sin(theta)*cos(phi)/lambda; + } + + T gy_0() const + { + return sin(theta)*sin(phi)/lambda; + } + + R_2d gu_0() const + { + return R_2d(gx_0(), gy_0()); + } + + void set_eels_fr_atom(const dt_int32& iatoms, const Ptc_Atom& atoms) + { + eels_fr.x = grid_2d.factor_2pi_rx_ctr(atoms.x[iatoms]); + eels_fr.y = grid_2d.factor_2pi_ry_ctr(atoms.y[iatoms]); + eels_fr.occ = atoms.occ[iatoms]; + } + + /***************************************************************************************/ + dt_bool is_multislice() const + { + return mt::is_multislice(elec_spec_interact_mod); + } + + dt_bool is_phase_object() const + { + return mt::is_phase_object(elec_spec_interact_mod); + } + + dt_bool is_weak_phase_object() const + { + return mt::is_weak_phase_object(elec_spec_interact_mod); + } + + /***************************************************************************************/ + + dt_bool is_avm_still_atom() const + { + return atomic_vib.is_avm_still_atom(); + } + + dt_bool is_avm_absorptive_pot() const + { + return atomic_vib.is_avm_absorptive_pot(); + } + + dt_bool is_avm_frozen_phonon() const + { + return atomic_vib.is_avm_frozen_phonon(); + } + + dt_bool is_avm_frozen_phonon_sgl_conf() const + { + return atomic_vib.is_avm_frozen_phonon_sgl_conf(); + } + + /***************************************************************************************/ + dt_bool is_sim_whole_spec() const + { + return mt::is_sim_whole_spec(thick_type); + } + + dt_bool is_sim_through_slices() const + { + return mt::is_sim_through_slices(thick_type); + } + + dt_bool is_sim_through_thick() const + { + return mt::is_sim_through_thick(thick_type); + } + + /***************************************************************************************/ + dt_bool is_spec_slic_by_plns_proj() const + { + return mt::is_spec_slic_by_plns_proj(elec_spec_interact_mod, spec_slic_typ); + } + + dt_bool is_spec_slic_by_dz_proj() const + { + return mt::is_spec_slic_by_dz_proj(elec_spec_interact_mod, spec_slic_typ); + } + + dt_bool is_spec_slic_by_dz_sub() const + { + return mt::is_spec_slic_by_dz_sub(elec_spec_interact_mod, spec_slic_typ); + } + + dt_bool is_spec_slic_by_dz_sub_whole_spec() const + { + return mt::is_spec_slic_by_dz_sub_whole_spec(elec_spec_interact_mod, spec_slic_typ, thick_type); + } + + /***************************************************************************************/ + dt_bool is_plane_wave() const + { + return mt::is_plane_wave(iw_type); + } + + dt_bool is_convergent_wave() const + { + return mt::is_convergent_wave(iw_type); + } + + dt_bool is_user_define_wave() const + { + return mt::is_user_define_wave(iw_type); + } + + /***************************************************************************************/ + dt_bool is_STEM() const + { + return mt::is_STEM(em_sim_typ); + } + + dt_bool is_ISTEM() const + { + return mt::is_ISTEM(em_sim_typ); + } + + dt_bool is_CBED() const + { + return mt::is_CBED(em_sim_typ); + } + + dt_bool is_CBEI() const + { + return mt::is_CBEI(em_sim_typ); + } + + dt_bool is_ED() const + { + return mt::is_ED(em_sim_typ); + } + + dt_bool is_HRTEM() const + { + return mt::is_HRTEM(em_sim_typ); + } + + dt_bool is_PED() const + { + return mt::is_PED(em_sim_typ); + } + + dt_bool is_HCTEM() const + { + return mt::is_HCTEM(em_sim_typ); + } + + dt_bool is_EWFS() const + { + return mt::is_EWFS(em_sim_typ); + } + + dt_bool is_EWRS() const + { + return mt::is_EWRS(em_sim_typ); + } + + dt_bool is_EWFS_SC() const + { + return mt::is_EWFS_SC(em_sim_typ, atomic_vib.model, atomic_vib.sgl_conf); + } + + dt_bool is_EWRS_SC() const + { + return mt::is_EWRS_SC(em_sim_typ, atomic_vib.model, atomic_vib.sgl_conf); + } + + dt_bool is_STEM_EELS() const + { + return mt::is_STEM_EELS(em_sim_typ); + } + + dt_bool is_ISTEM_EELS() const + { + return mt::is_ISTEM_EELS(em_sim_typ); + } + + dt_bool is_STEM_ISTEM_EELS() const + { + return mt::is_STEM_ISTEM_EELS(em_sim_typ); + } + + dt_bool is_EFTEMFS() const + { + return mt::is_EFTEMFS(em_sim_typ); + } + + dt_bool is_EFTEMRS() const + { + return mt::is_EFTEMRS(em_sim_typ); + } + + dt_bool is_EFTEM() const + { + return mt::is_EFTEM(em_sim_typ); + } + + dt_bool is_IWFS() const + { + return mt::is_IWFS(em_sim_typ); + } + + dt_bool is_IWRS() const + { + return mt::is_IWRS(em_sim_typ); + } + + dt_bool is_PPFS() const + { + return mt::is_PPFS(em_sim_typ); + } + + dt_bool is_PPRS() const + { + return mt::is_PPRS(em_sim_typ); + } + + dt_bool is_TFFS() const + { + return mt::is_TFFS(em_sim_typ); + } + + dt_bool is_TFRS() const + { + return mt::is_TFRS(em_sim_typ); + } + + dt_bool is_PropFS() const + { + return mt::is_PropFS(em_sim_typ); + } + + dt_bool is_PropRS() const + { + return mt::is_PropRS(em_sim_typ); + } + + dt_bool is_STEM_ISTEM() const + { + return mt::is_STEM_ISTEM(em_sim_typ); + } + + dt_bool is_CBED_CBEI() const + { + return mt::is_CBED_CBEI(em_sim_typ); + } + + dt_bool is_ED_HRTEM() const + { + return mt::is_ED_HRTEM(em_sim_typ); + } + + dt_bool is_PED_HCTEM() const + { + return mt::is_PED_HCTEM(em_sim_typ); + } + + dt_bool is_EWFS_EWRS() const + { + return mt::is_EWFS_EWRS(em_sim_typ); + } + + dt_bool is_EWFS_EWRS_SC() const + { + return mt::is_EWFS_EWRS_SC(em_sim_typ, atomic_vib.model, atomic_vib.sgl_conf); + } + + dt_bool is_EELS_EFTEM() const + { + return mt::is_EELS_EFTEM(em_sim_typ); + } + + dt_bool is_IWFS_IWRS() const + { + return mt::is_IWFS_IWRS(em_sim_typ); + } + + dt_bool is_PPFS_PPRS() const + { + return mt::is_PPFS_PPRS(em_sim_typ); + } + + dt_bool is_TFFS_TFRS() const + { + return mt::is_TFFS_TFRS(em_sim_typ); + } + + dt_bool is_PropFS_PropRS() const + { + return mt::is_PropFS_PropRS(em_sim_typ); + } + + dt_bool is_grid_FS() const + { + return mt::is_grid_FS(em_sim_typ); + } + + dt_bool is_grid_RS() const + { + return mt::is_grid_RS(em_sim_typ); + } + + dt_bool is_simulation_type_FS() const + { + return mt::is_simulation_type_FS(em_sim_typ); + } + + dt_bool is_simulation_type_RS() const + { + return mt::is_simulation_type_RS(em_sim_typ); + } + + dt_bool is_specimen_required() const + { + return mt::is_specimen_required(em_sim_typ); + } + + dt_bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS() const + { + return mt::is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS(em_sim_typ); + } + + dt_bool is_CBED_ED_EWFS_PED() const + { + return mt::is_CBED_ED_EWFS_PED(em_sim_typ); + } + + dt_bool is_obj_lens_temp_spat() const + { + return mt::is_obj_lens_temp_spat(em_sim_typ); + } + + dt_bool is_cond_lens_temp_spat() const + { + return mt::is_cond_lens_temp_spat(em_sim_typ); + } + + eSpace get_simulation_space() const + { + return mt::get_simulation_space(em_sim_typ); + } + + dt_bool is_scanning() const + { + return mt::is_scanning(em_sim_typ); + } + + /***************************************************************************************/ + void set_incident_wave_type(eIncident_Wave_Typ iw_type_i) + { + iw_type = mt::validate_incident_wave_type(em_sim_typ, iw_type_i); + } + + /***************************************************************************************/ + dt_bool is_illu_mod_coherent() const + { + return illum_mod == eim_coherent; + } + + dt_bool is_illu_mod_partial_coherent() const + { + return illum_mod == eim_partial_coherent; + } + + dt_bool is_illu_mod_trans_cross_coef() const + { + return illum_mod == eim_trans_cross_coef; + } + + dt_bool is_illu_mod_full_integration() const + { + return illum_mod == eim_full_integration; + } + + /***************************************************************************************/ + dt_bool is_incoh_temporal_spatial() const + { + return illum_inc == eii_temporal_spatial; + } + + dt_bool is_incoh_temporal() const + { + return illum_inc == eii_temporal; + } + + dt_bool is_incoh_spatial() const + { + return illum_inc == etst_spatial; + } + + /***************************************************************************************/ + dt_bool is_detector_circular() const + { + return detector.is_detector_circular(); + } + + dt_bool is_detector_radial() const + { + return detector.is_detector_radial(); + } + + dt_bool is_detector_matrix() const + { + return detector.is_detector_matrix(); + } + + /***************************************************************************************/ + dt_bool is_slice_storage() const + { + dt_bool slice_storage = is_PED_HCTEM() || is_EELS_EFTEM(); + slice_storage = slice_storage || is_ISTEM() || (is_STEM() && !atomic_vib.coh_contrib); + slice_storage = slice_storage || (is_CBED_CBEI() && is_illu_mod_full_integration()); + + return slice_storage; + } + + dt_bool is_operation_mode_normal() const + { + return operation_mode == eOM_Normal; + } + + dt_bool is_operation_mode_advanced() const + { + return operation_mode == eOM_Advanced; + } + + /***************************************************************************************/ + dt_bool is_lvt_off() const + { + return cdl_var == eLVT_off; + } + + dt_bool is_lvt_m() const + { + return cdl_var == eLVT_m; + } + + dt_bool is_lvt_Cs3() const + { + return cdl_var == eLVT_Cs3; + } + + dt_bool is_lvt_Cs5() const + { + return cdl_var == eLVT_Cs5; + } + + dt_bool is_lvt_mfa2() const + { + return cdl_var == eLVT_mfa2; + } + + dt_bool is_lvt_afa2() const + { + return cdl_var == eLVT_afa2; + } + + dt_bool is_lvt_mfa3() const + { + return cdl_var == eLVT_mfa3; + } + + dt_bool is_lvt_afa3() const + { + return cdl_var == eLVT_afa3; + } + + dt_bool is_lvt_inner_aper_ang() const + { + return cdl_var == eLVT_inner_aper_ang; + } + + dt_bool is_lvt_outer_aper_ang() const + { + return cdl_var == eLVT_outer_aper_ang; + } + + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/mx_2x2.cuh b/src - Copy (2)/mx_2x2.cuh new file mode 100755 index 00000000..34ef9c87 --- /dev/null +++ b/src - Copy (2)/mx_2x2.cuh @@ -0,0 +1,523 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MX_2x2_H + #define MX_2x2_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + #include "r_2d.cuh" + + namespace mt + { + /***************************************************************************************/ + /******************************* forward declarations **********************************/ + /***************************************************************************************/ + template + class Mx_2x2; + + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_2x2& mx); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_2x2& mx); + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_2x2& mx); + + template + CGPU_EXEC + T fmin(const Mx_2x2& mx); + + template + CGPU_EXEC + T fmax(const Mx_2x2& mx); + + template + CGPU_EXEC + T det(const Mx_2x2& mx); + + template + CGPU_EXEC + Mx_2x2 inv(const Mx_2x2& mx); + + /***************************************************************************************/ + /******************************* 2x2 matrix *****************************/ + /***************************************************************************************/ + + template + class Mx_2x2 + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + Mx_2x2(): m_data{0, 0, 0, 0} {} + + // ! constructor + CGPU_EXEC + Mx_2x2(const T& c_11, const T& c_21, const T& c_12, const T& c_22) + { + m_data[0] = c_11; + m_data[1] = c_21; + m_data[2] = c_12; + m_data[3] = c_22; + } + + /* converting constructor */ + template + CGPU_EXEC + Mx_2x2(const U& c_11, const U& c_21, const U& c_12, const U& c_22) + { + m_data[0] = T(c_11); + m_data[1] = T(c_21); + m_data[2] = T(c_12); + m_data[3] = T(c_22); + } + + /* Copy constructor */ + CGPU_EXEC + Mx_2x2(const Mx_2x2& mx) + { + *this = mx; + } + + /* Move constructor */ + template + CGPU_EXEC + Mx_2x2(Mx_2x2&& mx) + { + *this = std::move(mx); + } + + /* converting copy constructor */ + template + CGPU_EXEC + Mx_2x2(const Mx_2x2& mx) + { + *this = mx; + } + + template > + CGPU_EXEC + Mx_2x2(U* v) + { + m_data[0] = T(v[0]); + m_data[1] = T(v[1]); + m_data[2] = T(v[2]); + m_data[3] = T(v[3]); + } + + /******************************** assignment operators *********************************/ + + /* copy assignment operator */ + CGPU_EXEC + Mx_2x2& operator=(const Mx_2x2& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + } + + return *this; + } + + /* Move assignment operator */ + CGPU_EXEC + Mx_2x2& operator=(Mx_2x2&& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Mx_2x2& operator=(const Mx_2x2& mx) + { + m_data[0] = T(mx.m_data[0]); + m_data[1] = T(mx.m_data[1]); + m_data[2] = T(mx.m_data[2]); + m_data[3] = T(mx.m_data[3]); + + return *this; + } + + /******************* Compound assignment operators *******************/ + template + CGPU_EXEC + Mx_2x2& operator+=(const Mx_2x2& mx) + { + *this = *this + mx; + + return *this; + } + + template + CGPU_EXEC + Mx_2x2& operator+=(const U& mx) + { + *this = *this + mx; + + return *this; + } + + template + CGPU_EXEC + Mx_2x2& operator-=(const Mx_2x2& mx) + { + *this = *this - mx; + + return *this; + } + + template + CGPU_EXEC + Mx_2x2& operator-=(const U& mx) + { + *this = *this - mx; + + return *this; + } + + template + CGPU_EXEC + Mx_2x2& operator*=(const Mx_2x2& mx) + { + *this = *this*mx; + + return *this; + } + + template + CGPU_EXEC + Mx_2x2& operator*=(const U& mx) + { + *this = *this*mx; + + return *this; + } + + template + CGPU_EXEC + Mx_2x2& operator/=(const Mx_2x2& mx) + { + *this = *this/mx; + + return *this; + } + + template + CGPU_EXEC + Mx_2x2& operator/=(const U& mx) + { + *this = *this/mx; + + return *this; + } + + /************************** Other operators **************************/ + dt_int32 size() const + { + return 4; + } + + CGPU_EXEC_INL + T& operator[](const dt_int32 idx) { return m_data[idx]; } + + CGPU_EXEC_INL + const T& operator[](const dt_int32 idx) const { return m_data[idx]; } + + CGPU_EXEC_INL + T& operator()(const dt_int32 ir, const dt_int32 ic) { return m_data[ir - 1 + 2*(ic - 1)]; } + + CGPU_EXEC_INL + const T& operator()(const dt_int32 ir, const dt_int32 ic) const { return m_data[ir - 1 + 2*(ic - 1)]; } + + + CGPU_EXEC + dt_bool fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + CGPU_EXEC + dt_bool is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + CGPU_EXEC + dt_bool is_id_mx() const + { + return mt::is_id_mx(*this); + } + + CGPU_EXEC + T min() const + { + return mt::fmin(*this); + } + + CGPU_EXEC + T max() const + { + return mt::fmax(*this); + } + + CGPU_EXEC + T det() const + { + return mt::det(*this); + } + + CGPU_EXEC + Mx_2x2 inv() const + { + return mt::inv(*this); + } + + private: + T m_data[4]; + }; + + /******************** Unitary arithmetic operators ********************/ + template + CGPU_EXEC + Mx_2x2 operator-(const Mx_2x2& mx) + { + return {-mx[0], -mx[1], -mx[2], -mx[3]}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_2x2& mx) + { + return fcn_is_zero(mx[0], mx[1], mx[2], mx[3]); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_2x2& mx) + { + return fcn_is_nzero(mx[0], mx[1], mx[2], mx[3]); + } + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_2x2& mx) + { + return fcn_is_one(mx[0], mx[3]) && fcn_is_zero(mx[1], mx[2]); + } + + template + CGPU_EXEC + T fmin(const Mx_2x2& mx) + { + return ::fmin(mx[0], ::fmin(mx[1], ::fmin(mx[2], mx[3]))); + } + + template + CGPU_EXEC + T fmax(const Mx_2x2& mx) + { + return ::fmax(mx[0], ::fmax(mx[1], ::fmax(mx[2], mx[3]))); + } + + template + CGPU_EXEC + T det(const Mx_2x2& mx) + { + return mx(1, 1)*mx(2, 2) - mx(1, 2)*mx(2, 1); + } + + template + CGPU_EXEC + Mx_2x2 inv(const Mx_2x2& mx) + { + Mx_2x2 mx_inv{mx(2, 2), -mx(2, 1), -mx(1, 2), mx(1, 1)}; + + return mx_inv/det(mx); + } + + /************************ arithmetic operators ***********************/ + template > + CGPU_EXEC + Mx_2x2 operator+(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator+(const Mx_2x2& lhs, const U& rhs) + { + return {lhs[0] + rhs, lhs[1] + rhs, lhs[2] + rhs, lhs[3] + rhs}; + } + + template > + CGPU_EXEC + Mx_2x2 operator+(const T& lhs, const Mx_2x2& rhs) + { + return {lhs + rhs[0], lhs + rhs[1], lhs + rhs[2], lhs + rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator-(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator-(const Mx_2x2& lhs, const U& rhs) + { + return {lhs[0] - rhs, lhs[1] - rhs, lhs[2] - rhs, lhs[3] -rhs}; + } + + template > + CGPU_EXEC + Mx_2x2 operator-(const T& lhs, const Mx_2x2& rhs) + { + return {lhs - rhs[0], lhs - rhs[1], lhs - rhs[2], lhs - rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator*(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + Mx_2x2 mx; + + mx[0] = lhs[0]*rhs[0] + lhs[2]*rhs[1]; + mx[1] = lhs[1]*rhs[0] + lhs[3]*rhs[1]; + + mx[2] = lhs[0]*rhs[2] + lhs[2]*rhs[3]; + mx[3] = lhs[1]*rhs[2] + lhs[3]*rhs[3]; + + return mx; + } + + template > + CGPU_EXEC + Mx_2x2 operator*(const Mx_2x2& lhs, const U& rhs) + { + return {lhs[0]*rhs, lhs[1]*rhs, lhs[2]*rhs, lhs[3]*rhs}; + } + + template > + CGPU_EXEC + Mx_2x2 operator*(const T& lhs, const Mx_2x2& rhs) + { + return {lhs*rhs[0], lhs*rhs[1], lhs*rhs[2], lhs*rhs[3]}; + } + + template > + CGPU_EXEC + R_2d operator*(const Mx_2x2& lhs, const R_2d& rhs) + { + return {lhs[0]*rhs.x + lhs[2]*rhs.y, lhs[1]*rhs.x + lhs[3]*rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator*(const R_2d& lhs, const Mx_2x2& rhs) + { + return {lhs.x*rhs[0] + lhs.y*rhs[1], lhs.x*rhs[2] + lhs.y*rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator/(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return lhs*inv(rhs); + } + + template > + CGPU_EXEC + Mx_2x2 operator/(const Mx_2x2& lhs, const U& rhs) + { + return {fcn_div(lhs[0], rhs), fcn_div(lhs[1], rhs), fcn_div(lhs[2], rhs), fcn_div(lhs[3], rhs)}; + } + + template > + CGPU_EXEC + Mx_2x2 operator/(const T& lhs, const Mx_2x2& rhs) + { + return {fcn_div(lhs, rhs[0]), fcn_div(lhs, rhs[1]), fcn_div(lhs, rhs[2]), fcn_div(lhs, rhs[3])}; + } + + template > + CGPU_EXEC + Mx_2x2 fmin(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {::fmin(lhs[0], rhs[0]), ::fmin(lhs[1], rhs[1]), ::fmin(lhs[2], rhs[2]), ::fmin(lhs[3], rhs[3])}; + } + + template > + CGPU_EXEC + Mx_2x2 fmax(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {::fmax(lhs[0], rhs[0]), ::fmax(lhs[1], rhs[1]), ::fmax(lhs[2], rhs[2]), ::fmax(lhs[3], rhs[3])}; + } + + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_mx_2x2_f64 = std::initializer_list>; + + /************************** other operators **************************/ + template + CGPU_EXEC + Mx_2x2 fcn_rot_mx_2d(const T& theta) + { + T cos_theta, sin_theta; + sincos(theta, &sin_theta, &cos_theta); + + return {cos_theta, sin_theta, -sin_theta, cos_theta}; + } + + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/mx_3x3.cuh b/src - Copy (2)/mx_3x3.cuh new file mode 100755 index 00000000..c6ac1279 --- /dev/null +++ b/src - Copy (2)/mx_3x3.cuh @@ -0,0 +1,611 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MX_3x3_H + #define MX_3x3_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "r_3d.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + namespace mt + { + /***************************************************************************************/ + /******************************* forward declarations **********************************/ + /***************************************************************************************/ + template + class Mx_3x3; + + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_3x3& mx); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_3x3& mx); + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_3x3& mx); + + template + CGPU_EXEC + T fmin(const Mx_3x3& mx); + + template + CGPU_EXEC + T fmax(const Mx_3x3& mx); + + template + CGPU_EXEC + T det(const Mx_3x3& mx); + + template + CGPU_EXEC + Mx_3x3 inv(const Mx_3x3& mx); + + /***************************************************************************************/ + /******************************* 3x3 matrix *****************************/ + /***************************************************************************************/ + + template + class Mx_3x3 + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + Mx_3x3(): m_data{T(), T(), T(), T(), T(), T(), T(), T(), T()} {} + + // ! constructor + CGPU_EXEC + Mx_3x3(const T& c_11, const T& c_21, const T& c_31, const T& c_12, + const T& c_22, const T& c_32, const T& c_13, const T& c_23, const T& c_33) + { + m_data[0] = c_11; + m_data[1] = c_21; + m_data[2] = c_31; + m_data[3] = c_12; + m_data[4] = c_22; + m_data[5] = c_32; + m_data[6] = c_13; + m_data[7] = c_23; + m_data[8] = c_33; + } + + /* converting constructor */ + template + CGPU_EXEC + Mx_3x3(const U& c_11, const U& c_21, const U& c_31, const U& c_12, + const U& c_22, const U& c_32, const U& c_13, const U& c_23, const U& c_33) + { + m_data[0] = T(c_11); + m_data[1] = T(c_21); + m_data[2] = T(c_31); + m_data[3] = T(c_12); + m_data[4] = T(c_22); + m_data[5] = T(c_32); + m_data[6] = T(c_13); + m_data[7] = T(c_23); + m_data[8] = T(c_33); + } + + ///* converting constructor */ + //template + //CGPU_EXEC + //Mx_3x3(dt_init_list& list) + //{ + // m_data[0] = T(ptr[0]); + // m_data[1] = T(ptr[1]); + // m_data[2] = T(ptr[2]); + // m_data[3] = T(ptr[3]); + // m_data[4] = T(ptr[4]); + // m_data[5] = T(ptr[5]); + // m_data[6] = T(ptr[6]); + // m_data[7] = T(ptr[7]); + // m_data[8] = T(ptr[8]); + //} + + /* Copy constructor */ + CGPU_EXEC + Mx_3x3(const Mx_3x3& mx) + { + *this = mx; + } + + /* Move constructor */ + template + CGPU_EXEC + Mx_3x3(Mx_3x3&& mx) + { + *this = std::move(mx); + } + + /* converting copy constructor */ + template + CGPU_EXEC + Mx_3x3(const Mx_3x3& mx) + { + *this = mx; + } + + template > + CGPU_EXEC + Mx_3x3(U* v) + { + m_data[0] = T(v[0]); + m_data[1] = T(v[1]); + m_data[2] = T(v[2]); + m_data[3] = T(v[3]); + m_data[4] = T(v[4]); + m_data[5] = T(v[5]); + m_data[6] = T(v[6]); + m_data[7] = T(v[7]); + m_data[8] = T(v[8]); + } + + /******************************** assignment operators *********************************/ + + /* copy assignment operator */ + CGPU_EXEC + Mx_3x3& operator=(const Mx_3x3& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + m_data[4] = mx.m_data[4]; + m_data[5] = mx.m_data[5]; + m_data[6] = mx.m_data[6]; + m_data[7] = mx.m_data[7]; + m_data[8] = mx.m_data[8]; + } + + return *this; + } + + /* Move assignment operator */ + CGPU_EXEC + Mx_3x3& operator=(Mx_3x3&& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + m_data[4] = mx.m_data[4]; + m_data[5] = mx.m_data[5]; + m_data[6] = mx.m_data[6]; + m_data[7] = mx.m_data[7]; + m_data[8] = mx.m_data[8]; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Mx_3x3& operator=(const Mx_3x3& mx) + { + m_data[0] = T(mx.m_data[0]); + m_data[1] = T(mx.m_data[1]); + m_data[2] = T(mx.m_data[2]); + m_data[3] = T(mx.m_data[3]); + m_data[4] = T(mx.m_data[4]); + m_data[5] = T(mx.m_data[5]); + m_data[6] = T(mx.m_data[6]); + m_data[7] = T(mx.m_data[7]); + m_data[8] = T(mx.m_data[8]); + + return *this; + } + + /******************* Compound assignment operators *******************/ + template + CGPU_EXEC + Mx_3x3& operator+=(const Mx_3x3& mx) + { + *this = *this + mx; + + return *this; + } + + template + CGPU_EXEC + Mx_3x3& operator+=(const U& mx) + { + *this = *this + mx; + + return *this; + } + + template + CGPU_EXEC + Mx_3x3& operator-=(const Mx_3x3& mx) + { + *this = *this - mx; + + return *this; + } + + template + CGPU_EXEC + Mx_3x3& operator-=(const U& mx) + { + *this = *this - mx; + + return *this; + } + + template + CGPU_EXEC + Mx_3x3& operator*=(const Mx_3x3& mx) + { + *this = *this*mx; + + return *this; + } + + template + CGPU_EXEC + Mx_3x3& operator*=(const U& mx) + { + *this = *this*mx; + + return *this; + } + + template + CGPU_EXEC + Mx_3x3& operator/=(const Mx_3x3& mx) + { + *this = *this/mx; + + return *this; + } + + template + CGPU_EXEC + Mx_3x3& operator/=(const U& mx) + { + *this = *this/mx; + + return *this; + } + + /************************** Other operators **************************/ + dt_int32 size() const + { + return 9; + } + + CGPU_EXEC_INL + T& operator[](const dt_int32 idx) { return m_data[idx]; } + + CGPU_EXEC_INL + const T& operator[](const dt_int32 idx) const { return m_data[idx]; } + + CGPU_EXEC_INL + T& operator()(const dt_int32 ir, const dt_int32 ic) { return m_data[ir - 1 + 3*(ic - 1)]; } + + CGPU_EXEC_INL + const T& operator()(const dt_int32 ir, const dt_int32 ic) const { return m_data[ir - 1 + 3*(ic - 1)]; } + + + CGPU_EXEC + dt_bool fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + CGPU_EXEC + dt_bool is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + CGPU_EXEC + dt_bool is_id_mx() const + { + return mt::is_id_mx(*this); + } + + CGPU_EXEC + T min() const + { + return mt::fmin(*this); + } + + CGPU_EXEC + T max() const + { + return mt::fmax(*this); + } + + CGPU_EXEC + T det() const + { + return mt::det(*this); + } + + CGPU_EXEC + Mx_3x3 inv() const + { + return mt::inv(*this); + } + + private: + T m_data[9]; + }; + + /******************** Unitary arithmetic operators ********************/ + template + CGPU_EXEC + Mx_3x3 operator-(const Mx_3x3& mx) + { + return {-mx[0], -mx[1], -mx[2], -mx[3], -mx[4], -mx[5], -mx[6], -mx[7], -mx[8]}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_3x3& mx) + { + return fcn_is_zero(mx[0], mx[1], mx[2], mx[3], mx[4], mx[5], mx[6], mx[7], mx[8]); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_3x3& mx) + { + return fcn_is_nzero(mx[0], mx[1], mx[2], mx[3], mx[4], mx[5], mx[6], mx[7], mx[8]); + } + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_3x3& mx) + { + return fcn_is_one(mx[0], mx[4], mx[8]) && fcn_is_zero(mx[1], mx[2], mx[3], mx[5], mx[6], mx[7]); + } + + template + CGPU_EXEC + T fmin(const Mx_3x3& mx) + { + return ::fmin(mx[0], ::fmin(mx[1], ::fmin(mx[2], ::fmin(mx[3], ::fmin(mx[4], ::fmin(mx[5], ::fmin(mx[6], ::fmin(mx[7], mx[8])))))))); + } + + template + CGPU_EXEC + T fmax(const Mx_3x3& mx) + { + return ::fmax(mx[0], ::fmax(mx[1], ::fmax(mx[2], ::fmax(mx[3], ::fmax(mx[4], ::fmax(mx[5], ::fmax(mx[6], ::fmax(mx[7], mx[8])))))))); + } + + template + CGPU_EXEC + T det(const Mx_3x3& mx) + { + T val = mx(1, 1)*mx(2, 2)*mx(3, 3) + mx(1, 2)*mx(2, 3)*mx(3, 1) + mx(1, 3)*mx(2, 1)*mx(3, 2); + val -= mx(1, 3)*mx(2, 2)*mx(3, 1) + mx(1, 2)*mx(2, 1)*mx(3, 3) + mx(1, 1)*mx(2, 3)*mx(3, 2); + + return val; + } + + template + CGPU_EXEC + Mx_3x3 inv(const Mx_3x3& mx) + { + Mx_3x3 mx_inv; + + mx_inv(1, 1) = mx(2, 2)*mx(3, 3) - mx(2, 3)*mx(3, 2); + mx_inv(2, 1) = mx(2, 3)*mx(3, 1) - mx(2, 1)*mx(3, 3); + mx_inv(3, 1) = mx(2, 1)*mx(3, 2) - mx(2, 2)*mx(3, 1); + + mx_inv(1, 2) = mx(1, 3)*mx(3, 2) - mx(1, 2)*mx(3, 3); + mx_inv(2, 2) = mx(1, 1)*mx(3, 3) - mx(1, 3)*mx(3, 1); + mx_inv(3, 2) = mx(1, 2)*mx(3, 1) - mx(1, 1)*mx(3, 2); + + mx_inv(1, 3) = mx(1, 2)*mx(2, 3) - mx(1, 3)*mx(2, 2); + mx_inv(3, 3) = mx(1, 1)*mx(2, 2) - mx(1, 2)*mx(2, 1); + mx_inv(2, 3) = mx(1, 3)*mx(2, 1) - mx(1, 1)*mx(2, 3); + + return mx_inv/det(mx); + } + + /************************ arithmetic operators ***********************/ + template > + CGPU_EXEC + Mx_3x3 operator+(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3], + lhs[4] + rhs[4], lhs[5] + rhs[5], lhs[6] + rhs[6], lhs[7] + rhs[7], lhs[8] + rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator+(const Mx_3x3& lhs, const U& rhs) + { + return {lhs[0] + rhs, lhs[1] + rhs, lhs[2] + rhs, lhs[3] + rhs, + lhs[4] + rhs, lhs[5] + rhs, lhs[6] + rhs, lhs[7] + rhs, lhs[8] + rhs}; + } + + template > + CGPU_EXEC + Mx_3x3 operator+(const T& lhs, const Mx_3x3& rhs) + { + return {lhs + rhs[0], lhs + rhs[1], lhs + rhs[2], lhs + rhs[3], + lhs + rhs[4], lhs + rhs[5], lhs + rhs[6], lhs + rhs[7], lhs + rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator-(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3], + lhs[4] - rhs[4], lhs[5] - rhs[5], lhs[6] - rhs[6], lhs[7] - rhs[7], lhs[8] - rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator-(const Mx_3x3& lhs, const U& rhs) + { + return {lhs[0] - rhs, lhs[1] - rhs, lhs[2] - rhs, lhs[3] - rhs, + lhs[4] - rhs, lhs[5] - rhs, lhs[6] - rhs, lhs[7] - rhs, lhs[8] - rhs}; + } + + template > + CGPU_EXEC + Mx_3x3 operator-(const T& lhs, const Mx_3x3& rhs) + { + return {lhs - rhs[0], lhs - rhs[1], lhs - rhs[2], lhs - rhs[3], + lhs - rhs[4], lhs - rhs[5], lhs - rhs[6], lhs - rhs[7], lhs - rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator*(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + Mx_3x3 mx; + + mx[0] = lhs[0]*rhs[0] + lhs[3]*rhs[1] + lhs[6]*rhs[2]; + mx[1] = lhs[1]*rhs[0] + lhs[4]*rhs[1] + lhs[7]*rhs[2]; + mx[2] = lhs[2]*rhs[0] + lhs[5]*rhs[1] + lhs[8]*rhs[2]; + + mx[3] = lhs[0]*rhs[3] + lhs[3]*rhs[4] + lhs[6]*rhs[5]; + mx[4] = lhs[1]*rhs[3] + lhs[4]*rhs[4] + lhs[7]*rhs[5]; + mx[5] = lhs[2]*rhs[3] + lhs[5]*rhs[4] + lhs[8]*rhs[5]; + + mx[6] = lhs[0]*rhs[6] + lhs[3]*rhs[7] + lhs[6]*rhs[8]; + mx[7] = lhs[1]*rhs[6] + lhs[4]*rhs[7] + lhs[7]*rhs[8]; + mx[8] = lhs[2]*rhs[6] + lhs[5]*rhs[7] + lhs[8]*rhs[8]; + + return mx; + } + + template > + CGPU_EXEC + Mx_3x3 operator*(const Mx_3x3& lhs, const U& rhs) + { + return {lhs[0]*rhs, lhs[1]*rhs, lhs[2]*rhs, lhs[3]*rhs, + lhs[4]*rhs, lhs[5]*rhs, lhs[6]*rhs, lhs[7]*rhs, lhs[8]*rhs}; + } + + template > + CGPU_EXEC + Mx_3x3 operator*(const T& lhs, const Mx_3x3& rhs) + { + return {lhs*rhs[0], lhs*rhs[1], lhs*rhs[2], lhs*rhs[3], + lhs*rhs[4], lhs*rhs[5], lhs*rhs[6], lhs*rhs[7], lhs*rhs[8]}; + } + + template > + CGPU_EXEC + R_3d operator*(const Mx_3x3& lhs, const R_3d& rhs) + { + return {lhs[0]*rhs.x + lhs[3]*rhs.y + lhs[6]*rhs.z, + lhs[1]*rhs.x + lhs[4]*rhs.y + lhs[7]*rhs.z, + lhs[2]*rhs.x + lhs[5]*rhs.y + lhs[8]*rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator*(const R_3d& lhs, const Mx_3x3& rhs) + { + return {lhs.x*rhs[0] + lhs.y*rhs[1] + lhs.z*rhs[2], + lhs.x*rhs[3] + lhs.y*rhs[4] + lhs.z*rhs[5], + lhs.x*rhs[6] + lhs.y*rhs[7] + lhs.z*rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator/(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return lhs*inv(rhs); + } + + template > + CGPU_EXEC + Mx_3x3 operator/(const Mx_3x3& lhs, const U& rhs) + { + return {fcn_div(lhs[0], rhs), fcn_div(lhs[1], rhs), fcn_div(lhs[2], rhs), fcn_div(lhs[3], rhs), + fcn_div(lhs[4], rhs), fcn_div(lhs[5], rhs), fcn_div(lhs[6], rhs), fcn_div(lhs[7], rhs), fcn_div(lhs[8], rhs)}; + } + + template > + CGPU_EXEC + Mx_3x3 operator/(const T& lhs, const Mx_3x3& rhs) + { + return {fcn_div(lhs, rhs[0]), fcn_div(lhs, rhs[1]), fcn_div(lhs, rhs[2]), fcn_div(lhs, rhs[3]), + fcn_div(lhs, rhs[4]), fcn_div(lhs, rhs[5]), fcn_div(lhs, rhs[6]), fcn_div(lhs, rhs[7]), fcn_div(lhs, rhs[8])}; + } + + template > + CGPU_EXEC + Mx_3x3 fmin(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {::fmin(lhs[0], rhs[0]), ::fmin(lhs[1], rhs[1]), ::fmin(lhs[2], rhs[2]), ::fmin(lhs[3], rhs[3]), + ::fmin(lhs[4], rhs[4]), ::fmin(lhs[5], rhs[5]), ::fmin(lhs[6], rhs[6]), ::fmin(lhs[7], rhs[7]), ::fmin(lhs[8], rhs[8])}; + } + + template > + CGPU_EXEC + Mx_3x3 fmax(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {::fmax(lhs[0], rhs[0]), ::fmax(lhs[1], rhs[1]), ::fmax(lhs[2], rhs[2]), ::fmax(lhs[3], rhs[3]), + ::fmax(lhs[4], rhs[4]), ::fmax(lhs[5], rhs[5]), ::fmax(lhs[6], rhs[6]), ::fmax(lhs[7], rhs[7]), ::fmax(lhs[8], rhs[8])}; + } + + + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_mx_3x3_f64 = std::initializer_list>; + + /************************** other operators **************************/ + template + CGPU_EXEC + Mx_3x3 fcn_rot_mx_3d(const T& theta, const R_3d& u0) + { + T alpha = T(1)-cos(theta); + alpha = fcn_is_zero(alpha)?0:alpha; + T beta = sin(theta); + beta = fcn_is_zero(beta)?0:beta; + + return {T(1) + alpha*(u0.x*u0.x-T(1)), u0.y*u0.x*alpha + u0.z*beta, u0.z*u0.x*alpha - u0.y*beta, + u0.x*u0.y*alpha - u0.z*beta, T(1) + alpha*(u0.y*u0.y-1), u0.z*u0.y*alpha + u0.x*beta, + u0.x*u0.z*alpha + u0.y*beta, u0.y*u0.z*alpha - u0.x*beta, T(1) + alpha*(u0.z*u0.z-1)}; + } + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/output_multem.hpp b/src - Copy (2)/output_multem.hpp new file mode 100755 index 00000000..a1aa9bed --- /dev/null +++ b/src - Copy (2)/output_multem.hpp @@ -0,0 +1,1033 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef OUTPUT_MULTEM_H +#define OUTPUT_MULTEM_H + +#include +#include + +#include "math.cuh" +#include "types.cuh" +#include "type_traits_gen.cuh" +#include "cgpu_stream.cuh" +#include "particles.cuh" +#include "in_classes.cuh" +#include "cpu_fcns.hpp" +#include "gpu_fcns.cuh" + +namespace mt +{ + inline + dt_bool is_ot_image_tot_coh(const eEM_Output_Typ &output_type) + { + return output_type == eemot_image_tot_coh; + } + + inline + dt_bool is_ot_image_tot(const eEM_Output_Typ &output_type) + { + return output_type == eemot_image_tot; + } + + inline + dt_bool is_ot_m2psi_tot_coh(const eEM_Output_Typ &output_type) + { + return output_type == eemot_m2psi_tot_coh; + } + + inline + dt_bool is_ot_m2psi_tot(const eEM_Output_Typ &output_type) + { + return output_type == eemot_m2psi_tot; + } + + inline + dt_bool is_ot_m2psi_tot_psi_coh(const eEM_Output_Typ &output_type) + { + return output_type == eemot_m2psi_tot_psi_coh; + } + + inline + dt_bool is_ot_psi_coh(const eEM_Output_Typ &output_type) + { + return output_type == eemot_psi_coh; + } + + inline + dt_bool is_ot_psi_0(const eEM_Output_Typ &output_type) + { + return output_type == eemot_psi_0; + } + + inline + dt_bool is_ot_V(const eEM_Output_Typ &output_type) + { + return output_type == eemot_V; + } + + inline + dt_bool is_ot_trans(const eEM_Output_Typ &output_type) + { + return output_type == eemot_trans; + } + + /***************************************************************************************/ + template + class Output_Multem:public Multem_In_Parm + { + public: + using T_r = T; + using T_c = complex; + + using TVctr_hr = host_vector; + using TVctr_hc = host_vector>; + + using TVctr_dr = device_vector; + using TVctr_dc = device_vector>; + + Output_Multem(): Multem_In_Parm(), output_type(eemot_m2psi_tot), + ndetector(0), nx(0), ny(0), dx(0), dy(0), dr(0), n_thk(0), n_thk_d(0), bb_only_cpu_mem(false) {} + + Output_Multem(Multem_In_Parm *multem_in_parm, dt_bool bb_only_cpu_mem_i=false) + { + set_in_data(multem_in_parm, bb_only_cpu_mem_i); + } + + Output_Multem(const Output_Multem& output_multem) + { + assign(output_multem); + } + + template + void assign(TOutput_Multem &output_multem) + { + assign_multem_in_parm(output_multem); + + output_type = output_multem.output_type; + ndetector = output_multem.ndetector; + nx = output_multem.nx; + ny = output_multem.ny; + dx = output_multem.dx; + dy = output_multem.dy; + dr = output_multem.dr; + + x = output_multem.x; + y = output_multem.y; + r = output_multem.r; + + n_thk = output_multem.n_thk; + + bb_only_cpu_mem = output_multem.bb_only_cpu_mem; + + image_tot = output_multem.image_tot; + + image_coh = output_multem.image_coh; + + m2psi_tot = output_multem.m2psi_tot; + + m2psi_coh = output_multem.m2psi_coh; + + psi_coh = output_multem.psi_coh; + + V = output_multem.V; + + trans = output_multem.trans; + + psi_0 = output_multem.psi_0; + } + + template + Output_Multem& operator=(const TOutput_Multem &output_multem) + { + assign(output_multem); + return *this; + } + + template + void set_in_data(TIn_Multislice *multem_in_parm, dt_bool bb_only_cpu_mem_i=false) + { + clear(); + + bb_only_cpu_mem = bb_only_cpu_mem_i; + stream.resize(1); + + assign_multem_in_parm(*multem_in_parm); + + // set required number of thickness + n_thk = this->thick.size(); + + // check selected device + auto bb_is_device = this->system_config.is_gpu() && !bb_only_cpu_mem; + + // get available gpu free memory + dt_float64 free_gpu_memory_mb = (bb_is_device)?fcn_free_mem()-10:0; + + dt_int32 nxy_out = this->output_area.size_s(); + dt_int32 nxy_grid = this->grid_2d.size(); + + if (this->system_config.is_gpu()) + { + psi_zh.resize(nxy_grid); + m2psi_zh.resize(nxy_grid); + } + + ndetector = (this->is_STEM_ISTEM_EELS())?1:this->detector.size(); + dt_int32 n_beams = this->number_of_beams(); + + set_output_grid(); + + set_output_type(); + + auto n_vgpu_a_tr = [&](dt_int32 n_vgpu, dt_int32 nxy)->dt_int32 + { + dt_int32 n_vgpu_a = (bb_is_device)?dt_int32(::floor(free_gpu_memory_mb/mt::fcn_size_mb(nxy))):0; + return min(n_vgpu_a, n_vgpu); + }; + + auto n_vgpu_a_tc = [&](dt_int32 n_vgpu, dt_int32 nxy)->dt_int32 + { + dt_int32 n_vgpu_a = (bb_is_device)?dt_int32(::floor(free_gpu_memory_mb/mt::fcn_size_mb(nxy))):0; + return min(n_vgpu_a, n_vgpu); + }; + + switch (output_type) + { + case eemot_image_tot_coh: + { + image_tot.set_size(n_thk, ndetector, nxy_out); + image_coh.set_size(n_thk, ndetector, nxy_out); + + psi_coh.set_size(n_thk, 1, nxy_grid); + + dt_int32 n_vgpu = n_thk*1; + dt_int32 n_vgpu_a = n_vgpu_a_tc(n_vgpu, nxy_grid); + + psi_coh_d.set_size(n_thk, 1, nxy_grid, n_vgpu_a); + } + break; + case eemot_image_tot: + { + image_tot.set_size(n_thk, ndetector, nxy_out); + } + break; + case eemot_m2psi_tot_coh: + { + m2psi_tot.set_size(n_thk, n_beams, nxy_out); + m2psi_coh.set_size(n_thk, n_beams, nxy_out); + psi_coh.set_size(n_thk, n_beams, nxy_out); + + dt_int32 n_vgpu = n_thk*n_beams; + dt_int32 n_vgpu_a = n_vgpu_a_tc(n_vgpu, 2*nxy_out); + + m2psi_tot_d.set_size(n_thk, n_beams, nxy_out, n_vgpu_a); + m2psi_coh_d.set_size(n_thk, n_beams, nxy_out, n_vgpu_a); + psi_coh_d.set_size(n_thk, n_beams, nxy_out, n_vgpu_a); + } + break; + case eemot_m2psi_tot: + { + m2psi_tot.set_size(n_thk, n_beams, nxy_out); + + dt_int32 n_vgpu = n_thk*n_beams; + dt_int32 n_vgpu_a = n_vgpu_a_tr(n_vgpu, nxy_out); + + m2psi_tot_d.set_size(n_thk, n_beams, nxy_out, n_vgpu_a); + } + break; + case eemot_m2psi_tot_psi_coh: + { + m2psi_tot.set_size(n_thk, n_beams, nxy_out); + psi_coh.set_size(n_thk, n_beams, nxy_out); + + dt_int32 n_vgpu = n_thk*n_beams; + dt_int32 n_vgpu_a = n_vgpu_a_tr(n_vgpu, 3*nxy_out); + + m2psi_tot_d.set_size(n_thk, n_beams, nxy_out, n_vgpu_a); + psi_coh_d.set_size(n_thk, n_beams, nxy_out, n_vgpu_a); + } + break; + case eemot_psi_coh: + { + psi_coh.set_size(n_thk, n_beams, nxy_out); + + dt_int32 n_vgpu = n_thk*n_beams; + dt_int32 n_vgpu_a = n_vgpu_a_tc(n_vgpu, nxy_out); + + psi_coh_d.set_size(n_thk, n_beams, nxy_out, n_vgpu_a); + } + break; + case eemot_V: + { + V.set_size(n_thk, 1, nxy_out); + } + break; + case eemot_trans: + { + trans.set_size(n_thk, 1, nxy_out); + } + break; + case eemot_psi_0: + { + // check the number of beams of this + psi_0.set_size(n_thk, 1, nxy_out); + } + break; + } + } + + void joint_data(std::vector>& output_multem_v) + { + dt_int32 n_out_v = output_multem_v.size(); + /***************************************************************************************/ + for(auto ik = 0; ik < image_tot.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &image_tot_v = output_multem_v[iv].image_tot[ik]; + thrust::copy(image_tot_v.begin(), image_tot_v.end(), image_tot[ik].begin()+shift); + shift += image_tot_v.size(); + } + } + /***************************************************************************************/ + for(auto ik = 0; ik < image_coh.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &image_coh_v = output_multem_v[iv].image_coh[ik]; + thrust::copy(image_coh_v.begin(), image_coh_v.end(), image_coh[ik].begin()+shift); + shift += image_coh_v.size(); + } + } + /***************************************************************************************/ + for(auto ik = 0; ik < m2psi_tot.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &m2psi_tot_v = output_multem_v[iv].m2psi_tot[ik]; + thrust::copy(m2psi_tot_v.begin(), m2psi_tot_v.end(), m2psi_tot[ik].begin()+shift); + shift += m2psi_tot_v.size(); + } + } + /***************************************************************************************/ + for(auto ik = 0; ik < m2psi_coh.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &m2psi_coh_v = output_multem_v[iv].m2psi_coh[ik]; + thrust::copy(m2psi_coh_v.begin(), m2psi_coh_v.end(), m2psi_coh[ik].begin()+shift); + shift += m2psi_coh_v.size(); + } + } + /***************************************************************************************/ + for(auto ik = 0; ik < psi_coh.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &psi_coh_v = output_multem_v[iv].psi_coh[ik]; + thrust::copy(psi_coh_v.begin(), psi_coh_v.end(), psi_coh[ik].begin()+shift); + shift += psi_coh_v.size(); + } + } + /***************************************************************************************/ + for(auto ik = 0; ik < V.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &V_v = output_multem_v[iv].V[ik]; + thrust::copy(V_v.begin(), V_v.end(), V[ik].begin()+shift); + shift += V_v.size(); + } + } + /***************************************************************************************/ + for(auto ik = 0; ik < trans.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &trans_v = output_multem_v[iv].trans[ik]; + thrust::copy(trans_v.begin(), trans_v.end(), trans[ik].begin()+shift); + shift += trans_v.size(); + } + } + /***************************************************************************************/ + for(auto ik = 0; ik < psi_0.size(); ik++) + { + dt_int32 shift = 0; + for(auto iv = 0; iv < n_out_v; iv++) + { + auto &psi_0_v = output_multem_v[iv].psi_0[ik]; + thrust::copy(psi_0_v.begin(), psi_0_v.end(), psi_0[ik].begin()+shift); + shift += psi_0_v.size(); + } + } + } + + void clear() + { + output_type = eemot_m2psi_tot; + ndetector = 0; + nx = 0; + ny = 0; + dx = 0; + dy = 0; + dr = 0; + + n_thk = 0; + + x.clear(); + x.shrink_to_fit(); + + y.clear(); + y.shrink_to_fit(); + + r.clear(); + r.shrink_to_fit(); + + /***************************************************************************************/ + image_tot.clear_shrink_to_fit(); + image_coh.clear_shrink_to_fit(); + + m2psi_tot.clear_shrink_to_fit(); + m2psi_coh.clear_shrink_to_fit(); + psi_coh.clear_shrink_to_fit(); + + /***************************************************************************************/ + psi_zh.clear(); + psi_zh.shrink_to_fit(); + + m2psi_zh.clear(); + m2psi_zh.shrink_to_fit(); + + m2psi_tot_d.clear_shrink_to_fit(); + m2psi_coh_d.clear_shrink_to_fit(); + psi_coh_d.clear_shrink_to_fit(); + + /***************************************************************************************/ + V.clear_shrink_to_fit(); + trans.clear_shrink_to_fit(); + psi_0.clear_shrink_to_fit(); + } + + void clean_temporal() + { + psi_zh.clear(); + psi_zh.shrink_to_fit(); + + m2psi_zh.clear(); + m2psi_zh.shrink_to_fit(); + + switch (output_type) + { + case eemot_image_tot_coh: + { + psi_coh.clear_shrink_to_fit(); + + psi_coh_d.clear_shrink_to_fit(); + } + break; + case eemot_image_tot: + { + + } + break; + case eemot_m2psi_tot_coh: + { + psi_coh.clear_shrink_to_fit(); + + m2psi_tot_d.clear_shrink_to_fit(); + m2psi_coh_d.clear_shrink_to_fit(); + psi_coh_d.clear_shrink_to_fit(); + } + break; + case eemot_m2psi_tot: + { + m2psi_tot_d.clear_shrink_to_fit(); + } + break; + case eemot_m2psi_tot_psi_coh: + { + m2psi_tot_d.clear_shrink_to_fit(); + psi_coh_d.clear_shrink_to_fit(); + } + break; + case eemot_psi_coh: + { + psi_coh_d.clear_shrink_to_fit(); + } + break; + } + } + + void init() + { + image_tot.fill(0); + image_coh.fill(0); + + m2psi_tot.fill(0); + m2psi_coh.fill(0); + psi_coh.fill(0); + + /***************************************************************************************/ + thrust::fill(psi_zh.begin(), psi_zh.end(), T_c(0)); + thrust::fill(m2psi_zh.begin(), m2psi_zh.end(), T_r(0)); + + /***************************************************************************************/ + m2psi_tot_d.fill(0); + m2psi_coh_d.fill(0); + psi_coh_d.fill(0); + + /***************************************************************************************/ + V.fill(0); + trans.fill(0); + psi_0.fill(0); + } + + void init_psi_coh() + { + psi_coh.fill(0); + psi_coh_d.fill(0); + } + + /***************************************************************************************/ + template + void add_sc_psi_coh(dt_int32 irow, dt_int32 icol, T_c w, TVctr& phi) + { + if (psi_coh_d.exists(irow, icol)) + { + thrust::transform(thrust::device, phi.begin(), phi.end(), psi_coh_d(irow, icol).begin(), psi_coh_d(irow, icol).begin(), cgpu_fctr::add_scale(w)); + } + else + { + mt::add_sc_to_host(stream, w, phi, psi_coh(irow, icol), &psi_zh); + } + } + + template + void add_sc_sft_psi_coh(dt_int32 irow, dt_int32 icol, T_c w, TVctr& phi) + { + if (psi_coh_d.exists(irow, icol)) + { + mt::fcn_add_sc_fftsft_2d(this->grid_2d, w, phi, psi_coh_d(irow, icol), &psi_zh); + } + else + { + mt::fcn_add_sc_fftsft_2d(this->grid_2d, w, phi, psi_coh(irow, icol), &psi_zh); + } + } + + template + void add_sc_crop_sft_psi_coh(dt_int32 irow, dt_int32 icol, T_c w, TVctr& phi) + { + if (psi_coh_d.exists(irow, icol)) + { + mt::fcn_add_sc_crop_fftsft_2d(this->grid_2d, w, phi, this->output_area, psi_coh_d(irow, icol), &psi_zh); + } + else + { + mt::fcn_add_sc_crop_fftsft_2d(this->grid_2d, w, phi, this->output_area, psi_coh(irow, icol), &psi_zh); + } + } + + template + void add_sc_crop_sft_m2psi_coh_from_psi(dt_int32 irow, dt_int32 icol, T_r w, TVctr& phi) + { + if (m2psi_coh_d.exists(irow, icol)) + { + mt::fcn_add_sc_norm_2_crop_fftsft_2d(this->grid_2d, w, phi, this->output_area, m2psi_coh_d(irow, icol), &psi_zh); + } + else + { + mt::fcn_add_sc_norm_2_crop_fftsft_2d(this->grid_2d, w, phi, this->output_area, m2psi_coh(irow, icol), &psi_zh); + } + } + + template + void add_sc_crop_sft_m2psi_coh_from_m2psi(dt_int32 irow, dt_int32 icol, T_r w, TVctr& m2phi) + { + if (m2psi_coh_d.exists(irow, icol)) + { + mt::fcn_add_sc_crop_fftsft_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_coh_d(irow, icol), &m2psi_zh); + } + else + { + mt::fcn_add_sc_crop_fftsft_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_coh(irow, icol), &m2psi_zh); + } + } + + template + void add_sc_crop_sft_m2psi_tot_from_psi(dt_int32 irow, dt_int32 icol, T_r w, TVctr phi) + { + if (m2psi_tot_d.exists(irow, icol)) + { + mt::fcn_add_sc_norm_2_crop_fftsft_2d(this->grid_2d, w, phi, this->output_area, m2psi_tot_d(irow, icol), &psi_zh); + } + else + { + mt::fcn_add_sc_norm_2_crop_fftsft_2d(this->grid_2d, w, phi, this->output_area, m2psi_tot(irow, icol), &psi_zh); + } + } + + template + void add_sc_crop_sft_m2psi_tot_from_m2psi(dt_int32 irow, dt_int32 icol, T_r w, TVctr& m2phi) + { + if (m2psi_tot_d.exists(irow, icol)) + { + mt::fcn_add_sc_crop_fftsft_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_tot_d(irow, icol), &m2psi_zh); + } + else + { + mt::fcn_add_sc_crop_fftsft_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_tot(irow, icol), &m2psi_zh); + } + } + + /***************************************************************************************/ + template + void set_psi_coh(dt_int32 irow, dt_int32 icol, TVctr& phi) + { + if (psi_coh_d.exists(irow, icol)) + { + thrust::copy(phi.begin(), phi.end(), psi_coh_d(irow, icol).begin()); + } + else + { + thrust::copy(phi.begin(), phi.end(), psi_coh(irow, icol).begin()); + } + } + + template + void set_sft_psi_coh(dt_int32 irow, dt_int32 icol, TVctr& phi) + { + if (psi_coh_d.exists(irow, icol)) + { + mt::fcn_fftsft_2d(this->grid_2d, phi, psi_coh_d(irow, icol), &psi_zh); + } + else + { + mt::fcn_fftsft_2d(this->grid_2d, phi, psi_coh(irow, icol), &psi_zh); + } + } + + template + void set_crop_sft_psi_coh(dt_int32 irow, dt_int32 icol, TVctr& phi) + { + if (psi_coh_d.exists(irow, icol)) + { + mt::fcn_assign_crop_fftsft_2d(this->grid_2d, phi, this->output_area, psi_coh_d(irow, icol), &psi_zh); + } + else + { + mt::fcn_assign_crop_fftsft_2d(this->grid_2d, phi, this->output_area, psi_coh(irow, icol), &psi_zh); + } + } + + template + void set_crop_sft_m2psi_coh(dt_int32 irow, dt_int32 icol, TVctr& m2phi) + { + if (m2psi_coh_d.exists(irow, icol)) + { + mt::fcn_assign_crop_fftsft_2d(this->grid_2d, m2phi, this->output_area, m2psi_coh_d(irow, icol), &m2psi_zh); + } + else + { + mt::fcn_assign_crop_fftsft_2d(this->grid_2d, m2phi, this->output_area, m2psi_coh(irow, icol), &m2psi_zh); + } + } + + template + void set_crop_sft_m2psi_tot(dt_int32 irow, dt_int32 icol, TVctr& m2phi) + { + if (m2psi_tot_d.exists(irow, icol)) + { + mt::fcn_assign_crop_fftsft_2d(this->grid_2d, m2phi, this->output_area, m2psi_tot_d(irow, icol), &m2psi_zh); + } + else + { + mt::fcn_assign_crop_fftsft_2d(this->grid_2d, m2phi, this->output_area, m2psi_tot(irow, icol), &m2psi_zh); + } + } + + /***************************************************************************************/ + template + void from_psi_coh_2_phi(dt_int32 irow, dt_int32 icol, TVctr& phi) + { + if (psi_coh_d.exists(irow, icol)) + { + thrust::copy(psi_coh_d(irow, icol).begin(), psi_coh_d(irow, icol).end(), phi.begin()); + } + else + { + thrust::copy(psi_coh(irow, icol).begin(), psi_coh(irow, icol).end(), phi.begin()); + } + } + + template + void from_m2psi_coh_2_m2phi(dt_int32 irow, dt_int32 icol, TVctr& m2phi) + { + if (m2psi_coh_d.exists(irow, icol)) + { + thrust::copy(m2psi_coh_d(irow, icol).begin(), m2psi_coh_d(irow, icol).end(), m2phi.begin()); + } + else + { + thrust::copy(m2psi_coh(irow, icol).begin(), m2psi_coh(irow, icol).end(), m2phi.begin()); + } + } + + template + void from_m2psi_tot_2_m2phi(dt_int32 irow, dt_int32 icol, TVctr& m2phi) + { + if (m2psi_tot_d.exists(irow, icol)) + { + thrust::copy(m2psi_tot_d(irow, icol).begin(), m2psi_tot_d(irow, icol).end(), m2phi.begin()); + } + else + { + thrust::copy(m2psi_tot(irow, icol).begin(), m2psi_tot(irow, icol).end(), m2phi.begin()); + } + } + + void gather() + { + cpy_allow_data(m2psi_tot_d, m2psi_tot); + cpy_allow_data(m2psi_coh_d, m2psi_coh); + cpy_allow_data(psi_coh_d, psi_coh); + } + + dt_int32 size() const { return nx*ny; } + + dt_int32 nxy_pot_g() const { return this->grid_2d.size(); } + + dt_int32 nxy_out_g() const { return this->output_area.size_s(); } + + dt_int32 nthk() const { return n_thk; } + + /***************************************************************************************/ + inline + dt_bool is_ot_image_tot_coh() const + { + return mt::is_ot_image_tot_coh(output_type); + } + + inline + dt_bool is_ot_image_tot() const + { + return mt::is_ot_image_tot(output_type); + } + + inline + dt_bool is_ot_m2psi_tot_coh() const + { + return mt::is_ot_m2psi_tot_coh(output_type); + } + + inline + dt_bool is_ot_m2psi_tot() const + { + return mt::is_ot_m2psi_tot(output_type); + } + + inline + dt_bool is_ot_m2psi_tot_psi_coh() const + { + return mt::is_ot_m2psi_tot_psi_coh(output_type); + } + + inline + dt_bool is_ot_psi_coh() const + { + return mt::is_ot_psi_coh(output_type); + } + + inline + dt_bool is_ot_psi_0() const + { + return mt::is_ot_psi_0(output_type); + } + + inline + dt_bool is_ot_V() const + { + return mt::is_ot_V(output_type); + } + + inline + dt_bool is_ot_trans() const + { + return mt::is_ot_trans(output_type); + } + + host_vector extract_data(eAtomic_Vib_Mod_Output fp_ctr, eShow_CData show_data, dt_int32 irow, dt_int32 icol = 0) + { + host_vector data(size()); + + switch (output_type) + { + case eemot_image_tot_coh: + { + data = (fp_ctr == epmo_total)?image_tot(irow, icol):image_coh(irow, icol); + } + break; + case eemot_image_tot: + { + data = image_tot(irow, icol); + } + break; + case eemot_m2psi_tot_coh: + { + data = (fp_ctr == epmo_total)?m2psi_tot(irow, icol):m2psi_coh(irow, icol); + } + break; + case eemot_m2psi_tot: + { + data = m2psi_tot(irow, icol); + } + break; + case eemot_m2psi_tot_psi_coh: + { + if (fp_ctr == epmo_total) + { + data = m2psi_tot(irow, icol); + } + else + { + from_complex_to_real(show_data, psi_coh(irow, icol), data); + } + } + break; + case eemot_psi_coh: + { + from_complex_to_real(show_data, psi_coh(irow, icol), data); + } + break; + case eemot_V: + { + data = V(irow, icol); + } + break; + case eemot_trans: + { + from_complex_to_real(show_data, trans(irow, icol), data); + } + break; + case eemot_psi_0: + { + from_complex_to_real(show_data, psi_0(irow, icol), data); + } + break; + } + + return data; + } + + eEM_Output_Typ output_type; + + dt_int32 ndetector; + dt_int32 nx; + dt_int32 ny; + T_r dx; + T_r dy; + T_r dr; + + host_vector x; + host_vector y; + host_vector r; + + AV_2d image_tot; + AV_2d image_coh; + + AV_2d m2psi_tot; + AV_2d m2psi_coh; + AV_2d psi_coh; + + AV_2d V; + AV_2d trans; + AV_2d psi_0; + + AV_2d image_tot_d; + AV_2d image_coh_d; + + AV_2d m2psi_tot_d; + AV_2d m2psi_coh_d; + AV_2d psi_coh_d; + + dt_bool bb_only_cpu_mem; + + Stream stream; + private: + Vctr psi_zh; + Vctr m2psi_zh; + + dt_int32 n_thk; + dt_int32 n_thk_d; + + template + void cpy_allow_data(TAV_2d_1 &av_2d_1, TAV_2d_2 &av_2d_2) + { + for(auto ik = 0; ik < av_2d_1.size_a(); ik++) + { + thrust::copy(av_2d_1[ik].begin(), av_2d_1[ik].end(), av_2d_2[ik].begin()); + } + } + + void set_output_grid() + { + if (this->is_STEM() || this->is_STEM_ISTEM_EELS()) + { + nx = this->scanning.nx; + ny = this->scanning.ny; + + dx = this->scanning.dR.x; + dy = this->scanning.dR.y; + + x = this->scanning.x(); + y = this->scanning.y(); + r = this->scanning.mR; + } + else + { + nx = this->output_area.nx_s(); + ny = this->output_area.ny_s(); + + const dt_bool is_RS = this->is_grid_RS(); + dx = (is_RS)?this->grid_2d.drx:this->grid_2d.dgx; + dy = (is_RS)?this->grid_2d.dry:this->grid_2d.dgy; + + x.resize(nx); + y.resize(ny); + + for(auto ix = this->output_area.ix_0; ix < this->output_area.ix_e; ix++) + { + dt_int32 ix_s = ix-this->output_area.ix_0; + x[ix_s] = (is_RS)?this->grid_2d.rx(ix):this->grid_2d.gx(ix); + } + + for(auto iy = this->output_area.iy_0; iy < this->output_area.iy_e; iy++) + { + dt_int32 iy_s = iy-this->output_area.iy_0; + y[iy_s] = (is_RS)?this->grid_2d.ry(iy):this->grid_2d.gy(iy); + } + } + } + + // 1:(image_tot, image_coh);2:(image_tot);3:(m2psi_tot, m2psi_coh);4:(m2psi_tot); + // 5:(m2psi_tot, psi_coh);6:(psi_coh);7:(psi_0);8:(V);9:(trans) + void set_output_type() + { + if (this->is_STEM() || this->is_STEM_ISTEM_EELS()) + { + output_type = (this->atomic_vib.coh_contrib)?eemot_image_tot_coh:eemot_image_tot; + } + else if (this->is_ISTEM() || this->is_CBED_CBEI() || this->is_PED_HCTEM() || + this->is_ED_HRTEM() || this->is_EFTEM()) + { + output_type = (this->atomic_vib.coh_contrib)?eemot_m2psi_tot_coh:eemot_m2psi_tot; + } + else if (this->is_EWFS_EWRS()) + { + output_type = (this->is_EWFS_EWRS_SC())?eemot_psi_coh:eemot_m2psi_tot_psi_coh; + } + else if (this->is_PropFS_PropRS()) + { + output_type = eemot_psi_coh; + } + else if (this->is_IWFS_IWRS()) + { + output_type = eemot_psi_0; + } + else if (this->is_PPFS_PPRS()) + { + output_type = eemot_V; + } + else if (this->is_TFFS_TFRS()) + { + output_type = eemot_trans; + } + } + + template + void assign_multem_in_parm(TIn_Multislice &multem_in_parm) + { + this->system_config = multem_in_parm.system_config; + + this->elec_spec_interact_mod = multem_in_parm.elec_spec_interact_mod; + this->atomic_pot_parm_typ = multem_in_parm.atomic_pot_parm_typ; + + this->operation_mode = multem_in_parm.operation_mode; + this->slice_storage = multem_in_parm.slice_storage; + this->reverse_multislice = multem_in_parm.reverse_multislice; + this->mul_sign = multem_in_parm.mul_sign; + this->Vrl = multem_in_parm.Vrl; + this->nR = multem_in_parm.nR; + + this->atomic_vib = multem_in_parm.atomic_vib; + + this->atoms = multem_in_parm.atoms; + this->is_xtl = multem_in_parm.is_xtl; + + this->rot_in_parm = multem_in_parm.rot_in_parm; + + this->thick_type = multem_in_parm.thick_type; + this->thick = multem_in_parm.thick; + + this->spec_slic_typ = multem_in_parm.spec_slic_typ; + + this->grid_2d = multem_in_parm.grid_2d; + this->output_area = multem_in_parm.output_area; + + this->em_sim_typ = multem_in_parm.em_sim_typ; + + this->iw_type = multem_in_parm.iw_type; + this->iw_psi = multem_in_parm.iw_psi; + this->beam_pos_2d = multem_in_parm.beam_pos_2d; + + this->E_0 = multem_in_parm.E_0; + this->theta = multem_in_parm.theta; + this->phi = multem_in_parm.phi; + this->nrot = multem_in_parm.nrot; + + this->illum_mod = multem_in_parm.illum_mod; + this->illum_inc = multem_in_parm.illum_inc; + + this->cond_lens = multem_in_parm.cond_lens; + this->obj_lens = multem_in_parm.obj_lens; + + this->scanning = multem_in_parm.scanning; + this->detector = multem_in_parm.detector; + + this->eels_fr = multem_in_parm.eels_fr; + + this->cdl_var_type = multem_in_parm.cdl_var_type; + this->cdl_var = multem_in_parm.cdl_var; + + this->beam_pos = multem_in_parm.beam_pos; + + this->islice = multem_in_parm.islice; + this->dp_Shift = multem_in_parm.dp_Shift; + } + }; + +} + +#endif \ No newline at end of file diff --git a/src - Copy (2)/particle_fcns.hpp b/src - Copy (2)/particle_fcns.hpp new file mode 100755 index 00000000..6be6adb1 --- /dev/null +++ b/src - Copy (2)/particle_fcns.hpp @@ -0,0 +1,381 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PARTICLE_FCNS_H + #define PARTICLE_FCNS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + + #include "macros.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "cgpu_vctr.cuh" + + namespace mt + { + // calculate the mean position using xy cordinates and it frequency + template + enable_if_vctr_cpu_r_2d>> + fcn_xy_2_xyc(TVctr& vr_2d, Value_type_r radius) + { + using T = Value_type_r; + using ST = Size_type; + + const ST n_vr_2d = vr_2d.size(); + + const T r2_max = ::square(radius); + + Vctr_r_3d_cpu vr_3d; + vr_3d.reserve(n_vr_2d); + + std::vector bb(n_vr_2d, true); + + for(ST ip = 0; ip < n_vr_2d; ip++) + { + if (bb[ip]) + { + const auto r_i = vr_2d[ip]; + + ST ic = 0; + R_2d p_m = 0; + + for(ST ip_s = 0; ip_s < n_vr_2d; ip_s++) + { + if (bb[ip_s]) + { + if (norm_2(vr_2d[ip_s]-r_i) < r2_max) + { + p_m += vr_2d[ip_s]; + bb[ip_s] = false; + ic++; + } + } + } + p_m /= T(ic); + + vr_3d.push_back(R_3d(p_m.x, p_m.y, T(ic))); + } + } + + return vr_3d; + } + + // replace xy positions by its mean positions using a xy reference + template + enable_if_vctr_cpu_r_2d + fcn_xy_2_xym(const TVctr& vr_2d_r, Value_type_r radius, TVctr& vr_2d_io) + { + using T = Value_type_r; + using ST = Size_type; + + const ST n_vr_2d = vr_2d_io.size(); + const ST n_vr_2d_r = vr_2d_r.size(); + //const ST n_vr_2d_r = min(vr_2d_r.size(), n_vr_2d); + + const T r2_max = ::square(radius); + + std::vector bb(n_vr_2d, true); + std::vector ind_s(n_vr_2d, ST(0)); + + for(ST ip = 0; ip < n_vr_2d_r; ip++) + { + const auto r_c = vr_2d_r[ip]; + + ST ic = 0; + R_2d p_m = 0; + + for(ST ip_s = 0; ip_s < n_vr_2d; ip_s++) + { + if (bb[ip_s]) + { + if (norm_2(vr_2d_io[ip_s]-r_c) < r2_max) + { + p_m += vr_2d_io[ip_s]; + bb[ip_s] = false; + ind_s[ic] = ip_s; + ic++; + } + } + } + p_m /= T(ic); + + for(ST ip_s = 0; ip_s < ic; ip_s++) + { + vr_2d_io[ind_s[ip_s]] = p_m; + } + } + } + + // match one to one xy positions: vr_2d_r: array of R_2d and vr_2d: array of R_2d + template + enable_if_vctr_cpu_r_2d + fcn_xy_match_one_2_one(const TVctr& vr_2d_r, TVctr& vr_2d, Vctr_cpu& ind_match) + { + if (vr_2d_r.size() != vr_2d.size()) + return; + + using T = Value_type; + using U = Value_type_r; + using ST = Size_type; + + const ST n_vr_2d = vr_2d.size(); + + using typ_ind_d2 = std::tuple; + + std::vector data(n_vr_2d, std::make_tuple(ST(), ST(), U(), T())); + + // find minimum distance for each reference position + for(ST ip = 0; ip < n_vr_2d; ip++) + { + const auto r_c = vr_2d_r[ip]; + + ST ip_s_min = 0; + U d2_s_min = norm_2(vr_2d[ip_s_min]-r_c); + + for(ST ip_s = 1; ip_s < n_vr_2d; ip_s++) + { + auto d2_ip = norm_2(vr_2d[ip_s]-r_c); + + if (d2_ip < d2_s_min) + { + d2_s_min = d2_ip; + ip_s_min =ip_s; + } + } + + data[ip] = std::make_tuple(ip, ip_s_min, d2_s_min, vr_2d[ip_s_min]); + } + + // sort by distance + std::sort(data.begin(), data.end(), [](const typ_ind_d2 &a, const typ_ind_d2 &b) + { return (std::get<1>(a) < std::get<1>(b)) || + ((std::get<1>(a) == std::get<1>(b)) && (std::get<2>(a) < std::get<2>(b))); + }); + + // std::sort(data.begin(), data.end(), [](const typ_ind_d2 &a, const typ_ind_d2 &b){ return std::get<2>(a) < std::get<2>(b); }); + + // get unique indices + auto last = std::unique(data.begin(), data.end(), [](const typ_ind_d2 &a, const typ_ind_d2 &b){ return std::get<1>(a) == std::get<1>(b); }); + ST n_uniq = std::distance(data.begin(), last); + ST n_left = n_vr_2d - n_uniq; + + // return if there is not duplicate indices + if (n_left==0) + { + for(ST ip = 0; ip < n_vr_2d; ip++) + { + ind_match[std::get<0>(data[ip])] = std::get<1>(data[ip]); + vr_2d[std::get<0>(data[ip])] = std::get<3>(data[ip]); + } + + return; + } + + // select unique matches + std::vector bb_r(n_vr_2d, true); + std::vector bb(n_vr_2d, true); + + for(ST ip = 0; ip < n_uniq; ip++) + { + bb_r[std::get<0>(data[ip])] = false; + bb[std::get<1>(data[ip])] = false; + } + + // get duplicated indices + std::vector ind_r; + ind_r.reserve(n_left); + + std::vector ind; + ind.reserve(n_left); + + for(ST ip = 0; ip < n_vr_2d; ip++) + { + if (bb_r[ip]) + ind_r.push_back(ip); + + if (bb[ip]) + ind.push_back(ip); + } + + // match duplicate indices + for(ST ip = 0; ip < n_left; ip++) + { + const auto r_c = vr_2d_r[ind_r[ip]]; + + // initial index have to be calculated for each iteration + ST ip_s_g_min = 0; + + for(ST ip_s = 0; ip_s < n_left; ip_s++) + { + if (bb[ind[ip_s]]) + { + ip_s_g_min = ind[ip_s]; + break; + } + } + + U d2 = norm_2(vr_2d[ip_s_g_min]-r_c); + + for(ST ip_s = 1; ip_s < n_left; ip_s++) + { + auto ip_s_g = ind[ip_s]; + + if (bb[ip_s_g]) + { + auto d2_ip = norm_2(vr_2d[ip_s_g]-r_c); + + if (d2_ip < d2) + { + d2 = d2_ip; + ip_s_g_min =ip_s_g; + } + } + } + + bb[ip_s_g_min] = false; + data[n_uniq + ip] = std::make_tuple(ind_r[ip], ip_s_g_min, d2, vr_2d[ip_s_g_min]); + } + + for(ST ip = 0; ip < n_vr_2d; ip++) + { + ind_match[std::get<0>(data[ip])] = std::get<1>(data[ip]); + vr_2d[std::get<0>(data[ip])] = std::get<3>(data[ip]); + } + } + + /***************************************************************************************/ + // radial distribution function + template + enable_if_vctr_cpu_r_nd_and_vctr_cpu + fcn_rdf(TVctr_r_nd& vr_nd, Value_type r_max, dt_int32 nr, TVctr& r_o, TVctr& rdf_o) + { + using T = Value_type; + using ST = Size_type; + + const T dr = r_max/T(nr); + + for(ST ir = 0; ir < nr; ir++) + { + r_o[ir] = ir*dr; + rdf_o[ir] = T(0); + } + + const auto r2_max = ::square(r_max); + + const ST n_vr_nd = vr_nd.size(); + for(ST ixy = 0; ixy < n_vr_nd; ixy++) + { + const auto r_i = vr_nd[ixy]; + for(ST ixy_s = 0; ixy_s < n_vr_nd; ixy_s++) + { + auto d2 = norm_2(vr_nd[ixy_s]-r_i); + if ((d2 < r2_max) && (ixy != ixy_s)) + { + const auto ir = static_cast(::floor(::sqrt(d2)/dr)); + rdf_o[ir] += 1; + } + } + } + if (typeid(Value_type) == typeid(R_2d)) + { + for(auto ir = 1; ir < nr; ir++) + { + rdf_o[ir] = rdf_o[ir]/(c_pi*r_o[ir]*dr); + } + } + else if (typeid(Value_type) == typeid(R_3d)) + { + for(auto ir = 1; ir < nr; ir++) + { + rdf_o[ir] = rdf_o[ir]/(T(4)*c_pi*::square(r_o[ir])*dr); + } + } + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu_r_nd, Size_type, Size_type>> + fcn_vctr_r_nd_dist(const TVctr& vr_nd, TFcn fcn) + { + using T = Value_type_r; + using ST = Size_type; + + const ST n_vr_nd = vr_nd.size(); + + if (n_vr_nd == 1) + { + return std::make_tuple(T(0), ST(0), ST(0)); + } + + ST idx_0 = 0; + ST idx_e = 1; + T d2_op = norm_2(vr_nd[0]-vr_nd[1]); + + for(ST ixy = 0; ixy < n_vr_nd; ixy++) + { + const auto r_i = vr_nd[ixy]; + //for (ST ixy_s = 0; ixy_s < n_vr_nd; ixy_s++) // check out this line because it can be optmize by + for(ST ixy_s = ixy+1; ixy_s < n_vr_nd; ixy_s++) + { + auto d2 = norm_2(vr_nd[ixy_s]-r_i); + if ((ixy != ixy_s) && fcn(d2, d2_op)) + { + idx_0 = ixy; + idx_e = ixy_s; + d2_op = d2; + } + } + } + + return std::make_tuple(::sqrt(d2_op), idx_0, idx_e); + } + + template + enable_if_vctr_cpu_r_nd> + fcn_min_dist(const TVctr& vr_nd) + { + using T = Value_type_r; + + auto dist_t = fcn_vctr_r_nd_dist(vr_nd, std::less()); + + return std::get<0>(dist_t); + } + + template + enable_if_vctr_cpu_r_nd> + fcn_max_dist(const TVctr& vr_nd) + { + using T = Value_type_r; + + auto dist_t = fcn_vctr_r_nd_dist(vr_nd, std::greater()); + + return std::get<0>(dist_t); + } + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/particles.cuh b/src - Copy (2)/particles.cuh new file mode 100755 index 00000000..9cfff4f9 --- /dev/null +++ b/src - Copy (2)/particles.cuh @@ -0,0 +1,3257 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PARTICLES_H + #define PARTICLES_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "macros.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "mx_2x2.cuh" + #include "mx_3x3.cuh" + #include "cgpu_vctr.cuh" + #include "cpu_fcns.hpp" + #ifdef __CUDACC__ + #include "gpu_fcns.cuh" + #endif + #include "grid.cuh" + #include "range.cuh" + #include "fcns_elem.cuh" + + #include + + /***************************************************************************************/ + /************************************* fcn particle ************************************/ + /***************************************************************************************/ + namespace mt + { + template class Ptc_s_fcn_xd; + + /* Gauss */ + template + using Ptc_s_Gauss_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_3d = Ptc_s_fcn_xd; + + /* Exp */ + template + using Ptc_s_Exp_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_3d = Ptc_s_fcn_xd; + + /* Fermi */ + template + using Ptc_s_Fermi_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_3d = Ptc_s_fcn_xd; + + /* Butwth */ + template + using Ptc_s_Butwth_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_3d = Ptc_s_fcn_xd; + + /* Hann */ + template + using Ptc_s_Hann_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_3d = Ptc_s_fcn_xd; + } + + /***************************************************************************************/ + /********************************* gaussian particle ***********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max) + { + set_in_data(r, a, sigma, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, sigma, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, sigma); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, sigma, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + + }; + } + + /***************************************************************************************/ + /******************************** exponential particle *********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max) + { + set_in_data(r, a, beta, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, beta, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, beta); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, beta, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; + } + + /***************************************************************************************/ + /*********************************** fermi particle ************************************/ + /***************************************************************************************/ + namespace mt + { + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max) + { + set_in_data(r, a, alpha, radius, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, alpha, radius, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, alpha, radius); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, alpha, radius, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; + } + + /***************************************************************************************/ + /******************************* butterworth particle **********************************/ + /***************************************************************************************/ + namespace mt + { + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max) + { + set_in_data(r, a, n, radius, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, n, radius, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, n, radius); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, n, radius, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; + } + + /***************************************************************************************/ + /*********************************** hann particle *************************************/ + /***************************************************************************************/ + namespace mt + { + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max) + { + set_in_data(r, a, l, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, l, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, l); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, l, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; + } + + /***************************************************************************************/ + namespace mt + { + namespace ptc_detail + { + template + void set_ptc_pbc_xy(const PTC_i& ptc_i, const dt_bool& pbc_xy, const dt_bool& b_statistic, PTC_o& ptc_o) + { + using T = typename PTC_o::value_type; + + ptc_o.bs = ptc_i.bs; + + if (ptc_i.size()==0) + return; + + if (!pbc_xy) + { + ptc_o = ptc_i; + } + else + { + auto bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < ptc_i.size(); ia++) + { + auto bb_x = fcn_chk_bound(ptc_i.x[ia], T(0), bs_e.x); + auto bb_y = fcn_chk_bound(ptc_i.y[ia], T(0), bs_e.y); + + if (bb_x && bb_y) + { + ptc_o.push_back(ptc_i.get(ia)); + } + } + + ptc_o.shrink_to_fit(); + } + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + template + void set_ptc_pbc_xy(const pVctr_cpu_64& p_ptc, const dt_int64& icol, const R_D& bs, const dt_bool& pbc_xy, const dt_bool& b_statistic, PTC_o& ptc_o) + { + using T = typename PTC_o::value_type; + using Ptc_s = typename PTC_o::Ptc_s; + + ptc_o.bs = bs; + + if (p_ptc.empty()) + return; + + auto s_0 = p_ptc.s0(); + auto s_1 = p_ptc.s1(); + + if (!pbc_xy) + { + for(dt_int64 ia = 0; ia < s_0; ia++) + { + ptc_o.push_back(Ptc_s(p_ptc.data(), s_0, s_1, ia, icol)); + } + } + else + { + auto bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < s_0; ia++) + { + auto ptc_s = Ptc_s(p_ptc.data(), s_0, s_1, ia, icol); + auto bb_x = fcn_chk_bound(ptc_s.x, T(0), bs_e.x); + auto bb_y = fcn_chk_bound(ptc_s.y, T(0), bs_e.y); + + if (bb_x && bb_y) + { + ptc_o.push_back(ptc_s); + } + } + } + + ptc_o.shrink_to_fit(); + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + /***************************************************************************************/ + /*********************************** macros 2d/3d **************************************/ + /***************************************************************************************/ + #define CASE_SORT(N) case N: { thrust::sort(first, last, mt::cgpu_fctr::less_soa()); } break; + + #define ZIPITER_0_2D this->x, this->y + #define ZIPITER_0_3D this->x, this->y, this->z + + #define ZIPITER_0(DIM) ZIPITER_0_##DIM##D + #define ZIPITER_1(DIM) ZIPITER_0(DIM), this->c_1 + #define ZIPITER_2(DIM) ZIPITER_1(DIM), this->c_2 + #define ZIPITER_3(DIM) ZIPITER_2(DIM), this->c_3 + #define ZIPITER_4(DIM) ZIPITER_3(DIM), this->c_4 + #define ZIPITER_5(DIM) ZIPITER_4(DIM), this->c_5 + #define ZIPITER_6(DIM) ZIPITER_5(DIM), this->c_6 + #define ZIPITER_7(DIM) ZIPITER_6(DIM), this->c_7 + #define ZIPITER_8(DIM) ZIPITER_7(DIM), this->c_8 + #define ZIPITER_9(DIM) ZIPITER_8(DIM), this->c_9 + + #define SWITCH_0_2D(macro) macro(0) macro(1) + #define SWITCH_1_2D(macro) SWITCH_0_2D(macro) macro(2) + #define SWITCH_2_2D(macro) SWITCH_1_2D(macro) macro(3) + #define SWITCH_3_2D(macro) SWITCH_2_2D(macro) macro(4) + #define SWITCH_4_2D(macro) SWITCH_3_2D(macro) macro(5) + #define SWITCH_5_2D(macro) SWITCH_4_2D(macro) macro(6) + #define SWITCH_6_2D(macro) SWITCH_5_2D(macro) macro(7) + #define SWITCH_7_2D(macro) SWITCH_6_2D(macro) macro(8) + #define SWITCH_8_2D(macro) SWITCH_7_2D(macro) macro(9) + #define SWITCH_9_2D(macro) SWITCH_8_2D(macro) macro(10) + + #define SWITCH_0_3D(macro) macro(0) macro(1) macro(2) + #define SWITCH_1_3D(macro) SWITCH_0_3D(macro) macro(3) + #define SWITCH_2_3D(macro) SWITCH_1_3D(macro) macro(4) + #define SWITCH_3_3D(macro) SWITCH_2_3D(macro) macro(5) + #define SWITCH_4_3D(macro) SWITCH_3_3D(macro) macro(6) + #define SWITCH_5_3D(macro) SWITCH_4_3D(macro) macro(7) + #define SWITCH_6_3D(macro) SWITCH_5_3D(macro) macro(8) + #define SWITCH_7_3D(macro) SWITCH_6_3D(macro) macro(9) + #define SWITCH_8_3D(macro) SWITCH_7_3D(macro) macro(10) + #define SWITCH_9_3D(macro) SWITCH_8_3D(macro) macro(11) + + #define FCN_SORT_BY_IDX(DIM, N) \ + virtual void sort_by_idx(const dt_int32& idx) \ + { \ + auto first = fcn_mkzipiter_begin(ZIPITER_##N(DIM)); \ + auto last = fcn_mkzipiter_end(ZIPITER_##N(DIM)); \ + \ + switch(idx) \ + { \ + SWITCH_##N##_##DIM##D(CASE_SORT) \ + } \ + } + + #define CD_PASTE(pre, x, y) pre ## _ ## x ## d ## _ ## y + #define CD_EVAL_PASTE(pre, x, y) CD_PASTE(pre, x, y) + #define CD_EVAL_2_PASTE(pre, x, y) CD_EVAL_PASTE(pre, x, y) + + #define CD_PTC_S_N(DIM, N) CD_EVAL_PASTE(Ptc_s, DIM, N) + #define CD_PTC_S_NB(DIM, N) CD_EVAL_2_PASTE(Ptc_s, DIM, DEC(N, 1)) + + #define CD_PTC_N(DIM, N) CD_EVAL_PASTE(Ptc, DIM, N) + #define CD_PTC_NB(DIM, N) CD_EVAL_2_PASTE(Ptc, DIM, DEC(N, 1)) + + #define N_DIM(N, DIM) EVAL_2_PASTE(INC, DEC(DIM, 1), N) + + /***************************************************************************************/ + #define C_PTC_S_COEF_DIM_N(DIM, N) \ + template \ + class CD_PTC_S_N(DIM, N): public CD_PTC_S_NB(DIM, N) \ + { \ + public: \ + T c_##N; \ + \ + CD_PTC_S_N(DIM, N)(): CD_PTC_S_NB(DIM, N)(), c_##N(0) {} \ + \ + /* constructor by initializer list */ \ + template \ + CD_PTC_S_N(DIM, N)(const dt_init_list& list): CD_PTC_S_NB(DIM, N)(list) \ + { \ + auto ptr = list.begin(); \ + \ + c_##N = T(ptr[N_DIM(N, DIM)]); \ + } \ + \ + /* constructor by base class */ \ + template \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_NB(DIM, N)& base, const T& c_##N): CD_PTC_S_NB(DIM, N)(base) \ + { \ + this->c_##N = T(c_##N); \ + } \ + \ + /* constructor by pointer */ \ + template \ + CD_PTC_S_N(DIM, N)(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): CD_PTC_S_NB(DIM, N)(v, n_r, n_c, idx, icol) \ + { \ + const auto ip = icol*n_r + idx; \ + c_##N = (n_c>N_DIM(N, DIM))?T(v[ip + N_DIM(N, DIM)*n_r]):T(1); \ + } \ + \ + /* copy constructor */ \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + *this = ptc_s; \ + } \ + \ + /* converting constructor */ \ + template \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + *this = ptc_s; \ + } \ + \ + /******************************** assignment operators *********************************/ \ + /* copy assignment operator */ \ + CD_PTC_S_N(DIM, N)& operator=(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + if (this != &ptc_s) \ + { \ + CD_PTC_S_NB(DIM, N)::operator=(ptc_s); \ + \ + c_##N = ptc_s.c_##N; \ + } \ + \ + return *this; \ + } \ + \ + /* converting assignment operator */ \ + template \ + CD_PTC_S_N(DIM, N)& operator=(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + assign(ptc_s); \ + \ + return *this; \ + } \ + \ + template \ + void assign(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + if ((void*)this != (void*)&ptc_s) \ + { \ + CD_PTC_S_NB(DIM, N)::assign(ptc_s); \ + \ + c_##N = T(ptc_s.c_##N); \ + } \ + } \ + } + + /***************************************************************************************/ + #define C_PTC_COEF_DIM_N(DIM, N) \ + template \ + class CD_PTC_N(DIM, N): public CD_PTC_NB(DIM, N) \ + { \ + public: \ + using value_type = T; \ + using size_type = dt_int64; \ + \ + using Ptc_s = CD_PTC_S_N(DIM, N); \ + \ + mutable Vctr_cpu c_##N; \ + \ + R_2d c_##N##_lim; \ + \ + /************************************* constructors ************************************/ \ + CD_PTC_N(DIM, N)(): CD_PTC_NB(DIM, N)(), c_##N##_lim(){} \ + \ + template \ + CD_PTC_N(DIM, N)(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_##DIM##d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); \ + } \ + \ + /* copy constructor */ \ + CD_PTC_N(DIM, N)(const CD_PTC_N(DIM, N)& ptc) \ + { \ + *this = ptc; \ + } \ + \ + /* converting constructor */ \ + template \ + CD_PTC_N(DIM, N)(const CD_PTC_N(DIM, N)& ptc) \ + { \ + *this = ptc; \ + } \ + \ + /******************************** assignment operators *********************************/ \ + /* copy assignment operator */ \ + CD_PTC_N(DIM, N)& operator=(const CD_PTC_N(DIM, N)& ptc) \ + { \ + assign(ptc); \ + \ + return *this; \ + } \ + \ + /* converting assignment operator */ \ + template \ + CD_PTC_N(DIM, N)& operator=(const CD_PTC_N(DIM, N)& ptc) \ + { \ + assign(ptc); \ + \ + return *this; \ + } \ + \ + template \ + void assign(const CD_PTC_N(DIM, N)& ptc) \ + { \ + if ((void*)this != (void*)&ptc) \ + { \ + CD_PTC_NB(DIM, N)::assign(ptc); \ + \ + c_##N = ptc.c_##N; \ + \ + c_##N##_lim = ptc.c_##N##_lim; \ + } \ + } \ + \ + /***************************************************************************************/ \ + virtual size_type cols() const \ + { \ + return INC(N, DIM); \ + } \ + \ + void clear() \ + { \ + CD_PTC_NB(DIM, N)::clear(); \ + \ + c_##N.clear(); \ + \ + c_##N##_lim = 0; \ + } \ + \ + void resize(size_type new_size) \ + { \ + new_size = max(size_type(0), new_size); \ + \ + CD_PTC_NB(DIM, N)::resize(new_size); \ + \ + c_##N.resize(new_size); \ + } \ + \ + void reserve(size_type new_size) \ + { \ + new_size = max(size_type(0), new_size); \ + \ + CD_PTC_NB(DIM, N)::reserve(new_size); \ + \ + c_##N.reserve(new_size); \ + } \ + \ + void shrink_to_fit() \ + { \ + CD_PTC_NB(DIM, N)::shrink_to_fit(); \ + \ + c_##N.shrink_to_fit(); \ + } \ + \ + void push_back(const Ptc_s& ptc_s) \ + { \ + CD_PTC_NB(DIM, N)::push_back(ptc_s); \ + \ + c_##N.push_back(ptc_s.c_##N); \ + } \ + \ + Ptc_s get(const size_type& ia) const \ + { \ + return {CD_PTC_NB(DIM, N)::get(ia), c_##N[ia]}; \ + } \ + \ + void set(const size_type& ia, const Ptc_s& ptc_s) \ + { \ + CD_PTC_NB(DIM, N)::set(ia, ptc_s); \ + \ + c_##N[ia] = ptc_s.c_##N; \ + } \ + \ + template \ + void set_ptc(const CD_PTC_N(DIM, N)& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + clear(); \ + reserve(ptc.size()); \ + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); \ + } \ + \ + template \ + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_##DIM##d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + clear(); \ + reserve(ptc.size()); \ + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); \ + } \ + \ + /* copy data to pointer */ \ + template \ + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=INC(N, DIM)) const \ + { \ + if (is_0>is_e) \ + { \ + std::swap(is_0, is_e); \ + } \ + \ + auto n_data = min(n_ptc, this->size()); \ + auto is = CD_PTC_NB(DIM, N)::cpy_to_ptr(ptc, n_ptc, is_0, is_e); \ + \ + if (fcn_chk_bound(N_DIM(N, DIM), is_0, is_e)) \ + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), c_##N.data(), n_data); \ + \ + return is; \ + } \ + \ + /* get statistic */ \ + virtual void get_statistic() \ + { \ + if (this->empty()) \ + { \ + return; \ + } \ + \ + CD_PTC_NB(DIM, N)::get_statistic(); \ + \ + fcn_minmax_element(c_##N, c_##N##_lim.x, c_##N##_lim.y); \ + } \ + \ + /* sort by idx */ \ + FCN_SORT_BY_IDX(DIM, N); \ + } + }; + } + + /***************************************************************************************/ + /******************************** position particle ************************************/ + /***************************************************************************************/ + namespace mt + { + template class Ptc_s_xd_0; + + /* 1d */ + template + using Ptc_s_1d_0 = Ptc_s_xd_0; + + /* 2d */ + template + using Ptc_s_2d_0 = Ptc_s_xd_0; + + /* 3d */ + template + using Ptc_s_3d_0 = Ptc_s_xd_0; + } + + /* template specialization 1d*/ + namespace mt + { + template + class Ptc_s_xd_0 + { + public: + using value_type = T; + + T x; + + /************************************* constructors ************************************/ + Ptc_s_xd_0(): x(0) {} + + Ptc_s_xd_0(const T& x): x(x){} + + template + Ptc_s_xd_0(const U& x): x(x){} + + // ! constructor by initializer list + template + Ptc_s_xd_0(const dt_init_list& list) + { + auto ptr = list.begin(); + + x = T(ptr[0]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + x = (n_c>0)?T(v[ip + 0*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + x = ptc.x; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + x = T(ptc.x); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + CGPU_EXEC + void clear() + { + x = T(0); + } + + CGPU_EXEC + void set_pos(const T& r) + { + x = r; + } + + CGPU_EXEC + T get_pos() const + { + return x; + } + }; + } + + /* template specialization 2d*/ + namespace mt + { + template + class Ptc_s_xd_0: public Ptc_s_xd_0 + { + public: + T y; + + Ptc_s_xd_0(): Ptc_s_xd_0(), y(0) {} + + Ptc_s_xd_0(const T& x, const T& y): Ptc_s_xd_0(x), y(y){} + + template + Ptc_s_xd_0(const U& x, const U& y): Ptc_s_xd_0(x), y(y){} + + // ! constructor by initializer list + template + Ptc_s_xd_0(const dt_init_list& list): Ptc_s_xd_0(list) + { + auto ptr = list.begin(); + + y = T(ptr[1]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): Ptc_s_xd_0(v, n_r, n_c, idx, icol) + { + const auto ip = icol*n_r + idx; + + y = (n_c>1)?T(v[ip + 1*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + Ptc_s_xd_0::operator=(ptc); + + y = ptc.y; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + Ptc_s_xd_0::operator=(ptc); + + y = T(ptc.y); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + CGPU_EXEC + void set_pos(const R_2d& r) + { + this->x = r.x; + y = r.y; + } + + CGPU_EXEC + R_2d get_pos() const + { + return {this->x, y}; + } + }; + } + + /* template specialization 3d*/ + namespace mt + { + template + class Ptc_s_xd_0: public Ptc_s_xd_0 + { + public: + T z; + + Ptc_s_xd_0(): Ptc_s_xd_0(), z(0) {} + + Ptc_s_xd_0(const T& x, const T& y, const T& z): Ptc_s_xd_0(x, y), z(z){} + + template + Ptc_s_xd_0(const U& x, const U& y, const U& z): Ptc_s_xd_0(x, y), z(z){} + + // ! constructor by initializer list + template + Ptc_s_xd_0(const dt_init_list& list): Ptc_s_xd_0(list) + { + auto ptr = list.begin(); + + z = T(ptr[2]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): Ptc_s_xd_0(v, n_r, n_c, idx, icol) + { + const auto ip = icol*n_r + idx; + + z = (n_c>1)?T(v[ip + 2*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + Ptc_s_xd_0::operator=(ptc); + + z = ptc.z; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + Ptc_s_xd_0::operator=(ptc); + + z = T(ptc.z); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + CGPU_EXEC + void set_pos(const R_3d& r) + { + this->x = r.x; + this->y = r.y; + z = r.z; + } + + CGPU_EXEC + R_3d get_pos() const + { + return {this->x, this->y, z}; + } + }; + } + + /***************************************************************************************/ + /******************************** position particles ***********************************/ + /***************************************************************************************/ + namespace mt + { + template class Ptc_xd_0; + + /* 1d */ + template + using Ptc_1d_0 = Ptc_xd_0; + + /* 2d */ + template + using Ptc_2d_0 = Ptc_xd_0; + + /* 3d */ + template + using Ptc_3d_0 = Ptc_xd_0; + } + + /* forward declarations */ + namespace mt + { + /* 1d */ + template + void fcn_ptc_pos_statistic(Ptc_1d_0& ptc); + + template + void fcn_ptc_pos_shift(const R_1d& r_sft, Ptc_1d_0& ptc); + + template + void fcn_ptc_pos_recenter(const R_1d& bs, Ptc_1d_0& ptc); + + template + void fcn_ptc_pos_apply_ltf(const T& mx, const R_1d& p, Ptc_1d_0& ptc); + + /* 2d */ + template + void fcn_ptc_pos_statistic(Ptc_2d_0& ptc); + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_2d_0& ptc); + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_2d_0& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_2d_0& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_2d_0& ptc); + + /* 3d */ + template + void fcn_ptc_pos_statistic(Ptc_3d_0& ptc); + + template + void fcn_ptc_pos_shift(const R_3d& bs, Ptc_3d_0& ptc); + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_3d_0& ptc); + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_3d_0& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_3d_0& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_3d_0& ptc); + } + + /* template specialization 1d */ + namespace mt + { + template + class Ptc_xd_0 + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_1d_0; + + R_1d bs; // box size + + mutable Vctr_cpu x; + + R_2d x_lim; + + R_1d r_mean; // mean position + R_1d r_std; // standard deviation + R_1d sz; // size + + /************************************* constructors ************************************/ + Ptc_xd_0(): bs(), x_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_xd_0(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_x, b_statistic); + } + + /* copy constructor */ + Ptc_xd_0(const Ptc_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_xd_0(const Ptc_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_xd_0& operator=(const Ptc_xd_0& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_xd_0& operator=(const Ptc_xd_0& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_xd_0& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + + x_lim = ptc.x_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 1; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + + x_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + } + + template + void set_bs(const R_2d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return x[ia]; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + } + + R_1d get_pos(const size_type& ia) const + { + return x[ia]; + } + + void set_pos(const size_type& ia, const R_1d& r) + { + x[ia] = r; + } + + template + void set_ptc(const Ptc_xd_0& ptc, dt_bool pbc_x = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_x, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_x, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=1) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = std::begin(this->x); + auto last = std::end(this->x); + + switch(idx) + { + case 0: + { + thrust::sort(x, last, mt::cgpu_fctr::less()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_x(const size_type& ia, const R_1d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r = fabs(r); + + r = ::fmin(r, fabs(r-bs)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_1d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r = fabs(r); + + r = ::fmin(r, fabs(r-bs)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_1d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_x(const size_type& ia, const R_1d& r_0) const + { + return ::sqrt(this->norm_2_pbc_x(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_1d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_1d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_1d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void apply_ltf(const T mx, const R_1d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + }; + } + + /* template specialization 2d */ + namespace mt + { + template + class Ptc_xd_0 + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_2d_0; + + R_2d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + + R_2d x_lim; + R_2d y_lim; + + R_2d r_mean; // mean position + R_2d r_std; // standard deviation + R_2d sz; // size + + /************************************* constructors ************************************/ + Ptc_xd_0(): bs(), x_lim(), y_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_xd_0(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_xd_0(const Ptc_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_xd_0(const Ptc_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_xd_0& operator=(const Ptc_xd_0& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_xd_0& operator=(const Ptc_xd_0& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_xd_0& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 2; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + y.clear(); + + x_lim = 0; + y_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + y.push_back(ptc_s.y); + } + + template + void set_bs(const R_2d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + y[ia] = ptc_s.y; + } + + R_2d get_pos(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + void set_pos(const size_type& ia, const R_2d& r) + { + x[ia] = r.x; + y[ia] = r.y; + } + + template + void set_ptc(const Ptc_xd_0& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=2) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(1); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y); + auto last = fcn_mkzipiter_end(this->x, this->y); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = ::fabs(r.x); + r.y = ::fabs(r.y); + + r.x = ::fmin(r.x, ::fabs(r.x-bs.x)); + r.y = ::fmin(r.y, ::fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_2d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia, const T& x, const T& y) const + { + return mt::norm_2(get_pos(ia) - R_2d(x, y)); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia, const T& x, const T& y) const + { + return ::sqrt(this->norm_2(ia, x, y)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_2d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_2d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void apply_ltf(const Mx_2x2& mx, const R_2d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + void rotate(const T& theta, const R_2d& p) + { + mt::fcn_ptc_pos_rotate(theta, p, *this); + } + }; + } + + /* template specialization 3d */ + namespace mt + { + template + class Ptc_xd_0 + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_3d_0; + + R_3d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + mutable Vctr_cpu z; + + R_2d x_lim; // x limits + R_2d y_lim; // y limits + R_2d z_lim; // z limits + + R_3d r_mean; // mean position + R_3d r_std; // standard deviation + R_3d sz; // size + + /************************************* constructors ************************************/ + Ptc_xd_0(): bs(), x_lim(), y_lim(), z_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_xd_0(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_xd_0(const Ptc_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_xd_0(const Ptc_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_xd_0& operator=(const Ptc_xd_0& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_xd_0& operator=(const Ptc_xd_0& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_xd_0& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + z = ptc.z; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + z_lim = ptc.z_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 3; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + y.clear(); + z.clear(); + + x_lim = 0; + y_lim = 0; + z_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + z.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + z.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + z.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + y.push_back(ptc_s.y); + z.push_back(ptc_s.z); + } + + template + void set_bs(const R_3d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + y[ia] = ptc_s.y; + z[ia] = ptc_s.z; + } + + R_3d get_pos(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + void set_pos(const size_type& ia, const R_3d& r) + { + x[ia] = r.x; + y[ia] = r.y; + z[ia] = r.z; + } + + template + void set_ptc(const Ptc_xd_0& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=3) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), z.data(), n_data); // z-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(1); + } + + // sort by z + void sort_by_z() + { + sort_by_idx(2); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(this->x, this->y, this->z); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + r.z = fabs(r.z); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + r.z = ::fmin(r.z, fabs(r.y-bs.z)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_3d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia, const T& x, const T& y, const T& z) const + { + return mt::norm_2(get_pos(ia) - R_3d(x, y, z)); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia, const T& x, const T& y, const T& z) const + { + return ::sqrt(this->norm_2(ia, x, y, z)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_3d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_3d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter_xy(const R_2d& bs) + { + fcn_ptc_pos_recenter_xy(bs, *this); + } + + void recenter_xy() + { + cn_ptc_pos_recenter_xy({bs.x, bs.y}, *this); + } + + void apply_ltf(const Mx_2x2& mx, const R_3d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + void rotate(const T& theta, const R_3d& u_0, const R_3d& p) + { + mt::fcn_ptc_pos_rotate(theta, u_0, p, *this); + } + }; + } + + /* fcns 1d */ + namespace mt + { + template + void fcn_ptc_pos_statistic(Ptc_1d_0& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean, ptc.r_std); + + ptc.sz = ptc.x_lim.y - ptc.x_lim.x; + } + + template + void fcn_ptc_pos_shift(const R_1d& r_sft, Ptc_1d_0& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_1d& bs, Ptc_1d_0& ptc) + { + const R_1d r_sft = (bs-ptc.sz)/T(2) - ptc.x_lim.x; + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const T& mx, const R_1d& p, Ptc_1d_0& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r; + } + + fcn_ptc_pos_statistic(ptc); + } + } + + /* fcns 2d */ + namespace mt + { + template + void fcn_ptc_pos_statistic(Ptc_2d_0& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + fcn_minmax_element(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + + ptc.sz = R_2d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_2d_0& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_2d_0& ptc) + { + const R_2d r_sft = (bs-ptc.sz)/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_2d_0& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_2d_0& ptc) + { + const auto Rm = fcn_rot_mx_2d(theta); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } + } + + /* fcns 3d */ + namespace mt + { + template + void fcn_ptc_pos_statistic(Ptc_3d_0& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + fcn_minmax_element(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + fcn_minmax_element(ptc.z, ptc.z_lim.x, ptc.z_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + fcn_mean_std(ptc.z, ptc.r_mean.z, ptc.r_std.z); + + ptc.sz = R_3d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x, ptc.z_lim.y - ptc.z_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_3d& r_sft, Ptc_3d_0& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + ptc.z[ia] += r_sft.z; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_3d_0& ptc) + { + const R_3d r_sft = (bs-ptc.sz)/T(2) - R_3d(ptc.x_lim.x, ptc.y_lim.x, ptc.z_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_3d_0& ptc) + { + const R_2d r_sft = (bs-R_2d(ptc.sz.x, ptc.sz.y))/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift({r_sft.x, r_sft.y, T(0)}, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_3d_0& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_3d_0& ptc) + { + const auto Rm = fcn_rot_mx_3d(theta, u_0); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } + } + + /* derived class 2d */ + namespace mt + { + /***************************************************************************************/ + /************************************ pos 2d/c1 ****************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 1); // Ptc_s_2d_1 + C_PTC_COEF_DIM_N(2, 1); // Ptc_2d_1 + + /***************************************************************************************/ + /*********************************** pos 2d/c1/c2 **************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 2); // Ptc_s_2d_2 + C_PTC_COEF_DIM_N(2, 2); // Ptc_2d_2 + + /***************************************************************************************/ + /*********************************** pos 2d/c1/c2/c3 ***********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 3); // Ptc_s_2d_3 + C_PTC_COEF_DIM_N(2, 3); // Ptc_2d_3 + + /***************************************************************************************/ + /********************************* pos 2d/c1/c2/c3/c4 **********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 4); // Ptc_s_2d_4 + C_PTC_COEF_DIM_N(2, 4); // Ptc_2d_4 + + /***************************************************************************************/ + /******************************** pos 2d/c1/c2/c3/c4/c5 ********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 5); // Ptc_s_2d_5 + C_PTC_COEF_DIM_N(2, 5); // Ptc_2d_5 + + } + + /* derived class 3d */ + namespace mt + { + /***************************************************************************************/ + /************************************** pos 3d/c1 **************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 1); // Ptc_s_3d_1 + C_PTC_COEF_DIM_N(3, 1); // Ptc_3d_1 + + /***************************************************************************************/ + /************************************* pos 3d/c1/c2 ************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 2); // Ptc_s_3d_2 + C_PTC_COEF_DIM_N(3, 2); // Ptc_3d_2 + + /***************************************************************************************/ + /*********************************** pos 3d/c1/c2/c3 ***********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 3); // Ptc_s_3d_3 + C_PTC_COEF_DIM_N(3, 3); // Ptc_3d_3 + + /***************************************************************************************/ + /********************************** pos 3d/c1/c2/c3/c4 *********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 4); // Ptc_s_3d_4 + C_PTC_COEF_DIM_N(3, 4); // Ptc_3d_4 + + /***************************************************************************************/ + /******************************** pos 3d/c1/c2/c3/c4/c5 ********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 5); // Ptc_s_3d_5 + C_PTC_COEF_DIM_N(3, 5); // Ptc_3d_5 + } + + /********************************* atomic particles ************************************/ + namespace mt + { + /******************************* forward declarations **********************************/ + template + class Ptc_Atom; + + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& atoms); + + /***************************************************************************************/ + template + class Ptc_s_Atom: public Ptc_s_3d_0 + { + public: + dt_int32 Z; + dt_float32 sigma; + dt_float32 occ; + dt_int32 tag; + dt_int32 charge; + + Ptc_s_Atom():Z(0), Ptc_s_3d_0(), sigma(0), occ(0), tag(0), charge(0) {}; + + Ptc_s_Atom(const dt_int32& Z, const T& x, const T& y, const T& z, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge): + Z(Z), Ptc_s_3d_0(x, y, z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + Ptc_s_Atom(const dt_int32& Z, const R_3d& r, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge): + Z(Z), Ptc_s_3d_0(r.x, r.y, r.z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + /* constructor by pointer */ + template + Ptc_s_Atom(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + Z = dt_int32(v[ip + 0*n_r]); // atomic number + this->x = (n_c>1)?T(v[ip + 1*n_r]):T(0); // x-position + this->y = (n_c>2)?T(v[ip + 2*n_r]):T(0); // y-position + this->z = (n_c>3)?T(v[ip + 3*n_r]):T(0); // z-position + + sigma = (n_c>4)?dt_float32(v[ip + 4*n_r]):c_dflt_rms3d; // standard deviation + occ = (n_c>5)?dt_float32(v[ip + 5*n_r]):c_dflt_occ; // occupancy + tag = (n_c>6)?dt_int32(v[ip + 6*n_r]):c_dflt_tag; // tag + charge = (n_c>7)?dt_int32(v[ip + 7*n_r]):c_dflt_charge; // charge + } + + /* copy constructor */ + Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /* converting constructor */ + template + Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /******************************** assignment operators *********************************/ + // ! copy assignment operator + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s) + { + if (this != &ptc_s) + { + Z = ptc_s.Z; + this->x = ptc_s.x; + this->y = ptc_s.y; + this->z = ptc_s.z; + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + + return *this; + } + + /* converting assignment operator */ + template + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s) + { + assign(ptc_s); + + return *this; + } + + template + void assign(const Ptc_s_Atom& ptc_s) + { + if ((void*)this != (void*)&ptc_s) + { + Z = ptc_s.Z; + this->x = T(ptc_s.x); + this->y = T(ptc_s.y); + this->z = T(ptc_s.z); + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + } + }; + + template + class Ptc_Atom: public Ptc_3d_0 + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_Atom; + + mutable Vctr_cpu Z; // atomic number + mutable Vctr_cpu sigma; // 3d root fcn_mean squared displacement (rmsd) + mutable Vctr_cpu occ; // occupancy + mutable Vctr_cpu tag; // tag + mutable Vctr_cpu charge; // charge + + dt_int32 cols_used; // number of used columns + + R_2d Z_lim; + R_2d sigma_lim; + R_2d occ_lim; + R_2d tag_lim; + R_2d charge_lim; + + /************************************* constructors ************************************/ + Ptc_Atom(): Ptc_3d_0(), cols_used(4), Z_lim(), sigma_lim(), occ_lim(), tag_lim(), charge_lim() {} + + template + Ptc_Atom(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* assignment operator */ + Ptc_Atom& operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_Atom& operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_Atom& ptc) + { + if ((void*)this != (void*)&ptc) + { + cols_used = ptc.cols_used; + + Z = ptc.Z; + + Ptc_3d_0::assign(ptc); + + sigma = ptc.sigma; + occ = ptc.occ; + tag = ptc.tag; + charge = ptc.charge; + + Z_lim = ptc.Z_lim; + sigma_lim = ptc.sigma_lim; + occ_lim = ptc.occ_lim; + tag_lim = ptc.tag_lim; + charge_lim = ptc.charge_lim; + } + } + + /***************************************************************************************/ + virtual size_type cols() const + { + return 8; + } + + void clear() + { + cols_used = 4; + + Z.clear(); + + Ptc_3d_0::clear(); + + sigma.clear(); + occ.clear(); + tag.clear(); + charge.clear(); + + Z_lim = 0; + sigma_lim = 0; + occ_lim = 0; + tag_lim = 0; + charge_lim = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.resize(new_size); + + Ptc_3d_0::resize(new_size); + + if (cols_used>4) + sigma.resize(new_size); + + if (cols_used>5) + occ.resize(new_size); + + if (cols_used>6) + tag.resize(new_size); + + if (cols_used>7) + charge.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.reserve(new_size); + + Ptc_3d_0::reserve(new_size); + + if (cols_used>4) + sigma.reserve(new_size); + + if (cols_used>5) + occ.reserve(new_size); + + if (cols_used>6) + tag.reserve(new_size); + + if (cols_used>7) + charge.reserve(new_size); + } + + void shrink_to_fit() + { + Z.shrink_to_fit(); + + Ptc_3d_0::shrink_to_fit(); + + sigma.shrink_to_fit(); + occ.shrink_to_fit(); + tag.shrink_to_fit(); + charge.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + Z.push_back(ptc_s.Z); // atomic number + + Ptc_3d_0::push_back(ptc_s); // xyz + + if (cols_used>4) + sigma.push_back(ptc_s.sigma); // standard deviation + + if (cols_used>5) + occ.push_back(ptc_s.occ); // occupancy + + if (cols_used>6) + tag.push_back(abs(ptc_s.tag)); // tag + + if (cols_used>7) + charge.push_back(ptc_s.charge); // charge + } + + dt_float32 get_sigma(const size_type& ia) const + { + return (cols_used>4)?sigma[ia]:c_dflt_rms3d; // standard deviation + } + + dt_float32 get_occ(const size_type& ia) const + { + return (cols_used>5)?occ[ia]:c_dflt_occ; // occupancy + } + + dt_int32 get_tag(const size_type& ia) const + { + return (cols_used>6)?tag[ia]:c_dflt_tag; // tag + } + + dt_int32 get_charge(const size_type& ia) const + { + return (cols_used>7)?charge[ia]:c_dflt_charge; // charge + } + + Ptc_s get(const size_type& ia) const + { + return {Z[ia], this->x[ia], this->y[ia], this->z[ia], get_sigma(ia), get_occ(ia), get_tag(ia), get_charge(ia)}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + Z[ia] = ptc_s.Z; // atomic number + + Ptc_3d_0::set(ia, ptc_s); // xyz + + if (cols_used>4) // standard deviation + sigma[ia] = ptc_s.sigma; + + if (cols_used>5) // occupancy + occ[ia] = ptc_s.occ; + + if (cols_used>6) // tag + tag[ia] = ptc_s.tag; + + if (cols_used>7) // charge + charge[ia] = ptc_s.charge; + } + + template + void set_ptc(const Ptc_Atom& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + cols_used = ptc.cols_used; + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + cols_used = ptc.s1_32(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, 0, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=8) + { + is_e = min(is_e, cols_used); + + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, this->size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), Z.data(), n_data); // atomic number + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->x.data(), n_data); // x-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->y.data(), n_data); // y-position + + if (fcn_chk_bound(3, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->z.data(), n_data); // z-position + + if (fcn_chk_bound(4, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), sigma.data(), n_data); // standard deviation + + if (fcn_chk_bound(5, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), occ.data(), n_data); // occupancy + + if (fcn_chk_bound(6, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), tag.data(), n_data); // tag + + if (fcn_chk_bound(7, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), charge.data(), n_data); // charge + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(1); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(2); + } + + // sort by z + void sort_by_z() + { + sort_by_idx(3); + } + + // sort by idx + void sort_by_idx(const dt_int32 idx = 3) + { + if (cols_used==4) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z); + + switch(idx) + { + SWITCH_1_3D(CASE_SORT) + } + } + else if (cols_used==5) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma); + + switch(idx) + { + SWITCH_2_3D(CASE_SORT) + } + } + else if (cols_used==6) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ); + + switch(idx) + { + SWITCH_3_3D(CASE_SORT) + } + } + else if (cols_used==7) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag); + + switch(idx) + { + SWITCH_4_3D(CASE_SORT) + } + } + else if (cols_used==8) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + + switch(idx) + { + SWITCH_5_3D(CASE_SORT) + } + } + } + + + /***************************************************************************************/ + virtual void get_statistic() + { + if (this->empty()) + { + return; + } + + mt::fcn_minmax_element(Z, Z_lim.x, Z_lim.y); + + Ptc_3d_0::get_statistic(); + + sigma_lim.x = c_dflt_rms3d; + sigma_lim.y = c_dflt_rms3d; + if (cols_used>4) + mt::fcn_minmax_element(sigma, sigma_lim.x, sigma_lim.y); + + occ_lim.x = c_dflt_occ; + occ_lim.y = c_dflt_occ; + if (cols_used>5) + mt::fcn_minmax_element(occ, occ_lim.x, occ_lim.y); + + tag_lim.x = c_dflt_tag; + tag_lim.y = c_dflt_tag; + if (cols_used>6) + mt::fcn_minmax_element(tag, tag_lim.x, tag_lim.y); + + charge_lim.x = c_dflt_charge; + charge_lim.y = c_dflt_charge; + if (cols_used>7) + mt::fcn_minmax_element(tag, charge_lim.x, charge_lim.y); + + this->bs.z = ::fmax(this->sz.z, this->bs.z); + } + + // max z value within a tag + void minmax_z_by_region(const T& tag_v, T& z_min, T& z_max) + { + z_min = 1e20; + z_max = -1e20; + for(auto iz = 0; iz < this->size(); iz++) + { + if (tag[iz]==tag_v) + { + z_max = ::fmax(z_max, this->z[iz]); + z_min = ::fmin(z_min, this->z[iz]); + } + } + } + + void remove_ptc_out_z_range(const T& z_0, const T& z_e) + { + mt::remove_ptc_out_z_range(z_0, z_e, *this); + } + }; + + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& ptc) + { + dt_int32 ia_z = 0; + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + if (fcn_chk_bound(ptc.z[ia], z_0, z_e)) + { + ptc.Z[ia_z] = ptc.Z[ia]; + ptc.x[ia_z] = ptc.x[ia]; + ptc.y[ia_z] = ptc.y[ia]; + ptc.z[ia_z] = ptc.z[ia]; + + if (ptc.cols_used>4) + ptc.sigma[ia_z] = ptc.sigma[ia]; + + if (ptc.cols_used>5) + ptc.occ[ia_z] = ptc.occ[ia]; + + if (ptc.cols_used>6) + ptc.tag[ia_z] = ptc.tag[ia]; + + if (ptc.cols_used>7) + ptc.charge[ia_z] = ptc.charge[ia]; + + ia_z++; + } + } + + ptc.resize(ia_z); + ptc.shrink_to_fit(); + } + + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/peak_finding.cuh b/src - Copy (2)/peak_finding.cuh new file mode 100755 index 00000000..a0172a75 --- /dev/null +++ b/src - Copy (2)/peak_finding.cuh @@ -0,0 +1,1891 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PEAK_FINDING_H + #define PEAK_FINDING_H + + #include + #include + + #include + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_stream.cuh" + #include "lapack.hpp" + #include "box_occ.hpp" + #include "cgpu_classes.cuh" + #include "cpu_fcns_image.hpp" + + namespace mt + { + template + class Peak_Finding + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using size_type = dt_uint64; + + Peak_Finding(): sigma(1.0), thres(0.5), niter(10), d_error(1e-3), + image_mean(0), image_std(1), radius_n(6*sigma), ref_mean(500), ref_std(80) {}; + + Peak_Finding(Grid_2d& grid_i, TVctr_r &image_i, T sigma_i, T thres_i, dt_int32 niter_i) + { + operator()(grid_i, image_i, sigma_i, thres_i, niter_i); + } + + void cleanup() + { + fft_2d.cleanup(); + } + + void operator()(Grid_2d& grid_i, TVctr_r &image_i, T sigma_i, T thres_i, dt_int32 niter_i) + { + grid_2d = grid_i; + sigma = sigma_i; + thres = thres_i; + niter = niter_i; + d_error = 1e-4; + + ref_mean = 500; + ref_std = 80; + radius_n = 6*sigma; + + stream.resize(4); + fft_2d.create_plan_2d(grid_2d.ny, grid_2d.nx, stream.size()); + + // image_mean and image_std are defined here + image = scale_in_image(stream, image_i); + } + + void find() + { + // denoise im + dt_int32 nkr_w = max(1, static_cast(::floor(sigma/2+0.5))); + dt_int32 nkr_m = max(1, static_cast(::floor(sigma/3+0.5))); + image_den = fltr_poiss_nois_2d(stream, grid_2d, image, nkr_w, nkr_m); + + // get peak signal to noise ratio + auto PSNR = fcn_get_psnr(stream, image, image_den); + + // deconvolute in image + auto image_dcon = image; + Gauss_Dcv_2d gauss_dcv_2d(&stream, &fft_2d, grid_2d); + gauss_dcv_2d(sigma, PSNR, image_dcon); + + thrust::for_each(image_dcon.begin(), image_dcon.end(), [&](T& v){ v = (v<0)?0:v; }); + + // get background + dt_int32 nkr = static_cast(::round(5.0*sigma/grid_2d.dR_min())); + auto image_thr = fcn_morp_op_open(stream, grid_2d.ny, grid_2d.nx, image_dcon, nkr); + + Gauss_Cv_2d gauss_cv_2d(&stream, &fft_2d, grid_2d); + gauss_cv_2d(sigma, image_thr); + + // background substraction + thrust::transform(image_dcon.begin(), image_dcon.end(), image_thr.begin(), + image_thr.begin(), [](const T& a, const T&b){ return ::fmax(a-b, T(0)); }); + + // fast peak finding + fast_peak_finding(stream, image_thr, x, y); + + // deleting close neighbors + neigh.delete_points(x, y, grid_2d); + + // set output data + A.resize(x.size()); + std::fill(A.begin(), A.end(), T(0)); + + A_min.resize(x.size()); + std::fill(A_min.begin(), A_min.end(), T(0)); + + A_max.resize(x.size()); + std::fill(A_max.begin(), A_max.end(), T(0)); + + S.resize(x.size()); + std::fill(S.begin(), S.end(), T(0)); + + S_min.resize(x.size()); + std::fill(S_min.begin(), S_min.end(), T(0)); + + S_max.resize(x.size()); + std::fill(S_max.begin(), S_max.end(), T(0)); + + bg = 0; + + dt_int32 ibor = max(10, grid_2d.r_2_ir_cds_dr_min(3*sigma)); + range_ct.ix_0 = ibor; + range_ct.ix_e = grid_2d.nx-ibor; + range_ct.iy_0 = ibor; + range_ct.iy_e = grid_2d.ny-ibor; + } + + void fit() + { + // get neighbors + neigh(stream, x, y, radius_n); + + // get image mask + mask = get_mask(stream, neigh, x, y); + + // set bg values + T bg_min, bg_max; + set_init_bg_values(stream, mask, image_den, x, y, bg, bg_min, bg_max); + + // set A values + set_init_A_values(stream, image_den, neigh, x, y, A, A_min, A_max, bg); + + // get first approximations + S = fit_b_0(stream, mask, image, x, y, A, sigma, bg, 15, d_error); + A = fit_a_0(stream, mask, image, x, y, A, A_min, A_max, S, bg); + + for(auto ipk = 0; ipk < x.size(); ipk++) + { + S_min[ipk] = ::fmax(0.5*grid_2d.dR_min(), 0.25*S[ipk]); + S_max[ipk] = ::fmin(0.9*neigh.d_min(ipk), 1.5*S[ipk]); + } + + region.set(stream, grid_2d, image, neigh, x, y, 1, 1); + for(auto it = 0; it < 1; it++) + { + fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + } + + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // for(auto it = 0; it < 3; it++) + // { + // fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + // } + // bg = fit_c_0(stream, image, x, y, A, S, bg, bg_min, bg_max); + + for(auto it = 0; it < niter; it++) + { + region.set(stream, grid_2d, image, neigh, x, y, 1, 0.4); + fit_x_y_0(stream, region, x, y, A, S, bg, 10, d_error); + + region.set(stream, grid_2d, image, neigh, x, y, 1, 1); + fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + } + + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // fit_a_b_x_y_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // for(auto it = 0; it < 3; it++) + // { + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // fit_a_b_x_y_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // } + // neigh(stream, x, y, radius_n); + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // fit_a_b_x_y(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // fit_a_b_x_y_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + } + + void get_data(TVctr_r &x_o, TVctr_r &y_o, TVctr_r &A_o, TVctr_r &S_o, T& bg_o) + { + dt_int32 npeaks = x.size(); + + x_o.resize(npeaks); + y_o.resize(npeaks); + A_o.resize(npeaks); + S_o.resize(npeaks); + + T sf = ref_std/image_std; + for(auto idx=0; idx& grid_2d, TVctr_r &Im_s, T x, T y) + { + TVctr_r v = Ixy; + + T R2_max = pow(R_max, 2); + + R_2d p(x, y); + auto range = grid_2d.region_ind(p, R_max); + dt_int32 iv = 0; + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + v[iv++] -= Im_s[grid_2d.sub_2_ind(ix, iy)]/Ixy_sc; + } + } + } + return v; + } + + TVctr_r sft_Ixy(Grid_2d& grid_2d, TVctr_r &Im_s, T x, T y, T a, T s) + { + TVctr_r v = sub_region_to_Ixy(grid_2d, Im_s, x*Rxy_sc+Rx_sf, y*Rxy_sc+Ry_sf); + + T alpha = 0.5/pow(s, 2); + T r2_l = pow(4.0*s, 2); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x; + T ry = Ry[im]-y; + T r2 = rx*rx+ry*ry; + if (r2& grid_2d, TVctr_r &Im_s, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + TVctr_r v = sub_region_to_Ixy(grid_2d, Im_s, x[0]*Rxy_sc+Rx_sf, y[0]*Rxy_sc+Ry_sf); + + for(auto ip = 0; ip < x.size(); ip++) + { + T a = A[ip]; + T b = S[ip]; + T alpha = 0.5/pow(b, 2); + T r2_l = pow(4.0*b, 2); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x[ip]; + T ry = Ry[im]-y[ip]; + T r2 = rx*rx+ry*ry; + if (r2 sft_x_y(T x, T y) const + { + x = sft_Rx(x); + y = sft_Ry(y); + return R_2d(x, y); + } + }; + + struct Regions + { + public: + using size_type = dt_uint64; + + dt_int32 m_max; + dt_int32 n_max; + Regions():m_max(1), n_max(1) {} + + size_type size() const + { + return reg.size(); + } + + void set(Stream& stream, const Grid_2d& grid_i, TVctr_r &Im_i, + Neigh_2d& neigh, TVctr_r &x, TVctr_r &y, dt_int32 iradius=1, T ff=0.5) + { + grid_2d = grid_i; + reg.resize(x.size()); + T R_min = 3.1*grid_2d.dR_min(); + + auto sel_radius = [&neigh, R_min, ff](dt_int32 ipk, dt_int32 iradius)->T + { + T radius = 0; + switch (iradius) + { + case 1: + radius = ::fmax(R_min, ff*neigh.d_min(ipk)); + break; + case 2: + radius = neigh.d_max(ipk) + ff*neigh.d_min(ipk); + break; + } + return radius; + }; + + auto thr_select_cir_reg = [&](const iThread_Rect_2d& range) + { + for(auto ipk = range.ind_0; ipk < range.ind_e; ipk++) + { + R_2d p(x[ipk], y[ipk]); + T radius = sel_radius(ipk, iradius); + reg[ipk] = select_cir_reg(Im_i, p, radius); + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_select_cir_reg); + + T d_max = 0; + n_max = 1; + for(auto ipk = 0; ipk < x.size(); ipk++) + { + T radius = sel_radius(ipk, iradius); + d_max = max(d_max, radius); + n_max = max(n_max, neigh.size(ipk)); + } + d_max += 3*grid_i.dR_min(); + m_max = static_cast(std::round(c_pi*pow(d_max, 2)/pow(grid_i.dR_min(), 2))); + } + + Region_Rad_2d& operator[](const dt_int32 i){ return reg[i]; } + + const Region_Rad_2d& operator[](const dt_int32 i) const { return reg[i]; } + private: + vector reg; + Grid_2d grid_2d; + + Region_Rad_2d select_cir_reg(TVctr_r &Im, R_2d p, T radius) + { + T R_max = radius; + T R2_max = pow(R_max, 2); + + auto range = grid_2d.region_ind(p, R_max); + + Region_Rad_2d region; + region.clear(); + region.reserve(range.ind_e); + + // select circular region + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2_d = grid_2d.r2(ix, iy, p.x, p.y); + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + if (r2_d < R2_max) + { + region.Rx.push_back(grid_2d.rx(ix)); + region.Ry.push_back(grid_2d.ry(iy)); + region.R2.push_back(r2_d); + region.Ixy.push_back(Im[ixy]); + } + } + } + + region.R_max = R_max; + region.Rx_sf = p.x; + region.Ry_sf = p.y; + region.Rxy_sc = R_max; + + // really important that Ixy_mean is zero if not + // we have to change our reference system to fit the parameters + region.Ixy_sf = 0; + region.Ixy_sc = sqrt(fcn_variance(region.Ixy)); + // shift and fcn_scale + dt_int32 m = region.Ixy.size(); + for(auto ixy = 0; ixy < m; ixy++) + { + region.Rx[ixy] = (region.Rx[ixy]-region.Rx_sf)/region.Rxy_sc; + region.Ry[ixy] = (region.Ry[ixy]-region.Ry_sf)/region.Rxy_sc; + region.R2[ixy] = region.R2[ixy]/pow(region.Rxy_sc, 2); + region.Ixy[ixy] = (region.Ixy[ixy]-region.Ixy_sf)/region.Ixy_sc; + } + + region.shrink_to_fit(); + return region; + } + }; + + TVctr_r scale_in_image(Stream& stream, TVctr_r &image_i) + { + fcn_mean_var(stream, image_i, image_mean, image_std); + image_std = sqrt(image_std); + + auto thr_scale = [=](const iThread_Rect_2d& range, TVctr_r &image_i, TVctr_r &image_o) + { + for(auto ixy = range.ind_0; ixy < range.ind_e; ixy++) + { + T v = image_i[ixy]; + v = (v-image_mean)/image_std; + v = v*ref_std + ref_mean; + image_o[ixy] = ::fmax(v, 4); + } + }; + + TVctr_r image_o(image_i.size()); + stream.set_n_stream_act(grid_2d.nx); + stream.set_grid(grid_2d.nx, grid_2d.ny); + stream.exec(thr_scale, image_i, image_o); + + return image_o; + } + + void fast_peak_finding(Stream& stream, TVctr_r &image, TVctr_r &x, TVctr_r &y) + { + auto Im_minmax = fcn_minmax_element(image.begin(), image.end()); + + T thres_n = *(Im_minmax.first) + thres*(*(Im_minmax.second)-*(Im_minmax.first)); + + image = fcn_threshold_max(stream, image, thres_n); + + // local maximum + auto krn_maximum = [thres_n](const dt_int32& ix, const dt_int32& iy, Grid_2d& grid_2d, TVctr_r &Im, R_2d& peak)->dt_bool + { + auto v = Im[grid_2d.sub_2_ind(ix, iy)]; + peak = R_2d(grid_2d.rx(ix), grid_2d.ry(iy)); + + if (v <= thres_n) + { + return false; + } + + T v1 = Im[grid_2d.sub_2_ind(ix-1, iy-1)]; + T v2 = Im[grid_2d.sub_2_ind(ix, iy-1)]; + T v3 = Im[grid_2d.sub_2_ind(ix+1, iy-1)]; + + T v4 = Im[grid_2d.sub_2_ind(ix-1, iy)]; + T v6 = Im[grid_2d.sub_2_ind(ix+1, iy)]; + + T v7 = Im[grid_2d.sub_2_ind(ix-1, iy+1)]; + T v8 = Im[grid_2d.sub_2_ind(ix, iy+1)]; + T v9 = Im[grid_2d.sub_2_ind(ix+1, iy+1)]; + + T v_s = v1+v2+v3+v4+v+v6+v7+v8+v9; + + T x1 = grid_2d.rx(ix-1); + T x2 = grid_2d.rx(ix); + T x3 = grid_2d.rx(ix+1); + + T y1 = grid_2d.ry(iy-1); + T y2 = grid_2d.ry(iy); + T y3 = grid_2d.ry(iy+1); + + T x = v1*x1 + v2*x2 + v3*x3 + v4*x1 + v*x2 + v6*x3 + v7*x1 + v8*x2 + v9*x3; + T y = v1*y1 + v2*y2 + v3*y3 + v4*y1 + v*y2 + v6*y3 + v7*y1 + v8*y2 + v9*y3; + peak = R_2d(x, y)/v_s; + + return (v1<=v) && (v2<=v) && (v3<=v) && (v4<=v) && (v6<=v) && (v7<=v) && (v8<=v) && (v9<=v); + }; + + auto npeaks_m = static_cast(::ceil(grid_2d.bs_x*grid_2d.bs_y/(c_pi*sigma*sigma))); + + x.reserve(2*npeaks_m); + y.reserve(2*npeaks_m); + + // get local peaks + auto thr_peaks = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, TVctr_r &image, TVctr_r &x_o, TVctr_r &y_o) + { + TVctr_r x; + x.reserve(npeaks_m); + + TVctr_r y; + y.reserve(npeaks_m); + + auto ix_0 = 1 + range.ix_0; + auto ix_e = 1 + range.ix_e; + auto iy_0 = 1 + range.iy_0; + auto iy_e = 1 + range.iy_e; + + for(auto ix = ix_0; ix < ix_e; ix++) + { + for(auto iy = iy_0; iy < iy_e; iy++) + { + R_2d peak; + if (krn_maximum(ix, iy, grid_2d, image, peak)) + { + x.push_back(peak.x); + y.push_back(peak.y); + } + } + } + + stream.stream_mutex.lock(); + x_o.insert(x_o.end(), x.begin(), x.end()); + y_o.insert(y_o.end(), y.begin(), y.end()); + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(grid_2d.nx-2); + stream.set_grid(grid_2d.nx-2, grid_2d.ny-2); + stream.exec(thr_peaks, grid_2d, image, x, y); + + x.shrink_to_fit(); + y.shrink_to_fit(); + } + + void set_init_bg_values(Stream& stream, vector& mask, TVctr_r &image, + TVctr_r &x, TVctr_r &y, T& bg, T& bg_min, T& bg_max) + { + T R_max = 2.5*grid_2d.dR_min(); + T peak_min = image[grid_2d.rv_2_ir_bfds(x[0], y[0])]; + + auto get_mean_peak = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, const TVctr_r &image)->T + { + T R2_max = pow(R_max, 2); + auto range = grid_2d.region_ind(p, R_max); + T Ixy_mean = 0; + dt_int32 n_Ixy_mean = 0; + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + Ixy_mean += image[grid_2d.sub_2_ind(ix, iy)]; + n_Ixy_mean++; + } + } + } + Ixy_mean /= n_Ixy_mean; + return Ixy_mean; + }; + + auto thr_min_peak = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, vector& mask, TVctr_r &image, + TVctr_r &x, TVctr_r &y, T& peak_min) + { + T peak_min_t = 100*image[grid_2d.rv_2_ir_bfds(x[0], y[0])]; + for(auto ipk=range.ind_0; ipk p(x[ipk], y[ipk]); + if (mask[grid_2d.rv_2_ir_bfds(p.x, p.y)]) + { + peak_min_t = ::fmin(peak_min_t, get_mean_peak(p, R_max, grid_2d, image)); + } + } + stream.stream_mutex.lock(); + peak_min = ::fmin(peak_min, peak_min_t); + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_min_peak, grid_2d, mask, image, x, y, peak_min); + + // fcn_mean bellow thr + T I_min = 0; + T I_mean = 0; + T I_std = 0; + T I_low = 0; + for(auto it=0; it<2; it++) + { + I_min = peak_min; + T I_sum = 0; + T I_sum_ee = 0; + T I_sum2 = 0; + T I_sum2_ee = 0; + dt_int32 I_c = 0; + for(auto ix = range_ct.ix_0; ix < range_ct.ix_e; ix++) + { + for(auto iy = range_ct.iy_0; iy < range_ct.iy_e; iy++) + { + T v = image[grid_2d.sub_2_ind(ix, iy)]; + if ((v < peak_min) && (I_low < v)) + { + fcn_kh_sum(I_sum, v, I_sum_ee); + fcn_kh_sum(I_sum2, v*v, I_sum2_ee); + I_min = ::fmin(I_min, v); + I_c++; + } + } + } + I_mean = I_sum/I_c; + I_std = sqrt(fabs(I_sum2/I_c-I_mean*I_mean)); + peak_min = I_mean; + I_low = I_mean-3*I_std; + } + bg = ::fmax(0, I_mean - I_std); + // bg_o = (0-image_mean)*sf + ref_mean; + bg_min = ::fmax(I_mean-4*I_std, I_min-0.5*I_std); + bg_max = I_mean+0.5*I_std; + } + + void set_init_A_values(Stream& stream, TVctr_r &image, Neigh_2d& neigh, + TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max, T Bg) + { + auto thr_A_values = [Bg](const iThread_Rect_2d& range, Grid_2d& grid_2d, TVctr_r &image, + Neigh_2d& neigh, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max) + { + auto get_A_values = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, + const TVctr_r &image, T& A, T& A_min, T& A_max) + { + T R2_max = pow(R_max, 2); + T R2_peak_max = pow(1.75*grid_2d.dR_min(), 2); + + auto range = grid_2d.region_ind(p, R_max); + + T Ixy_min = image[grid_2d.rv_2_ir_bfds(p.x, p.y)]; + + T Ixy_peak = 0; + dt_int32 Ixy_peak_c = 0; + + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + T v = image[grid_2d.sub_2_ind(ix, iy)]; + Ixy_min = (v p(x[ipk], y[ipk]); + T R_max = neigh.d_min(ipk); + get_A_values(p, R_max, grid_2d, image, A[ipk], A_min[ipk], A_max[ipk]); + A[ipk] -= Bg; + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_A_values, grid_2d, image, neigh, x, y, A, A_min, A_max); + } + + vector get_mask(Stream& stream, TVctr_r &x, TVctr_r &y, TVctr_r &S) + { + vector image(grid_2d.size(), false); + + auto set_area = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, vector& image) + { + T R2_max = pow(R_max, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + image[grid_2d.sub_2_ind(ix, iy)] = true; + } + } + } + }; + + auto thr_area = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, TVctr_r &x, TVctr_r &y, TVctr_r &S, vector& image) + { + for(auto ipk = range.ind_0; ipk < range.ind_e; ipk++) + { + R_2d p(x[ipk], y[ipk]); + T R_max = 3.5*S[ipk]; + set_area(p, R_max, grid_2d, image); + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_area, grid_2d, x, y, S, image); + + return image; + } + + vector get_mask(Stream& stream, Neigh_2d& neigh, TVctr_r &x, TVctr_r &y) + { + vector image(grid_2d.size(), false); + + auto set_area = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, vector& image) + { + T R2_max = pow(R_max, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + image[grid_2d.sub_2_ind(ix, iy)] = true; + } + } + } + }; + + auto thr_area = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, Neigh_2d& neigh, TVctr_r &x, TVctr_r &y, vector& image) + { + for(auto ipk=range.ind_0; ipk p(x[ipk], y[ipk]); + T R_max = neigh.d_min(ipk); + set_area(p, R_max, grid_2d, image); + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_area, grid_2d, neigh, x, y, image); + + // left + for(auto ix = 0; ix < range_ct.ix_0; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + // right + for(auto ix = range_ct.ix_e; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + // top + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < range_ct.iy_0; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + // bottom + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = range_ct.iy_e; iy < grid_2d.ny; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + return image; + } + + void set_mask_and_scale(Stream& stream, vector& mask, + TVctr_r &image, TVctr_r &image_m, T& image_m_sc) + { + image_m.resize(image.size()); + T image_sum = 0; + T image2_sum = 0; + dt_int32 c_image_sum = 0; + + // mask image + auto thr_mask = [&](const iThread_Rect_2d& range, TVctr_r &image, + TVctr_r &image_m, dt_int32& c_image_sum, T& image_sum, T& image2_sum) + { + // set mask and get fcn_mean and std + T im_sum = 0; + T im_sum_ee = 0; + T im2_sum = 0; + T im2_sum_ee = 0; + dt_int32 c_sum = 0; + for(auto ixy = range.ind_0; ixy& mask, TVctr_r &image) + { + for(auto ixy = range.ind_0; ixy& stream, TVctr_r &image, TVctr_r &image_m, T& image_m_sc) + { + image_m.resize(image.size()); + + image_m_sc = sqrt(fcn_variance(stream, image)); + + auto thr_sft_scale = [image_m_sc](const iThread_Rect_2d& range, TVctr_r &image, TVctr_r &image_m) + { + for(auto ixy = range.ind_0; ixysig_u))?s_mean:S[ipk]; + } + } + + TVctr_r gauss_sp(Stream& stream, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &S, T Bg) + { + auto thr_gauss_sp = [&stream](const Grid_2d& grid_2d, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S, T Bg) + { + dt_int32 m = grid_2d.size(); + TVctr_r Ixy(m, Bg); + + auto thr_gauss_sup = [&](const iThread_Rect_2d& range, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + auto gaussian = [](R_2d p, T a, T b, T R_max, const Grid_2d& grid_2d, TVctr_r &Ixy) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + Ixy[grid_2d.sub_2_ind(ix, iy)] += a*exp(-c_alpha*r2); + } + } + } + }; + + TVctr_r Ixy_p(m, T(0)); + for(auto ip = range.ind_0; ip < range.ind_e; ip++) + { + R_2d p(x[ip], y[ip]); + T a = A[ip]; + T b = S[ip]; + T R_max = 4.0*b; + gaussian(p, a, b, R_max, grid_2d, Ixy_p); + } + + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + Ixy[ixy] += Ixy_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup, x, y, A, S); + return Ixy; + }; + + return thr_gauss_sp(grid_2d, x, y, A, S, Bg); + }; + + TVctr_r fit_b_0(Stream& stream, vector& mask, TVctr_r &image, + TVctr_r x, TVctr_r y, TVctr_r A, T S, T Bg, dt_int32 niter, T d_error) + { + // mask and scaling + TVctr_r Ixy; + T Ixy_sc; + set_mask_and_scale(stream, mask, image, Ixy, Ixy_sc); + + const T factor = 2; + T Rxy_sc = grid_2d.bs_max()/factor; + + Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.bs_x/Rxy_sc, grid_2d.bs_y/Rxy_sc); + + // scaling + for(auto ip = 0; ip& grid_2d, vector& mask, TVctr_r &Ixy, + TVctr_r &x, TVctr_r &y, TVctr_r &A, T& b, T b_min, T b_max, dt_int32 niter, T d_error) + { + auto dgaussian = [&mask](R_2d p, T a, T b, T R_max, const Grid_2d& grid_2d, TVctr_r &J, TVctr_r &d_Ixy) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + T c_a = a/pow(b, 3); + auto range = grid_2d.region_ind(p, R_max); + + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + if ((r2 < R2_max) && mask[ixy]) + { + T f = exp(-c_alpha*r2); + J[ixy] += c_a*r2*f; + d_Ixy[ixy] += a*f; + } + } + } + }; + + auto solve_d_b = [&mask](TVctr_r &J, TVctr_r &d_Ixy)->T + { + T sxx = 0; + T sxx_ee = 0; + T sxy = 0; + T sxy_ee = 0; + for(auto ixy = 0; ixy < d_Ixy.size(); ixy++) + { + if (mask[ixy]) + { + T x = J[ixy]; + T y = d_Ixy[ixy]; + + fcn_kh_sum(sxx, x*x, sxx_ee); + fcn_kh_sum(sxy, x*y, sxy_ee); + } + } + + return sxy/sxx; + }; + + dt_int32 m = Ixy.size(); + TVctr_r d_Ixy(m); + TVctr_r J(m); + for(auto iter = 0; iter p(x[ip], y[ip]); + T a = A[ip]; + T R_max = 4.0*b; + dgaussian(p, a, b, R_max, grid_2d, J_p, d_Ixy_p); + } + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + J[ixy] += J_p[ixy]; + d_Ixy[ixy] -= d_Ixy_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup); + + T d_b = solve_d_b(J, d_Ixy); + + b += d_b; + + b = min(max(b_min, b), b_max); + + if (fabs(d_b/b)& stream, vector& mask, TVctr_r &image, + TVctr_r x, TVctr_r y, TVctr_r A, TVctr_r &A_min, TVctr_r &A_max, TVctr_r S, T Bg) + { + // mask and scaling + TVctr_r Ixy; + T Ixy_sc; + set_mask_and_scale(stream, mask, image, Ixy, Ixy_sc); + + const T factor = 2; + T Rxy_sc = grid_2d.bs_max()/factor; + + Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.bs_x/Rxy_sc, grid_2d.bs_y/Rxy_sc); + + // scaling + for(auto ip = 0; ip& grid_2d, vector& mask, TVctr_r &Ixy, + TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + auto dgaussian = [&mask](R_2d p, T a, T b, T R_max, const Grid_2d& grid_2d, TVctr_r &J) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + if ((r2 < R2_max) && mask[ixy]) + { + J[ixy] += a*exp(-c_alpha*r2); + } + } + } + }; + + dt_int32 m = Ixy.size(); + TVctr_r J(m, T(0)); + auto thr_gauss_sup = [&](const iThread_Rect_2d& range) + { + TVctr_r J_p(m, T(0)); + for(auto ip = range.ind_0; ip < range.ind_e; ip++) + { + R_2d p(x[ip], y[ip]); + T a = A[ip]; + T b = S[ip]; + T R_max = 4.0*b; + dgaussian(p, a, b, R_max, grid_2d, J_p); + } + + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + J[ixy] += J_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup); + + T sxy = 0; + T sxy_ee = 0; + T sxx = 0; + T sxx_ee = 0; + for(auto ixy = 0; ixy < Ixy.size(); ixy++) + { + if (mask[ixy]) + { + fcn_kh_sum(sxy, Ixy[ixy]*J[ixy], sxy_ee); + fcn_kh_sum(sxx, J[ixy]*J[ixy], sxx_ee); + } + } + return sxy/sxx; + }; + + T alpha = get_a(grid_s, mask, Ixy, x, y, A, S); + for(auto ip = 0; ip < x.size(); ip++) + { + T a = A[ip]*alpha*Ixy_sc + Bg; + if ((aA_max[ip])) + { + a = A[ip]*Ixy_sc + Bg; + } + A[ip] = a-Bg; + } + return A; + }; + + T fit_c_0(Stream& stream, TVctr_r &image, TVctr_r x, TVctr_r y, + TVctr_r A, TVctr_r S, T Bg, T Bg_min, T Bg_max) + { + // mask and scaling + TVctr_r Ixy; + T Ixy_sc; + fcn_scale(stream, image, Ixy, Ixy_sc); + + const T factor = 2; + T Rxy_sc = grid_2d.bs_max()/factor; + + Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.bs_x/Rxy_sc, grid_2d.bs_y/Rxy_sc); + + // scaling + for(auto ip = 0; ip& grid_2d, vector& mask, TVctr_r &Ixy, + TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + auto dgaussian = [](const R_2d& p, const T& a, const T& b, const T& R_max, const Grid_2d& grid_2d, TVctr_r &J) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + J[grid_2d.sub_2_ind(ix, iy)] += a*exp(-c_alpha*r2); + } + } + } + }; + + dt_int32 m = Ixy.size(); + TVctr_r d_Ixy = Ixy; + auto thr_gauss_sup = [&](const iThread_Rect_2d& range) + { + TVctr_r d_Ixy_p(m, T(0)); + for(auto ip = range.ind_0; ip < range.ind_e; ip++) + { + R_2d p(x[ip], y[ip]); + T a = A[ip]; + T b = S[ip]; + T R_max = 4.0*b; + dgaussian(p, a, b, R_max, grid_2d, d_Ixy_p); + } + + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + d_Ixy[ixy] -= d_Ixy_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup); + + T sxy = 0; + T sxy_ee = 0; + dt_int32 sxx = 0; + for(auto ix = range_ct.ix_0; ix < range_ct.ix_e; ix++) + { + for(auto iy = range_ct.iy_0; iy < range_ct.iy_e; iy++) + { + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + fcn_kh_sum(sxy, d_Ixy[ixy], sxy_ee); + sxx++; + } + } + return sxy/sxx; + }; + + T c = get_c(grid_s, mask, Ixy, x, y, A, S); + c = ((cc_max))?c_0:c_0+(1.0/2.0)*(c-c_0); + return c*Ixy_sc; + }; + + void fit_a_b_0(Stream& stream, Regions ®ion, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max, TVctr_r &S, TVctr_r &S_min, + TVctr_r &S_max, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + auto thr_fit_a_b_0 = [&](const iThread_Rect_2d& range) + { + dt_int32 m_max = region.m_max; + dt_int32 n_max = 2; + + TVctr_r Ja(m_max); + TVctr_r Jb(m_max); + TVctr_r d_Ixy(m_max); + + auto solve_a_b = [](dt_int32 m, TVctr_r &Ja, TVctr_r &Jb, + TVctr_r &d_Ixy, T lambda, T& d_a, T& d_b, T& g_m, T& rho_f) + { + T sx1x1 = 0; + T sx2x2 = 0; + T sx1x2 = 0; + T sx1y = 0; + T sx2y = 0; + for(auto ixy = 0; ixy < m; ixy++) + { + T x1 = Ja[ixy]; + T x2 = Jb[ixy]; + T y = d_Ixy[ixy]; + + sx1x1 += x1*x1; + sx2x2 += x2*x2; + sx1x2 += x1*x2; + sx1y += x1*y; + sx2y += x2*y; + } + T D_a = lambda*(sx1x1 > 1e-10)?sx1x1:1; + T D_b = lambda*(sx2x2 > 1e-10)?sx2x2:1; + + sx1x1 += D_a; + sx2x2 += D_b; + + T det = sx1x1*sx2x2 - sx1x2*sx1x2; + d_a = (sx2x2*sx1y - sx1x2*sx2y)/det; + d_b = (sx1x1*sx2y - sx1x2*sx1y)/det; + + g_m = ::fmax(fabs(sx1y), fabs(sx2y)); + rho_f = d_a*(D_a*d_a + sx1y) + d_b*(D_b*d_b + sx2y); + }; + + auto get_chi2 = [](TVctr_r &R2, TVctr_r &Ixy, T a, T b)->T + { + T c_alpha = 0.5/pow(b, 2); + T chi2 = 0; + T chi2_ee = 0; + for(auto im = 0; im < R2.size(); im++) + { + T v = Ixy[im]-a*exp(-c_alpha*R2[im]); + fcn_kh_sum(chi2, v*v, chi2_ee); + } + return chi2; + }; + + for(auto ipk=range.ind_0; ipk0) + { + a = a_t; + b = b_t; + + // a = ((a < a_min)||(a>a_max))?a_0:a; + // b = ((bb_max))?b_0:b; + + a = min(max(a, a_min), a_max); + b = min(max(b, b_min), b_max); + + chi2 = get_chi2(R2, Ixy, a, b); + } + + lambda = (rho>1e-3)?(::fmax(lambda/lambda_f, 1e-7)):(::fmin(lambda*lambda_f, 1e+7)); + + // a = min(max(a, a_min), a_max); + // b = min(max(b, b_min), b_max); + + // if (fabs(d_b/b)& stream, Regions ®ion, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &S, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + auto thr_fit_x_y_0 = [&](const iThread_Rect_2d& range) + { + dt_int32 m_max = region.m_max; + dt_int32 n_max = 2; + + TVctr_r Jx(m_max); + TVctr_r Jy(m_max); + TVctr_r d_Ixy(m_max); + + auto solve_x_y = [](dt_int32 m, TVctr_r &Jx, TVctr_r &Jy, TVctr_r &d_Ixy, T& d_x, T& d_y) + { + T sx1x1 = 0; + T sx2x2 = 0; + T sx1x2 = 0; + T sx1y = 0; + T sx2y = 0; + for(auto ixy = 0; ixy < m; ixy++) + { + T x1 = Jx[ixy]; + T x2 = Jy[ixy]; + T y = d_Ixy[ixy]; + + sx1x1 += x1*x1; + sx2x2 += x2*x2; + sx1x2 += x1*x2; + sx1y += x1*y; + sx2y += x2*y; + } + sx1x1 *= 1.001; + sx2x2 *= 1.001; + + T det = sx1x1*sx2x2 - sx1x2*sx1x2; + d_x = (sx2x2*sx1y - sx1x2*sx2y)/det; + d_y = (sx1x1*sx2y - sx1x2*sx1y)/det; + }; + + for(auto ipk=range.ind_0; ipk p(x_0, y_0); + R_2d p_0 = p; + R_2d p_min(p.x-dxy, p.y-dxy); + R_2d p_max(p.x+dxy, p.y+dxy); + + dt_int32 m = Ixy.size(); + dt_int32 n = 2; + + TVctr_r d_abxy(n); + for(auto iter = 0; iter(d_x, d_y); + + T ff = 0.5; + p.x = ((p.xp_max.x))?p_0.x:p_0.x+ff*(p.x-p_0.x); + p.y = ((p.yp_max.y))?p_0.y:p_0.y+ff*(p.y-p_0.y); + + T d_xy = sqrt(d_x*d_x+d_y*d_y); + if (d_xy& stream, Regions ®ion, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max, TVctr_r &S, TVctr_r &S_min, + TVctr_r &S_max, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + auto thr_fit_a_b_x_y_0 = [&](const iThread_Rect_2d& range) + { + lapack::LSF_1 fls_1; + + dt_int32 m_max = region.m_max; + dt_int32 n_max = 4; + + TVctr_r M(m_max*n_max); + TVctr_r d_Ixy(m_max); + + for(auto ipk=range.ind_0; ipk p(x_0, y_0); + R_2d p_0 = p; + R_2d p_min(p.x-dxy, p.y-dxy); + R_2d p_max(p.x+dxy, p.y+dxy); + + dt_int32 m = Ixy.size(); + dt_int32 n = 4; + + TVctr_r d_abxy(n); + for(auto iter = 0; iter(d_abxy[2], d_abxy[3]); + + T ff = 0.75; + a = ((a < a_min)||(a>a_max))?a_0:a_0+ff*(a-a_0); + b = ((bb_max))?b_0:b_0+ff*(b-b_0); + p.x = ((p.xp_max.x))?p_0.x:p_0.x+ff*(p.x-p_0.x); + p.y = ((p.yp_max.y))?p_0.y:p_0.y+ff*(p.y-p_0.y); + + if (fabs(d_abxy[1]/b)& stream, Regions ®ion, TVctr_r &x_i, TVctr_r &y_i, + TVctr_r &A_i, TVctr_r &A_min, TVctr_r &A_max, TVctr_r &S_i, TVctr_r &S_min, + TVctr_r &S_max, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + dt_int32 m_max = region.m_max; + dt_int32 n_max = 4*region.n_max; + + auto thr_fit_a_b_x_y = [&](const iThread_Rect_2d& range) + { + TVctr_r d_beta(n_max); + TVctr_r beta(n_max); + TVctr_r beta_0(n_max); + TVctr_r beta_min(n_max); + TVctr_r beta_max(n_max); + + lapack::LSF_1 fls_1; + + auto dgaussian = [](dt_int32 n, TVctr_r &beta, TVctr_r &Rx, TVctr_r &Ry, TVctr_r &J, TVctr_r &d_Ixy) + { + dt_int32 m = Rx.size(); + dt_int32 npn = n/4; + for(auto ip = 0; ip < npn; ip++) + { + dt_int32 idx_p = 4*ip; + + R_2d p(beta[idx_p+0], beta[idx_p+1]); + T a = beta[idx_p+2]; + T b = beta[idx_p+3]; + T r2_lim = pow(4*b, 2); + T c_alpha = 0.5/pow(b, 2); + T c_b = a/pow(b, 3); + T c_xy = a/pow(b, 2); + for(auto im = 0; im < m; im++) + { + T rx = Rx[im]-p.x; + T ry = Ry[im]-p.y; + T r2 = rx*rx + ry*ry; + if (r2 < r2_lim) + { + T f = exp(-c_alpha*r2); + J[(idx_p + 0)*m + im] = c_xy*rx*f; + J[(idx_p + 1)*m + im] = c_xy*ry*f; + J[(idx_p + 2)*m + im] = f; + J[(idx_p + 3)*m + im] = c_b*r2*f; + d_Ixy[im] -= a*f; + } + } + } + }; + + auto x = x_i; + auto y = y_i; + auto A = A_i; + auto S = S_i; + for(auto ipk = range.ind_0; ipk < range.ind_e; ipk++) + { + TVctr_r &Rx = region[ipk].Rx; + TVctr_r &Ry = region[ipk].Ry; + + TVctr_r xn = neigh.select(ipk, x, region[ipk].Rx_sf, region[ipk].Rxy_sc); + TVctr_r yn = neigh.select(ipk, y, region[ipk].Ry_sf, region[ipk].Rxy_sc); + TVctr_r An = neigh.select(ipk, A, 0, region[ipk].Ixy_sc); + TVctr_r Sn = neigh.select(ipk, S, 0, region[ipk].Rxy_sc); + + TVctr_r Ixy = region[ipk].sft_Ixy(grid_2d, image_s, xn, yn, An, Sn); + + for(auto ipn = 0; ipn < xn.size(); ipn++) + { + dt_int32 idx_p = 4*ipn; + + beta_0[idx_p + 0] = xn[ipn]; + beta_0[idx_p + 1] = yn[ipn]; + beta_0[idx_p + 2] = An[ipn]; + beta_0[idx_p + 3] = Sn[ipn]; + + T dxy = ::fmax(1.1*grid_2d.dR_min()/region[ipk].Rxy_sc, 0.25*Sn[ipn]); + R_2d p(xn[ipn], yn[ipn]); + + beta_min[idx_p + 0] = p.x-dxy; + beta_min[idx_p + 1] = p.y-dxy; + beta_min[idx_p + 2] = (A_min[ipn]-Bg)/region[ipk].Ixy_sc; + beta_min[idx_p + 3] = S_min[ipn]/region[ipk].Rxy_sc; + + beta_max[idx_p + 0] = p.x+dxy; + beta_max[idx_p + 1] = p.y+dxy; + beta_max[idx_p + 2] = (A_max[ipn]-Bg)/region[ipk].Ixy_sc; + beta_max[idx_p + 3] = S_max[ipn]/region[ipk].Rxy_sc; + } + + beta = beta_0; + + dt_int32 m = Rx.size(); + dt_int32 n = 4*xn.size(); + + for(auto iter = 0; iter < niter; iter++) + { + TVctr_r J(m*n, 0); + TVctr_r d_Ixy = Ixy; + + dgaussian(n, beta, Rx, Ry, J, d_Ixy); + + fls_1(m, n, J.data(), d_Ixy.data(), d_beta.data()); + + thrust::transform(beta.begin(), beta.end(), d_beta.begin(), beta.begin(), thrust::plus()); + + for(auto ip = 0; ip < n; ip++) + { + beta[ip] = ((beta[ip]beta_max[ip]))?beta_0[ip]:beta[ip]; + } + + if (fabs(d_beta[3]/beta[3]) stream; + FFT fft_2d; + + Grid_2d grid_2d; + TVctr_r image; + TVctr_r image_den; + vector mask; + + T sigma; + T thres; + T d_error; + dt_int32 niter; + + T ref_mean; + T ref_std; + T image_mean; + T image_std; + + T radius_n; + Neigh_2d neigh; + Regions region; + iThread_Rect_2d range_ct; + + TVctr_r x; + TVctr_r y; + TVctr_r A; + TVctr_r S; + T bg; + + TVctr_r A_min; + TVctr_r A_max; + TVctr_r S_min; + TVctr_r S_max; + }; + + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/pn_fact.hpp b/src - Copy (2)/pn_fact.hpp new file mode 100755 index 00000000..b8c6a8a1 --- /dev/null +++ b/src - Copy (2)/pn_fact.hpp @@ -0,0 +1,149 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PN_FACT_H + #define PN_FACT_H + + #include + #include + + #include "macros.cuh" + #include "const_enum.cuh" + + namespace mt + { + /***************************************************************************************/ + /******************** factorization of a number in small prime number ******************/ + // factorization: 2^a × 3^b × 5^c × 7^d, where a>1 + // https:// docs.nvidia.com/cuda/cufft/index.html + + struct PN_Fact + { + public: + PN_Fact() + { + load_prime_numbers(); + } + + dt_int32 operator()(dt_int64 n, eDat_Sel_Typ dst = edst_closest) + { + auto p_idx = std::min_element(pnv.begin(), pnv.end(), [n](dt_int64 p0, dt_int64 pe){ return std::abs(n-p0) < std::abs(n-pe); }); + + auto pn = static_cast(*p_idx); + + switch(dst) + { + case edst_less_than: + { + if (pn>=n) + { + pn = static_cast(*(p_idx-1)); + } + } + break; + case edst_eless_than: + { + if (pn>n) + { + pn = static_cast(*(p_idx-1)); + } + } + break; + case edst_greater_than: + { + if (pn<=n) + { + pn = static_cast(*(p_idx+1)); + } + } + break; + case edst_egreater_than: + { + if (pn(*(p_idx+1)); + } + } + break; + } + return pn; + } + + private: + std::vector pnv; + + void load_prime_numbers() + { + dt_int64 b_2 = 2; + dt_int64 b_3 = 3; + dt_int64 b_5 = 5; + dt_int64 b_7 = 7; + + dt_int32 e_2_m = 16; + dt_int32 e_3_m = 7; + dt_int32 e_5_m = 5; + dt_int32 e_7_m = 4; + + dt_int64 pn_0 = std::pow(b_2, 5); + dt_int64 pn_e = static_cast(std::pow(b_2, e_2_m)); + + // reserve enough space + pnv.reserve((e_2_m+1)*(e_3_m + 1)*(e_5_m + 1)*(e_7_m + 1)); + + // fill in first numbers + for(auto ie=1; ie<6; ie++) + { + auto p = static_cast(std::pow(b_2, ie)); + pnv.push_back(p); + } + + // calculate the other numbers + for(auto ip7=0; ip7<=e_7_m; ip7++) + { + auto p7 = static_cast(std::pow(b_7, ip7)); + + for(auto ip5=0; ip5<=e_5_m; ip5++) + { + auto p5 = static_cast(std::pow(b_5, ip5)); + + for(auto ip3=0; ip3<=e_3_m; ip3++) + { + auto p3 = static_cast(std::pow(b_3, ip3)); + + for(auto ip2=1; ip2<=e_2_m; ip2++) + { + auto p2 = static_cast(std::pow(b_2, ip2)); + + auto p = p7*p5*p3*p2; + + if ((pn_0 + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PROJECTED_POTENTIAL_H +#define PROJECTED_POTENTIAL_H + +#include "math.cuh" +#include "types.cuh" +#include "type_traits_gen.cuh" +#include "cgpu_stream.cuh" +#include "quad_data.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" +#include "cpu_fcns.hpp" +#include "gpu_fcns.cuh" +#include "cgpu_fcns.cuh" +#include "spec.hpp" + +namespace mt + + template + class Projected_Potential: public Spec{ + public: + using size_type = dt_uint64; + + static const eDev device = Dev; + + Projected_Potential(): stream(nullptr), n_atoms_s(512) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i) + { + Spec::set_in_data(multem_in_parm_i); + stream = stream_i; + + Quad_Data quad_data; + quad_data(0, c_nqz, qz); // 0: int_-1^1 y(x) dx - tanh_sinh quad_data + + atom_type.resize(c_n_atom_typ); + for(auto iatom_type = 0; iatom_type::atom_type[iatom_type]); + } + + n_atoms_s = (device==edev_cpu)?(stream->size()):256; + + dt_int32 nv = max(this->multem_in_parm->grid_2d.rx_2_irx_cd(this->atoms.bs_x_int), this->multem_in_parm->grid_2d.ry_2_iry_cd(this->atoms.bs_y_int)); + + stream_data.resize(n_atoms_s); + + for(auto i = 0; imultem_in_parm->is_spec_slic_by_dz_sub()) + { + stream_data.c0[i].resize(c_nR); + stream_data.c1[i].resize(c_nR); + stream_data.c2[i].resize(c_nR); + stream_data.c3[i].resize(c_nR); + } + } + + atom_Vp_h.resize(n_atoms_s); + atom_Vp.resize(n_atoms_s); + + V_0.resize(this->multem_in_parm->grid_2d.size()); + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(const T& z_0, const T& z_e, const dt_int32& iatom_0, const dt_int32& iatom_e, Vctr& V) + { + auto fcn_eval_poly3 = [](Stream& stream, Grid_2d& grid_2d, + Vctr, edev_cpu>& atom, Vctr& mx_o) + { + if (stream.n_stream_act<= 0) + { + return; + } + + for(auto istm = 0; istm < stream.n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(cpu_detail::fcn_eval_poly3, std::ref(stream), std::ref(grid_2d), std::ref(atom[istm]), std::ref(mx_o))); + } + + cpu_detail::fcn_eval_poly3(stream, grid_2d, atom[stream.n_stream_act-1], mx_o); + + stream.synchronize(); + }; + + mt::fill(*stream, V, T(0)); + + dt_int32 iatoms = iatom_0; + while (iatoms <= iatom_e) + { + stream->set_n_stream_act(iatom_e-iatoms+1); + set_atom_Vp(z_0, z_e, iatoms, stream->n_stream_act, atom_Vp); + // get_cubic_poly_coef_Vz(*stream, atom_Vp); + fcn_eval_poly3(*stream, this->multem_in_parm->grid_2d, atom_Vp, V); + iatoms += stream->n_stream_act; + } + + stream->synchronize(); + } + + /*************************************** device ****************************************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(const T& z_0, const T& z_e, const dt_int32& iatom_0, const dt_int32& iatom_e, Vctr& V) + { + auto get_eval_cubic_poly_gridBT = [](dt_int32 natoms)->D_Grid_Blk + { + D_Grid_Blk d_grid_blk; + d_grid_blk.grid = dim3(natoms, 1, 1); + d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y, 1); + + return d_grid_blk; + }; + + mt::fill(*stream, V, T(0)); + + dt_int32 iatoms = iatom_0; + while (iatoms <= iatom_e) + { + dt_int32 n_atoms = min(n_atoms_s, iatom_e-iatoms+1); + set_atom_Vp(z_0, z_e, iatoms, n_atoms, atom_Vp); + // get_cubic_poly_coef_Vz(*stream, atom_Vp_h); + + auto d_grid_blk = get_eval_cubic_poly_gridBT(n_atoms); + gpu_detail::fcn_eval_poly3<<>>(this->multem_in_parm->grid_2d, atom_Vp, V); + + iatoms += n_atoms; + } + } + #endif + + void operator()(const dt_int32& islice_0, const dt_int32& islice_e, Vctr& V) + { + if ((islice_0<0) || (islice_e>=this->slicing.slice.size())) + { + mt::fill(*stream, V, 0.0); + return; + } + this->operator()(this->slicing.slice[islice_0].z_0, this->slicing.slice[islice_e].z_e, + this->slicing.slice[islice_0].iatom_0, this->slicing.slice[islice_e].iatom_e, V); + } + + void operator()(const dt_int32& islice_0, const dt_int32& islice_e) + { + this->operator()(islice_0, islice_e, V_0); + } + + void operator()(const dt_int32& islice, Vctr& V) + { + this->operator()(islice, islice, V); + } + + void operator()(const dt_int32& islice) + { + this->operator()(islice, islice, V_0); + } + + template + void operator()(const dt_int32& islice, TOutput_multislice &output_multem) + { + this->operator()(islice, islice, V_0); + mt::cpy_to_host(output_multem.stream, V_0, output_multem.V[0]); + } + + Vctr V_0; + Stream *stream; + private: + dt_int32 n_atoms_s; + + struct Stream_Data + { + using value_type = T; + using size_type = dt_uint64; + + static const eDev device = edev_cpu; + + size_type size() const + { + return iv.size(); + } + + void resize(const size_type& new_size) + { + iv.resize(new_size); + v.resize(new_size); + c0.resize(new_size); + c1.resize(new_size); + c2.resize(new_size); + c3.resize(new_size); + } + + Vctr, edev_cpu> iv; + Vctr, edev_cpu> v; + Vctr, edev_cpu> c0; // zero coefficient + Vctr, edev_cpu> c1; // first coefficient + Vctr, edev_cpu> c2; // second coefficient + Vctr, edev_cpu> c3; // third coefficient + }; + + void set_atom_Vp(const T& z_0, const T& z_e, dt_int32 iatoms, dt_int32 n_atoms, Vctr, Dev>& atom_Vp) + { + for(auto istm = 0; istm < n_atoms; istm++) + { + auto iZ = this->atoms.Z[iatoms]-1; + auto charge = this->atoms.charge[iatoms]; + dt_int32 icharge = atom_type[iZ].charge_to_ind(charge); + auto &coef = atom_type[iZ].coef[icharge]; + + atom_Vp_h[istm].charge = charge; + atom_Vp_h[istm].x = this->atoms.x[iatoms]; + atom_Vp_h[istm].y = this->atoms.y[iatoms]; + atom_Vp_h[istm].occ = this->atoms.occ[iatoms]; + atom_Vp_h[istm].R2_min = coef.R2_min(); + atom_Vp_h[istm].R2_max = coef.R2_max(); + atom_Vp_h[istm].R2 = raw_pointer_cast(coef.R2.data()); + atom_Vp_h[istm].set_ix0_ixn(this->multem_in_parm->grid_2d, coef.R_max); + atom_Vp_h[istm].set_iy0_iyn(this->multem_in_parm->grid_2d, coef.R_max); + atom_Vp_h[istm].R2_tap = coef.R2_tap(); + atom_Vp_h[istm].coef_tap = coef.coef_tap; + + if (device==edev_cpu) + { + atom_Vp_h[istm].iv = raw_pointer_cast(stream_data.iv[istm].data()); + atom_Vp_h[istm].v = raw_pointer_cast(stream_data.v[istm].data()); + } + + if (this->multem_in_parm->is_spec_slic_by_dz_sub()) + { + atom_Vp_h[istm].z0h = 0.5*(z_0 - this->atoms.z[iatoms]); + atom_Vp_h[istm].zeh = 0.5*(z_e - this->atoms.z[iatoms]); + atom_Vp_h[istm].split = (atom_Vp_h[istm].z0h<0) && (0& stream, Vctr, edev_cpu>& atom_Vp) + { + if (this->multem_in_parm->is_spec_slic_by_dz_sub()) + { + mt::linear_Vz(stream, this->multem_in_parm->atomic_pot_parm_typ, qz, atom_Vp); + mt::fcn_vd_2_coef_poly3(stream, atom_Vp); + } + } + + Quad_Coef_1d qz; + Vctr, edev_cpu> atom_type; // Atom types + + Stream_Data stream_data; + Vctr, edev_cpu> atom_Vp_h; + Vctr, Dev> atom_Vp; + }; + +} +#endif \ No newline at end of file diff --git a/src - Copy (2)/propagator.cuh b/src - Copy (2)/propagator.cuh new file mode 100755 index 00000000..456a7f08 --- /dev/null +++ b/src - Copy (2)/propagator.cuh @@ -0,0 +1,113 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PROPAGATOR_H +#define PROPAGATOR_H + +#include "math.cuh" +#include "types.cuh" +#include "type_traits_gen.cuh" +#include "cgpu_stream.cuh" +#include "cgpu_fft.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" +#include "cpu_fcns.hpp" +#include "gpu_fcns.cuh" +#include "cgpu_fcns.cuh" + +namespace mt +{ + template + class Propagator{ + public: + using T_r = T; + using T_c = complex; + + static const eDev device = Dev; + + Propagator(): multem_in_parm(nullptr), stream(nullptr), fft_2d(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + multem_in_parm = multem_in_parm_i; + stream = stream_i; + fft_2d = fft2_i; + } + + void operator()(const eSpace &space_out, T_r gxu, T_r gyu, + T_r z, Vctr& psi_i, Vctr& psi_o) + { + if (fcn_is_zero(z)) + { + if (multem_in_parm->grid_2d.bwl) + { + fft_2d->forward(psi_i, psi_o); + mt::fcn_fermi_aperture(*stream, multem_in_parm->grid_2d, psi_o); + + if (space_out == esp_real) + { + fft_2d->inverse(psi_o); + } + } + else + { + if (space_out == esp_fourier) + { + fft_2d->forward(psi_i, psi_o); + mt::fcn_scale(*stream, multem_in_parm->grid_2d.isize_r(), psi_o); + } + } + } + else + { + fft_2d->forward(psi_i, psi_o); + + mt::fcn_propagate(*stream, multem_in_parm->grid_2d, multem_in_parm->get_propagator_factor(z), gxu, gyu, psi_o, psi_o); + + if (space_out == esp_real) + { + fft_2d->inverse(psi_o, psi_o); + } + } + } + + void operator()(const eSpace &space_out, T_r gxu, T_r gyu, + T_r z, Vctr& psi_io) + { + this->operator()(space_out, gxu, gyu, z, psi_io, psi_io); + } + + template + void operator()(const eSpace &space_out, T_r gxu, T_r gyu, + T_r z, TOutput_multislice &output_multem) + { + Vctr psi(multem_in_parm->iw_psi.begin(), multem_in_parm->iw_psi.end()); + mt::fcn_fftsft_2d(*stream, multem_in_parm->grid_2d, psi); + this->operator()(space_out, gxu, gyu, z, psi); + mt::cpy_to_host(output_multem.stream, psi, output_multem.psi_coh[0]); + } + + private: + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + }; + +} + +#endif \ No newline at end of file diff --git a/src - Copy (2)/quad_data.cuh b/src - Copy (2)/quad_data.cuh new file mode 100755 index 00000000..30f21ea5 --- /dev/null +++ b/src - Copy (2)/quad_data.cuh @@ -0,0 +1,3101 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef QUAD_DATA_H + #define QUAD_DATA_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_vctr.cuh" + + namespace mt + { + /***************************** quad_data 1d ****************************/ + template class Quad_Coef_1d; + + template + class pQuad_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ x; + T* __restrict__ w; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pQuad_Coef_1d(): x(nullptr), w(nullptr), m_size(0) {} + + CGPU_EXEC + pQuad_Coef_1d(T* x, T* w, const size_type& size): x(x), w(w), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pQuad_Coef_1d(const pQuad_Coef_1d& pcoef_quad_1d) + { + *this = pcoef_quad_1d; + } + + // ! constructor from Quad_Coef_1d + explicit pQuad_Coef_1d(const Quad_Coef_1d& coef_quad_1d) + { + *this = coef_quad_1d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pQuad_Coef_1d& operator=(const pQuad_Coef_1d& pcoef_quad_1d) + { + if (this != &pcoef_quad_1d) + { + x = pcoef_quad_1d.x; + w = pcoef_quad_1d.w; + m_size = pcoef_quad_1d.m_size; + } + + return *this; + } + + // ! Assignment operator: Quad_Coef_1d -> pQuad_Coef_1d + CPU_EXEC + pQuad_Coef_1d& operator=(const Quad_Coef_1d& coef_quad_1d) + { + x = coef_quad_1d.x.data(); + w = coef_quad_1d.w.data(); + m_size = size_type(coef_quad_1d.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pQuad_Coef_1d_cpu = pQuad_Coef_1d; + + template + using pQuad_Coef_1d_gpu = pQuad_Coef_1d; + + /***************************************************************************************/ + template + class Quad_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr x; + mutable Vctr w; + + /************************************* constructors ************************************/ + Quad_Coef_1d() {} + + Quad_Coef_1d(const Vctr_cpu& x, const Vctr_cpu& w): x(x), w(w){} + + Quad_Coef_1d(const dt_init_list_f64& x, const dt_init_list_f64& w): x(x), w(w) {} + + Quad_Coef_1d(const size_type& new_size) + { + resize(new_size); + } + + Quad_Coef_1d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Quad_Coef_1d(const Quad_Coef_1d& coef_quad_1d) + { + *this = coef_quad_1d; + } + + /* converting constructor */ + template + Quad_Coef_1d(const Quad_Coef_1d& coef_quad_1d) + { + *this = coef_quad_1d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Quad_Coef_1d& operator=(const Quad_Coef_1d& coef_quad_1d) + { + this->assign(coef_quad_1d); + + return *this; + } + + /* converting assignment operator */ + template + Quad_Coef_1d& operator=(const Quad_Coef_1d& coef_quad_1d) + { + this->assign(coef_quad_1d); + + return *this; + } + + template + void assign(const Quad_Coef_1d& coef_quad_1d) + { + x.assign(coef_quad_1d.x); + w.assign(coef_quad_1d.w); + } + + /**************** user define conversion operators *******************/ + pQuad_Coef_1d ptr() const + { + return pQuad_Coef_1d(*this); + } + + // ! user define conversion for pointer Vctr + operator pQuad_Coef_1d() const + { + return pQuad_Coef_1d(*this); + } + + void fill(const T& val_x, const T& val_w) + { + x.fill(val_x); + w.fill(val_w); + } + + size_type size() const + { + return size_type(x.size()); + } + + void clear() + { + x.clear(); + w.clear(); + } + + void reserve(const size_type& new_size) + { + x.reserve(new_size); + w.reserve(new_size); + } + + void resize(const size_type& new_size) + { + x.resize(new_size); + w.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + x.resize(new_size, value); + w.resize(new_size, value); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + w.shrink_to_fit(); + } + }; + + template + using Quad_Coef_1d_cpu = Quad_Coef_1d; + + template + using Quad_Coef_1d_gpu = Quad_Coef_1d; + + /***************************** quad_data 2d ****************************/ + template class Quad_Coef_2d; + + template + class pQuad_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ x; + T* __restrict__ y; + T* __restrict__ w; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pQuad_Coef_2d(): x(nullptr), y(nullptr), w(nullptr), m_size(0) {} + + CGPU_EXEC + pQuad_Coef_2d(T* x, T* y, T* w, const size_type& size): x(x), y(y), w(w), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pQuad_Coef_2d(const pQuad_Coef_2d& pcoef_quad_2d) + { + *this = pcoef_quad_2d; + } + + // ! constructor from Quad_Coef_2d + explicit pQuad_Coef_2d(const Quad_Coef_2d& coef_quad_2d) + { + *this = coef_quad_2d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pQuad_Coef_2d& operator=(const pQuad_Coef_2d& pcoef_quad_2d) + { + if (this != &pcoef_quad_2d) + { + x = pcoef_quad_2d.x; + y = pcoef_quad_2d.y; + w = pcoef_quad_2d.w; + m_size = pcoef_quad_2d.m_size; + } + + return *this; + } + + // ! Assignment operator: Quad_Coef_2d -> pQuad_Coef_2d + CPU_EXEC + pQuad_Coef_2d& operator=(Quad_Coef_2d& coef_quad_2d) + { + x = coef_quad_2d.x.data(); + y = coef_quad_2d.y.data(); + w = coef_quad_2d.w.data(); + m_size = size_type(coef_quad_2d.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pQuad_Coef_2d_cpu = pQuad_Coef_2d; + + template + using pQuad_Coef_2d_gpu = pQuad_Coef_2d; + + /***************************************************************************************/ + template + class Quad_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr x; + mutable Vctr y; + mutable Vctr w; + + /************************************* constructors ************************************/ + Quad_Coef_2d() {} + + Quad_Coef_2d(const Vctr_cpu& x, const Vctr_cpu& y, const Vctr_cpu& w): + x(x), y(y), w(w){} + + Quad_Coef_2d(const dt_init_list_f64& x, const dt_init_list_f64& y, const dt_init_list_f64& w): + x(x), y(y), w(w) {} + + Quad_Coef_2d(const size_type& new_size) + { + resize(new_size); + } + + Quad_Coef_2d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Quad_Coef_2d(const Quad_Coef_2d& coef_quad_2d) + { + *this = coef_quad_2d; + } + + /* converting constructor */ + template + Quad_Coef_2d(const Quad_Coef_2d& coef_quad_2d) + { + *this = coef_quad_2d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Quad_Coef_2d& operator=(const Quad_Coef_2d& coef_quad_2d) + { + this->assign(coef_quad_2d); + + return *this; + } + + /* converting assignment operator */ + template + Quad_Coef_2d& operator=(const Quad_Coef_2d& coef_quad_2d) + { + this->assign(coef_quad_2d); + + return *this; + } + + template + void assign(const Quad_Coef_2d& coef_quad_2d) + { + x.assign(coef_quad_2d.x); + y.assign(coef_quad_2d.y); + w.assign(coef_quad_2d.w); + } + + /**************** user define conversion operators *******************/ + pQuad_Coef_2d ptr() const + { + return pQuad_Coef_2d(*this); + } + + // ! user define conversion for pointer Vctr + operator pQuad_Coef_2d() const + { + return pQuad_Coef_2d(*this); + } + + void fill(const T& val_x, const T& val_y, const T& val_w) + { + x.fill(val_x); + y.fill(val_y); + w.fill(val_w); + } + + size_type size() const + { + return x.size(); + } + + void clear() + { + x.clear(); + y.clear(); + w.clear(); + } + + void reserve(const size_type& new_size) + { + x.reserve(new_size); + y.reserve(new_size); + w.reserve(new_size); + } + + void resize(const size_type& new_size) + { + x.resize(new_size); + y.resize(new_size); + w.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + x.resize(new_size, value); + y.resize(new_size, value); + w.resize(new_size, value); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + w.shrink_to_fit(); + } + }; + + template + using Quad_Coef_2d_cpu = Quad_Coef_2d; + + template + using Quad_Coef_2d_gpu = Quad_Coef_2d; + + /***************************************************************************************/ + /***************************************************************************************/ + /***************************************************************************************/ + class Quad_Data + { + public: + using T = dt_float64; + using value_type = T; + using size_type = dt_int32; + + Quad_Data() {} + + template + Quad_Data(const eQuad_Typ& quad_typ, const dt_int32& n_quad, Quad_Coef_1d& quad, T alpha = 0, T beta = 0, T a = 0, T b = 1) + { + this->operator()(quad_typ, n_quad, quad, alpha, beta, a, b); + } + + template + void operator()(const eQuad_Typ& quad_typ, const dt_int32& n_quad, Quad_Coef_1d& quad, T alpha=0, T beta=0, T a=0, T b=1) + { + Quad_Coef_1d_cpu quad_t(n_quad); + + if (n_quad <= 1) + { + quad.resize(1); + quad.x[0] = 0; + quad.w[0] = 1; + + return; + } + + switch(quad_typ) + { + // Double exponential quadrature + case eqt_tanh_sinh_int_n1_p1: // int_-1^1 f(x) dx + { + T x_min = T(-1) + Epsilon::eps; + T x_max = T(1) - Epsilon::eps; + + nw_tanh_sinh_int_n1_p1(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_exp_sinh_int_0_pinfty: // int_0^infty f(x) dx + { + T x_min = Epsilon::eps; + //T x_max = 225.0; + T x_max = 1e+5; + + nw_exp_sinh_int_0_pinfty(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_exp_exp_int_0_pinfty: // int_0^infty f(x)exp(-x) dx + { + T x_min = Epsilon::eps; + T x_max = 225.0; + + nw_exp_exp_int_0_pinfty(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_sinh_sinh_int_ninfty_pinfty: // int_-infty^infty f(x) dx + { + T x_min = -225.0; + T x_max = 225.0; + + nw_sinh_sinh_int_ninfty_pinfty(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_fourier_sin_int_0_pinfty: // int_0^infty f(x)sin(wx) dx + { + T tai = 4.0; + nw_fourier_sin_int_0_pinfty(quad_t.size(), tai, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_fourier_cos_int_0_pinfty: // int_0^infty f(x)Cos(wx) dx + { + T tai = 4.0; + nw_fourier_cos_int_0_pinfty(quad_t.size(), tai, quad_t.x.data(), quad_t.w.data()); + } + break; + // smooth functions + case eqt_gauss_legendre_int_n1_p1: // int_-1^1 f(x) dx + { + nw_gauss_legendre_int_n1_p1(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_hermite_x0_int_ninfty_pinfty: // int_-infty^infty f(x) x^0 Exp[-x^2] dx + { + nw_gauss_hermite_x0_int_ninfty_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_hermite_x1_int_ninfty_pinfty: // int_-infty^infty f(x) |x|^1 Exp[-x^2] dx + { + nw_gauss_hermite_x1_int_ninfty_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_hermite_x2_int_ninfty_pinfty: // int_-infty^infty f(x) |x|^2 Exp[-x^2] dx + { + nw_gauss_hermite_x2_int_ninfty_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_x0_int_0_pinfty: // int_0^infty f(x) x^0 Exp[-x] dx + { + nw_gauss_laguerre_x0_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_x1_int_0_pinfty: // int_0^infty f(x) x^1 Exp[-x] dx + { + nw_gauss_laguerre_x1_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_x2_int_0_pinfty: // int_0^infty f(x) x^2 Exp[-x] dx + { + nw_gauss_laguerre_x2_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_xi2_int_0_pinfty: // int_0^infty f(x) Exp[-x]/Sqrt[x] dx + { + nw_gauss_laguerre_xi2_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_legendre: // legendre, (a, b) + { + cgqf(1, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_chebyshev: // chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + { + cgqf(2, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gegenbauer: // gegenbauer, (a, b) ((b-x)*(x-a))^alpha + { + cgqf(3, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_jacobi: // jacobi, (a, b) (b-x)^alpha*(x-a)^beta + { + cgqf(4, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_laguerre: // generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + { + cgqf(5, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_hermite: // generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + { + cgqf(6, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_exponential: // exponential, (a, b) |x-(a+b)/2.0|^alpha + { + cgqf(7, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_rational: // rational, (a, inf) (x-a)^alpha*(x+b)^beta + { + cgqf(8, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + } + + quad.assign(quad_t); + } + + private: + // 1: int_-1^1 f(x) dx + void nw_tanh_sinh_int_n1_p1(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](const T& x)->T + { + return asinh(atanh(x)/c_i2pi); + }; + + const auto t_min = get_limit(x_min); + const auto t_max = get_limit(x_max); + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto t_ik = t_min + T(ix)*h; + const auto tt_ix = c_i2pi*sinh(t_ik); + + px[ix] = tanh(tt_ix); + pw[ix] = h*c_i2pi*cosh(t_ik)/::square(cosh(tt_ix)); + } + } + + // 2: int_0^infty f(x) dx + void nw_exp_sinh_int_0_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](T x)->T + { + return asinh(log(x)/c_i2pi); + }; + + const auto t_min = get_limit(x_min); + const auto t_max = get_limit(x_max); + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto f = ((ix==0)||(ix==nx-1))?T(0.5):T(1.0); + const auto t_ik = t_min + T(ix)*h; + + px[ix] = exp(c_i2pi*sinh(t_ik)); + pw[ix] = f*h*c_i2pi*cosh(t_ik)*px[ix]; + } + } + + // 3: int_0^infty f(x)exp(-x) dx + void nw_exp_exp_int_0_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](T x, T t, dt_int32 n)->T + { + const auto t_s = log(x); + for(auto ix = 0; ix < n; ix++) + { + const auto exp_t = exp(-t); + t = t - (t - exp_t - t_s)/(T(1) + exp_t); + } + return t; + }; + + auto t_min = -log(-log(x_min)); + t_min = get_limit(x_min, t_min, 5); + + auto t_max = log(x_max); + t_max = get_limit(x_max, t_max, 5); + + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto f = ((ix==0)||(ix==nx-1))?T(0.5):T(1.0); + const auto t_ik = t_min + T(ix)*h; + const auto exp_t_ik = exp(-t_ik); + + px[ix] = exp(t_ik-exp_t_ik); + pw[ix] = f*h*px[ix]*(T(1) + exp_t_ik); + } + } + + // 4: int_-infty^infty f(x) dx + void nw_sinh_sinh_int_ninfty_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](T x)->T + { + return asinh(asin(x)/c_i2pi); + }; + + const auto t_min = get_limit(x_min); + const auto t_max = get_limit(x_max); + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto t_ix = t_min + T(ix)*h; + const auto tt_ix = c_i2pi*sinh(t_ix); + + px[ix] = sinh(tt_ix); + pw[ix] = h*c_i2pi*cosh(t_ix)*cosh(tt_ix); + } + } + //1. Ooura, T. & Mori, M. A robust double exponential formula for Fourier-type integrals. J. Comput. Appl. Math. 112, 229–241 (1999). + // 5: int_0^infty f(x)sin(wx) dx + void nw_fourier_sin_int_0_pinfty(const dt_int32& nx, const T& ta, T* px, T* pw) + { + const T h = T(2)*ta/T(nx); + const T M = c_pi/h; + const T k = T(6); + + for(auto ix = 0; ix < nx; ix++) + { + auto t_ix = -ta + T(ix+1)*h; + + if (t_ix == 0 ) + { + const auto phi = T(1)/k; + const auto dphi = T(0.5); + px[ix] = M*phi; + pw[ix] = c_pi*dphi*sin(M*phi); + } + else + { + const auto ut = T(1) - exp(-k*sinh(t_ix)); + const auto phi = t_ix/ut; + const auto dphi = (T(1)+(T(1)+k*t_ix*cosh(t_ix))*(ut-T(1)))/(ut*ut); + + px[ix] = M*phi; + pw[ix] = c_pi*dphi*sin(M*phi); + } + } + } + + // 6: int_0^infty f(x)Cos(wx) dx + void nw_fourier_cos_int_0_pinfty(const dt_int32& nx, const T& ta, T* px, T* pw) + { + const T h = T(2)*ta/T(nx); + const T M = c_pi/h; + const T k = T(6); + + for(auto ix = 0; ix < nx; ix++) + { + auto t_ix = -ta + (T(ix)+T(0.5))*h; + + if (t_ix == 0 ) + { + const auto phi = T(1)/k; + const auto dphi = T(0.5); + px[ix] = M*phi; + pw[ix] = c_pi*dphi*cos(M*phi); + } + else + { + const auto ut = T(1) - exp(-k*sinh(t_ix)); + const auto phi = t_ix/ut; + const auto dphi = (T(1)+(T(1)+k*t_ix*cosh(t_ix))*(ut-T(1)))/(ut*ut); + px[ix] = M*phi; + pw[ix] = c_pi*dphi*cos(M*phi); + } + } + } + + // 7: int_-1^1 f(x) dx + void nw_gauss_legendre_int_n1_p1(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 1; + dt_int32 n_quad = nx; + T alpha = 0; + T beta = 0; + T a = -1.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 8: int_-infty^infty f(x) x^0 Exp[-x^2] dx + void nw_gauss_hermite_x0_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 6; + dt_int32 n_quad = nx; + T alpha = 0; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 9: int_-infty^infty f(x) |x|^1 Exp[-x^2] dx + void nw_gauss_hermite_x1_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 6; + dt_int32 n_quad = nx; + T alpha = 1; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 9: int_-infty^infty f(x) |x|^2 Exp[-x^2] dx + void nw_gauss_hermite_x2_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 6; + dt_int32 n_quad = nx; + T alpha = 2; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 11: int_0^infty f(x) x^0 Exp[-x] dx + void nw_gauss_laguerre_x0_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 5; + dt_int32 n_quad = nx; + T alpha = 0; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 12: int_0^infty f(x) x^1 Exp[-x] dx + void nw_gauss_laguerre_x1_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 n_quad = nx; + dt_int32 kind = 5; + T alpha = 1; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 13: int_0^infty f(x) x^2 Exp[-x] dx + void nw_gauss_laguerre_x2_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 5; + dt_int32 n_quad = nx; + T alpha = 2; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 14: int_0^infty f(x) Exp[-x]/Sqrt[x] dx + void nw_gauss_laguerre_xi2_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + switch(nx) + { + case 2: + px[0] = 2.7525512860841095e-1;pw[0] = 1.6098281800110257e0; + px[1] = 2.7247448713915890e0;pw[1] = 1.6262567089449035e-1; + break; + case 4: + px[0] = 1.4530352150331709e-1;pw[0] = 1.3222940251164826e0; + px[1] = 1.3390972881263614e0;pw[1] = 4.1560465162978376e-1; + px[2] = 3.9269635013582872e0;pw[2] = 3.4155966014826951e-2; + px[3] = 8.5886356890120343e0;pw[3] = 3.9920814442273524e-4; + break; + case 8: + px[0] = 7.4791882596818270e-2;pw[0] = 1.0158589580332275e0; + px[1] = 6.7724908764928915e-1;pw[1] = 5.6129491705706735e-1; + px[2] = 1.9051136350314284e0;pw[2] = 1.6762008279797166e-1; + px[3] = 3.8094763614849071e0;pw[3] = 2.5760623071019947e-2; + px[4] = 6.4831454286271704e0;pw[4] = 1.8645680172483611e-3; + px[5] = 1.0093323675221343e1;pw[5] = 5.4237201850757630e-5; + px[6] = 1.4972627088426393e1;pw[6] = 4.6419616897304213e-7; + px[7] = 2.1984272840962651e1;pw[7] = 5.3096149480223645e-10; + break; + case 16: + px[0] = 3.7962914575313455e-2;pw[0] = 7.5047670518560479e-1; + px[1] = 3.4220015601094768e-1;pw[1] = 5.5491628460505980e-1; + px[2] = 9.5355315539086550e-1;pw[2] = 3.0253946815328497e-1; + px[3] = 1.8779315076960743e0;pw[3] = 1.2091626191182523e-1; + px[4] = 3.1246010507021443e0;pw[4] = 3.5106857663146861e-2; + px[5] = 4.7067267076675872e0;pw[5] = 7.3097806533088562e-3; + px[6] = 6.6422151797414440e0;pw[6] = 1.0725367310559441e-3; + px[7] = 8.9550013377233902e0;pw[7] = 1.0833168123639965e-4; + px[8] = 1.1677033673975957e1;pw[8] = 7.3011702591247521e-6; + px[9] = 1.4851431341801250e1;pw[9] = 3.1483355850911881e-7; + px[10] = 1.8537743178606694e1;pw[10] = 8.1976643295417932e-9; + px[11] = 2.2821300693525208e1;pw[11] = 1.1866582926793277e-10; + px[12] = 2.7831438211328676e1;pw[12] = 8.4300204226528951e-13; + px[13] = 3.3781970488226166e1;pw[13] = 2.3946880341856973e-15; + px[14] = 4.1081666525491202e1;pw[14] = 1.8463473073036584e-18; + px[15] = 5.0777223877537080e1;pw[15] = 1.4621352854768325e-22; + break; + case 24: + px[0] = 2.5437996585689359e-2;pw[0] = 6.2200206075592616e-1; + px[1] = 2.2910231649262433e-1;pw[1] = 5.0792308532951820e-1; + px[2] = 6.3729027873266879e-1;pw[2] = 3.3840894389128221e-1; + px[3] = 1.2517406323627464e0;pw[3] = 1.8364459415857036e-1; + px[4] = 2.0751129098523806e0;pw[4] = 8.0959353969207698e-2; + px[5] = 3.1110524551477130e0;pw[5] = 2.8889923149962199e-2; + px[6] = 4.3642830769353062e0;pw[6] = 8.3060098239551049e-3; + px[7] = 5.8407332713236080e0;pw[7] = 1.9127846396388306e-3; + px[8] = 7.5477046800234544e0;pw[8] = 3.5030086360234566e-4; + px[9] = 9.4940953300264876e0;pw[9] = 5.0571980554969778e-5; + px[10] = 1.1690695926056073e1;pw[10] = 5.6945173834696962e-6; + px[11] = 1.4150586187285759e1;pw[11] = 4.9373179873395010e-7; + px[12] = 1.6889671928527108e1;pw[12] = 3.2450282717915397e-8; + px[13] = 1.9927425875242462e1;pw[13] = 1.5860934990330765e-9; + px[14] = 2.3287932824879917e1;pw[14] = 5.6305930756763382e-11; + px[15] = 2.7001406056472356e1;pw[15] = 1.4093865163091778e-12; + px[16] = 3.1106464709046565e1;pw[16] = 2.3951797309583587e-14; + px[17] = 3.5653703516328212e1;pw[17] = 2.6303192453168170e-16; + px[18] = 4.0711598185543107e1;pw[18] = 1.7460319202373353e-18; + px[19] = 4.6376979557540133e1;pw[19] = 6.3767746470102769e-21; + px[20] = 5.2795432527283630e1;pw[20] = 1.1129154937804570e-23; + px[21] = 6.0206666963057223e1;pw[21] = 7.3700721603013398e-27; + px[22] = 6.9068601975304369e1;pw[22] = 1.1969225386627757e-30; + px[23] = 8.0556280819950406e1;pw[23] = 1.5871103023654473e-35; + break; + case 32: + px[0] = 1.9127510968446856e-2;pw[0] = 5.4275484988260796e-1; + px[1] = 1.7221572414539558e-1;pw[1] = 4.6598957212535609e-1; + px[2] = 4.7875647727748885e-1;pw[2] = 3.4337168469816740e-1; + px[3] = 9.3948321450073428e-1;pw[3] = 2.1699669861237368e-1; + px[4] = 1.5555082314789380e0;pw[4] = 1.1747996392819887e-1; + px[5] = 2.3283376682103970e0;pw[5] = 5.4406257907377837e-2; + px[6] = 3.2598922564569419e0;pw[6] = 2.1512081019758274e-2; + px[7] = 4.3525345293301410e0;pw[7] = 7.2451739570689175e-3; + px[8] = 5.6091034574961513e0;pw[8] = 2.0726581990151553e-3; + px[9] = 7.0329577982838936e0;pw[9] = 5.0196739702612497e-4; + px[10] = 8.6280298574059291e0;pw[10] = 1.0251858271572549e-4; + px[11] = 1.0398891905552624e1;pw[11] = 1.7576998461700718e-5; + px[12] = 1.2350838217714770e1;pw[12] = 2.5166805020623692e-6; + px[13] = 1.4489986690780274e1;pw[13] = 2.9910658734544941e-7; + px[14] = 1.6823405362953694e1;pw[14] = 2.9302506329522187e-8; + px[15] = 1.9359271087268714e1;pw[15] = 2.3472334846430987e-9; + px[16] = 2.2107070382206007e1;pw[16] = 1.5230434500290903e-10; + px[17] = 2.5077856544198053e1;pw[17] = 7.9183555338954479e-12; + px[18] = 2.8284583194970531e1;pw[18] = 3.2566814614194407e-13; + px[19] = 3.1742543790616606e1;pw[19] = 1.0437247453181695e-14; + px[20] = 3.5469961396173283e1;pw[20] = 2.5601867826448761e-16; + px[21] = 3.9488797123368127e1;pw[21] = 4.7037694213516382e-18; + px[22] = 4.3825886369903902e1;pw[22] = 6.3045091330075628e-20; + px[23] = 4.8514583867416048e1;pw[23] = 5.9657255685597023e-22; + px[24] = 5.3597231826148512e1;pw[24] = 3.8234137666012857e-24; + px[25] = 5.9129027934391951e1;pw[25] = 1.5723595577851821e-26; + px[26] = 6.5184426376135782e1;pw[26] = 3.8582071909299337e-29; + px[27] = 7.1868499359551422e1;pw[27] = 5.0993217982259985e-32; + px[28] = 7.9339086528823201e1;pw[28] = 3.1147812492595276e-35; + px[29] = 8.7856119943133525e1;pw[29] = 6.8422760225114810e-39; + px[30] = 9.7916716426062762e1;pw[30] = 3.3594959802163184e-43; + px[31] = 1.1079926894707576e2;pw[31] = 1.1088644990767160e-48; + break; + case 40: + px[0] = 1.5325663331507189e-2;pw[0] = 4.8767170761442366e-1; + px[1] = 1.3796600174102882e-1;pw[1] = 4.3154989254866095e-1; + px[2] = 3.8343384139288653e-1;pw[2] = 3.3787593855180386e-1; + px[3] = 7.5210508353159711e-1;pw[3] = 2.3396146760859843e-1; + px[4] = 1.2445475511131953e0;pw[4] = 1.4320149538368678e-1; + px[5] = 1.8615258453171583e0;pw[5] = 7.7417199829675957e-2; + px[6] = 2.6040079765974233e0;pw[6] = 3.6931502308855776e-2; + px[7] = 3.4731739113527927e0;pw[7] = 1.5528078810799283e-2; + px[8] = 4.4704262206423379e0;pw[8] = 5.7463950661794487e-3; + px[9] = 5.5974030703416056e0;pw[9] = 1.8686353739223537e-3; + px[10] = 6.8559938552704945e0;pw[10] = 5.3295577338670161e-4; + px[11] = 8.2483578563697614e0;pw[11] = 1.3303482483630581e-4; + px[12] = 9.7769463941849785e0;pw[12] = 2.8992888382259350e-5; + px[13] = 1.1444529069317641e1;pw[13] = 5.5014492548024867e-6; + px[14] = 1.3254224828602629e1;pw[14] = 9.0610711317226041e-7; + px[15] = 1.5209538784718065e1;pw[15] = 1.2908925900239279e-7; + px[16] = 1.7314405960671086e1;pw[16] = 1.5845846578300512e-8; + px[17] = 1.9573243448531832e1;pw[17] = 1.6686111852173423e-9; + px[18] = 2.1991012891259404e1;pw[18] = 1.4999439829316549e-10; + px[19] = 2.4573295756577260e1;pw[19] = 1.1446559437004013e-11; + px[20] = 2.7326384629341011e1;pw[20] = 7.3696996403182414e-13; + px[21] = 3.0257394787336121e1;pw[21] = 3.9750416693969613e-14; + px[22] = 3.3374401770413884e1;pw[22] = 1.7818922081332433e-15; + px[23] = 3.6686612696144794e1;pw[23] = 6.5783240287291484e-17; + px[24] = 4.0204582016183319e1;pw[24] = 1.9793057979240198e-18; + px[25] = 4.3940486724615585e1;pw[25] = 4.7956805512357826e-20; + px[26] = 4.7908482506508098e1;pw[26] = 9.2269421491078646e-22; + px[27] = 5.2125172273284642e1;pw[27] = 1.3868239639057759e-23; + px[28] = 5.6610234272577454e1;pw[28] = 1.5970374396346345e-25; + px[29] = 6.1387282639433491e1;pw[29] = 1.3766914087267507e-27; + px[30] = 6.6485076698107068e1;pw[30] = 8.6356346860439419e-30; + px[31] = 7.1939271994415582e1;pw[31] = 3.8059812200638324e-32; + px[32] = 7.7795048292119587e1;pw[32] = 1.1274385558954499e-34; + px[33] = 8.4111230042098140e1;pw[33] = 2.1190293856555058e-37; + px[34] = 9.0967109281657703e1;pw[34] = 2.3384153996394935e-40; + px[35] = 9.8474564473065897e1;pw[35] = 1.3584866032309069e-43; + px[36] = 1.0680170504629888e2;pw[36] = 3.5284114086777935e-47; + px[37] = 1.1622557258080335e2;pw[37] = 3.1343129875498926e-51; + px[38] = 1.2727662323235295e2;pw[38] = 5.7648218162351852e-52; + px[39] = 1.4132130003237776e2;pw[39] = 5.6256581525587782e-50; + break; + case 48: + px[0] = 1.2784572337116694e-2;pw[0] = 4.4654004699506952e-1; + px[1] = 1.1508148358837804e-1;pw[1] = 4.0322602695846852e-1; + px[2] = 3.1978387827943194e-1;pw[2] = 3.2875926119699403e-1; + px[3] = 6.2710953585675593e-1;pw[3] = 2.4196623372503065e-1; + px[4] = 1.0373867221540579e0;pw[4] = 1.6070790016128415e-1; + px[5] = 1.5510561307962492e0;pw[5] = 9.6279813462180107e-2; + px[6] = 2.1686735147948251e0;pw[6] = 5.2000680542488898e-2; + px[7] = 2.8909130466944233e0;pw[7] = 2.5302750225600317e-2; + px[8] = 3.7185714571096889e0;pw[8] = 1.1083262578877953e-2; + px[9] = 4.6525730143474026e0;pw[9] = 4.3662639521934365e-3; + px[10] = 5.6939754224427003e0;pw[10] = 1.5453916433633038e-3; + px[11] = 6.8439767318335151e0;pw[11] = 4.9083618546105323e-4; + px[12] = 8.1039233766453468e0;pw[12] = 1.3970864889083082e-4; + px[13] = 9.4753194758919079e0;pw[13] = 3.5583611836440579e-5; + px[14] = 1.0959837563734646e1;pw[14] = 8.0964663575545199e-6; + px[15] = 1.2559330947448595e1;pw[15] = 1.6427089095665616e-6; + px[16] = 1.4275847932399555e1;pw[16] = 2.9659388100100142e-7; + px[17] = 1.6111648203063945e1;pw[17] = 4.7547324295148571e-8; + px[18] = 1.8069221710408724e1;pw[18] = 6.7511694622554086e-9; + px[19] = 2.0151310492061653e1;pw[19] = 8.4671875670220449e-10; + px[20] = 2.2360933946965237e1;pw[20] = 9.3520207719701412e-11; + px[21] = 2.4701418206395586e1;pw[21] = 9.0666067491677764e-12; + px[22] = 2.7176430396128092e1;pw[22] = 7.6873634497532554e-13; + px[23] = 2.9790018780757460e1;pw[23] = 5.6775347903386773e-14; + px[24] = 3.2546660035349492e1;pw[24] = 3.6363382609864670e-15; + px[25] = 3.5451315222092618e1;pw[25] = 2.0098102983149713e-16; + px[26] = 3.8509496489187991e1;pw[26] = 9.5336623423732135e-18; + px[27] = 4.1727347097011937e1;pw[27] = 3.8577586536742773e-19; + px[28] = 4.5111738172331784e1;pw[28] = 1.3225902352962134e-20; + px[29] = 4.8670386683149351e1;pw[29] = 3.8125203773751006e-22; + px[30] = 5.2412000646782474e1;pw[30] = 9.1612021970998299e-24; + px[31] = 5.6346459734243123e1;pw[31] = 1.8171931294097668e-25; + px[32] = 6.0485042530508732e1;pw[32] = 2.9424831099483641e-27; + px[33] = 6.4840716257286064e1;pw[33] = 3.8399414135897572e-29; + px[34] = 6.9428511589042573e1;pw[34] = 3.9790937885390546e-31; + px[35] = 7.4266015688703556e1;pw[35] = 3.2177464158769137e-33; + px[36] = 7.9374033184791669e1;pw[36] = 1.9893600118442518e-35; + px[37] = 8.4777491893280191e1;pw[37] = 9.1748033317163899e-38; + px[38] = 9.0506715916613337e1;pw[38] = 3.0635979294223916e-40; + px[39] = 9.6599269661943114e1;pw[39] = 7.1378771235620131e-43; + px[40] = 1.0310272648925973e2;pw[40] = 1.1074129639565051e-45; + px[41] = 1.1007901167333772e2;pw[41] = 1.0766445013940194e-48; + px[42] = 1.1761159733441177e2;pw[42] = 6.0445878630042245e-52; + px[43] = 1.2581828912230779e2;pw[43] = 1.7467465671838054e-55; + px[44] = 1.3487618875613396e2;pw[44] = 2.1867649475035571e-59; + px[45] = 1.4507736943128927e2;pw[45] = 8.9374048433626366e-64; + px[46] = 1.5698162310364024e2;pw[46] = 6.9616827754363648e-69; + px[47] = 1.7203286674516623e2;pw[47] = 7.3843030686139940e-50; + break; + case 56: + px[0] = 1.0966296964922414e-2;pw[0] = 4.1431861461592488e-1; + px[1] = 9.8709503981500921e-2;pw[1] = 3.7958824335151592e-1; + px[2] = 2.7426441281900728e-1;pw[2] = 3.1859560878006560e-1; + px[3] = 5.3776830760580984e-1;pw[3] = 2.4493804875366549e-1; + px[4] = 8.8942785389626524e-1;pw[4] = 1.7245385388352993e-1; + px[5] = 1.3295199945387192e0;pw[5] = 1.1116552769641440e-1; + px[6] = 1.8583931587330957e0;pw[6] = 6.5583934984821083e-2; + px[7] = 2.4764687971240665e0;pw[7] = 3.5397526052325080e-2; + px[8] = 3.1842432594503771e0;pw[8] = 1.7469565741779008e-2; + px[9] = 3.9822900352751187e0;pw[9] = 7.8791146628173459e-3; + px[10] = 4.8712623827436266e0;pw[10] = 3.2454637275858797e-3; + px[11] = 5.8518963752570206e0;pw[11] = 1.2200069198095973e-3; + px[12] = 6.9250144015294926e0;pw[12] = 4.1819509658049854e-4; + px[13] = 8.0915291608577938e0;pw[13] = 1.3059682676732009e-4; + px[14] = 9.3524482027415579e0;pw[14] = 3.7118324819779832e-5; + px[15] = 1.0708879068458080e1;pw[15] = 9.5910914884881867e-6; + px[16] = 1.2162035102064631e1;pw[16] = 2.2503384827035532e-6; + px[17] = 1.3713242009881661e1;pw[17] = 4.7880157280422767e-7; + px[18] = 1.5363945261179596e1;pw[18] = 9.2250198493335919e-8; + px[19] = 1.7115718439020667e1;pw[19] = 1.6069558346408703e-8; + px[20] = 1.8970272669583436e1;pw[20] = 2.5265449989883177e-9; + px[21] = 2.0929467281561854e1;pw[21] = 3.5787741726578897e-10; + px[22] = 2.2995321875320932e1;pw[22] = 4.5577902726623018e-11; + px[23] = 2.5170030015603701e1;pw[23] = 5.2076385947795911e-12; + px[24] = 2.7455974803255672e1;pw[24] = 5.3255665746212511e-13; + px[25] = 2.9855746632650704e1;pw[25] = 4.8619672412277693e-14; + px[26] = 3.2372163504856039e1;pw[26] = 3.9515202575705826e-15; + px[27] = 3.5008294345466858e1;pw[27] = 2.8503559634838643e-16; + px[28] = 3.7767485874979349e1;pw[28] = 1.8187535954103432e-17; + px[29] = 4.0653393704581200e1;pw[29] = 1.0228519632208071e-18; + px[30] = 4.3670018489449905e1;pw[30] = 5.0500039302829468e-20; + px[31] = 4.6821748176145590e1;pw[31] = 2.1793149108595921e-21; + px[32] = 5.0113407645739421e1;pw[32] = 8.1812395526908028e-23; + px[33] = 5.3550317401224539e1;pw[33] = 2.6576488518963704e-24; + px[34] = 5.7138363406574332e1;pw[34] = 7.4271309204470600e-26; + px[35] = 6.0884080798556528e1;pw[35] = 1.7740931536888198e-27; + px[36] = 6.4794755023535346e1;pw[36] = 3.5960724740047246e-29; + px[37] = 6.8878545092128855e1;pw[37] = 6.1357429171822799e-31; + px[38] = 7.3144635233014682e1;pw[38] = 8.7325878464563983e-33; + px[39] = 7.7603423474903333e1;pw[39] = 1.0260913087634106e-34; + px[40] = 8.2266758923044609e1;pw[40] = 9.8379556343138002e-37; + px[41] = 8.7148244251462459e1;pw[41] = 7.5937692877807736e-39; + px[42] = 9.2263627069792685e1;pw[42] = 4.6460504504603365e-41; + px[43] = 9.7631314803869374e1;pw[43] = 2.2125228051355289e-43; + px[44] = 1.0327306509488168e2;pw[44] = 8.0267804054671947e-46; + px[45] = 1.0921493206709584e2;pw[45] = 2.1621413990444480e-48; + px[46] = 1.1548859679336965e2;pw[46] = 4.1913798221383726e-51; + px[47] = 1.2213329501416645e2;pw[47] = 5.6258187814957665e-54; + px[48] = 1.2919871245898944e2;pw[48] = 4.9791444365660730e-57; + px[49] = 1.3674952821727593e2;pw[49] = 2.7270187769624205e-60; + px[50] = 1.4487294472877377e2;pw[50] = 8.4854893562244169e-64; + px[51] = 1.5369207574377554e2;pw[51] = 1.3300105642340421e-67; + px[52] = 1.6339209491703519e2;pw[52] = 8.7671924329217860e-72; + px[53] = 1.7427858611626866e2;pw[53] = 1.8070041919711762e-76; + px[54] = 1.8693771869007120e2;pw[54] = 1.0229121536329777e-48; + px[55] = 2.0288303763687224e2;pw[55] = 7.4032472491198754e-53; + break; + case 64: + px[0] = 9.6008293650696286e-3;pw[0] = 3.8819522372817551e-1; + px[1] = 8.6416074005085619e-2;pw[1] = 3.5954616781559853e-1; + px[2] = 2.4009251326551299e-1;pw[2] = 3.0842087059670877e-1; + px[3] = 4.7072219845762405e-1;pw[3] = 2.4500654632827139e-1; + px[4] = 7.7844358612953627e-1;pw[4] = 1.8021735675289784e-1; + px[5] = 1.1634419969552807e0;pw[5] = 1.2272144200898013e-1; + px[6] = 1.6259502332928078e0;pw[6] = 7.7347909621273805e-2; + px[7] = 2.1662493604094500e0;pw[7] = 4.5108620335648845e-2; + px[8] = 2.7846696577606368e0;pw[8] = 2.4333837728938679e-2; + px[9] = 3.4815917481914229e0;pw[9] = 1.2137724813851775e-2; + px[10] = 4.2574479145349120e0;pw[10] = 5.5956788032115785e-3; + px[11] = 5.1127236148341415e0;pw[11] = 2.3831276289143345e-3; + px[12] = 6.0479592093454125e0;pw[12] = 9.3710307561682273e-4; + px[13] = 7.0637519146269628e0;pw[13] = 3.4002817652561882e-4; + px[14] = 8.1607580024185598e0;pw[14] = 1.1377487520080482e-4; + px[15] = 9.3396952637232506e0;pw[15] = 3.5080971696187810e-5; + px[16] = 1.0601345761568931e1;pw[16] = 9.9598490651819740e-6; + px[17] = 1.1946558899421827e1;pw[17] = 2.6014940064763985e-6; + px[18] = 1.3376254836226536e1;pw[18] = 6.2457459723578062e-7; + px[19] = 1.4891428283653888e1;pw[19] = 1.3769162244308700e-7; + px[20] = 1.6493152726464029e1;pw[20] = 2.7843814305870358e-8; + px[21] = 1.8182585113077513e1;pw[21] = 5.1587944588527896e-9; + px[22] = 1.9960971070661513e1;pw[22] = 8.7463733196968069e-10; + px[23] = 2.1829650707488929e1;pw[23] = 1.3551560975549108e-10; + px[24] = 2.3790065075269629e1;pw[24] = 1.9160633017471715e-11; + px[25] = 2.5843763375899103e1;pw[25] = 2.4684289732011134e-12; + px[26] = 2.7992411011009711e1;pw[26] = 2.8926946423808331e-13; + px[27] = 3.0237798589328330e1;pw[27] = 3.0780994607070916e-14; + px[28] = 3.2581852026749626e1;pw[28] = 2.9684476750277130e-15; + px[29] = 3.5026643897992604e1;pw[29] = 2.5890963186787431e-16; + px[30] = 3.7574406227691570e1;pw[30] = 2.0378664608465850e-17; + px[31] = 4.0227544944021652e1;pw[31] = 1.4440214633856584e-18; + px[32] = 4.2988656261067658e1;pw[32] = 9.1880153546594432e-20; + px[33] = 4.5860545309175844e1;pw[33] = 5.2349151678696223e-21; + px[34] = 4.8846247398170421e1;pw[34] = 2.6627357180671792e-22; + px[35] = 5.1949052380103696e1;pw[35] = 1.2051968064012909e-23; + px[36] = 5.5172532680822943e1;pw[36] = 4.8368069192953299e-25; + px[37] = 5.8520575699338077e1;pw[37] = 1.7145660967538707e-26; + px[38] = 6.1997421439210377e1;pw[38] = 5.3458472401161465e-28; + px[39] = 6.5607706448472386e1;pw[39] = 1.4593090013536809e-29; + px[40] = 6.9356515419807817e1;pw[40] = 3.4702060405641224e-31; + px[41] = 7.3249442163003752e1;pw[41] = 7.1487577917588421e-33; + px[42] = 7.7292662138289202e1;pw[42] = 1.2679827052732978e-34; + px[43] = 8.1493019376821402e1;pw[43] = 1.9233416135935014e-36; + px[44] = 8.5858131478224402e1;pw[44] = 2.4761711159527361e-38; + px[45] = 9.0396517560549849e1;pw[45] = 2.6829949635287387e-40; + px[46] = 9.5117755689162181e1;pw[46] = 2.4235590682611838e-42; + px[47] = 1.0003267864790140e2;pw[47] = 1.8056080277573288e-44; + px[48] = 1.0515362028215433e2;pw[48] = 1.0960434057957593e-46; + px[49] = 1.1049472958850639e2;pw[49] = 5.3454875034721357e-49; + px[50] = 1.1607237715014811e2;pw[50] = 2.0609725041113895e-51; + px[51] = 1.2190568994074218e2;pw[51] = 6.1641547666785974e-54; + px[52] = 1.2801726858944196e2;pw[52] = 1.3986145848103912e-56; + px[53] = 1.3443417070003274e2;pw[53] = 2.3439570024259610e-59; + px[54] = 1.4118929376119792e2;pw[54] = 2.8089345154809745e-62; + px[55] = 1.4832337939847587e2;pw[55] = 2.3123103281927504e-65; + px[56] = 1.5588802451891946e2;pw[56] = 1.2428488323660627e-68; + px[57] = 1.6395040789497031e2;pw[57] = 4.0831715944879700e-72; + px[58] = 1.7260112638093499e2;pw[58] = 7.5024317376094500e-76; + px[59] = 1.8196813220934213e2;pw[59] = 6.8024601738732743e-80; + px[60] = 1.9224396472236875e2;pw[60] = 2.5224989666770768e-84; + px[61] = 2.0374654228943264e2;pw[61] = 9.5158011667265254e-49; + px[62] = 2.1708611403654403e2;pw[62] = 5.3192427849433605e-52; + px[63] = 2.3383975178282573e2;pw[63] = 2.9535559171937292e-66; + break; + case 72: + px[0] = 8.5377530337449248e-3;pw[0] = 3.6646133805754739e-1; + px[1] = 7.6845831749819249e-2;pw[1] = 3.4230533863506727e-1; + px[2] = 2.1349429706226695e-1;pw[2] = 2.9865564028363514e-1; + px[3] = 4.1854784885205123e-1;pw[3] = 2.4337240372556322e-1; + px[4] = 6.9210374777076850e-1;pw[4] = 1.8521384480327197e-1; + px[5] = 1.0342920697248060e0;pw[5] = 1.3161967742383411e-1; + px[6] = 1.4452760476859431e0;pw[6] = 8.7325860377519644e-2; + px[7] = 1.9252525030070945e0;pw[7] = 5.4082218044787982e-2; + px[8] = 2.4744523690138993e0;pw[8] = 3.1257614600552892e-2; + px[9] = 3.0931413102677093e0;pw[9] = 1.6855126430119594e-2; + px[10] = 3.7816204415611087e0;pw[10] = 8.4772081114631611e-3; + px[11] = 4.5402271514220959e0;pw[11] = 3.9753232176891744e-3; + px[12] = 5.3693360356771178e0;pw[12] = 1.7375161592345435e-3; + px[13] = 6.2693599474670913e0;pw[13] = 7.0752789404236957e-4; + px[14] = 7.2407511710366363e0;pw[14] = 2.6830022946769146e-4; + px[15] = 8.2840027276389276e0;pw[15] = 9.4699597895333223e-5; + px[16] = 9.3996498230328796e0;pw[16] = 3.1095207369238697e-5; + px[17] = 1.0588271447314284e1;pw[17] = 9.4930705560516880e-6; + px[18] = 1.1850492139239455e1;pw[18] = 2.6928856004713719e-6; + px[19] = 1.3186983928793866e1;pw[19] = 7.0931074479099719e-7; + px[20] = 1.4598468473558433e1;pw[20] = 1.7336070598064455e-7; + px[21] = 1.6085719406466767e1;pw[21] = 3.9284921495770124e-8; + px[22] = 1.7649564914868501e1;pw[22] = 8.2471566241554238e-9; + px[23] = 1.9290890573464524e1;pw[23] = 1.6025182143590107e-9; + px[24] = 2.1010642456716749e1;pw[24] = 2.8794742979351125e-10; + px[25] = 2.2809830559825846e1;pw[25] = 4.7796759804694583e-11; + px[26] = 2.4689532561396773e1;pw[26] = 7.3213811680310381e-12; + px[27] = 2.6650897965571812e1;pw[27] = 1.0337134692368372e-12; + px[28] = 2.8695152666822676e1;pw[28] = 1.3436626222686719e-13; + px[29] = 3.0823603986900308e1;pw[29] = 1.6058255460718379e-14; + px[30] = 3.3037646240818195e1;pw[30] = 1.7620660009112015e-15; + px[31] = 3.5338766897405687e1;pw[31] = 1.7726340324641576e-16; + px[32] = 3.7728553410174551e1;pw[32] = 1.6323127659605682e-17; + px[33] = 4.0208700806318587e1;pw[33] = 1.3735451099194697e-18; + px[34] = 4.2781020136014409e1;pw[34] = 1.0542790113729066e-19; + px[35] = 4.5447447901312514e1;pw[35] = 7.3672431203789817e-21; + px[36] = 4.8210056604429630e1;pw[36] = 4.6773118965550795e-22; + px[37] = 5.1071066579968236e1;pw[37] = 2.6919741928296506e-23; + px[38] = 5.4032859305501852e1;pw[38] = 1.4012014167408308e-24; + px[39] = 5.7097992421357986e1;pw[39] = 6.5793246486772861e-26; + px[40] = 6.0269216734953006e1;pw[40] = 2.7792387816429709e-27; + px[41] = 6.3549495539818125e1;pw[41] = 1.0530654909535471e-28; + px[42] = 6.6942026647284918e1;pw[42] = 3.5677140725415228e-30; + px[43] = 7.0450267613328067e1;pw[43] = 1.0770556703499718e-31; + px[44] = 7.4077964749136873e1;pw[44] = 2.8865806752335222e-33; + px[45] = 7.7829186638083087e1;pw[45] = 6.8402497184153889e-35; + px[46] = 8.1708363052613987e1;pw[46] = 1.4268974543918404e-36; + px[47] = 8.5720330384148150e1;pw[47] = 2.6077204118485067e-38; + px[48] = 8.9870384983719634e1;pw[48] = 4.1533050523669125e-40; + px[49] = 9.4164346183819770e1;pw[49] = 5.7316992987700021e-42; + px[50] = 9.8608631264982208e1;pw[50] = 6.8102796020749233e-44; + px[51] = 1.0321034529045834e2;pw[51] = 6.9179617811502756e-46; + px[52] = 1.0797738962609581e2;pw[52] = 5.9610219491215519e-48; + px[53] = 1.1291859418950553e2;pw[53] = 4.3190839650906910e-50; + px[54] = 1.1804388018177253e2;pw[54] = 2.6056833265450411e-52; + px[55] = 1.2336446247428126e2;pw[55] = 1.2944535536043246e-54; + px[56] = 1.2889310430876951e2;pw[56] = 5.2287531735186084e-57; + px[57] = 1.3464444208967572e2;pw[57] = 1.6926455724514031e-59; + px[58] = 1.4063540573754781e2;pw[58] = 4.3183461553903832e-62; + px[59] = 1.4688577190557120e2;pw[59] = 8.5145486452100040e-65; + px[60] = 1.5341890608220506e2;pw[60] = 1.2678660729891205e-67; + px[61] = 1.6026278017056644e2;pw[61] = 1.3869468532834784e-70; + px[62] = 1.6745140389442310e2;pw[62] = 1.0778332837412283e-73; + px[63] = 1.7502689981511292e2;pw[63] = 5.7084939874269743e-77; + px[64] = 1.8304262155336948e2;pw[64] = 1.9550707098857624e-80; + px[65] = 1.9156804971323859e2;pw[65] = 4.0440344494888973e-84; + px[66] = 2.0069691105825289e2;pw[66] = 4.6082741548145242e-88; + px[67] = 2.1056162324265798e2;pw[67] = 2.5411102164420924e-92; + px[68] = 2.2136152670104394e2;pw[68] = 5.5818464378910382e-97; + px[69] = 2.3342593022383359e2;pw[69] = 3.8018252344681360e-50; + px[70] = 2.4738731475402643e2;pw[70] = 2.0795745925390798e-53; + px[71] = 2.6488137073545847e2;pw[71] = 5.9029492520141047e-68; + break; + case 80: + px[0] = 7.6866318444038650e-3;pw[0] = 3.4801121234964061e-1; + px[1] = 6.9184104726922287e-2;pw[1] = 3.2728554809172511e-1; + px[2] = 1.9220262418784241e-1;pw[2] = 2.8945683894699143e-1; + px[3] = 3.7678938735594810e-1;pw[3] = 2.4073751764332210e-1; + px[4] = 6.2301531452046157e-1;pw[4] = 1.8826779554366350e-1; + px[5] = 9.3097519935847685e-1;pw[5] = 1.3843298565975990e-1; + px[6] = 1.3007879104323092e0;pw[6] = 9.5693623713172557e-2; + px[7] = 1.7325966449946741e0;pw[7] = 6.2179086370712325e-2; + px[8] = 2.2265692364173354e0;pw[8] = 3.7970908655009312e-2; + px[9] = 2.7828985168491514e0;pw[9] = 2.1788109306695115e-2; + px[10] = 3.4018027370152287e0;pw[10] = 1.1745069517438239e-2; + px[11] = 4.0835260453933245e0;pw[11] = 5.9463917421429804e-3; + px[12] = 4.8283390293501774e0;pw[12] = 2.8268077494244823e-3; + px[13] = 5.6365393211929032e0;pw[13] = 1.2614066531994309e-3; + px[14] = 6.5084522724931878e0;pw[14] = 5.2818895724163281e-4; + px[15] = 7.4444317004794741e0;pw[15] = 2.0746547336341577e-4; + px[16] = 8.4448607107699771e0;pw[16] = 7.6411540013651783e-5; + px[17] = 9.5101526012431861e0;pw[17] = 2.6378489263127714e-5; + px[18] = 1.0640751852419332e1;pw[18] = 8.5315214346510367e-6; + px[19] = 1.1837135210363891e1;pw[19] = 2.5839402017229379e-6; + px[20] = 1.3099812868831478e1;pw[20] = 7.3248237980755977e-7; + px[21] = 1.4429329758155656e1;pw[21] = 1.9423835172306337e-7; + px[22] = 1.5826266949269123e1;pw[22] = 4.8155353038663436e-8; + px[23] = 1.7291243182222957e1;pw[23] = 1.1154712143820550e-8; + px[24] = 1.8824916529679155e1;pw[24] = 2.4126359656654055e-9; + px[25] = 2.0427986207095807e1;pw[25] = 4.8690306206928333e-10; + px[26] = 2.2101194542730669e1;pw[26] = 9.1619835022640038e-11; + px[27] = 2.3845329122181760e1;pw[27] = 1.6061727543126440e-11; + px[28] = 2.5661225123992617e1;pw[28] = 2.6211365629406585e-12; + px[29] = 2.7549767864910021e1;pw[29] = 3.9783127491115241e-13; + px[30] = 2.9511895575734651e1;pw[30] = 5.6106664386726106e-14; + px[31] = 3.1548602431399443e1;pw[31] = 7.3452477074096906e-15; + px[32] = 3.3660941862004724e1;pw[32] = 8.9170156740924202e-16; + px[33] = 3.5850030175103469e1;pw[33] = 1.0027003519531224e-16; + px[34] = 3.8117050523647834e1;pw[34] = 1.0431576805686864e-17; + px[35] = 4.0463257258780339e1;pw[35] = 1.0027987156316190e-18; + px[36] = 4.2889980712201399e1;pw[36] = 8.8958541452840810e-20; + px[37] = 4.5398632459316878e1;pw[37] = 7.2721294867218350e-21; + px[38] = 4.7990711121944935e1;pw[38] = 5.4700089499572571e-22; + px[39] = 5.0667808778260416e1;pw[39] = 3.7798889589128719e-23; + px[40] = 5.3431618058147838e1;pw[40] = 2.3955393929296669e-24; + px[41] = 5.6283940014554144e1;pw[41] = 1.3898975276677134e-25; + px[42] = 5.9226692876193983e1;pw[42] = 7.3686649638685550e-27; + px[43] = 6.2261921804579421e1;pw[43] = 3.5623617964926723e-28; + px[44] = 6.5391809799470289e1;pw[44] = 1.5670671394405450e-29; + px[45] = 6.8618689922287050e1;pw[45] = 6.2579202126857896e-31; + px[46] = 7.1945059037830997e1;pw[46] = 2.2630134382743232e-32; + px[47] = 7.5373593312139102e1;pw[47] = 7.3910051432137950e-34; + px[48] = 7.8907165750162510e1;pw[48] = 2.1738965407946768e-35; + px[49] = 8.2548866113398157e1;pw[49] = 5.7406301865352811e-37; + px[50] = 8.6302023627490826e1;pw[50] = 1.3565280389341554e-38; + px[51] = 9.0170232976927819e1;pw[51] = 2.8582178093556767e-40; + px[52] = 9.4157384193266820e1;pw[52] = 5.3491017715110987e-42; + px[53] = 9.8267697181550113e1;pw[53] = 8.8545200956130098e-44; + px[54] = 1.0250576180568381e2;pw[54] = 1.2905303360994193e-45; + px[55] = 1.0687658467989708e2;pw[55] = 1.6479024314408629e-47; + px[56] = 1.1138564410689640e2;pw[56] = 1.8335510486003441e-49; + px[57] = 1.1603895498763616e2;pw[57] = 1.7670959327066303e-51; + px[58] = 1.2084314603612786e2;pw[58] = 1.4654679930191558e-53; + px[59] = 1.2580555231319460e2;pw[59] = 1.0382012259739465e-55; + px[60] = 1.3093432701495951e2;pw[60] = 6.2325264712640765e-58; + px[61] = 1.3623857771756320e2;pw[61] = 3.1419744937690600e-60; + px[62] = 1.4172853404292507e2;pw[62] = 1.3167216299744360e-62; + px[63] = 1.4741575620660480e2;pw[63] = 4.5348612513885167e-65; + px[64] = 1.5331339750560076e2;pw[64] = 1.2669383082047862e-67; + px[65] = 1.5943653908891510e2;pw[65] = 2.8286860158479256e-70; + px[66] = 1.6580262329068657e2;pw[66] = 4.9608576653838684e-73; + px[67] = 1.7243202402097285e2;pw[67] = 6.6976362308197039e-76; + px[68] = 1.7934881203693207e2;pw[68] = 6.7974784724244015e-79; + px[69] = 1.8658180447952091e2;pw[69] = 5.0405265141181345e-82; + px[70] = 1.9416604151140286e2;pw[70] = 2.6380873260356514e-85; + px[71] = 2.0214492732686698e2;pw[71] = 9.3369329897351393e-89; + px[72] = 2.1057344821155215e2;pw[72] = 2.1169241731154879e-92; + px[73] = 2.1952322632251781e2;pw[73] = 2.8655194931946936e-96; + px[74] = 2.2909090256827742e2;pw[74] = 2.1061692586895640e-100; + px[75] = 2.3941305411072180e2;pw[75] = 7.6547423878179816e-105; + px[76] = 2.5069535780481856e2;pw[76] = 4.5949033294697062e-51; + px[77] = 2.6327773413988054e2;pw[77] = 6.4123032211485360e-55; + px[78] = 2.7781337017790295e2;pw[78] = 2.6355344341971242e-68; + px[79] = 2.9599252372507157e2;pw[79] = 4.2626228488835649e-81; + break; + case 88: + px[0] = 6.9898229051547411e-3;pw[0] = 3.3209344438409325e-1; + px[1] = 6.2911728289785692e-2;pw[1] = 3.1405674898440063e-1; + px[2] = 1.7477326359221082e-1;pw[2] = 2.8086402575909276e-1; + px[3] = 3.4260990879552213e-1;pw[3] = 2.3752476979765092e-1; + px[4] = 5.6647496129652395e-1;pw[4] = 1.8994306166644856e-1; + px[5] = 8.4643962917804553e-1;pw[5] = 1.4361800366234363e-1; + px[6] = 1.1825931561845759e0;pw[6] = 1.0266599963917014e-1; + px[7] = 1.5750429789323641e0;pw[7] = 6.9379346479544336e-2; + px[8] = 2.0239149170256255e0;pw[8] = 4.4316467105237175e-2; + px[9] = 2.5293533968962740e0;pw[9] = 2.6752780145097017e-2; + px[10] = 3.0915217103368590e0;pw[10] = 1.5260575426000781e-2; + px[11] = 3.7106023088564040e0;pw[11] = 8.2241712678339878e-3; + px[12] = 4.3867971351580078e0;pw[12] = 4.1864435774652050e-3; + px[13] = 5.1203279932168699e0;pw[13] = 2.0124922623294288e-3; + px[14] = 5.9114369586294842e0;pw[14] = 9.1338594776452588e-4; + px[15] = 6.7603868311109156e0;pw[15] = 3.9128377994473102e-4; + px[16] = 7.6674616312393195e0;pw[16] = 1.5816991465628900e-4; + px[17] = 8.6329671437874178e0;pw[17] = 6.0313998121755884e-5; + px[18] = 9.6572315102419724e0;pw[18] = 2.1688652721856188e-5; + px[19] = 1.0740605873397186e1;pw[19] = 7.3521662189359001e-6; + px[20] = 1.1883465077219540e1;pw[20] = 2.3485735170662032e-6; + px[21] = 1.3086208425523377e1;pw[21] = 7.0668575490339494e-7; + px[22] = 1.4349260503372554e1;pw[22] = 2.0021570985018051e-7; + px[23] = 1.5673072065538298e1;pw[23] = 5.3385656195939403e-8; + px[24] = 1.7058120996802116e1;pw[24] = 1.3390564636227622e-8; + px[25] = 1.8504913349401250e1;pw[25] = 3.1579273648368550e-9; + px[26] = 2.0013984463479417e1;pw[26] = 6.9984639734477468e-10; + px[27] = 2.1585900177035253e1;pw[27] = 1.4566522851312418e-10; + px[28] = 2.3221258132563997e1;pw[28] = 2.8457916194634976e-11; + px[29] = 2.4920689188374744e1;pw[29] = 5.2152057446839083e-12; + px[30] = 2.6684858943448156e1;pw[30] = 8.9592785232829909e-13; + px[31] = 2.8514469385691634e1;pw[31] = 1.4417973875868243e-13; + px[32] = 3.0410260674566840e1;pw[32] = 2.1719253795631441e-14; + px[33] = 3.2373013070326923e1;pw[33] = 3.0602546728763147e-15; + px[34] = 3.4403549023529919e1;pw[34] = 4.0298283180374064e-16; + px[35] = 3.6502735440116345e1;pw[35] = 4.9551512528428224e-17; + px[36] = 3.8671486139183441e1;pw[36] = 5.6842543746643022e-18; + px[37] = 4.0910764522691699e1;pw[37] = 6.0774264422552206e-19; + px[38] = 4.3221586478743604e1;pw[38] = 6.0500123323576681e-20; + px[39] = 4.5605023542830377e1;pw[39] = 5.6016998994982451e-21; + px[40] = 4.8062206344609867e1;pw[40] = 4.8186081446164731e-22; + px[41] = 5.0594328371429292e1;pw[41] = 3.8463215773862006e-23; + px[42] = 5.3202650084026280e1;pw[42] = 2.8454232488178569e-24; + px[43] = 5.5888503424734049e1;pw[43] = 1.9482724641523455e-25; + px[44] = 5.8653296764206622e1;pw[44] = 1.2329494549301778e-26; + px[45] = 6.1498520339319444e1;pw[45] = 7.2009452095564265e-28; + px[46] = 6.4425752242674225e1;pw[46] = 3.8752556618667624e-29; + px[47] = 6.7436665033270514e1;pw[47] = 1.9184700627092652e-30; + px[48] = 7.0533033048677930e1;pw[48] = 8.7214115374171135e-32; + px[49] = 7.3716740511795214e1;pw[49] = 3.6339711712303267e-33; + px[50] = 7.6989790540440737e1;pw[50] = 1.3850762473413167e-34; + px[51] = 8.0354315186114501e1;pw[51] = 4.8188380976506615e-36; + px[52] = 8.3812586649969540e1;pw[52] = 1.5268836098287974e-37; + px[53] = 8.7367029850170202e1;pw[53] = 4.3955893390762546e-39; + px[54] = 9.1020236546461036e1;pw[54] = 1.1467178326064145e-40; + px[55] = 9.4774981266282465e1;pw[55] = 2.7034989251018274e-42; + px[56] = 9.8634239323895773e1;pw[56] = 5.7430338090994212e-44; + px[57] = 1.0260120728198211e2;pw[57] = 1.0957767689227991e-45; + px[58] = 1.0667932627700808e2;pw[58] = 1.8714704533178499e-47; + px[59] = 1.1087230871918132e2;pw[59] = 2.8505049132116738e-49; + px[60] = 1.1518416899019180e2;pw[60] = 3.8566146717396706e-51; + px[61] = 1.1961925890402067e2;pw[61] = 4.6148622579363381e-53; + px[62] = 1.2418230887717554e2;pw[62] = 4.8611462511088885e-55; + px[63] = 1.2887847598742982e2;pw[63] = 4.4845808683072384e-57; + px[64] = 1.3371340040194700e2;pw[64] = 3.6030988117615386e-59; + px[65] = 1.3869327205088259e2;pw[65] = 2.5057229445134590e-61; + px[66] = 1.4382490994553306e2;pw[66] = 1.4981434219579486e-63; + px[67] = 1.4911585724002039e2;pw[67] = 7.6434036433722766e-66; + px[68] = 1.5457449608379523e2;pw[68] = 3.3000635664912984e-68; + px[69] = 1.6021018761433266e2;pw[69] = 1.1946162455653543e-70; + px[70] = 1.6603344425357073e2;pw[70] = 3.5882216086453966e-73; + px[71] = 1.7205614404012268e2;pw[71] = 8.8381795575894759e-76; + px[72] = 1.7829180043052003e2;pw[72] = 1.7614304684723708e-78; + px[73] = 1.8475590644174345e2;pw[73] = 2.7972091009100451e-81; + px[74] = 1.9146638017638173e2;pw[74] = 3.4772790784565961e-84; + px[75] = 1.9844415134556974e2;pw[75] = 3.3145008476708899e-87; + px[76] = 2.0571394830191976e2;pw[76] = 2.3639811252252232e-90; + px[77] = 2.1330537759040182e2;pw[77] = 1.2252220679209011e-93; + px[78] = 2.2125444306253341e2;pw[78] = 4.4534409258766820e-97; + px[79] = 2.2960574884915661e2;pw[79] = 1.0863817141918454e-100; + px[80] = 2.3841581114398289e2;pw[80] = 1.6822680293726604e-104; + px[81] = 2.4775826014248507e2;pw[81] = 1.5380603201854840e-108; + px[82] = 2.5773247037077271e2;pw[82] = 7.5305256625793262e-113; + px[83] = 2.6847892170878440e2;pw[83] = 1.7204742760900275e-117; + px[84] = 2.8020923651927812e2;pw[84] = 2.4712355922645459e-52; + px[85] = 2.9327329106785954e2;pw[85] = 2.0946397303280510e-50; + px[86] = 3.0834369296097073e2;pw[86] = 9.0428276327931568e-65; + px[87] = 3.2716185523285862e2;pw[87] = 1.9175767652062620e-79; + break; + case 96: + px[0] = 6.4088479693086173e-3;pw[0] = 3.1817720207314518e-1; + px[1] = 5.7682192384603139e-2;pw[1] = 3.0229450239014958e-1; + px[2] = 1.6024254224241131e-1;pw[2] = 2.7286429856942241e-1; + px[3] = 3.1411723962617867e-1;pw[3] = 2.3399502554972005e-1; + px[4] = 5.1934734780450853e-1;pw[4] = 1.9063041737616373e-1; + px[5] = 7.7598771160231075e-1;pw[5] = 1.4752978061991784e-1; + px[6] = 1.0841070382287637e0;pw[6] = 1.0845245228344696e-1; + px[7] = 1.4437879988503862e0;pw[7] = 7.5724332195484464e-2; + px[8] = 1.8551273512731066e0;pw[8] = 5.0214141133917932e-2; + px[9] = 2.3182360841752035e0;pw[9] = 3.1620089370995634e-2; + px[10] = 2.8332395834139107e0;pw[10] = 1.8905681570520517e-2; + px[11] = 3.4002778210128949e0;pw[11] = 1.0731321018794248e-2; + px[12] = 4.0195055675263257e0;pw[12] = 5.7820073860565274e-3; + px[13] = 4.6910926285685173e0;pw[13] = 2.9566179089772504e-3; + px[14] = 5.4152241063968240e0;pw[14] = 1.4345733126805138e-3; + px[15] = 6.1921006875403740e0;pw[15] = 6.6035034249772304e-4; + px[16] = 7.0219389575791665e0;pw[16] = 2.8830782856393540e-4; + px[17] = 7.9049717442979328e0;pw[17] = 1.1936254041747660e-4; + px[18] = 8.8414484905679871e0;pw[18] = 4.6849104586421198e-5; + px[19] = 9.8316356584491658e0;pw[19] = 1.7427730160295739e-5; + px[20] = 1.0875817166154111e1;pw[20] = 6.1427630640308088e-6; + px[21] = 1.1974294859679961e1;pw[21] = 2.0508762851384060e-6; + px[22] = 1.3127389021089503e1;pw[22] = 6.4837954271472021e-7; + px[23] = 1.4335438915616705e1;pw[23] = 1.9403784928607733e-7; + px[24] = 1.5598803379982271e1;pw[24] = 5.4948470407217337e-8; + px[25] = 1.6917861454535469e1;pw[25] = 1.4718810972300389e-8; + px[26] = 1.8293013062091624e1;pw[26] = 3.7279041518397285e-9; + px[27] = 1.9724679736612835e1;pw[27] = 8.9237873517832415e-10; + px[28] = 2.1213305405186056e1;pw[28] = 2.0180598524189019e-10; + px[29] = 2.2759357227090996e1;pw[29] = 4.3094025836606105e-11; + px[30] = 2.4363326494124491e1;pw[30] = 8.6853173406217016e-12; + px[31] = 2.6025729596762688e1;pw[31] = 1.6512638032485222e-12; + px[32] = 2.7747109061202697e1;pw[32] = 2.9598835329453310e-13; + px[33] = 2.9528034662837436e1;pw[33] = 4.9993510953075103e-14; + px[34] = 3.1369104622288073e1;pw[34] = 7.9519688037928626e-15; + px[35] = 3.3270946890755629e1;pw[35] = 1.1903810906669537e-15; + px[36] = 3.5234220532166221e1;pw[36] = 1.6759557500075327e-16; + px[37] = 3.7259617210383481e1;pw[37] = 2.2177113226367451e-17; + px[38] = 3.9347862790659313e1;pw[38] = 2.7561280628581385e-18; + px[39] = 4.1499719065504354e1;pw[39] = 3.2145199936756972e-19; + px[40] = 4.3715985616298953e1;pw[40] = 3.5156800159203487e-20; + px[41] = 4.5997501823253394e1;pw[41] = 3.6025990545465830e-21; + px[42] = 4.8345149037785020e1;pw[42] = 3.4558483324761214e-22; + px[43] = 5.0759852933036353e1;pw[43] = 3.1004532672815943e-23; + px[44] = 5.3242586050143369e1;pw[44] = 2.5990033771037196e-24; + px[45] = 5.5794370560013523e1;pw[45] = 2.0335626660738988e-25; + px[46] = 5.8416281262832383e1;pw[46] = 1.4835853103395276e-26; + px[47] = 6.1109448850337470e1;pw[47] = 1.0080516345867198e-27; + px[48] = 6.3875063459139563e1;pw[48] = 6.3716760141675274e-29; + px[49] = 6.6714378547108836e1;pw[49] = 3.7418231588440592e-30; + px[50] = 6.9628715129163805e1;pw[50] = 2.0389207136140223e-31; + px[51] = 7.2619466413811364e1;pw[51] = 1.0294436657754091e-32; + px[52] = 7.5688102887614222e1;pw[52] = 4.8089946872814419e-34; + px[53] = 7.8836177901563518e1;pw[53] = 2.0753148425343429e-35; + px[54] = 8.2065333821298500e1;pw[54] = 8.2600326269673452e-37; + px[55] = 8.5377308812473848e1;pw[55] = 3.0268879909029589e-38; + px[56] = 8.8773944343613222e1;pw[56] = 1.0193701477126852e-39; + px[57] = 9.2257193501856653e1;pw[57] = 3.1487953377266536e-41; + px[58] = 9.5829130232545822e1;pw[58] = 8.9030283898555212e-43; + px[59] = 9.9491959632139456e1;pw[59] = 2.2991067830207375e-44; + px[60] = 1.0324802944619364e2;pw[60] = 5.4099632013102152e-46; + px[61] = 1.0709984295093964e2;pw[61] = 1.1570760541533550e-47; + px[62] = 1.1105007342943756e2;pw[62] = 2.2434027937343383e-49; + px[63] = 1.1510158049277213e2;pw[63] = 3.9318356145233163e-51; + px[64] = 1.1925742854508090e2;pw[64] = 6.2101615333023767e-53; + px[65] = 1.2352090775068523e2;pw[65] = 8.8106771041998731e-55; + px[66] = 1.2789555793525788e2;pw[66] = 1.1188872437683772e-56; + px[67] = 1.3238519594478634e2;pw[67] = 1.2670287078247711e-58; + px[68] = 1.3699394710135137e2;pw[68] = 1.2741754871478997e-60; + px[69] = 1.4172628154048866e2;pw[69] = 1.1328848065466888e-62; + px[70] = 1.4658705640065854e2;pw[70] = 8.8625846243039034e-65; + px[71] = 1.5158156507410060e2;pw[71] = 6.0683384585205647e-67; + px[72] = 1.5671559503799880e2;pw[72] = 3.6159126920762266e-69; + px[73] = 1.6199549619039953e2;pw[73] = 1.8632314937659433e-71; + px[74] = 1.6742826215197814e2;pw[74] = 8.2452068773611101e-74; + px[75] = 1.7302162771302658e2;pw[75] = 3.1094858299677929e-76; + px[76] = 1.7878418657827880e2;pw[76] = 9.9088925545678630e-79; + px[77] = 1.8472553489864371e2;pw[77] = 2.6428813129457523e-81; + px[78] = 1.9085644794111835e2;pw[78] = 5.8372225441875102e-84; + px[79] = 1.9718909988484638e2;pw[79] = 1.0548005520682382e-86; + px[80] = 2.0373734053112526e2;pw[80] = 1.5381913402837248e-89; + px[81] = 2.1051704829955498e2;pw[81] = 1.7819545894948543e-92; + px[82] = 2.1754658727070438e2;pw[82] = 1.6104009725265265e-95; + px[83] = 2.2484740894787622e2;pw[83] = 1.1114881452557864e-98; + px[84] = 2.3244485984497173e2;pw[84] = 5.7137871484250277e-102; + px[85] = 2.4036928938394857e2;pw[85] = 2.1230825957651528e-105; + px[86] = 2.4865760911996251e2;pw[86] = 5.4979966939612256e-109; + px[87] = 2.5735555421768465e2;pw[87] = 9.4850943127338216e-113; + px[88] = 2.6652108371132283e2;pw[88] = 1.0296088521328023e-116; + px[89] = 2.7622972228180378e2;pw[89] = 6.4585972823499812e-121; + px[90] = 2.8658342409205652e2;pw[90] = 1.7529595043807457e-117; + px[91] = 2.9772635225359436e2;pw[91] = 3.1105665306320562e-130; + px[92] = 3.0987574005931242e2;pw[92] = 2.5102657022454895e-50; + px[93] = 3.2339085777326039e2;pw[93] = 1.1598746411740026e-54; + px[94] = 3.3896263242081578e2;pw[94] = 1.8735722301688603e-68; + px[95] = 3.5838071121369978e2;pw[95] = 3.6413912508706140e-80; + break; + case 104: + px[0] = 5.9170399902629313e-3;pw[0] = 3.0587540675027521e-1; + px[1] = 5.3255375119357608e-2;pw[1] = 2.9174971091826186e-1; + px[2] = 1.4794279594504654e-1;pw[2] = 2.6542237352386527e-1; + px[3] = 2.9000081703620763e-1;pw[3] = 2.3031197872444814e-1; + px[4] = 4.7946174387139034e-1;pw[4] = 1.9060462767137745e-1; + px[5] = 7.1636871330281893e-1;pw[5] = 1.5044217126994679e-1; + px[6] = 1.0007757476986113e0;pw[6] = 1.1324045142276644e-1; + px[7] = 1.3327478229276096e0;pw[7] = 8.1283295752663497e-2; + px[8] = 1.7123609503940247e0;pw[8] = 5.5633427651614899e-2; + px[9] = 2.1397022733730653e0;pw[9] = 3.6305080311286526e-2; + px[10] = 2.6148701779441033e0;pw[10] = 2.2586734959646651e-2; + px[11] = 3.1379744188649923e0;pw[11] = 1.3395115370766690e-2; + px[12] = 3.7091362607801872e0;pw[12] = 7.5717088395729501e-3; + px[13] = 4.3284886352066046e0;pw[13] = 4.0788547539583762e-3; + px[14] = 4.9961763137950506e0;pw[14] = 2.0937112294538550e-3; + px[15] = 5.7123560984218524e0;pw[15] = 1.0239096611160486e-3; + px[16] = 6.4771970287254551e0;pw[16] = 4.7697940575163359e-4; + px[17] = 7.2908806077665737e0;pw[17] = 2.1161778351897556e-4; + px[18] = 8.1536010465584800e0;pw[18] = 8.9399513582116538e-5; + px[19] = 9.0655655282866201e0;pw[19] = 3.5954968465819779e-5; + px[20] = 1.0026994493114549e1;pw[20] = 1.3763471639247608e-5; + px[21] = 1.1038121944556697e1;pw[21] = 5.0135007842022910e-6; + px[22] = 1.2099195778488418e1;pw[22] = 1.7373642266442212e-6; + px[23] = 1.3210478135960773e1;pw[23] = 5.7261651269671511e-7; + px[24] = 1.4372245781092441e1;pw[24] = 1.7944867221251103e-7; + px[25] = 1.5584790505424801e1;pw[25] = 5.3455660388561925e-8; + px[26] = 1.6848419560249673e1;pw[26] = 1.5131821405551822e-8; + px[27] = 1.8163456118553402e1;pw[27] = 4.0690485475645235e-9; + px[28] = 1.9530239768367304e1;pw[28] = 1.0390864670042617e-9; + px[29] = 2.0949127039474128e1;pw[29] = 2.5189139018781987e-10; + px[30] = 2.2420491965594827e1;pw[30] = 5.7944986530631928e-11; + px[31] = 2.3944726684371185e1;pw[31] = 1.2644148134587503e-11; + px[32] = 2.5522242077669684e1;pw[32] = 2.6161135978115952e-12; + px[33] = 2.7153468454962594e1;pw[33] = 5.1301572545741211e-13; + px[34] = 2.8838856282796113e1;pw[34] = 9.5305252540215033e-14; + px[35] = 3.0578876963635225e1;pw[35] = 1.6765288843561763e-14; + px[36] = 3.2374023667684009e1;pw[36] = 2.7912570841914264e-15; + px[37] = 3.4224812221621939e1;pw[37] = 4.3960232489011666e-16; + px[38] = 3.6131782058575501e1;pw[38] = 6.5457287737442617e-17; + px[39] = 3.8095497234064709e1;pw[39] = 9.2097916367430484e-18; + px[40] = 4.0116547513131397e1;pw[40] = 1.2237146175390552e-18; + px[41] = 4.2195549534376423e1;pw[41] = 1.5345540324461345e-19; + px[42] = 4.4333148057213359e1;pw[42] = 1.8150011522883905e-20; + px[43] = 4.6530017299294814e1;pw[43] = 2.0233572060917363e-21; + px[44] = 4.8786862371793691e1;pw[44] = 2.1245357575136396e-22; + px[45] = 5.1104420821036147e1;pw[45] = 2.0995790452740547e-23; + px[46] = 5.3483464285898315e1;pw[46] = 1.9513862776804163e-24; + px[47] = 5.5924800281409502e1;pw[47] = 1.7043065745685083e-25; + px[48] = 5.8429274120167462e1;pw[48] = 1.3975904770003455e-26; + px[49] = 6.0997770984486184e1;pw[49] = 1.0751199957435543e-27; + px[50] = 6.3631218163686521e1;pw[50] = 7.7513543786225607e-29; + px[51] = 6.6330587472631968e1;pw[51] = 5.2326478018346559e-30; + px[52] = 6.9096897869537813e1;pw[52] = 3.3040599143163473e-31; + px[53] = 7.1931218293279340e1;pw[53] = 1.9493708377000895e-32; + px[54] = 7.4834670742938227e1;pw[54] = 1.0734353038941787e-33; + px[55] = 7.7808433625208567e1;pw[55] = 5.5103919609823204e-35; + px[56] = 8.0853745398597933e1;pw[56] = 2.6337753192506890e-36; + px[57] = 8.3971908547179854e1;pw[57] = 1.1705805971768911e-37; + px[58] = 8.7164293921072095e1;pw[58] = 4.8312277173311803e-39; + px[59] = 9.0432345485938809e1;pw[59] = 1.8489404848533130e-40; + px[60] = 9.3777585529775213e1;pw[60] = 6.5514799851540860e-42; + px[61] = 9.7201620382189983e1;pw[61] = 2.1459149564917285e-43; + px[62] = 1.0070614670954704e2;pw[62] = 6.4864747764771309e-45; + px[63] = 1.0429295845890204e2;pw[63] = 1.8061451197301461e-46; + px[64] = 1.0796395453496108e2;pw[64] = 4.6240601087164368e-48; + px[65] = 1.1172114730766026e2;pw[65] = 1.0863042774855916e-49; + px[66] = 1.1556667206386112e2;pw[66] = 2.3367590047772692e-51; + px[67] = 1.1950279753563604e2;pw[67] = 4.5923018372463456e-53; + px[68] = 1.2353193766037873e2;pw[68] = 8.2254183241711378e-55; + px[69] = 1.2765666475539859e2;pw[69] = 1.3393229733255628e-56; + px[70] = 1.3187972432286344e2;pw[70] = 1.9770897715441433e-58; + px[71] = 1.3620405174137066e2;pw[71] = 2.6382340385810416e-60; + px[72] = 1.4063279114988850e2;pw[72] = 3.1724019756972273e-62; + px[73] = 1.4516931689069355e2;pw[73] = 3.4260518574631090e-64; + px[74] = 1.4981725795333762e2;pw[74] = 3.3110336284062607e-66; + px[75] = 1.5458052595568164e2;pw[75] = 2.8523873910804969e-68; + px[76] = 1.5946334731603723e2;pw[76] = 2.1812446026410382e-70; + px[77] = 1.6447030041968208e2;pw[77] = 1.4739245558990479e-72; + px[78] = 1.6960635877321616e2;pw[78] = 8.7573978000268771e-75; + px[79] = 1.7487694138470448e2;pw[79] = 4.5505714966004102e-77; + px[80] = 1.8028797192464818e2;pw[80] = 2.0558561295409975e-79; + px[81] = 1.8584594863812376e2;pw[81] = 8.0232998204915563e-82; + px[82] = 1.9155802752806165e2;pw[82] = 2.6857246723649169e-84; + px[83] = 1.9743212206533502e2;pw[83] = 7.6508024905351989e-87; + px[84] = 2.0347702367824598e2;pw[84] = 1.8386578992442195e-89; + px[85] = 2.0970254864305275e2;pw[85] = 3.6915967746713164e-92; + px[86] = 2.1611971890494698e2;pw[86] = 6.1249132399226474e-95; + px[87] = 2.2274098706028915e2;pw[87] = 8.2946217677700358e-98; + px[88] = 2.2958051962428511e2;pw[88] = 9.0408055705882247e-101; + px[89] = 2.3665455843056904e2;pw[89] = 7.8044833919279015e-104; + px[90] = 2.4398188860512600e2;pw[90] = 5.2375692667980381e-107; + px[91] = 2.5158445479007743e2;pw[91] = 2.6738203410490589e-110; + px[92] = 2.5948818823677792e2;pw[92] = 1.0120749135417976e-113; + px[93] = 2.6772414159918294e2;pw[93] = 2.7544888677231600e-117; + px[94] = 2.7633008621234766e2;pw[94] = 5.1929686996596160e-121; + px[95] = 2.8535282906339674e2;pw[95] = 6.4755792717472659e-125; + px[96] = 2.9485169696486133e2;pw[96] = 5.0218621637969880e-129; + px[97] = 3.0490401093647767e2;pw[97] = 1.9758139579198723e-133; + px[98] = 3.1561417142961915e2;pw[98] = 2.6170200395803803e-134; + px[99] = 3.2712983445040887e2;pw[99] = 2.0394890255436422e-51; + px[100] = 3.3967355383586156e2;pw[100] = 1.9410589620744451e-56; + px[101] = 3.5361350610111344e2;pw[101] = 1.9061593758307076e-70; + px[102] = 3.6965798176808293e2;pw[102] = 9.4662691701560053e-80; + px[103] = 3.8964232774217858e2;pw[103] = 1.1104725813752798e-82; + break; + case 112: + px[0] = 5.4953341803301609e-3;pw[0] = 2.9489826922398073e-1; + px[1] = 4.9459621920962637e-2;pw[1] = 2.8222796178145113e-1; + px[2] = 1.3739680892391444e-1;pw[2] = 2.5849487746587741e-1; + px[3] = 2.6932412751335894e-1;pw[3] = 2.2657942282144552e-1; + px[4] = 4.4526744940170549e-1;pw[4] = 1.9006161252137982e-1; + px[5] = 6.6526131362871422e-1;pw[5] = 1.5256636998998856e-1; + px[6] = 9.2934896392688816e-1;pw[6] = 1.1719118584424322e-1; + px[7] = 1.2375823956108998e0;pw[7] = 8.6135126997093899e-2; + px[8] = 1.5900224121141247e0;pw[8] = 6.0574317417714514e-2; + px[9] = 1.9867386913212612e0;pw[9] = 4.0755803971739961e-2; + px[10] = 2.4278098618726480e0;pw[10] = 2.6233066082736348e-2; + px[11] = 2.9133235896433742e0;pw[11] = 1.6152112426163087e-2; + px[12] = 3.4433766746287615e0;pw[12] = 9.5123620147754134e-3; + px[13] = 4.0180751584974267e0;pw[13] = 5.3577229622045945e-3; + px[14] = 4.6375344431040623e0;pw[14] = 2.8857253991993310e-3; + px[15] = 5.3018794202864780e0;pw[15] = 1.4861359153491582e-3; + px[16] = 6.0112446133054996e0;pw[16] = 7.3169919995809469e-4; + px[17] = 6.7657743303222200e0;pw[17] = 3.4436155411986205e-4; + px[18] = 7.5656228303450516e0;pw[18] = 1.5489520162150497e-4; + px[19] = 8.4109545021192616e0;pw[19] = 6.6578086192592747e-5; + px[20] = 9.3019440564744304e0;pw[20] = 2.7341291782963178e-5; + px[21] = 1.0238776732690826e1;pw[21] = 1.0725583190203260e-5; + px[22] = 1.1221648519494320e1;pw[22] = 4.0183900973494323e-6; + px[23] = 1.2250766391341530e1;pw[23] = 1.4375499392088491e-6; + px[24] = 1.3326348560712631e1;pw[24] = 4.9095191796603443e-7; + px[25] = 1.4448624747189284e1;pw[25] = 1.6002973367034795e-7; + px[26] = 1.5617836464159565e1;pw[26] = 4.9774112595986853e-8; + px[27] = 1.6834237324061373e1;pw[27] = 1.4768543773235768e-8; + px[28] = 1.8098093363150867e1;pw[28] = 4.1791497540829771e-9; + px[29] = 1.9409683386863716e1;pw[29] = 1.1275442160204611e-9; + px[30] = 2.0769299336924940e1;pw[30] = 2.8996675589492684e-10; + px[31] = 2.2177246681458568e1;pw[31] = 7.1055803679543191e-11; + px[32] = 2.3633844829452103e1;pw[32] = 1.6586292637190786e-11; + px[33] = 2.5139427571043608e1;pw[33] = 3.6868289748704489e-12; + px[34] = 2.6694343545222255e1;pw[34] = 7.8011677084046385e-13; + px[35] = 2.8298956736667379e1;pw[35] = 1.5707664005052362e-13; + px[36] = 2.9953647003597728e1;pw[36] = 3.0084617930185426e-14; + px[37] = 3.1658810638663093e1;pw[37] = 5.4788162867425923e-15; + px[38] = 3.3414860965086388e1;pw[38] = 9.4832975673093346e-16; + px[39] = 3.5222228970457193e1;pw[39] = 1.5594657436863047e-16; + px[40] = 3.7081363980789887e1;pw[40] = 2.4352390869127641e-17; + px[41] = 3.8992734377692841e1;pw[41] = 3.6095571137034836e-18; + px[42] = 4.0956828361752369e1;pw[42] = 5.0757642386344912e-19; + px[43] = 4.2974154765518962e1;pw[43] = 6.7680555851412924e-20; + px[44] = 4.5045243919797104e1;pw[44] = 8.5528682924618337e-21; + px[45] = 4.7170648577287264e1;pw[45] = 1.0237779829567897e-21; + px[46] = 4.9350944898013731e1;pw[46] = 1.1601029671831009e-22; + px[47] = 5.1586733501399526e1;pw[47] = 1.2437241818417510e-23; + px[48] = 5.3878640590325199e1;pw[48] = 1.2607163390079573e-24; + px[49] = 5.6227319153038116e1;pw[49] = 1.2075186187234281e-25; + px[50] = 5.8633450249370054e1;pw[50] = 1.0920906578859209e-26; + px[51] = 6.1097744388381858e1;pw[51] = 9.3197543545708300e-28; + px[52] = 6.3620943005294023e1;pw[52] = 7.4991199467470311e-29; + px[53] = 6.6203820046392479e1;pw[53] = 5.6851415515118275e-30; + px[54] = 6.8847183671532207e1;pw[54] = 4.0573989053601805e-31; + px[55] = 7.1551878084912556e1;pw[55] = 2.7237314698332196e-32; + px[56] = 7.4318785505984439e1;pw[56] = 1.7183408111964119e-33; + px[57] = 7.7148828293691083e1;pw[57] = 1.0178497763141794e-34; + px[58] = 8.0042971238764368e1;pw[58] = 5.6554871509106191e-36; + px[59] = 8.3002224040525493e1;pw[59] = 2.9446351279717004e-37; + px[60] = 8.6027643986604472e1;pw[60] = 1.4351943180018244e-38; + px[61] = 8.9120338856236006e1;pw[61] = 6.5407638433990210e-40; + px[62] = 9.2281470070355184e1;pw[62] = 2.7840843888220453e-41; + px[63] = 9.5512256114659083e1;pw[63] = 1.1054661469676639e-42; + px[64] = 9.8813976265183997e1;pw[64] = 4.0894445809546643e-44; + px[65] = 1.0218797464984955e2;pw[65] = 1.4075301928520080e-45; + px[66] = 1.0563566468393243e2;pw[66] = 4.5010556553905317e-47; + px[67] = 1.0915853392266498e2;pw[67] = 1.3353375262485678e-48; + px[68] = 1.1275814938024115e2;pw[68] = 3.6695275610607160e-50; + px[69] = 1.1643616337161760e2;pw[69] = 9.3251810053654335e-52; + px[70] = 1.2019431994181835e2;pw[70] = 2.1876527359441781e-53; + px[71] = 1.2403446195723057e2;pw[71] = 4.7290816436201351e-55; + px[72] = 1.2795853894491414e2;pw[72] = 9.4017744393225470e-57; + px[73] = 1.3196861577960725e2;pw[73] = 1.7154770732070957e-58; + px[74] = 1.3606688233435014e2;pw[74] = 2.8665242731015198e-60; + px[75] = 1.4025566423003982e2;pw[75] = 4.3763989573541065e-62; + px[76] = 1.4453743484248376e2;pw[76] = 6.0897571742385102e-64; + px[77] = 1.4891482875354178e2;pw[77] = 7.7031170730276684e-66; + px[78] = 1.5339065686687570e2;pw[78] = 8.8328749793303574e-68; + px[79] = 1.5796792345012664e2;pw[79] = 9.1539586505379100e-70; + px[80] = 1.6264984541588618e2;pw[80] = 8.5466832132929860e-72; + px[81] = 1.6743987421605101e2;pw[81] = 7.1643610696800221e-74; + px[82] = 1.7234172080122024e2;pw[82] = 5.3721243887414992e-76; + px[83] = 1.7735938419287581e2;pw[83] = 3.5890274005464772e-78; + px[84] = 1.8249718433670430e2;pw[84] = 2.1271822587291959e-80; + px[85] = 1.8775980005795738e2;pw[85] = 1.1132951771397071e-82; + px[86] = 1.9315231313418438e2;pw[86] = 5.1191820200621500e-85; + px[87] = 1.9868025975060599e2;pw[87] = 2.0567744853280919e-87; + px[88] = 2.0434969092759117e2;pw[88] = 7.1772526649596168e-90; + px[89] = 2.1016724393431546e2;pw[89] = 2.1609888032718971e-92; + px[90] = 2.1614022726467649e2;pw[90] = 5.5733711965802891e-95; + px[91] = 2.2227672250383794e2;pw[91] = 1.2214353570041591e-97; + px[92] = 2.2858570743324025e2;pw[92] = 2.2544498870469226e-100; + px[93] = 2.3507720612202630e2;pw[93] = 3.4698364983238705e-103; + px[94] = 2.4176247370399097e2;pw[94] = 4.4037992320193089e-106; + px[95] = 2.4865422630218547e2;pw[95] = 4.5511410854658978e-109; + px[96] = 2.5576693054575381e2;pw[96] = 3.7753744367507348e-112; + px[97] = 2.6311717297716247e2;pw[97] = 2.4729177063662401e-115; + px[98] = 2.7072413844178640e2;pw[98] = 1.2549250228724467e-118; + px[99] = 2.7861024009039942e2;pw[99] = 4.8255791873729851e-122; + px[100] = 2.8680196505406753e2;pw[100] = 1.3697149157065236e-125; + px[101] = 2.9533103485728541e2;pw[101] = 2.7803242111394275e-129; + px[102] = 3.0423603893997241e2;pw[102] = 5.7192111543195200e-133; + px[103] = 3.1356480447692787e2;pw[103] = 2.7224139503928083e-135; + px[104] = 3.2337796045230511e2;pw[104] = 1.4985049959339292e-124; + px[105] = 3.3375453828748506e2;pw[105] = 2.4300435849929846e-132; + px[106] = 3.4480126780658105e2;pw[106] = 1.2259326780033627e-133; + px[107] = 3.5666913087724963e2;pw[107] = 2.4281860924963857e-51; + px[108] = 3.6958574691724203e2;pw[108] = 1.3766733748904064e-55; + px[109] = 3.8392777037966436e2;pw[109] = 5.9376811746370755e-69; + px[110] = 4.0042001600670709e2;pw[110] = 2.6857350954106024e-82; + px[111] = 4.2094130637188611e2;pw[111] = 2.9834955778444689e-81; + break; + case 120: + px[0] = 5.1297391669498222e-3;pw[0] = 2.8502395317547204e-1; + px[1] = 4.6168965558965583e-2;pw[1] = 2.7357523293518048e-1; + px[2] = 1.2825442268012189e-1;pw[2] = 2.5203716182373969e-1; + px[3] = 2.5140012578184619e-1;pw[3] = 2.2286337164152000e-1; + px[4] = 4.1562711419913549e-1;pw[4] = 1.8914288655924106e-1; + px[5] = 6.2096347114179658e-1;pw[5] = 1.5406584277742807e-1; + px[6] = 8.6744435015264118e-1;pw[6] = 1.2044049267022821e-1; + px[7] = 1.1551120082929025e0;pw[7] = 9.0358744219355181e-2; + px[8] = 1.4840158461306763e0;pw[8] = 6.5054591666537773e-2; + px[9] = 1.8542124546240439e0;pw[9] = 4.4943958036852311e-2; + px[10] = 2.2657656690067761e0;pw[10] = 2.9793575056951512e-2; + px[11] = 2.7187466298012132e0;pw[11] = 1.8949643702576734e-2; + px[12] = 3.2132338511001456e0;pw[12] = 1.1563055121878621e-2; + px[13] = 3.7493132962773567e0;pw[13] = 6.7686183318686482e-3; + px[14] = 4.3270784613050146e0;pw[14] = 3.8005184078890596e-3; + px[15] = 4.9466304658754044e0;pw[15] = 2.0467143746931182e-3; + px[16] = 5.6080781525446617e0;pw[16] = 1.0570513354181031e-3; + px[17] = 6.3115381941373083e0;pw[17] = 5.2349052163887461e-4; + px[18] = 7.0571352096725975e0;pw[18] = 2.4856586787767428e-4; + px[19] = 7.8450018890970696e0;pw[19] = 1.1314532553553562e-4; + px[20] = 8.6752791271324176e0;pw[20] = 4.9366594298931427e-5; + px[21] = 9.5481161665738945e0;pw[21] = 2.0642700128290312e-5; + px[22] = 1.0463670751402208e1;pw[22] = 8.2711958203927816e-6; + px[23] = 1.1422109290101294e1;pw[23] = 3.1751663936728944e-6; + px[24] = 1.2423607029605695e1;pw[24] = 1.1675760027782005e-6; + px[25] = 1.3468348240334714e1;pw[25] = 4.1119185727034140e-7; + px[26] = 1.4556526412806197e1;pw[26] = 1.3866304189070192e-7; + px[27] = 1.5688344466361026e1;pw[27] = 4.4765756397348091e-8; + px[28] = 1.6864014970570331e1;pw[28] = 1.3832734889608059e-8; + px[29] = 1.8083760379941373e1;pw[29] = 4.0902585285705370e-9; + px[30] = 1.9347813282585301e1;pw[30] = 1.1571064421471916e-9; + px[31] = 2.0656416663560776e1;pw[31] = 3.1309092427946476e-10; + px[32] = 2.2009824183662284e1;pw[32] = 8.1008838545649928e-11; + px[33] = 2.3408300474481054e1;pw[33] = 2.0037543940941961e-11; + px[34] = 2.4852121450630391e1;pw[34] = 4.7368238655988873e-12; + px[35] = 2.6341574640096350e1;pw[35] = 1.0698826247166949e-12; + px[36] = 2.7876959533749559e1;pw[36] = 2.3081364934421758e-13; + px[37] = 2.9458587955135198e1;pw[37] = 4.7547562946209405e-14; + px[38] = 3.1086784451746349e1;pw[38] = 9.3496621251942795e-15; + px[39] = 3.2761886709081786e1;pw[39] = 1.7543580097101897e-15; + px[40] = 3.4484245988893703e1;pw[40] = 3.1400971154418774e-16; + px[41] = 3.6254227593144597e1;pw[41] = 5.3593522678761522e-17; + px[42] = 3.8072211355316697e1;pw[42] = 8.7188945766817631e-18; + px[43] = 3.9938592160852983e1;pw[43] = 1.3515106234226978e-18; + px[44] = 4.1853780498657202e1;pw[44] = 1.9953021921306626e-19; + px[45] = 4.3818203045742856e1;pw[45] = 2.8044282474471764e-20; + px[46] = 4.5832303287299388e1;pw[46] = 3.7508906971614997e-21; + px[47] = 4.7896542174639558e1;pw[47] = 4.7717681635147569e-22; + px[48] = 5.0011398823707265e1;pw[48] = 5.7712738310619112e-23; + px[49] = 5.2177371257062108e1;pw[49] = 6.6327836836945849e-24; + px[50] = 5.4394977192518312e1;pw[50] = 7.2398182117815891e-25; + px[51] = 5.6664754881904218e1;pw[51] = 7.5012587727931265e-26; + px[52] = 5.8987264003727612e1;pw[52] = 7.3734885029706274e-27; + px[53] = 6.1363086613885492e1;pw[53] = 6.8721443844602975e-28; + px[54] = 6.3792828158948708e1;pw[54] = 6.0691779183687126e-29; + px[55] = 6.6277118556987132e1;pw[55] = 5.0759007367076133e-30; + px[56] = 6.8816613351385211e1;pw[56] = 4.0175221438220706e-31; + px[57] = 7.1411994943637213e1;pw[57] = 3.0072530813297540e-32; + px[58] = 7.4063973911713684e1;pw[58] = 2.1273584216828318e-33; + px[59] = 7.6773290421263832e1;pw[59] = 1.4211829797498313e-34; + px[60] = 7.9540715737672631e1;pw[60] = 8.9590957177462511e-36; + px[61] = 8.2367053847837527e1;pw[61] = 5.3251918761543396e-37; + px[62] = 8.5253143201480774e1;pw[62] = 2.9819503451853612e-38; + px[63] = 8.8199858582884791e1;pw[63] = 1.5717412988204925e-39; + px[64] = 9.1208113125147039e1;pw[64] = 7.7908008505381426e-41; + px[65] = 9.4278860480418384e1;pw[65] = 3.6281971412784443e-42; + px[66] = 9.7413097161138711e1;pw[66] = 1.5859015177178711e-43; + px[67] = 1.0061186506904395e2;pw[67] = 6.4996104375459879e-45; + px[68] = 1.0387625423072283e2;pw[68] = 2.4948970341280962e-46; + px[69] = 1.0720740576078862e2;pw[69] = 8.9593901038397884e-48; + px[70] = 1.1060651507634780e2;pw[70] = 3.0064061869829462e-49; + px[71] = 1.1407483538944766e2;pw[71] = 9.4149529210783543e-51; + px[72] = 1.1761368150763627e2;pw[72] = 2.7480284196099378e-52; + px[73] = 1.2122443397674619e2;pw[73] = 7.4655144872656008e-54; + px[74] = 1.2490854360461544e2;pw[74] = 1.8849778633354656e-55; + px[75] = 1.2866753640979513e2;pw[75] = 4.4167295028366118e-57; + px[76] = 1.3250301904550293e2;pw[76] = 9.5884544111130115e-59; + px[77] = 1.3641668475632833e2;pw[77] = 1.9253846157160579e-60; + px[78] = 1.4041031993368383e2;pw[78] = 3.5697275921210464e-62; + px[79] = 1.4448581134597201e2;pw[79] = 6.0993788510648131e-64; + px[80] = 1.4864515413120591e2;pw[80] = 9.5853191608176058e-66; + px[81] = 1.5289046065375615e2;pw[81] = 1.3825627736640795e-67; + px[82] = 1.5722397034346682e2;pw[82] = 1.8262174400320119e-69; + px[83] = 1.6164806065516658e2;pw[83] = 2.2038494574755515e-71; + px[84] = 1.6616525931033000e2;pw[84] = 2.4237108166704223e-73; + px[85] = 1.7077825801123656e2;pw[85] = 2.4226238499885409e-75; + px[86] = 1.7548992785259882e2;pw[86] = 2.1946080740100573e-77; + px[87] = 1.8030333669777762e2;pw[87] = 1.7962565586872283e-79; + px[88] = 1.8522176883828634e2;pw[88] = 1.3240410388018822e-81; + px[89] = 1.9024874731879046e2;pw[89] = 8.7585968525902169e-84; + px[90] = 1.9538805938846759e2;pw[90] = 5.1800274294960421e-86; + px[91] = 2.0064378563766165e2;pw[91] = 2.7279222749641292e-88; + px[92] = 2.0602033350188195e2;pw[92] = 1.2735953172719079e-90; + px[93] = 2.1152247597090631e2;pw[93] = 5.2465045442237418e-93; + px[94] = 2.1715539653923255e2;pw[94] = 1.8971890062657397e-95; + px[95] = 2.2292474168927554e2;pw[95] = 5.9884763458065071e-98; + px[96] = 2.2883668252968495e2;pw[96] = 1.6399282759538974e-100; + px[97] = 2.3489798764468268e2;pw[97] = 3.8700481929789787e-103; + px[98] = 2.4111610978413709e2;pw[98] = 7.8122606315689856e-106; + px[99] = 2.4749928979224946e2;pw[99] = 1.3379893855632987e-108; + px[100] = 2.5405668221374821e2;pw[100] = 1.9266285323004829e-111; + px[101] = 2.6079850844627440e2;pw[101] = 2.3089140588011642e-114; + px[102] = 2.6773624530027240e2;pw[102] = 2.2768662844496908e-117; + px[103] = 2.7488285964960641e2;pw[103] = 1.8239060669490364e-120; + px[104] = 2.8225310392367891e2;pw[104] = 1.1696325620584706e-123; + px[105] = 2.8986389317085953e2;pw[105] = 5.9089203696565755e-127; + px[106] = 2.9773479340583953e2;pw[106] = 2.3982393520466646e-130; + px[107] = 3.0588866478394910e2;pw[107] = 1.3336608988109749e-133; + px[108] = 3.1435252503773286e2;pw[108] = 1.8554662333955921e-131; + px[109] = 3.2315873437660234e2;pw[109] = 5.6745552433723977e-133; + px[110] = 3.3234666364534706e2;pw[110] = 6.4148023503115847e-132; + px[111] = 3.4196511464296833e2;pw[111] = 1.7690546779468858e-132; + px[112] = 3.5207596053730912e2;pw[112] = 2.3559424075535023e-133; + px[113] = 3.6275986709694166e2;pw[113] = 7.0346860953952109e-133; + px[114] = 3.7412578995211861e2;pw[114] = 8.2581860285237120e-132; + px[115] = 3.8632788878085670e2;pw[115] = 3.8298599230421540e-49; + px[116] = 3.9959862252409562e2;pw[116] = 8.6830434227075531e-52; + px[117] = 4.1432274380983757e2;pw[117] = 7.8569306274869450e-66; + px[118] = 4.3124084763817151e2;pw[118] = 1.0876766815421296e-79; + px[119] = 4.5227326181239169e2;pw[119] = 1.7576416430685541e-80; + break; + case 128: + px[0] = 4.8097546269833893e-3;pw[0] = 2.7607937255104182e-1; + px[1] = 4.3288873981462912e-2;pw[1] = 2.6566783614880718e-1; + px[2] = 1.2025288615546319e-1;pw[2] = 2.4600646227023164e-1; + px[3] = 2.3571334284486281e-1;pw[3] = 2.1920556026860463e-1; + px[4] = 3.8968758351746751e-1;pw[4] = 1.8795185561410056e-1; + px[5] = 5.8219874974842322e-1;pw[5] = 1.5506780698139096e-1; + px[6] = 8.1327580437858389e-1;pw[6] = 1.2310171404959776e-1; + px[7] = 1.0829535555341720e0;pw[7] = 9.4028368962612467e-2; + px[8] = 1.3912726855559166e0;pw[8] = 6.9101651733143485e-2; + px[9] = 1.7382797848958800e0;pw[9] = 4.8857640815463552e-2; + px[10] = 2.1240273910504205e0;pw[10] = 3.3232907130961684e-2; + px[11] = 2.5485740326082378e0;pw[11] = 2.1745560021797622e-2; + px[12] = 3.0119842785032310e0;pw[12] = 1.3687095820753643e-2; + px[13] = 3.5143287925730293e0;pw[13] = 8.2862847528073521e-3; + px[14] = 4.0556843935355590e0;pw[14] = 4.8248404263837572e-3; + px[15] = 4.6361341205079486e0;pw[15] = 2.7017467389205526e-3; + px[16] = 5.2557673042044822e0;pw[16] = 1.4548097345670083e-3; + px[17] = 5.9146796439632562e0;pw[17] = 7.5322752691836494e-4; + px[18] = 6.6129732907647177e0;pw[18] = 3.7493875811399589e-4; + px[19] = 7.3507569364194338e0;pw[19] = 1.7941616616270753e-4; + px[20] = 8.1281459091173179e0;pw[20] = 8.2523935092697431e-5; + px[21] = 8.9452622755461916e0;pw[21] = 3.6480646490280587e-5; + px[22] = 9.8022349498040578e0;pw[22] = 1.5497209992155702e-5; + px[23] = 1.0699199809346890e1;pw[23] = 6.3254880868062279e-6; + px[24] = 1.1636299818232177e1;pw[24] = 2.4804025381841617e-6; + px[25] = 1.2613685157937996e1;pw[25] = 9.3427092817735856e-7; + px[26] = 1.3631513366058145e1;pw[26] = 3.3796972810877498e-7; + px[27] = 1.4689949483195887e1;pw[27] = 1.1739931842906987e-7; + px[28] = 1.5789166208402366e1;pw[28] = 3.9152666460117425e-8; + px[29] = 1.6929344063530748e1;pw[29] = 1.2533919800530000e-8; + px[30] = 1.8110671566903898e1;pw[30] = 3.8508855814103435e-9; + px[31] = 1.9333345416721943e1;pw[31] = 1.1352650067802054e-9; + px[32] = 2.0597570684666645e1;pw[32] = 3.2107610902767967e-10; + px[33] = 2.1903561020192286e1;pw[33] = 8.7096417230648332e-11; + px[34] = 2.3251538866027899e1;pw[34] = 2.2655716245890225e-11; + px[35] = 2.4641735685453456e1;pw[35] = 5.6498933794313194e-12; + px[36] = 2.6074392201953201e1;pw[36] = 1.3504651749637866e-12; + px[37] = 2.7549758651893053e1;pw[37] = 3.0931346162094001e-13; + px[38] = 2.9068095050916087e1;pw[38] = 6.7869387110402112e-14; + px[39] = 3.0629671474800940e1;pw[39] = 1.4262371047812445e-14; + px[40] = 3.2234768355582876e1;pw[40] = 2.8696621621608344e-15; + px[41] = 3.3883676793796597e1;pw[41] = 5.5266882811584044e-16; + px[42] = 3.5576698887764130e1;pw[42] = 1.0185057527135605e-16; + px[43] = 3.7314148080920709e1;pw[43] = 1.7955213298120343e-17; + px[44] = 3.9096349528247114e1;pw[44] = 3.0269510335107605e-18; + px[45] = 4.0923640482958862e1;pw[45] = 4.8782259058116175e-19; + px[46] = 4.2796370704691817e1;pw[46] = 7.5129177544606858e-20; + px[47] = 4.4714902890520744e1;pw[47] = 1.1053212066329750e-20; + px[48] = 4.6679613130253012e1;pw[48] = 1.5528826688231492e-21; + px[49] = 4.8690891387554891e1;pw[49] = 2.0825248019667178e-22; + px[50] = 5.0749142008593753e1;pw[50] = 2.6648208774549398e-23; + px[51] = 5.2854784260017013e1;pw[51] = 3.2523000556521267e-24; + px[52] = 5.5008252898239286e1;pw[52] = 3.7841616175987121e-25; + px[53] = 5.7209998772174173e1;pw[53] = 4.1957539145536696e-26; + px[54] = 5.9460489461728161e1;pw[54] = 4.4310753939163665e-27; + px[55] = 6.1760209954572964e1;pw[55] = 4.4550960738061500e-28; + px[56] = 6.4109663363931410e1;pw[56] = 4.2622210868369363e-29; + px[57] = 6.6509371690352848e1;pw[57] = 3.8781073546455843e-30; + px[58] = 6.8959876630719803e1;pw[58] = 3.3540852993298416e-31; + px[59] = 7.1461740438021006e1;pw[59] = 2.7558487347346862e-32; + px[60] = 7.4015546835750457e1;pw[60] = 2.1498637246741931e-33; + px[61] = 7.6621901991151567e1;pw[61] = 1.5913963136894115e-34; + px[62] = 7.9281435551924119e1;pw[62] = 1.1170819746689115e-35; + px[63] = 8.1994801751454565e1;pw[63] = 7.4310093282819445e-37; + px[64] = 8.4762680588122938e1;pw[64] = 4.6813625515950693e-38; + px[65] = 8.7585779084788683e1;pw[65] = 2.7909522621573202e-39; + px[66] = 9.0464832635170634e1;pw[66] = 1.5735113668960615e-40; + px[67] = 9.3400606444521639e1;pw[67] = 8.3828847876304648e-42; + px[68] = 9.6393897072765977e1;pw[68] = 4.2167560748751703e-43; + px[69] = 9.9445534089129095e1;pw[69] = 2.0010861658834713e-44; + px[70] = 1.0255638184825758e2;pw[70] = 8.9512017753845699e-46; + px[71] = 1.0572734139891817e2;pw[71] = 3.7708148208752655e-47; + px[72] = 1.0895935253759580e2;pw[72] = 1.4945851640195755e-48; + px[73] = 1.1225339602070313e2;pw[73] = 5.5681807795587594e-50; + px[74] = 1.1561049595069244e2;pw[74] = 1.9479151853826422e-51; + px[75] = 1.1903172235315340e2;pw[75] = 6.3918683903792039e-53; + px[76] = 1.2251819396402152e2;pw[76] = 1.9651813087431218e-54; + px[77] = 1.2607108124835155e2;pw[77] = 5.6544197387738892e-56; + px[78] = 1.2969160967477476e2;pw[78] = 1.5207362927895532e-57; + px[79] = 1.3338106327281588e2;pw[79] = 3.8180775856184579e-59; + px[80] = 1.3714078850376025e2;pw[80] = 8.9367191262601894e-61; + px[81] = 1.4097219847981490e2;pw[81] = 1.9473442897375391e-62; + px[82] = 1.4487677757099489e2;pw[82] = 3.9445422891662265e-64; + px[83] = 1.4885608644460317e2;pw[83] = 7.4159150213626314e-66; + px[84] = 1.5291176758849769e2;pw[84] = 1.2919234936181112e-67; + px[85] = 1.5704555137672418e2;pw[85] = 2.0819221394737772e-69; + px[86] = 1.6125926274474058e2;pw[86] = 3.0978378698037742e-71; + px[87] = 1.6555482855162421e2;pw[87] = 4.2480171859192708e-73; + px[88] = 1.6993428571864366e2;pw[88] = 5.3575541752687071e-75; + px[89] = 1.7439979024777800e2;pw[89] = 6.2010829537374423e-77; + px[90] = 1.7895362724065057e2;pw[90] = 6.5720579636670588e-79; + px[91] = 1.8359822205850647e2;pw[91] = 6.3623825304174234e-81; + px[92] = 1.8833615278804584e2;pw[92] = 5.6118813553226041e-83; + px[93] = 1.9317016420706524e2;pw[93] = 4.4976052330512204e-85; + px[94] = 1.9810318347914946e2;pw[94] = 3.2656789300649514e-87; + px[95] = 2.0313833784961355e2;pw[95] = 2.1415773771514337e-89; + px[96] = 2.0827897466747490e2;pw[96] = 1.2642009038210272e-91; + px[97] = 2.1352868412296766e2;pw[97] = 6.6937523730388343e-94; + px[98] = 2.1889132517029559e2;pw[98] = 3.1668515385882014e-96; + px[99] = 2.2437105520529297e2;pw[99] = 1.3331988108895188e-98; + px[100] = 2.2997236419317798e2;pw[100] = 4.9720167074631327e-101; + px[101] = 2.3570011410033001e2;pw[101] = 1.6347801791277616e-103; + px[102] = 2.4155958468639006e2;pw[102] = 4.7134964221305137e-106; + px[103] = 2.4755652697313934e2;pw[103] = 1.1851002424541479e-108; + px[104] = 2.5369722604409365e2;pw[104] = 2.5820543464647026e-111; + px[105] = 2.5998857527081546e2;pw[105] = 4.8417253805291566e-114; + px[106] = 2.6643816464709542e2;pw[106] = 7.7550688581883223e-117; + px[107] = 2.7305438669552003e2;pw[107] = 1.0522110136923271e-119; + px[108] = 2.7984656447262174e2;pw[108] = 1.1982172530332628e-122; + px[109] = 2.8682510765704206e2;pw[109] = 1.1333834975480497e-125; + px[110] = 2.9400170473751538e2;pw[110] = 8.8091250671314200e-129; + px[111] = 3.0138956219582173e2;pw[111] = 5.1031266854191002e-132; + px[112] = 3.0900370572897370e2;pw[112] = 3.7889105113753785e-134; + px[113] = 3.1686136465414833e2;pw[113] = 1.6614242788060531e-135; + px[114] = 3.2498246980378542e2;pw[114] = 3.3159273335592529e-133; + px[115] = 3.3339030932831591e2;pw[115] = 6.6730040001944718e-134; + px[116] = 3.4211240916012430e2;pw[116] = 1.2949575356743615e-133; + px[117] = 3.5118174138517492e2;pw[117] = 9.1532484444758395e-133; + px[118] = 3.6063842559961562e2;pw[118] = 1.9549729552902828e-134; + px[119] = 3.7053219762567725e2;pw[119] = 8.0781662197334676e-122; + px[120] = 3.8092612308026272e2;pw[120] = 3.7898513479231859e-137; + px[121] = 3.9190243416377710e2;pw[121] = 1.0948592196247296e-132; + px[122] = 4.0357221976913419e2;pw[122] = 3.6495237116054534e-50; + px[123] = 4.1609268503849895e2;pw[123] = 7.9553417261007054e-54; + px[124] = 4.2970092632479113e2;pw[124] = 5.8160707456163802e-67; + px[125] = 4.4478945491488902e2;pw[125] = 1.6308626485034593e-79; + px[126] = 4.6211398112631172e2;pw[126] = 8.1797036981379553e-83; + px[127] = 4.8363457770593729e2;pw[127] = 4.4300469125827045e-82; + break; + } + } + + /***************************************************************************************/ + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + void cgqf(dt_int32 kind, dt_int32 nt, T alpha, T beta, T a, T b, T t[], T wts[]) + // Purpose: + // + // CGQF computes knots and weights of a Gauss quad_data formula. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // The user may specify the interval (A, B). + // Only simple knots are produced. + // Use routine EIQFS to evaluate this quad_data formula. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev Type 1, (a, b) ((b-x)*(x-a))^-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, +oo) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-oo, +oo) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, +oo) (x-a)^alpha*(x+b)^beta + // 9, chebyshev Type 2, (a, b) ((b-x)*(x-a))^(+0.5) + // + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // in, T A, B, the interval endpoints, or other parameters. + // + // Output, T T[NT], the knots. + // Output, T WTS[NT], the weights. + { + dt_int32 *mlt; + dt_int32 *ndx; + // Compute the Gauss quad_data formula for default values of A and B. + cdgqf(kind, nt, alpha, beta, t, wts); + + // Prepare to fcn_scale the quad_data formula to other weight function with valid A and B. + mlt = new dt_int32[nt]; + for(auto i = 0; i < nt; i++) + { + mlt[i] = 1; + } + ndx = new dt_int32[nt]; + + for(auto i = 0; i < nt; i++) + { + ndx[i] = i + 1; + } + scqf(nt, t, mlt, wts, nt, ndx, wts, t, kind, alpha, beta, a, b); + + delete[] mlt; + delete[] ndx; + + return; + } + + void cdgqf(dt_int32 kind, dt_int32 nt, T alpha, T beta, T t[], T wts[]) + // Purpose: + // + // CDGQF computes a Gauss quad_data formula with default A, B and simple knots. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine computes all the knots and weights of a Gauss quad_data + // formula with a classical weight function with default values for A and B, + // and only simple knots. + // There are no moments checks and no printing is done. + // Use routine EIQFS to evaluate a quad_data computed by CGQFS. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + // + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // Output, T T[NT], the knots. + // Output, T WTS[NT], the weights. + { + T* aj; + T* bj; + T zemu; + + parchk(kind, 2 * nt, alpha, beta); + // Get the jacobi matrix and zero-th moment. + aj = new T[nt]; + bj = new T[nt]; + + zemu = class_matrix(kind, nt, alpha, beta, aj, bj); + // Compute the knots and weights. + sgqf(nt, aj, bj, zemu, t, wts); + + delete[] aj; + delete[] bj; + + return; + } + + T class_matrix(dt_int32 kind, dt_int32 m, T alpha, T beta, T aj[], T bj[]) + // Purpose: + // + // CLASS_MATRIX computes the jacobi matrix for a quad_data rule. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine computes the diagonal AJ and sub-diagonal BJ + // elements of the order M tridiagonal symmetric jacobi matrix + // associated with the polynomials orthogonal with respect to + // the weight function specified by KIND. + // + // For weight functions 1-7, M elements are defined in BJ even + // though only M-1 are needed. For weight function 8, BJ(M) is + // set to zero. + // + // The zero-th moment of the weight function is returned in ZEMU. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + // + // in, dt_int32 M, the order of the jacobi matrix. + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // Output, T AJ[M], BJ[M], the diagonal and subdiagonal + // of the jacobi matrix. + // Output, T CLASS_MATRIX, the zero-th moment. + { + T a2b2; + T ab; + T aba; + T abi; + T abj; + T abti; + T apone; + dt_int32 i; + T pi = 3.14159265358979323846264338327950; + T temp; + T temp2; + T zemu; + + temp = r8_epsilon(); + + parchk(kind, 2 * m - 1, alpha, beta); + + temp2 = 0.5; + + if (500.0 * temp < fabs(pow(tgamma(temp2), 2) - pi)) + { + // cout << "\n"; + // cout << "CLASS_MATRIX - Fatal error!\n"; + // cout << " Gamma function does not match machine parameters.\n"; + // exit(1); + } + + if (kind == 1) + { + ab = 0.0; + + zemu = 2.0/(ab + 1.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + for(i = 1; i <= m; i++) + { + abi = i + ab * (i % 2); + abj = 2 * i + ab; + bj[i - 1] = ::sqrt(abi * abi/(abj * abj - 1.0)); + } + } + else if (kind == 2) + { + zemu = pi; + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + bj[0] = ::sqrt(0.5); + for(i = 1; i < m; i++) + { + bj[i] = 0.5; + } + } + else if (kind == 3) + { + ab = alpha * 2.0; + zemu = pow(2.0, ab + 1.0) * pow(tgamma(alpha + 1.0), 2) + / tgamma(ab + 2.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + bj[0] = ::sqrt(1.0/(2.0 * alpha + 3.0)); + for(i = 2; i <= m; i++) + { + bj[i - 1] = ::sqrt(i * (i + ab)/(4.0 * pow(i + alpha, 2) - 1.0)); + } + } + else if (kind == 4) + { + ab = alpha + beta; + abi = 2.0 + ab; + zemu = pow(2.0, ab + 1.0) * tgamma(alpha + 1.0) + * tgamma(beta + 1.0)/tgamma(abi); + aj[0] = (beta - alpha)/abi; + bj[0] = ::sqrt(4.0 * (1.0 + alpha) * (1.0 + beta) + / ((abi + 1.0) * abi * abi)); + a2b2 = beta * beta - alpha * alpha; + + for(i = 2; i <= m; i++) + { + abi = 2.0 * i + ab; + aj[i - 1] = a2b2/((abi - 2.0) * abi); + abi = abi * abi; + bj[i - 1] = ::sqrt(4.0 * i * (i + alpha) * (i + beta) * (i + ab) + / ((abi - 1.0) * abi)); + } + } + else if (kind == 5) + { + zemu = tgamma(alpha + 1.0); + + for(i = 1; i <= m; i++) + { + aj[i - 1] = 2.0 * i - 1.0 + alpha; + bj[i - 1] = ::sqrt(i * (i + alpha)); + } + } + else if (kind == 6) + { + zemu = tgamma((alpha + 1.0)/2.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + for(i = 1; i <= m; i++) + { + bj[i - 1] = ::sqrt((i + alpha * (i % 2))/2.0); + } + } + else if (kind == 7) + { + ab = alpha; + zemu = 2.0/(ab + 1.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + for(i = 1; i <= m; i++) + { + abi = i + ab * (i % 2); + abj = 2 * i + ab; + bj[i - 1] = ::sqrt(abi * abi/(abj * abj - 1.0)); + } + } + else if (kind == 8) + { + ab = alpha + beta; + zemu = tgamma(alpha + 1.0) * tgamma(-(ab + 1.0)) + / tgamma(-beta); + apone = alpha + 1.0; + aba = ab * apone; + aj[0] = -apone/(ab + 2.0); + bj[0] = -aj[0] * (beta + 1.0)/(ab + 2.0)/(ab + 3.0); + for(i = 2; i <= m; i++) + { + abti = ab + 2.0 * i; + aj[i - 1] = aba + 2.0 * (ab + i) * (i - 1); + aj[i - 1] = -aj[i - 1]/abti/(abti - 2.0); + } + + for(i = 2; i <= m - 1; i++) + { + abti = ab + 2.0 * i; + bj[i - 1] = i * (alpha + i)/(abti - 1.0) * (beta + i) + / (abti * abti) * (ab + i)/(abti + 1.0); + } + bj[m - 1] = 0.0; + for(i = 0; i < m; i++) + { + bj[i] = ::sqrt(bj[i]); + } + } + + return zemu; + } + + void imtqlx(dt_int32 n, T d[], T e[], T z[]) + // Purpose: + // + // IMTQLX diagonalizes a symmetric tridiagonal matrix. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine is a slightly modified version of the EISPACK routine to + // perform the implicit QL algorithm on a symmetric tridiagonal matrix. + // + // The authors thank the authors of EISPACK for permission to use this + // routine. + // + // It has been modified to produce the product coef_quad_1d' * Z, where Z is an in + // vector and coef_quad_1d is the orthogonal matrix diagonalizing the in matrix. + // The changes consist (essentialy) of applying the orthogonal transformations + // directly to Z as they are generated. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Roger Martin, James Wilkinson, + // The Implicit QL Algorithm, + // Numerische Mathematik, + // Volume 12, Number 5, December 1968, pages 377-383. + // + // Parameters: + // + // in, dt_int32 N, the order of the matrix. + // + // in/output, T D(N), the diagonal entries of the matrix. + // On output, the information in D has been overwritten. + // + // in/output, T E(N), the subdiagonal entries of the + // matrix, in entries E(1) through E(N-1). On output, the information in + // E has been overwritten. + // + // in/output, T Z(N). On in, a vector. On output, + // the value of coef_quad_1d' * Z, where coef_quad_1d is the matrix that diagonalizes the + // in symmetric tridiagonal matrix. + { + T b; + T c; + T f; + T g; + dt_int32 i; + dt_int32 ii; + dt_int32 itn = 30; + dt_int32 j; + dt_int32 k; + dt_int32 l; + dt_int32 m; + dt_int32 mml; + T p; + T prec; + T r; + T s; + + prec = r8_epsilon(); + + if (n == 1) + { + return; + } + + e[n - 1] = 0.0; + + for(l = 1;l <= n;l++) + { + j = 0; + for( ; ; ) + { + for(m = l;m <= n;m++) + { + if (m == n) + { + break; + } + + if (fabs(e[m - 1]) <= prec * (fabs(d[m - 1]) + fabs(d[m]))) + { + break; + } + } + p = d[l - 1]; + if (m == l) + { + break; + } + if (itn <= j) + { + // cout << "\n"; + // cout << "IMTQLX - Fatal error!\n"; + // cout << " Iteration limit exceeded\n"; + // exit(1); + } + + j = j + 1; + g = (d[l] - p)/(2.0 * e[l - 1]); + r = ::sqrt(g * g + 1.0); + g = d[m - 1] - p + e[l - 1]/(g + fabs(r) * r8_sign(g)); + s = 1.0; + c = 1.0; + p = 0.0; + mml = m - l; + + for(ii = 1; ii <= mml; ii++) + { + i = m - ii; + f = s * e[i - 1]; + b = c * e[i - 1]; + + if (fabs(g) <= fabs(f)) + { + c = g/f; + r = ::sqrt(c * c + 1.0); + e[i] = f * r; + s = 1.0/r; + c = c * s; + } + else + { + s = f/g; + r = ::sqrt(s * s + 1.0); + e[i] = g * r; + c = 1.0/r; + s = s * c; + } + g = d[i] - p; + r = (d[i - 1] - g) * s + 2.0 * c * b; + p = s * r; + d[i] = g + p; + g = c * r - b; + f = z[i]; + z[i] = s * z[i - 1] + c * f; + z[i - 1] = c * z[i - 1] - s * f; + } + d[l - 1] = d[l - 1] - p; + e[l - 1] = g; + e[m - 1] = 0.0; + } + } + // + // Sorting. + // + for(ii = 2; ii <= m; ii++) + { + i = ii - 1; + k = i; + p = d[i - 1]; + + for(j = ii; j <= n; j++) + { + if (d[j - 1] < p) + { + k = j; + p = d[j - 1]; + } + } + + if (k != i) + { + d[k - 1] = d[i - 1]; + d[i - 1] = p; + p = z[i - 1]; + z[i - 1] = z[k - 1]; + z[k - 1] = p; + } + } + return; + } + + void parchk(dt_int32 kind, dt_int32 m, T alpha, T beta) + // Purpose: + // + // PARCHK checks parameters ALPHA and BETA for classical weight functions. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + // + // in, dt_int32 M, the order of the highest moment to + // be calculated. This value is only needed when KIND = 8. + // + // in, T ALPHA, BETA, the parameters, if required + // by the value of KIND. + { + T tmp; + + if (kind <= 0) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " KIND <= 0.\n"; + // exit(1); + } + + // check ALPHA for gegenbauer, jacobi, laguerre, hermite, exponential. + if (3 <= kind && alpha <= -1.0) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " 3 <= KIND and ALPHA <= -1.\n"; + // exit(1); + } + + // check BETA for jacobi. + if (kind == 4 && beta <= -1.0) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " KIND == 4 and BETA <= -1.0.\n"; + // exit(1); + } + + // check ALPHA and BETA for rational. + if (kind == 8) + { + tmp = alpha + beta + m + 1.0; + if (0.0 <= tmp || tmp <= beta) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " KIND == 8 but condition on ALPHA and BETA fails.\n"; + // exit(1); + } + } + return; + } + + void scqf(dt_int32 nt, T t[], dt_int32 mlt[], T wts[], dt_int32 nwts, dt_int32 ndx[], + T swts[], T st[], dt_int32 kind, T alpha, T beta, T a, T b) + // Purpose: + // + // SCQF scales a quad_data formula to a nonstandard interval. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // The arrays WTS and SWTS may coincide. + // The arrays T and ST may coincide. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // in, T T[NT], the original knots. + // in, dt_int32 MLT[NT], the multiplicity of the knots. + // in, T WTS[NWTS], the weights. + // in, dt_int32 NWTS, the number of weights. + // in, dt_int32 NDX[NT], used to index the array WTS. + // For more details see the comments in CAWIQ. + // + // Output, T SWTS[NWTS], the scaled weights. + // Output, T ST[NT], the scaled knots. + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev Type 1, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, +oo) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-oo, +oo) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, +oo) (x-a)^alpha*(x+b)^beta + // 9, chebyshev Type 2, (a, b) ((b-x)*(x-a))^(+0.5) + // + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // in, T A, B, the interval endpoints. + { + T al; + T be; + dt_int32 i; + dt_int32 k; + dt_int32 l; + T p; + T shft; + T slp; + T temp; + T tmp; + + temp = r8_epsilon(); + + parchk(kind, 1, alpha, beta); + + if (kind == 1) + { + al = 0.0; + be = 0.0; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 2) + { + al = -0.5; + be = -0.5; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 3) + { + al = alpha; + be = alpha; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 4) + { + al = alpha; + be = beta; + + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 5) + { + if (b <= 0.0) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " B <= 0\n"; + // exit(1); + } + shft = a; + slp = 1.0/b; + al = alpha; + be = 0.0; + } + else if (kind == 6) + { + if (b <= 0.0) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " B <= 0.\n"; + // exit(1); + } + shft = a; + slp = 1.0/::sqrt(b); + al = alpha; + be = 0.0; + } + else if (kind == 7) + { + al = alpha; + be = 0.0; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 8) + { + if (a + b <= 0.0) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " A + B <= 0.\n"; + // exit(1); + } + shft = a; + slp = a + b; + al = alpha; + be = beta; + } + else if (kind == 9) + { + al = 0.5; + be = 0.5; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + + p = pow(slp, al + be + 1.0); + + for(k = 0;k < nt;k++) + { + st[k] = shft + slp * t[k]; + l = abs(ndx[k]); + + if (l != 0) + { + tmp = p; + for(i = l - 1; i <= l - 1 + mlt[k] - 1; i++) + { + swts[i] = wts[i] * tmp; + tmp = tmp * slp; + } + } + } + return; + } + + void sgqf(dt_int32 nt, T aj[], T bj[], T zemu, T t[], T wts[]) + // Purpose: + // + // SGQF computes knots and weights of a Gauss Quad_Data formula. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine computes all the knots and weights of a Gauss quad_data + // formula with simple knots from the jacobi matrix and the zero-th + // moment of the weight function, using the Golub-Welsch technique. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // + // in, T AJ[NT], the diagonal of the jacobi matrix. + // + // in/output, T BJ[NT], the subdiagonal of the jacobi + // matrix, in entries 1 through NT-1. On output, BJ has been overwritten. + // + // in, T ZEMU, the zero-th moment of the weight function. + // + // Output, T T[NT], the knots. + // + // Output, T WTS[NT], the weights. + { + dt_int32 i; + + // Exit if the zero-th moment is not positive. + if (zemu <= 0.0) + { + // cout << "\n"; + // cout << "SGQF - Fatal error!\n"; + // cout << " ZEMU <= 0.\n"; + // exit(1); + } + + // Set up vectors for IMTQLX. + for(i = 0; i < nt; i++) + { + t[i] = aj[i]; + } + wts[0] = ::sqrt(zemu); + for(i = 1; i < nt; i++) + { + wts[i] = 0.0; + } + + // Diagonalize the jacobi matrix. + imtqlx(nt, t, bj, wts); + + for(i = 0; i < nt; i++) + { + wts[i] = wts[i] * wts[i]; + } + + return; + } + + T r8_epsilon() + // Purpose: + // + // R8_EPSILON returns the R8 roundoff unit. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // Reference: + // + // Discussion: + // + // The roundoff unit is a number R which is a power of 2 with the + // property that, to the precision of the computer's arithmetic, + // 1 < 1 + R + // but + // 1 = ( 1 + R/2 ) + // + // Parameters: + // + // Output, T R8_EPSILON, the R8 round-off unit. + { + const T value = 2.220446049250313E-016; + + return value; + } + + T r8_huge() + // Purpose: + // + // R8_HUGE returns a "huge" R8. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // The value returned by this function is NOT required to be the + // maximum representable R8. This value varies from machine to machine, + // from compiler to compiler, and may cause problems when being printed. + // We simply want a "very large" but non-infinite number. + // + // Parameters: + // + // Output, T R8_HUGE, a "huge" R8 value. + { + T value; + + value = 1.0E+30; + + return value; + } + + T r8_sign(T x) + // Purpose: + // + // R8_SIGN returns the sign of an R8. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Parameters: + // + // in, T X, the number whose sign is desired. + // Output, T R8_SIGN, the sign of X. + { + T value; + + if (x < 0.0) + { + value = -1.0; + } + else + { + value = 1.0; + } + return value; + } + }; + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/r_2d.cuh b/src - Copy (2)/r_2d.cuh new file mode 100755 index 00000000..4dfa3ab2 --- /dev/null +++ b/src - Copy (2)/r_2d.cuh @@ -0,0 +1,778 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef R_2D_H + #define R_2D_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_fcns_gen.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + /* forward declarations */ + namespace mt + { + template + using R_2d = R_xtd; + + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_2d& r); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_2d& r); + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_2d& r); + + template + CGPU_EXEC + R_2d floor(const R_2d& r); + + template + CGPU_EXEC + R_2d ceil(const R_2d& r); + + template + CGPU_EXEC + R_2d round(const R_2d& r); + + template + CGPU_EXEC + T fmin(const R_2d& r); + + template + CGPU_EXEC + T fmax(const R_2d& r); + + template + CGPU_EXEC + T norm_2(const R_2d& r); + + template + CGPU_EXEC + T norm(const R_2d& r); + + template + CGPU_EXEC + R_2d normalize(const R_2d& r); + } + + /* R_2d */ + namespace mt + { + template + class R_xtd + { + public: + using value_type = T; + + T x; + T y; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + R_xtd(): x(T()), y(T()) {} + + // ! constructor by initializer list + template + CPU_EXEC + R_xtd(const dt_init_list& list) + { + auto ptr = list.begin(); + + x = T(ptr[0]); + y = T(ptr[1]); + } + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + x = T(v[ip + 0*n_r]); + y = (n_c>1)?T(v[ip + 1*n_r]):T(0); + } + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v) + { + x = T(v[0]); + y = T(v[1]); + } + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int32& n_v) + { + x = (n_v>0)?T(v[0]):T(0); + y = (n_v>1)?T(v[1]):T(0); + } + + // ! constructor a R_2d with an x. + CGPU_EXEC + R_xtd(const T& x): x(x), y(T()) {} + + /* converting constructor: R_2d with an x. */ + template + CGPU_EXEC + R_xtd(const U& x): x(T(x)), y(T()) {} + + // ! constructor a R_2d from its x and y parts. + CGPU_EXEC + R_xtd(const T& x, const T& y): x(x), y(y) {} + + /* converting constructor: R_2d from its x and y parts. */ + template + CGPU_EXEC + R_xtd(const U& x, const U& y): x(T(x)), y(T(y)) {} + + /* Copy constructor */ + CGPU_EXEC + R_xtd(const R_xtd& r): x(r.x), y(r.y) {} + + /* Move constructor */ + CGPU_EXEC + R_xtd(R_xtd&& r): x(std::move(r.x)), y(std::move(r.y)) {} + + /* converting copy constructor */ + template + CGPU_EXEC + R_xtd(const R_xtd& r): x(T(r.x)), y(T(r.y)) {} + + /******************************** assignment operators *********************************/ + // ! Assign x and set y to 0. + CGPU_EXEC + R_xtd& operator=(const T& x) + { + this->x = x; + this->y = T(0); + + return *this; + } + + // ! Convert and assign x and set y to 0. + template + CGPU_EXEC + R_xtd& operator=(const U& x) + { + this->x = T(x); + this->y = T(0); + + return *this; + } + + /* copy assignment operator */ + CGPU_EXEC + R_xtd& operator=(const R_xtd& r) + { + x = r.x; + y = r.y; + + return *this; + } + + /* Move assignment operator */ + CGPU_EXEC + R_xtd& operator=(R_xtd&& r) + { + if (this != &r) + { + x = std::move(r.x); + y = std::move(r.y); + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + R_xtd& operator=(const R_xtd& r) + { + x = T(r.x); + y = T(r.y); + + return *this; + } + + #ifdef __CUDACC__ + // ! Assignment operator from thrust::complex + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r) + { + x = r.real(); + y = r.imag(); + + return *this; + } + + /* converting assignment operator from thrust::complex */ + template + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + + return *this; + } + #endif + + // ! Assignment operator from std::complex + CPU_EXEC + R_xtd& operator=(const std::complex& r) + { + x = r.real(); + y = r.imag(); + + return *this; + } + + /* converting assignment operator from std::complex */ + template + CPU_EXEC + R_xtd& operator=(const std::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + + return *this; + } + + /******************* Compound assignment operators *******************/ + template + CGPU_EXEC + R_xtd& operator+=(const R_xtd& r) + { + *this = *this + r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator+=(const U& r) + { + *this = *this + r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator-=(const R_xtd& r) + { + *this = *this - r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator-=(const U& r) + { + *this = *this - r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator*=(const R_xtd& r) + { + *this = *this*r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator*=(const U& r) + { + *this = *this*r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator/=(const R_xtd& r) + { + *this = *this/r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator/=(const U& r) + { + *this = *this/r; + + return *this; + } + + /************************** Other operators **************************/ + CGPU_EXEC + dt_bool fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + CGPU_EXEC + dt_bool is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + CGPU_EXEC + dt_bool is_one() const + { + return mt::fcn_is_one(*this); + } + + CGPU_EXEC + R_xtd floor() const + { + return mt::floor(*this); + } + + CGPU_EXEC + R_xtd ceil() const + { + return mt::ceil(*this); + } + + CGPU_EXEC + R_xtd round() const + { + return mt::round(*this); + } + + CGPU_EXEC + T min() const + { + return mt::fmin(*this); + } + + CGPU_EXEC + T max() const + { + return mt::fmax(*this); + } + + CGPU_EXEC + T norm_2() const + { + return mt::norm_2(*this); + } + + CGPU_EXEC + T norm() const + { + return mt::norm(*this); + } + + CGPU_EXEC + void normalize() + { + *this = mt::normalize(*this); + } + + CGPU_EXEC + void fill(const T& v) + { + x = y = v; + } + + CGPU_EXEC + void assign_nzero(const R_xtd& r) + { + x = r.x; + y = (fcn_is_nzero(r.y))?r.y:r.x; + } + }; + } + + /* unitary operators */ + namespace mt + { + template + CGPU_EXEC + R_2d operator-(const R_2d& r) + { + return {-r.x, -r.y}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_2d& r) + { + return fcn_is_zero(r.x, r.y); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_2d& r) + { + return fcn_is_nzero(r.x, r.y); + } + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_2d& r) + { + return fcn_is_one(r.x, r.y); + } + + template + CGPU_EXEC + R_2d floor(const R_2d& r) + { + return {::floor(r.x), ::floor(r.y)}; + } + + template + CGPU_EXEC + R_2d ceil(const R_2d& r) + { + return {::ceil(r.x), ::ceil(r.y)}; + } + + template + CGPU_EXEC + R_2d round(const R_2d& r) + { + return {::round(r.x), ::round(r.y)}; + } + + template + CGPU_EXEC + T fmin(const R_2d& r) + { + return ::fmin(r.x, r.y); + } + + template + CGPU_EXEC + T fmax(const R_2d& r) + { + return ::fmax(r.x, r.y); + } + + template + CGPU_EXEC + R_2d square(const R_2d& r) + { + return {r.x*r.x, r.y*r.y}; + } + + template + CGPU_EXEC + R_2d sqrt(const R_2d& r) + { + return {::sqrt(r.x), ::sqrt(r.y)}; + } + + template + CGPU_EXEC + T norm_2(const R_2d& r) + { + return r.x*r.x + r.y*r.y; + } + + template + CGPU_EXEC + T norm(const R_2d& r) + { + return ::sqrt(norm_2(r)); + } + + template + CGPU_EXEC + R_2d normalize(const R_2d& r) + { + return fcn_div(r, r.norm()); + } + + template + CGPU_EXEC + R_2d fill_nzero(R_2d r) + { + r.x = r.x; + r.y = (fcn_is_nzero(r.y))?r.y:r.x; + + return r; + } + } + + /* binary operators */ + namespace mt + { + template > + CGPU_EXEC + R_2d operator+(const R_2d& lhs, const R_2d& rhs) + { + return {lhs.x + rhs.x, lhs.y + rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator+(const R_2d& lhs, const U& rhs) + { + return {lhs.x + rhs, lhs.y + rhs}; + } + + template > + CGPU_EXEC + R_2d operator+(const T& lhs, const R_2d& rhs) + { + return {lhs+ rhs.x, lhs + rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator-(const R_2d& lhs, const R_2d& rhs) + { + return {lhs.x - rhs.x, lhs.y - rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator-(const R_2d& lhs, const U& rhs) + { + return {lhs.x - rhs, lhs.y - rhs}; + } + + template > + CGPU_EXEC + R_2d operator-(const T& lhs, const R_2d& rhs) + { + return {lhs - rhs.x, lhs - rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator*(const R_2d& lhs, const R_2d& rhs) + { + return {lhs.x*rhs.x, lhs.y*rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator*(const R_2d& lhs, const U& rhs) + { + return {lhs.x*rhs, lhs.y*rhs}; + } + + template > + CGPU_EXEC + R_2d operator*(const T& lhs, const R_2d& rhs) + { + return {lhs*rhs.x, lhs*rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator/(const R_2d& lhs, const R_2d& rhs) + { + return {fcn_div(lhs.x, rhs.x), fcn_div(lhs.y, rhs.y)}; + } + + template > + CGPU_EXEC + R_2d operator/(const R_2d& lhs, const U& rhs) + { + return {fcn_div(lhs.x, rhs), fcn_div(lhs.y, rhs)}; + } + + template > + CGPU_EXEC + R_2d operator/(const T& lhs, const R_2d& rhs) + { + return {fcn_div(lhs, rhs.x), fcn_div(lhs, rhs.y)}; + } + + template > + CGPU_EXEC + R_2d fmin(const R_2d& lhs, const R_2d& rhs) + { + return {::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y)}; + } + + template > + CGPU_EXEC + R_2d fmax(const R_2d& lhs, const R_2d& rhs) + { + return {::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y)}; + } + + template > + CGPU_EXEC + X dot(const R_2d& lhs, const R_2d& rhs) + { + return lhs.x*rhs.x + lhs.y*rhs.y; + } + + template > + CGPU_EXEC + X angle(const R_2d& lhs, const R_2d& rhs) + { + X m = ::sqrt(lhs.norm_2()*rhs.norm_2()); + return ::acos(fcn_div(dot(lhs, rhs), m)); + } + } + + /* traits */ + namespace mt + { + template + struct is_r_2d: std::integral_constant>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value> {}; + + template + using enable_if_r_2d = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_r_2d_f64 = std::initializer_list>; + } + + /* data copy */ + namespace mt + { + // (dst, src): cpu -> cpu: R_2d + template + enable_if_real_real + memcpy_pos_cpu_cpu(R_2d* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, Ts* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + pcpu_dst[ik]= R_2d(pcpu_src[ik + 0*n_size], pcpu_src[ik + 1*n_size]); + } + } + + // (dst, src): cpu: R_2d -> cpu + template + enable_if_real_real + memcpy_pos_cpu_cpu(Td* pcpu_dst, const R_2d* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_2d* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + const auto& r_2d = pcpu_src[ik]; + + pcpu_dst[ip + 0*n_size] = Td(r_2d.x); + pcpu_dst[ip + 1*n_size] = Td(r_2d.y); + } + } + + #ifdef __CUDACC__ + // (dst, src): gpu: R_2d -> cpu + template + enable_if_real_real + memcpy_pos_gpu_cpu(Td* pcpu_dst, const R_2d* pgpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_2d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_2d)); + + if (pcpu_jk == nullptr) + { + R_2d* pcpu_t = new R_2d[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_t, n_size, icol); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_jk, n_size, icol); + } + } + + // (dst, src): cpu -> gpu: R_2d + template + enable_if_real_real + memcpy_pos_cpu_gpu(R_2d* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_2d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_2d)); + + if (pcpu_jk == nullptr) + { + R_2d* pcpu_t = new R_2d[n_size]; + memcpy_pos_cpu_cpu(pcpu_t, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_pos_cpu_cpu(pcpu_jk, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + #endif + + /************************** other operators **************************/ + // distance from point to line + template + CGPU_EXEC_INL + T fcn_pt_2_ln_dist(const T& a, const T& b, const T& c, const R_2d& r_0) + { + return fcn_pt_2_ln_dist(a, b, c, r_0.x, r_0.y); + } + + // calculate intersection from point to line + template + CGPU_EXEC_INL + R_2d fcn_pt_2_ln_intxn_2d(const T& a, const T& b, const T& c, const R_2d& r_0) + { + R_2d r; + fcn_pt_2_ln_intxn_2d(a, b, c, r_0.x, r_0.y, r.x, r.y); + + return r; + } + + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/r_3d.cuh b/src - Copy (2)/r_3d.cuh new file mode 100755 index 00000000..e57e9676 --- /dev/null +++ b/src - Copy (2)/r_3d.cuh @@ -0,0 +1,817 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef R_3D_H + #define R_3D_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "const_enum.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_fcns_gen.cuh" + #include "r_2d.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + /* forward declarations */ + namespace mt + { + template + using R_3d = R_xtd; + + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_3d& r); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_3d& r); + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_3d& r); + + template + CGPU_EXEC + R_3d floor(const R_3d& r); + + template + CGPU_EXEC + R_3d ceil(const R_3d& r); + + template + CGPU_EXEC + R_3d round(const R_3d& r); + + template + CGPU_EXEC + T fmin(const R_3d& r); + + template + CGPU_EXEC + T fmax(const R_3d& r); + + template + CGPU_EXEC + T norm_2(const R_3d& r); + + template + CGPU_EXEC + T norm(const R_3d& r); + + template + CGPU_EXEC + R_3d normalize(const R_3d& r); + } + + /* R_3d */ + namespace mt + { + template + class R_xtd + { + public: + using value_type = T; + + T x; + T y; + T z; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + R_xtd(): x(T()), y(T()), z(T()) {} + + // ! converting constructor by initializer list + template + CPU_EXEC + R_xtd(const dt_init_list& list) + { + auto ptr = list.begin(); + + x = T(ptr[0]); + y = T(ptr[1]); + z = T(ptr[2]); + } + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + x = T(v[ip + 0*n_r]); + y = (n_c>1)?T(v[ip + 1*n_r]):T(0); + z = (n_c>2)?T(v[ip + 2*n_r]):T(0); + } + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v) + { + x = T(v[0]); + y = T(v[1]); + z = T(v[2]); + } + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int32& n_v) + { + x = (n_v>0)?T(v[0]):T(0); + y = (n_v>1)?T(v[1]):T(0); + z = (n_v>2)?T(v[2]):T(0); + } + + // ! constructor a R_3d with an x part. + CGPU_EXEC + R_xtd(const T& x): x(x), y(T()), z(T()) {} + + /* converting constructor: R_3d with an x part. */ + template + CGPU_EXEC + R_xtd(const U& x): x(T(x)), y(T()), z(T()) {} + + // ! constructor a R_3d from its x and y parts. + CGPU_EXEC + R_xtd(const T& x, const T& y): x(x), y(y), z(T()) {} + + /* converting constructor: R_3d from its x and y parts. */ + template + CGPU_EXEC + R_xtd(const U& x, const U& y): x(T(x)), y(T(y)), z(T()) {} + + // ! constructor a R_3d from its x, y and z parts. + CGPU_EXEC + R_xtd(const T& x, const T& y, const T& z): x(x), y(y), z(z) {} + + /* converting constructor: R_3d from its x, y and z parts. */ + template + CGPU_EXEC + R_xtd(const U& x, const U& y, const U& z): x(T(x)), y(T(y)), z(T(z)) {} + + /* copy constructor */ + CGPU_EXEC + R_xtd(const R_xtd& r): x(r.x), y(r.y), z(r.z) {} + + /* Move constructor */ + CGPU_EXEC + R_xtd(R_xtd&& r): x(std::move(r.x)), y(std::move(r.y)), z(std::move(r.z)) {} + + /* converting copy constructor */ + template + CGPU_EXEC + R_xtd(const R_xtd& r): x(T(r.x)), y(T(r.y)), z(T(r.z)) {} + + /******************************** assignment operators *********************************/ + // ! Assign x and set y to 0. + CGPU_EXEC + R_xtd& operator=(const T& x) + { + this->x = x; + this->y = T(0); + this->z = T(0); + + return *this; + } + + // ! Convert and assign x and set y to 0. + template + CGPU_EXEC + R_xtd& operator=(const U& x) + { + this->x = T(x); + this->y = T(0); + this->z = T(0); + + return *this; + } + + /* copy assignment operator */ + CGPU_EXEC + R_xtd& operator=(const R_xtd& r) + { + x = r.x; + y = r.y; + z = r.z; + + return *this; + } + + /* Move assignment operator */ + CGPU_EXEC + R_xtd& operator=(R_xtd&& r) + { + if (this != &r) + { + x = std::move(r.x); + y = std::move(r.y); + z = std::move(r.z); + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + R_xtd& operator=(const R_xtd& r) + { + x = T(r.x); + y = T(r.y); + z = T(r.z); + + return *this; + } + + // ! Assignment operator from R_2d + CGPU_EXEC + R_xtd& operator=(const R_2d& r) + { + x = r.x; + y = r.y; + z = T(0); + + return *this; + } + + /* converting assignment operator from R_2d */ + template + CGPU_EXEC + R_xtd& operator=(const R_2d& r) + { + x = T(r.x); + y = T(r.y); + z = T(0); + + return *this; + } + + #ifdef __CUDACC__ + // ! Assignment operator from thrust::complex + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r) + { + x = r.real(); + y = r.imag(); + z = T(0); + + return *this; + } + + /* converting assignment operator from thrust::complex */ + template + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + z = T(0); + + return *this; + } + #endif + + // ! Assignment operator from std::complex + CPU_EXEC + R_xtd& operator=(const std::complex& r) + { + x = r.real(); + y = r.imag(); + z = T(0); + + return *this; + } + + /* converting assignment operator from std::complex */ + template + CPU_EXEC + R_xtd& operator=(const std::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + z = T(0); + + return *this; + } + + /******************* Compound assignment operators *******************/ + + template + CGPU_EXEC + R_xtd& operator+=(const R_xtd& r) + { + *this = *this + r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator+=(const U& r) + { + *this = *this + r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator-=(const R_xtd& r) + { + *this = *this - r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator-=(const U& r) + { + *this = *this - r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator*=(const R_xtd& r) + { + *this = *this*r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator*=(const U& r) + { + *this = *this*r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator/=(const R_xtd& r) + { + *this = *this/r; + + return *this; + } + + template + CGPU_EXEC + R_xtd& operator/=(const U& r) + { + *this = *this/r; + + return *this; + } + + /************************** Other operators **************************/ + CGPU_EXEC + dt_bool fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + CGPU_EXEC + dt_bool is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + CGPU_EXEC + dt_bool is_one() const + { + return fcn_is_one(*this); + } + + CGPU_EXEC + R_2d floor() const + { + return mt::floor(*this); + } + + CGPU_EXEC + R_2d ceil() const + { + return mt::ceil(*this); + } + + CGPU_EXEC + R_2d round() const + { + return mt::round(*this); + } + + CGPU_EXEC + T min() const + { + return mt::fmin(*this); + } + + CGPU_EXEC + T max() const + { + return mt::fmax(*this); + } + + CGPU_EXEC + T norm_2() const + { + return mt::norm_2(*this); + } + + CGPU_EXEC + T norm() const + { + return mt::norm(*this); + } + + CGPU_EXEC + void normalize() + { + *this = mt::normalize(*this); + } + + CGPU_EXEC + void fill(const T& v) + { + x = y = z = v; + } + }; + } + + /* unitary operators */ + namespace mt + { + template + CGPU_EXEC + R_3d operator-(const R_3d& r) + { + return {-r.x, -r.y, -r.z}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_3d& r) + { + return fcn_is_zero(r.x, r.y, r.z); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_3d& r) + { + return fcn_is_nzero(r.x, r.y, r.z); + } + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_3d& r) + { + return fcn_is_one(r.x, r.y, r.z); + } + + template + CGPU_EXEC + R_3d floor(const R_3d& r) + { + return {::floor(r.x), ::floor(r.y), ::floor(r.z)}; + } + + template + CGPU_EXEC + R_3d ceil(const R_3d& r) + { + return {::ceil(r.x), ::ceil(r.y), ::ceil(r.z)}; + } + + template + CGPU_EXEC + R_3d round(const R_3d& r) + { + return {::round(r.x), ::round(r.y), ::round(r.z)}; + } + + template + CGPU_EXEC + T fmin(const R_3d& r) + { + return ::fmin(r.x, ::fmin(r.y, r.z)); + } + + template + CGPU_EXEC + T fmax(const R_3d& r) + { + return ::fmax(r.x, ::fmax(r.y, r.z)); + } + + template + CGPU_EXEC + R_3d square(const R_3d& r) + { + return {r.x*r.x, r.y*r.y, r.z*r.z}; + } + + template + CGPU_EXEC + R_3d sqrt(const R_3d& r) + { + return {::sqrt(r.x), ::sqrt(r.y), ::sqrt(r.z)}; + } + + template + CGPU_EXEC + T norm_2(const R_3d& r) + { + return r.x*r.x + r.y*r.y + r.z*r.z; + } + + template + CGPU_EXEC + T norm(const R_3d& r) + { + return ::sqrt(norm_2(r)); + } + + template + CGPU_EXEC + R_3d normalize(const R_3d& r) + { + return fcn_div(r, r.norm()); + } + + template + CGPU_EXEC + R_3d fill_nzero(R_3d r) + { + r.x = r.x; + r.y = (fcn_is_nzero(r.y))?r.y:r.x; + r.z = (fcn_is_nzero(r.z))?r.z:r.y; + + return r; + } + } + + /* binary operators */ + namespace mt + { + template > + CGPU_EXEC + R_3d operator+(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator+(const R_3d& lhs, const U& rhs) + { + return {lhs.x + rhs, lhs.y + rhs, lhs.z + rhs}; + } + + template > + CGPU_EXEC + R_3d operator+(const T& lhs, const R_3d& rhs) + { + return {lhs+ rhs.x, lhs + rhs.y, lhs + rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator-(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator-(const R_3d& lhs, const U& rhs) + { + return {lhs.x - rhs, lhs.y - rhs, lhs.z - rhs}; + } + + template > + CGPU_EXEC + R_3d operator-(const T& lhs, const R_3d& rhs) + { + return {lhs - rhs.x, lhs - rhs.y, lhs - rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator*(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator*(const R_3d& lhs, const U& rhs) + { + return {lhs.x*rhs, lhs.y*rhs, lhs.z*rhs}; + } + + template > + CGPU_EXEC + R_3d operator*(const T& lhs, const R_3d& rhs) + { + return {lhs*rhs.x, lhs*rhs.y, lhs*rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator/(const R_3d& lhs, const R_3d& rhs) + { + return {fcn_div(lhs.x, rhs.x), fcn_div(lhs.y, rhs.y), fcn_div(lhs.z, rhs.z)}; + } + + template > + CGPU_EXEC + R_3d operator/(const R_3d& lhs, const U& rhs) + { + return {fcn_div(lhs.x, rhs), fcn_div(lhs.y, rhs), fcn_div(lhs.z, rhs)}; + } + + template > + CGPU_EXEC + R_3d operator/(const T& lhs, const R_3d& rhs) + { + return {fcn_div(lhs, rhs.x), fcn_div(lhs, rhs.y), fcn_div(lhs, rhs.z)}; + } + + template > + CGPU_EXEC + R_3d fmin(const R_3d& lhs, const R_3d& rhs) + { + return {::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y), ::fmin(lhs.z, rhs.z)}; + } + + template > + CGPU_EXEC + R_3d fmax(const R_3d& lhs, const R_3d& rhs) + { + return {::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y), ::fmax(lhs.z, rhs.z)}; + } + + template > + CGPU_EXEC + X dot(const R_3d& lhs, const R_3d& rhs) + { + return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; + } + + template > + CGPU_EXEC + R_3d cross(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.y*rhs.z-lhs.z*rhs.y, lhs.z*rhs.x-lhs.x*rhs.z, lhs.x*rhs.y-lhs.y*rhs.x}; + } + + template > + CGPU_EXEC + X angle(const R_3d& lhs, const R_3d& rhs) + { + X m = ::sqrt(lhs.norm_2()*rhs.norm_2()); + return ::acos(fcn_div(dot(lhs, rhs), m)); + } + } + + /* traits */ + namespace mt + { + template + struct is_r_3d: std::integral_constant>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value> {}; + + template + using enable_if_r_3d = typename std::enable_if::value, U>::type; + + template + struct is_r_nd: std::integral_constant::value || is_r_3d::value> {}; + + template + using enable_if_r_nd = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_r_3d_f64 = std::initializer_list>; + } + + /* data copy */ + namespace mt + { + /***************************************************************************************/ + // (dst, src): cpu -> cpu: R_3d + template + enable_if_real_real + memcpy_pos_cpu_cpu(R_3d* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, Ts* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + pcpu_dst[ik]= R_3d(pcpu_src[ik + 0*n_size], pcpu_src[ik + 1*n_size], pcpu_src[ik + 2*n_size]); + } + } + + // (dst, src): cpu: R_3d -> cpu + template + enable_if_real_real + memcpy_pos_cpu_cpu(Td* pcpu_dst, const R_3d* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_3d* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + const auto& r_3d = pcpu_src[ik]; + + pcpu_dst[ip + 0*n_size] = Td(r_3d.x); + pcpu_dst[ip + 1*n_size] = Td(r_3d.y); + pcpu_dst[ip + 2*n_size] = Td(r_3d.z); + } + } + + #ifdef __CUDACC__ + // (dst, src): gpu: R_3d -> cpu + template + enable_if_real_real + memcpy_pos_gpu_cpu(Td* pcpu_dst, const R_3d* pgpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_3d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_3d)); + + if (pcpu_jk == nullptr) + { + R_3d* pcpu_t = new R_3d[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_t, n_size, icol); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_jk, n_size, icol); + } + } + + // (dst, src): cpu -> gpu: R_3d + template + enable_if_real_real + memcpy_pos_cpu_gpu(R_3d* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_3d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_3d)); + + if (pcpu_jk == nullptr) + { + R_3d* pcpu_t = new R_3d[n_size]; + memcpy_pos_cpu_cpu(pcpu_t, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_pos_cpu_cpu(pcpu_jk, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + #endif + + /************************** other operators **************************/ + + } +#endif \ No newline at end of file diff --git a/src - Copy (2)/range.cuh b/src - Copy (2)/range.cuh new file mode 100755 index 00000000..c65c1fa8 --- /dev/null +++ b/src - Copy (2)/range.cuh @@ -0,0 +1,360 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef RANGE_H + #define RANGE_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "grid.cuh" + + /***************************************************************************************/ + /************************** Range template forward declaration *************************/ + /***************************************************************************************/ + namespace mt + { + template class Range_xd; + + template + using Range = Range_xd; + + /* 1d */ + template + using Range_1d_st = Range_xd; + + using Range_1d = Range_xd; + + using Range_1d_64 = Range_xd; + + /* 2d */ + template + using Range_2d_st = Range_xd; + + using Range_2d = Range_xd; + + using Range_2d_64 = Range_xd; + + /* 3d */ + template + using Range_3d_st = Range_xd; + + using Range_3d = Range_xd; + + using Range_3d_64 = Range_xd; + } + + /* template specialization 1d */ + namespace mt + { + template + class Range_xd + { + public: + using size_type = ST; + + ST ix_0; // initial x index + ST nx; // x points + + /************************************* constructors ************************************/ + CGPU_EXEC + Range_xd() : ix_0(0), nx(0) {} + + Range_xd(const ST& ix_0, const ST& nx) : ix_0(ix_0), nx(nx) {} + + /* copy constructor */ + CGPU_EXEC + Range_xd(const Range_xd& range) + { + *this = range; + } + + /* converting constructor */ + template + CGPU_EXEC + Range_xd(const Range_xd& range) + { + *this = range; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Range_xd& operator=(const Range_xd& range) + { + if (this != &range) + { + ix_0 = range.ix_0; + nx = range.nx; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Range_xd& operator=(const Range_xd& range) + { + if (this != &range) + { + ix_0 = ST(range.ix_0); + nx = ST(range.nx); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Range_xd& range) + { + *this = range; + } + + /***************************************************************************************/ + template + void set_in_data(const SU& ix_0, const SU& nx) + { + this->ix_0 = ST(ix_0); + this->nx = ST(nx); + } + + template + void set_in_data(const T& r, const T& r_max, const Grid_1d& grid) + { + grid.ix_0_ix_n(r, r_max, ix_0, nx); + } + + CGPU_EXEC + void clear() + { + ix_0 = ST(0); + nx = ST(0); + } + }; + } + + /* template specialization 2d */ + namespace mt + { + template + class Range_xd: public Range_xd + { + public: + using size_type = ST; + + ST iy_0; // initial y index + ST ny; // y points + + /************************************* constructors ************************************/ + CGPU_EXEC + Range_xd(): Range_xd(), iy_0(0), ny(0) {} + + Range_xd(const ST& ix_0, const ST& nx, const ST& iy_0, const ST& ny) + : Range_xd(ix_0, nx), iy_0(iy_0), ny(ny) {} + + /* copy constructor */ + CGPU_EXEC + Range_xd(const Range_xd& range) + { + *this = range; + } + + /* converting constructor */ + template + CGPU_EXEC + Range_xd(const Range_xd& range) + { + *this = range; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Range_xd& operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iy_0 = range.iy_0; + ny = range.ny; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Range_xd& operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iy_0 = ST(range.iy_0); + ny = ST(range.ny); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Range_xd& range) + { + *this = range; + } + + /***************************************************************************************/ + template + void set_in_data(const SU& ix_0, const SU& nx, const SU& iy_0, const SU& ny) + { + Range_xd::set_in_data(ix_0, nx); + + this->iy_0 = ST(iy_0); + this->ny = ST(ny); + } + + template + void set_in_data(const R_2d& r, const T& r_max, const Grid_2d& grid) + { + grid.ix_0_ix_n(r.x, r_max, this->ix_0, this->nx); + grid.iy_0_iy_n(r.y, r_max, iy_0, ny); + } + + CGPU_EXEC + void clear() + { + Range_xd::clear(); + + iy_0 = ST(0); + ny = ST(0); + } + }; + } + + /* template specialization 3d */ + namespace mt + { + template + class Range_xd: public Range_xd + { + public: + using size_type = ST; + + ST iz_0; // initial z index + ST nz; // z points + + /************************************* constructors ************************************/ + CGPU_EXEC + Range_xd(): Range_xd(), iz_0(0), nz(0) {} + + Range_xd(const ST& ix_0, const ST& nx, const ST& iy_0, const ST& ny, const ST& iz_0, const ST& nz) + : Range_xd(ix_0, nx, iy_0, ny), iz_0(iz_0), nz(nz) {} + + /* copy constructor */ + CGPU_EXEC + Range_xd(const Range_xd& range) + { + *this = range; + } + + /* converting constructor */ + template + CGPU_EXEC + Range_xd(const Range_xd& range) + { + *this = range; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Range_xd& operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iz_0 = range.iz_0; + nz = range.nz; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Range_xd& operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iz_0 = ST(range.iz_0); + nz = ST(range.nz); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Range_xd& range) + { + *this = range; + } + + /***************************************************************************************/ + template + void set_in_data(const SU& ix_0, const SU& nx, const SU& iy_0, const SU& ny, const SU& iz_0, const SU& nz) + { + Range_xd::set_in_data(ix_0, nx, iy_0, ny); + + this->iz_0 = ST(iz_0); + this->nz = ST(nz); + } + + template + void set_in_data(const R_3d& r, const T& r_max, const Grid_3d& grid) + { + grid.ix_0_ix_n(r.x, r_max, this->ix_0, this->nx); + grid.iy_0_iy_n(r.y, r_max, this->iy_0, this->ny); + grid.iz_0_iz_n(r.z, r_max, iz_0, nz); + } + + CGPU_EXEC + void clear() + { + Range_xd::clear(); + + iz_0 = ST(0); + nz = ST(0); + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/region.cuh b/src - Copy (2)/region.cuh new file mode 100755 index 00000000..9c9dd071 --- /dev/null +++ b/src - Copy (2)/region.cuh @@ -0,0 +1,938 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef REGION_H + #define REGION_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "math.cuh" + #include "const_enum.cuh" + #include "cgpu_fcns_gen.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + + /***************************************************************************************/ + /********************** iRegion_Rect template forward declaration **********************/ + /***************************************************************************************/ + namespace mt + { + template class Region_Rect_xd; + + template + using iRegion_Rect_xd = Region_Rect_xd; + + /* 1d */ + template + using Region_Rect_1d = Region_Rect_xd; + + using iRegion_Rect_1d = Region_Rect_xd; + + using iRegion_Rect_1d_64 = Region_Rect_xd; + + /* 2d */ + template + using Region_Rect_2d = Region_Rect_xd; + + using iRegion_Rect_2d = Region_Rect_xd; + + using iRegion_Rect_2d_64 = Region_Rect_xd; + + /* 3d */ + template + using Region_Rect_3d = Region_Rect_xd; + + using iRegion_Rect_3d = Region_Rect_xd; + + using iRegion_Rect_3d_64 = Region_Rect_xd; + } + + /* template specialization 1d */ + namespace mt + { + template + class Region_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T rx_0; // initial x position + T rx_e; // final x position + + /************************************* constructors ************************************/ + CGPU_EXEC + Region_Rect_xd(): rx_0(0), rx_e(0) {} + + Region_Rect_xd(const T& rx_0, const T& rx_e) + { + set_in_data(rx_0, rx_e); + } + + template + Region_Rect_xd(U *data, const size_type& n_data) + { + rx_0 = (n_data>0)?data[0]:T(0); + rx_e = (n_data>1)?data[1]:T(0); + } + + /* copy constructor */ + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /* converting constructor */ + template + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + rx_0 = region.rx_0; + rx_e = region.rx_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + rx_0 = T(region.rx_0); + rx_e = T(region.rx_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Region_Rect_xd& region) + { + *this = region; + } + + /***************************************************************************************/ + template + void set_in_data(const U& rx_0, const U& rx_e) + { + this->rx_0 = rx_0; + this->rx_e = rx_e; + } + + CGPU_EXEC + void clear() + { + rx_0 = T(0); + rx_e = T(0); + } + + CGPU_EXEC + T bs_x() const + { + return fcn_max(rx_e-rx_0, T(0)); + } + + CGPU_EXEC + T bs() const + { + return bs_x(); + } + + CGPU_EXEC + T bs_x_h() const + { + return bs_x()/T(2); + } + + CGPU_EXEC + T bs_h() const + { + return bs_x_h(); + } + + CGPU_EXEC + T rx_c() const + { + return (rx_e+rx_0)/T(2); + } + + CGPU_EXEC + T r_c() const + { + return rx_c(); + } + + CGPU_EXEC + T radius_x() const + { + return bs_x_h(); + } + + CGPU_EXEC + T radius() const + { + return radius_x(); + } + + CGPU_EXEC + T radius_x_p(const T& p) const + { + return (T(1)-p)*radius_x(); + } + + CGPU_EXEC + T radius_p(const T& p) const + { + return radius_x_p(p); + } + + void sft_region(const T& bs, const T& dr) + { + rx_0 = fcn_set_bound(rx_0 + dr, T(0), bs); + rx_e = fcn_set_bound(rx_e + dr, T(0), bs); + } + + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_0, rx_e); + } + + CGPU_EXEC + dt_bool chk_bound(const T& r) const + { + return chk_bound_x(r); + } + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_0, rx_e); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const T& r) const + { + return chk_bound_x_eps(r); + } + + template > + CGPU_EXEC + T sub_2_ind(const T& ix) const + { + return ix-rx_0; + } + }; + } + + /* template specialization 2d */ + namespace mt + { + template + class Region_Rect_xd: public Region_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T ry_0; // initial y position + T ry_e; // final y position + + /************************************* constructors ************************************/ + CGPU_EXEC + Region_Rect_xd(): Region_Rect_xd(), ry_0(0), ry_e(0) {} + + Region_Rect_xd(const T& rx_0, const T& rx_e, const T& ry_0, const T& ry_e) + { + set_in_data(rx_0, rx_e, ry_0, ry_e); + } + + template + Region_Rect_xd(U *data, const size_type& n_data) + { + Region_Rect_xd(data, n_data); + + ry_0 = (n_data>2)?data[2]:T(0); + ry_e = (n_data>3)?data[3]:T(0); + } + + /* copy constructor */ + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /* converting constructor */ + template + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + ry_0 = region.ry_0; + ry_e = region.ry_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + ry_0 = T(region.ry_0); + ry_e = T(region.ry_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Region_Rect_xd& region) + { + *this = region; + } + + /***************************************************************************************/ + template + void set_in_data(const U& rx_0, const U& rx_e, const U& ry_0, const U& ry_e) + { + Region_Rect_xd::set_in_data(rx_0, rx_e); + + this->ry_0 = ry_0; + this->ry_e = ry_e; + } + + CGPU_EXEC + void clear() + { + Region_Rect_xd::clear(); + + ry_0 = T(0); + ry_e = T(0); + } + + CGPU_EXEC + T bs_y() const + { + return fcn_max(ry_e-ry_0, T(0)); + } + + CGPU_EXEC + R_2d bs() const + { + return {this->bs_x(), bs_y()}; + } + + CGPU_EXEC + T bs_y_h() const + { + return bs_y()/T(2); + } + + CGPU_EXEC + R_2d bs_h() const + { + return {this->bs_x_h(), bs_y_h()}; + } + + CGPU_EXEC + T ry_c() const + { + return (ry_e+ry_0)/T(2); + } + + CGPU_EXEC + R_2d r_c() const + { + return {this->rx_c(), ry_c()}; + } + + CGPU_EXEC + T radius_y() const + { + return bs_y_h(); + } + + CGPU_EXEC + R_2d radius() const + { + return {this->radius_x(), radius_y()}; + } + + CGPU_EXEC + T radius_y_p(const T& p) const + { + return (T(1)-p)*radius_y(); + } + + CGPU_EXEC + R_2d radius_p(const T& p) const + { + return {this->radius_x_p(p), radius_y_p(p)}; + } + + void sft_region(const R_2d& bs, const R_2d& dr) + { + Region_Rect_xd::sft_region(bs.x, dr.x); + + ry_0 = fcn_set_bound(ry_0 + dr.y, T(0), bs.y); + ry_e = fcn_set_bound(ry_e + dr.y, T(0), bs.y); + } + + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_y(const T& y) const + { + return fcn_chk_bound(y, ry_0, ry_e); + } + + CGPU_EXEC + dt_bool chk_bound(const R_2d& r) const + { + return this->chk_bound_x(r.x) && chk_bound_y(r.y); + } + + CGPU_EXEC + dt_bool chk_bound(const T& rx, const T& ry)const + { + return this->chk_bound_x(rx) && chk_bound_y(ry); + } + + CGPU_EXEC + dt_bool chk_bound_y_eps(const T& y) const + { + return fcn_chk_bound_eps(y, ry_0, ry_e); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const R_2d& r) const + { + return this->chk_bound_x_eps(r.x) && chk_bound_y_eps(r.y); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const T& rx, const T& ry)const + { + return this->chk_bound_x_eps(rx) && chk_bound_y_eps(ry); + } + + template > + CGPU_EXEC + T sub_2_ind(const T& ix, const T& iy) const + { + return (iy-ry_0) + (ix-this->rx_0)*bs_y(); + } + }; + } + + /* template specialization 3d */ + namespace mt + { + template + class Region_Rect_xd: public Region_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T rz_0; // initial z position + T rz_e; // final z position + + /************************************* constructors ************************************/ + CGPU_EXEC + Region_Rect_xd(): Region_Rect_xd(), rz_0(0), rz_e(0) {} + + Region_Rect_xd(const T& rx_0, const T& rx_e, const T& ry_0, const T& ry_e, const T& rz_0, const T& rz_e) + { + set_in_data(rx_0, rx_e, ry_0, ry_e, rz_0, rz_e); + } + + template + Region_Rect_xd(U *data, const size_type& n_data) + { + Region_Rect_xd(data, n_data); + + rz_0 = (n_data>4)?data[4]:T(0); + rz_e = (n_data>5)?data[5]:T(0); + } + + /* copy constructor */ + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /* converting constructor */ + template + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + rz_0 = region.rz_0; + rz_e = region.rz_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + rz_0 = T(region.rz_0); + rz_e = T(region.rz_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Region_Rect_xd& region) + { + *this = region; + } + + /***************************************************************************************/ + template + void set_in_data(const U& rx_0, const U& rx_e, const U& ry_0, const U& ry_e, const U& rz_0, const U& rz_e) + { + Region_Rect_xd::set_in_data(rx_0, rx_e, ry_0, ry_e); + + this->rz_0 = rz_0; + this->rz_e = rz_e; + } + + CGPU_EXEC + void clear() + { + Region_Rect_xd::clear(); + + rz_0 = T(0); + rz_e = T(0); + } + + CGPU_EXEC + T bs_z() const + { + return fcn_max(rz_e-rz_0, T(0)); + } + + CGPU_EXEC + R_3d bs() const + { + return {this->bs_x(), this->bs_y(), bs_z()}; + } + + CGPU_EXEC + T bs_z_h() const + { + return bs_z()/T(2); + } + + CGPU_EXEC + R_3d bs_h() const + { + return {this->bs_x_h(), this->bs_y_h(), bs_z_h()}; + } + + CGPU_EXEC + T rz_c() const + { + return (rz_e+rz_0)/T(2); + } + + CGPU_EXEC + R_3d r_c() const + { + return {this->rx_c(), this->ry_c(), rz_c()}; + } + + CGPU_EXEC + T radius_z() const + { + return bs_z_h(); + } + + CGPU_EXEC + R_3d radius() const + { + return {this->radius_x(), this->radius_y(), radius_z()}; + } + + CGPU_EXEC + T radius_z_p(const T& p) const + { + return (T(1)-p)*radius_z(); + } + + CGPU_EXEC + R_3d radius_p(const T& p) const + { + return {this->radius_x_p(p), this->radius_y_p(p), radius_z_p(p)}; + } + + void sft_region(const R_3d& bs, const R_3d& dr) + { + Region_Rect_xd::sft_region({bs.x, bs.y}, {dr.x, dr.y}); + + rz_0 = fcn_set_bound(rz_0 + dr.z, T(0), bs.z); + rz_e = fcn_set_bound(rz_e + dr.z, T(0), bs.z); + } + + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_z(const T& z) const + { + return fcn_chk_bound(z, rz_0, rz_e); + } + + CGPU_EXEC + dt_bool chk_bound(const R_3d& r) const + { + return this->chk_bound_x(r.x) && this->chk_bound_y(r.y) && chk_bound_z(r.z); + } + + CGPU_EXEC + dt_bool chk_bound(const T& rx, const T& ry, const T& rz)const + { + return this->chk_bound_x(rx) && this->chk_bound_y(ry) && chk_bound_z(rz); + } + + CGPU_EXEC + dt_bool chk_bound_z_eps(const T& z) const + { + return fcn_chk_bound_eps(z, rz_0, rz_e); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const R_3d& r) const + { + return this->chk_bound_x_eps(r.x) && this->chk_bound_y_eps(r.y) && chk_bound_z_eps(r.z); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const T& rx, const T& ry, const T& rz)const + { + return this->chk_bound_x_eps(rx) && this->chk_bound_y_eps(ry) && chk_bound_z_eps(rz); + } + + template > + CGPU_EXEC + T sub_2_ind(const T& ix, const T& iy, const T& iz) const + { + return (iy-this->ry_0) + (ix-this->rx_0)*this->bs_y() + (iz-rz_0)*this->bs_y()*this->bs_x(); + } + }; + } + + /***************************************************************************************/ + /* symmetric region */ + namespace mt + { + /* + template + struct Region_Rad_1d + { + public: + using T = class TVctr::value_type; + using size_type = dt_uint64; + + TVctr Rx; + TVctr R2; + TVctr Ixy; + + T R_max; + T Rx_sf; + + T Ixy_sf; + T Ixy_sc; + T Ixy_sum; + + Region_Rad_1d(): Rx_sf(0), Ixy_sf(0), Ixy_sc(1), Ixy_sum(0) + { + } + + size_type size() const + { + return Ixy.size(); + } + + void clear() + { + Rx.clear(); + R2.clear(); + Ixy.clear(); + } + + void reserve(const size_type& new_size) + { + Rx.reserve(new_size); + R2.reserve(new_size); + Ixy.reserve(new_size); + } + + void shrink_to_fit() + { + Rx.shrink_to_fit(); + R2.shrink_to_fit(); + Ixy.shrink_to_fit(); + } + + TVctr sft_Ixy(T bg) + { + TVctr Ixy_s; + Ixy_s.reserve(Ixy.size()); + + for(auto ixy=0; ixy + struct Region_Rad_2d + { + public: + using T = class TVctr::value_type; + using size_type = dt_uint64; + + TVctr Rx; + TVctr Ry; + TVctr R2; + TVctr Ixy; + + T R_max; + T Rx_sf; + T Ry_sf; + T Rxy_sc; + + T Ixy_sf; + T Ixy_sc; + T Ixy_sum; + + Region_Rad_2d(): Rx_sf(0), Ry_sf(0), Rxy_sc(1), + Ixy_sf(0), Ixy_sc(1), Ixy_sum(0) {} + + size_type size() const + { + return Ixy.size(); + } + + void clear() + { + Rx.clear(); + Ry.clear(); + R2.clear(); + Ixy.clear(); + } + + void reserve(const size_type& new_size) + { + Rx.reserve(new_size); + Ry.reserve(new_size); + R2.reserve(new_size); + Ixy.reserve(new_size); + } + + void shrink_to_fit() + { + Rx.shrink_to_fit(); + Ry.shrink_to_fit(); + R2.shrink_to_fit(); + Ixy.shrink_to_fit(); + } + + TVctr sft_Ixy(T bg) + { + TVctr Ixy_s; + Ixy_s.reserve(Ixy.size()); + + for(auto ixy=0; ixy& grid_2d, TVctr& Im_s, T x, T y) + { + TVctr v = Ixy; + + T R2_max = ::square(R_max); + + R_2d p(x, y); + auto range = grid_2d.ithread(p, R_max); + dt_int32 iv = 0; + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + v[iv++] -= Im_s[grid_2d.sub_2_ind(ix, iy)]/Ixy_sc; + } + } + } + + return v; + } + + TVctr sft_Ixy(Grid_2d& grid_2d, TVctr& Im_s, T x, T y, T a, T s) + { + TVctr v = sub_region_to_Ixy(grid_2d, Im_s, x*Rxy_sc+Rx_sf, y*Rxy_sc+Ry_sf); + + T alpha = T(0.5)/::square(s); + T r2_l = ::square(T(4)*s); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x; + T ry = Ry[im]-y; + T r2 = rx*rx+ry*ry; + if (r2& grid_2d, TVctr& Im_s, TVctr& x, TVctr& y, TVctr& A, TVctr& S) + { + TVctr v = sub_region_to_Ixy(grid_2d, Im_s, x[0]*Rxy_sc+Rx_sf, y[0]*Rxy_sc+Ry_sf); + + for(auto ip = 0; ip < x.size(); ip++) + { + T a = A[ip]; + T b = S[ip]; + T alpha = 0.5/pow(b, 2); + T r2_l = pow(4.0*b, 2); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x[ip]; + T ry = Ry[im]-y[ip]; + T r2 = rx*rx+ry*ry; + if (r2 sft_x_y(T x, T y) const + { + x = sft_Rx(x); + y = sft_Ry(y); + return R_2d(x, y); + } + + // not including R2 + void sf_sc() + { + KS Ixy_sum_t = 0; + for(auto ixy = 0; ixy < Ixy.size(); ixy++) + { + Rx[ixy] = (Rx[ixy] - Rx_sf)/Rxy_sc; + Ry[ixy] = (Ry[ixy] - Ry_sf)/Rxy_sc; + T Iv = Ixy[ixy]/Ixy_sc; + Ixy[ixy] = Iv; + Ixy_sum_t += Iv; + } + Ixy_sum = Ixy_sum_t; + } + }; + */ + + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/rot_in_parm.hpp b/src - Copy (2)/rot_in_parm.hpp new file mode 100755 index 00000000..5d4c9042 --- /dev/null +++ b/src - Copy (2)/rot_in_parm.hpp @@ -0,0 +1,100 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ROT_IN_PARM_H + #define ROT_IN_PARM_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "r_3d.cuh" + + namespace mt + { + /*********************** rotation parameters *************************/ + template + class Rot_In_Parm + { + public: + T theta; // angle + R_3d u_0; // unitary vector + eRot_Ctr_Typ ctr_type; // erct_geometric_ctr, erct_user_def + R_3d ctr_p; // rotation point + + Rot_In_Parm(): theta(0), u_0(0, 0, 1), ctr_type(erct_geometric_ctr), ctr_p(1, 0, 0) {} + + template + void assign(Rot_In_Parm& rot_in_parm) + { + if (this != &rot_in_parm) + { + theta = rot_in_parm.theta; + u_0 = rot_in_parm.u_0; + ctr_type = rot_in_parm.ctr_type; + ctr_p = rot_in_parm.ctr_p; + } + } + + void set_in_data(const T& theta, const R_3d& u_0, const eRot_Ctr_Typ& ctr_type, const R_3d& ctr_p) + { + this->theta = theta; + this->u_0 = u_0; + this->ctr_type = ctr_type; + this->ctr_p = ctr_p; + + set_dep_var(); + } + + void set_dep_var() + { + u_0.normalize(); + } + + template + Rot_In_Parm& operator=(Rot_In_Parm& rot_in_parm) + { + assign(rot_in_parm); + return *this; + } + + dt_bool is_rot_ctr_none() const + { + return mt::is_rot_ctr_none(center_type); + } + + dt_bool is_rot_ctr_geometric_ctr() const + { + return mt::is_rot_ctr_geometric_ctr(center_type); + } + + dt_bool is_rot_ctr_user_def() const + { + return mt::is_rot_ctr_user_def(center_type); + } + + dt_bool is_rot_active() const + { + return fcn_is_nzero(theta); + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/scan_pat.hpp b/src - Copy (2)/scan_pat.hpp new file mode 100755 index 00000000..2fb81123 --- /dev/null +++ b/src - Copy (2)/scan_pat.hpp @@ -0,0 +1,237 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SCAN_PAT_H + #define SCAN_PAT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.cuh" + #include "math.cuh" + #include "cgpu_fcns_gen.cuh" + #include "r_2d.cuh" + #include "cgpu_vctr.cuh" + + namespace mt + { + /************************* scanning pattern **************************/ + template + struct Scan_Pat + { + public: + using value_type = T; + using size_type = dt_int32; + + eScan_Pat_Typ typ; // 1: Line, 2: Area, 3: User_Define + dt_bool pbc; // periodic boundary conditions + dt_bool spxs; // square pixel size + R_2d nsp; // number of sampling points + R_2d r_0; // initial scanning position + R_2d r_e; // final scanning position + Vctr_r_2d_cpu r; // user define positions + + Scan_Pat(): typ(espt_line), pbc(false), spxs(true), nsp(0, 0), + r_0(0, 0), r_e(0, 0), dr(0, 0){}; + + template + void assign(Scan_Pat& scan) + { + if (this != &scan) + { + typ = scan.typ; + pbc = scan.pbc; + spxs = scan.spxs; + nsp = scan.nsp; + r_0 = scan.r_0; + r_e = scan.r_e; + + dr = scan.dr; + r = scan.r; + } + } + + void set_in_data(const eScan_Pat_Typ& typ, const dt_bool& pbc, const dt_bool& spxs, + const R_2d& nsp, const R_2d& r_0, const R_2d& r_e, const Vctr_r_2d_cpu& r) + { + this->typ = typ; + this->pbc = pbc; + this->spxs = spxs; + this->nsp = nsp; + this->r_0 = r_0; + this->r_e = r_e; + this->r = r; + + set_dep_var(); + } + + void set_dep_var() + { + if ((nsp.x <= 0) || (nsp.y <= 0)) + { + clear(); + return; + } + + if (is_scan_pat_line()) + { + set_grid_scan_pat_line(); + } + else if (is_scan_pat_area()) + { + set_grid_scan_pat_area(); + } + else if (is_scan_pat_user_def()) + { + nsp.x = r.size(); + nsp.y = nsp.x; + } + } + + template + Scan_Pat& operator=(Scan_Pat& scan) + { + assign(scan); + return *this; + } + + size_type size() const + { + return nsp.x*nsp.y; + } + + void clear() + { + typ = espt_line; + pbc = false; + spxs = true; + nsp.x = 0; + nsp.y = 0; + r_0 = 0; + r_e = 0; + r.clear_shrink_to_fit(); + dr = 0; + } + + R_2d operator()(const dt_int32& ind) const + { + if (is_scan_pat_user_def()) + { + return r_ud[ind]; + } + else + { + const dt_int32 ix = ind/nsp.y; + const dt_int32 iy = ind - ix*nsp.y; + + return (r_0 + R_2d(ix, iy)*dr); + } + } + + Vctr_cpu rx_vctr() const + { + Vctr_cpu x; + x.reserve(nsp.x); + if (is_scan_pat_user_def()) + { + for(auto ix = 0; ix ry_vctr() const + { + Vctr_cpu y; + y.reserve(nsp.y); + if (is_scan_pat_user_def()) + { + for(auto iy = 0; iy dr; // pixel size + + void set_grid_scan_pat_line() + { + const auto r_u = r_e-r_0; + dr = r_u/((pbc)?nsp:(nsp-1)); + } + + void set_grid_scan_pat_area() + { + const auto r_u = r_e-r_0; + dr = r_u/((pbc)?nsp:(nsp-1)); + + if (spxs) + { + if (fabs(r_u.x)>fabs(r_u.y)) + { + dr.y = std::copysign(dr.x, r_u.y); + nsp.y = fcn_cfloor(r_u.y/dr.y+Epsilon::rel+0.5); + nsp.y += (pbc)?0:1; + } + else + { + dr.x = std::copysign(dr.y, r_u.x); + nsp.x = fcn_cfloor(r_u.x/dr.x+Epsilon::rel+0.5); + nsp.x += (pbc)?0:1; + } + } + } + + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/shape_t.hpp b/src - Copy (2)/shape_t.hpp new file mode 100755 index 00000000..01a61c6e --- /dev/null +++ b/src - Copy (2)/shape_t.hpp @@ -0,0 +1,178 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SHAPE_H + #define SHAPE_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "macros.cuh" + + template + class dt_shape_st + { + public: + /************************************* constructors ************************************/ + dt_shape_st(): dim_max(4) + { + for (int32_t ik=0; ik + dt_shape_st(const U& s0): dt_shape_st() + { + m_data[0] = T(s0); + } + + template + dt_shape_st(const U& s0, const V& s1): dt_shape_st() + { + m_data[0] = T(s0); + m_data[1] = T(s1); + } + + template + dt_shape_st(const U& s0, const V& s1, const X& s2): dt_shape_st() + { + m_data[0] = T(s0); + m_data[1] = T(s1); + m_data[2] = T(s2); + } + + template + dt_shape_st(const U& s0, const V& s1, const X& s2, const Y& s3): dt_shape_st() + { + m_data[0] = T(s0); + m_data[1] = T(s1); + m_data[2] = T(s2); + m_data[3] = T(s3); + } + + /* copy constructor */ + dt_shape_st(const dt_shape_st& shape): dt_shape_st() + { + *this = shape; + } + + /* converting constructor */ + template + dt_shape_st(const dt_shape_st& shape): dt_shape_st() + { + *this = shape; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + dt_shape_st& operator=(const dt_shape_st& shape) + { + for (int32_t ik=0; ik + dt_shape_st& operator=(const dt_shape_st& shape) + { + for (int32_t ik=0; ik1; ik--) + { + if (m_data[ik]<2) + { + ic++; + } + else + break; + } + + return T(dim_max-ic); + } + + T m_data[4]; + + private: + const int32_t dim_max; + }; + + using dt_shape = dt_shape_st; + + using dt_shape_64 = dt_shape_st; +#endif \ No newline at end of file diff --git a/src - Copy (2)/space_group.hpp b/src - Copy (2)/space_group.hpp new file mode 100755 index 00000000..49b19e05 --- /dev/null +++ b/src - Copy (2)/space_group.hpp @@ -0,0 +1,596 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPACE_GROUP_H + #define SPACE_GROUP_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "mx_2x2.cuh" + #include "mx_3x3.cuh" + #include "cgpu_vctr.cuh" + #include "types.cuh" + #include "particles.cuh" + + namespace mt + { + + template + struct Symm_Oper + { + Vctr_r_3d tr_g; + Vctr_Mx_3x3 M; + Vctr_r_3d tr; + + Symm_Oper(const Vctr_std>& tr_g, const Vctr_std>& M, const Vctr_std>& tr): + tr_g(tr_g), M(M), tr(tr) {} + + //Symm_Oper(const dt_init_list_r_3d_f64& tr_g, const dt_init_list_mx_3x3_f64& M, const dt_init_list_r_3d_f64& tr): + //tr_g(tr_g), M(M), tr(tr) {} + }; + + template + class Space_Group{ + public: + Space_Group(): ee(1e-4) {}; + + Space_Group(Ptc_Atom& asym_uc, dt_int32 sg=1): Space_Group() + { + ptc_atom = operator()(asym_uc, sg); + } + + operator Ptc_Atom() const + { + return ptc_atom; + } + + Ptc_Atom operator()(Ptc_Atom& asym_uc, dt_int32 sg=1) + { + auto sym = load_symm_oper(sg); + + const dt_int32 n_asym_uc = asym_uc.size(); + + const dt_int32 n_M = sym.M.size(); + const dt_int32 n_tr_g = sym.tr_g.size(); + + Ptc_Atom base; + base.reserve(n_M*n_tr_g*n_asym_uc); + base.cols_used = asym_uc.cols_used; + + for(auto i_tr=0; i_tr ptc_atom; + + T ee; + + dt_bool exist(Ptc_Atom& base, const R_3d& r) + { + const auto ee_2 = ee*ee; + for(auto i_b=0; i_b load_symm_oper(const dt_int32& sg) + { + switch(sg) + { + case 1: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}}}; + case 2: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 3: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 4: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 5: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 6: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 7: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 8: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 9: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 10: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 11: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 12: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 13: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 14: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 15: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 16: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 17: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 18: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 19: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 20: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 21: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 22: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 23: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 24: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 25: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 26: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 27: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 28: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 29: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 30: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 31: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 32: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 33: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 34: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 35: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 36: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 37: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 38: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 39: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 40: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 41: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 42: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 43: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 44: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 45: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 46: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 47: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 48: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 49: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 50: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 51: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 52: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 53: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 54: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 55: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 56: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 57: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}}}; + case 58: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 59: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 60: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 61: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 62: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 63: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 64: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 65: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 66: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 67: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 68: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 69: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 70: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {3.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 1.0/4.0}}}; + case 71: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 72: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 73: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 74: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 75: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 76: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 3.0/4.0}}}; + case 77: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 78: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/4.0}}}; + case 79: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 80: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}}}; + case 81: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 82: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 83: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 84: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 85: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 86: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 87: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 88: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 89: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 90: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 91: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/4.0}}}; + case 92: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 93: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 94: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 95: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 3.0/4.0}}}; + case 96: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 97: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 98: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 99: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 100: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 101: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 102: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 103: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 104: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 105: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 106: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 107: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 108: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 109: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}}}; + case 110: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 0.0, 1.0/4.0}}}; + case 111: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 112: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 113: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 114: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 115: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 116: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 117: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 118: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 119: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 120: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 121: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 122: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}}}; + case 123: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 124: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 125: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 126: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 127: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 128: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 129: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 130: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 131: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 132: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 133: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 134: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 135: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 136: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 137: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 138: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 139: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 140: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 141: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}}}; + case 142: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 143: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 144: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}}}; + case 145: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}}}; + case 146: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 147: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 148: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 149: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 150: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 151: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}}}; + case 152: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}}}; + case 153: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}}}; + case 154: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}}}; + case 155: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 156: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 157: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 158: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 159: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 160: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 161: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 162: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 163: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 164: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 165: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 166: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 167: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 168: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 169: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 1.0/6.0}}}; + case 170: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 5.0/6.0}}}; + case 171: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}}}; + case 172: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}}}; + case 173: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 174: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 175: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 176: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 177: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 178: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/6.0}}}; + case 179: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 5.0/6.0}}}; + case 180: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}}}; + case 181: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}}}; + case 182: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 183: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 184: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 185: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 186: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 187: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 188: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 189: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 190: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 191: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 192: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 193: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 194: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 195: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 196: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 197: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 198: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 199: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 200: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 201: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 202: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 203: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {3.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 0.0}}}; + case 204: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 205: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 206: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 207: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 208: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 209: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 210: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 211: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 212: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 213: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 214: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 215: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 216: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 217: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 218: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 219: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 220: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 221: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 222: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 223: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 224: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 225: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 226: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 227: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}}}; + case 228: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 0.0}, {0.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/4.0, 0.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {3.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 0.0}, {0.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {3.0/4.0, 0.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 229: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 230: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + } + return {{}, {}, {}}; + } + }; + } +#endif diff --git a/src - Copy (2)/spec.hpp b/src - Copy (2)/spec.hpp new file mode 100755 index 00000000..18490b64 --- /dev/null +++ b/src - Copy (2)/spec.hpp @@ -0,0 +1,150 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPEC_H +#define SPEC_H + +#include "math.cuh" +#include "types.cuh" +#include "cgpu_rand.cuh" +#include "atomic_data_mt.cuh" +#include "particles.cuh" +#include "in_classes.cuh" +#include "cgpu_fcns.cuh" +#include "cpu_fcns.hpp" +#include "spec_slic.hpp" + +namespace mt +{ + template + class Spec + { + public: + using T_r = T; + using size_type = dt_uint64; + + Spec(): multem_in_parm(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i) + { + multem_in_parm = multem_in_parm_i; + + /***************************************************************************************/ + Atomic_Data atomic_data_mt(multem_in_parm->atomic_pot_parm_typ); + + atom_type.resize(c_n_atom_typ); + for(auto i = 0; i < atom_type.size(); i++) + { + atomic_data_mt.To_atom_type_CPU(i+1, multem_in_parm->Vrl, multem_in_parm->nR, multem_in_parm->grid_2d.dR_min(), atom_type[i]); + } + + /***************************************************************************************/ + atoms_u.set_ptc(multem_in_parm->atoms, multem_in_parm->grid_2d.pbc_xy, &atom_type); + atoms_u.sort_by_z(); + + /***************************************************************************************/ + slicing.set_in_data(multem_in_parm, &atoms_u, &atoms); + + /***************************************************************************************/ + if ((atoms_u.s_z_int < 2.0*multem_in_parm->grid_2d.sli_thick) || ((slicing.z_plane.size() == 1) && multem_in_parm->is_spec_slic_by_plns_proj())) + { + multem_in_parm->grid_2d.sli_thick = atoms_u.s_z_int; + multem_in_parm->elec_spec_interact_mod = eesim_phase_object; + multem_in_parm->islice = 0; + multem_in_parm->atomic_vib.dim_z = false; + if (multem_in_parm->is_sim_through_slices()) + { + multem_in_parm->thick_type = estt_through_thick; + } + multem_in_parm->slice_storage = multem_in_parm->slice_storage || !multem_in_parm->is_sim_whole_spec(); + atoms_u.sli_thick = multem_in_parm->grid_2d.sli_thick; + } + + atoms.set_ptc(atoms_u, false, &atom_type); + // This is needed for memory preallocation in Transmission function + slicing.calculate(); + } + + /* Move atoms (random distribution will be included in the future) */ + void move_atoms(const dt_int32& fp_iconf) + { + // set atomic_vib configuration + if (multem_in_parm->is_avm_frozen_phonon()) + { + rand.seed(multem_in_parm->atomic_vib.seed, fp_iconf); + rand.set_act_dim(multem_in_parm->atomic_vib.dim_x, multem_in_parm->atomic_vib.dim_y, multem_in_parm->atomic_vib.dim_z); + } + + // move atoms + for(dt_int32 iatoms = 0; iatomsis_avm_frozen_phonon()) + { + auto sigma_x = atoms_u.sigma[iatoms]; + auto sigma_y = atoms_u.sigma[iatoms]; + auto sigma_z = atoms_u.sigma[iatoms]; + r += rand(sigma_x, sigma_y, sigma_z); + } + + atoms.x[iatoms] = r.x; + atoms.y[iatoms] = r.y; + atoms.z[iatoms] = r.z; + atoms.sigma[iatoms] = atoms_u.sigma[iatoms]; + atoms.occ[iatoms] = atoms_u.occ[iatoms]; + atoms.tag[iatoms] = atoms_u.tag[iatoms]; + atoms.charge[iatoms] = atoms_u.charge[iatoms]; + } + + if (multem_in_parm->atomic_vib.dim_z) + { + atoms.sort_by_z(); + } + + // get atom information + atoms.get_statistic(&atom_type); + + // slicing procedure + slicing.calculate(); + } + + T sli_thick(const dt_int32& islice) + { + return slicing.sli_thick(islice)/cos(multem_in_parm->theta); + } + + T dz_m(const dt_int32& islice_0, const dt_int32& islice_e) + { + return slicing.dz_m(islice_0, islice_e)/cos(multem_in_parm->theta); + } + + Multem_In_Parm *multem_in_parm; + + Ptc_Atom atoms; // displaced atoms + Spec_Slic slicing; // slicing procedure + Vctr, edev_cpu> atom_type; // Atom types + private: + Randn_3d rand; + Ptc_Atom atoms_u; + }; + +} + +#endif \ No newline at end of file diff --git a/src - Copy (2)/spec_slic.hpp b/src - Copy (2)/spec_slic.hpp new file mode 100755 index 00000000..91609518 --- /dev/null +++ b/src - Copy (2)/spec_slic.hpp @@ -0,0 +1,704 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPEC_SLIC_H + #define SPEC_SLIC_H + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "kahan_sum.cuh" + #include "r_2d.cuh" + #include "types_mt.cuh" + #include "cgpu_fcns_gen.cuh" + #include "particles.cuh" + #include "cpu_fcns.hpp" + #include "cgpu_vctr.cuh" + #include "spec_slic_in_parm.hpp" + + namespace mt + { + + /*************************** identify planes *************************/ + class Ident_Pla + { + public: + using T = dt_float64; + + Ident_Pla(): dv(0.1) {} + + // identify planes: require v to be sorted + template + Vctr_cpu operator()(pVctr_cpu_32& v, T v_min=0, T v_max=0) + { + if (v.size()==0) + { + return Vctr_cpu(); + } + + if (v_min >= v_max) + { + v_min = T(v.front()); + v_max = T(v.back()); + } + + // calculate hist and correct it + auto v_hist = hist(v, dv, v_min, v_max); + + if (v_hist.size()==1) + { + return Vctr_cpu({fcn_mean(v)}); + } + + // calculate layer limits + Vctr_cpu v_lim; + v_lim.reserve(v_hist.size()+1); + + for(auto iv = 0; iv < v_hist.size()-1; iv++) + { + if ((v_hist[iv]>0) && (v_hist[iv+1]==0)) + { + v_lim.push_back(v_min + T(iv+1)*dv); + } + } + v_hist.clear_shrink_to_fit(); // free v_hist + + v_lim.push_back(v_max+dv); + v_lim.shrink_to_fit(); + + // calculate planes + Vctr_cpu v_pln; + v_pln.reserve(v_lim.size()); + + KS v_s = 0; + dt_int32 v_c = 1; + dt_int32 ip = 0; + for(auto iv = 0; iv < v.size(); iv++) + { + const auto v_ih = v[iv]; + + if (!fcn_chk_bound_eps(v_ih, v_min, v_max)) + { + continue; + } + + if (v_ih + Vctr_cpu operator()(U v_min, U v_max, U dv, eMatch_Bdr match_bdr=emb_minmax) + { + if (fcn_is_equal(v_min, v_max)) + { + return Vctr_cpu({U(0.5)*(v_min+v_max)}); + } + + if (v_min >= v_max) + { + return Vctr_cpu(); + } + + const auto v_l = T(v_max-v_min); + + const dt_int32 nv = max(0, fcn_cceil(v_l/T(dv)))+1; + + // calculate planes + Vctr_cpu v_pln; + v_pln.reserve(nv); + + switch (match_bdr) + { + case emb_min: + { + for(auto iv=0; iv=0; iv--) + { + v_pln.push_back(v_max - U(iv)*dv); + } + } + break; + case emb_minmax: + { + const auto dv_b = dv + 0.5*(v_l-(nv-1)*dv); + + v_pln.push_back(v_min); + for(auto iv=1; iv + Vctr_cpu hist(pVctr_cpu_32& v, const T& dv, const T& v_min, const T& v_max) + { + const auto v_l = ::fmax(v_max-v_min, dv); + + const auto n_bins = fcn_cceil(v_l/dv); + + auto fcn_v_r = [v_min, dv](const dt_int32& ik, T& v_r_0, T& v_r_e) + { + v_r_0 = v_min + T(ik-1)*dv; + v_r_e = v_r_0 + dv; + }; + + Vctr_cpu v_hist(n_bins, 0); + + // get histogram + for(auto iv = 0; iv< v.size(); iv++) + { + T v_r_0, v_r_e; + const auto v_id = T(v[iv]); + auto ih = fcn_cfloor((v_id-v_min)/dv); + + fcn_v_r(ih-1, v_r_0, v_r_e); + + if (v_id= 0; ik--) + { + fcn_v_r(ik-1, v_r_0, v_r_e); + if (fcn_chk_bound(v_id, v_r_0, v_r_e)) + { + ih = ik-1; + break; + } + } + } + else if (v_id>v_r_e) + { + for(auto ik = ih; ik < n_bins; ik++) + { + fcn_v_r(ik, v_r_0, v_r_e); + if (fcn_chk_bound(v_id, v_r_0, v_r_e)) + { + ih = ik; + break; + } + } + } + ih = fcn_set_bound(ih, 0, n_bins-1); + + v_hist[ih]++; + } + + return v_hist; + } + }; + + /************************* slice thickness ***************************/ + template + class Out_Slic + { + public: + Out_Slic(): z_pln(0), z_lim(0, 0), z_int_lim(0, 0), + iatom_lim(0, 0), ithk(-1) {} + + R_2d z_pln; // z-position + R_2d z_lim; // z-position limit + R_2d z_int_lim; // z-int-position limit + R_2d iatom_lim; // index to z-position limit + dt_int32 ithk; // thick index + + T sli_thick() const { return ::fabs(z_lim.y-z_lim.x); } + }; + + template + class Spec_Slic + { + public: + using value_type = T; + using size_type = dt_uint64; + + Vctr_cpu z_plns; + Vctr_cpu> slice; + Vctr_cpu> thick; + + Spec_Slic(): patoms_r(nullptr), patoms(nullptr), z_eps(1e-3) {} + + void set_in_data(const Vctr_cpu& in_slic, Ptc_Atom* patoms_r=nullptr, Ptc_Atom* patoms=nullptr) + { + patoms_r = patoms_r; + if (fcn_is_null_ptr(patoms)) + { + patoms = patoms_r; + } + + z_plns = get_z_plns(in_slic, patoms_r); + } + + Vctr_cpu get_z_plns(const Vctr_cpu& in_slic, Ptc_Atom* patoms) + { + // get planes + Vctr_cpu> z_pln_s(in_slic.size()); + + for(auto ir=0; ir> z_pln(in_slic.size()); + + for(auto ir=0; ir& patoms, + //eSim_Thick_Typ thick_type, Vctr_cpu &thick) + //{ + // if (thick_type == estt_whole_spec) + // { + // thick.resize(1); + // thick[0] = patoms->z_max; + // return; + // } + + // auto z_plns = get_z_plane(spec_slic_typ, patoms); + + // if (thick_type == estt_through_slices) + // { + // z_plns = get_z_slice(spec_slic_typ, z_plns, patoms); + // } + + // fcn_match_vctr(z_plns.begin(), z_plns.end(), thick, 0.25*patoms->sli_thick); + //} + + //T sli_thick(dt_int32 islice_0, dt_int32 islice_e) + //{ + // return (islice_espec_slic_typ, z_plns, *patoms); + + // thick = get_thick(m_multem_in_parm, m_z_slice, *patoms_r); + + // slice = get_slicing(m_multem_in_parm, m_z_slice, thick, *patoms); + //} + + private: + const T z_eps; + + Ptc_Atom* patoms_r; + Ptc_Atom* patoms; + + Vctr_cpu m_z_slice; + Ident_Pla ident_pln; + + // get z positions by tag + Vctr_cpu get_z_pos_by_tag(Ptc_Atom* patoms, const dt_int32& tag) + { + Vctr_cpu z; + z.reserve(patoms->size()); + + for(auto iz = 0; izsize(); iz++) + { + if (patoms->get_tag(iz)==tag) + { + z.push_back(patoms->z[iz]); + } + } + z.shrink_to_fit(); + std::sort(z.begin(), z.end()); + + return z; + } + + // get z positions by z range and atomic number + Vctr_cpu get_z_pos_by_rng(Ptc_Atom* patoms, const dt_int32& Z, const R_2d& z_lim) + { + Vctr_cpu z; + z.reserve(patoms->size()); + + if Z<=0 + { + for(auto iz = 0; izsize(); iz++) + { + if (fcn_chk_bound_eps(patoms->z[iz], z_lim.x, z_lim.y)) + { + z.push_back(patoms->z[iz]); + } + } + } + else + { + for(auto iz = 0; izsize(); iz++) + { + if ((patoms->Z[iz]==Z) && fcn_chk_bound_eps(patoms->z[iz], z_lim.x, z_lim.y)) + { + z.push_back(patoms->z[iz]); + } + } + } + + z.shrink_to_fit(); + std::sort(z.begin(), z.end()); + + return z; + } + + // identify planes: atoms have to be sorted along z + Vctr_cpu get_z_plns(const Spec_Slic_In_Parm& in_slic, Ptc_Atom* patoms) + { + if (patoms->size() == 0) + { + return Vctr_cpu(); + } + + // get z planes + if (in_slic.is_spec_slic_by_user_def()) + { + return in_slic.z_plns; + } + else + { + Vctr_cpu z; + + if (in_slic.is_spec_slic_sel_typ_by_tag()) + { + z = get_z_pos_by_tag(patoms, in_slic.sel_tag); + } + else if (in_slic.is_spec_slic_sel_typ_by_z()) + { + z = get_z_pos_by_rng(patoms, in_slic.sel_Z, in_slic.sel_z_lim); + } + + if (in_slic.is_spec_slic_by_planes()) + { + return ident_pln(z); + } + else + { + return ident_pln(z_ct_min, z_ct_max, in_slic.sli_thick); + } + } + + return Vctr_cpu(); + } + + + //// get spacing + //T get_spacing(size_type ix, Vctr_cpu &x, T sli_thick=0.5) + //{ + // if (x.size()==1) + // { + // return sli_thick; + // } + + // ix = (ix <= 0)?1:min(ix, x.size()-1); + // return (x.size()>1)?x[ix]-x[ix-1]:0.0; + //} + + //// get z slicing + //Vctr_cpu get_z_slice(eSpec_Slic_Typ spec_slic_typ, Vctr_cpu &z_plns, Ptc_Atom& patoms) + //{ + // Vctr_cpu z_slice; + + // if ((spec_slic_typ!=esst_dz_sub) && (z_plns.size() == 1)) + // { + // z_slice.resize(2); + // z_slice[0] = patoms->z_int_min; + // z_slice[1] = patoms->z_int_max; + // z_slice.shrink_to_fit(); + + // return z_slice; + // } + + // Vctr_cpu z_plane_sli = z_plns; + + // z_slice.resize(z_plane_sli.size()+1); + // z_slice[0] = z_plane_sli[0]-0.5*get_spacing(0, z_plane_sli, patoms->sli_thick); + // for(auto iz=1; izsli_thick); + + // if (spec_slic_typ==esst_dz_sub) + // { + // T dz_b = get_spacing(1, z_plane_sli, patoms->sli_thick); + // if (patoms->z_int_minsli_thick); + // auto z_slice_top = ident_pln(patoms->z_int_min, z_slice.front()-dz_b, dz_s); + // z_slice.insert(z_slice.begin(), z_slice_top.begin(), z_slice_top.end()); + // } + // else + // { + // z_slice[0] = patoms->z_int_min; + // } + + // dz_b = get_spacing(z_plane_sli.size()-1, z_plane_sli, patoms->sli_thick); + // if (z_slice.back()+dz_bz_int_max) + // { + // T dz_s = get_spacing(z_plane_sli.size()-2, z_plane_sli, patoms->sli_thick); + // auto z_slice_bottom = ident_pln(z_slice.back()+dz_b, patoms->z_int_max, dz_s); + // z_slice.insert(z_slice.end(), z_slice_bottom.begin(), z_slice_bottom.end()); + // } + // else + // { + // z_slice[z_slice.size()-1] = patoms->z_int_max; + // } + // } + + // z_slice.shrink_to_fit(); + + // return z_slice; + //} + + //// get thick + //Vctr, edev_cpu> get_thick(Multem_In_Parm *multem_in_parm, + //Vctr_cpu &z_slice, Ptc_Atom& patoms) + //{ + // const auto thick_type = multem_in_parm->thick_type; + + // auto get_islice = [thick_type](Vctr_cpu &z_slice, const T& z)->dt_int32 + // { + // if (thick_type==estt_through_slices) + // { + // for(auto i = 0; i::rel) + // { + // return i; + // } + // } + // return 0; + // } + // else + // { + // for(auto i = 0; iis_spec_slic_by_dz_sub_whole_spec(); + + // Vctr, edev_cpu> thick(multem_in_parm->thick.size()); + // for(auto ik = 0; ikthick[ik]; + // auto islice = (b_sws)?(z_slice.size()-2):get_islice(z_slice, thick[ik].z); + // thick[ik].islice = islice; + + // auto iatom_e = fd_by_z(patoms->z, z_slice[islice+1], false); + // thick[ik].iatom_e = iatom_e; + + // thick[ik].z_zero_def_plane = multem_in_parm->obj_lens.get_zero_def_plane(patoms->z[0], patoms->z[iatom_e]); + // if (multem_in_parm->is_sim_through_slices()) + // { + // thick[ik].z_back_prop = 0; + // } + // else + // { + // // I need to recheck this part, the average should be replace by the plane + // thick[ik].z_back_prop = thick[ik].z_zero_def_plane - 0.5*(z_slice[islice]+z_slice[islice+1]); + // if (fabs(thick[ik].z_back_prop)::rel) + // { + // thick[ik].z_back_prop = 0; + // } + // } + // } + + // if (!multem_in_parm->is_multislice()) + // { + // for(auto ithick = 0; ithick, edev_cpu> get_slicing(Multem_In_Parm *multem_in_parm, + //Vctr_cpu &z_slice, Vctr, edev_cpu>& thick, Ptc_Atom& patoms) + //{ + // if (!multem_in_parm->is_multislice()) + // { + // Vctr, edev_cpu> slice(thick.size()); + // for(auto islice = 0; islicez_int_min:thick[islice-1].z; + // slice[islice].z_e = (thick.size() == 1)?patoms->z_int_max:thick[islice].z; + // slice[islice].z_int_0 = slice[islice].z_0; + // slice[islice].z_int_e = slice[islice].z_e; + // slice[islice].iatom_0 = (islice == 0)?0:(thick[islice-1].iatom_e+1); + // slice[islice].iatom_e = thick[islice].iatom_e; + // slice[islice] .ithk = islice; + // } + // return slice; + // } + + // Vctr, edev_cpu> slice(z_slice.size()-1); + // for(auto islice = 0; islicespec_slic_typ) + // { + // case esst_plns_proj: + // { + // slice[islice].z_int_0 = slice[islice].z_0; + // slice[islice].z_int_e = slice[islice].z_e; + // Inc_Borders = false; + // } + // break; + // case esst_dz_proj: + // { + // slice[islice].z_int_0 = slice[islice].z_0; + // slice[islice].z_int_e = slice[islice].z_e; + // Inc_Borders = false; + // } + // break; + // case esst_dz_sub: + // { + // T z_m = slice[islice].z_m(); + + // slice[islice].z_int_0 = ::fmin(z_m - patoms->R_int_max, slice[islice].z_0); + // slice[islice].z_int_e = ::fmax(z_m + patoms->R_int_max, slice[islice].z_e); + // Inc_Borders = true; + // } + // break; + // } + + // fd_by_z(patoms->z, slice[islice].z_int_0, slice[islice].z_int_e, slice[islice].iatom_0, slice[islice].iatom_e, Inc_Borders); + // + // slice[islice].ithk = -1; + // } + + // // set thickness index + // for(auto ithk = 0; ithk &z, T z_e, dt_bool Inc_Borders) + //{ + // dt_int32 iz_e =-1; + // z_e = (Inc_Borders)?z_e+Epsilon::rel:z_e; + + // if (z_e &z, T z_0, T z_e, dt_int32& iz_0, dt_int32& iz_e, dt_bool Inc_Borders) + //{ + // z_0 = (Inc_Borders)?(z_0-Epsilon::rel):z_0; + // z_e = (Inc_Borders)?(z_e+Epsilon::rel):z_e; + + // if ((z_0>z_e)||(z.back() iz_e)||(z[iz_e] < z_0)||(z_e < z[iz_0])) + // { + // iz_0 = 1; + // iz_e = 0; + // } + //} + }; + + } + +#endif diff --git a/src - Copy (2)/spec_slic_in_parm.hpp b/src - Copy (2)/spec_slic_in_parm.hpp new file mode 100755 index 00000000..02e63e25 --- /dev/null +++ b/src - Copy (2)/spec_slic_in_parm.hpp @@ -0,0 +1,158 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPEC_SLIC_IN_PARM_H + #define SPEC_SLIC_IN_PARM_H + + #include "const_enum_mt.cuh" + #include "r_2d.cuh" + #include "cgpu_vctr.cuh" + + namespace mt + { + template + class Spec_Slic_In_Parm + { + public: + using value_type = T; + + eSpec_Slic_Typ typ; // esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + T sli_thick; // slice thickness + eSpec_Slic_Sel_Typ sel_typ; // essso_tag = 1, essso_z = 2 + dt_int32 sel_tag; // tag + dt_int32 sel_Z; // atomic number + R_2d sel_z_lim; // [z_0, z_e] + Vctr_cpu z_plns; // z planes positions + + Spec_Slic_In_Parm(): typ( esst_plns_proj), sli_thick(0), sel_typ(0), + sel_tag(0), sel_Z(0), sel_z_lim{0, 0} {} + + template + void assign(Spec_Slic_In_Parm& spec_slic_in_parm) + { + if (this != &spec_slic_in_parm) + { + typ = spec_slic_in_parm.typ; + sli_thick = T(spec_slic_in_parm.sli_thick); + sel_typ = spec_slic_in_parm.sel_typ; + sel_tag = spec_slic_in_parm.sel_tag; + sel_Z = spec_slic_in_parm.sel_Z; + sel_z_lim = spec_slic_in_parm.sel_z_lim; + z_plns = spec_slic_in_parm.z_plns; + } + } + + void set_in_data(const eSpec_Slic_Typ& typ, const T& sli_thick, const eSpec_Slic_Sel_Typ& sel_typ, + const dt_int32& sel_tag, const dt_int32& sel_Z, const R_2d& sel_z_lim, const Vctr_cpu& z_plns) + { + this->typ = typ; + this->sli_thick = sli_thick; + this->sel_typ = sel_typ; + this->sel_tag = sel_tag; + this->sel_Z = sel_Z; + this->sel_z_lim = sel_z_lim; + this->z_plns = z_plns; + + set_dep_var(); + } + + void set_dep_var() + { + sel_Z = fcn_max(sel_Z, 0); + + if (!is_spec_slic_by_user_def()) + { + z_plns.clear_shrink_to_fit(); + } + else + { + if (is_spec_slic_sel_typ_by_z() && (sel_z_lim.y + Spec_Slic_In_Parm& operator=(Spec_Slic_In_Parm& spec_slic_in_parm) + { + assign(spec_slic_in_parm); + return *this; + } + + void clear() + { + typ = esst_plns_proj; + sli_thick = 0; + el_typ = 0; + sel_tag = 0; + sel_Z = 0; + sel_z_lim = 0; + } + + dt_bool is_spec_slic_by_plns_proj() + { + return mt::is_spec_slic_by_plns_proj(typ); + } + + dt_bool is_spec_slic_by_dz_proj() + { + return mt::is_spec_slic_by_dz_proj(typ); + } + + dt_bool is_spec_slic_by_plns_sub() + { + return mt::is_spec_slic_by_plns_sub(typ); + } + + dt_bool is_spec_slic_by_dz_sub() + { + return mt::is_spec_slic_by_dz_sub(typ); + } + + dt_bool is_spec_slic_by_user_def() + { + return mt::is_spec_slic_by_user_def(typ); + } + + dt_bool is_spec_slic_by_auto() + { + return mt::is_spec_slic_by_auto(typ); + } + + dt_bool is_spec_slic_by_planes() + { + return mt::is_spec_slic_by_planes(typ); + } + + dt_bool is_spec_slic_sel_typ_by_tag() + { + return mt::is_spec_slic_sel_typ_by_tag(sel_typ); + } + + dt_bool is_spec_slic_sel_typ_by_z() + { + return mt::is_spec_slic_sel_typ_by_z(sel_typ); + } + }; + + template + using Vctr_Spec_Slic_In_Parm = Vctr_cpu>; + } + +#endif diff --git a/src - Copy (2)/tem_simulation.cuh b/src - Copy (2)/tem_simulation.cuh new file mode 100755 index 00000000..91ea1acc --- /dev/null +++ b/src - Copy (2)/tem_simulation.cuh @@ -0,0 +1,602 @@ +/* + * This file is part of Multem. + * Copyright 2014 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TEM_SIMULATION_H + #define TEM_SIMULATION_H + + #include + #include "math.cuh" + #include "types.cuh" + #include "type_traits_gen.cuh" + #include "in_classes.cuh" + #include "output_multem.hpp" + #include "cpu_fcns.hpp" + #include "gpu_fcns.cuh" + #include "cgpu_fcns.cuh" + #include "energy_loss.cuh" + #include "wave_function.cuh" + #include "timing.cuh" + + namespace mt + { + template + class Tem_Simulation + { + public: + using T_r = T; + using T_c = complex; + + static const eDev device = Dev; + + static dt_bool ext_stop_sim; + static dt_int32 ext_niter; + static dt_int32 ext_iter; + + Tem_Simulation(): multem_in_parm(nullptr) {} + + Tem_Simulation(Multem_In_Parm *multem_in_parm_i) + { + set_in_data(multem_in_parm_i); + } + + void set_in_data(Multem_In_Parm *multem_in_parm_i) + { + multem_in_parm = multem_in_parm_i; + + stream.resize(multem_in_parm->system_config.n_stream); + + fft_2d.create_plan_2d(multem_in_parm->grid_2d.ny, multem_in_parm->grid_2d.nx, multem_in_parm->system_config.n_stream); + + if (multem_in_parm->is_EELS_EFTEM()) + { + energy_loss.set_in_data(multem_in_parm, &stream, &fft_2d); + psi_thk.resize(multem_in_parm->grid_2d.size()); + if (multem_in_parm->eels_fr.is_Mixed_Chan()) + { + trans_thk.resize(multem_in_parm->grid_2d.size()); + } + } + + wave_function.set_in_data(multem_in_parm, &stream, &fft_2d); + } + + template + void operator()(TOutput_multislice &output_multem) + { + if (multem_in_parm->is_STEM_ISTEM()) + { + STEM_ISTEM(output_multem); + } + else if (multem_in_parm->is_CBED_CBEI()) + { + CBED_CBEI(output_multem); + } + else if (multem_in_parm->is_ED_HRTEM()) + { + ED_HRTEM(output_multem); + } + else if (multem_in_parm->is_PED_HCTEM()) + { + PED_HCTEM(output_multem); + } + else if (multem_in_parm->is_EWFS_EWRS()) + { + EWFS_EWRS(output_multem); + } + else if (multem_in_parm->is_EELS_EFTEM()) + { + EELS_EFTEM(output_multem); + } + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + } + + void cleanup() + { + psi_thk.clear(); + trans_thk.clear(); + + fft_2d.cleanup(); + stream.cleanup(); + } + + private: + template + void STEM_ISTEM(TOutput_multislice &output_multem) + { + ext_niter = multem_in_parm->scanning.size()*multem_in_parm->number_pn_conf(); + ext_iter = 0; + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + output_multem.init(); + + multem_in_parm->ibeam.resize(1); + multem_in_parm->beam_x.resize(1); + multem_in_parm->beam_y.resize(1); + + + if (multem_in_parm->is_STEM() && multem_in_parm->atomic_vib.coh_contrib) + { + for(auto ibeam = 0; ibeam < multem_in_parm->scanning.size(); ibeam++) + { + output_multem.init_psi_coh(); + multem_in_parm->ibeam[0] = ibeam; + multem_in_parm->set_iscan_beam_position(); + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + wave_function.set_m2psi_coh(output_multem); + + if (ext_stop_sim) break; + } + } + else + { + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + for(auto ibeam = 0; ibeam < multem_in_parm->scanning.size(); ibeam++) + { + multem_in_parm->ibeam[0] = ibeam; + multem_in_parm->set_iscan_beam_position(); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + if (ext_stop_sim) break; + } + + wave_function.set_m2psi_coh(output_multem); + } + } + + template + void CBED_CBEI(TOutput_multislice &output_multem) + { + output_multem.init(); + + multem_in_parm->ibeam.resize(1); + multem_in_parm->beam_x.resize(1); + multem_in_parm->beam_y.resize(1); + + Quad_Coef_1d qt; + Quad_Coef_2d qs; + + // Load quadratures + cond_lens_temporal_spatial_quadratures(multem_in_parm->cond_lens, qt, qs); + + /***************************************************************************************/ + dt_float64 w_pr_0 = multem_in_parm->get_phonon_rot_weight(); + dt_float64 c_10_0 = multem_in_parm->cond_lens.c_10; + const dt_int32 n_beams = multem_in_parm->number_of_beams(); + + ext_niter = qs.size()*qt.size()*multem_in_parm->number_pn_conf(); + ext_iter = 0; + + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + + for(auto ibeam=0; ibeamibeam[0] = ibeam; + multem_in_parm->beam_x[0] = multem_in_parm->beam_x[ibeam]; + multem_in_parm->beam_y[0] = multem_in_parm->beam_y[ibeam]; + + // spatial incoherence + for(auto ispat = 0; ispatbeam_x[0]; + auto beam_y = qs.y[ispat] + multem_in_parm->beam_y[0]; + + // temporal incoherence + for(auto itemp = 0; itempcond_lens.set_defocus(c_10); + wave_function.set_incident_wave(wave_function.psi_z, beam_x, beam_y); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + } + } + + if (ext_stop_sim) break; + } + wave_function.set_m2psi_coh(output_multem); + + multem_in_parm->cond_lens.set_defocus(c_10_0); + multem_in_parm->set_beam_position(multem_in_parm->beam_x, multem_in_parm->beam_y); + } + + template + void ED_HRTEM(TOutput_multislice &output_multem) + { + EWFS_EWRS(output_multem); + } + + template + void PED_HCTEM(TOutput_multislice &output_multem) + { + ext_niter = multem_in_parm->nrot*multem_in_parm->number_pn_conf(); + ext_iter = 0; + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + output_multem.init(); + + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + for(auto irot = 0; irot < multem_in_parm->nrot; irot++) + { + multem_in_parm->set_phi(irot); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + if (ext_stop_sim) break; + } + + wave_function.set_m2psi_coh(output_multem); + } + + template + void EWFS_EWRS(TOutput_multislice &output_multem) + { + ext_niter = multem_in_parm->number_pn_conf(); + ext_iter = 0; + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + output_multem.init(); + + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + + wave_function.set_incident_wave(wave_function.psi_z); + + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + + wave_function.set_m2psi_coh(output_multem); + } + + template + void EELS_EFTEM(TOutput_multislice &output_multem) + { + ext_niter = wave_function.slicing.slice.size()*multem_in_parm->number_pn_conf(); + ext_iter = 0; + + if (multem_in_parm->is_STEM_ISTEM_EELS()) + { + ext_niter *= multem_in_parm->scanning.size(); + } + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + auto psi = [&](T_r w, Vctr& psi_z, TOutput_multislice &output_multem) + { + T_r gx_0 = multem_in_parm->gx_0(); + T_r gy_0 = multem_in_parm->gy_0(); + + for(auto islice = 0; islice < wave_function.slicing.slice.size(); islice++) + { + if (multem_in_parm->eels_fr.is_Mixed_Chan()) + { + wave_function.trans(islice, wave_function.slicing.slice.size()-1, trans_thk); + } + + for(auto iatoms = wave_function.slicing.slice[islice].iatom_0; iatoms <= wave_function.slicing.slice[islice].iatom_e; iatoms++) + { + if (wave_function.atoms.Z[iatoms] == multem_in_parm->eels_fr.Z) + { + multem_in_parm->set_eels_fr_atom(iatoms, wave_function.atoms); + energy_loss.set_atom_type(multem_in_parm->eels_fr); + + for(auto ikn = 0; ikn < energy_loss.kernel.size(); ikn++) + { + mt::ew_mult(stream, energy_loss.kernel[ikn], psi_z, wave_function.psi_z); + wave_function.psi(islice, wave_function.slicing.slice.size()-1, w, trans_thk, output_multem); + } + } + + if (ext_stop_sim) break; + } + wave_function.psi_slice(gx_0, gy_0, islice, psi_z); + + ext_iter++; + if (ext_stop_sim) break; + } + }; + + output_multem.init(); + + multem_in_parm->ibeam.resize(1); + multem_in_parm->beam_x.resize(1); + multem_in_parm->beam_y.resize(1); + + if (multem_in_parm->is_STEM_ISTEM_EELS()) + { + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + for(auto ibeam = 0; ibeam < multem_in_parm->scanning.size(); ibeam++) + { + multem_in_parm->ibeam[0] = ibeam; + multem_in_parm->set_iscan_beam_position(); + wave_function.set_incident_wave(psi_thk); + psi(w, psi_thk, output_multem); + + if (ext_stop_sim) break; + } + + if (ext_stop_sim) break; + } + } + else + { + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + wave_function.set_incident_wave(psi_thk); + psi(w, psi_thk, output_multem); + + if (ext_stop_sim) break; + } + } + } + + Multem_In_Parm *multem_in_parm; + Stream stream; + FFT fft_2d; + + Wave_Function wave_function; + Energy_Loss energy_loss; + + Vctr psi_thk; + Vctr trans_thk; + }; + + template + dt_bool Tem_Simulation::ext_stop_sim = false; + + template + dt_int32 Tem_Simulation::ext_niter = 0; + + template + dt_int32 Tem_Simulation::ext_iter = 0; + + template + class Multem + { + public: + Multem(): n_devices(1), multem_in_parm(nullptr) {} + + Multem(Multem_In_Parm *multem_in_parm_i) + { + set_in_data(multem_in_parm_i); + } + + void set_in_data(Multem_In_Parm *multem_in_parm_i) + { + multem_in_parm = multem_in_parm_i; + n_devices = 1; + if (multem_in_parm->is_STEM_ISTEM()||multem_in_parm->is_CBED_CBEI()) + { + n_devices = multem_in_parm->system_config.get_n_sel_gpu(); + } + output_multem_v.resize(n_devices); + } + + template + void operator()(TOutput_Multem &output_multem) + { + if (multem_in_parm->is_STEM_ISTEM()) + { + STEM_ISTEM(output_multem); + } + else if (multem_in_parm->is_CBED_CBEI()) + { + CBED_CBEI(output_multem); + } + else if (multem_in_parm->is_ED_HRTEM()) + { + ED_HRTEM(output_multem); + } + else if (multem_in_parm->is_PED_HCTEM()) + { + PED_HCTEM(output_multem); + } + else if (multem_in_parm->is_EWFS_EWRS()) + { + EWFS_EWRS(output_multem); + } + else if (multem_in_parm->is_EELS_EFTEM()) + { + EELS_EFTEM(output_multem); + } + } + private: + template + void STEM_ISTEM(TOutput_Multem &output_multem) + { + vector threads; + threads.reserve(n_devices); + + auto stem_istem_thr =[&](dt_int32 ithr) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.scanning.type = espt_user_def; + multem_in_parm_thr.scanning.R = multem_in_parm->extract_beam_pos(ithr, n_devices); + multem_in_parm_thr.set_dep_var(); + + multem_in_parm_thr.system_config.set_gpu_by_ind(ithr); + + Tem_Simulation tem_simulation(&multem_in_parm_thr); + output_multem_v[ithr].set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem_v[ithr]); + tem_simulation.cleanup(); + }; + + for(auto ithr=0; ithr + void CBED_CBEI(TOutput_Multem &output_multem) + { + vector threads; + threads.reserve(n_devices); + + auto cbed_cbei_thr =[&](dt_int32 ithr) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.beam_x = multem_in_parm->extract_probe_pos_x(ithr, n_devices); + multem_in_parm_thr.beam_y = multem_in_parm->extract_probe_pos_y(ithr, n_devices); + multem_in_parm_thr.set_dep_var(); + + multem_in_parm_thr.system_config.set_gpu_by_ind(ithr); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem_v[ithr].set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem_v[ithr]); + tem_simulation.cleanup(); + }; + + for(auto ithr=0; ithr + void ED_HRTEM(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + template + void PED_HCTEM(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + template + void EWFS_EWRS(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + template + void EELS_EFTEM(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + dt_int32 n_devices; + Multem_In_Parm *multem_in_parm; + vector> output_multem_v; + }; + + } + +#endif diff --git a/src - Copy (2)/timing.cuh b/src - Copy (2)/timing.cuh new file mode 100755 index 00000000..f6720daa --- /dev/null +++ b/src - Copy (2)/timing.cuh @@ -0,0 +1,121 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TIMING_H +#define TIMING_H + +#include "types.cuh" +#include + +#ifdef __CUDACC__ + #include + #include +#endif + +namespace mt +{ + template + struct Timing; + + template <> + struct Timing + { + public: + + Timing() + { + cudaEventCreate(&start); + cudaEventCreate(&stop); + } + + ~Timing() + { + free(); + } + + void tic() + { + cudaEventRecord(start); + } + + void toc() + { + cudaEventRecord(stop); + } + + dt_float32 elapsed_ms() + { + // cudaDeviceSynchronize(); + cudaEventSynchronize(stop); + + dt_float32 milliseconds = 0; + cudaEventElapsedTime(&milliseconds, start, stop); + + return milliseconds; + } + + dt_float32 elapsed_s() + { + return elapsed_ms()/1000; + } + + private: + cudaEvent_t start; + cudaEvent_t stop; + + void free() + { + cudaEventDestroy(start); + cudaEventDestroy(stop); + } + }; + + + template <> + struct Timing + { + public: + void tic() + { + start = std::chrono::high_resolution_clock::now(); + } + + void toc() + { + stop = std::chrono::high_resolution_clock::now(); + } + + dt_float32 elapsed_ms() + { + dt_float32 milliseconds = std::chrono::duration_cast(stop-start).count()*1e-3; + + return milliseconds; + } + + dt_float32 elapsed_s() + { + return elapsed_ms()/1000; + } + + private: + std::chrono::high_resolution_clock::time_point start; + std::chrono::high_resolution_clock::time_point stop; + }; +} + +#endif \ No newline at end of file diff --git a/src - Copy (2)/transmission_fcn.cuh b/src - Copy (2)/transmission_fcn.cuh new file mode 100755 index 00000000..bb4fb644 --- /dev/null +++ b/src - Copy (2)/transmission_fcn.cuh @@ -0,0 +1,228 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato transmission_fcn + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TRANSMISSION_FCNS_H +#define TRANSMISSION_FCNS_H + +#include "math.cuh" +#include "types.cuh" +#include "type_traits_gen.cuh" +#include "cgpu_stream.cuh" +#include "quad_data.cuh" +#include "cgpu_info.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" +#include "projected_potential.cuh" + +namespace mt +{ + template + class Transmission_Fcn: public Projected_Potential + { + public: + using T_r = T; + using T_c = complex; + using size_type = dt_uint64; + + Transmission_Fcn(): Projected_Potential(), fft_2d(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + Projected_Potential::set_in_data(multem_in_parm_i, stream_i); + fft_2d = fft2_i; + + trans_0.resize(this->multem_in_parm->grid_2d.size()); + + if (!this->multem_in_parm->slice_storage) + { + memory_slice.clear(); + return; + } + + dt_int32 n_slice_sig = (this->multem_in_parm->atomic_vib.dim_z)?(dt_int32)ceil(3.0*this->atoms.sigma_max/this->multem_in_parm->grid_2d.sli_thick):0; + dt_int32 n_slice_req = this->slicing.slice.size() + 2*n_slice_sig; + + memory_slice.set_in_data(n_slice_req, this->multem_in_parm->grid_2d.size()); + + if (memory_slice.is_potential()) + { + memory_slice.resize_vector(this->multem_in_parm->grid_2d.size(), Vp_v); + } + else if (memory_slice.is_transmission()) + { + memory_slice.resize_vector(this->multem_in_parm->grid_2d.size(), trans_v); + } + } + + void trans(T_r w, Vctr& V0_i, Vctr& Trans_o) + { + mt::transmission_fcn(*(this->stream), this->multem_in_parm->grid_2d, this->multem_in_parm->elec_spec_interact_mod, w, V0_i, Trans_o); + + if (this->multem_in_parm->grid_2d.bwl) + { + fft_2d->forward(Trans_o); + mt::fcn_fermi_aperture(*(this->stream), this->multem_in_parm->grid_2d, Trans_o); + fft_2d->inverse(Trans_o); + } + } + + void trans(const dt_int32& islice, Vctr& trans_0) + { + if (islice < memory_slice.n_slice_cur(this->slicing.slice.size())) + { + if (memory_slice.is_potential()) + { + trans(this->multem_in_parm->Vr_factor(), Vp_v[islice], trans_0); + } + else if (memory_slice.is_transmission()) + { + mt::assign(trans_v[islice], trans_0); + } + } + else + { + Projected_Potential::operator()(islice, this->V_0); + // this->operator()(islice, this->V_0); + trans(this->multem_in_parm->Vr_factor(), this->V_0, trans_0); + } + } + + void trans(const dt_int32& islice_0, const dt_int32& islice_e, Vctr& trans_0) + { + Projected_Potential::operator()(islice_0, islice_e, this->V_0); + // this->operator()(islice_0, islice_e, this->V_0); + trans(this->multem_in_parm->Vr_factor(), this->V_0, trans_0); + } + + template + void trans(const dt_int32& islice, TOutput_multislice &output_multem) + { + trans(islice, trans_0); + mt::cpy_to_host(output_multem.stream, trans_0, output_multem.trans[0]); + } + + void move_atoms(const dt_int32& fp_iconf) + { + Projected_Potential::move_atoms(fp_iconf); + + // Calculate transmission functions + for(auto islice = 0; islice< memory_slice.n_slice_cur(this->slicing.slice.size()); islice++) + { + if (memory_slice.is_potential()) + { + Projected_Potential::operator()(islice, Vp_v[islice]); + } + else if (memory_slice.is_transmission()) + { + Projected_Potential::operator()(islice, this->V_0); + trans(this->multem_in_parm->Vr_factor(), this->V_0, trans_v[islice]); + } + } + } + + void transmit(const dt_int32& islice, Vctr& psi_io) + { + trans(islice, trans_0); + mt::ew_mult(*(this->stream), trans_0, psi_io); + } + + Vctr trans_0; + private: + struct Memory_Slice + { + public: + dt_int32 n_slice_req; + dt_int32 n_slice_Allow; + eSlice_Memory_Typ slice_mem_type; + + Memory_Slice(): n_slice_req(0), n_slice_Allow(0), slice_mem_type(esmt_none) {} + + void clear() + { + n_slice_req = n_slice_Allow = 0; + slice_mem_type = esmt_none; + } + + void set_in_data(const dt_int32& nSlice_req_i, const dt_int32& nxy_i) + { + n_slice_req = nSlice_req_i; + dt_float64 free_memory = fcn_free_mem() - 10; + + if (number_slices(free_memory, nxy_i) >= n_slice_req) + { + slice_mem_type = esmt_transmission; + n_slice_Allow = number_slices(free_memory, nxy_i); + } + else + { + slice_mem_type = esmt_potential; + n_slice_Allow = number_slices(free_memory, nxy_i); + } + n_slice_Allow = min(n_slice_Allow, n_slice_req); + + if (n_slice_Allow == 0 ) + { + slice_mem_type = esmt_none; + } + } + + template + void resize_vector(const dt_int32& nxy_i, U &vector) + { + vector.resize(n_slice_Allow); + for(auto i = 0; i < n_slice_Allow; i++) + { + vector[i].resize(nxy_i); + } + } + + dt_int32 n_slice_cur(const dt_int32& n_slice_i) + { + return min(n_slice_Allow, n_slice_i); + } + + dt_bool is_transmission() const + { + return slice_mem_type == esmt_transmission; + } + + dt_bool is_potential() const + { + return slice_mem_type == esmt_potential; + } + + private: + template + dt_int32 number_slices(const dt_float64 &memory, const dt_int32& nxy) + { + return static_cast(::floor(memory/mt::fcn_size_mb(nxy))); + } + }; + + Memory_Slice memory_slice; + + protected: + Vctr, edev_cpu> trans_v; + Vctr, edev_cpu> Vp_v; + + FFT *fft_2d; + }; + +} + +#endif \ No newline at end of file diff --git a/src - Copy (2)/type_traits_gen.cuh b/src - Copy (2)/type_traits_gen.cuh new file mode 100755 index 00000000..443ffe56 --- /dev/null +++ b/src - Copy (2)/type_traits_gen.cuh @@ -0,0 +1,889 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TYPE_TRAITS_GEN_H + #define TYPE_TRAITS_GEN_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "macros.cuh" + #include "const_enum.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + /* same decay */ + namespace mt + { + template + struct is_same_decay: std::integral_constant::type, typename std::decay::type>::value> {}; + + template + struct is_diff_decay: std::integral_constant::value> {}; + } + + /* enable if */ + namespace mt + { + template + using enable_if_same_decay = typename std::enable_if::value, V>::type; + + template + using enable_if_diff_decay = typename std::enable_if::value, V>::type; + } + + /* enum types - verification */ + namespace mt + { + dt_bool is_ebool(const eData_Typ& ed_typ) + { + return edt_bool == ed_typ; + } + + dt_bool is_eint8(const eData_Typ& ed_typ) + { + return edt_int8 == ed_typ; + } + + dt_bool is_euint8(const eData_Typ& ed_typ) + { + return edt_uint8 == ed_typ; + } + + dt_bool is_eint16(const eData_Typ& ed_typ) + { + return edt_int16 == ed_typ; + } + + dt_bool is_euint16(const eData_Typ& ed_typ) + { + return edt_uint16 == ed_typ; + } + + dt_bool is_eint32(const eData_Typ& ed_typ) + { + return edt_int32 == ed_typ; + } + + dt_bool is_euint32(const eData_Typ& ed_typ) + { + return edt_uint32 == ed_typ; + } + + dt_bool is_eint64(const eData_Typ& ed_typ) + { + return edt_int64 == ed_typ; + } + + dt_bool is_euint64(const eData_Typ& ed_typ) + { + return edt_uint64 == ed_typ; + } + + dt_bool is_efloat32(const eData_Typ& ed_typ) + { + return edt_float32 == ed_typ; + } + + dt_bool is_efloat64(const eData_Typ& ed_typ) + { + return edt_float64 == ed_typ; + } + + dt_bool is_ecint8(const eData_Typ& ed_typ) + { + return edt_cint8 == ed_typ; + } + + dt_bool is_ecuint8(const eData_Typ& ed_typ) + { + return edt_cuint8 == ed_typ; + } + + dt_bool is_ecint16(const eData_Typ& ed_typ) + { + return edt_cint16 == ed_typ; + } + + dt_bool is_ecuint16(const eData_Typ& ed_typ) + { + return edt_cuint16 == ed_typ; + } + + dt_bool is_ecint32(const eData_Typ& ed_typ) + { + return edt_cint32 == ed_typ; + } + + dt_bool is_ecuint32(const eData_Typ& ed_typ) + { + return edt_cuint32 == ed_typ; + } + + dt_bool is_ecint64(const eData_Typ& ed_typ) + { + return edt_cint64 == ed_typ; + } + + dt_bool is_ecuint64(const eData_Typ& ed_typ) + { + return edt_cuint64 == ed_typ; + } + + dt_bool is_ecfloat32(const eData_Typ& ed_typ) + { + return edt_cfloat32 == ed_typ; + } + + dt_bool is_ecfloat64(const eData_Typ& ed_typ) + { + return edt_cfloat64 == ed_typ; + } + } + + /* real types - verification */ + namespace mt + { + template + struct is_bool : std::integral_constant::value> {}; + + template + struct is_enum : std::integral_constant::type>::value> {}; + + template + struct is_enum_bool: std::integral_constant::value || is_bool::value> {}; + + template + struct is_int8 : std::integral_constant::value> {}; + + template + struct is_uint8 : std::integral_constant::value> {}; + + template + struct is_int16 : std::integral_constant::value> {}; + + template + struct is_uint16 : std::integral_constant::value> {}; + + template + struct is_int32 : std::integral_constant::value> {}; + + template + struct is_uint32 : std::integral_constant::value> {}; + + template + struct is_int64 : std::integral_constant::value> {}; + + template + struct is_uint64 : std::integral_constant::value> {}; + + template + struct is_float32 : std::integral_constant::value> {}; + + template + struct is_float64 : std::integral_constant::value> {}; + + template + struct is_int: std::integral_constant::value || is_uint8::value \ + || is_int16::value || is_uint16::value || is_int32::value || is_uint32::value \ + || is_int64::value || is_uint64::value> {}; + + template + struct is_float : std::integral_constant::value || is_float64::value> {}; + + template + struct is_real : std::integral_constant::value || is_int8::value \ + || is_uint8::value || is_int16::value || is_uint16::value || is_int32::value \ + || is_uint32::value || is_int64::value || is_uint64::value || is_float::value> {}; + } + + /* std complex types - verification */ + namespace mt + { + template ::type> + struct is_std_cint8 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint8 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cint16 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint16 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cint32 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint32 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cint64 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint64 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cfloat32 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cfloat64 : std::integral_constant::value> {}; + + template + struct is_std_cfloat : std::integral_constant::value || is_std_cfloat64::value> {}; + + template + struct is_std_cmplx : std::integral_constant::value \ + || is_std_cuint8::value || is_std_cint16::value || is_std_cuint16::value || is_std_cint32::value \ + || is_std_cuint32::value || is_std_cint64::value || is_std_cuint64::value || is_std_cfloat::value> {}; + } + + /* thrust types - verification */ + namespace mt + { + #ifdef __CUDACC__ + template + struct is_thr_cint8: std::integral_constant::value> {}; + + template + struct is_thr_cuint8: std::integral_constant::value> {}; + + template + struct is_thr_cint16: std::integral_constant::value> {}; + + template + struct is_thr_cuint16: std::integral_constant::value> {}; + + template + struct is_thr_cint32: std::integral_constant::value> {}; + + template + struct is_thr_cuint32: std::integral_constant::value> {}; + + template + struct is_thr_cint64: std::integral_constant::value> {}; + + template + struct is_thr_cuint64: std::integral_constant::value> {}; + + template + struct is_thr_cfloat32: std::integral_constant::value> {}; + + template + struct is_thr_cfloat64: std::integral_constant::value> {}; + + template + struct is_thr_cfloat: std::integral_constant::value || is_thr_cfloat64::value> {}; + + template + struct is_thr_cmplx: std::integral_constant::value \ + || is_thr_cuint8::value || is_thr_cint16::value || is_thr_cuint16::value || is_thr_cint32::value \ + || is_thr_cuint32::value || is_thr_cint64::value || is_thr_cuint64::value || is_thr_cfloat::value> {}; + #endif + } + + /* complex types - verification */ + namespace mt + { + #ifdef __CUDACC__ + template + struct is_cint8: std::integral_constant::value || is_thr_cint8::value> {}; + + template + struct is_cuint8: std::integral_constant::value || is_thr_cuint8::value> {}; + + template + struct is_cint16: std::integral_constant::value || is_thr_cint16::value> {}; + + template + struct is_cuint16: std::integral_constant::value || is_thr_cuint16::value> {}; + + template + struct is_cint32: std::integral_constant::value || is_thr_cint32::value> {}; + + template + struct is_cuint32: std::integral_constant::value || is_thr_cuint32::value> {}; + + template + struct is_cint64: std::integral_constant::value || is_thr_cint64::value> {}; + + template + struct is_cuint64: std::integral_constant::value || is_thr_cuint64::value> {}; + + template + struct is_cfloat32: std::integral_constant::value || is_thr_cfloat32::value> {}; + + template + struct is_cfloat64: std::integral_constant::value || is_thr_cfloat64::value> {}; + + template + struct is_cmplx: std::integral_constant::value || is_thr_cmplx::value> {}; + #else + template + struct is_cint8: std::integral_constant::value> {}; + + template + struct is_cuint8: std::integral_constant::value> {}; + + template + struct is_cint16: std::integral_constant::value> {}; + + template + struct is_cuint16: std::integral_constant::value> {}; + + template + struct is_cint32: std::integral_constant::value> {}; + + template + struct is_cuint32: std::integral_constant::value> {}; + + template + struct is_cint64: std::integral_constant::value> {}; + + template + struct is_cuint64: std::integral_constant::value> {}; + + template + struct is_cfloat32: std::integral_constant::value> {}; + + template + struct is_cfloat64: std::integral_constant::value> {}; + + template + struct is_cmplx: std::integral_constant::value> {}; + #endif + + template + struct is_cfloat: std::integral_constant::value || is_cfloat64::value> {}; + + template + struct is_number: std::integral_constant::value || is_cmplx::value> {}; + } + + /* real types - enable */ + namespace mt + { + template + using enable_if_bool = typename std::enable_if::value, U>::type; + + template + using enable_if_enum = typename std::enable_if::value, U>::type; + + template + using enable_if_enum_bool = typename std::enable_if::value, U>::type; + + template + using enable_if_int8 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_int16 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_int32 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_int64 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_float32 = typename std::enable_if::value, U>::type; + + template + using enable_if_float64 = typename std::enable_if::value, U>::type; + + template + using enable_if_int = typename std::enable_if::value, U>::type; + + template + using enable_if_float = typename std::enable_if::value, U>::type; + + template + using enable_if_float_float = typename std::enable_if::value && is_float::value, V>::type; + + template + using enable_if_real = typename std::enable_if::value, U>::type; + + template + using enable_if_real_real = typename std::enable_if::value && is_real::value, V>::type; + } + + /* std complex types - enable */ + namespace mt + { + template + using enable_if_std_cint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cfloat32 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cfloat64 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cfloat = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cmplx = typename std::enable_if::value, U>::type; + } + + /* thrust complex types - enable */ + namespace mt + { + #ifdef __CUDACC__ + template + using enable_if_thr_cint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cfloat32 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cfloat64 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cfloat = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cmplx = typename std::enable_if::value, U>::type; + #endif + } + + /* complex types - enable */ + namespace mt + { + template + using enable_if_cint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_cint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_cint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_cint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_cfloat32 = typename std::enable_if::value, U>::type; + + template + using enable_if_cfloat64 = typename std::enable_if::value, U>::type; + + template + using enable_if_cfloat = typename std::enable_if::value, U>::type; + + template + using enable_if_cmplx = typename std::enable_if::value, U>::type; + + template + using enable_if_cmplx_cmplx = typename std::enable_if::value && is_cmplx::value, V>::type; + + template + using enable_if_number = typename std::enable_if::value, U>::type; + + template + using enable_if_number_number = typename std::enable_if::value && is_number::value, V>::type; + } + + /* eDev/eDim - verification */ + namespace mt + { + dt_bool is_edev_cpu(const eDev& edev) + { + return edev_cpu == edev; + } + + dt_bool is_edev_gpu(const eDev& edev) + { + return edev_gpu == edev; + } + + dt_bool is_edim_1(const eDim& edim) + { + return edim_1 == edim; + } + + dt_bool is_edim_2(const eDim& edim) + { + return edim_2 == edim; + } + + dt_bool is_edim_3(const eDim& edim) + { + return edim_3 == edim; + } + } + + /* ptr/eDev/eDim - enable */ + namespace mt + { + template + using enable_if_ptr = typename std::enable_if::value, U>::type; + + template + using enable_if_edev_cpu = typename std::enable_if::type; + + template + using enable_if_edev_gpu = typename std::enable_if::type; + + template + using enable_if_edim_1 = typename std::enable_if::type; + + template + using enable_if_edim_2 = typename std::enable_if::type; + + template + using enable_if_edim_3 = typename std::enable_if::type; + } + + /* types conversion */ + namespace mt + { + template + using chg_btw_int32_int64 = typename std::conditional::value, dt_int64, dt_int32>::type; + + // ! change to complementary floating point type: this include complex number + #ifdef __CUDACC__ + template + using chg_2_compl_float_type = typename std::conditional::value, dt_float64, \ + typename std::conditional::value, dt_float32, \ + typename std::conditional::value, std::complex, \ + typename std::conditional::value, std::complex, \ + typename std::conditional::value, thrust::complex, thrust::complex>::type>::type>::type>::type>::type; + #else + template + using chg_2_compl_float_type = typename std::conditional::value, dt_float64, \ + typename std::conditional::value, dt_float32, \ + typename std::conditional::value, std::complex, std::complex>::type>::type>::type; + #endif + + // ! large type sel + template + using sel_lg_type = typename std::conditional::value && is_float32::value, dt_float32, \ + typename std::conditional::value && is_float32::value, dt_float64, \ + typename std::conditional::value && is_float64::value, dt_float64, \ + typename std::conditional::value && is_int::value, T, \ + typename std::conditional::value && is_float::value, U, dt_float64>::type>::type>::type>::type>::type; /* types - enable */ + } + + /* detail_traits */ + namespace mt + { + namespace detail_traits + { + template + struct check_type + { + typedef void type; + }; + + /************************************ value type****************************************/ + template + struct sValue_type + { + using type = T; + }; + + template + struct sValue_type::type> + { + using type = typename T::value_type; + }; + + template + struct sValue_type_r + { + using type = typename sValue_type::type; + }; + + template + struct sValue_type_r::type> + { + using type = typename T::value_type::value_type; + }; + + /************************************* size type ***************************************/ + template + struct sSize_type + { + using type = T; + }; + + template + struct sSize_type::type> + { + using type = typename T::size_type; + }; + + template + struct sSize_type_r + { + using type = typename sSize_type::type; + }; + + template + struct sSize_type_r::type> + { + using type = typename T::value_type::size_type; + }; + } + } + + /* vector value type - extraction */ + namespace mt + { + template + using Value_type = typename detail_traits::sValue_type::type; + + template + using Value_type_r = typename detail_traits::sValue_type_r::type; + } + + /* vector size type - extraction */ + namespace mt + { + template + using Size_type = typename detail_traits::sSize_type::type; + + template + using Size_type_r = typename detail_traits::sSize_type_r::type; + } + + /* vector type - verification */ + namespace mt + { + template + struct is_vctr_cpu: std::integral_constant {}; + + template + struct is_vctr_gpu: std::integral_constant {}; + + template + struct is_vctr: std::integral_constant::value || is_vctr_gpu::value> {}; + + template + struct is_vctr_and_vctr: std::integral_constant::value || is_vctr::value> {}; + + /***************************************************************************************/ + template + struct is_rvctr_cpu: std::integral_constant::value && is_real::value> {}; + + template + struct is_vctr_rgpu: std::integral_constant::value && is_real::value> {}; + + template + struct is_rvctr: std::integral_constant::value || is_vctr_rgpu::value> {}; + + /***************************************************************************************/ + template + struct is_cvctr_cpu: std::integral_constant::value && is_cmplx::value> {}; + + template + struct is_cvctr_gpu: std::integral_constant::value && is_cmplx::value> {}; + + template + struct is_cvctr: std::integral_constant::value || is_cvctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_vctr_cpu_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_vctr_cpu_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + template + struct is_vctr_gpu_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_vctr_gpu_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_cvctr_cpu_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_cvctr_cpu_and_rvctr_cpu: std::integral_constant::value && is_rvctr_cpu::value> {}; + + template + struct is_cvctr_gpu_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + template + struct is_cvctr_gpu_and_vctr_rgpu: std::integral_constant::value && is_vctr_rgpu::value> {}; + + template + struct is_cvctr_and_rvctr: std::integral_constant::value && is_rvctr::value> {}; + } + + /* vector type - enable */ + namespace mt + { + template + using enable_if_vctr_cpu = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_and_vctr = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_rvctr_cpu = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_rgpu = typename std::enable_if::value, U>::type; + + template + using enable_if_rvctr = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + template + using enable_if_cvctr_cpu = typename std::enable_if::value, U>::type; + + template + using enable_if_cvctr_gpu = typename std::enable_if::value, U>::type; + + template + using enable_if_cvctr = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_cpu_and_vctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_gpu_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_gpu_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_cvctr_cpu_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_cpu_and_rvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_gpu_and_vctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_gpu_and_vctr_rgpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_and_rvctr = typename std::enable_if::value, V>::type; + } + + /* matrxi type - enable */ + namespace mt + { + template + enable_if_float32, dt_int32> + matrix_type(TVctr& vector){ return 1; } + + template + enable_if_float64, dt_int32> + matrix_type(TVctr& vector){ return 2; } + + template + enable_if_cfloat32, dt_int32> + matrix_type(TVctr& vector){ return 3; } + + template + enable_if_cfloat64, dt_int32> + matrix_type(TVctr& vector){ return 4; } + } + +#endif diff --git a/src - Copy (2)/type_traits_mt.cuh b/src - Copy (2)/type_traits_mt.cuh new file mode 100755 index 00000000..a8506070 --- /dev/null +++ b/src - Copy (2)/type_traits_mt.cuh @@ -0,0 +1,100 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TYPE_TRAITS_MT_H + #define TYPE_TRAITS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "const_enum_mt.cuh" + #include "type_traits_gen.cuh" + + namespace mt + { + /***************************************************************************************/ + template + using enable_if_eappt_doyle_0_4 = typename std::enable_if::type; + + template + using enable_if_eappt_peng_0_4 = typename std::enable_if::type; + + template + using enable_if_eappt_peng_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_kirkland_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_weickenmeier_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_lobato_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_peng_ion_0_4 = typename std::enable_if::type; + + /****************************** types ********************************/ + template + using enable_if_STEM = typename std::enable_if::type; + + template + using enable_if_ISTEM = typename std::enable_if::type; + + template + using enable_if_CBED = typename std::enable_if::type; + + template + using enable_if_CBEI = typename std::enable_if::type; + + template + using enable_if_ED = typename std::enable_if::type; + + template + using enable_if_HRTEM = typename std::enable_if::type; + + template + using enable_if_PED = typename std::enable_if::type; + + template + using enable_if_HCTEM = typename std::enable_if::type; + + template + using enable_if_EWFS = typename std::enable_if::type; + + template + using enable_if_EWRS = typename std::enable_if::type; + + template + using enable_if_EELS = typename std::enable_if::type; + + template + using enable_if_EFTEM = typename std::enable_if::type; + + template + using enable_if_ProbeFS = typename std::enable_if::type; + + template + using enable_if_ProbeRS = typename std::enable_if::type; + + } + +#endif diff --git a/src - Copy (2)/types.cuh b/src - Copy (2)/types.cuh new file mode 100755 index 00000000..d64da1e3 --- /dev/null +++ b/src - Copy (2)/types.cuh @@ -0,0 +1,460 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TYPES_H + #define TYPES_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + #include + + #include "const_enum.cuh" + #include "type_traits_gen.cuh" + #include "math.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "cgpu_fcns_gen.cuh" + #include "cgpu_vctr.cuh" + #include "grid.cuh" + + namespace mt + { + /********************************* 2d array of vectors *********************************/ + template + struct AV_2d + { + using value_type = Value_type; + + AV_2d():m_dim_0(0), m_dim_1(0), m_size(0), m_size_a(0), m_d_size(0) {} + + AV_2d(dt_int32 rows, dt_int32 cols, dt_int32 d_size, dt_int32 size_a=-1) + { + set_size(rows, cols, d_size, size_a); + } + + void clear() + { + for(auto ik = 0; ik < m_size_a; ik++) + { + m_data[ik].clear(); + } + m_data.clear(); + } + + void shrink_to_fit() + { + for(auto ik = 0; ik < m_size_a; ik++) + { + m_data[ik].shrink_to_fit(); + } + m_data.shrink_to_fit(); + } + + void clear_shrink_to_fit() + { + clear(); + shrink_to_fit(); + } + + void set_size(dt_int32 dim_0, dt_int32 dim_1, dt_int32 d_size, dt_int32 size_a=-1) + { + m_dim_0 = dim_0; + m_dim_1 = dim_1; + m_size = m_dim_0*m_dim_1; + m_size_a = (size_a<0)?m_size:min(m_size, size_a); + m_d_size = max(0, d_size); + + m_data.resize(m_size); + + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + m_data[ik].resize(m_d_size); + } + } + } + + dt_bool sub_2_ind(const dt_int32 ix_0, const dt_int32 ix_1) const + { + return (ix_0 + m_dim_0*ix_1); + } + + dt_bool exists(const dt_int32 ix_0, const dt_int32 ix_1) const + { + return (sub_2_ind(ix_0, ix_1) < m_size_a); + } + + template + void assign(TAV_2d &av_2d) + { + set_size(av_2d.dim_0(), av_2d.dim_1(), av_2d.d_size(), av_2d.size_a()); + + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + thrust::copy(av_2d[ik].begin(), av_2d[ik].end(), m_data[ik].begin()); + } + } + } + + template + void cpy_allow_data(TAV_2d &av_2d) + { + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + thrust::copy(m_data[ik].begin(), m_data[ik].end(), av_2d[ik].begin()); + } + } + } + + template + AV_2d& operator=(const TAV_2d &av_2d) + { + assign(av_2d); + return *this; + } + + CGPU_EXEC_INL + TVctr& operator[](const dt_int32 idx) { return m_data[idx]; } + + CGPU_EXEC_INL + const TVctr& operator[](const dt_int32 idx) const { return m_data[idx]; } + + TVctr& operator()(const dt_int32 ix_0, const dt_int32 ix_1) + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + const TVctr& operator()(const dt_int32 ix_0, const dt_int32 ix_1) const + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + value_type& operator()(const dt_int32 ix_0, const dt_int32 ix_1, const dt_int32 id) + { + return m_data[sub_2_ind(ix_0, ix_1)][id]; + } + + const value_type& operator()(const dt_int32 ix_0, const dt_int32 ix_1, const dt_int32 id) const + { + return m_data[sub_2_ind(ix_0, ix_1)][id]; + } + + dt_int32 dim_0() const + { + return m_dim_0; + } + + dt_int32 dim_1() const + { + return m_dim_1; + } + + dt_int32 size() const + { + return m_size; + } + + dt_int32 size_a() const + { + return m_size_a; + } + + dt_int32 d_size() const + { + return m_d_size; + } + + void fill(value_type value) + { + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + thrust::fill(m_data[ik].begin(), m_data[ik].end(), value); + } + } + } + + dt_int32 m_dim_0; + dt_int32 m_dim_1; + dt_int32 m_size; + dt_int32 m_size_a; + dt_int32 m_d_size; + Vctr_cpu m_data; + }; + + /***************************** atoms for simulated annealing ***************************/ + template + class Atom_Data_Sa{ + public: + using value_type = T; + using size_type = dt_uint64; + + size_type size() const + { + return Z.size(); + } + + dt_bool empty() const + { + return size() == 0; + } + + template + void assign(TAtom_SA &atom_sa) + { + Z.assign(atom_sa.Z.begin(), atom_sa.Z.end()); + + r_min.assign(atom_sa.r_min.begin(), atom_sa.r_min.end()); + r_max.assign(atom_sa.r_max.begin(), atom_sa.r_max.end()); + r_0.assign(atom_sa.r_0.begin(), atom_sa.r_0.end()); + r_d.assign(atom_sa.r_d.begin(), atom_sa.r_d.end()); + + r.assign(atom_sa.r.begin(), atom_sa.r.end()); + r_n.assign(atom_sa.r_n.begin(), atom_sa.r_n.end()); + r_opt.assign(atom_sa.r_opt.begin(), atom_sa.r_opt.end()); + + chi2.assign(atom_sa.chi2.begin(), atom_sa.chi2.end()); + chi2_n.assign(atom_sa.chi2_n.begin(), atom_sa.chi2_n.end()); + chi2_opt.assign(atom_sa.chi2_opt.begin(), atom_sa.chi2_opt.end()); + + df.assign(atom_sa.df.begin(), atom_sa.df.end()); + } + + // resize number of atoms + void resize(const size_type& new_size, const value_type& value = value_type()) + { + Z.resize(new_size, value); + + r_min.resize(new_size, value); + r_max.resize(new_size, value); + r_0.resize(new_size, value); + r_d.resize(new_size, value); + + r.resize(new_size, value); + r_n.resize(new_size, value); + r_opt.resize(new_size, value); + + chi2.resize(new_size, value); + chi2_n.resize(new_size, value); + chi2_opt.resize(new_size, value); + + df.resize(new_size, value); + + } + + // set atoms + void set_ptc(const size_type& natoms_i, dt_float64 *atoms_i, dt_float64 *atoms_min_i, dt_float64 *atoms_max_i) + { + resize(natoms_i); + + for(auto iatoms = 0; iatoms < size(); iatoms++) + { + Z[iatoms] = static_cast(atoms_i[0*natoms_i + iatoms]); // atomic number + r[iatoms].x = atoms_i[1*natoms_i + iatoms]; // x-position + r[iatoms].y = atoms_i[2*natoms_i + iatoms]; // y-position + r[iatoms].z = atoms_i[3*natoms_i + iatoms]; // z-position + + r_min[iatoms].x = atoms_min_i[0*natoms_i + iatoms]; // x-position + r_min[iatoms].y = atoms_min_i[1*natoms_i + iatoms]; // y-position + r_min[iatoms].z = atoms_min_i[2*natoms_i + iatoms]; // z-position + + r_max[iatoms].x = atoms_max_i[0*natoms_i + iatoms]; // x-position + r_max[iatoms].y = atoms_max_i[1*natoms_i + iatoms]; // y-position + r_max[iatoms].z = atoms_max_i[2*natoms_i + iatoms]; // z-position + + r_0[iatoms] = r_min[iatoms]; + r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; + + df[iatoms] = 1; + } + } + + // set atoms + void set_ptc(const size_type& natoms_i, dt_float64 *atoms_i, R_3d d_i) + { + resize(natoms_i); + + for(auto iatoms = 0; iatoms < size(); iatoms++) + { + Z[iatoms] = static_cast(atoms_i[0*natoms_i + iatoms]); // atomic number + + r[iatoms].x = atoms_i[0*natoms_i + iatoms]; // x-position + r[iatoms].y = atoms_i[1*natoms_i + iatoms]; // y-position + r[iatoms].z = atoms_i[2*natoms_i + iatoms]; // z-position + + r_min[iatoms] = r - d_i; + r_max[iatoms] = r + d_i; + + r_0[iatoms] = r_min[iatoms]; + r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; + + df[iatoms] = 1; + } + } + + void set_range(dt_int32 Z_i, R_3d r_min_i, R_3d r_max_i) + { + for(auto iatoms = 0; iatoms < size(); iatoms++) + { + Z[iatoms] = Z_i; + + r_min[iatoms] = r_min_i; + r_max[iatoms] = r_max_i; + r_0[iatoms] = r_min[iatoms]; + r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; + df[iatoms] = 1; + } + } + + inline + T norm_2(const dt_int32& iatoms, const R_3d& r) + { + auto rd = r_n[iatoms]-r; + return mt::norm_2(rd); + } + + Vctr Z; + + Vctr, edev_cpu> r_min; + Vctr, edev_cpu> r_max; + Vctr, edev_cpu> r_0; + Vctr, edev_cpu> r_d; + + Vctr, edev_cpu> r; + Vctr, edev_cpu> r_n; + Vctr, edev_cpu> r_opt; + + Vctr chi2; + Vctr chi2_n; + Vctr chi2_opt; + + Vctr df; + }; + + template + struct Atom_Sa + { + public: + using value_type = T; + + T x; + T y; + T R2_max; + T* r2; + T* c3; + T* c2; + T* c1; + T* c0; + + dt_int32 ix_0; + dt_int32 ix_n; + dt_int32 iy_0; + dt_int32 iy_n; + + dt_int32 *iv; + T* v; + + Atom_Sa(): x(0), y(0), R2_max(0), r2(nullptr), c3(nullptr), c2(nullptr), c1(nullptr), + c0(nullptr), ix_0(1), ix_n(0), iy_0(0), iy_n(0), iv(nullptr), v(nullptr) {} + + inline + void set_ix0_ixn(const Grid_2d& grid_2d, const T& r_max) + { + fcn_get_idx_0_idx_n(x, r_max, grid_2d.drx, grid_2d.pbc_x, grid_2d.nx, ix_0, ix_n); + } + + inline + void set_iy0_iyn(const Grid_2d& grid_2d, const T& r_max) + { + fcn_get_idx_0_idx_n(y, r_max, grid_2d.dry, grid_2d.pbc_y, grid_2d.ny, iy_0, iy_n); + } + + #ifdef __CUDACC__ + inline + D_Grid_Blk get_eval_cubic_poly_gridBT() + { + D_Grid_Blk d_grid_blk; + d_grid_blk.grid = dim3((iy_n+c_thr_2d_x-1)/c_thr_2d_x, (ix_n+c_thr_2d_y-1)/c_thr_2d_y); + d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + return d_grid_blk; + } + #endif + }; + + /************************* affine parameters for shx and scy ***************************/ + template + struct Atp_1 + { + R_2d f; + R_2d tr; + T chi2; + + Atp_1():f(T(0), T(1)), tr(T(0), T(0)), chi2(0) {} + + Atp_1(const R_2d& f_i, const R_2d& tr_i, const T& chi2_i): f(f_i), tr(tr_i), chi2(chi2_i) {} + + template + Atp_1& operator=(TAtp_1 &atp_1) + { + f = atp_1.f; + tr = atp_1.tr; + chi2 = atp_1.chi2; + + return *this; + } + }; + + /*************************** affine parameters for rotation ****************************/ + template + struct Atp_2 + { + T theta; + R_2d tr; + T chi2; + + Atp_2():theta(T(0)), tr(T(0), T(0)), chi2(0) {} + + Atp_2(const T& theta_i, const R_2d& tr_i, const T& chi2_i): theta(theta_i), tr(tr_i), chi2(chi2_i) {} + + template + Atp_2& operator=(TAtp_2 &atp_2) + { + theta = atp_2.theta; + tr = atp_2.tr; + chi2 = atp_2.chi2; + + return *this; + } + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/types_mt.cuh b/src - Copy (2)/types_mt.cuh new file mode 100755 index 00000000..394af998 --- /dev/null +++ b/src - Copy (2)/types_mt.cuh @@ -0,0 +1,332 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TYPES_MT_H + #define TYPES_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + #include + + #include "const_enum_mt.cuh" + #include "math.cuh" + #include "type_traits_gen.cuh" + #include "cgpu_fcns_gen.cuh" + #include "r_2d.cuh" + #include "r_3d.cuh" + #include "particles.cuh" + #include "types.cuh" + + namespace mt + { + /******************* spec layer information *********************/ + template + class Spec_Lay_Info + { + public: + R_3d bs; // box size + R_3d r_0; // initial position + dt_int32 tag; // tag + eSpec_Lay_Pos type; // specimen layer type + T sli_thick; // slice thickness + + Spec_Lay_Info(): bs(), r_0(), tag(c_dflt_tag), type(eslp_none), sli_thick(2) {}; + + Spec_Lay_Info(const R_3d& bs, R_3d r_0 = R_3d(), dt_int32 tag = c_dflt_tag, + eSpec_Lay_Pos type = eslp_none, T sli_thick = 2.0): bs(bs), r_0(r_0), tag(tag), type(type), sli_thick(sli_thick) {}; + + Spec_Lay_Info& operator=(Spec_Lay_Info &spec_lay_info) + { + if (this != &spec_lay_info) + { + bs = spec_lay_info.bs; + r_0 = spec_lay_info.r_0; + sli_thick = spec_lay_info.sli_thick; + tag = spec_lay_info.tag; + type = spec_lay_info.type; + } + + return *this; + } + + template + Spec_Lay_Info& operator=(Spec_Lay_Info &spec_lay_info) + { + assign(spec_lay_info); + + return *this; + } + + template + void assign(const Spec_Lay_Info& spec_lay_info) + { + if ((void*)this != (void*)&spec_lay_info) + { + bs = spec_lay_info.bs; + r_0 = spec_lay_info.r_0; + r_e = spec_lay_info.r_e; + sli_thick = T(spec_lay_info.sli_thick); + tag = spec_lay_info.tag; + type = spec_lay_info.type; + } + } + + R_3d r_e() const + { + return r_0 + bs; + }; + + T z_e() const + { + return r_0.z + bs.z; + }; + + dt_bool is_spec_lay_top() const + { + return is_spec_lay_top(type); + }; + + dt_bool is_spec_lay_bottom() const + { + return is_spec_lay_bottom(type); + }; + + dt_bool is_spec_lay_middle() const + { + return is_spec_lay_middle(type); + }; + + dt_bool is_spec_lay_user_def() const + { + return is_spec_lay_user_def(type); + }; + + void set_region(Ptc_Atom& atoms) + { + if (bs.z<1e-4) + { + tag = 0; + return; + } + + dt_int32 f_region = 0; + dt_int32 c_region = 0; + const T z_0 = r_0.z; + const T z_e = z_e(); + for(auto iatoms = 0; iatoms < atoms.size(); iatoms++) + { + auto z = atoms.z[iatoms]; + if ((z_0(::round(T(f_region)/T(c_region))); + } + }; + + template + using Vctr_Spec_Lay_Info = Vctr_std>; + + + /**************************** thickness ******************************/ + template + struct Thick + { + Thick(): z(0), z_zero_def_plane(0), z_back_prop(0), + islice(0), iatom_e(0) {} + + T z; // z + T z_zero_def_plane; // z: Zero defocus + T z_back_prop; // z: Back propagation + + dt_int32 islice; // slice position + dt_int32 iatom_e; // Last atom index + }; + + /************************** stem fetector ****************************/ + template + struct Detector + { + using value_type = T; + using size_type = dt_int32; + + static const eDev device = Dev; + + Detector(): type(mt::edt_circular) {} + + size_type size() const + { + size_type size_out = 0; + switch (type) + { + case mt::edt_circular: + { + size_out = g_inner.size(); + } + break; + case mt::edt_radial: + { + size_out = fx.size(); + } + break; + case mt::edt_matrix: + { + size_out = fR.size(); + } + break; + } + return size_out; + } + + void clear() + { + g_inner.clear(); + g_outer.clear(); + fx.clear(); + fR.clear(); + fcn.clear(); + grid_1d.clear(); + grid_2d.clear(); + } + + void resize(const size_type& new_size) + { + switch (type) + { + case mt::edt_circular: + { + g_inner.resize(new_size); + g_outer.resize(new_size); + } + break; + case mt::edt_radial: + { + fx.resize(new_size); + fcn.resize(new_size); + grid_1d.resize(new_size); + } + break; + case mt::edt_matrix: + { + fR.resize(new_size); + fcn.resize(new_size); + grid_2d.resize(new_size); + } + break; + } + } + + template + void assign(TDetector &detector) + { + type = detector.type; + g_inner.assign(detector.g_inner.begin(), detector.g_inner.end()); + g_outer.assign(detector.g_outer.begin(), detector.g_outer.end()); + + fx.resize(detector.fx.size()); + for(auto i = 0; i + Detector& operator=(TDetector &detector) + { + assign(detector); + return *this; + } + + dt_bool is_detector_circular() const + { + return mt::is_detector_circular(type); + } + + dt_bool is_detector_radial() const + { + return mt::is_detector_radial(type); + } + + dt_bool is_detector_matrix() const + { + return mt::is_detector_matrix(type); + } + + eDetector_Typ type; // mt::edt_circular = 1, mt::edt_radial = 2, mt::edt_matrix = 3 + Vctr g_inner; // Inner aperture Ang^-1 + Vctr g_outer; // Outer aperture Ang^-1 + Vctr, edev_cpu> fx; // radial sensitivity value + Vctr, edev_cpu> fR; // 2D sensitivity value + std::vector> grid_1d; // grid_1d + std::vector> grid_2d; // grid_2d + std::vector fcn; // file names + }; + + /************************* stem intensity ****************************/ + template + struct Det_Int + { + using value_type = typename TVctr::value_type; + using size_type = dt_int32; + + static const eDev device = edev_cpu; + + size_type size() const + { + return image.size(); + } + + Vctr image; + }; + + /******************** radial schrodinger equation ********************/ + template + class In_Rad_Schr + { + public: + T E_0; // Acceleration Voltage + eAtomic_Pot_Parm_Typ atomic_pot_parm_typ; // Parameterization type + dt_int32 n; // Principal quantum number + dt_int32 nr; // number of grid points + dt_int32 natomsM; // number of atoms + T* atomsM; // atoms + }; + } + +#endif \ No newline at end of file diff --git a/src - Copy (2)/wave_function.cuh b/src - Copy (2)/wave_function.cuh new file mode 100755 index 00000000..53c7fc4b --- /dev/null +++ b/src - Copy (2)/wave_function.cuh @@ -0,0 +1,387 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef WAVE_FUNCTION_H +#define WAVE_FUNCTION_H + +#include "math.cuh" +#include "types.cuh" +#include "cgpu_fft.cuh" +#include "in_classes.cuh" +#include "cpu_fcns.hpp" +#include "gpu_fcns.cuh" +#include "cgpu_fcns.cuh" +#include "transmission_fcn.cuh" +#include "incident_wave.cuh" +#include "propagator.cuh" +#include "microscope_effects.cuh" + +#include "timing.cuh" + +#include + +namespace mt +{ + template + class Wave_Function: public Transmission_Fcn + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using size_type = dt_uint64; + + Wave_Function(): Transmission_Fcn() {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + psi_z.resize(multem_in_parm_i->grid_2d.size()); + m2psi_z.resize(multem_in_parm_i->grid_2d.size()); + + if (multem_in_parm_i->is_STEM()) + { + detector.assign(multem_in_parm_i->detector); + if (multem_in_parm_i->is_detector_matrix()) + { + for(auto i = 0; igrid_2d, detector.fR[i]); + } + } + } + + incident_wave.set_in_data(multem_in_parm_i, stream_i, fft2_i); + + propagator.set_in_data(multem_in_parm_i, stream_i, fft2_i); + + if (multem_in_parm_i->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS()) + { + microscope_effects.set_in_data(multem_in_parm_i, stream_i, fft2_i); + } + + Transmission_Fcn::set_in_data(multem_in_parm_i, stream_i, fft2_i); + } + + void phase_multiplication(const T_r &gxu, const T_r &gyu, TVctr_c& psi_i, TVctr_c& psi_o) + { + if (this->multem_in_parm->dp_Shift || fcn_is_zero(gxu, gyu)) + { + if (psi_i.data() != psi_o.data()) + { + psi_o.assign(psi_i.begin(), psi_i.end()); + } + return; + } + + mt::fcn_rs_exp_factor_2d(*(this->stream), this->multem_in_parm->grid_2d, c_2pi*gxu, c_2pi*gyu, psi_i, psi_o); + } + + void phase_multiplication(const T_r &gxu, const T_r &gyu, TVctr_c& psi_io) + { + phase_multiplication(gxu, gyu, psi_io, psi_io); + } + + TVctr_c* get_psi(const eSpace &space, const T_r &gxu, const T_r &gyu, + T_r z, TVctr_c& psi_i) + { + TVctr_c *psi_o = &(this->trans_0); + phase_multiplication(gxu, gyu, psi_i, *psi_o); + propagator(space, gxu, gyu, z, *psi_o); + + return psi_o; + } + + T_r integrated_intensity_over_det(T_r w_i, const dt_int32& iDet, TVctr_c& psi_z) + { + T_r int_val = 0; + switch (detector.type) + { + case mt::edt_circular: + { + auto g_inner = detector.g_inner[iDet]; + auto g_outer = detector.g_outer[iDet]; + + int_val = w_i*mt::fcn_int_det_ring_norm_2(*(this->stream), this->multem_in_parm->grid_2d, g_inner, g_outer, psi_z); + } + break; + case mt::edt_radial: + { + int_val = 0; + } + break; + case mt::edt_matrix: + { + int_val = w_i*mt::fcn_int_det_ring_norm_2(*(this->stream), this->multem_in_parm->grid_2d, detector.fR[iDet], psi_z); + } + break; + } + + return int_val; + } + + template + void set_m2psi_tot_psi_coh(TVctr_c& psi_z_i, const T_r &gxu, const T_r &gyu, + const dt_int32& islice, const T_r &w_i, TOutput_multislice &output_multem) + { + dt_int32 ithk = this->slicing.slice[islice].ithk; + if (0 <= ithk) + { + auto *psi_z_o = get_psi(this->multem_in_parm->get_simulation_space(), gxu, gyu, this->slicing.thick[ithk].z_back_prop, psi_z_i); + + if (this->multem_in_parm->is_STEM()) + { + for(auto iDet = 0; iDetmultem_in_parm->ibeam[0]; + output_multem.image_tot(ithk, iDet, ibeam) += integrated_intensity_over_det(w_i, iDet, *psi_z_o); + } + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk, 0, w_i, *psi_z_o); + } + } + else if (this->multem_in_parm->is_EWFS_EWRS_SC()) + { + output_multem.set_crop_sft_psi_coh(ithk, *psi_z_o); + } + else if (this->multem_in_parm->is_EWFS_EWRS()) + { + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); + output_multem.add_sc_crop_sft_psi_coh(ithk, w_i, *psi_z_o); + } + else if (this->multem_in_parm->is_CBED()) + { + dt_int32 ithk_beam = (this->multem_in_parm->thick.size()==1)?this->multem_in_parm->ibeam[0]:ithk; + + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk_beam, w_i, *psi_z_o); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk_beam, w_i, *psi_z_o); + } + } + else if (this->multem_in_parm->is_CBEI()) + { + dt_int32 ithk_beam = (this->multem_in_parm->thick.size()==1)?this->multem_in_parm->ibeam[0]:ithk; + + microscope_effects(*psi_z_o, m2psi_z); + output_multem.add_sc_crop_sft_m2psi_tot_from_m2psi(ithk_beam, w_i, m2psi_z); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk_beam, w_i, *psi_z_o); + } + } + else if (this->multem_in_parm->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS()) + { + microscope_effects(*psi_z_o, m2psi_z); + output_multem.add_sc_crop_sft_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk, w_i, *psi_z_o); + } + } + else + { + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk, w_i, *psi_z_o); + } + } + + // this->stream->synchronize(); + } + } + + template + void set_m2psi_coh(TOutput_multislice &output_multem) + { + if (!this->multem_in_parm->atomic_vib.coh_contrib || this->multem_in_parm->is_EWFS_EWRS()) + { + return; + } + + dt_int32 n_thk = this->multem_in_parm->thick.size(); + + if (this->multem_in_parm->is_STEM()) + { + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + for(auto iDet = 0; iDetmultem_in_parm->ibeam[0]; + output_multem.image_coh(ithk, iDet, ibeam) = integrated_intensity_over_det(1, iDet, psi_z); + } + } + } + else if (this->multem_in_parm->is_CBED()) + { + n_thk = (n_thk==1)?this->multem_in_parm->number_of_beams():n_thk; + + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + output_multem.add_sc_crop_sft_m2psi_coh_from_psi(ithk, 1.0, psi_z); + } + } + else if (this->multem_in_parm->is_CBEI()) + { + n_thk = (n_thk==1)?this->multem_in_parm->number_of_beams():n_thk; + + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + microscope_effects(psi_z, m2psi_z); + output_multem.set_crop_sft_m2psi_coh(ithk, m2psi_z); + } + } + else if (this->multem_in_parm->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS()) + { + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + microscope_effects(psi_z, m2psi_z); + output_multem.set_crop_sft_m2psi_coh(ithk, m2psi_z); + } + } + else + { + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + output_multem.add_sc_crop_sft_m2psi_coh_from_psi(ithk, 1.0, psi_z); + } + } + + // this->stream->synchronize(); + } + + template + void psi_slice(const T_r &gxu, const T_r &gyu, const dt_int32& islice, TVctr_c& psi_z) + { + this->transmit(islice, psi_z); + + if (this->multem_in_parm->is_multislice()) + { + // time.tic(); + propagator(esp_real, gxu, gyu, this->sli_thick(islice), psi_z); + // time.toc(); + // mexPrintf("time = %7.5f\n", time.elapsed_ms()); + } + } + + template + void psi(T_r w_i, TVctr_c& psi_z, TOutput_multislice &output_multem) + { + T_r gx_0 = this->multem_in_parm->gx_0(); + T_r gy_0 = this->multem_in_parm->gy_0(); + + for(auto islice = 0; isliceslicing.slice.size(); islice++) + { + psi_slice(gx_0, gy_0, islice, psi_z); + + set_m2psi_tot_psi_coh(psi_z, gx_0, gy_0, islice, w_i, output_multem); + } + } + + template + void psi(dt_int32 islice_0, dt_int32 islice_e, T_r w_i, TVctr_c& trans, TOutput_multislice &output_multem) + { + dt_int32 ithk = this->slicing.slice[islice_e].ithk; + if (0 <= ithk) + { + T_r gx_0 = this->multem_in_parm->gx_0(); + T_r gy_0 = this->multem_in_parm->gy_0(); + + if (this->multem_in_parm->eels_fr.is_Single_Chan()) + { + T_r sli_thick = this->dz_m(islice_0, islice_e); + propagator(esp_real, gx_0, gy_0, sli_thick, psi_z); + } + else if (this->multem_in_parm->eels_fr.is_Mixed_Chan()) + { + T_r sli_thick = 0.5*this->dz_m(islice_0, islice_e); + propagator(esp_real, gx_0, gy_0, sli_thick, psi_z); + mt::ew_mult(*(this->stream), trans, psi_z); + propagator(esp_real, gx_0, gy_0, sli_thick, psi_z); + } + else if (this->multem_in_parm->eels_fr.is_Double_Chan()) + { + for(auto islice = islice_0; islice<= islice_e; islice++) + { + psi_slice(gx_0, gy_0, islice, psi_z); + } + } + + phase_multiplication(gx_0, gy_0, psi_z); + propagator(esp_fourier, gx_0, gy_0, this->slicing.thick[ithk].z_back_prop, psi_z); + + if (this->multem_in_parm->is_STEM_ISTEM_EELS()) + { + dt_int32 ibeam = this->multem_in_parm->ibeam[0]; + output_multem.image_tot(ithk, 0, ibeam) += w_i*mt::fcn_int_det_ring_norm_2(*(this->stream), this->multem_in_parm->grid_2d, 0, this->multem_in_parm->eels_fr.g_coll, psi_z); + } + if (this->multem_in_parm->is_EFTEMRS()) + { + microscope_effects(psi_z, m2psi_z); + output_multem.add_sc_crop_sft_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); + } + else + { + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk, w_i, psi_z); + } + } + } + + void set_incident_wave(TVctr_c& psi, Beam_Pos_2d& beam_pos) + { + T_r gxu = 0; + T_r gyu = 0; + auto z_init = this->slicing.z_m(0); + + incident_wave(psi, gxu, gyu, beam_pos, z_init); + } + + void set_incident_wave(TVctr_c& psi) + { + auto &beam_pos = this->multem_in_parm->beam_pos; + + set_incident_wave(psi, beam_pos); + } + + Propagator propagator; + + TVctr_c psi_z; + TVctr_r m2psi_z; + + Detector detector; + Microscope_Effects microscope_effects; + Incident_Wave incident_wave; + + mt::Timing time; + }; + +} + +#endif \ No newline at end of file diff --git a/src - Copy (2)/xtl_build.hpp b/src - Copy (2)/xtl_build.hpp new file mode 100755 index 00000000..d85c2342 --- /dev/null +++ b/src - Copy (2)/xtl_build.hpp @@ -0,0 +1,277 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef XTL_BUILD_H + #define XTL_BUILD_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + + #include "types.cuh" + #include "particles.cuh" + #include "xtl_build_in_parm.hpp" + #include "space_group.hpp" + + namespace mt + { + // from space group number to xtl system number + dt_int32 xtl_sgn_2_csn(const dt_int32& sgn) + { + if (fcn_chk_bound(sgn, 1, 3)) // triclinic or anorthic + { + return 1; + } + else if (fcn_chk_bound(sgn, 3, 16)) // monoclinic + { + return 2; + } + else if (fcn_chk_bound(sgn, 16, 75)) // orthorhombic + { + return 3; + } + else if (fcn_chk_bound(sgn, 75, 143)) // tetragonal + { + return 4; + } + else if (fcn_chk_bound(sgn, 143, 168)) // rhombohedral or trigonal + { + return 5; + } + else if (fcn_chk_bound(sgn, 168, 195)) // hexagonal + { + return 6; + } + else if (fcn_chk_bound(sgn, 195, 231)) // cubic + { + return 7; + } + + return 1; + } + + // from xtl system string to xtl system number + dt_int32 xtl_css_2_csn(std::string cs_str) + { + fcn_str_rtrim_ip(cs_str); + + cs_str = mt::fcn_str_2_lower(cs_str); + //std::transform(cs_str.begin(), cs_str.end(), cs_str.begin(), ::tolower); + + if (fcn_str_cmp(cs_str, "triclinic")||fcn_str_cmp(cs_str, "a")) // triclinic or anorthic + { + return 1; + } + else if (fcn_str_cmp(cs_str, "monoclinic")||fcn_str_cmp(cs_str, "m")) // monoclinic + { + return 2; + } + else if (fcn_str_cmp(cs_str, "orthorhombic")||fcn_str_cmp(cs_str, "o")) // orthorhombic + { + return 3; + } + else if (fcn_str_cmp(cs_str, "tetragonal")||fcn_str_cmp(cs_str, "t")) // tetragonal + { + return 4; + } + else if (fcn_str_cmp(cs_str, "rhombohedral")||fcn_str_cmp(cs_str, "r")) // rhombohedral or trigonal + { + return 5; + } + else if (fcn_str_cmp(cs_str, "hexagonal")||fcn_str_cmp(cs_str, "h")) // hexagonal + { + return 6; + } + else if (fcn_str_cmp(cs_str, "cubic")||fcn_str_cmp(cs_str, "c")) // cubic + { + return 7; + } + + return 1; + } + + // from xtl system number to space group range + std::pair xtl_csn_2_sgr(const dt_int32& csn) + { + switch(csn) + { + case 1: // triclinic or anorthic + return {1, 2}; + case 2: // monoclinic + return {3, 15}; + case 3: // orthorhombic + return {16, 74}; + case 4: // tetragonal + return {75, 142}; + case 5: // rhombohedral or trigonal + return {143, 167}; + case 6: // hexagonal + return {168, 194}; + case 7: // cubic + return {195, 230}; + } + + return {0, 0}; + } + + // from xtl system string to space group range + std::pair xtl_css_2_sgr(const std::string& cs_str) + { + auto csn = xtl_css_2_csn(cs_str); + + return xtl_csn_2_sgr(csn); + } + + template + class Xtl_Build{ + public: + Xtl_Build(): n_a(0), n_b(0), n_c(0), a(0), b(0), c(0) {}; + + Xtl_Build(const Xtl_Build_In_Parm& xtl_build_in_parm) + { + set_in_data(xtl_build_in_parm); + } + + void set_in_data(const Xtl_Build_In_Parm& xtl_build_in_parm) + { + a = xtl_build_in_parm.a; + b = xtl_build_in_parm.b; + c = xtl_build_in_parm.c; + + alpha = xtl_build_in_parm.alpha; + beta = xtl_build_in_parm.beta; + gamma = xtl_build_in_parm.gamma; + + n_a = xtl_build_in_parm.n_a; + n_b = xtl_build_in_parm.n_b; + n_c = xtl_build_in_parm.n_c; + + sgn = xtl_build_in_parm.sgn; + pbc = xtl_build_in_parm.pbc; + + asym_uc = xtl_build_in_parm.asym_uc; + base = xtl_build_in_parm.base; + + if (xtl_build_in_parm.base.size()==0) + { + base = space_group(asym_uc, sgn); + } + } + + Ptc_Atom operator()() const + { + const auto dsm = direct_struct_metric(); + const R_3d box_n = R_3d(T(n_a), T(n_b), T(n_c)) + T(1e-4); + + const dt_int32 n_base = base.size(); + + dt_int32 nt_a = n_a; + dt_int32 nt_b = n_b; + dt_int32 nt_c = n_c; + + if (!pbc) + { + nt_a++; + nt_b++; + nt_c++; + } + else + { + nt_a = max(1, nt_a); + nt_b = max(1, nt_b); + nt_c = max(1, nt_c); + } + + Ptc_Atom xtl; + xtl.reserve(nt_a*nt_b*nt_c*n_base); + xtl.cols_used = base.cols_used; + + for(auto ic = 0; ic < nt_c; ic++) + { + for(auto ib = 0; ib < nt_b; ib++) + { + for(auto ia = 0; ia < nt_a; ia++) + { + for(auto ik = 0; ik < n_base; ik++) + { + auto atom = base.get(ik); + + atom.x += T(ia); + atom.y += T(ib); + atom.z += T(ic); + + if ((atom.x direct_struct_metric() const + { + T cos_alpha = cos(alpha); + T cos_beta = cos(beta); + T cos_gamma = cos(gamma); + + T sin_gamma = sin(gamma); + + T F_bga = cos_beta*cos_gamma - cos_alpha; + + T vol2 = ::square(a*b*c)*(1-::square(cos_alpha)-::square(cos_beta)-::square(cos_gamma)+2*cos_alpha*cos_beta*cos_gamma); + T vol = ::sqrt(vol2); + + return {a, 0, 0, b*cos_gamma, b*sin_gamma, 0, c*cos_beta, -c*F_bga/sin_gamma, vol/(a*b*sin_gamma)}; + } + + private: + + T a; // lattice constant a + T b; // lattice constant b + T c; // lattice constant c + + T alpha; // angle between b & c + T beta; // angle between c & a + T gamma; // angle between a & b + + dt_int32 n_a; + dt_int32 n_b; + dt_int32 n_c; + + dt_int32 sgn; // space group number + dt_bool pbc; + + Ptc_Atom asym_uc; // normalized positions in the asymmetric unit cell + Ptc_Atom base; // normalized positions of atom in the unit cell + Space_Group space_group; + }; + + } + +#endif diff --git a/src - Copy (2)/xtl_build_in_parm.hpp b/src - Copy (2)/xtl_build_in_parm.hpp new file mode 100755 index 00000000..68331bb4 --- /dev/null +++ b/src - Copy (2)/xtl_build_in_parm.hpp @@ -0,0 +1,61 @@ +/* + * This file is part of Multem. + * Copyright 2021 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef XTL_BUILD_IN_PARM_H + #define XTL_BUILD_IN_PARM_H + + #include "particles.cuh" + + /* xtl */ + namespace mt + { + /* Asymmetric Unit + The asymmetric unit is the smallest fraction of the unit cell that + can be rotated and translated using only the symmetry operators + allowed by the xtllographic symmetry to generate one unit cell. + */ + template + class Xtl_Build_In_Parm + { + public: + using value_type = T; + + T a; // lattice constant a + T b; // lattice constant b + T c; // lattice constant c + + T alpha; // angle between b & c + T beta; // angle between c & a + T gamma; // angle between a & b + + dt_int32 n_a; + dt_int32 n_b; + dt_int32 n_c; + + dt_int32 sgn; // space group number + dt_bool pbc; + + Ptc_Atom asym_uc; // normalized positions in the asymmetric unit cell + Ptc_Atom base; // normalized positions of atom in the unit cell + + Xtl_Build_In_Parm() : + a(0), b(0), c(0), alpha(0), beta(0), gamma(0), + n_a(0), n_b(0), n_c(0), sgn(1), pbc(false) {}; + }; + } +#endif \ No newline at end of file diff --git a/src/amorp_build.hpp b/src/amorp_build.hpp new file mode 100755 index 00000000..d5a19b83 --- /dev/null +++ b/src/amorp_build.hpp @@ -0,0 +1,179 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef AMORPHOUS_BUILD_H + #define AMORPHOUS_BUILD_H + + #include "math_mt.h" + #include "types.cuh" + #include "types_mt.cuh" + #include "particles.cuh" + #include "atomic_data_mt.cuh" + #include "cgpu_rand.cuh" + #include "box_occ.hpp" + + namespace mt + { + template + class Amorp_Build { + public: + Amorp_Build():n_trial(500), randu_3d() {} + + Ptc_Atom operator()(dt_int32 Z, T rms_3d, T occ, T d_min, T rho, dt_int32 seed, Spec_Lay_Info spec_lay_info) + { + // calculate number of atoms for the amorphous spec + const auto n_atoms_amorp = n_amorp_atoms(Z, rho, spec_lay_info.bs); + + Ptc_Atom atoms; + atoms.bs = spec_lay_info.bs; + atoms.cols_used = 7; + atoms.reserve(n_atoms_amorp); + + // set box occupancy input data + box_occ.set_in_data(d_min, spec_lay_info.bs, spec_lay_info.r_0); + + // set random input data + randu_3d.set_in_data(seed, spec_lay_info.bs, spec_lay_info.r_0); + + const dt_int32 tag = spec_lay_info.tag; + + dt_int32 iatom_c = 0; + for(dt_int32 iatom = 0; iatom < n_atoms_amorp; iatom++) + { + R_3d r; + if (rnd_point(atoms, r)) + { + const Ptc_s_Atom atom_ik(Z, r, rms_3d, occ, tag, c_dflt_charge); + + atoms.push_back(atom_ik); + + box_occ.set(r, iatom_c); + iatom_c++; + } + } + + atoms.shrink_to_fit(); + atoms.sort_by_z(); + + return atoms; + } + + void operator()(Ptc_Atom& atoms, dt_int32 Z, T rms_3d, T occ, T d_min, T rho, dt_int32 seed, Spec_Lay_Info spec_lay_info) + { + // calculate number of atoms for the amorphous spec + const auto n_atoms_amorp = n_amorp_atoms(Z, rho, spec_lay_info.bs); + + Ptc_Atom m_atoms; + m_atoms.bs = fmax(atoms.bs, spec_lay_info.bs); + m_atoms.cols_used = atoms.cols_used; + + // set box occupancy input data + box_occ.set_in_data(d_min, spec_lay_info.bs, spec_lay_info.r_0); + + // select atoms within the depth + const T depth = 0.1; // set depth + const T z_0 = spec_lay_info.r_0.z - depth; + const T z_e = spec_lay_info.z_e() + depth; + + m_atoms.reserve(atoms.size()); + + dt_int32 iatom_0 = 0; + for(auto iatom = 0; iatom < atoms.size(); iatom++) + { + if (fcn_chk_bound(atoms.z[iatom], z_0, z_e)) + { + const auto atom_ik = atoms.get(iatom); + m_atoms.push_back(atom_ik); + // set occupancy + box_occ.set(atom_ik.get_pos(), iatom_0); + iatom_0++; + } + } + const dt_int32 n_atoms = iatom_0 + n_atoms_amorp; + m_atoms.reserve(n_atoms); + atoms.reserve(atoms.size() + n_atoms_amorp); + + // set random input data + randu_3d.set_in_data(seed, spec_lay_info.bs, spec_lay_info.r_0); + + const dt_int32 tag = spec_lay_info.tag; + + dt_int32 iatom_c = iatom_0; + for(dt_int32 iatom = iatom_0; iatom < n_atoms; iatom++) + { + R_3d r; + if (rnd_point(m_atoms, r)) + { + const Ptc_s_Atom atom_ik(Z, r, rms_3d, occ, tag, c_dflt_charge); + + m_atoms.push_back(atom_ik); + atoms.push_back(atom_ik); + + box_occ.set(r, iatom_c); + iatom_c++; + } + } + m_atoms.clear(); + m_atoms.shrink_to_fit(); + + atoms.shrink_to_fit(); + atoms.sort_by_z(); + } + + private: + const dt_int32 n_trial; + + Rndu_3d_cpu randu_3d; + + Box_Occ_3d box_occ; + + T vol(const R_3d& bs) const + { + return bs.x*bs.y*bs.z; + } + + T rho_n_A3(dt_int32 Z, T rho) const + { + Atomic_Info_cpu atomic_info = Atomic_Data(Z); + const T m = atomic_info.atomic_mass(); + + return rho*c_Na/(m*c_cm3_A3); + } + + dt_int32 n_amorp_atoms(dt_int32 Z, const T& rho, const R_3d& bs) const + { + return fcn_cceil(rho_n_A3(Z, rho)*vol(bs)); + } + + dt_bool rnd_point(const Ptc_Atom& atoms, R_3d& r_o) + { + for(auto itrial = 0; itrial < n_trial; itrial++) + { + const auto r = randu_3d(); + if (box_occ.check_r_min(atoms, r)) + { + r_o = r; + return true; + } + } + + return false; + } + }; + } +#endif \ No newline at end of file diff --git a/src/amorp_spec.hpp b/src/amorp_spec.hpp deleted file mode 100644 index 31387f74..00000000 --- a/src/amorp_spec.hpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2015 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef AMORPHOUS_SPECIMEN_H -#define AMORPHOUS_SPECIMEN_H - -#include "math.cuh" -#include "types.cuh" -#include "lin_alg_def.cuh" -#include "atomic_data_mt.hpp" -#include "atomic_data.hpp" -#include "cgpu_rand.cuh" -#include "box_occ.hpp" - -namespace mt -{ - template - class Amorp_Spec { - public: - Amorp_Spec() : m_ntrial(500), m_depth(0.01), - m_l_x(0), m_l_y(0), m_l_z(0), m_al_type(eALT_Top) {} - - void create(Atom_Data &atoms, T d_min, int Z, - T rms_3d, T rho, int seed = 300183) - { - T depth = m_depth; - - const int iatoms_0 = set_init_values(atoms, d_min, Z, rms_3d, rho, seed, depth); - const int region = atoms.amorp_lay_info[0].region; - - int iatoms_c = iatoms_0; - for (int iatoms = iatoms_0; iatoms < m_atoms.size(); iatoms++) - { - r3d r; - if (rand_point(m_atoms, r)) - { - box.set_occ(r, iatoms_c); - m_atoms.Z[iatoms_c] = Z; - m_atoms.x[iatoms_c] = r.x; - m_atoms.y[iatoms_c] = r.y; - m_atoms.z[iatoms_c] = r.z; - m_atoms.sigma[iatoms_c] = rms_3d; - m_atoms.occ[iatoms_c] = 1.0; - m_atoms.region[iatoms_c] = region; - m_atoms.charge[iatoms_c] = 0; - iatoms_c++; - } - } - m_atoms.resize(iatoms_c); - m_atoms.shrink_to_fit(); - - depth = box.l_z-atoms.amorp_lay_info[0].lz(); - const int natoms_am = m_atoms.size() - iatoms_0; - iatoms_c = atoms.size(); - atoms.resize(iatoms_c+natoms_am); - for (int iatoms = iatoms_0; iatoms < m_atoms.size(); iatoms++) - { - atoms.Z[iatoms_c] = m_atoms.Z[iatoms]; - atoms.x[iatoms_c] = m_atoms.x[iatoms]; - atoms.y[iatoms_c] = m_atoms.y[iatoms]; - atoms.z[iatoms_c] = (m_al_type==eALT_Top)?(atoms.z_min+depth-m_atoms.z[iatoms]):(atoms.z_max-depth+m_atoms.z[iatoms]); - atoms.sigma[iatoms_c] = m_atoms.sigma[iatoms]; - atoms.occ[iatoms_c] = m_atoms.occ[iatoms]; - atoms.region[iatoms_c] = m_atoms.region[iatoms]; - atoms.charge[iatoms_c] = m_atoms.charge[iatoms]; - iatoms_c++; - } - atoms.sort_by_z(); - } - - Atom_Data m_atoms; - - private: - const int m_ntrial; - const T m_depth; - - T m_l_x; - T m_l_y; - T m_l_z; - T m_rho; - eAmorp_Lay_Type m_al_type; - - Box_Occ box; - Rand_3d rand_3d; - - int set_init_values(Atom_Data &atoms, T d_min, int Z, - T rms_3d, T rho, int seed, T depth) - { - m_l_x = atoms.l_x; - m_l_y = atoms.l_y; - m_l_z = atoms.amorp_lay_info[0].lz(); - m_al_type = atoms.amorp_lay_info[0].type; - m_rho = convert_density(Z, rho); - - // set cgpu_rand set - rand_3d.seed(seed); - - // calculate number of atoms for the amorphous spec - int natoms_am = static_cast(ceil(m_rho*vol())); - m_atoms.l_x = m_l_x; - m_atoms.l_y = m_l_y; - m_atoms.l_z = m_l_z; - - if(atoms.empty()) - { - m_atoms.resize(natoms_am); - - // set amorphous box size - box.set_input_data(d_min, m_l_x, m_l_y, m_l_z); - - // set cgpu_rand box size - rand_3d.set_box_size(m_l_x, m_l_y, m_l_z); - - return 0; - } - - const int natoms_ct = atoms.size(); - m_atoms.resize(natoms_ct); - - // select atoms within the depth - T z_e = (m_al_type==eALT_Top)?(atoms.z_min+depth):(atoms.z_max-depth); - - int iatoms_c = 0; - for(auto iatoms = 0; iatoms < natoms_ct; iatoms++) - { - auto bb = (m_al_type==eALT_Top)?(atoms.z[iatoms]z_e); - if(bb) - { - m_atoms.Z[iatoms_c] = atoms.Z[iatoms]; - m_atoms.x[iatoms_c] = atoms.x[iatoms]; - m_atoms.y[iatoms_c] = atoms.y[iatoms]; - m_atoms.z[iatoms_c] = atoms.z[iatoms]; - m_atoms.sigma[iatoms_c] = atoms.sigma[iatoms]; - m_atoms.occ[iatoms_c] = atoms.occ[iatoms]; - m_atoms.region[iatoms_c] = atoms.region[iatoms]; - m_atoms.charge[iatoms_c] = atoms.charge[iatoms]; - iatoms_c++; - } - } - m_atoms.resize(iatoms_c); - - T z_min, z_max; - minmax_element(m_atoms.z, z_min, z_max); - - auto depth_ct = (m_al_type==eALT_Top)?(z_max-atoms.z_min):(atoms.z_max-z_min); - - // set amorphous box size - box.set_input_data(d_min, m_l_x, m_l_y, m_l_z+depth_ct); - - // set cgpu_rand box size - rand_3d.set_box_size(m_l_x, m_l_y, m_l_z+depth_ct); - - // set number of atoms - const int natoms_sct = iatoms_c; - m_atoms.resize(natoms_sct+natoms_am); - m_atoms.shrink_to_fit(); - - // change reference system - for(auto iatoms = 0; iatoms < natoms_sct; iatoms++) - { - m_atoms.z[iatoms] = (m_al_type==eALT_Top)?(z_max-m_atoms.z[iatoms]):(m_atoms.z[iatoms]-z_min); - box.set_occ(m_atoms.to_r3d(iatoms), iatoms); - } - - return natoms_sct; - } - - T convert_density(int Z, T m_rho) - { - const double Na = 6.022140857e23; - const double cm3_A3 = 1e24; - - Atomic_Data atomic_data; - const T m = atomic_data.atomic_mass(Z); - - return m_rho*Na/(m*cm3_A3); - } - - T vol() const - { - return m_l_x*m_l_y*m_l_z; - } - - T density(int natoms) const - { - return natoms/vol(); - } - - bool rand_point(Atom_Data &atoms, r3d &r_o) - { - for(auto itrial = 0; itrial < m_ntrial; itrial++) - { - auto r = rand_3d(); - if(box.check_r_min(atoms, r)) - { - r_o = r; - return true; - } - } - - return false; - } - }; -} -#endif \ No newline at end of file diff --git a/src/atom_cal.hpp b/src/atom_cal.hpp new file mode 100755 index 00000000..06a782c9 --- /dev/null +++ b/src/atom_cal.hpp @@ -0,0 +1,315 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef ATOM_CAL_H +#define ATOM_CAL_H + +#ifdef _MSC_VER +#pragma once +#endif// _MSC_VER + +#include + +#include "math.cuh" +#include "types.cuh" +#include "quadrature.hpp" +#include "host_device_functions.cuh" + +namespace mt +{ + template + class Atom_Cal{ + public: + using value_type = T; + + Atom_Cal(): potential_type(ePT_Lobato_0_12), charge(0), atom_type(nullptr), + pr_feg(nullptr), pr_fxg(nullptr), pr_Pr(nullptr), pr_Vr(nullptr), pr_VR(nullptr) + { + Quadrature quadrature; + quadrature(0, c_nqz, Qz_a_b); // 0: int_-1^1 y(x) dx - TanhSinh quadrature + quadrature(1, c_nqz, Qz_0_I); // 1: int_0^infty y(x) dx - ExpSinh quadrature + } + + void Set_Atom_Type(const ePotential_Type &PotPar_i, const int &charge_i, Atom_Type *atom_type_CPU_i) + { + potential_type = PotPar_i; + charge = atom_type_CPU_i->check_charge(charge_i); + atom_type = atom_type_CPU_i; + pr_feg = atom_type->feg(charge); + pr_fxg = atom_type->fxg(charge); + pr_Pr = atom_type->Pr(charge); + pr_Vr = atom_type->Vr(charge); + pr_VR = atom_type->VR(charge); + } + + // Electron scattering factors calculation (feg) + inline void feg(const T &g, T &y) + { + mt::feg(potential_type, charge, g, *pr_feg, y); + } + + void feg(const int &ng, T *g, T *y) + { + for(auto i = 0; i < ng; i++) + { + feg(g[i], y[i]); + } + } + + // Electron scattering factor(feg, dfeg) where dfg is the first derivative along g + inline void feg_dfeg(const T &g, T &y, T &dy) + { + mt::feg_dfeg(potential_type, charge, g, *pr_feg, y, dy); + } + + void feg_dfeg(const int &ng, T *g, T *y, T *dy) + { + for(auto i = 0; i < ng; i++) + { + feg_dfeg(g[i], y[i], dy[i]); + } + } + + // Electron scattering factor(fg) + inline void fxg(const T &g, T &y) + { + mt::fxg(potential_type, charge, atom_type->Z, g, *pr_fxg, y); + } + + void fxg(const int &ng, T *g, T *y) + { + for(auto i = 0; i < ng; i++) + { + fxg(g[i], y[i]); + } + } + + // Electron scattering factor(fg, dfg) where dfg is the first derivative along g + inline void fxg_dfxg(const T &g, T &y, T &dy) + { + mt::fxg_dfxg(potential_type, charge, atom_type->Z, g, *pr_fxg, y, dy); + } + + void fxg_dfxg(const int &ng, T *g, T *y, T *dy) + { + for(auto i = 0; i < ng; i++) + { + fxg_dfxg(g[i], y[i], dy[i]); + } + } + + // Electron density (Pr) + inline void Pr(const T &r, T &y) + { + mt::Pr(potential_type, charge, r, *pr_Pr, y); + } + + void Pr(const int &nr, T *r, T *y) + { + for(auto i = 0; i < nr; i++) + { + Pr(r[i], y[i]); + } + } + + // Electron density (Pr, dPr) where dPr is the first derivative along r + inline void Pr_dPr(const T &r, T &y, T &dy) + { + mt::Pr_dPr(potential_type, charge, r, *pr_Pr, y, dy); + } + + void Pr_dPr(const int &nr, T *r, T *y, T *dy) + { + for(auto i = 0; i < nr; i++) + { + Pr_dPr(r[i], y[i], dy[i]); + } + } + + // Projected_Potential calculation(Vr) + inline void Vr(const T &r, T &y) + { + mt::Vr(potential_type, charge, r, *pr_Vr, y); + } + + void Vr(const int &nr, T *r, T *y) + { + for(auto i = 0; i < nr; i++) + { + Vr(r[i], y[i]); + } + } + + // Projected_Potential calculation (Vr, dVr) where dVr is the first derivative along r + inline void Vr_dVr(const T &r, T &y, T &dy) + { + mt::Vr_dVr(potential_type, charge, r, *pr_Vr, y, dy); + } + + void Vr_dVr(const int &nr, T *r, T *y, T *dy) + { + for(auto i = 0; i < nr; i++) + { + Vr_dVr(r[i], y[i], dy[i]); + } + } + + // Projected potential (VR) + inline void VR(const T &R, T &y) + { + mt::VR(potential_type, charge, R, *pr_VR, Qz_0_I, y); + } + + void VR(const int &nR, T *R, T *y) + { + for(auto i = 0; i < nR; i++) + { + VR(R[i], y[i]); + } + } + + // Projected potential (VR, dVR) where dVr is the first derivative along R + inline void VR_dVR(const T &R, T &y, T &dy) + { + mt::VR_dVR(potential_type, charge, R, *pr_VR, Qz_0_I, y, dy); + } + + void VR_dVR(const int &nR, T *R, T *y, T *dy) + { + for(auto i = 0; i < nR; i++) + { + VR_dVR(R[i], y[i], dy[i]); + } + } + + // Projected potential (Vz)[z0, ze] + inline void Vz(const T &z0, const T &ze, const T &R, T &y) + { + mt::Vz(potential_type, charge, z0, ze, R, *pr_Vr, Qz_a_b, y); + } + + void Vz(const T &z0, const T &ze, const int &nR, T *R, T *y) + { + for(auto i = 0; i < nR; i++) + { + Vz(z0, ze, R[i], y[i]); + } + } + + // Projected potential (Vz, dVz)[z0, ze] where dVr is the first derivative along R + inline void Vz_dVz(const T &z0, const T &ze, const T &R, T &y, T &dy) + { + mt::Vz_dVz(potential_type, charge, z0, ze, R, *pr_Vr, Qz_a_b, y, dy); + } + + void Vz_dVz(const T &z0, const T &ze, const int &nR, T *R, T *y, T *dy) + { + for(auto i = 0; i < nR; i++) + { + Vz_dVz(z0, ze, R[i], y[i], dy[i]); + } + } + + T AtomicRadius_rms(const int &Dim) + { + + if(isZero(pr_Vr->cl[0])) + { + return 0.0; + } + else + { + auto fx = [=](const T &x)->T + { + T V; + if(Dim == 3) + { + this->Vr(x, V); + } + else + { + this->VR(x, V); + } + return V; + }; + + auto rmin = atom_type->rn_c; + auto Vri = fx(rmin); + + auto iVr = Vri*pow(rmin, Dim)/Dim; + auto iVrn = Vri*pow(rmin, Dim+2)/(Dim+2); + + for(auto i = 0; i< Qz_0_I.size(); i++) + { + auto ri = Qz_0_I.x[i] + rmin; + Vri = fx(ri); + T Vrt; + iVr += Vrt = Qz_0_I.w[i]*Vri*pow(ri, Dim-1); + iVrn += Vrt*ri*ri; + } + return sqrt(iVrn/iVr); + } + } + + T AtomicRadius_Cutoff(const int &Dim, const T &Vrl) + { + if(!nonZero(Vrl, pr_Vr->cl[0])) + { + return 0; + } + else + { + auto f = [=](const T &x)->T + { + T V; + if(Dim == 3) + { + this->Vr(x, V); + } + else + { + this->VR(x, V); + } + return V-Vrl; + }; + + T rmin = atom_type->rn_c; + T rmax = 25.0; + + return host_device_detail::Root_Finder(f, rmin, rmax); + } + } + + private: + ePotential_Type potential_type; + int charge; + + Atom_Type *atom_type; + PP_Coef *pr_feg; + PP_Coef *pr_fxg; + PP_Coef *pr_Pr; + PP_Coef *pr_Vr; + PP_Coef *pr_VR; + + Q1 Qz_a_b; + Q1 Qz_0_I; + }; + +} // namespace mt + +#endif \ No newline at end of file diff --git a/src/atom_data.hpp b/src/atom_data.hpp new file mode 100755 index 00000000..c6e05417 --- /dev/null +++ b/src/atom_data.hpp @@ -0,0 +1,792 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef ATOM_DATA_H +#define ATOM_DATA_H + +#ifdef _MSC_VER +#pragma once +#endif// _MSC_VER + +#include +#include + +#include "math.cuh" +#include "types.cuh" +#include "traits.cuh" +#include "lin_alg_def.cuh" + +#include + +namespace mt +{ + namespace host_device_detail + { + template + DEVICE_CALLABLE FORCE_INLINE + void kh_sum(T &sum_v, T v, T &error); + } + + template + void minmax_element(TVector &x, Value_type &x_min, Value_type &x_max); + + template + Value_type mean(TVector &M_i); + + template + void mean_std(TVector &M_i, Value_type &x_mean, Value_type_r &x_std); + + template + void scale(Value_type f, TVector &x); + + template + class Atom_Data; + + template + void rotate_atoms(Atom_Data &atoms, T theta, r3d u0, r3d p0) + { + const auto Rm = get_rotation_matrix(theta, u0); + + for(int iatoms = 0; iatoms + void remove_atoms_outside_z_range(Atom_Data &atoms, T z_0, T z_e) + { + int iatoms_z = 0; + for(int iatoms = 0; iatoms + class Atom_Data + { + public: + using value_type = T; + using size_type = std::size_t; + using TVector_r = Vector; + + Atom_Data(): l_x(0), l_y(0), l_z(0), dz(0.25), + ct_na(1), ct_nb(1), ct_nc(1), ct_a(0), + ct_b(0), ct_c(0), ct_x0(0), ct_y0(0), + Z_min(0), Z_max(0), x_min(0), x_max(0), + y_min(0), y_max(0), z_min(0), z_max(0), + sigma_min(0), sigma_max(0), occ_min(0), + occ_max(0), region_min(0), region_max(0), + R_int_min(0), R_int_max(0), + x_mean(0), y_mean(0), z_mean(0), x_std(0), + y_std(0), z_std(0), s_x(0), s_y(0), s_z(0), + x_int_min(0), x_int_max(0), y_int_min(0), + y_int_max(0), z_int_min(0), z_int_max(0), + s_x_int(0), s_y_int(0), s_z_int(0), + l_x_int(0), l_y_int(0), l_z_int(0){} + + size_type size() const + { + return Z.size(); + } + + bool empty() const + { + return size() == 0; + } + + void clear() + { + l_x = l_y = l_z = 0; + dz = 0.25; + ct_na = ct_nb = ct_nc = 1; + ct_a = ct_b = ct_c = 0; + ct_x0 = ct_y0 = 0; + Z_min = Z_max = 0; + x_min = x_max = 0; + y_min = y_max = 0; + z_min = z_max = 0; + sigma_min = sigma_max = 0; + occ_min = occ_max = 0; + region_min = region_max = 0; + R_int_min = R_int_max = 0; + x_mean = y_mean = 0; + z_mean = x_std = 0; + y_std = z_std = 0; + s_x = s_y = s_z = 0; + x_int_min = x_int_max = 0; + y_int_min = y_int_max = 0; + z_int_min = z_int_max = 0; + s_x_int = s_y_int = s_z_int = 0; + l_x_int =l_y_int = l_z_int = 0; + + Z.clear(); + x.clear(); + y.clear(); + z.clear(); + sigma.clear(); + occ.clear(); + region.clear(); + charge.clear(); + + amorp_lay_info.clear(); + Z_unique.clear(); + + } + + // resize number of atoms + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.resize(new_size); + x.resize(new_size); + y.resize(new_size); + z.resize(new_size); + sigma.resize(new_size); + occ.resize(new_size); + region.resize(new_size); + charge.resize(new_size); + } + + template + void assign(TAtom_Data &atoms) + { + this->l_x = atoms.l_x; + this->l_y = atoms.l_y; + this->l_z = atoms.l_z; + this->dz = atoms.dz; + + this->ct_na = atoms.ct_na; + this->ct_nb = atoms.ct_nb; + this->ct_nc = atoms.ct_nc; + + this->ct_a = atoms.ct_a; + this->ct_b = atoms.ct_b; + this->ct_c = atoms.ct_c; + + this->ct_x0 = atoms.ct_x0; + this->ct_y0 = atoms.ct_y0; + + this->ct_x0 = atoms.ct_x0; + this->ct_y0 = atoms.ct_y0; + + this->amorp_lay_info.resize(atoms.amorp_lay_info.size()); + for(auto ik=0; ikamorp_lay_info[ik] = atoms.amorp_lay_info[ik]; + + this->Z.assign(atoms.Z.begin(), atoms.Z.end()); + this->x.assign(atoms.x.begin(), atoms.x.end()); + this->y.assign(atoms.y.begin(), atoms.y.end()); + this->z.assign(atoms.z.begin(), atoms.z.end()); + this->sigma.assign(atoms.sigma.begin(), atoms.sigma.end()); + this->occ.assign(atoms.occ.begin(), atoms.occ.end()); + this->region.assign(atoms.region.begin(), atoms.region.end()); + this->charge.assign(atoms.charge.begin(), atoms.charge.end()); + + this->Z_unique.assign(atoms.Z_unique.begin(), atoms.Z_unique.end()); + + this->Z_min = atoms.Z_min; + this->Z_max = atoms.Z_max; + + this->x_min = atoms.x_min; + this->x_max = atoms.x_max; + + this->y_min = atoms.y_min; + this->y_max = atoms.y_max; + + this->z_min = atoms.z_min; + this->z_max = atoms.z_max; + + this->sigma_min = atoms.sigma_min; + this->sigma_max = atoms.sigma_max; + + this->occ_min = atoms.occ_min; + this->occ_max = atoms.occ_max; + + this->region_min = atoms.region_min; + this->region_max = atoms.region_max; + + this->R_int_min = atoms.R_int_min; + this->R_int_max = atoms.R_int_max; + + this->x_mean = atoms.x_mean; + this->y_mean = atoms.y_mean; + this->z_mean = atoms.z_mean; + + this->x_std = atoms.x_std; + this->y_std = atoms.y_std; + this->z_std = atoms.z_std; + + this->s_x = atoms.s_x; + this->s_y = atoms.s_y; + this->s_z = atoms.s_z; + + this->x_int_min = atoms.x_int_min; + this->x_int_max = atoms.x_int_max; + + this->y_int_min = atoms.y_int_min; + this->y_int_max = atoms.y_int_max; + + this->z_int_min = atoms.z_int_min; + this->z_int_max = atoms.z_int_max; + + this->s_x_int = atoms.s_x_int; + this->s_y_int = atoms.s_y_int; + this->s_z_int = atoms.s_z_int; + + this->l_x_int = atoms.l_x_int; + this->l_y_int = atoms.l_y_int; + this->l_z_int = atoms.l_z_int; + } + + template + Atom_Data& operator=(TAtom_Data &atoms) + { + assign(atoms); + return *this; + } + + void shrink_to_fit() + { + Z.shrink_to_fit(); + x.shrink_to_fit(); + y.shrink_to_fit(); + z.shrink_to_fit(); + sigma.shrink_to_fit(); + occ.shrink_to_fit(); + region.shrink_to_fit(); + charge.shrink_to_fit(); + } + + // set xtl_build parameters + void set_crystal_parameters(int ct_na_i = 1, int ct_nb_i = 1, int ct_nc_i = 1, + T ct_a_i = 0, T ct_b_i = 0, T ct_c_i = 0, T ct_x0_i = 0, T ct_y0_i = 0) + { + ct_na = max(1, ct_na_i); + ct_nb = max(1, ct_nb_i); + ct_nc = max(1, ct_nc_i); + ct_a = max(T(0), ct_a_i); + ct_b = max(T(0), ct_b_i); + ct_c = max(T(0), ct_c_i); + ct_x0 = max(T(0), ct_x0_i); + ct_y0 = max(T(0), ct_y0_i); + } + + // set amorphous parameters + void set_amorphous_parameters(Vector, e_host> &amorp_lay_info_i) + { + amorp_lay_info = amorp_lay_info_i; + } + + // set atoms + void set_atoms(size_type nr_atoms_i, size_type nc_atoms_i, + double *atoms_i, T l_x_i = 0, T l_y_i = 0, T l_z_i = 0, T dz_i= 0.25) + { + resize(nr_atoms_i); + + l_x = l_x_i; + l_y = l_y_i; + l_z = l_z_i; + dz = dz_i; + + size_type iatoms_c = 0; + for(auto iatoms = 0; iatoms < nr_atoms_i; iatoms++) + { + auto atom = read_atom(nr_atoms_i, nc_atoms_i, atoms_i, iatoms); + //if(atom.is_xy_positive()) + Z[iatoms_c] = atom.Z; // Atomic number + x[iatoms_c] = atom.x; // x-position + y[iatoms_c] = atom.y; // y-position + z[iatoms_c] = atom.z; // z-position + sigma[iatoms_c] = atom.sigma; // standard deviation + occ[iatoms_c] = atom.occ; // Occupancy + region[iatoms_c] = abs(atom.region); // Region + charge[iatoms_c] = atom.charge; // charge + + iatoms_c++; + } + + resize(iatoms_c); + + get_statistic(); + } + + // set atoms + template + void set_atoms(const Atom_Data &atoms, bool pbc_xy_i = false, + Vector, e_host> *atom_type = 0, bool b_statistic=true) + { + resize(atoms.size()); + + l_x = atoms.l_x; + l_y = atoms.l_y; + l_z = atoms.l_z; + dz = atoms.dz; + + ct_na = atoms.ct_na; + ct_nb = atoms.ct_nb; + ct_nc = atoms.ct_nc; + + ct_a = atoms.ct_a; + ct_b = atoms.ct_b; + ct_c = atoms.ct_c; + + ct_x0 = atoms.ct_x0; + ct_y0 = atoms.ct_y0; + + amorp_lay_info.resize(atoms.amorp_lay_info.size()); + for(auto ik=0; ik, e_host> *atom_type_ptr = nullptr) + { + if(empty()) + { + return; + } + + get_Z_unique(); + + auto Z_min_max = std::minmax_element(Z.begin(), Z.end(), [](const int &a, const int &b){ return (a % 1000)<(b % 1000); }); + Z_min = *(Z_min_max.first); + Z_max = *(Z_min_max.second); + + mt::minmax_element(x, x_min, x_max); + mt::minmax_element(y, y_min, y_max); + mt::minmax_element(z, z_min, z_max); + mt::minmax_element(sigma, sigma_min, sigma_max); + mt::minmax_element(occ, occ_min, occ_max); + mt::minmax_element(region, region_min, region_max); + + mt::mean_std(x, x_mean, x_std); + mt::mean_std(y, y_mean, y_std); + mt::mean_std(z, z_mean, z_std); + + bool bAtomTypes = (atom_type_ptr == nullptr)?false:true; + R_int_min = R_int_max = 2.5; + if(bAtomTypes) + { + R_int_min = R_int_max = (*atom_type_ptr)[get_Z(Z[0])-1].coef[0].R_max; + for(auto iatoms = 0; iatoms < size(); iatoms++) + { + R_int_min = min((*atom_type_ptr)[get_Z(Z[iatoms])-1].coef[0].R_max, R_int_min); + R_int_max = max((*atom_type_ptr)[get_Z(Z[iatoms])-1].coef[0].R_max, R_int_max); + } + } + + s_x = x_max - x_min; + s_y = y_max - y_min; + s_z = z_max - z_min; + + x_int_min = x_min - R_int_max; + x_int_max = x_max + R_int_max; + + y_int_min = y_min - R_int_max; + y_int_max = y_max + R_int_max; + + z_int_min = z_min - R_int_max; + z_int_max = z_max + R_int_max; + + s_x_int = x_int_max - x_int_min; + s_y_int = y_int_max - y_int_min; + s_z_int = z_int_max - z_int_min; + + if(isZero(l_x)) + { + l_x = s_x; + } + + if(isZero(l_y)) + { + l_y = s_y; + } + + l_z = ::fmax(s_z, l_z); + + l_x_int = l_x + 2.0*R_int_max; + l_y_int = l_y + 2.0*R_int_max; + l_z_int = l_z + 2.0*R_int_max; + + if(isZero(ct_a)) + { + ct_a = l_x; + } + + if(isZero(ct_b)) + { + ct_b = l_y; + } + + if(isZero(ct_c)) + { + ct_c = l_z; + } + } + + // Sort atoms along z-axis. + void sort_by_z() + { + // if(!thrust::is_sorted(z.begin(), z.end())); + auto first = thrust::make_zip_iterator(thrust::make_tuple(Z.begin(), x.begin(), y.begin(), z.begin(), sigma.begin(), occ.begin(), region.begin(), charge.begin())); + auto last = thrust::make_zip_iterator(thrust::make_tuple(Z.end(), x.end(), y.end(), z.end(), sigma.end(), occ.end(), region.end(), charge.end())); + + thrust::sort(first, last, sort_atoms_by_z()); + } + + // max z value within a region + void minmax_z_by_region(T region_v, T &zr_min, T &zr_max) + { + zr_min = 1e20; + zr_max = -1e20; + for(auto iz=0; iz &v1, Amorp_Lay_Info &v2){ return v1.z_00) + { + T zc_min, zc_max; + int region_c = 0; + minmax_z_by_region(region_c, zc_min, zc_max); + + for(auto il=0; il(amorp_lay_info[il].dz)) + { + amorp_lay_info[il].dz = 2.0; + } + + auto z_0 = amorp_lay_info[il].z_0; + if(z_0 to_r3d(const int &iatoms) const + { + return r3d(x[iatoms], y[iatoms], z[iatoms]); + } + + inline + T norm(const int &iatoms, r3d r) const + { + auto r_i = to_r3d(iatoms)-r; + return r_i.norm(); + } + + inline + T norm_pbc_xy(const int &iatoms, r3d r) const + { + auto x_d = fabs(x[iatoms]-r.x); + auto y_d = fabs(y[iatoms]-r.y); + auto z_d = z[iatoms]-r.z; + + x_d = ::fmin(x_d, fabs(x_d-l_x)); + y_d = ::fmin(y_d, fabs(y_d-l_y)); + + return (x_d*x_d + y_d*y_d + z_d*z_d); + } + + inline + T norm(const int &iatoms, T x_i, T y_i, T z_i) const + { + auto x_d = x[iatoms]-x_i; + auto y_d = y[iatoms]-y_i; + auto z_d = z[iatoms]-z_i; + return (x_d*x_d + y_d*y_d + z_d*z_d); + } + + inline + T distance(const int &iatoms, T x_i, T y_i, T z_i) + { + return sqrt(norm(iatoms, x_i, y_i, z_i)); + } + + T l_x; // box length along x direction (Å) + T l_y; // box length along y direction (Å) + T l_z; // box length along z direction (Å) + T dz; // slice thickness (Å) + + int ct_na; // number of unit cell along a + int ct_nb; // number of unit cell along b + int ct_nc; // number of unit cell along c + + T ct_a; // length along a (Å) + T ct_b; // length along b (Å) + T ct_c; // length along c (Å) + + T ct_x0; // reference position along x direction (Å) + T ct_y0; // reference position along y direction (Å) + + Vector, e_host> amorp_lay_info; // amorphous layer information + + Vector Z; + TVector_r x; + TVector_r y; + TVector_r z; + Vector sigma; + Vector occ; + Vector region; + Vector charge; + + Vector Z_unique; + + int Z_min; + int Z_max; + + T x_min; + T x_max; + + T y_min; + T y_max; + + T z_min; + T z_max; + + float sigma_min; + float sigma_max; + + float occ_min; + float occ_max; + + int region_min; + int region_max; + + T R_int_min; + T R_int_max; + + T x_mean; + T y_mean; + T z_mean; + + T x_std; + T y_std; + T z_std; + + T s_x; // size-x + T s_y; // size-y + T s_z; // size-z + + T x_int_min; + T x_int_max; + + T y_int_min; + T y_int_max; + + T z_int_min; + T z_int_max; + + T s_x_int; + T s_y_int; + T s_z_int; + + T l_x_int; + T l_y_int; + T l_z_int; + + private: + Identify_Planes identify_planes; + + struct sort_atoms_by_z + { + template + DEVICE_CALLABLE + bool operator()(const Ttuple1 &t1, const Ttuple2 &t2) + { + return thrust::get<3>(t1) < thrust::get<3>(t2); + } + }; + + struct Atom + { + int Z; + T x; + T y; + T z; + T sigma; + T occ; + int region; + int charge; + + Atom():Z(0), x(0), y(0), z(0), sigma(0), occ(0), charge(0){}; + + // check if atomic position are in the first quadrant + bool is_xy_positive() const + { + const T ee = 1e-4; + return (-ee + Atom read_atom(const int &nr, const int &nc, X *atoms, const int &iatoms) + { + Atom atom; + atom.Z = static_cast(atoms[0*nr + iatoms]); // Atomic number + atom.x = atoms[1*nr + iatoms]; // x-position + atom.y = atoms[2*nr + iatoms]; // y-position + atom.z = atoms[3*nr + iatoms]; // z-position + atom.sigma = static_cast((nc>4)?(atoms[4*nr + iatoms]):0.085); // Standard deviation + atom.occ = static_cast((nc>5)?(atoms[5*nr + iatoms]):1.0); // Occupancy + atom.region = static_cast((nc>6)?(atoms[6*nr + iatoms]):0); // Region + atom.charge = static_cast((nc>7)?(atoms[7*nr + iatoms]):0); // charge + + return atom; + } + }; + +} // namespace mt + +#endif \ No newline at end of file diff --git a/src/atomic_cross_section.cuh b/src/atomic_cross_section.cuh old mode 100644 new mode 100755 index 99e9f1ab..2454bb79 --- a/src/atomic_cross_section.cuh +++ b/src/atomic_cross_section.cuh @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,9 +25,9 @@ #include "fft.cuh" #include "input_multislice.cuh" #include "output_multislice.hpp" -#include "tem_simulation.cuh" +#include "multislice.cuh" #include "cubic_spline.hpp" -#include "cgpu_classes.cuh" +#include "host_device_classes.cuh" #include namespace mt @@ -48,16 +48,16 @@ namespace mt template void get(TVector &r_o, TVector &fr_o) { - /**************************tem_simulation calculation*******************************/ + /**************************multislice calculation*******************************/ mt::Output_Multislice_Vector output_multislice; output_multislice.set_input_data(input_multislice); - mt::Multislice tem_simulation; - tem_simulation.set_input_data(input_multislice); + mt::Multislice multislice; + multislice.set_input_data(input_multislice); - tem_simulation.run(output_multislice); + multislice.run(output_multislice); - tem_simulation.cleanup(); + multislice.cleanup(); /******************************* Cross section ********************************/ mt::Grid_2d grid_2d; diff --git a/src/atomic_data.hpp b/src/atomic_data.hpp old mode 100644 new mode 100755 index 6e135331..d9a1afde --- a/src/atomic_data.hpp +++ b/src/atomic_data.hpp @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,7 +26,7 @@ #include #include "math.cuh" #include "types.cuh" -#include "atomic_fcns_mt.hpp" +#include "atom_cal.hpp" namespace mt { @@ -534,7 +534,7 @@ namespace mt data_table[99].edges[0] = 0.00; data_table[99].edges[1] = 0.00; data_table[99].edges[2] = 0.00; data_table[99].edges[3] = 0.00; data_table[99].edges[4] = 0.00; data_table[99].edges[5] = 0.00; data_table[99].edges[6] = 0.00; data_table[99].edges[7] = 0.00; data_table[99].edges[8] = 0.00; data_table[99].edges[9] = 0.00; data_table[99].edges[10] = 0.00; data_table[99].edges[11] = 0.00; data_table[100].edges[0] = 0.00; data_table[100].edges[1] = 0.00; data_table[100].edges[2] = 0.00; data_table[100].edges[3] = 0.00; data_table[100].edges[4] = 0.00; data_table[100].edges[5] = 0.00; data_table[100].edges[6] = 0.00; data_table[100].edges[7] = 0.00; data_table[100].edges[8] = 0.00; data_table[100].edges[9] = 0.00; data_table[100].edges[10] = 0.00; data_table[100].edges[11] = 0.00; data_table[101].edges[0] = 0.00; data_table[101].edges[1] = 0.00; data_table[101].edges[2] = 0.00; data_table[101].edges[3] = 0.00; data_table[101].edges[4] = 0.00; data_table[101].edges[5] = 0.00; data_table[101].edges[6] = 0.00; data_table[101].edges[7] = 0.00; data_table[101].edges[8] = 0.00; data_table[101].edges[9] = 0.00; data_table[101].edges[10] = 0.00; data_table[101].edges[11] = 0.00; - data_table[102].edges[0] = 0.00; data_table[102].edges[1] = 0.00; data_table[102].edges[2] = 0.00; data_table[102].edges[3] = 0.00; data_table[102].edges[4] = 0.00; data_table[102].edges[5] = 0.00; data_table[102].edges[6] = 0.00; data_table[102].edges[7] = 0.00; data_table[102].edges[8] = 0.00; data_table[102].edges[9] = 0.00; data_table[102].edges[10] = 0.00; data_table[102].edges[11] = 0.00; +data_table[102].edges[0] = 0.00; data_table[102].edges[1] = 0.00; data_table[102].edges[2] = 0.00; data_table[102].edges[3] = 0.00; data_table[102].edges[4] = 0.00; data_table[102].edges[5] = 0.00; data_table[102].edges[6] = 0.00; data_table[102].edges[7] = 0.00; data_table[102].edges[8] = 0.00; data_table[102].edges[9] = 0.00; data_table[102].edges[10] = 0.00; data_table[102].edges[11] = 0.00; } // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] @@ -1326,23 +1326,6 @@ namespace mt VR.cl[j] = c_Potf*c_Pi*cl/cnl; VR.cnl[j] = c_Pi2/cnl; } - else - { - feg.cl[j] = 0.0; - feg.cnl[j] = 1.0; - - fxg.cl[j] = 0.0; - fxg.cnl[j] = 1.0; - - Pr.cl[j] = 0.0; - Pr.cnl[j] = 1.0; - - Vr.cl[j] = 0.0; - Vr.cnl[j] = 1.0; - - VR.cl[j] = 0.0; - VR.cnl[j] = 1.0; - } } } @@ -1464,23 +1447,6 @@ namespace mt VR.cl[j] = 2.0*c_Potf*c_Pi2*cl/pow(cnl, 1.5); VR.cnl[j] = c_2Pi/sqrt(cnl); } - else - { - feg.cl[j] = 0.0; - feg.cnl[j] = 1.0; - - fxg.cl[j] = 0.0; - fxg.cnl[j] = 1.0; - - Pr.cl[j] = 0.0; - Pr.cnl[j] = 1.0; - - Vr.cl[j] = 0.0; - Vr.cnl[j] = 1.0; - - VR.cl[j] = 0.0; - VR.cnl[j] = 1.0; - } } } @@ -1610,15 +1576,12 @@ namespace mt coef.R_min = R_min; c_atom_cal.Set_Atom_Type(potential_type, coef.charge, &atom_type); coef.R_max = (coef.charge == 0)?c_atom_cal.AtomicRadius_Cutoff(3, Vrl):atom_type.coef[0].R_max; - coef.R_max = ::fmax(coef.R_max, T(2)*R_min); - if(isZero(coef.R_max)) { coef.R_max = 1.75*atom_type.ra_e; } - //coef.R_tap = 0.85*coef.R_max; - coef.R_tap = coef.R_min + 0.85*(coef.R_max - coef.R_min); + coef.R_tap = 0.85*coef.R_max; coef.tap_cf = c_i2Pi/(coef.R2_max()-coef.R2_tap()); // R and R2 diff --git a/src/atomic_data_mt.cuh b/src/atomic_data_mt.cuh new file mode 100755 index 00000000..db9ab92d --- /dev/null +++ b/src/atomic_data_mt.cuh @@ -0,0 +1,2857 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ATOMIC_DATA_MT_H + #define ATOMIC_DATA_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "const_enum_mt.cuh" + #include "fcns_cgpu_gen.h" + #include "intrpl_coef.cuh" + + namespace mt + { + /************************* atomic coefficients ***********************/ + template + class Atomic_Coef + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + eAtomic_Pot_Parm_Typ atomic_pot_parm_typ; // feg parameterization + dt_int32 Z; // atomic number + dt_int32 charge; // charge + + mutable LNL_Coef feg; // electron scattering factor coefficients + mutable LNL_Coef fxg; // x-ray scattering factor coefficients + mutable LNL_Coef pr; // electron density coefficients + mutable LNL_Coef vr; // potential coefficients + mutable LNL_Coef vzp; // projected potential coefficients + + /************************************* constructors ************************************/ + Atomic_Coef():atomic_pot_parm_typ(eappt_lobato_0_12), Z(0), charge(0) {} + + Atomic_Coef(const size_type& new_size): Atomic_Coef() + { + resize(new_size); + } + + Atomic_Coef(const size_type& new_size, const T& value): Atomic_Coef() + { + resize(new_size, value); + } + + /* copy constructor */ + Atomic_Coef(const Atomic_Coef& atomic_coef): Atomic_Coef() + { + *this = atomic_coef; + } + + /* converting constructor */ + template + Atomic_Coef(const Atomic_Coef& atomic_coef) + { + *this = atomic_coef; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Atomic_Coef& operator=(const Atomic_Coef& atomic_coef) + { + this->assign(atomic_coef); + + return *this; + } + + /* converting assignment operator */ + template + Atomic_Coef& operator=(const Atomic_Coef& atomic_coef) + { + this->assign(atomic_coef); + + return *this; + } + + template + void assign(const Atomic_Coef& atomic_coef) + { + atomic_pot_parm_typ = atomic_coef.atomic_pot_parm_typ; + Z = atomic_coef.Z; + charge = atomic_coef.charge; + + feg.assign(atomic_coef.feg); + fxg.assign(atomic_coef.fxg); + pr.assign(atomic_coef.pr); + vr.assign(atomic_coef.vr); + vzp.assign(atomic_coef.vzp); + } + + void fill(const T& val) + { + feg.fill(val); + fxg.fill(val); + pr.fill(val); + vr.fill(val); + vzp.fill(val); + } + + size_type size() const + { + return size_type(feg.size()); + } + + template + ST size() const + { + return static_cast(feg.size()); + } + + void clear() + { + atomic_pot_parm_typ = eappt_lobato_0_12; + Z = 0; + charge = 0; + + feg.clear(); + fxg.clear(); + pr.clear(); + vr.clear(); + vzp.clear(); + } + + void resize(const size_type& new_size) + { + feg.resize(new_size); + fxg.resize(new_size); + pr.resize(new_size); + vr.resize(new_size); + vzp.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + feg.resize(new_size, value); + fxg.resize(new_size, value); + pr.resize(new_size, value); + vr.resize(new_size, value); + vzp.resize(new_size, value); + } + + void shrink_to_fit() + { + feg.shrink_to_fit(); + fxg.shrink_to_fit(); + pr.shrink_to_fit(); + vr.shrink_to_fit(); + vzp.shrink_to_fit(); + } + + T Z_diff() + { + return T(Z - charge); + } + }; + + template + using Atomic_Coef_cpu = Atomic_Coef; + + template + using Atomic_Coef_gpu = Atomic_Coef; + + /*************************** atomic info *****************************/ + template + class Atomic_Info + { + public: + using value_type = T; + using size_type = dt_int32; + + std::string name; // atom name + dt_int32 Z; // atomic number + dt_int32 A; // mass number + T m; // atomic mass + T rn; // experimental nuclear radius (Angs.) + T ra; // experimental atomic radius (Angs.) + + mutable Vctr_cpu eels_maj_edg; // major eels edges + mutable Vctr_cpu eels_min_edg; // minor eels edges + mutable Vctr_cpu> coef; // atomic coefficients + + /************************************* constructors ************************************/ + Atomic_Info(): name(""), Z(0), A(0), m(0), rn(0), ra(0){} + + Atomic_Info(const std::string& name, const dt_int32& Z, const dt_int32& A, const T& m, + const T& rn, const T& ra): name(name), Z(Z), A(A), m(m), rn(rn), ra(ra) {} + + Atomic_Info(const std::string& name, const dt_int32& Z, const dt_int32& A, const T& m, + const T& rn, const T& ra, const dt_init_list_f64& eels_maj_edg, const dt_init_list_f64& eels_min_edg): Atomic_Info(name, Z, A, m, rn, ra) + { + this->eels_maj_edg.assign(eels_maj_edg.begin(), eels_maj_edg.end()); + this->eels_min_edg.assign(eels_min_edg.begin(), eels_min_edg.end()); + } + + /* copy constructor */ + Atomic_Info(const Atomic_Info& atomic_info) + { + *this = atomic_info; + } + + /* converting constructor */ + template + Atomic_Info(const Atomic_Info& atomic_info) + { + *this = atomic_info; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Atomic_Info& operator=(const Atomic_Info& atomic_info) + { + if (this != &atomic_info) + { + this->assign(atomic_info); + } + + return *this; + } + + /* converting assignment operator */ + template + Atomic_Info& operator=(const Atomic_Info& atomic_info) + { + this->assign(atomic_info); + + return *this; + } + + template + void assign(const Atomic_Info& atomic_info) + { + name = atomic_info.name; + Z = atomic_info.Z; + A = atomic_info.A; + m = T(atomic_info.m); + rn = T(atomic_info.rn); + ra = T(atomic_info.ra); + + eels_maj_edg.assign(atomic_info.eels_maj_edg); + eels_min_edg.assign(atomic_info.eels_min_edg); + + coef.resize(atomic_info.coef.size()); + for(auto ik = 0; ik < atomic_info.coef.size(); ik++) + { + coef[ik].assign(atomic_info.coef[ik]); + } + + } + + template + void add_atomic_coef(const Atomic_Coef_cpu& atomic_coef) + { + if (atomic_coef.size()==0) + { + return; + } + coef.resize(coef.size()+1); + coef.back() = atomic_coef; + } + + T Z_r() + { + return T(Z); + } + + int mass_number() const + { + return A; + } + + T atomic_mass() const + { + return m; + } + + T nuclear_radius() const + { + return rn; + } + + T atomic_radius() const + { + return ra; + } + + T nuclear_radius_cal() const + { + return 1.2e-05*pow(T(A), T(1.0/3.0)); + } + }; + + template + using Atomic_Info_cpu = Atomic_Info; + + template + using Atomic_Info_gpu = Atomic_Info; + + /**************************** atomic data ****************************/ + class Atomic_Data{ + public: + using T = double; + using value_type = T; + using size_type = dt_int32; + static const eDev device = edev_cpu; + + Atomic_Data() {} + + Atomic_Data(const dt_int32& Z) + { + atomic_info = operator()(Z); + } + + Atomic_Data(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, dt_int32 charge=0) + { + atomic_info = operator()(Z, atomic_pot_parm_typ, charge); + } + + Atomic_Data(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const Vctr_int32_cpu& charge) + { + atomic_info = operator()(Z, atomic_pot_parm_typ, charge); + } + + // conversion operator + operator Atomic_Info_cpu() const + { + return atomic_info; + } + + // conversion operator + operator Atomic_Info_cpu() const + { + return atomic_info; + } + + // get atomic info + Atomic_Info_cpu operator()(const dt_int32& Z) + { + return operator()(Z, eappt_lobato_0_12); + } + + // get atomic info + Atomic_Info_cpu operator()(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, dt_int32 charge=0) + { + auto atomic_info = load_atomic_info_1(Z); + + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_doyle_neutral_0_4(Z)); + } + break; + case eappt_peng_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_4(Z)); + } + break; + case eappt_peng_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_12(Z)); + } + break; + case eappt_kirkland_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_kirkland_neutral_0_12(Z)); + } + break; + case eappt_weickenmeier_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_weickenmeier_neutral_0_12(Z)); + } + break; + case eappt_lobato_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_lobato_neutral_0_12(Z)); + } + break; + case eappt_peng_ion_0_4: + { + auto atomic_coef = atomic_coef_peng_ion_0_4(Z, charge); + + if (atomic_coef.size()==0) + { + atomic_coef = atomic_coef_peng_neutral_0_4(Z); + } + + atomic_info.add_atomic_coef(atomic_coef); + } + break; + } + + return atomic_info; + } + + // get atomic info + Atomic_Info_cpu operator()(const dt_int32& Z, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const Vctr_int32_cpu& charge) + { + auto atomic_info = load_atomic_info_1(Z); + + for(auto ik=0; ik < charge.size(); ik++) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_doyle_neutral_0_4(Z)); + } + break; + case eappt_peng_0_4: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_4(Z)); + } + break; + case eappt_peng_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_peng_neutral_0_12(Z)); + } + break; + case eappt_kirkland_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_kirkland_neutral_0_12(Z)); + } + break; + case eappt_weickenmeier_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_weickenmeier_neutral_0_12(Z)); + } + break; + case eappt_lobato_0_12: + { + atomic_info.add_atomic_coef(atomic_coef_lobato_neutral_0_12(Z)); + } + break; + case eappt_peng_ion_0_4: + { + auto atomic_coef = atomic_coef_peng_ion_0_4(Z, charge[ik]); + + if (atomic_coef.size()==0) + { + atomic_coef = atomic_coef_peng_neutral_0_4(Z); + } + + atomic_info.add_atomic_coef(atomic_coef); + } + break; + } + } + + return atomic_info; + } + + private: + Atomic_Info_cpu atomic_info; + + /***************************************************************************************/ + // load atomic info + Atomic_Info_cpu load_atomic_info_1(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {"H", 1, 1, 1.0080e+00, 8.7770e-06, 7.9000e-01, {13.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 2: + return {"He", 2, 4, 4.0026e+00, 1.6753e-05, 4.9000e-01, {22.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 3: + return {"Li", 3, 7, 6.9410e+00, 2.4173e-05, 2.0500e+00, {55.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 4: + return {"Be", 4, 9, 9.0122e+00, 2.5180e-05, 1.4000e+00, {111.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 5: + return {"B", 5, 11, 1.0811e+01, 2.4060e-05, 1.1700e+00, {188.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 6: + return {"C", 6, 12, 1.2011e+01, 2.4702e-05, 9.1000e-01, {284.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 7: + return {"N", 7, 14, 1.4007e+01, 2.5582e-05, 7.5000e-01, {401.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 8: + return {"O", 8, 16, 1.5999e+01, 2.6991e-05, 6.5000e-01, {532.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 9: + return {"F", 9, 19, 1.8998e+01, 2.8976e-05, 5.7000e-01, {685.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 10: + return {"Ne", 10, 20, 2.0180e+01, 3.0058e-05, 5.1000e-01, {867.00, 18.00, 0.00, 0.00, 0.00}, {45.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 11: + return {"Na", 11, 23, 2.2990e+01, 2.9935e-05, 2.2300e+00, {1072.00, 31.00, 0.00, 0.00, 0.00}, {63.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 12: + return {"Mg", 12, 24, 2.4305e+01, 3.0570e-05, 1.7200e+00, {1305.00, 51.00, 0.00, 0.00, 0.00}, {89.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 13: + return {"Al", 13, 27, 2.6982e+01, 3.0610e-05, 1.6200e+00, {1560.00, 73.00, 0.00, 0.00, 0.00}, {118.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 14: + return {"Si", 14, 28, 2.8085e+01, 3.1224e-05, 1.4400e+00, {1839.00, 99.00, 0.00, 0.00, 0.00}, {149.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 15: + return {"P", 15, 31, 3.0974e+01, 3.1889e-05, 1.2300e+00, {2146.00, 132.00, 0.00, 0.00, 0.00}, {189.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 16: + return {"S", 16, 32, 3.2066e+01, 3.2847e-05, 1.0900e+00, {2472.00, 165.00, 0.00, 0.00, 0.00}, {229.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 17: + return {"Cl", 17, 35, 3.5453e+01, 3.3654e-05, 9.7000e-01, {2822.00, 200.00, 0.00, 0.00, 0.00}, {270.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 18: + return {"Ar", 18, 40, 3.9948e+01, 3.4276e-05, 8.8000e-01, {3203.00, 245.00, 12.00, 0.00, 0.00}, {320.00, 25.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 19: + return {"K", 19, 39, 3.9098e+01, 3.4350e-05, 2.7700e+00, {3607.00, 296.00, 294.00, 18.00, 0.00}, {377.00, 34.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 20: + return {"Ca", 20, 40, 4.0078e+01, 3.4777e-05, 2.2300e+00, {4038.00, 350.00, 346.00, 25.00, 0.00}, {438.00, 44.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 21: + return {"Sc", 21, 45, 4.4956e+01, 3.5460e-05, 2.0900e+00, {4493.00, 407.00, 402.00, 32.00, 0.00}, {500.00, 54.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 22: + return {"Ti", 22, 48, 4.7880e+01, 3.5922e-05, 2.0000e+00, {4966.00, 462.00, 456.00, 35.00, 0.00}, {564.00, 60.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 23: + return {"V", 23, 51, 5.0941e+01, 3.6002e-05, 1.9200e+00, {521.00, 513.00, 38.00, 0.00, 0.00}, {628.00, 66.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 24: + return {"Cr", 24, 52, 5.1996e+01, 3.6452e-05, 1.8500e+00, {584.00, 575.00, 42.00, 0.00, 0.00}, {695.00, 74.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 25: + return {"Mn", 25, 55, 5.4938e+01, 3.7057e-05, 1.7900e+00, {651.00, 640.00, 49.00, 0.00, 0.00}, {769.00, 84.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 26: + return {"Fe", 26, 56, 5.5847e+01, 3.7384e-05, 1.7200e+00, {721.00, 708.00, 54.00, 0.00, 0.00}, {846.00, 93.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 27: + return {"Co", 27, 59, 5.8933e+01, 3.7875e-05, 1.6700e+00, {794.00, 779.00, 60.00, 0.00, 0.00}, {926.00, 101.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 28: + return {"Ni", 28, 58, 5.8693e+01, 3.7757e-05, 1.6200e+00, {872.00, 855.00, 68.00, 0.00, 0.00}, {1008.00, 112.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 29: + return {"Cu", 29, 63, 6.3456e+01, 3.8823e-05, 1.5700e+00, {951.00, 931.00, 74.00, 0.00, 0.00}, {1096.00, 120.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 30: + return {"Zn", 30, 64, 6.5390e+01, 3.9279e-05, 1.5300e+00, {1043.00, 1020.00, 0.00, 0.00, 0.00}, {1194.00, 136.00, 87.00, 0.00, 0.00, 0.00, 0.00}}; + case 31: + return {"Ga", 31, 69, 6.9723e+01, 3.9973e-05, 1.8100e+00, {1142.00, 1115.00, 0.00, 0.00, 0.00}, {1298.00, 158.00, 103.00, 0.00, 0.00, 0.00, 0.00}}; + case 32: + return {"Ge", 32, 74, 7.2610e+01, 4.0742e-05, 1.5200e+00, {1248.00, 1217.00, 29.00, 0.00, 0.00}, {1414.00, 180.00, 121.00, 0.00, 0.00, 0.00, 0.00}}; + case 33: + return {"As", 33, 75, 7.4922e+01, 4.0968e-05, 1.3300e+00, {1359.00, 1323.00, 41.00, 0.00, 0.00}, {1526.00, 203.00, 140.00, 0.00, 0.00, 0.00, 0.00}}; + case 34: + return {"Se", 34, 80, 7.8960e+01, 4.1400e-05, 1.2200e+00, {1476.00, 1436.00, 57.00, 0.00, 0.00}, {1654.00, 231.00, 162.00, 0.00, 0.00, 0.00, 0.00}}; + case 35: + return {"Br", 35, 79, 7.9904e+01, 4.1629e-05, 1.1200e+00, {1596.00, 1150.00, 69.00, 0.00, 0.00}, {1782.00, 256.00, 181.00, 0.00, 0.00, 0.00, 0.00}}; + case 36: + return {"Kr", 36, 84, 8.3800e+01, 4.1883e-05, 1.0300e+00, {1727.00, 1675.00, 89.00, 11.00, 0.00}, {1921.00, 289.00, 214.00, 24.00, 0.00, 0.00, 0.00}}; + case 37: + return {"Rb", 37, 85, 8.5468e+01, 4.2037e-05, 2.9800e+00, {1864.00, 1804.00, 110.00, 14.00, 0.00}, {2065.00, 322.00, 247.00, 238.00, 29.00, 0.00, 0.00}}; + case 38: + return {"Sr", 38, 88, 8.7620e+01, 4.2246e-05, 2.4500e+00, {2007.00, 1940.00, 133.00, 20.00, 0.00}, {2216.00, 357.00, 280.00, 269.00, 38.00, 0.00, 0.00}}; + case 39: + return {"Y", 39, 89, 8.8906e+01, 4.2438e-05, 2.2700e+00, {2155.00, 2080.00, 157.00, 26.00, 0.00}, {2372.00, 394.00, 312.00, 300.00, 45.00, 0.00, 0.00}}; + case 40: + return {"Zr", 40, 90, 9.1224e+01, 4.2690e-05, 2.1600e+00, {2307.00, 2222.00, 180.00, 29.00, 0.00}, {2532.00, 430.00, 344.00, 330.00, 51.00, 0.00, 0.00}}; + case 41: + return {"Nb", 41, 93, 9.2906e+01, 4.3240e-05, 2.0800e+00, {2465.00, 2371.00, 205.00, 34.00, 0.00}, {2698.00, 468.00, 378.00, 363.00, 58.00, 0.00, 0.00}}; + case 42: + return {"Mo", 42, 98, 9.5940e+01, 4.4090e-05, 2.0100e+00, {2625.00, 2520.00, 227.00, 35.00, 0.00}, {2865.00, 505.00, 410.00, 392.00, 62.00, 0.00, 0.00}}; + case 43: + return {"Tc", 43, 98, 9.8000e+01, 4.4130e-05, 1.9500e+00, {2793.00, 2677.00, 253.00, 39.00, 0.00}, {3042.00, 544.00, 445.00, 425.00, 68.00, 0.00, 0.00}}; + case 44: + return {"Ru", 44, 102, 1.0107e+02, 4.4811e-05, 1.8900e+00, {2967.00, 2838.00, 279.00, 43.00, 0.00}, {3224.00, 585.00, 483.00, 461.00, 75.00, 0.00, 0.00}}; + case 45: + return {"Rh", 45, 103, 1.0291e+02, 4.4945e-05, 1.8300e+00, {3146.00, 3004.00, 307.00, 48.00, 0.00}, {3412.00, 627.00, 521.00, 496.00, 81.00, 0.00, 0.00}}; + case 46: + return {"Pd", 46, 106, 1.0642e+02, 4.5324e-05, 1.7900e+00, {3330.00, 3173.00, 335.00, 51.00, 0.00}, {3604.00, 670.00, 559.00, 531.00, 86.00, 0.00, 0.00}}; + case 47: + return {"Ag", 47, 107, 1.0787e+02, 4.5464e-05, 1.7500e+00, {3524.00, 3351.00, 367.00, 0.00, 0.00}, {3806.00, 717.00, 602.00, 571.00, 95.00, 56.00, 0.00}}; + case 48: + return {"Cd", 48, 114, 1.1241e+02, 4.6068e-05, 1.7100e+00, {3727.00, 3538.00, 404.00, 0.00, 0.00}, {4018.00, 770.00, 651.00, 616.00, 108.00, 67.00, 0.00}}; + case 49: + return {"In", 49, 115, 1.1482e+02, 4.6155e-05, 2.0000e+00, {3938.00, 3730.00, 443.00, 0.00, 0.00}, {4237.00, 826.00, 702.00, 664.00, 122.00, 77.00, 0.00}}; + case 50: + return {"Sn", 50, 120, 1.1871e+02, 4.6525e-05, 1.7200e+00, {4156.00, 3929.00, 485.00, 24.00, 0.00}, {4465.00, 884.00, 756.00, 714.00, 136.00, 89.00, 0.00}}; + case 51: + return {"Sb", 51, 121, 1.2176e+02, 4.6802e-05, 1.5300e+00, {4380.00, 4132.00, 528.00, 31.00, 0.00}, {944.00, 812.00, 766.00, 152.00, 98.00, 0.00, 0.00}}; + case 52: + return {"Te", 52, 130, 1.2760e+02, 4.7420e-05, 1.4200e+00, {4612.00, 4341.00, 40.00, 572.00, 0.00}, {1006.00, 870.00, 819.00, 168.00, 110.00, 0.00, 0.00}}; + case 53: + return {"I", 53, 127, 1.2690e+02, 4.7500e-05, 1.3200e+00, {4852.00, 4557.00, 619.00, 50.00, 0.00}, {1072.00, 930.00, 875.00, 186.00, 123.00, 0.00, 0.00}}; + case 54: + return {"Xe", 54, 132, 1.3129e+02, 4.7850e-05, 1.2400e+00, {4782.00, 672.00, 63.00, 0.00, 0.00}, {1145.00, 999.00, 937.00, 208.00, 147.00, 0.00, 0.00}}; + case 55: + return {"Cs", 55, 133, 1.3291e+02, 4.8040e-05, 3.3400e+00, {740.00, 726.00, 76.00, 0.00, 0.00}, {1217.00, 1065.00, 998.00, 231.00, 162.00, 0.00, 0.00}}; + case 56: + return {"Ba", 56, 138, 1.3733e+02, 4.8370e-05, 2.7600e+00, {796.00, 781.00, 90.00, 15.00, 0.00}, {1293.00, 1137.00, 1062.00, 253.00, 180.00, 0.00, 0.00}}; + case 57: + return {"La", 57, 139, 1.3891e+02, 4.8549e-05, 2.7400e+00, {849.00, 832.00, 99.00, 14.00, 0.00}, {1361.00, 1204.00, 1123.00, 270.00, 191.00, 0.00, 0.00}}; + case 58: + return {"Ce", 58, 140, 1.4012e+02, 4.8773e-05, 2.7000e+00, {901.00, 883.00, 110.00, 20.00, 0.00}, {1435.00, 1273.00, 1185.00, 290.00, 207.00, 0.00, 0.00}}; + case 59: + return {"Pr", 59, 141, 1.4091e+02, 4.8919e-05, 2.6700e+00, {951.00, 931.00, 113.00, 22.00, 0.00}, {1511.00, 1337.00, 1242.00, 305.00, 218.00, 0.00, 0.00}}; + case 60: + return {"Nd", 60, 142, 1.4424e+02, 4.9115e-05, 2.6400e+00, {1000.00, 978.00, 118.00, 21.00, 0.00}, {1575.00, 1403.00, 1297.00, 315.00, 225.00, 0.00, 0.00}}; + case 61: + return {"Pm", 61, 145, 1.4500e+02, 4.9530e-05, 2.6200e+00, {1052.00, 1027.00, 120.00, 24.00, 0.00}, {1649.00, 1471.00, 1357.00, 331.00, 236.00, 0.00, 0.00}}; + case 62: + return {"Sm", 62, 152, 1.5036e+02, 5.0823e-05, 2.5900e+00, {1106.00, 1080.00, 129.00, 21.00, 0.00}, {1723.00, 1541.00, 1420.00, 346.00, 247.00, 0.00, 0.00}}; + case 63: + return {"Eu", 63, 153, 1.5197e+02, 5.1093e-05, 2.5600e+00, {1161.00, 1131.00, 133.00, 22.00, 0.00}, {1800.00, 1614.00, 1481.00, 360.00, 257.00, 0.00, 0.00}}; + case 64: + return {"Gd", 64, 158, 1.5725e+02, 5.1578e-05, 2.5400e+00, {1217.00, 1185.00, 140.00, 20.00, 0.00}, {1881.00, 1688.00, 1544.00, 376.00, 271.00, 0.00, 0.00}}; + case 65: + return {"Tb", 65, 159, 1.5893e+02, 5.0600e-05, 2.5100e+00, {1275.00, 1241.00, 147.00, 25.00, 0.00}, {1967.00, 1768.00, 1611.00, 398.00, 285.00, 0.00, 0.00}}; + case 66: + return {"Dy", 66, 164, 1.6250e+02, 5.2240e-05, 2.4900e+00, {1332.00, 1295.00, 154.00, 26.00, 0.00}, {2047.00, 1842.00, 1676.00, 416.00, 293.00, 0.00, 0.00}}; + case 67: + return {"Ho", 67, 165, 1.6493e+02, 5.2022e-05, 2.4700e+00, {1391.00, 1351.00, 161.00, 20.00, 0.00}, {2128.00, 1923.00, 1741.00, 436.00, 307.00, 51.00, 0.00}}; + case 68: + return {"Er", 68, 166, 1.6726e+02, 5.2527e-05, 2.4500e+00, {1453.00, 1409.00, 168.00, 29.00, 0.00}, {2206.00, 2006.00, 1812.00, 449.00, 320.00, 60.00, 0.00}}; + case 69: + return {"Tm", 69, 169, 1.6893e+02, 5.2256e-05, 2.4200e+00, {1515.00, 1468.00, 180.00, 32.00, 0.00}, {2307.00, 2090.00, 1884.00, 472.00, 337.00, 53.00, 0.00}}; + case 70: + return {"Yb", 70, 174, 1.7304e+02, 5.3105e-05, 2.4000e+00, {1576.00, 1528.00, 185.00, 24.00, 0.00}, {2398.00, 2173.00, 1950.00, 487.00, 343.00, 54.00, 0.00}}; + case 71: + return {"Lu", 71, 175, 1.7497e+02, 5.3700e-05, 2.2500e+00, {1639.00, 1588.00, 195.00, 28.00, 0.00}, {2491.00, 2263.00, 2024.00, 506.00, 359.00, 57.00, 0.00}}; + case 72: + return {"Hf", 72, 180, 1.7849e+02, 5.3482e-05, 2.1600e+00, {1716.00, 1662.00, 31.00, 0.00, 0.00}, {2601.00, 2365.00, 2108.00, 538.00, 380.00, 214.00, 65.00}}; + case 73: + return {"Ta", 73, 181, 1.8095e+02, 5.3507e-05, 2.0900e+00, {1793.00, 1735.00, 36.00, 0.00, 0.00}, {2708.00, 2469.00, 2194.00, 565.00, 404.00, 229.00, 71.00}}; + case 74: + return {"W", 74, 184, 1.8385e+02, 5.3646e-05, 2.0200e+00, {1872.00, 1809.00, 36.00, 0.00, 0.00}, {2820.00, 2575.00, 2281.00, 595.00, 425.00, 245.00, 77.00}}; + case 75: + return {"Re", 75, 187, 1.8621e+02, 5.3697e-05, 1.9700e+00, {1949.00, 1883.00, 35.00, 0.00, 0.00}, {2932.00, 2682.00, 2367.00, 625.00, 444.00, 260.00, 83.00}}; + case 76: + return {"Os", 76, 192, 1.9020e+02, 5.4122e-05, 1.9200e+00, {2031.00, 1960.00, 45.00, 0.00, 0.00}, {2792.00, 2457.00, 654.00, 468.00, 273.00, 46.00, 84.00}}; + case 77: + return {"Ir", 77, 193, 1.9222e+02, 5.4020e-05, 1.8700e+00, {2116.00, 2040.00, 50.00, 0.00, 0.00}, {2909.00, 2551.00, 690.00, 494.00, 295.00, 60.00, 95.00}}; + case 78: + return {"Pt", 78, 195, 1.9508e+02, 5.4250e-05, 1.8300e+00, {2202.00, 2122.00, 52.00, 0.00, 0.00}, {3026.00, 2645.00, 722.00, 519.00, 313.00, 102.00, 71.00}}; + case 79: + return {"Au", 79, 197, 1.9697e+02, 5.4379e-05, 1.7900e+00, {2291.00, 2206.00, 54.00, 0.00, 0.00}, {3148.00, 2743.00, 759.00, 545.00, 334.00, 108.00, 83.00}}; + case 80: + return {"Hg", 80, 202, 2.0059e+02, 5.4637e-05, 1.7600e+00, {2385.00, 2295.00, 58.00, 0.00, 0.00}, {3278.00, 2847.00, 800.00, 571.00, 360.00, 120.00, 98.00}}; + case 81: + return {"Tl", 81, 205, 2.0438e+02, 5.4757e-05, 2.0800e+00, {2485.00, 2389.00, 75.00, 0.00, 0.00}, {3416.00, 2957.00, 845.00, 609.00, 386.00, 136.00, 118.00}}; + case 82: + return {"Pb", 82, 208, 2.0720e+02, 5.5010e-05, 1.8100e+00, {2586.00, 2484.00, 86.00, 19.00, 0.00}, {3554.00, 3066.00, 894.00, 644.00, 413.00, 147.00, 138.00}}; + case 83: + return {"Bi", 83, 209, 2.0898e+02, 5.5210e-05, 1.6300e+00, {2688.00, 2580.00, 93.00, 24.00, 0.00}, {3696.00, 3177.00, 938.00, 679.00, 440.00, 159.00, 157.00}}; + case 84: + return {"Po", 84, 209, 2.0900e+02, 5.5262e-05, 1.5300e+00, {3491.00, 3332.00, 0.00, 0.00, 0.00}, {4046.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 85: + return {"At", 85, 210, 2.1000e+02, 5.5310e-05, 1.4300e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 86: + return {"Rn", 86, 222, 2.2200e+02, 5.6547e-05, 1.3400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 87: + return {"Fr", 87, 223, 2.2300e+02, 5.6584e-05, 2.7000e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 88: + return {"Ra", 88, 226, 2.2603e+02, 5.6840e-05, 2.2300e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 89: + return {"Ac", 89, 227, 2.2700e+02, 5.7120e-05, 1.8800e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 90: + return {"Th", 90, 232, 2.3204e+02, 5.7800e-05, 1.8000e+00, {3491.00, 3332.00, 344.00, 335.00, 88.00}, {4046.00, 1329.00, 967.00, 714.00, 676.00, 290.00, 182.00}}; + case 91: + return {"Pa", 91, 231, 2.3104e+02, 5.7660e-05, 1.6100e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 92: + return {"U", 92, 238, 2.3803e+02, 5.8571e-05, 1.3800e+00, {3728.00, 3552.00, 391.00, 381.00, 96.00}, {4303.00, 1441.00, 1045.00, 780.00, 738.00, 324.00, 195.00}}; + case 93: + return {"Np", 93, 237, 2.3705e+02, 5.8410e-05, 1.3000e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 94: + return {"Pu", 94, 244, 2.4400e+02, 5.8948e-05, 1.5100e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 95: + return {"Am", 95, 243, 2.4300e+02, 5.9042e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 96: + return {"Cm", 96, 247, 2.4700e+02, 5.9630e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 97: + return {"Bk", 97, 247, 2.4700e+02, 5.9300e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 98: + return {"Cf", 98, 251, 2.5100e+02, 6.0200e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 99: + return {"Es", 99, 252, 2.5200e+02, 6.0340e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 100: + return {"Fm", 100, 257, 2.5700e+02, 6.1070e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 101: + return {"Md", 101, 258, 2.5800e+02, 6.1220e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 102: + return {"No", 102, 259, 2.5900e+02, 6.1370e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + case 103: + return {"Lr", 103, 262, 2.6000e+02, 6.1820e-05, 1.8400e+00, {0.00, 0.00, 0.00, 0.00, 0.00}, {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + } + return {}; + } + + // 1: doyle and Turner parameterization - 4 Gaussians - [0, 4] + LNL_Coef_cpu load_feg_doyle_neutral_0_4(const dt_int32& Z) + { + switch(Z) + { + case 2: + return {{9.0600e-02, 1.8140e-01, 1.0950e-01, 3.6200e-02}, {1.8183e+01, 6.2109e+00, 1.8026e+00, 2.8440e-01}}; + case 3: + return {{1.6108e+00, 1.2460e+00, 3.2570e-01, 9.8600e-02}, {1.0764e+02, 3.0480e+01, 4.5331e+00, 4.9510e-01}}; + case 4: + return {{1.2498e+00, 1.3335e+00, 3.6030e-01, 1.0550e-01}, {6.0804e+01, 1.8591e+01, 3.6534e+00, 4.1570e-01}}; + case 5: + return {{9.4460e-01, 1.3120e+00, 4.1880e-01, 1.1590e-01}, {4.6444e+01, 1.4178e+01, 3.2228e+00, 3.7670e-01}}; + case 6: + return {{7.3070e-01, 1.1951e+00, 4.5630e-01, 1.2470e-01}, {3.6995e+01, 1.1297e+01, 2.8139e+00, 3.4560e-01}}; + case 7: + return {{5.7170e-01, 1.0425e+00, 4.6470e-01, 1.3110e-01}, {2.8846e+01, 9.0542e+00, 2.4213e+00, 3.1670e-01}}; + case 8: + return {{4.5400e-01, 9.1730e-01, 4.7190e-01, 1.3840e-01}, {2.3780e+01, 7.6220e+00, 2.1440e+00, 2.9590e-01}}; + case 9: + return {{3.6860e-01, 8.1090e-01, 4.7510e-01, 1.4590e-01}, {2.0239e+01, 6.6093e+00, 1.9310e+00, 2.7930e-01}}; + case 10: + return {{3.0250e-01, 7.2020e-01, 4.7510e-01, 1.5340e-01}, {1.7639e+01, 5.8604e+00, 1.7623e+00, 2.6560e-01}}; + case 11: + return {{2.2406e+00, 1.3326e+00, 9.0700e-01, 2.8630e-01}, {1.0800e+02, 2.4505e+01, 3.3914e+00, 4.3460e-01}}; + case 12: + return {{2.2692e+00, 1.8025e+00, 8.3940e-01, 2.8920e-01}, {7.3670e+01, 2.0175e+01, 3.0131e+00, 4.0460e-01}}; + case 13: + return {{2.2756e+00, 2.4280e+00, 8.5780e-01, 3.2660e-01}, {7.2322e+01, 1.9773e+01, 3.0799e+00, 4.0760e-01}}; + case 14: + return {{2.1293e+00, 2.5333e+00, 8.3490e-01, 3.2160e-01}, {5.7775e+01, 1.6476e+01, 2.6796e+00, 3.8600e-01}}; + case 15: + return {{1.8882e+00, 2.4685e+00, 8.0460e-01, 3.2040e-01}, {4.4876e+01, 1.3538e+01, 2.6424e+00, 3.6030e-01}}; + case 16: + return {{1.6591e+00, 2.3863e+00, 7.8990e-01, 3.2080e-01}, {3.6650e+01, 1.1488e+01, 2.4686e+00, 3.4030e-01}}; + case 17: + return {{1.4524e+00, 2.2926e+00, 7.8740e-01, 3.2170e-01}, {3.0935e+01, 9.9798e+00, 2.3336e+00, 3.2280e-01}}; + case 18: + return {{1.2736e+00, 2.1894e+00, 7.9270e-01, 3.2250e-01}, {2.6682e+01, 8.8130e+00, 2.2186e+00, 3.0710e-01}}; + case 19: + return {{3.9507e+00, 2.5452e+00, 1.9795e+00, 4.0170e-01}, {1.3707e+02, 2.2402e+01, 4.5319e+00, 4.3400e-01}}; + case 20: + return {{4.4696e+00, 2.9703e+00, 1.9696e+00, 4.8180e-01}, {9.9523e+01, 2.2696e+01, 4.1954e+00, 4.1650e-01}}; + case 21: + return {{3.9659e+00, 2.9169e+00, 1.9254e+00, 4.8020e-01}, {3.8960e+01, 2.0606e+01, 3.8557e+00, 3.9880e-01}}; + case 22: + return {{3.5653e+00, 2.8181e+00, 1.8930e+00, 4.8250e-01}, {8.1982e+01, 1.9049e+01, 3.5904e+00, 3.8550e-01}}; + case 23: + return {{3.2449e+00, 2.6978e+00, 1.8597e+00, 4.8640e-01}, {7.6379e+01, 1.7726e+01, 3.3632e+00, 3.7430e-01}}; + case 24: + return {{2.3066e+00, 2.3339e+00, 1.8226e+00, 4.9010e-01}, {7.8405e+01, 1.5785e+01, 3.1566e+00, 3.6360e-01}}; + case 25: + return {{2.7467e+00, 2.4556e+00, 1.7923e+00, 4.9840e-01}, {6.7786e+01, 1.5674e+01, 2.9998e+00, 3.5690e-01}}; + case 26: + return {{2.5440e+00, 2.3434e+00, 1.7588e+00, 5.0620e-01}, {6.4424e+01, 1.4531e+01, 2.8539e+00, 3.5020e-01}}; + case 27: + return {{2.3668e+00, 2.2361e+00, 1.7243e+00, 5.1480e-01}, {6.1431e+01, 1.4179e+01, 2.7247e+00, 3.4420e-01}}; + case 28: + return {{2.2104e+00, 2.1342e+00, 1.6891e+00, 5.2380e-01}, {5.8727e+01, 1.3553e+01, 2.6094e+00, 3.3880e-01}}; + case 29: + return {{1.5792e+00, 1.8197e+00, 1.6576e+00, 5.3230e-01}, {6.2940e+01, 1.2453e+01, 2.5042e+00, 3.3310e-01}}; + case 30: + return {{1.9418e+00, 1.9501e+00, 1.6192e+00, 5.4340e-01}, {5.4162e+01, 1.2518e+01, 2.4164e+00, 3.2950e-01}}; + case 31: + return {{2.3205e+00, 2.4955e+00, 1.6879e+00, 5.9920e-01}, {6.5602e+01, 1.5458e+01, 2.5806e+00, 3.5100e-01}}; + case 32: + return {{2.4467e+00, 2.7015e+00, 1.6157e+00, 6.0090e-01}, {5.5893e+01, 1.4393e+01, 2.4461e+00, 3.4150e-01}}; + case 33: + return {{2.3989e+00, 2.7898e+00, 1.5288e+00, 5.9360e-01}, {4.5718e+01, 3.2817e+01, 2.2799e+00, 3.2770e-01}}; + case 34: + return {{2.2980e+00, 2.8541e+00, 1.4555e+00, 5.8950e-01}, {3.8830e+01, 1.1536e+01, 2.1463e+00, 3.1630e-01}}; + case 35: + return {{2.1659e+00, 2.9037e+00, 1.3951e+00, 5.8860e-01}, {3.3899e+01, 1.0500e+01, 2.0413e+00, 3.0700e-01}}; + case 36: + return {{2.0338e+00, 2.9271e+00, 1.3425e+00, 5.8880e-01}, {2.9999e+01, 9.5977e+00, 1.9520e+00, 2.9860e-01}}; + case 37: + return {{4.7760e+00, 3.8588e+00, 2.2339e+00, 8.6830e-01}, {1.4078e+02, 1.8991e+01, 3.7010e+00, 4.1940e-01}}; + case 38: + return {{5.8478e+00, 4.0026e+00, 2.3420e+00, 8.7950e-01}, {1.0497e+02, 1.9367e+01, 3.7368e+00, 4.1420e-01}}; + case 42: + return {{3.1199e+00, 3.9061e+00, 2.3615e+00, 8.5040e-01}, {7.2464e+01, 1.4642e+01, 3.2370e+00, 3.6620e-01}}; + case 47: + return {{2.0355e+00, 3.2716e+00, 2.5105e+00, 8.3720e-01}, {6.1497e+01, 1.1324e+01, 2.8456e+00, 3.2710e-01}}; + case 48: + return {{2.5737e+00, 3.2536e+00, 2.5468e+00, 8.3790e-01}, {5.5675e+01, 1.1838e+01, 2.7842e+00, 3.2170e-01}}; + case 49: + return {{3.1528e+00, 3.5565e+00, 2.8180e+00, 8.8420e-01}, {6.6649e+01, 1.4449e+01, 2.9758e+00, 3.3450e-01}}; + case 50: + return {{3.4495e+00, 3.7349e+00, 2.7779e+00, 8.7860e-01}, {5.9104e+01, 1.4179e+01, 2.8548e+00, 3.2700e-01}}; + case 51: + return {{3.5644e+00, 3.8437e+00, 2.6366e+00, 8.6380e-01}, {5.0487e+01, 1.3316e+01, 2.6909e+00, 3.1610e-01}}; + case 53: + return {{3.4728e+00, 4.0602e+00, 2.5215e+00, 8.3980e-01}, {3.9441e+01, 1.1816e+01, 2.4148e+00, 2.9760e-01}}; + case 54: + return {{3.3656e+00, 4.1468e+00, 2.4430e+00, 8.2930e-01}, {3.5509e+01, 1.1117e+01, 2.2940e+00, 2.8920e-01}}; + case 55: + return {{6.0620e+00, 5.9861e+00, 3.3033e+00, 1.0958e+00}, {1.5583e+02, 1.9695e+01, 3.3354e+00, 3.7930e-01}}; + case 56: + return {{7.8212e+00, 6.0040e+00, 3.2803e+00, 1.1030e+00}, {1.1766e+02, 1.8778e+01, 3.2634e+00, 3.7600e-01}}; + case 57: + return {{6.2661e+00, 4.8440e+00, 3.2023e+00, 1.2009e+00}, {1.0030e+02, 1.6066e+01, 2.9803e+00, 3.6740e-01}}; + case 79: + return {{2.3880e+00, 4.2259e+00, 2.6886e+00, 1.2551e+00}, {4.2866e+01, 9.7430e+00, 2.2641e+00, 3.0670e-01}}; + case 80: + return {{2.6817e+00, 4.2414e+00, 2.7549e+00, 1.2706e+00}, {4.2822e+01, 9.8557e+00, 2.2951e+00, 3.0670e-01}}; + case 82: + return {{3.5099e+00, 4.5523e+00, 3.1539e+00, 1.3591e+00}, {5.2914e+01, 1.1884e+01, 2.5713e+00, 3.2050e-01}}; + case 83: + return {{3.8412e+00, 4.6784e+00, 3.1924e+00, 1.3625e+00}, {5.0261e+01, 1.1999e+01, 2.5598e+00, 3.1770e-01}}; + case 86: + return {{4.0779e+00, 4.9778e+00, 3.0955e+00, 1.3259e+00}, {2.8406e+01, 1.1020e+01, 2.3549e+00, 2.9910e-01}}; + case 92: + return {{6.7668e+00, 6.7287e+00, 4.0135e+00, 1.5607e+00}, {8.5951e+01, 1.5642e+01, 2.9364e+00, 3.3480e-01}}; + } + + return {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}}; + } + + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + LNL_Coef_cpu load_feg_peng_neutral_0_4(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{3.490000e-02, 1.201000e-01, 1.970000e-01, 5.730000e-02, 1.195000e-01}, {5.347000e-01, 3.586700e+00, 1.234710e+01, 1.895250e+01, 3.862690e+01}}; + case 2: + return {{3.170000e-02, 8.380000e-02, 1.526000e-01, 1.334000e-01, 1.640000e-02}, {2.507000e-01, 1.475100e+00, 4.493800e+00, 1.266460e+01, 3.116530e+01}}; + case 3: + return {{7.500000e-02, 2.249000e-01, 5.548000e-01, 1.495400e+00, 9.354000e-01}, {3.864000e-01, 2.938300e+00, 1.538290e+01, 5.355450e+01, 1.387337e+02}}; + case 4: + return {{7.800000e-02, 2.210000e-01, 6.740000e-01, 1.386700e+00, 6.925000e-01}, {3.131000e-01, 2.238100e+00, 1.015170e+01, 3.090610e+01, 7.832730e+01}}; + case 5: + return {{9.090000e-02, 2.551000e-01, 7.738000e-01, 1.213600e+00, 4.606000e-01}, {2.995000e-01, 2.115500e+00, 8.381600e+00, 2.412920e+01, 6.313140e+01}}; + case 6: + return {{8.930000e-02, 2.563000e-01, 7.570000e-01, 1.048700e+00, 3.575000e-01}, {2.465000e-01, 1.710000e+00, 6.409400e+00, 1.861130e+01, 5.025230e+01}}; + case 7: + return {{1.022000e-01, 3.219000e-01, 7.982000e-01, 8.197000e-01, 1.715000e-01}, {2.451000e-01, 1.748100e+00, 6.192500e+00, 1.738940e+01, 4.814310e+01}}; + case 8: + return {{9.740000e-02, 2.921000e-01, 6.910000e-01, 6.990000e-01, 2.039000e-01}, {2.067000e-01, 1.381500e+00, 4.694300e+00, 1.271050e+01, 3.247260e+01}}; + case 9: + return {{1.083000e-01, 3.175000e-01, 6.487000e-01, 5.846000e-01, 1.421000e-01}, {2.057000e-01, 1.343900e+00, 4.278800e+00, 1.139320e+01, 2.878810e+01}}; + case 10: + return {{1.269000e-01, 3.535000e-01, 5.582000e-01, 4.674000e-01, 1.460000e-01}, {2.200000e-01, 1.377900e+00, 4.020300e+00, 9.493400e+00, 2.312780e+01}}; + case 11: + return {{2.142000e-01, 6.853000e-01, 7.692000e-01, 1.658900e+00, 1.448200e+00}, {3.334000e-01, 2.344600e+00, 1.008300e+01, 4.830370e+01, 1.382700e+02}}; + case 12: + return {{2.314000e-01, 6.866000e-01, 9.677000e-01, 2.188200e+00, 1.133900e+00}, {3.278000e-01, 2.272000e+00, 1.092410e+01, 3.928980e+01, 1.019748e+02}}; + case 13: + return {{2.390000e-01, 6.573000e-01, 1.201100e+00, 2.558600e+00, 1.231200e+00}, {3.138000e-01, 2.106300e+00, 1.041630e+01, 3.445520e+01, 9.853440e+01}}; + case 14: + return {{2.519000e-01, 6.372000e-01, 1.379500e+00, 2.508200e+00, 1.050000e+00}, {3.075000e-01, 2.017400e+00, 9.674600e+00, 2.937440e+01, 8.047320e+01}}; + case 15: + return {{2.548000e-01, 6.106000e-01, 1.454100e+00, 2.320400e+00, 8.477000e-01}, {2.908000e-01, 1.874000e+00, 8.517600e+00, 2.434340e+01, 6.329960e+01}}; + case 16: + return {{2.497000e-01, 5.628000e-01, 1.389900e+00, 2.186500e+00, 7.715000e-01}, {2.681000e-01, 1.671100e+00, 7.026700e+00, 1.953770e+01, 5.038880e+01}}; + case 17: + return {{2.443000e-01, 5.397000e-01, 1.391900e+00, 2.019700e+00, 6.621000e-01}, {2.468000e-01, 1.524200e+00, 6.153700e+00, 1.666870e+01, 4.230860e+01}}; + case 18: + return {{2.385000e-01, 5.017000e-01, 1.342800e+00, 1.889900e+00, 6.079000e-01}, {2.289000e-01, 1.369400e+00, 5.256100e+00, 1.409280e+01, 3.553610e+01}}; + case 19: + return {{4.115000e-01, 1.403100e+00, 2.278400e+00, 2.674200e+00, 2.216200e+00}, {3.703000e-01, 3.387400e+00, 1.310290e+01, 6.895920e+01, 1.944329e+02}}; + case 20: + return {{4.054000e-01, 1.388000e+00, 2.160200e+00, 3.753200e+00, 2.206300e+00}, {3.499000e-01, 3.099100e+00, 1.196080e+01, 5.393530e+01, 1.423892e+02}}; + case 21: + return {{3.787000e-01, 1.218100e+00, 2.059400e+00, 3.261800e+00, 2.387000e+00}, {3.133000e-01, 2.585600e+00, 9.581300e+00, 4.176880e+01, 1.167282e+02}}; + case 22: + return {{3.825000e-01, 1.259800e+00, 2.000800e+00, 3.061700e+00, 2.069400e+00}, {3.040000e-01, 2.486300e+00, 9.278300e+00, 3.907510e+01, 1.094583e+02}}; + case 23: + return {{3.876000e-01, 1.275000e+00, 1.910900e+00, 2.831400e+00, 1.897900e+00}, {2.967000e-01, 2.378000e+00, 8.798100e+00, 3.595280e+01, 1.017201e+02}}; + case 24: + return {{4.046000e-01, 1.369600e+00, 1.894100e+00, 2.080000e+00, 1.219600e+00}, {2.986000e-01, 2.395800e+00, 9.140600e+00, 3.747010e+01, 1.137121e+02}}; + case 25: + return {{3.796000e-01, 1.209400e+00, 1.781500e+00, 2.542000e+00, 1.593700e+00}, {2.699000e-01, 2.045500e+00, 7.472600e+00, 3.106040e+01, 9.156220e+01}}; + case 26: + return {{3.946000e-01, 1.272500e+00, 1.703100e+00, 2.314000e+00, 1.479500e+00}, {2.717000e-01, 2.044300e+00, 7.600700e+00, 2.997140e+01, 8.622650e+01}}; + case 27: + return {{4.118000e-01, 1.316100e+00, 1.649300e+00, 2.193000e+00, 1.283000e+00}, {2.742000e-01, 2.037200e+00, 7.720500e+00, 2.996800e+01, 8.493830e+01}}; + case 28: + return {{3.860000e-01, 1.176500e+00, 1.545100e+00, 2.073000e+00, 1.381400e+00}, {2.478000e-01, 1.766000e+00, 6.310700e+00, 2.522040e+01, 7.431460e+01}}; + case 29: + return {{4.314000e-01, 1.320800e+00, 1.523600e+00, 1.467100e+00, 8.562000e-01}, {2.694000e-01, 1.922300e+00, 7.347400e+00, 2.898920e+01, 9.062460e+01}}; + case 30: + return {{4.288000e-01, 1.264600e+00, 1.447200e+00, 1.829400e+00, 1.093400e+00}, {2.593000e-01, 1.799800e+00, 6.750000e+00, 2.558600e+01, 7.352840e+01}}; + case 31: + return {{4.818000e-01, 1.403200e+00, 1.656100e+00, 2.460500e+00, 1.105400e+00}, {2.825000e-01, 1.978500e+00, 8.754600e+00, 3.252380e+01, 9.855230e+01}}; + case 32: + return {{4.655000e-01, 1.301400e+00, 1.608800e+00, 2.699800e+00, 1.300300e+00}, {2.647000e-01, 1.792600e+00, 7.607100e+00, 2.655410e+01, 7.752380e+01}}; + case 33: + return {{4.517000e-01, 1.222900e+00, 1.585200e+00, 2.795800e+00, 1.263800e+00}, {2.493000e-01, 1.643600e+00, 6.815400e+00, 2.236810e+01, 6.203900e+01}}; + case 34: + return {{4.477000e-01, 1.167800e+00, 1.584300e+00, 2.808700e+00, 1.195600e+00}, {2.405000e-01, 1.544200e+00, 6.323100e+00, 1.946100e+01, 5.202330e+01}}; + case 35: + return {{4.798000e-01, 1.194800e+00, 1.869500e+00, 2.695300e+00, 8.203000e-01}, {2.504000e-01, 1.596300e+00, 6.965300e+00, 1.984920e+01, 5.032330e+01}}; + case 36: + return {{4.546000e-01, 1.099300e+00, 1.769600e+00, 2.706800e+00, 8.672000e-01}, {2.309000e-01, 1.427900e+00, 5.944900e+00, 1.667520e+01, 4.222430e+01}}; + case 37: + return {{1.016000e+00, 2.852800e+00, 3.546600e+00, -7.780400e+00, 1.211480e+01}, {4.853000e-01, 5.092500e+00, 2.578510e+01, 1.304515e+02, 1.386775e+02}}; + case 38: + return {{6.703000e-01, 1.492600e+00, 3.336800e+00, 4.460000e+00, 3.150100e+00}, {3.190000e-01, 2.228700e+00, 1.035040e+01, 5.232910e+01, 1.512216e+02}}; + case 39: + return {{6.894000e-01, 1.547400e+00, 3.245000e+00, 4.212600e+00, 2.976400e+00}, {3.189000e-01, 2.290400e+00, 1.000620e+01, 4.407710e+01, 1.250120e+02}}; + case 40: + return {{6.719000e-01, 1.468400e+00, 3.166800e+00, 3.955700e+00, 2.892000e+00}, {3.036000e-01, 2.124900e+00, 8.923600e+00, 3.684580e+01, 1.082049e+02}}; + case 41: + return {{6.123000e-01, 1.267700e+00, 3.034800e+00, 3.384100e+00, 2.368300e+00}, {2.709000e-01, 1.768300e+00, 7.248900e+00, 2.794650e+01, 9.856240e+01}}; + case 42: + return {{6.773000e-01, 1.479800e+00, 3.178800e+00, 3.082400e+00, 1.838400e+00}, {2.920000e-01, 2.060600e+00, 8.112900e+00, 3.053360e+01, 1.000658e+02}}; + case 43: + return {{7.082000e-01, 1.639200e+00, 3.199300e+00, 3.432700e+00, 1.871100e+00}, {2.976000e-01, 2.210600e+00, 8.524600e+00, 3.314560e+01, 9.663770e+01}}; + case 44: + return {{6.735000e-01, 1.493400e+00, 3.096600e+00, 2.725400e+00, 1.559700e+00}, {2.773000e-01, 1.971600e+00, 7.324900e+00, 2.668910e+01, 9.055810e+01}}; + case 45: + return {{6.413000e-01, 1.369000e+00, 2.985400e+00, 2.695200e+00, 1.543300e+00}, {2.580000e-01, 1.772100e+00, 6.385400e+00, 2.325490e+01, 8.515170e+01}}; + case 46: + return {{5.904000e-01, 1.177500e+00, 2.651900e+00, 2.287500e+00, 8.689000e-01}, {2.324000e-01, 1.501900e+00, 5.159100e+00, 1.554280e+01, 4.682130e+01}}; + case 47: + return {{6.377000e-01, 1.379000e+00, 2.829400e+00, 2.363100e+00, 1.455300e+00}, {2.466000e-01, 1.697400e+00, 5.765600e+00, 2.009430e+01, 7.673720e+01}}; + case 48: + return {{6.364000e-01, 1.424700e+00, 2.780200e+00, 2.597300e+00, 1.788600e+00}, {2.407000e-01, 1.682300e+00, 5.658800e+00, 2.072190e+01, 6.911090e+01}}; + case 49: + return {{6.768000e-01, 1.658900e+00, 2.774000e+00, 3.183500e+00, 2.132600e+00}, {2.522000e-01, 1.854500e+00, 6.293600e+00, 2.514570e+01, 8.454480e+01}}; + case 50: + return {{7.224000e-01, 1.961000e+00, 2.716100e+00, 3.560300e+00, 1.897200e+00}, {2.651000e-01, 2.060400e+00, 7.301100e+00, 2.754930e+01, 8.133490e+01}}; + case 51: + return {{7.106000e-01, 1.924700e+00, 2.614900e+00, 3.832200e+00, 1.889900e+00}, {2.562000e-01, 1.964600e+00, 6.885200e+00, 2.476480e+01, 6.891680e+01}}; + case 52: + return {{6.947000e-01, 1.869000e+00, 2.535600e+00, 4.001300e+00, 1.895500e+00}, {2.459000e-01, 1.854200e+00, 6.441100e+00, 2.217300e+01, 5.922060e+01}}; + case 53: + return {{7.047000e-01, 1.948400e+00, 2.594000e+00, 4.152600e+00, 1.505700e+00}, {2.455000e-01, 1.863800e+00, 6.763900e+00, 2.180070e+01, 5.643950e+01}}; + case 54: + return {{6.737000e-01, 1.790800e+00, 2.412900e+00, 4.210000e+00, 1.705800e+00}, {2.305000e-01, 1.689000e+00, 5.821800e+00, 1.839280e+01, 4.724960e+01}}; + case 55: + return {{1.270400e+00, 3.801800e+00, 5.661800e+00, 9.205000e-01, 4.810500e+00}, {4.356000e-01, 4.205800e+00, 2.343420e+01, 1.367783e+02, 1.717561e+02}}; + case 56: + return {{9.049000e-01, 2.607600e+00, 4.849800e+00, 5.160300e+00, 4.738800e+00}, {3.066000e-01, 2.436300e+00, 1.218210e+01, 5.461350e+01, 1.619978e+02}}; + case 57: + return {{8.405000e-01, 2.386300e+00, 4.613900e+00, 5.151400e+00, 4.794900e+00}, {2.791000e-01, 2.141000e+00, 1.034000e+01, 4.191480e+01, 1.320204e+02}}; + case 58: + return {{8.551000e-01, 2.391500e+00, 4.577200e+00, 5.027800e+00, 4.511800e+00}, {2.805000e-01, 2.120000e+00, 1.018080e+01, 4.206330e+01, 1.309893e+02}}; + case 59: + return {{9.096000e-01, 2.531300e+00, 4.526600e+00, 4.637600e+00, 4.369000e+00}, {2.939000e-01, 2.247100e+00, 1.082660e+01, 4.888420e+01, 1.476020e+02}}; + case 60: + return {{8.807000e-01, 2.418300e+00, 4.444800e+00, 4.685800e+00, 4.172500e+00}, {2.802000e-01, 2.083600e+00, 1.003570e+01, 4.745060e+01, 1.469976e+02}}; + case 61: + return {{9.471000e-01, 2.546300e+00, 4.352300e+00, 4.478900e+00, 3.908000e+00}, {2.977000e-01, 2.227600e+00, 1.057620e+01, 4.936190e+01, 1.453580e+02}}; + case 62: + return {{9.699000e-01, 2.583700e+00, 4.277800e+00, 4.457500e+00, 3.598500e+00}, {3.003000e-01, 2.244700e+00, 1.064870e+01, 5.079940e+01, 1.464179e+02}}; + case 63: + return {{8.694000e-01, 2.241300e+00, 3.919600e+00, 3.969400e+00, 4.549800e+00}, {2.653000e-01, 1.859000e+00, 8.399800e+00, 3.673970e+01, 1.257089e+02}}; + case 64: + return {{9.673000e-01, 2.470200e+00, 4.114800e+00, 4.497200e+00, 3.209900e+00}, {2.909000e-01, 2.101400e+00, 9.706700e+00, 4.342700e+01, 1.259474e+02}}; + case 65: + return {{9.325000e-01, 2.367300e+00, 3.879100e+00, 3.967400e+00, 3.799600e+00}, {2.761000e-01, 1.951100e+00, 8.929600e+00, 4.159370e+01, 1.310122e+02}}; + case 66: + return {{9.505000e-01, 2.370500e+00, 3.821800e+00, 4.047100e+00, 3.445100e+00}, {2.773000e-01, 1.946900e+00, 8.886200e+00, 4.309380e+01, 1.331396e+02}}; + case 67: + return {{9.248000e-01, 2.242800e+00, 3.618200e+00, 3.791000e+00, 3.791200e+00}, {2.660000e-01, 1.818300e+00, 7.965500e+00, 3.311290e+01, 1.018139e+02}}; + case 68: + return {{1.037300e+00, 2.482400e+00, 3.655800e+00, 3.892500e+00, 3.005600e+00}, {2.944000e-01, 2.079700e+00, 9.415600e+00, 4.580560e+01, 1.327720e+02}}; + case 69: + return {{1.007500e+00, 2.378700e+00, 3.544000e+00, 3.693200e+00, 3.175900e+00}, {2.816000e-01, 1.948600e+00, 8.716200e+00, 4.184200e+01, 1.250320e+02}}; + case 70: + return {{1.034700e+00, 2.391100e+00, 3.461900e+00, 3.655600e+00, 3.005200e+00}, {2.855000e-01, 1.967900e+00, 8.761900e+00, 4.233040e+01, 1.256499e+02}}; + case 71: + return {{9.927000e-01, 2.243600e+00, 3.355400e+00, 3.781300e+00, 3.099400e+00}, {2.701000e-01, 1.807300e+00, 7.811200e+00, 3.448490e+01, 1.033526e+02}}; + case 72: + return {{1.029500e+00, 2.291100e+00, 3.411000e+00, 3.949700e+00, 2.492500e+00}, {2.761000e-01, 1.862500e+00, 8.096100e+00, 3.427120e+01, 9.852950e+01}}; + case 73: + return {{1.019000e+00, 2.229100e+00, 3.409700e+00, 3.925200e+00, 2.267900e+00}, {2.694000e-01, 1.796200e+00, 7.694400e+00, 3.109420e+01, 9.110890e+01}}; + case 74: + return {{9.853000e-01, 2.116700e+00, 3.357000e+00, 3.798100e+00, 2.279800e+00}, {2.569000e-01, 1.674500e+00, 7.009800e+00, 2.692340e+01, 8.139100e+01}}; + case 75: + return {{9.914000e-01, 2.085800e+00, 3.453100e+00, 3.881200e+00, 1.852600e+00}, {2.548000e-01, 1.651800e+00, 6.884500e+00, 2.672340e+01, 8.172150e+01}}; + case 76: + return {{9.813000e-01, 2.032200e+00, 3.366500e+00, 3.623500e+00, 1.974100e+00}, {2.487000e-01, 1.597300e+00, 6.473700e+00, 2.328170e+01, 7.092540e+01}}; + case 77: + return {{1.019400e+00, 2.064500e+00, 3.442500e+00, 3.491400e+00, 1.697600e+00}, {2.554000e-01, 1.647500e+00, 6.596600e+00, 2.322690e+01, 7.002720e+01}}; + case 78: + return {{9.148000e-01, 1.809600e+00, 3.213400e+00, 3.295300e+00, 1.575400e+00}, {2.263000e-01, 1.381300e+00, 5.324300e+00, 1.759870e+01, 6.001710e+01}}; + case 79: + return {{9.674000e-01, 1.891600e+00, 3.399300e+00, 3.052400e+00, 1.260700e+00}, {2.358000e-01, 1.471200e+00, 5.675800e+00, 1.871190e+01, 6.152860e+01}}; + case 80: + return {{1.003300e+00, 1.946900e+00, 3.439600e+00, 3.154800e+00, 1.418000e+00}, {2.413000e-01, 1.529800e+00, 5.800900e+00, 1.945200e+01, 6.057530e+01}}; + case 81: + return {{1.068900e+00, 2.103800e+00, 3.603900e+00, 3.492700e+00, 1.828300e+00}, {2.540000e-01, 1.671500e+00, 6.350900e+00, 2.315310e+01, 7.870990e+01}}; + case 82: + return {{1.089100e+00, 2.186700e+00, 3.616000e+00, 3.803100e+00, 1.899400e+00}, {2.552000e-01, 1.717400e+00, 6.513100e+00, 2.391700e+01, 7.470390e+01}}; + case 83: + return {{1.100700e+00, 2.230600e+00, 3.568900e+00, 4.154900e+00, 2.038200e+00}, {2.546000e-01, 1.735100e+00, 6.494800e+00, 2.364640e+01, 7.037800e+01}}; + case 84: + return {{1.156800e+00, 2.435300e+00, 3.645900e+00, 4.406400e+00, 1.717900e+00}, {2.648000e-01, 1.878600e+00, 7.174900e+00, 2.517660e+01, 6.928210e+01}}; + case 85: + return {{1.090900e+00, 2.197600e+00, 3.383100e+00, 4.670000e+00, 2.127700e+00}, {2.466000e-01, 1.670700e+00, 6.019700e+00, 2.076570e+01, 5.726630e+01}}; + case 86: + return {{1.075600e+00, 2.163000e+00, 3.317800e+00, 4.885200e+00, 2.048900e+00}, {2.402000e-01, 1.616900e+00, 5.764400e+00, 1.945680e+01, 5.250090e+01}}; + case 87: + return {{1.428200e+00, 3.508100e+00, 5.676700e+00, 4.196400e+00, 3.894600e+00}, {3.183000e-01, 2.688900e+00, 1.348160e+01, 5.438660e+01, 2.008321e+02}}; + case 88: + return {{1.312700e+00, 3.124300e+00, 5.298800e+00, 5.389100e+00, 5.413300e+00}, {2.887000e-01, 2.289700e+00, 1.082760e+01, 4.353890e+01, 1.456109e+02}}; + case 89: + return {{1.312800e+00, 3.102100e+00, 5.338500e+00, 5.961100e+00, 4.756200e+00}, {2.861000e-01, 2.250900e+00, 1.052870e+01, 4.177960e+01, 1.282973e+02}}; + case 90: + return {{1.255300e+00, 2.917800e+00, 5.086200e+00, 6.120600e+00, 4.712200e+00}, {2.701000e-01, 2.063600e+00, 9.305100e+00, 3.459770e+01, 1.079200e+02}}; + case 91: + return {{1.321800e+00, 3.144400e+00, 5.437100e+00, 5.644400e+00, 4.010700e+00}, {2.827000e-01, 2.225000e+00, 1.024540e+01, 4.111620e+01, 1.244449e+02}}; + case 92: + return {{1.338200e+00, 3.204300e+00, 5.455800e+00, 5.483900e+00, 3.634200e+00}, {2.838000e-01, 2.245200e+00, 1.025190e+01, 4.172510e+01, 1.249023e+02}}; + case 93: + return {{1.519300e+00, 4.005300e+00, 6.532700e+00, -1.402000e-01, 6.748900e+00}, {3.213000e-01, 2.820600e+00, 1.488780e+01, 6.891030e+01, 8.172570e+01}}; + case 94: + return {{1.351700e+00, 3.293700e+00, 5.321300e+00, 4.646600e+00, 3.571400e+00}, {2.813000e-01, 2.241800e+00, 9.995200e+00, 4.279390e+01, 1.321739e+02}}; + case 95: + return {{1.213500e+00, 2.796200e+00, 4.754500e+00, 4.573100e+00, 4.478600e+00}, {2.483000e-01, 1.843700e+00, 7.542100e+00, 2.938410e+01, 1.124579e+02}}; + case 96: + return {{1.293700e+00, 3.110000e+00, 5.039300e+00, 4.754600e+00, 3.503100e+00}, {2.638000e-01, 2.034100e+00, 8.710100e+00, 3.529920e+01, 1.094972e+02}}; + case 97: + return {{1.291500e+00, 3.102300e+00, 4.930900e+00, 4.600900e+00, 3.466100e+00}, {2.611000e-01, 2.002300e+00, 8.437700e+00, 3.415590e+01, 1.058911e+02}}; + case 98: + return {{1.208900e+00, 2.739100e+00, 4.348200e+00, 4.004700e+00, 4.649700e+00}, {2.421000e-01, 1.748700e+00, 6.726200e+00, 2.321530e+01, 8.031080e+01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + LNL_Coef_cpu load_feg_peng_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{8.800000e-03, 4.490000e-02, 1.481000e-01, 2.356000e-01, 9.140000e-02}, {1.152000e-01, 1.086700e+00, 4.975500e+00, 1.655910e+01, 4.327430e+01}}; + case 2: + return {{8.400000e-03, 4.430000e-02, 1.314000e-01, 1.671000e-01, 6.660000e-02}, {5.960000e-02, 5.360000e-01, 2.427400e+00, 7.785200e+00, 2.031260e+01}}; + case 3: + return {{4.780000e-02, 2.048000e-01, 5.253000e-01, 1.522500e+00, 9.853000e-01}, {2.258000e-01, 2.103200e+00, 1.293490e+01, 5.075010e+01, 1.366280e+02}}; + case 4: + return {{4.230000e-02, 1.874000e-01, 6.019000e-01, 1.431100e+00, 7.891000e-01}, {1.445000e-01, 1.418000e+00, 8.116500e+00, 2.797050e+01, 7.486840e+01}}; + case 5: + return {{4.360000e-02, 1.898000e-01, 6.788000e-01, 1.327300e+00, 5.544000e-01}, {1.207000e-01, 1.159500e+00, 6.247400e+00, 2.104600e+01, 5.936190e+01}}; + case 6: + return {{4.890000e-02, 2.091000e-01, 7.537000e-01, 1.142000e+00, 3.555000e-01}, {1.140000e-01, 1.082500e+00, 5.428100e+00, 1.788110e+01, 5.113410e+01}}; + case 7: + return {{2.670000e-02, 1.328000e-01, 5.301000e-01, 1.102000e+00, 4.215000e-01}, {5.410000e-02, 5.165000e-01, 2.820700e+00, 1.062970e+01, 3.437640e+01}}; + case 8: + return {{3.650000e-02, 1.729000e-01, 5.805000e-01, 8.814000e-01, 3.121000e-01}, {6.520000e-02, 6.184000e-01, 2.944900e+00, 9.629800e+00, 2.821940e+01}}; + case 9: + return {{3.820000e-02, 1.822000e-01, 5.972000e-01, 7.707000e-01, 2.130000e-01}, {6.130000e-02, 5.753000e-01, 2.685800e+00, 8.821400e+00, 2.566680e+01}}; + case 10: + return {{3.800000e-02, 1.785000e-01, 5.494000e-01, 6.942000e-01, 1.918000e-01}, {5.540000e-02, 5.087000e-01, 2.263900e+00, 7.331600e+00, 2.169120e+01}}; + case 11: + return {{1.260000e-01, 6.442000e-01, 8.893000e-01, 1.819700e+00, 1.298800e+00}, {1.684000e-01, 1.715000e+00, 8.838600e+00, 5.082650e+01, 1.472073e+02}}; + case 12: + return {{1.130000e-01, 5.575000e-01, 9.046000e-01, 2.158000e+00, 1.473500e+00}, {1.356000e-01, 1.357900e+00, 6.925500e+00, 3.231650e+01, 9.211380e+01}}; + case 13: + return {{1.165000e-01, 5.504000e-01, 1.017900e+00, 2.629500e+00, 1.571100e+00}, {1.295000e-01, 1.261900e+00, 6.824200e+00, 2.845770e+01, 8.847500e+01}}; + case 14: + return {{5.670000e-02, 3.365000e-01, 8.104000e-01, 2.496000e+00, 2.118600e+00}, {5.820000e-02, 6.155000e-01, 3.252200e+00, 1.679290e+01, 5.767670e+01}}; + case 15: + return {{1.005000e-01, 4.615000e-01, 1.066300e+00, 2.585400e+00, 1.272500e+00}, {9.770000e-02, 9.084000e-01, 4.965400e+00, 1.854710e+01, 5.436480e+01}}; + case 16: + return {{9.150000e-02, 4.312000e-01, 1.084700e+00, 2.467100e+00, 1.085200e+00}, {8.380000e-02, 7.788000e-01, 4.346200e+00, 1.558460e+01, 4.463650e+01}}; + case 17: + return {{7.990000e-02, 3.891000e-01, 1.003700e+00, 2.333200e+00, 1.050700e+00}, {6.940000e-02, 6.443000e-01, 3.535100e+00, 1.250580e+01, 3.586330e+01}}; + case 18: + return {{1.044000e-01, 4.551000e-01, 1.423200e+00, 2.153300e+00, 4.459000e-01}, {8.530000e-02, 7.701000e-01, 4.468400e+00, 1.458640e+01, 4.124740e+01}}; + case 19: + return {{2.149000e-01, 8.703000e-01, 2.499900e+00, 2.359100e+00, 3.031800e+00}, {1.660000e-01, 1.690600e+00, 8.744700e+00, 4.678250e+01, 1.656923e+02}}; + case 20: + return {{2.355000e-01, 9.916000e-01, 2.395900e+00, 3.725200e+00, 2.564700e+00}, {1.742000e-01, 1.832900e+00, 8.840700e+00, 4.745830e+01, 1.349613e+02}}; + case 21: + return {{4.636000e-01, 2.080200e+00, 2.900300e+00, 1.419300e+00, 2.432300e+00}, {3.682000e-01, 4.031200e+00, 2.264930e+01, 7.182000e+01, 1.033691e+02}}; + case 22: + return {{2.123000e-01, 8.960000e-01, 2.176500e+00, 3.043600e+00, 2.443900e+00}, {1.399000e-01, 1.456800e+00, 6.753400e+00, 3.311680e+01, 1.018238e+02}}; + case 23: + return {{2.369000e-01, 1.077400e+00, 2.189400e+00, 3.082500e+00, 1.719000e+00}, {1.505000e-01, 1.639200e+00, 7.569100e+00, 3.687410e+01, 1.078517e+02}}; + case 24: + return {{1.970000e-01, 8.228000e-01, 2.020000e+00, 2.171700e+00, 1.751600e+00}, {1.197000e-01, 1.198500e+00, 5.409700e+00, 2.523610e+01, 9.442900e+01}}; + case 25: + return {{1.943000e-01, 8.190000e-01, 1.929600e+00, 2.496800e+00, 2.062500e+00}, {1.135000e-01, 1.131300e+00, 5.034100e+00, 2.417980e+01, 8.055980e+01}}; + case 26: + return {{1.929000e-01, 8.239000e-01, 1.868900e+00, 2.369400e+00, 1.906000e+00}, {1.087000e-01, 1.080600e+00, 4.763700e+00, 2.285000e+01, 7.673090e+01}}; + case 27: + return {{2.186000e-01, 9.861000e-01, 1.854000e+00, 2.325800e+00, 1.468500e+00}, {1.182000e-01, 1.230000e+00, 5.417700e+00, 2.576020e+01, 8.085420e+01}}; + case 28: + return {{2.313000e-01, 1.065700e+00, 1.822900e+00, 2.260900e+00, 1.188300e+00}, {1.210000e-01, 1.269100e+00, 5.687000e+00, 2.709170e+01, 8.302850e+01}}; + case 29: + return {{3.501000e-01, 1.655800e+00, 1.958200e+00, 2.134000e-01, 1.410900e+00}, {1.867000e-01, 1.991700e+00, 1.133960e+01, 5.326190e+01, 6.325200e+01}}; + case 30: + return {{1.780000e-01, 8.096000e-01, 1.674400e+00, 1.949900e+00, 1.449500e+00}, {8.760000e-02, 8.650000e-01, 3.861200e+00, 1.887260e+01, 6.470160e+01}}; + case 31: + return {{2.135000e-01, 9.768000e-01, 1.666900e+00, 2.566200e+00, 1.679000e+00}, {1.020000e-01, 1.021900e+00, 4.627500e+00, 2.287420e+01, 8.015350e+01}}; + case 32: + return {{2.135000e-01, 9.761000e-01, 1.655500e+00, 2.893800e+00, 1.635600e+00}, {9.890000e-02, 9.845000e-01, 4.552700e+00, 2.155630e+01, 7.039030e+01}}; + case 33: + return {{2.059000e-01, 9.518000e-01, 1.637200e+00, 3.049000e+00, 1.475600e+00}, {9.260000e-02, 9.182000e-01, 4.329100e+00, 1.929960e+01, 5.893290e+01}}; + case 34: + return {{1.574000e-01, 7.614000e-01, 1.483400e+00, 3.001600e+00, 1.797800e+00}, {6.860000e-02, 6.808000e-01, 3.116300e+00, 1.434580e+01, 4.404550e+01}}; + case 35: + return {{1.899000e-01, 8.983000e-01, 1.635800e+00, 3.184500e+00, 1.151800e+00}, {8.100000e-02, 7.957000e-01, 3.905400e+00, 1.577010e+01, 4.561240e+01}}; + case 36: + return {{1.742000e-01, 8.447000e-01, 1.594400e+00, 3.150700e+00, 1.133800e+00}, {7.230000e-02, 7.123000e-01, 3.519200e+00, 1.377240e+01, 3.911480e+01}}; + case 37: + return {{3.781000e-01, 1.490400e+00, 3.575300e+00, 3.003100e+00, 3.327200e+00}, {1.557000e-01, 1.534700e+00, 9.994700e+00, 5.142510e+01, 1.859828e+02}}; + case 38: + return {{3.723000e-01, 1.459800e+00, 3.512400e+00, 4.461200e+00, 3.303100e+00}, {1.480000e-01, 1.464300e+00, 9.232000e+00, 4.988070e+01, 1.480937e+02}}; + case 39: + return {{3.234000e-01, 1.273700e+00, 3.211500e+00, 4.056300e+00, 3.796200e+00}, {1.244000e-01, 1.194800e+00, 7.275600e+00, 3.414300e+01, 1.112079e+02}}; + case 40: + return {{2.997000e-01, 1.187900e+00, 3.107500e+00, 3.974000e+00, 3.576900e+00}, {1.121000e-01, 1.063800e+00, 6.389100e+00, 2.870810e+01, 9.742890e+01}}; + case 41: + return {{1.680000e-01, 9.370000e-01, 2.730000e+00, 3.815000e+00, 3.005300e+00}, {5.970000e-02, 6.524000e-01, 4.431700e+00, 1.955400e+01, 8.550110e+01}}; + case 42: + return {{3.069000e-01, 1.171400e+00, 3.229300e+00, 3.425400e+00, 2.122400e+00}, {1.101000e-01, 1.022200e+00, 5.961300e+00, 2.519650e+01, 9.358310e+01}}; + case 43: + return {{2.928000e-01, 1.126700e+00, 3.167500e+00, 3.661900e+00, 2.594200e+00}, {1.020000e-01, 9.481000e-01, 5.471300e+00, 2.381530e+01, 8.289910e+01}}; + case 44: + return {{2.604000e-01, 1.044200e+00, 3.076100e+00, 3.217500e+00, 1.944800e+00}, {8.870000e-02, 8.240000e-01, 4.827800e+00, 1.989770e+01, 8.045660e+01}}; + case 45: + return {{2.713000e-01, 1.055600e+00, 3.141600e+00, 3.045100e+00, 1.717900e+00}, {9.070000e-02, 8.324000e-01, 4.770200e+00, 1.978620e+01, 8.025400e+01}}; + case 46: + return {{2.003000e-01, 8.779000e-01, 2.613500e+00, 2.859400e+00, 1.025800e+00}, {6.590000e-02, 6.111000e-01, 3.556300e+00, 1.276380e+01, 4.442830e+01}}; + case 47: + return {{2.739000e-01, 1.050300e+00, 3.156400e+00, 2.754300e+00, 1.432800e+00}, {8.810000e-02, 8.028000e-01, 4.445100e+00, 1.870110e+01, 7.926330e+01}}; + case 48: + return {{3.072000e-01, 1.130300e+00, 3.204600e+00, 2.932900e+00, 1.656000e+00}, {9.660000e-02, 8.856000e-01, 4.627300e+00, 2.067890e+01, 7.347230e+01}}; + case 49: + return {{3.564000e-01, 1.301100e+00, 3.242400e+00, 3.483900e+00, 2.045900e+00}, {1.091000e-01, 1.045200e+00, 5.090000e+00, 2.465780e+01, 8.805130e+01}}; + case 50: + return {{2.966000e-01, 1.115700e+00, 3.097300e+00, 3.815600e+00, 2.528100e+00}, {8.960000e-02, 8.268000e-01, 4.224200e+00, 2.069000e+01, 7.133990e+01}}; + case 51: + return {{2.725000e-01, 1.065100e+00, 2.994000e+00, 4.069700e+00, 2.568200e+00}, {8.090000e-02, 7.488000e-01, 3.871000e+00, 1.888000e+01, 6.064990e+01}}; + case 52: + return {{2.422000e-01, 9.692000e-01, 2.811400e+00, 4.150900e+00, 2.816100e+00}, {7.080000e-02, 6.472000e-01, 3.360900e+00, 1.607520e+01, 5.017240e+01}}; + case 53: + return {{2.617000e-01, 1.032500e+00, 2.809700e+00, 4.480900e+00, 2.319000e+00}, {7.490000e-02, 6.914000e-01, 3.463400e+00, 1.636030e+01, 4.825220e+01}}; + case 54: + return {{2.334000e-01, 9.496000e-01, 2.638100e+00, 4.468000e+00, 2.502000e+00}, {6.550000e-02, 6.050000e-01, 3.038900e+00, 1.408090e+01, 4.100050e+01}}; + case 55: + return {{5.713000e-01, 2.486600e+00, 4.979500e+00, 4.019800e+00, 4.440300e+00}, {1.626000e-01, 1.821300e+00, 1.110490e+01, 4.905680e+01, 2.029987e+02}}; + case 56: + return {{5.229000e-01, 2.287400e+00, 4.724300e+00, 5.080700e+00, 5.638900e+00}, {1.434000e-01, 1.601900e+00, 9.451100e+00, 4.276850e+01, 1.484969e+02}}; + case 57: + return {{5.461000e-01, 2.385600e+00, 5.065300e+00, 5.760100e+00, 4.046300e+00}, {1.479000e-01, 1.655200e+00, 1.000590e+01, 4.732450e+01, 1.458464e+02}}; + case 58: + return {{2.227000e-01, 1.076000e+00, 2.948200e+00, 5.849600e+00, 7.183400e+00}, {5.710000e-02, 5.946000e-01, 3.202200e+00, 1.642530e+01, 9.570300e+01}}; + case 59: + return {{5.237000e-01, 2.291300e+00, 4.616100e+00, 4.723300e+00, 4.817300e+00}, {1.360000e-01, 1.506800e+00, 8.821300e+00, 4.195360e+01, 1.412424e+02}}; + case 60: + return {{5.368000e-01, 2.330100e+00, 4.605800e+00, 4.662100e+00, 4.462200e+00}, {1.378000e-01, 1.514000e+00, 8.871900e+00, 4.359670e+01, 1.418065e+02}}; + case 61: + return {{5.232000e-01, 2.262700e+00, 4.455200e+00, 4.478700e+00, 4.507300e+00}, {1.317000e-01, 1.433600e+00, 8.308700e+00, 4.060100e+01, 1.359196e+02}}; + case 62: + return {{5.162000e-01, 2.230200e+00, 4.344900e+00, 4.359800e+00, 4.429200e+00}, {1.279000e-01, 1.381100e+00, 7.962900e+00, 3.912130e+01, 1.327846e+02}}; + case 63: + return {{5.272000e-01, 2.284400e+00, 4.336100e+00, 4.317800e+00, 4.090800e+00}, {1.285000e-01, 1.394300e+00, 8.108100e+00, 4.096310e+01, 1.341233e+02}}; + case 64: + return {{9.664000e-01, 3.405200e+00, 5.080300e+00, 1.499100e+00, 4.252800e+00}, {2.641000e-01, 2.658600e+00, 1.622130e+01, 8.020600e+01, 9.253590e+01}}; + case 65: + return {{5.110000e-01, 2.157000e+00, 4.030800e+00, 3.993600e+00, 4.246600e+00}, {1.210000e-01, 1.270400e+00, 7.136800e+00, 3.503540e+01, 1.235062e+02}}; + case 66: + return {{4.974000e-01, 2.109700e+00, 3.890600e+00, 3.810000e+00, 4.308400e+00}, {1.157000e-01, 1.210800e+00, 6.737700e+00, 3.241500e+01, 1.169225e+02}}; + case 67: + return {{4.679000e-01, 1.969300e+00, 3.719100e+00, 3.963200e+00, 4.243200e+00}, {1.069000e-01, 1.099400e+00, 5.976900e+00, 2.714910e+01, 9.631190e+01}}; + case 68: + return {{5.034000e-01, 2.108800e+00, 3.823200e+00, 3.729900e+00, 3.896300e+00}, {1.141000e-01, 1.176900e+00, 6.608700e+00, 3.343320e+01, 1.164913e+02}}; + case 69: + return {{4.839000e-01, 2.026200e+00, 3.685100e+00, 3.587400e+00, 4.003700e+00}, {1.081000e-01, 1.101200e+00, 6.111400e+00, 3.037280e+01, 1.105988e+02}}; + case 70: + return {{5.221000e-01, 2.169500e+00, 3.756700e+00, 3.668500e+00, 3.427400e+00}, {1.148000e-01, 1.186000e+00, 6.752000e+00, 3.568070e+01, 1.180692e+02}}; + case 71: + return {{4.680000e-01, 1.946600e+00, 3.542800e+00, 3.849000e+00, 3.659400e+00}, {1.015000e-01, 1.019500e+00, 5.605800e+00, 2.748990e+01, 9.528460e+01}}; + case 72: + return {{4.048000e-01, 1.737000e+00, 3.339900e+00, 3.944800e+00, 3.729300e+00}, {8.680000e-02, 8.585000e-01, 4.637800e+00, 2.169000e+01, 8.024080e+01}}; + case 73: + return {{3.835000e-01, 1.674700e+00, 3.298600e+00, 4.046200e+00, 3.430300e+00}, {8.100000e-02, 8.020000e-01, 4.354500e+00, 1.996440e+01, 7.363370e+01}}; + case 74: + return {{3.661000e-01, 1.619100e+00, 3.245500e+00, 4.085600e+00, 3.206400e+00}, {7.610000e-02, 7.543000e-01, 4.095200e+00, 1.828860e+01, 6.809670e+01}}; + case 75: + return {{3.933000e-01, 1.697300e+00, 3.420200e+00, 4.127400e+00, 2.615800e+00}, {8.060000e-02, 7.972000e-01, 4.423700e+00, 1.956920e+01, 6.874770e+01}}; + case 76: + return {{3.854000e-01, 1.655500e+00, 3.412900e+00, 4.111100e+00, 2.410600e+00}, {7.870000e-02, 7.638000e-01, 4.244100e+00, 1.837000e+01, 6.510710e+01}}; + case 77: + return {{3.510000e-01, 1.562000e+00, 3.294600e+00, 4.061500e+00, 2.438200e+00}, {7.060000e-02, 6.904000e-01, 3.826600e+00, 1.608120e+01, 5.876380e+01}}; + case 78: + return {{3.083000e-01, 1.415800e+00, 2.966200e+00, 3.934900e+00, 2.170900e+00}, {6.090000e-02, 5.993000e-01, 3.192100e+00, 1.252850e+01, 4.976750e+01}}; + case 79: + return {{3.055000e-01, 1.394500e+00, 2.961700e+00, 3.899000e+00, 2.002600e+00}, {5.960000e-02, 5.827000e-01, 3.103500e+00, 1.196930e+01, 4.791060e+01}}; + case 80: + return {{3.593000e-01, 1.573600e+00, 3.523700e+00, 3.810900e+00, 1.695300e+00}, {6.940000e-02, 6.758000e-01, 3.845700e+00, 1.562030e+01, 5.666140e+01}}; + case 81: + return {{3.511000e-01, 1.548900e+00, 3.567600e+00, 4.090000e+00, 2.525100e+00}, {6.720000e-02, 6.522000e-01, 3.742000e+00, 1.597910e+01, 6.513540e+01}}; + case 82: + return {{3.540000e-01, 1.545300e+00, 3.597500e+00, 4.315200e+00, 2.774300e+00}, {6.680000e-02, 6.465000e-01, 3.696800e+00, 1.620560e+01, 6.149090e+01}}; + case 83: + return {{3.530000e-01, 1.525800e+00, 3.581500e+00, 4.553200e+00, 3.071400e+00}, {6.610000e-02, 6.324000e-01, 3.590600e+00, 1.599620e+01, 5.757600e+01}}; + case 84: + return {{3.673000e-01, 1.577200e+00, 3.707900e+00, 4.858200e+00, 2.844000e+00}, {6.780000e-02, 6.527000e-01, 3.739600e+00, 1.706680e+01, 5.597890e+01}}; + case 85: + return {{3.547000e-01, 1.520600e+00, 3.562100e+00, 5.018400e+00, 3.007500e+00}, {6.490000e-02, 6.188000e-01, 3.469600e+00, 1.560900e+01, 4.948180e+01}}; + case 86: + return {{4.586000e-01, 1.778100e+00, 3.987700e+00, 5.727300e+00, 1.546000e+00}, {8.310000e-02, 7.840000e-01, 4.359900e+00, 2.001280e+01, 6.215350e+01}}; + case 87: + return {{8.282000e-01, 2.994100e+00, 5.659700e+00, 4.929200e+00, 4.288900e+00}, {1.515000e-01, 1.616300e+00, 9.775200e+00, 4.284800e+01, 1.907366e+02}}; + case 88: + return {{1.412900e+00, 4.426900e+00, 7.046000e+00, -1.057300e+00, 8.643000e+00}, {2.921000e-01, 3.138100e+00, 1.967670e+01, 1.020436e+02, 1.139798e+02}}; + case 89: + return {{7.169000e-01, 2.571000e+00, 5.179100e+00, 6.348400e+00, 5.647400e+00}, {1.263000e-01, 1.290000e+00, 7.368600e+00, 3.244900e+01, 1.180558e+02}}; + case 90: + return {{6.958000e-01, 2.493600e+00, 5.126900e+00, 6.698800e+00, 5.079900e+00}, {1.211000e-01, 1.224700e+00, 6.939800e+00, 3.009910e+01, 1.051960e+02}}; + case 91: + return {{1.250200e+00, 4.228400e+00, 7.048900e+00, 1.139000e+00, 5.822200e+00}, {2.415000e-01, 2.644200e+00, 1.633130e+01, 7.357570e+01, 9.194010e+01}}; + case 92: + return {{6.410000e-01, 2.264300e+00, 4.871300e+00, 5.928700e+00, 5.393500e+00}, {1.097000e-01, 1.064400e+00, 5.790700e+00, 2.502610e+01, 1.013899e+02}}; + case 93: + return {{6.938000e-01, 2.465200e+00, 5.122700e+00, 5.596500e+00, 4.854300e+00}, {1.171000e-01, 1.175700e+00, 6.405300e+00, 2.752170e+01, 1.030482e+02}}; + case 94: + return {{6.902000e-01, 2.450900e+00, 5.128400e+00, 5.033900e+00, 4.857500e+00}, {1.153000e-01, 1.154500e+00, 6.229100e+00, 2.707410e+01, 1.113150e+02}}; + case 95: + return {{7.577000e-01, 2.726400e+00, 5.418400e+00, 4.819800e+00, 4.101300e+00}, {1.257000e-01, 1.304400e+00, 7.103500e+00, 3.246490e+01, 1.188647e+02}}; + case 96: + return {{7.567000e-01, 2.756500e+00, 5.436400e+00, 5.191800e+00, 3.564300e+00}, {1.239000e-01, 1.297900e+00, 7.079800e+00, 3.278710e+01, 1.101512e+02}}; + case 97: + return {{7.492000e-01, 2.726700e+00, 5.352100e+00, 5.036900e+00, 3.532100e+00}, {1.217000e-01, 1.265100e+00, 6.810100e+00, 3.160880e+01, 1.064853e+02}}; + case 98: + return {{8.100000e-01, 3.000100e+00, 5.463500e+00, 4.175600e+00, 3.506600e+00}, {1.310000e-01, 1.403800e+00, 7.605700e+00, 3.401860e+01, 9.052260e+01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 4: Kirkland parameterization - 3 yukawa + 3 Gaussians - [0, 12] + LNL_Coef_cpu load_feg_kirkland_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{4.20298320e-03, 6.27762505e-02, 3.00907347e-02, 6.77756695e-02, 3.56609240e-03, 2.76135815e-02}, {2.25350888e-01, 2.25366950e-01, 2.25331756e-01, 4.38854001e+00, 4.03884823e-01, 1.44490166e+00}}; + case 2: + return {{1.87544000e-05, 4.10595800e-04, 1.96300059e-01, 8.36015740e-03, 2.95102022e-02, 4.65900000e-07}, {2.12427997e-01, 3.32212279e-01, 5.17325152e-01, 3.66668239e-01, 1.37171827e+00, 3.75768025e+04}}; + case 3: + return {{7.45843816e-02, 7.15382250e-02, 1.45315229e-01, 1.12125769e+00, 2.51736530e-03, 3.58434971e-01}, {8.81151424e-01, 4.59142904e-02, 8.81301714e-01, 1.88483665e+01, 1.59189995e-01, 6.12371000e+00}}; + case 4: + return {{6.11642897e-02, 1.25755034e-01, 2.00831548e-01, 7.87242876e-01, 1.58847850e-03, 2.73962031e-01}, {9.90182132e-02, 9.90272412e-02, 1.87392509e+00, 9.32794929e+00, 8.91900236e-02, 3.20687658e+00}}; + case 5: + return {{1.25716066e-01, 1.73314452e-01, 1.84774811e-01, 1.95250221e-01, 5.29642075e-01, 1.08230500e-03}, {1.48258830e-01, 1.48257216e-01, 3.34227311e+00, 1.97339463e+00, 5.70035553e+00, 5.64857237e-02}}; + case 6: + return {{2.12080767e-01, 1.99811865e-01, 1.68254385e-01, 1.42048360e-01, 3.63830672e-01, 8.35012000e-04}, {2.08605417e-01, 2.08610186e-01, 5.57870773e+00, 1.33311887e+00, 3.80800263e+00, 4.03982620e-02}}; + case 7: + return {{5.33015554e-01, 5.29008883e-02, 9.24159648e-02, 2.61799101e-01, 8.80262100e-04, 1.10166555e-01}, {2.90952515e-01, 1.03547896e+01, 1.03540028e+01, 2.76252723e+00, 3.47681236e-02, 9.93421736e-01}}; + case 8: + return {{3.39969204e-01, 3.07570172e-01, 1.30369072e-01, 8.83326058e-02, 1.96586700e-01, 9.96220000e-04}, {3.81570280e-01, 3.81571436e-01, 1.91919745e+01, 7.60635525e-01, 2.07401094e+00, 3.03266869e-02}}; + case 9: + return {{2.30560593e-01, 5.26889648e-01, 1.24346755e-01, 1.24616890e-03, 7.20452555e-02, 1.53075777e-01}, {4.80754213e-01, 4.80763895e-01, 3.95306720e+01, 2.62181803e-02, 5.92495593e-01, 1.59127671e+00}}; + case 10: + return {{4.08371771e-01, 4.54418858e-01, 1.44564923e-01, 5.91531395e-02, 1.24003718e-01, 1.64986040e-03}, {5.88228627e-01, 5.88288655e-01, 1.21246013e+02, 4.63963540e-01, 1.23413025e+00, 2.05869217e-02}}; + case 11: + return {{1.36471662e-01, 7.70677865e-01, 1.56862014e-01, 9.96821513e-01, 3.80304670e-02, 1.27685089e-01}, {4.99965301e-02, 8.81899664e-01, 1.61768579e+01, 2.00132610e+01, 2.60516254e-01, 6.99559329e-01}}; + case 12: + return {{3.04384121e-01, 7.56270563e-01, 1.01164809e-01, 3.45203403e-02, 9.71751327e-01, 1.20593012e-01}, {8.42014377e-02, 1.64065598e+00, 2.97142975e+01, 2.16596094e-01, 1.21236852e+01, 5.60865838e-01}}; + case 13: + return {{7.77419424e-01, 5.78312036e-02, 4.26386499e-01, 1.13407220e-01, 7.90114035e-01, 3.23293496e-02}, {2.71058227e+00, 7.17532098e+01, 9.13331555e-02, 4.48867451e-01, 8.66366718e+00, 1.78503463e-01}}; + case 14: + return {{1.06543892e+00, 1.20143691e-01, 1.80915263e-01, 1.12065620e+00, 3.05452816e-02, 1.59963502e+00}, {1.04118455e+00, 6.87113368e+01, 8.87533926e-02, 3.70062619e+00, 2.14097897e-01, 9.99096638e+00}}; + case 15: + return {{1.05284447e+00, 2.99440284e-01, 1.17460748e-01, 9.60643452e-01, 2.63555748e-02, 1.38059330e+00}, {1.31962590e+00, 1.28460520e-01, 1.02190163e+02, 2.87477555e+00, 1.82076844e-01, 7.49165526e+00}}; + case 16: + return {{1.01646916e+00, 4.41766748e-01, 1.21503863e-01, 8.27966670e-01, 2.33022533e-02, 1.18302846e+00}, {1.69181965e+00, 1.74180288e-01, 1.67011091e+02, 2.30342810e+00, 1.56954150e-01, 5.85782891e+00}}; + case 17: + return {{9.44221116e-01, 4.37322049e-01, 2.54547926e-01, 5.47763323e-02, 8.00087488e-01, 1.07488641e-02}, {2.40052374e-01, 9.30510439e+00, 9.30486346e+00, 1.68655688e-01, 2.97849774e+00, 6.84240646e-02}}; + case 18: + return {{1.06983288e+00, 4.24631786e-01, 2.43897949e-01, 4.79446296e-02, 7.64958952e-01, 8.23128430e-03}, {2.87791022e-01, 1.24156957e+01, 1.24158868e+01, 1.36979796e-01, 2.43940729e+00, 5.27258749e-02}}; + case 19: + return {{6.92717865e-01, 9.65161085e-01, 1.48466588e-01, 2.64645027e-02, 1.80883768e+00, 5.43900018e-01}, {7.10849990e+00, 3.57532901e-01, 3.93763275e-02, 1.03591321e-01, 3.22845199e+01, 1.67791374e+00}}; + case 20: + return {{3.66902871e-01, 8.66378999e-01, 6.67203300e-01, 4.87743636e-01, 1.82406314e+00, 2.20248453e-02}, {6.14274129e-02, 5.70881727e-01, 7.82965639e+00, 1.32531318e+00, 2.10056032e+01, 9.11853450e-02}}; + case 21: + return {{3.78871777e-01, 9.00022505e-01, 7.15288914e-01, 1.88640973e-02, 4.07945949e-01, 1.61786540e+00}, {6.98910162e-02, 5.21061541e-01, 7.87707920e+00, 8.17512708e-02, 1.11141388e+00, 1.80840759e+01}}; + case 22: + return {{3.62383267e-01, 9.84232966e-01, 7.41715642e-01, 3.62555269e-01, 1.49159390e+00, 1.61659509e-02}, {7.54707114e-02, 4.97757309e-01, 8.17659391e+00, 9.55524906e-01, 1.62221677e+01, 7.33140839e-02}}; + case 23: + return {{3.52961378e-01, 7.46791014e-01, 1.08364068e+00, 1.39013610e+00, 3.31273356e-01, 1.40422612e-02}, {8.19204103e-02, 8.81189511e+00, 5.10646075e-01, 1.48901841e+01, 8.38543079e-01, 6.57432678e-02}}; + case 24: + return {{1.34348379e+00, 5.07040328e-01, 4.26358955e-01, 1.17241826e-02, 5.11966516e-01, 3.38285828e-01}, {1.25814353e+00, 1.15042811e+01, 8.53660389e-02, 6.00177061e-02, 1.53772451e+00, 6.62418319e-01}}; + case 25: + return {{3.26697613e-01, 7.17297000e-01, 1.33212464e+00, 2.80801702e-01, 1.15499241e+00, 1.11984488e-02}, {8.88813083e-02, 1.11300198e+01, 5.82141104e-01, 6.71583145e-01, 1.26825395e+01, 5.32334467e-02}}; + case 26: + return {{3.13454847e-01, 6.89290016e-01, 1.47141531e+00, 1.03298688e+00, 2.58280285e-01, 1.03460690e-02}, {8.99325756e-02, 1.30366038e+01, 6.33345291e-01, 1.16783425e+01, 6.09116446e-01, 4.81610627e-02}}; + case 27: + return {{3.15878278e-01, 1.60139005e+00, 6.56394338e-01, 9.36746624e-01, 9.77562650e-03, 2.38378578e-01}, {9.46683246e-02, 6.99436449e-01, 1.56954403e+01, 1.09392410e+01, 4.37446816e-02, 5.56286483e-01}}; + case 28: + return {{1.72254630e+00, 3.29543044e-01, 6.23007200e-01, 9.43496510e-03, 8.54063515e-01, 2.21073515e-01}, {7.76606908e-01, 1.02262360e-01, 1.94156207e+01, 3.98684596e-02, 1.04078166e+01, 5.10869330e-01}}; + case 29: + return {{3.58774531e-01, 1.76181348e+00, 6.36905053e-01, 7.44930670e-03, 1.89002347e-01, 2.29619589e-01}, {1.06153463e-01, 1.01640995e+00, 1.53659093e+01, 3.85345989e-02, 3.98427790e-01, 9.01419843e-01}}; + case 30: + return {{5.70893973e-01, 1.98908856e+00, 3.06060585e-01, 2.35600223e-01, 3.97061102e-01, 6.85657230e-03}, {1.26534614e-01, 2.17781965e+00, 3.78619003e+01, 3.67019041e-01, 8.66419596e-01, 3.35778823e-02}}; + case 31: + return {{6.25528464e-01, 2.05302901e+00, 2.89608120e-01, 2.07910594e-01, 3.45079617e-01, 6.55634300e-03}, {1.10005650e-01, 2.41095786e+00, 4.78685736e+01, 3.27807224e-01, 7.43139061e-01, 3.09411369e-02}}; + case 32: + return {{5.90952690e-01, 5.39980660e-01, 2.00626188e+00, 7.49705041e-01, 1.83581347e-01, 9.52190740e-03}, {1.18375976e-01, 7.18937433e+01, 1.39304889e+00, 6.89943350e+00, 3.64667232e-01, 2.69888650e-02}}; + case 33: + return {{7.77875218e-01, 5.93848150e-01, 1.95918751e+00, 1.79880226e-01, 8.63267222e-01, 9.59053430e-03}, {1.50733157e-01, 1.42882209e+02, 1.74750339e+00, 3.31800852e-01, 5.85490274e+00, 2.33777569e-02}}; + case 34: + return {{9.58390681e-01, 6.03851342e-01, 1.90828931e+00, 1.73885956e-01, 9.35265145e-01, 8.62254660e-03}, {1.83775557e-01, 1.96819224e+02, 2.15082053e+00, 3.00006024e-01, 4.92471215e+00, 2.12308108e-02}}; + case 35: + return {{1.14136170e+00, 5.18118737e-01, 1.85731975e+00, 1.68217399e-01, 9.75705606e-01, 7.24187870e-03}, {2.18708710e-01, 1.93916682e+02, 2.65755396e+00, 2.71719918e-01, 4.19482500e+00, 1.99325718e-02}}; + case 36: + return {{3.24386970e-01, 1.31732163e+00, 1.79912614e+00, 4.29961430e-03, 1.00429433e+00, 1.62188197e-01}, {6.31317973e+01, 2.54706036e-01, 3.23668394e+00, 1.98965610e-02, 3.61094513e+00, 2.45583672e-01}}; + case 37: + return {{2.90445351e-01, 2.44201329e+00, 7.69435449e-01, 1.58687000e+00, 2.81617590e-03, 1.28663830e-01}, {3.68420227e-02, 1.16013332e+00, 1.69591472e+01, 2.53082574e+00, 1.88577417e-02, 2.10753969e-01}}; + case 38: + return {{1.37373086e-02, 1.97548672e+00, 1.59261029e+00, 1.73263882e-01, 4.66280378e+00, 1.61265060e-03}, {1.87469061e-02, 6.36079230e+00, 2.21992482e-01, 2.01624958e-01, 2.53027803e+01, 1.53610568e-02}}; + case 39: + return {{6.75302747e-01, 4.70286720e-01, 2.63497677e+00, 1.09621746e-01, 9.60348773e-01, 5.28921560e-03}, {6.54331847e-02, 1.06108709e+02, 2.06643540e+00, 1.93131925e-01, 1.63310938e+00, 1.66083821e-02}}; + case 40: + return {{2.64365505e+00, 5.54225147e-01, 7.61376625e-01, 6.02946890e-03, 9.91630530e-02, 9.56782020e-01}, {2.20202699e+00, 1.78260107e+02, 7.67218745e-02, 1.55143296e-02, 1.76175995e-01, 1.54330682e+00}}; + case 41: + return {{6.59532875e-01, 1.84545854e+00, 1.25584405e+00, 1.22253422e-01, 7.06638328e-01, 2.62381590e-03}, {8.66145490e-02, 5.94774398e+00, 6.40851475e-01, 1.66646050e-01, 1.62853268e+00, 8.26257860e-03}}; + case 42: + return {{6.10160120e-01, 1.26544000e+00, 1.97428762e+00, 6.48028962e-01, 2.60380820e-03, 1.13887493e-01}, {9.11628054e-02, 5.06776025e-01, 5.89590381e+00, 1.46634108e+00, 7.84336310e-03, 1.55114340e-01}}; + case 43: + return {{8.55189183e-01, 1.66219641e+00, 1.45575475e+00, 1.05445664e-01, 7.71657112e-01, 2.20992640e-03}, {1.02962151e-01, 7.64907000e+00, 1.01639987e+00, 1.42303338e-01, 1.34659349e+00, 7.90358980e-03}}; + case 44: + return {{4.70847093e-01, 1.58180781e+00, 2.02419818e+00, 1.97036260e-03, 6.26912639e-01, 1.02641320e-01}, {9.33029874e-02, 4.52831347e-01, 7.11489023e+00, 7.56181600e-03, 1.25399858e+00, 1.33786087e-01}}; + case 45: + return {{4.20051553e-01, 1.76266507e+00, 2.02735641e+00, 1.45487180e-03, 6.22809600e-01, 9.91529915e-02}, {9.38882628e-02, 4.64441687e-01, 8.19346046e+00, 7.82704520e-03, 1.17194153e+00, 1.24532839e-01}}; + case 46: + return {{2.10475155e+00, 2.03884487e+00, 1.82067264e-01, 9.52040948e-02, 5.91445248e-01, 1.13328680e-03}, {8.68606470e+00, 3.78924449e-01, 1.42921634e-01, 1.17125900e-01, 1.07843808e+00, 7.80252090e-03}}; + case 47: + return {{2.07981390e+00, 4.43170726e-01, 1.96515215e+00, 5.96130591e-01, 4.78016333e-01, 9.46458470e-02}, {9.92540297e+00, 1.04920104e-01, 6.40103839e-01, 8.89594790e-01, 1.98509407e+00, 1.12744464e-01}}; + case 48: + return {{1.63657549e+00, 2.17927989e+00, 7.71300690e-01, 6.64193880e-01, 7.64563285e-01, 8.61126689e-02}, {1.24540381e+01, 1.45134660e+00, 1.26695757e-01, 7.77659202e-01, 1.66075210e+00, 1.05728357e-01}}; + case 49: + return {{2.24820632e+00, 1.64706864e+00, 7.88679265e-01, 8.12579069e-02, 6.68280346e-01, 6.38467475e-01}, {1.51913507e+00, 1.30113424e+01, 1.06128184e-01, 9.94045620e-02, 1.49742063e+00, 7.18422635e-01}}; + case 50: + return {{2.16644620e+00, 6.88691021e-01, 1.92431751e+00, 5.65359888e-01, 9.18683861e-01, 7.80542213e-02}, {1.13174909e+01, 1.10131285e-01, 6.74464853e-01, 7.33564610e-01, 1.02310312e+01, 9.31104308e-02}}; + case 51: + return {{1.73662114e+00, 9.99871380e-01, 2.13972409e+00, 5.60566526e-01, 9.93772747e-01, 7.37374982e-02}, {8.84334719e-01, 1.38462121e-01, 1.19666432e+01, 6.72672880e-01, 8.72330411e+00, 8.78577715e-02}}; + case 52: + return {{2.09383882e+00, 1.56940519e+00, 1.30941993e+00, 6.98067804e-02, 1.04969537e+00, 5.55594354e-01}, {1.26856869e+01, 1.21236537e+00, 1.66633292e-01, 8.30817576e-02, 7.43147857e+00, 6.17487676e-01}}; + case 53: + return {{1.60186925e+00, 1.98510264e+00, 1.48226200e+00, 5.53807199e-01, 1.11728722e+00, 6.60720847e-02}, {1.95031538e-01, 1.36976183e+01, 1.80304795e+00, 5.67912340e-01, 6.40879878e+00, 7.86615429e-02}}; + case 54: + return {{1.60015487e+00, 1.71644581e+00, 1.84968351e+00, 6.23813648e-02, 1.21387555e+00, 5.54051946e-01}, {2.92913354e+00, 1.55882990e+01, 2.22525983e-01, 7.45581223e-02, 5.56013271e+00, 5.21994521e-01}}; + case 55: + return {{2.95236854e+00, 4.28105721e-01, 1.89599233e+00, 5.48012938e-02, 4.70838600e+00, 5.90356719e-01}, {6.01461952e+00, 4.64151246e+01, 1.80109756e-01, 7.12799633e-02, 4.56702799e+01, 4.70236310e-01}}; + case 56: + return {{3.19434243e+00, 1.98289586e+00, 1.55121052e-01, 6.73222354e-02, 4.48474211e+00, 5.42674414e-01}, {9.27352241e+00, 2.28741632e-01, 3.82000231e-02, 7.30961745e-02, 2.95703565e+01, 4.08647015e-01}}; + case 57: + return {{2.05036425e+00, 1.42114311e-01, 3.23538151e+00, 6.34683429e-02, 3.97960586e+00, 5.20116711e-01}, {2.20348417e-01, 3.96438056e-02, 9.56979169e+00, 6.92443091e-02, 2.53178406e+01, 3.83614098e-01}}; + case 58: + return {{3.22990759e+00, 1.57618307e-01, 2.13477838e+00, 5.01907609e-01, 3.80889010e+00, 5.96625028e-02}, {9.94660135e+00, 4.15378676e-02, 2.40480572e-01, 3.66252019e-01, 2.43275968e+01, 6.59653503e-02}}; + case 59: + return {{1.58189324e-01, 3.18141995e+00, 2.27622140e+00, 3.97705472e+00, 5.58448277e-02, 4.85207954e-01}, {3.91309056e-02, 1.04139545e+01, 2.81671757e-01, 2.61872978e+01, 6.30921695e-02, 3.54234369e-01}}; + case 60: + return {{1.81379417e-01, 3.17616396e+00, 2.35221519e+00, 3.83125763e+00, 5.25889976e-02, 4.70090742e-01}, {4.37324793e-02, 1.07842572e+01, 3.05571833e-01, 2.54745408e+01, 6.02676073e-02, 3.39017003e-01}}; + case 61: + return {{1.92986811e-01, 2.43756023e+00, 3.17248504e+00, 3.58105414e+00, 4.56529394e-01, 4.94812177e-02}, {4.37785970e-02, 3.29336996e-01, 1.11259996e+01, 2.46709586e+01, 3.24990282e-01, 5.76553100e-02}}; + case 62: + return {{2.12002595e-01, 3.16891754e+00, 2.51503494e+00, 4.44080845e-01, 3.36742101e+00, 4.65652543e-02}, {4.57703608e-02, 1.14536599e+01, 3.55561054e-01, 3.11953363e-01, 2.40291435e+01, 5.52266819e-02}}; + case 63: + return {{2.59355002e+00, 3.16557522e+00, 2.29402652e-01, 4.32257780e-01, 3.17261920e+00, 4.37958317e-02}, {3.82452612e-01, 1.17675155e+01, 4.76642249e-02, 2.99719833e-01, 2.34462738e+01, 5.29440680e-02}}; + case 64: + return {{3.19144939e+00, 2.55766431e+00, 3.32681934e-01, 4.14243130e-02, 2.61036728e+00, 4.20526863e-01}, {1.20224655e+01, 4.08338876e-01, 5.85819814e-02, 5.06771477e-02, 1.99344244e+01, 2.85686240e-01}}; + case 65: + return {{2.59407462e-01, 3.16177855e+00, 2.75095751e+00, 2.79247686e+00, 3.85931001e-02, 4.10881708e-01}, {5.04689354e-02, 1.23140183e+01, 4.38337626e-01, 2.23797309e+01, 4.87920992e-02, 2.77622892e-01}}; + case 66: + return {{3.16055396e+00, 2.82751709e+00, 2.75140255e-01, 4.00967160e-01, 2.63110834e+00, 3.61333817e-02}, {1.25470414e+01, 4.67899094e-01, 5.23226982e-02, 2.67614884e-01, 2.19498166e+01, 4.68871497e-02}}; + case 67: + return {{2.88642467e-01, 2.90567296e+00, 3.15960159e+00, 3.91280259e-01, 2.48596038e+00, 3.37664478e-02}, {5.40507687e-02, 4.97581077e-01, 1.27599505e+01, 2.58151831e-01, 2.15400972e+01, 4.50664323e-02}}; + case 68: + return {{3.15573213e+00, 3.11519560e-01, 2.97722406e+00, 3.81563854e-01, 2.40247532e+00, 3.15224214e-02}, {1.29729009e+01, 5.81399387e-02, 5.31213394e-01, 2.49195776e-01, 2.13627616e+01, 4.33253257e-02}}; + case 69: + return {{3.15591970e+00, 3.22544710e-01, 3.05569053e+00, 2.92845100e-02, 3.72487205e-01, 2.27833695e+00}, {1.31232407e+01, 5.97223323e-02, 5.61876773e-01, 4.16534255e-02, 2.40821967e-01, 2.10034185e+01}}; + case 70: + return {{3.10794704e+00, 3.14091221e+00, 3.75660454e-01, 3.61901097e-01, 2.45409082e+00, 2.72383990e-02}, {6.06347847e-01, 1.33705269e+01, 7.29814740e-02, 2.32652051e-01, 2.12695209e+01, 3.99969597e-02}}; + case 71: + return {{3.11446863e+00, 5.39634353e-01, 3.06460915e+00, 2.58563745e-02, 2.13983556e+00, 3.47788231e-01}, {1.38968881e+01, 8.91708508e-02, 6.79919563e-01, 3.82808522e-02, 1.80078788e+01, 2.22706591e-01}}; + case 72: + return {{3.01166899e+00, 3.16284788e+00, 6.33421771e-01, 3.41417198e-01, 1.53566013e+00, 2.40723773e-02}, {7.10401889e-01, 1.38262192e+01, 9.48486572e-02, 2.14129678e-01, 1.55298698e+01, 3.67833690e-02}}; + case 73: + return {{3.20236821e+00, 8.30098413e-01, 2.86552297e+00, 2.24813887e-02, 1.40165263e+00, 3.33740596e-01}, {1.38446369e+01, 1.18381581e-01, 7.66369118e-01, 3.52934622e-02, 1.46148877e+01, 2.05704486e-01}}; + case 74: + return {{9.24906855e-01, 2.75554557e+00, 3.30440060e+00, 3.29973862e-01, 1.09916444e+00, 2.06498883e-02}, {1.28663377e-01, 7.65826479e-01, 1.34471170e+01, 1.98218895e-01, 1.35087534e+01, 3.38918459e-02}}; + case 75: + return {{1.96952105e+00, 1.21726619e+00, 4.10391685e+00, 2.90791978e-02, 2.30696669e-01, 6.08840299e-01}, {4.98830620e+01, 1.33243809e-01, 1.84396916e+00, 2.84192813e-02, 1.90968784e-01, 1.37090356e+00}}; + case 76: + return {{2.06385867e+00, 1.29603406e+00, 3.96920673e+00, 2.69835487e-02, 2.31083999e-01, 6.30466774e-01}, {4.05671697e+01, 1.46559047e-01, 1.82561596e+00, 2.84172045e-02, 1.79765184e-01, 1.38911543e+00}}; + case 77: + return {{2.21522726e+00, 1.37573155e+00, 3.78244405e+00, 2.44643240e-02, 2.36932016e-01, 6.48471412e-01}, {3.24464090e+01, 1.60920048e-01, 1.78756553e+00, 2.82909938e-02, 1.70692368e-01, 1.37928390e+00}}; + case 78: + return {{9.84697940e-01, 2.73987079e+00, 3.61696715e+00, 3.02885602e-01, 2.78370726e-01, 1.52124129e-02}, {1.60910839e-01, 7.18971667e-01, 1.29281016e+01, 1.70134854e-01, 1.49862703e+00, 2.83510822e-02}}; + case 79: + return {{9.61263398e-01, 3.69581030e+00, 2.77567491e+00, 2.95414176e-01, 3.11475743e-01, 1.43237267e-02}, {1.70932277e-01, 1.29335319e+01, 6.89997070e-01, 1.63525510e-01, 1.39200901e+00, 2.71265337e-02}}; + case 80: + return {{1.29200491e+00, 2.75161478e+00, 3.49387949e+00, 2.77304636e-01, 4.30232810e-01, 1.48294351e-02}, {1.83432865e-01, 9.42368371e-01, 1.46235654e+01, 1.55110144e-01, 1.28871670e+00, 2.61903834e-02}}; + case 81: + return {{3.75964730e+00, 3.21195904e+00, 6.47767825e-01, 2.76123274e-01, 3.18838810e-01, 1.31668419e-02}, {1.35041513e+01, 6.66330993e-01, 9.22518234e-02, 1.50312897e-01, 1.12565588e+00, 2.48879842e-02}}; + case 82: + return {{1.00795975e+00, 3.09796153e+00, 3.61296864e+00, 2.62401476e-01, 4.05621995e-01, 1.31812509e-02}, {1.17268427e-01, 8.80453235e-01, 1.47325812e+01, 1.43491014e-01, 1.04103506e+00, 2.39575415e-02}}; + case 83: + return {{1.59826875e+00, 4.38233925e+00, 2.06074719e+00, 1.94426023e-01, 8.22704978e-01, 2.33226953e-02}, {1.56897471e-01, 2.47094692e+00, 5.72438972e+01, 1.32979109e-01, 9.56532528e-01, 2.23038435e-02}}; + case 84: + return {{1.71463223e+00, 2.14115960e+00, 4.37512413e+00, 2.16216680e-02, 1.97843837e-01, 6.52047920e-01}, {9.79262841e+01, 2.10193717e-01, 3.66948812e+00, 1.98456144e-02, 1.33758807e-01, 7.80432104e-01}}; + case 85: + return {{1.48047794e+00, 2.09174630e+00, 4.75246033e+00, 1.85643958e-02, 2.05859375e-01, 7.13540948e-01}, {1.25943919e+02, 1.83803008e-01, 4.19890596e+00, 1.81383503e-02, 1.33035404e-01, 7.03031938e-01}}; + case 86: + return {{6.30022295e-01, 3.80962881e+00, 3.89756067e+00, 2.40755100e-01, 2.62868577e+00, 3.14285931e-02}, {1.40909762e-01, 3.08515540e+01, 6.51559763e-01, 1.08899672e-01, 6.42383261e+00, 2.42346699e-02}}; + case 87: + return {{5.23288135e+00, 2.48604205e+00, 3.23431354e-01, 2.55403596e-01, 5.53607228e-01, 5.75278890e-03}, {8.60599536e+00, 3.04543982e-01, 3.87759096e-02, 1.28717724e-01, 5.36977452e-01, 1.29417790e-02}}; + case 88: + return {{1.44192685e+00, 3.55291725e+00, 3.91259586e+00, 2.16173519e-01, 3.94191605e+00, 4.60422605e-02}, {1.18740873e-01, 1.01739750e+00, 6.31814783e+01, 9.55806441e-02, 3.50602732e+01, 2.20850385e-02}}; + case 89: + return {{1.45864127e+00, 4.18945405e+00, 3.65866182e+00, 2.08479229e-01, 3.16528117e+00, 5.23892556e-02}, {1.07760494e-01, 8.89090649e+01, 1.05088931e+00, 9.09335557e-02, 3.13297788e+01, 2.08807697e-02}}; + case 90: + return {{1.19014064e+00, 2.55380607e+00, 4.68110181e+00, 2.26121303e-01, 3.58250545e-01, 7.82263950e-03}, {7.73468729e-02, 6.59693681e-01, 1.28013896e+01, 1.08632194e-01, 4.56765664e-01, 1.62623474e-02}}; + case 91: + return {{4.68537504e+00, 2.98413708e+00, 8.91988061e-01, 2.24825384e-01, 3.04444846e-01, 9.48162710e-03}, {1.44503632e+01, 5.56438592e-01, 6.69512914e-02, 1.03235396e-01, 4.27255647e-01, 1.77730611e-02}}; + case 92: + return {{4.63343606e+00, 3.18157056e+00, 8.76455075e-01, 2.21685477e-01, 2.72917100e-01, 1.11737298e-02}, {1.63377267e+01, 5.69517868e-01, 6.88860012e-02, 9.84254550e-02, 4.09470917e-01, 1.86215410e-02}}; + case 93: + return {{4.56773888e+00, 3.40325179e+00, 8.61841923e-01, 2.19728870e-01, 2.38176903e-01, 1.38306499e-02}, {1.90992795e+01, 5.90099634e-01, 7.03204851e-02, 9.36334280e-02, 3.93554882e-01, 1.94437286e-02}}; + case 94: + return {{5.45671123e+00, 1.11687906e-01, 3.30260343e+00, 1.84568319e-01, 4.93644263e-01, 3.57484743e+00}, {1.01892720e+01, 3.98131313e-02, 3.14622212e-01, 1.04220860e-01, 4.63080540e-01, 2.19369542e+01}}; + case 95: + return {{5.38321999e+00, 1.23343236e-01, 3.46469090e+00, 1.75437132e-01, 3.39800073e+00, 4.69459519e-01}, {1.07289857e+01, 4.15137806e-02, 3.39326208e-01, 9.98932346e-02, 2.11601535e+01, 4.51996970e-01}}; + case 96: + return {{5.38402377e+00, 3.49861264e+00, 1.88039547e-01, 1.69143137e-01, 3.19595016e+00, 4.64393059e-01}, {1.11211419e+01, 3.56750210e-01, 5.39853583e-02, 9.60082633e-02, 1.80694389e+01, 4.36318197e-01}}; + case 97: + return {{3.66090688e+00, 2.03054678e-01, 5.30697515e+00, 1.60934046e-01, 3.04808401e+00, 4.43610295e-01}, {3.84420906e-01, 5.48547131e-02, 1.17150262e+01, 9.21020329e-02, 1.73525367e+01, 4.27132359e-01}}; + case 98: + return {{3.94150390e+00, 5.16915345e+00, 1.61941074e-01, 4.15299561e-01, 2.91761325e+00, 1.51474927e-01}, {4.18246722e-01, 1.25201788e+01, 4.81540117e-02, 4.24913856e-01, 1.90899693e+01, 8.81568925e-02}}; + case 99: + return {{4.09780623e+00, 5.10079393e+00, 1.74617289e-01, 2.76774658e+00, 1.44496639e-01, 4.02772109e-01}, {4.46021145e-01, 1.31768613e+01, 5.02742829e-02, 1.84815393e+01, 8.46232592e-02, 4.17640100e-01}}; + case 100: + return {{4.24934820e+00, 5.03556594e+00, 1.88920613e-01, 3.94356058e-01, 2.61213100e+00, 1.38001927e-01}, {4.75263933e-01, 1.38570834e+01, 5.26975158e-02, 4.11193751e-01, 1.78537905e+01, 8.12774434e-02}}; + case 101: + return {{2.00942931e-01, 4.40119869e+00, 4.97250102e+00, 2.47530599e+00, 3.86883197e-01, 1.31936095e-01}, {5.48366518e-02, 5.04248434e-01, 1.45721366e+01, 1.72978308e+01, 4.05043898e-01, 7.80821071e-02}}; + case 102: + return {{2.16052899e-01, 4.91106799e+00, 4.54862870e+00, 2.36114249e+00, 1.26277292e-01, 3.81364501e-01}, {5.83584058e-02, 1.53264212e+01, 5.34434760e-01, 1.68164803e+01, 7.50304633e-02, 3.99305852e-01}}; + case 103: + return {{4.86738014e+00, 3.19974401e-01, 4.58872425e+00, 1.21482448e-01, 2.31639872e+00, 3.79258137e-01}, {1.60320520e+01, 6.70871138e-02, 5.77039373e-01, 7.22275899e-02, 1.41279737e+01, 3.89973484e-01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + LNL_Coef_cpu load_feg_weickenmeier_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 2: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.542e+00, 8.743e+00, 1.269e+01, 4.371e-01, 5.294e+00, 2.825e+01}}; + case 3: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {6.845e-01, 3.065e+00, 6.240e+00, 1.262e+02, 1.312e+02, 1.318e+02}}; + case 4: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {5.400e-01, 3.388e+00, 5.562e+01, 5.078e+01, 6.701e+01, 9.637e+01}}; + case 5: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {3.314e-01, 2.975e+00, 3.401e+01, 3.598e+01, 3.668e+01, 6.081e+01}}; + case 6: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.946e-01, 3.934e+00, 2.498e+01, 2.528e+01, 2.547e+01, 4.670e+01}}; + case 7: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.393e-01, 4.935e+00, 1.812e+01, 1.570e+01, 1.582e+01, 4.024e+01}}; + case 8: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {6.376e+00, 8.037e+00, 2.721e+01, 1.116e-01, 3.869e-01, 1.090e+01}}; + case 9: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.180e-01, 6.770e+00, 7.051e+00, 6.675e+00, 1.238e+01, 2.808e+01}}; + case 10: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.006e-01, 5.498e+00, 6.281e+00, 7.192e+00, 7.548e+00, 2.326e+01}}; + case 11: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.190e-01, 5.300e+00, 5.319e+00, 5.283e+00, 5.285e+00, 1.282e+02}}; + case 12: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.976e+00, 2.809e+00, 1.639e+01, 5.490e-02, 2.061e+00, 1.217e+02}}; + case 13: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.297e+00, 2.358e+00, 2.499e+01, 7.460e-02, 5.595e-01, 1.285e+02}}; + case 14: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.737e+00, 3.043e+00, 3.057e+01, 5.070e-02, 9.918e-01, 8.618e+01}}; + case 15: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.795e-01, 2.632e+00, 2.676e+00, 3.457e+01, 3.678e+01, 5.406e+01}}; + case 16: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.006e+00, 4.904e+00, 3.135e+01, 3.700e-02, 9.870e-01, 4.494e+01}}; + case 17: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.846e-01, 1.480e+00, 5.210e+00, 2.479e+01, 3.206e+01, 3.910e+01}}; + case 18: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {2.006e-01, 6.533e+00, 2.272e+01, 1.200e+00, 1.274e+00, 3.626e+01}}; + case 19: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {4.442e-01, 3.367e+00, 1.963e+01, 1.820e-02, 2.351e+01, 2.129e+02}}; + case 20: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {1.827e-01, 2.066e+00, 1.699e+01, 1.158e+01, 1.398e+01, 1.861e+02}}; + case 21: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.425e-01, 1.466e+00, 1.547e+01, 4.243e+00, 9.804e+00, 1.215e+02}}; + case 22: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.278e-01, 1.456e+00, 1.210e+01, 4.617e+00, 1.197e+01, 1.050e+02}}; + case 23: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.313e-01, 1.399e+00, 8.008e+00, 7.981e+00, 1.341e+01, 9.531e+01}}; + case 24: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.231e-01, 2.384e+00, 9.921e+00, 1.648e+00, 1.100e+01, 6.846e+01}}; + case 25: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.817e-01, 3.783e+00, 8.473e+00, 4.690e-02, 8.745e+00, 7.744e+01}}; + case 26: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.470e-01, 6.894e+00, 6.903e+00, 5.690e-02, 3.026e+00, 7.087e+01}}; + case 27: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.071e-01, 3.636e+00, 7.558e+00, 1.280e+00, 5.140e+00, 6.716e+01}}; + case 28: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.107e-01, 1.619e+00, 6.003e+00, 5.975e+00, 6.060e+00, 5.941e+01}}; + case 29: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.129e-01, 1.891e+00, 5.085e+00, 5.073e+00, 5.099e+00, 4.639e+01}}; + case 30: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.021e-01, 1.734e+00, 4.783e+00, 4.807e+00, 5.645e+00, 5.122e+01}}; + case 31: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.064e-01, 1.537e+00, 5.138e+00, 4.743e+00, 5.000e+00, 6.143e+01}}; + case 32: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.580e-02, 1.677e+00, 4.703e+00, 2.912e+00, 7.870e+00, 6.494e+01}}; + case 33: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.430e-02, 2.214e+00, 3.951e+00, 1.521e+00, 1.581e+01, 5.241e+01}}; + case 34: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.250e-02, 1.602e+00, 3.049e+00, 3.185e+00, 1.894e+01, 4.763e+01}}; + case 35: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.250e-02, 1.773e+00, 3.481e+00, 1.884e+00, 2.269e+01, 4.069e+01}}; + case 36: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.932e-01, 2.083e+00, 1.141e+01, 3.330e-02, 2.097e+00, 4.238e+01}}; + case 37: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {1.580e-01, 1.715e+00, 9.392e+00, 1.675e+00, 2.359e+01, 1.525e+02}}; + case 38: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {3.605e-01, 2.128e+00, 1.246e+01, 1.530e-02, 2.108e+00, 1.332e+02}}; + case 39: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.000e-02, 1.414e+00, 2.053e+00, 1.026e+01, 1.075e+01, 9.064e+01}}; + case 40: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {1.009e-01, 1.154e+00, 2.347e+00, 1.058e+01, 1.095e+01, 8.282e+01}}; + case 41: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.240e-02, 1.170e+00, 5.940e+00, 1.306e+00, 1.343e+01, 6.637e+01}}; + case 42: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.354e-01, 1.248e+00, 7.454e+00, 3.540e-02, 9.914e+00, 6.172e+01}}; + case 43: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {4.594e-01, 1.182e+00, 8.317e+00, 3.230e-02, 8.323e+00, 6.498e+01}}; + case 44: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {8.600e-02, 1.396e+00, 1.170e+01, 1.396e+00, 3.452e+00, 5.556e+01}}; + case 45: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.210e-02, 1.113e+00, 7.658e+00, 1.126e+00, 8.325e+00, 4.838e+01}}; + case 46: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {9.010e-02, 1.125e+00, 9.698e+00, 1.085e+00, 5.709e+00, 3.349e+01}}; + case 47: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {8.940e-02, 3.191e+00, 9.100e+00, 8.090e-01, 8.144e-01, 4.134e+01}}; + case 48: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {2.885e-01, 1.613e+00, 8.997e+00, 1.710e-02, 9.467e+00, 5.813e+01}}; + case 49: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {8.950e-02, 1.233e+00, 8.231e+00, 1.224e+00, 7.062e+00, 5.970e+01}}; + case 50: + return {{6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01}, {7.120e-02, 8.553e-01, 6.401e+00, 1.336e+00, 6.382e+00, 5.092e+01}}; + case 51: + return {{6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01}, {3.575e-01, 1.325e+00, 6.517e+00, 3.550e-02, 6.519e+00, 5.081e+01}}; + case 52: + return {{6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01, 6.000e-01}, {5.009e-01, 3.953e+00, 7.628e+00, 3.010e-02, 5.074e-01, 4.963e+01}}; + case 53: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {8.430e-02, 1.130e+00, 8.862e+00, 1.130e+00, 9.132e+00, 5.602e+01}}; + case 54: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.780e-01, 1.621e+00, 1.145e+01, 2.030e-02, 3.275e+00, 5.144e+01}}; + case 55: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.204e-01, 1.537e+00, 9.816e+00, 4.122e+01, 4.262e+01, 2.243e+02}}; + case 56: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.223e-01, 1.449e+00, 9.502e+00, 4.941e+01, 7.495e+01, 2.170e+02}}; + case 57: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {8.930e-02, 1.262e+00, 8.097e+00, 1.203e+00, 1.766e+01, 1.166e+02}}; + case 58: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {8.500e-02, 1.283e+00, 1.122e+01, 1.327e+00, 4.610e+00, 1.122e+02}}; + case 59: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.810e-02, 1.526e+00, 8.590e+00, 1.239e+00, 2.249e+01, 1.400e+02}}; + case 60: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.410e-02, 1.266e+00, 5.988e+00, 1.779e+01, 1.814e+01, 1.326e+02}}; + case 61: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.450e-02, 1.251e+00, 5.912e+00, 1.629e+01, 1.673e+01, 1.279e+02}}; + case 62: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.060e-02, 1.593e+00, 1.064e+01, 1.789e+00, 2.221e+00, 1.246e+02}}; + case 63: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.049e-01, 1.544e+00, 8.652e+00, 7.093e+00, 5.337e+01, 1.837e+02}}; + case 64: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {9.340e-02, 1.387e+00, 7.359e+00, 1.551e+00, 2.082e+01, 1.110e+02}}; + case 65: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {1.019e-01, 1.524e+00, 7.169e+00, 2.086e+01, 4.929e+01, 1.661e+02}}; + case 66: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {8.400e-02, 1.409e+00, 7.140e+00, 1.348e+00, 1.142e+01, 1.080e+02}}; + case 67: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.440e-02, 1.618e+00, 6.271e+00, 4.035e+01, 4.283e+01, 1.306e+02}}; + case 68: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {8.210e-02, 1.251e+00, 4.812e+00, 1.084e+01, 1.090e+01, 1.001e+02}}; + case 69: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.660e-02, 1.602e+00, 5.675e+00, 3.059e+01, 3.113e+01, 1.387e+02}}; + case 70: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.490e-02, 1.602e+00, 5.439e+00, 2.831e+01, 2.928e+01, 1.381e+02}}; + case 71: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.660e-02, 1.568e+00, 5.322e+00, 3.418e+01, 3.525e+01, 1.214e+02}}; + case 72: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.290e-02, 1.555e+00, 5.251e+00, 3.752e+01, 3.888e+01, 1.052e+02}}; + case 73: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {6.300e-02, 8.195e-01, 2.891e+00, 5.543e+00, 5.981e+00, 5.442e+01}}; + case 74: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.900e-02, 1.371e+00, 8.234e+00, 1.383e+00, 1.392e+00, 7.712e+01}}; + case 75: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {5.270e-02, 9.072e-01, 4.438e+00, 9.459e-01, 4.375e+00, 4.398e+01}}; + case 76: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.270e-01, 1.570e+00, 6.345e+00, 1.560e-02, 1.618e+00, 4.616e+01}}; + case 77: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {5.060e-02, 8.677e-01, 5.093e+00, 8.812e-01, 3.569e+00, 3.977e+01}}; + case 78: + return {{5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01, 5.000e-01}, {5.250e-02, 8.377e-01, 3.959e+00, 8.152e-01, 6.442e+00, 3.421e+01}}; + case 79: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {5.493e-01, 1.728e+00, 6.720e+00, 2.640e-02, 7.250e-02, 3.546e+01}}; + case 80: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.194e-01, 1.416e+00, 6.682e+00, 1.470e-02, 1.576e+00, 3.716e+01}}; + case 81: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.246e-01, 1.128e+00, 4.303e+00, 1.490e-02, 7.156e+00, 4.309e+01}}; + case 82: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {6.430e-02, 1.194e+00, 7.393e+00, 1.142e+00, 1.289e+00, 5.113e+01}}; + case 83: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {5.380e-02, 8.672e-01, 1.875e+00, 7.648e+00, 7.868e+00, 4.564e+01}}; + case 84: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {5.011e-01, 1.638e+00, 6.786e+00, 2.190e-02, 8.600e-02, 4.673e+01}}; + case 85: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.232e-01, 1.108e+00, 3.591e+00, 1.010e-02, 1.164e+01, 4.507e+01}}; + case 86: + return {{4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01, 4.000e-01}, {2.115e-01, 1.140e+00, 3.415e+00, 1.190e-02, 1.341e+01, 4.311e+01}}; + case 87: + return {{1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01, 1.000e-01}, {9.440e-02, 1.026e+00, 6.255e+00, 3.251e+01, 3.629e+01, 1.491e+02}}; + case 88: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.300e-02, 1.018e+00, 5.896e+00, 1.031e+00, 2.037e+01, 1.153e+02}}; + case 89: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.520e-02, 9.494e-01, 3.725e+00, 1.758e+01, 1.975e+01, 1.091e+02}}; + case 90: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {6.390e-02, 9.019e-01, 4.657e+00, 9.025e-01, 1.571e+01, 8.370e+01}}; + case 91: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.560e-02, 8.492e-01, 4.010e+00, 1.695e+01, 1.779e+01, 1.002e+02}}; + case 92: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.140e-02, 1.149e+00, 9.212e+00, 9.592e-01, 1.203e+00, 1.043e+02}}; + case 93: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {6.920e-02, 9.810e-01, 5.954e+00, 9.909e-01, 2.206e+01, 9.098e+01}}; + case 94: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.140e-02, 9.577e-01, 6.132e+00, 9.744e-01, 1.567e+01, 8.987e+01}}; + case 95: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.300e-02, 9.327e-01, 6.348e+00, 9.103e-01, 1.326e+01, 8.686e+01}}; + case 96: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {5.780e-02, 7.227e-01, 3.011e+00, 9.219e+00, 9.534e+00, 6.587e+01}}; + case 97: + return {{2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01, 2.000e-01}, {7.090e-02, 7.759e-01, 6.143e+00, 1.790e+00, 1.512e+01, 8.357e+01}}; + case 98: + return {{3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01, 3.000e-01}, {6.160e-02, 8.136e-01, 6.562e+00, 8.381e-01, 4.189e+00, 6.141e+01}}; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 6: Lobato parameterization - Hydrogen functions - [0, 12] + LNL_Coef_cpu load_feg_lobato_neutral_0_12(const dt_int32& Z) + { + switch(Z) + { + case 1: + return {{5.29176831e-02, 5.29176831e-02, 5.29176831e-02, 5.29176831e-02, 5.29176831e-02}, {2.76376891e+00, 2.76376891e+00, 2.76376891e+00, 2.76376891e+00, 2.76376891e+00}}; + case 2: + return {{1.01746701e-01, 9.49040428e-02, -4.11936715e-02, 5.35294712e-02, 1.34533102e-05}, {1.49190903e+00, 1.01103199e+00, 4.90177989e-01, 4.72138286e-01, 2.12409496e-01}}; + case 3: + return {{6.19087696e-01, 1.72226405e+00, -7.92180777e-01, 8.37330297e-02, 1.01449499e-02}, {1.05523100e+01, 9.23192024e+00, 4.76025486e+00, 5.19986629e-01, 2.14180499e-01}}; + case 4: + return {{1.07960296e+00, 7.13181376e-01, -3.91357690e-01, 1.06852397e-01, 1.86710991e-02}, {6.00019121e+00, 4.10317707e+00, 1.37123895e+00, 5.52847624e-01, 1.53891206e-01}}; + case 5: + return {{1.31485796e+00, 2.52792597e-01, -2.02927098e-01, 2.92299408e-02, 3.54602700e-03}, {3.94681811e+00, 1.91365397e+00, 9.58502173e-01, 1.62817106e-01, 7.77361393e-02}}; + case 6: + return {{7.39281714e-01, 7.50964522e-01, -2.54863292e-01, 1.76229905e-02, 1.34442805e-03}, {3.47855496e+00, 1.63563204e+00, 8.30155313e-01, 9.63626578e-02, 5.00164293e-02}}; + case 7: + return {{3.26442391e-01, 8.36000979e-01, -7.21398070e-02, 1.31275300e-02, 5.07714599e-03}, {3.17208099e+00, 1.59607995e+00, 3.68962586e-01, 9.75946933e-02, 4.86027598e-02}}; + case 8: + return {{7.85341978e-01, 2.52642393e-01, -5.85432090e-02, 1.27868997e-02, 1.97321596e-03}, {1.78015697e+00, 8.17416310e-01, 2.44515404e-01, 6.56605288e-02, 3.27121913e-02}}; + case 9: + return {{6.07230484e-01, 4.81327087e-01, -1.94196299e-01, 7.56342197e-03, 7.61223928e-05}, {1.58934402e+00, 5.77747822e-01, 3.46372694e-01, 3.73525992e-02, 1.65033191e-02}}; + case 10: + return {{6.13327866e-05, 4.95682299e-01, 8.31292927e-01, -5.06411910e-01, 5.32641588e-03}, {1.25770597e+01, 1.38210797e+00, 4.62477595e-01, 3.64122301e-01, 2.77422108e-02}}; + case 11: + return {{2.38567805e+00, -5.41312218e-01, 5.80007017e-01, -4.31193784e-02, 4.69793798e-03}, {1.17757797e+01, 5.18739605e+00, 5.75649977e-01, 1.69096500e-01, 2.32259594e-02}}; + case 12: + return {{2.48242688e+00, -4.73447889e-01, 8.96034002e-01, -3.08043092e-01, 3.78086301e-03}, {7.48703098e+00, 1.11762202e+00, 3.95489693e-01, 2.52319604e-01, 1.92819294e-02}}; + case 13: + return {{2.84625793e+00, -5.46510279e-01, 7.44476914e-01, -1.04492702e-01, 3.32048093e-03}, {6.67600107e+00, 7.45036721e-01, 3.77064496e-01, 1.67518005e-01, 1.65107101e-02}}; + case 14: + return {{2.85535312e+00, -4.35813814e-01, 6.98928118e-01, -2.16126293e-01, 3.03548202e-03}, {5.05003214e+00, 5.29675722e-01, 2.47670904e-01, 1.50627494e-01, 1.44170700e-02}}; + case 15: + return {{2.83505607e+00, -2.85362303e-01, 2.51688510e-01, -5.73274195e-02, 3.27281700e-03}, {3.81684399e+00, 1.01348305e+00, 1.71625093e-01, 7.74765834e-02, 1.31826401e-02}}; + case 16: + return {{2.71400809e+00, -3.41581792e-01, 2.40847498e-01, -3.09837908e-02, 2.47210590e-03}, {2.95212793e+00, 6.79380417e-01, 1.75853401e-01, 6.52635694e-02, 1.12200603e-02}}; + case 17: + return {{2.53558207e+00, -1.92675203e-01, 1.20515399e-01, -3.50671113e-02, 3.20018711e-03}, {2.74467707e+00, 2.44560409e+00, 9.37200710e-02, 4.38743904e-02, 1.08148400e-02}}; + case 18: + return {{2.39861608e+00, -6.07183397e-01, 5.24528027e-01, -2.69268993e-02, 1.87984400e-03}, {2.05899811e+00, 3.09629112e-01, 1.89788997e-01, 5.85227199e-02, 8.71843286e-03}}; + case 19: + return {{2.46684504e+00, 1.92999494e+00, 1.54350102e-01, -8.12437236e-02, 2.15101591e-03}, {2.41689091e+01, 2.15578604e+00, 6.77528828e-02, 4.73528206e-02, 8.29782058e-03}}; + case 20: + return {{3.55370402e+00, 1.34050202e+00, 6.76007420e-02, -1.39076998e-02, 5.67091210e-03}, {1.34759798e+01, 1.55728805e+00, 6.80236369e-02, 1.71041396e-02, 9.30336956e-03}}; + case 21: + return {{3.44377804e+00, 1.13595498e+00, 6.00283407e-02, 1.71150803e-03, -1.41223101e-03}, {1.11026001e+01, 1.23438895e+00, 8.91299099e-02, 2.11031688e-03, 2.00439896e-03}}; + case 22: + return {{2.24129701e+00, 2.07236791e+00, 9.29673165e-02, -4.03135009e-02, 2.26346403e-03}, {1.70091000e+01, 1.85258400e+00, 4.71124090e-02, 2.76718698e-02, 6.66805590e-03}}; + case 23: + return {{2.92555189e+00, 1.16348600e+00, 4.43377793e-02, -1.35539500e-02, 4.69834497e-03}, {9.08362007e+00, 1.00832999e+00, 4.14920002e-02, 1.35524096e-02, 7.13791978e-03}}; + case 24: + return {{1.64590800e+00, 1.80008602e+00, 5.35616912e-02, -2.09835991e-02, 4.11470514e-03}, {1.21226702e+01, 1.31736004e+00, 3.45182195e-02, 1.51794404e-02, 6.56798482e-03}}; + case 25: + return {{2.39974809e+00, 1.31345499e+00, 5.21507002e-02, -4.50833105e-02, 1.73789803e-02}, {8.79271221e+00, 9.28560615e-01, 2.16320492e-02, 1.14173004e-02, 7.73268519e-03}}; + case 26: + return {{1.84187496e+00, 1.69585705e+00, 4.24552783e-02, 2.01590403e-04, -1.46712104e-04}, {1.19059095e+01, 1.14025199e+00, 5.56822792e-02, 4.73777589e-04, 4.29703505e-04}}; + case 27: + return {{2.13464499e+00, 1.70659602e+00, -5.68710923e-01, 1.51593298e-01, 5.05861302e-04}, {8.62808323e+00, 5.93899727e-01, 2.49489203e-01, 9.49204788e-02, 3.46111390e-03}}; + case 28: + return {{2.31999111e+00, 1.31185806e+00, -6.97869778e-01, 3.42176288e-01, 4.83954413e-04}, {5.89068222e+00, 4.14797008e-01, 1.55506194e-01, 9.88660678e-02, 3.21499701e-03}}; + case 29: + return {{1.23546398e+00, 1.54618704e+00, 2.77369693e-02, -1.17329899e-02, 4.77816490e-03}, {1.07732496e+01, 8.05693388e-01, 2.23376006e-02, 7.92775396e-03, 4.88925213e-03}}; + case 30: + return {{1.99225104e+00, 1.36421597e+00, -5.34584999e-01, 2.10798606e-01, 3.86487402e-04}, {5.84002686e+00, 4.15746897e-01, 1.55540794e-01, 8.27629790e-02, 2.77534500e-03}}; + case 31: + return {{2.66632009e+00, 1.94698906e+00, -1.18554604e+00, 1.21890597e-01, 3.09190800e-04}, {6.34141302e+00, 2.78902292e-01, 1.83026701e-01, 6.34498373e-02, 2.52509094e-03}}; + case 32: + return {{3.44351792e+00, -1.13572204e+00, 1.36060297e+00, 2.05168296e-02, 2.72685196e-04}, {4.83926678e+00, 1.60483098e+00, 5.87697089e-01, 3.27054188e-02, 2.32771295e-03}}; + case 33: + return {{3.23248005e+00, -1.32028103e+00, 1.74037302e+00, 1.42622404e-02, 1.96056702e-04}, {4.26419592e+00, 9.00477171e-01, 5.46430409e-01, 2.42819097e-02, 2.06261105e-03}}; + case 34: + return {{3.63524103e+00, -2.07056499e+00, 2.03258395e+00, 1.16819199e-02, 1.22890197e-04}, {3.28155088e+00, 8.77488911e-01, 5.28532326e-01, 1.97308101e-02, 1.78012101e-03}}; + case 35: + return {{3.69151306e+00, -1.79441595e+00, 1.62838995e+00, 7.51289679e-03, 5.47963391e-05}, {2.62788510e+00, 7.07726896e-01, 4.17159408e-01, 1.39476703e-02, 1.39450806e-03}}; + case 36: + return {{3.31220102e+00, -5.70945084e-01, 6.97833002e-01, 9.94181167e-03, 1.29992593e-04}, {2.61677909e+00, 9.20762420e-01, 3.22337389e-01, 1.78531203e-02, 1.64635398e-03}}; + case 37: + return {{2.98498106e+00, 2.36873889e+00, 5.00381887e-01, 7.34424405e-03, 4.27639898e-05}, {2.40395908e+01, 2.55953598e+00, 2.63484299e-01, 1.31538603e-02, 1.21721299e-03}}; + case 38: + return {{4.12212515e+00, 1.92479300e+00, 4.70577389e-01, 7.04240007e-03, 3.69832087e-05}, {1.62667599e+01, 2.20284200e+00, 2.45777294e-01, 1.25011001e-02, 1.12981803e-03}}; + case 39: + return {{3.74598193e+00, 2.12386703e+00, 4.42405105e-01, 5.74155105e-03, 1.75479108e-05}, {1.34013996e+01, 2.35688090e+00, 2.22515702e-01, 1.05318800e-02, 8.94146215e-04}}; + case 40: + return {{3.38130689e+00, 2.25415707e+00, 4.40226912e-01, 6.77093910e-03, 6.23684973e-05}, {1.21639204e+01, 2.35530710e+00, 2.21562207e-01, 1.22107305e-02, 1.17974204e-03}}; + case 41: + return {{2.17703199e+00, 2.78299403e+00, 3.90569508e-01, 4.67265584e-03, 6.22945709e-06}, {1.11494303e+01, 2.41581297e+00, 1.92431599e-01, 8.68258812e-03, 6.24530192e-04}}; + case 42: + return {{1.67860794e+00, 3.11303711e+00, 3.46704096e-01, 4.59088618e-03, 9.16880344e-06}, {1.36886101e+01, 2.27832890e+00, 1.75135896e-01, 8.52385256e-03, 6.70720416e-04}}; + case 43: + return {{2.88291001e+00, 2.22659802e+00, 2.98569113e-01, 4.29125316e-03, 9.66334756e-06}, {8.43309307e+00, 1.69386697e+00, 1.55848294e-01, 8.09361599e-03, 6.57025608e-04}}; + case 44: + return {{1.31261802e+00, 3.17361403e+00, 2.85882711e-01, 3.99975199e-03, 8.73038971e-06}, {1.25337400e+01, 1.96410704e+00, 1.46394894e-01, 7.61754299e-03, 6.17400685e-04}}; + case 45: + return {{1.44103205e+00, 2.94216609e+00, 2.32040107e-01, 3.09590693e-03, 2.05679089e-06}, {1.03466597e+01, 1.64708400e+00, 1.23005100e-01, 6.30735699e-03, 3.96098098e-04}}; + case 46: + return {{2.02130705e-01, 3.35615706e+00, 2.30525196e-01, 3.56838107e-03, 4.97298106e-06}, {1.69279804e+01, 1.69309103e+00, 1.22913197e-01, 6.80784881e-03, 4.96210472e-04}}; + case 47: + return {{1.21013403e+00, 2.92162895e+00, 1.98055595e-01, 3.18102399e-03, 8.53895926e-06}, {1.01067600e+01, 1.43554401e+00, 1.08165003e-01, 6.40084315e-03, 5.55367384e-04}}; + case 48: + return {{1.60705805e+00, 2.81508899e+00, 1.91956207e-01, 2.63145100e-03, 1.84189503e-06}, {9.29942894e+00, 1.37371194e+00, 1.02014497e-01, 5.39610581e-03, 3.47371009e-04}}; + case 49: + return {{2.70126796e+00, 2.29345989e+00, 2.16367900e-01, 3.69811291e-03, 1.95252096e-06}, {8.33631229e+00, 1.19331098e+00, 1.16310202e-01, 6.37960806e-03, 3.49309004e-04}}; + case 50: + return {{2.87292099e+00, 2.40417600e+00, 1.57168493e-01, 1.89157098e-03, 7.62896207e-06}, {8.46732521e+00, 1.12822700e+00, 8.41042623e-02, 4.36692312e-03, 4.75006207e-04}}; + case 51: + return {{3.50419807e+00, 1.83627403e+00, 1.50732994e-01, 3.59381200e-03, 1.05334497e-04}, {5.89424086e+00, 9.22941923e-01, 8.61572027e-02, 8.35711230e-03, 8.86740920e-04}}; + case 52: + return {{3.21798110e+00, 2.05408001e+00, 2.15190396e-01, 2.72924802e-03, 2.24804194e-06}, {5.26334810e+00, 1.19520295e+00, 1.02286197e-01, 5.08707995e-03, 3.28804512e-04}}; + case 53: + return {{4.13265181e+00, 1.18767595e+00, 1.35713801e-01, 1.50258699e-03, 1.33380800e-05}, {3.71807408e+00, 7.28209019e-01, 7.14013129e-02, 3.71678802e-03, 5.00523078e-04}}; + case 54: + return {{3.51788712e+00, 1.66314995e+00, 2.16246501e-01, 2.76901806e-03, 8.36265008e-06}, {3.94756007e+00, 1.07487500e+00, 1.00129701e-01, 5.00469515e-03, 4.41977201e-04}}; + case 55: + return {{3.81201100e+00, 3.07259011e+00, 1.22549701e+00, 8.76324698e-02, 2.59851106e-04}, {2.28876896e+01, 3.35200000e+00, 5.80402970e-01, 4.92655188e-02, 8.89977906e-04}}; + case 56: + return {{6.35506678e+00, 1.69075298e+00, 9.57290590e-01, 7.86023363e-02, 2.44261813e-04}, {1.39797802e+01, 1.68795502e+00, 5.12502193e-01, 4.48691696e-02, 8.56465078e-04}}; + case 57: + return {{4.28002501e+00, 3.07966208e+00, 1.45083499e+00, 8.27694386e-02, 2.41575995e-04}, {1.66275997e+01, 4.31141520e+00, 6.13337815e-01, 4.52826284e-02, 8.27733311e-04}}; + case 58: + return {{5.13602400e+00, 2.43740010e+00, 1.03740597e+00, 6.99751526e-02, 2.29697005e-04}, {1.42508097e+01, 2.43046999e+00, 4.76604193e-01, 4.05691713e-02, 7.97950372e-04}}; + case 59: + return {{5.35353422e+00, 2.12939692e+00, 9.15245771e-01, 7.25957975e-02, 2.31387705e-04}, {1.41875095e+01, 1.81712794e+00, 4.47230697e-01, 4.14027907e-02, 7.73125212e-04}}; + case 60: + return {{5.32854700e+00, 1.72848594e+00, 1.11297500e+00, 7.37465993e-02, 2.25470707e-04}, {1.31087599e+01, 1.74724901e+00, 4.96911108e-01, 4.08121310e-02, 7.47739687e-04}}; + case 61: + return {{4.36711407e+00, 1.98772097e+00, 1.65877998e+00, 7.46220574e-02, 2.23465599e-04}, {1.53489799e+01, 3.45163202e+00, 5.88005126e-01, 4.03418690e-02, 7.24034617e-04}}; + case 62: + return {{5.13235712e+00, 1.91035604e+00, 8.09289694e-01, 6.53573796e-02, 2.11307895e-04}, {1.30506601e+01, 1.27198803e+00, 4.12205100e-01, 3.68197896e-02, 6.99623721e-04}}; + case 63: + return {{4.25057316e+00, 2.08642793e+00, 1.35467899e+00, 6.16801083e-02, 2.06875600e-04}, {1.51125002e+01, 2.45922089e+00, 4.77150202e-01, 3.51009294e-02, 6.77573611e-04}}; + case 64: + return {{4.78696299e+00, 1.37942696e+00, 1.41249299e+00, 5.88963702e-02, 1.96196401e-04}, {1.08546200e+01, 2.08167791e+00, 4.78227913e-01, 3.32649015e-02, 6.55558892e-04}}; + case 65: + return {{4.72020006e+00, 1.16532505e+00, 1.50215197e+00, 6.71210736e-02, 2.09402002e-04}, {1.22190304e+01, 1.67899096e+00, 5.07295787e-01, 3.62123288e-02, 6.38881815e-04}}; + case 66: + return {{4.22459507e+00, 1.57796502e+00, 1.44352305e+00, 6.22941405e-02, 1.98618902e-04}, {1.33922796e+01, 2.03565693e+00, 4.68585610e-01, 3.41081098e-02, 6.18939695e-04}}; + case 67: + return {{3.68242311e+00, 1.69007802e+00, 1.73174500e+00, 6.26287907e-02, 1.94016204e-04}, {1.36538200e+01, 3.38136411e+00, 5.00155091e-01, 3.36822011e-02, 6.00808591e-04}}; + case 68: + return {{3.65319490e+00, 1.80632806e+00, 1.50050402e+00, 4.83703911e-02, 1.80868403e-04}, {1.33160105e+01, 2.66234398e+00, 4.23525512e-01, 2.84032505e-02, 5.81026427e-04}}; + case 69: + return {{2.81324100e+00, 2.29724407e+00, 1.71350300e+00, 5.38761392e-02, 1.82238698e-04}, {1.63576298e+01, 3.92391706e+00, 4.60097700e-01, 2.98996102e-02, 5.65685797e-04}}; + case 70: + return {{3.86458898e+00, 1.25103104e+00, 1.50890696e+00, 4.87409793e-02, 1.76625705e-04}, {1.09293900e+01, 2.05829406e+00, 4.10406888e-01, 2.79810801e-02, 5.49290911e-04}}; + case 71: + return {{2.78422499e+00, 2.18659902e+00, 1.62505805e+00, 5.04949987e-02, 1.76768895e-04}, {1.05224104e+01, 4.15039682e+00, 4.16781306e-01, 2.84288507e-02, 5.34839579e-04}}; + case 72: + return {{1.82888401e+00, 3.08626103e+00, 1.56239796e+00, 4.50708307e-02, 1.67344595e-04}, {1.09088402e+01, 4.48407412e+00, 3.92598897e-01, 2.59789601e-02, 5.18937595e-04}}; + case 73: + return {{1.34293997e+00, 3.54547095e+00, 1.43781698e+00, 4.28609811e-02, 1.62209704e-04}, {1.22230902e+01, 3.98015690e+00, 3.64430696e-01, 2.49023698e-02, 5.04579220e-04}}; + case 74: + return {{1.11627996e+00, 3.81305695e+00, 1.27436197e+00, 3.69497910e-02, 1.52609398e-04}, {1.21982803e+01, 3.51693296e+00, 3.22148204e-01, 2.25107409e-02, 4.89797501e-04}}; + case 75: + return {{1.15703595e+00, 3.75507998e+00, 1.18611205e+00, 3.35603990e-02, 1.41277094e-04}, {1.14396601e+01, 3.10535192e+00, 3.00034910e-01, 2.07285509e-02, 4.75228589e-04}}; + case 76: + return {{2.95070696e+00, 1.99730504e+00, 9.92647886e-01, 3.54575291e-02, 1.46259103e-04}, {5.83780003e+00, 1.72655404e+00, 2.71308392e-01, 2.16202103e-02, 4.64655401e-04}}; + case 77: + return {{3.32513905e+00, 1.52911794e+00, 9.36988473e-01, 2.82717198e-02, 1.28554704e-04}, {4.62521505e+00, 1.43798900e+00, 2.50209898e-01, 1.81400497e-02, 4.49112791e-04}}; + case 78: + return {{4.98159796e-01, 4.03055811e+00, 8.52239490e-01, 2.27640904e-02, 1.15693001e-04}, {1.65708504e+01, 2.17498207e+00, 2.20648602e-01, 1.56411994e-02, 4.34708607e-04}}; + case 79: + return {{8.70827496e-01, 3.66290498e+00, 7.21173406e-01, 2.25834902e-02, 1.15950199e-04}, {8.26474285e+00, 1.76541495e+00, 1.96660295e-01, 1.56456195e-02, 4.24816913e-04}}; + case 80: + return {{2.23930812e+00, 2.49683499e+00, 7.04915404e-01, 2.09938809e-02, 9.59475219e-05}, {4.66368914e+00, 1.36597097e+00, 1.94375604e-01, 1.40903797e-02, 4.09117813e-04}}; + case 81: + return {{2.71713591e+00, 2.91902208e+00, 7.08489776e-01, 1.79738607e-02, 8.45634204e-05}, {8.71158314e+00, 1.45481896e+00, 1.87859505e-01, 1.23882899e-02, 3.94706090e-04}}; + case 82: + return {{3.29438901e+00, 2.66650391e+00, 5.41207910e-01, 1.59845799e-02, 9.09762530e-05}, {7.26526308e+00, 1.15847301e+00, 1.53856993e-01, 1.19057801e-02, 3.87974986e-04}}; + case 83: + return {{2.90801311e+00, 2.94222403e+00, 6.40052676e-01, 1.98365692e-02, 1.03154103e-04}, {7.08211708e+00, 1.40495801e+00, 1.71940193e-01, 1.36806397e-02, 3.83776205e-04}}; + case 84: + return {{4.17358112e+00, 1.43807697e+00, 5.06418884e-01, 1.17866602e-02, 3.70279995e-05}, {3.63485503e+00, 7.84012079e-01, 1.42200202e-01, 8.50070175e-03, 3.35267512e-04}}; + case 85: + return {{4.40665388e+00, 1.68819594e+00, 6.11086190e-01, 1.74588896e-02, 8.35977771e-05}, {4.43530703e+00, 9.95206296e-01, 1.63246498e-01, 1.18547501e-02, 3.61005805e-04}}; + case 86: + return {{4.44254780e+00, 1.57980704e+00, 7.00253785e-01, 1.36486702e-02, 5.30898506e-05}, {3.88471198e+00, 1.23543596e+00, 1.67034298e-01, 9.34090279e-03, 3.36916302e-04}}; + case 87: + return {{4.44422293e+00, 3.84529591e+00, 6.47594690e-01, 1.57298408e-02, 8.11556311e-05}, {1.55769997e+01, 1.69413495e+00, 1.57903805e-01, 1.09456200e-02, 3.44481290e-04}}; + case 88: + return {{5.84577084e+00, 3.43635201e+00, 6.62875414e-01, 1.30639505e-02, 4.20832803e-05}, {1.44227695e+01, 1.58868802e+00, 1.56904906e-01, 8.72127432e-03, 3.15123296e-04}}; + case 89: + return {{6.56823683e+00, 3.08116007e+00, 5.87002397e-01, 1.18503897e-02, 3.66903696e-05}, {1.23099003e+01, 1.34582400e+00, 1.42942101e-01, 8.05882178e-03, 3.02906294e-04}}; + case 90: + return {{6.75877714e+00, 2.74244094e+00, 5.82863986e-01, 1.08115301e-02, 1.49991101e-05}, {9.66876411e+00, 1.26876402e+00, 1.39298707e-01, 7.15679117e-03, 2.59494089e-04}}; + case 91: + return {{6.37304688e+00, 2.82305002e+00, 5.40732384e-01, 1.19372196e-02, 5.09942292e-05}, {9.53488636e+00, 1.19764698e+00, 1.32480398e-01, 8.31615925e-03, 3.02768894e-04}}; + case 92: + return {{6.01751184e+00, 3.00574708e+00, 5.04366279e-01, 9.93358810e-03, 1.37084398e-05}, {9.77997780e+00, 1.16927600e+00, 1.23806901e-01, 6.66506588e-03, 2.45529693e-04}}; + case 93: + return {{5.20271587e+00, 3.61388612e+00, 5.22116423e-01, 8.51191860e-03, 1.63058994e-05}, {1.04132996e+01, 1.40175903e+00, 1.19989701e-01, 6.06458494e-03, 2.46154610e-04}}; + case 94: + return {{4.97225809e+00, 3.62590599e+00, 4.27345693e-01, 8.12398084e-03, 1.48722102e-05}, {1.17354097e+01, 1.18188906e+00, 1.05401397e-01, 5.83548006e-03, 2.37660599e-04}}; + case 95: + return {{4.50712395e+00, 3.90453696e+00, 4.45498198e-01, 7.97858369e-03, 8.28391057e-06}, {1.28308401e+01, 1.25748503e+00, 1.06835604e-01, 5.59567707e-03, 2.09513906e-04}}; + case 96: + return {{4.95550919e+00, 3.46335196e+00, 3.79075289e-01, 5.84759377e-03, 2.35737807e-05}, {9.56314087e+00, 1.07623196e+00, 9.16181728e-02, 4.78272792e-03, 2.42163704e-04}}; + case 97: + return {{4.87071705e+00, 3.45333791e+00, 3.44667703e-01, 6.47798879e-03, 1.13584201e-05}, {9.75995636e+00, 9.98554826e-01, 8.70402008e-02, 4.92938887e-03, 2.12656101e-04}}; + case 98: + return {{4.32416010e+00, 3.69497395e+00, 3.30316305e-01, 5.58224786e-03, 7.66277208e-06}, {1.12858105e+01, 1.00380003e+00, 8.26271027e-02, 4.33693221e-03, 1.90465493e-04}}; + case 99: + return {{3.96653795e+00, 3.86160207e+00, 3.56552094e-01, 7.00159417e-03, 2.81896791e-05}, {1.22629700e+01, 1.04874003e+00, 8.83088931e-02, 5.31629194e-03, 2.38887806e-04}}; + case 100: + return {{4.27992916e+00, 3.45720100e+00, 2.69533694e-01, 4.48193215e-03, 1.74949400e-05}, {9.27273178e+00, 8.65246892e-01, 6.92421496e-02, 3.92412720e-03, 2.13503794e-04}}; + case 101: + return {{3.94026089e+00, 3.62439609e+00, 2.89608896e-01, 6.40732795e-03, 3.19458813e-05}, {1.02414103e+01, 8.98189783e-01, 7.49766305e-02, 5.15825208e-03, 2.35140804e-04}}; + case 102: + return {{3.96523499e+00, 3.38761902e+00, 3.31892401e-01, 5.65199787e-03, 7.42224984e-06}, {8.30294800e+00, 8.89315307e-01, 8.13126490e-02, 4.15963400e-03, 1.77448994e-04}}; + case 103: + return {{4.46439791e+00, 3.20867705e+00, 2.26712495e-01, 4.08070907e-03, -1.60853798e-03}, {7.96693707e+00, 7.42235303e-01, 5.82330413e-02, 1.39190501e-03, 8.74621095e-04}}; + } + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + // 10: Peng et al. parameterization for Ions- 5 Gaussians - [0, 4] + LNL_Coef_cpu load_feg_peng_ion_0_4(const dt_int32& Z, const dt_int32& charge) + { + switch(Z) + { + case 1: + { + switch(charge) + { + case -1: + return {{1.400e-01, 6.490e-01, 1.370e+00, 3.370e-01, 7.870e-01}, {9.840e-01, 8.670e+00, 3.890e+01, 1.110e+02, 1.660e+02}}; + } + } + break; + case 3: + { + switch(charge) + { + case 1: + return {{4.600e-03, 1.650e-02, 4.350e-02, 6.490e-02, 2.700e-02}, {3.580e-02, 2.390e-01, 8.790e-01, 2.640e+00, 7.090e+00}}; + } + } + break; + case 4: + { + switch(charge) + { + case 2: + return {{3.400e-03, 1.030e-02, 2.330e-02, 3.250e-02, 1.200e-02}, {2.670e-02, 1.620e-01, 5.310e-01, 1.480e+00, 3.880e+00}}; + } + } + break; + case 8: + { + switch(charge) + { + case -1: + return {{2.050e-01, 6.280e-01, 1.170e+00, 1.030e+00, 2.900e-01}, {3.970e-01, 2.640e+00, 8.800e+00, 2.710e+01, 9.180e+01}}; + case -2: + return {{4.210e-02, 2.100e-01, 8.520e-01, 1.820e+00, 1.170e+00}, {6.090e-02, 5.590e-01, 2.960e+00, 1.150e+01, 3.770e+01}}; + } + } + break; + case 9: + { + switch(charge) + { + case -1: + return {{1.340e-01, 3.910e-01, 8.140e-01, 9.280e-01, 3.470e-01}, {2.280e-01, 1.470e+00, 4.680e+00, 1.320e+01, 3.600e+01}}; + } + } + break; + case 11: + { + switch(charge) + { + case 1: + return {{2.560e-02, 9.190e-02, 2.970e-01, 5.140e-01, 1.990e-01}, {3.970e-02, 2.870e-01, 1.180e+00, 3.750e+00, 1.080e+01}}; + } + } + break; + case 12: + { + switch(charge) + { + case 2: + return {{2.100e-02, 6.720e-02, 1.980e-01, 3.680e-01, 1.740e-01}, {3.310e-02, 2.220e-01, 8.380e-01, 2.480e+00, 6.750e+00}}; + } + } + break; + case 13: + { + switch(charge) + { + case 3: + return {{1.920e-02, 5.790e-02, 1.630e-01, 2.840e-01, 1.140e-01}, {3.060e-02, 1.980e-01, 7.130e-01, 2.040e+00, 5.250e+00}}; + } + } + break; + case 14: + { + switch(charge) + { + case 4: + return {{1.920e-01, 2.890e-01, 1.000e-01, -7.280e-02, 1.200e-03}, {3.590e-01, 1.960e+00, 9.340e+00, 1.110e+01, 1.340e+01}}; + } + } + break; + case 17: + { + switch(charge) + { + case -1: + return {{2.650e-01, 5.960e-01, 1.600e+00, 2.690e+00, 1.230e+00}, {2.520e-01, 1.560e+00, 6.210e+00, 1.780e+01, 4.780e+01}}; + } + } + break; + case 19: + { + switch(charge) + { + case 1: + return {{1.990e-01, 3.960e-01, 9.280e-01, 1.450e+00, 4.500e-01}, {1.920e-01, 1.100e+00, 3.910e+00, 9.750e+00, 2.340e+01}}; + } + } + break; + case 20: + { + switch(charge) + { + case 2: + return {{1.640e-01, 3.270e-01, 7.430e-01, 1.160e+00, 3.070e-01}, {1.570e-01, 8.940e-01, 3.150e+00, 7.670e+00, 1.770e+01}}; + } + } + break; + case 21: + { + switch(charge) + { + case 3: + return {{1.630e-01, 3.070e-01, 7.160e-01, 8.800e-01, 1.390e-01}, {1.570e-01, 8.990e-01, 3.060e+00, 7.050e+00, 1.610e+01}}; + } + } + break; + case 22: + { + switch(charge) + { + case 2: + return {{3.990e-01, 1.040e+00, 1.210e+00, -7.970e-02, 3.520e-01}, {3.760e-01, 2.740e+00, 8.100e+00, 1.420e+01, 2.320e+01}}; + case 3: + return {{3.640e-01, 9.190e-01, 1.350e+00, -9.330e-01, 5.890e-01}, {3.640e-01, 2.670e+00, 8.180e+00, 1.180e+01, 1.490e+01}}; + case 4: + return {{1.160e-01, 2.560e-01, 5.650e-01, 7.720e-01, 1.320e-01}, {1.080e-01, 6.550e-01, 2.380e+00, 5.510e+00, 1.230e+01}}; + } + } + break; + case 23: + { + switch(charge) + { + case 2: + return {{3.170e-01, 9.390e-01, 1.490e+00, -1.310e+00, 1.470e+00}, {2.690e-01, 2.090e+00, 7.220e+00, 1.520e+01, 1.760e+01}}; + case 3: + return {{3.410e-01, 8.050e-01, 9.420e-01, 7.830e-02, 1.560e-01}, {3.210e-01, 2.230e+00, 5.990e+00, 1.340e+01, 1.690e+01}}; + case 5: + return {{3.670e-02, 1.240e-01, 2.440e-01, 7.230e-01, 4.350e-01}, {3.300e-02, 2.220e-01, 8.240e-01, 2.800e+00, 6.700e+00}}; + } + } + break; + case 24: + { + switch(charge) + { + case 2: + return {{2.370e-01, 6.340e-01, 1.230e+00, 7.130e-01, 8.590e-02}, {1.770e-01, 1.350e+00, 4.300e+00, 1.220e+01, 3.900e+01}}; + case 3: + return {{3.930e-01, 1.050e+00, 1.620e+00, -1.150e+00, 4.070e-01}, {3.590e-01, 2.570e+00, 8.680e+00, 1.100e+01, 1.580e+01}}; + case 4: + return {{1.320e-01, 2.920e-01, 7.030e-01, 6.920e-01, 9.590e-02}, {1.090e-01, 6.950e-01, 2.390e+00, 5.650e+00, 1.470e+01}}; + } + } + break; + case 25: + { + switch(charge) + { + case 2: + return {{5.760e-02, 2.100e-01, 6.040e-01, 1.320e+00, 6.590e-01}, {3.980e-02, 2.840e-01, 1.290e+00, 4.230e+00, 1.450e+01}}; + case 3: + return {{1.160e-01, 5.230e-01, 8.810e-01, 5.890e-01, 2.140e-01}, {1.170e-02, 8.760e-01, 3.060e+00, 6.440e+00, 1.430e+01}}; + case 4: + return {{3.810e-01, 1.830e+00, -1.330e+00, 9.950e-01, 6.180e-02}, {3.540e-01, 2.720e+00, 3.470e+00, 5.470e+00, 1.610e+01}}; + } + } + break; + case 26: + { + switch(charge) + { + case 2: + return {{3.070e-01, 8.380e-01, 1.110e+00, 2.800e-01, 2.770e-01}, {2.300e-01, 1.620e+00, 4.870e+00, 1.070e+01, 1.920e+01}}; + case 3: + return {{1.980e-01, 3.870e-01, 8.890e-01, 7.090e-01, 1.170e-01}, {1.540e-01, 8.930e-01, 2.620e+00, 6.650e+00, 1.800e+01}}; + } + } + break; + case 27: + { + switch(charge) + { + case 2: + return {{2.130e-01, 4.880e-01, 9.980e-01, 8.280e-01, 2.300e-01}, {1.480e-01, 9.390e-01, 2.780e+00, 7.310e+00, 2.070e+01}}; + case 3: + return {{3.310e-01, 4.870e-01, 7.290e-01, 6.080e-01, 1.310e-01}, {2.670e-01, 1.410e+00, 2.890e+00, 6.450e+00, 1.580e+01}}; + } + } + break; + case 28: + { + switch(charge) + { + case 2: + return {{3.380e-01, 9.820e-01, 1.320e+00, -3.560e+00, 3.620e+00}, {2.370e-01, 1.670e+00, 5.730e+00, 1.140e+01, 1.210e+01}}; + case 3: + return {{3.470e-01, 8.770e-01, 7.900e-01, 5.380e-02, 1.920e-01}, {2.600e-01, 1.710e+00, 4.750e+00, 7.510e+00, 1.300e+01}}; + } + } + break; + case 29: + { + switch(charge) + { + case 1: + return {{3.120e-01, 8.120e-01, 1.110e+00, 7.940e-01, 2.570e-01}, {2.010e-01, 1.310e+00, 3.800e+00, 1.050e+01, 2.820e+01}}; + case 2: + return {{2.240e-01, 5.440e-01, 9.700e-01, 7.270e-01, 1.820e-01}, {1.450e-01, 9.330e-01, 2.690e+00, 7.110e+00, 1.940e+01}}; + } + } + break; + case 30: + { + switch(charge) + { + case 2: + return {{2.520e-01, 6.000e-01, 9.170e-01, 6.630e-01, 1.610e-01}, {1.610e-01, 1.010e+00, 2.760e+00, 7.080e+00, 1.900e+01}}; + } + } + break; + case 31: + { + switch(charge) + { + case 3: + return {{3.910e-01, 9.470e-01, 6.900e-01, 7.090e-02, 6.530e-02}, {2.640e-01, 1.650e+00, 4.820e+00, 1.070e+01, 1.520e+01}}; + } + } + break; + case 32: + { + switch(charge) + { + case 4: + return {{3.460e-01, 8.300e-01, 5.990e-01, 9.490e-02, -2.170e-02}, {2.320e-01, 1.450e+00, 4.080e+00, 1.320e+01, 2.950e+01}}; + } + } + break; + case 35: + { + switch(charge) + { + case -1: + return {{1.250e-01, 5.630e-01, 1.430e+00, 3.520e+00, 3.220e+00}, {5.300e-02, 4.690e-01, 2.150e+00, 1.110e+01, 3.890e+01}}; + } + } + break; + case 37: + { + switch(charge) + { + case 1: + return {{3.680e-01, 8.840e-01, 1.140e+00, 2.260e+00, 8.810e-01}, {1.870e-01, 1.120e+00, 3.980e+00, 1.090e+01, 2.660e+01}}; + } + } + break; + case 38: + { + switch(charge) + { + case 2: + return {{3.460e-01, 8.040e-01, 9.880e-01, 1.890e+00, 6.090e-01}, {1.760e-01, 1.040e+00, 3.590e+00, 9.320e+00, 2.140e+01}}; + } + } + break; + case 39: + { + switch(charge) + { + case 3: + return {{4.650e-01, 9.230e-01, 2.410e+00, -2.310e+00, 2.480e+00}, {2.400e-01, 1.430e+00, 6.450e+00, 9.970e+00, 1.220e+01}}; + } + } + break; + case 40: + { + switch(charge) + { + case 4: + return {{2.340e-01, 6.420e-01, 7.470e-01, 1.470e+00, 3.770e-01}, {1.130e-01, 7.360e-01, 2.540e+00, 6.720e+00, 1.470e+01}}; + } + } + break; + case 41: + { + switch(charge) + { + case 3: + return {{3.770e-01, 7.490e-01, 1.290e+00, 1.610e+00, 4.810e-01}, {1.840e-01, 1.020e+00, 3.800e+00, 9.440e+00, 2.570e+01}}; + case 5: + return {{8.280e-02, 2.710e-01, 6.540e-01, 1.240e+00, 8.290e-01}, {3.690e-02, 2.610e-01, 9.570e-01, 3.940e+00, 9.440e+00}}; + } + } + break; + case 42: + { + switch(charge) + { + case 3: + return {{4.010e-01, 7.560e-01, 1.380e+00, 1.580e+00, 4.970e-01}, {1.910e-01, 1.060e+00, 3.840e+00, 9.380e+00, 2.460e+01}}; + case 5: + return {{4.790e-01, 8.460e-01, 1.560e+01, -1.520e+01, 1.600e+00}, {2.410e-01, 1.460e+00, 6.790e+00, 7.130e+00, 1.040e+01}}; + case 6: + return {{2.030e-01, 5.670e-01, 6.460e-01, 1.160e+00, 1.710e-01}, {9.710e-02, 6.470e-01, 2.280e+00, 5.610e+00, 1.240e+01}}; + } + } + break; + case 44: + { + switch(charge) + { + case 3: + return {{4.280e-01, 7.730e-01, 1.550e+00, 1.460e+00, 4.860e-01}, {1.910e-01, 1.090e+00, 3.820e+00, 9.080e+00, 2.170e+01}}; + case 4: + return {{2.820e-01, 6.530e-01, 1.140e+00, 1.530e+00, 4.180e-01}, {1.250e-01, 7.530e-01, 2.850e+00, 7.010e+00, 1.750e+01}}; + } + } + break; + case 45: + { + switch(charge) + { + case 3: + return {{3.520e-01, 7.230e-01, 1.500e+00, 1.630e+00, 4.990e-01}, {1.510e-01, 8.780e-01, 3.280e+00, 8.160e+00, 2.070e+01}}; + case 4: + return {{3.970e-01, 7.250e-01, 1.510e+00, 1.190e+00, 2.510e-01}, {1.770e-01, 1.010e+00, 3.620e+00, 8.560e+00, 1.890e+01}}; + } + } + break; + case 46: + { + switch(charge) + { + case 2: + return {{9.350e-01, 3.110e+00, 2.460e+01, -4.360e+01, 2.110e+01}, {3.930e-01, 4.060e+00, 4.310e+01, 5.400e+01, 6.980e+01}}; + case 4: + return {{3.480e-01, 6.400e-01, 1.220e+00, 1.450e+00, 4.270e-01}, {1.510e-01, 8.320e-01, 2.850e+00, 6.590e+00, 1.560e+01}}; + } + } + break; + case 47: + { + switch(charge) + { + case 1: + return {{5.030e-01, 9.400e-01, 2.170e+00, 1.990e+00, 7.260e-01}, {1.990e-01, 1.190e+00, 4.050e+00, 1.130e+01, 3.240e+01}}; + case 2: + return {{4.310e-01, 7.560e-01, 1.720e+00, 1.780e+00, 5.260e-01}, {1.750e-01, 9.790e-01, 3.300e+00, 8.240e+00, 2.140e+01}}; + } + } + break; + case 48: + { + switch(charge) + { + case 2: + return {{4.250e-01, 7.450e-01, 1.730e+00, 1.740e+00, 4.870e-01}, {1.680e-01, 9.440e-01, 3.140e+00, 7.840e+00, 2.040e+01}}; + } + } + break; + case 49: + { + switch(charge) + { + case 3: + return {{4.170e-01, 7.550e-01, 1.590e+00, 1.360e+00, 4.510e-01}, {1.640e-01, 9.600e-01, 3.080e+00, 7.030e+00, 1.610e+01}}; + } + } + break; + case 50: + { + switch(charge) + { + case 2: + return {{7.970e-01, 2.130e+00, 2.150e+00, -1.640e+00, 2.720e+00}, {3.170e-01, 2.510e+00, 9.040e+00, 2.420e+01, 2.640e+01}}; + case 4: + return {{2.610e-01, 6.420e-01, 1.530e+00, 1.360e+00, 1.770e-01}, {9.570e-02, 6.250e-01, 2.510e+00, 6.310e+00, 1.590e+01}}; + } + } + break; + case 51: + { + switch(charge) + { + case 3: + return {{5.520e-01, 1.140e+00, 1.870e+00, 1.360e+00, 4.140e-01}, {2.120e-01, 1.420e+00, 4.210e+00, 1.250e+01, 2.900e+01}}; + case 5: + return {{3.770e-01, 5.880e-01, 1.220e+00, 1.180e+00, 2.440e-01}, {1.510e-01, 8.120e-01, 2.400e+00, 5.270e+00, 1.190e+01}}; + } + } + break; + case 53: + { + switch(charge) + { + case -1: + return {{9.010e-01, 2.800e+00, 5.610e+00, -8.690e+00, 1.260e+01}, {3.120e-01, 2.590e+00, 1.410e+01, 3.440e+01, 3.950e+01}}; + } + } + break; + case 55: + { + switch(charge) + { + case 1: + return {{5.870e-01, 1.400e+00, 1.870e+00, 3.480e+00, 1.670e+00}, {2.000e-01, 1.380e+00, 4.120e+00, 1.300e+01, 3.180e+01}}; + } + } + break; + case 56: + { + switch(charge) + { + case 2: + return {{7.330e-01, 2.050e+00, 2.300e+01, -1.520e+02, 1.340e+02}, {2.580e-01, 1.960e+00, 1.180e+01, 1.440e+01, 1.490e+01}}; + } + } + break; + case 57: + { + switch(charge) + { + case 3: + return {{4.930e-01, 1.100e+00, 1.500e+00, 2.700e+00, 1.080e+00}, {1.670e-01, 1.110e+00, 3.110e+00, 9.610e+00, 2.120e+01}}; + } + } + break; + case 58: + { + switch(charge) + { + case 3: + return {{5.600e-01, 1.350e+00, 1.590e+00, 2.630e+00, 7.060e-01}, {1.900e-01, 1.300e+00, 3.930e+00, 1.070e+01, 2.380e+01}}; + case 4: + return {{4.830e-01, 1.090e+00, 1.340e+00, 2.450e+00, 7.970e-01}, {1.650e-01, 1.100e+00, 3.020e+00, 8.850e+00, 1.880e+01}}; + } + } + break; + case 59: + { + switch(charge) + { + case 3: + return {{6.630e-01, 1.730e+00, 2.350e+00, 3.510e-01, 1.590e+00}, {2.260e-01, 1.610e+00, 6.330e+00, 1.100e+01, 1.690e+01}}; + case 4: + return {{5.210e-01, 1.190e+00, 1.330e+00, 2.360e+00, 6.900e-01}, {1.770e-01, 1.170e+00, 3.280e+00, 8.940e+00, 1.930e+01}}; + } + } + break; + case 60: + { + switch(charge) + { + case 3: + return {{5.010e-01, 1.180e+00, 1.450e+00, 2.530e+00, 9.200e-01}, {1.620e-01, 1.080e+00, 3.060e+00, 8.800e+00, 1.960e+01}}; + } + } + break; + case 61: + { + switch(charge) + { + case 3: + return {{4.960e-01, 1.200e+00, 1.470e+00, 2.430e+00, 9.430e-01}, {1.560e-01, 1.050e+00, 3.070e+00, 8.560e+00, 1.920e+01}}; + } + } + break; + case 62: + { + switch(charge) + { + case 3: + return {{5.180e-01, 1.240e+00, 1.430e+00, 2.400e+00, 7.810e-01}, {1.630e-01, 1.080e+00, 3.110e+00, 8.520e+00, 1.910e+01}}; + } + } + break; + case 63: + { + switch(charge) + { + case 2: + return {{6.130e-01, 1.530e+00, 1.840e+00, 2.460e+00, 7.140e-01}, {1.900e-01, 1.270e+00, 4.180e+00, 1.070e+01, 2.620e+01}}; + case 3: + return {{4.960e-01, 1.210e+00, 1.450e+00, 2.360e+00, 7.740e-01}, {1.520e-01, 1.010e+00, 2.950e+00, 8.180e+00, 1.850e+01}}; + } + } + break; + case 64: + { + switch(charge) + { + case 3: + return {{4.900e-01, 1.190e+00, 1.420e+00, 2.300e+00, 7.950e-01}, {1.480e-01, 9.740e-01, 2.810e+00, 7.780e+00, 1.770e+01}}; + } + } + break; + case 65: + { + switch(charge) + { + case 3: + return {{5.030e-01, 1.220e+00, 1.420e+00, 2.240e+00, 7.100e-01}, {1.500e-01, 9.820e-01, 2.860e+00, 7.770e+00, 1.770e+01}}; + } + } + break; + case 66: + { + switch(charge) + { + case 3: + return {{5.030e-01, 1.240e+00, 1.440e+00, 2.170e+00, 6.430e-01}, {1.480e-01, 9.700e-01, 2.880e+00, 7.730e+00, 1.760e+01}}; + } + } + break; + case 67: + { + switch(charge) + { + case 3: + return {{4.560e-01, 1.170e+00, 1.430e+00, 2.150e+00, 6.920e-01}, {1.290e-01, 8.690e-01, 2.610e+00, 7.240e+00, 1.670e+01}}; + } + } + break; + case 68: + { + switch(charge) + { + case 3: + return {{5.220e-01, 1.280e+00, 1.460e+00, 2.050e+00, 5.080e-01}, {1.500e-01, 9.640e-01, 2.930e+00, 7.720e+00, 1.780e+01}}; + } + } + break; + case 69: + { + switch(charge) + { + case 3: + return {{4.750e-01, 1.200e+00, 1.420e+00, 2.050e+00, 5.840e-01}, {1.320e-01, 8.640e-01, 2.600e+00, 7.090e+00, 1.660e+01}}; + } + } + break; + case 70: + { + switch(charge) + { + case 2: + return {{5.080e-01, 1.370e+00, 1.760e+00, 2.230e+00, 5.840e-01}, {1.360e-01, 9.220e-01, 3.120e+00, 8.720e+00, 2.370e+01}}; + case 3: + return {{4.980e-01, 1.220e+00, 1.390e+00, 1.970e+00, 5.590e-01}, {1.380e-01, 8.810e-01, 2.630e+00, 6.990e+00, 1.630e+01}}; + } + } + break; + case 71: + { + switch(charge) + { + case 3: + return {{4.830e-01, 1.210e+00, 1.410e+00, 1.940e+00, 5.220e-01}, {1.310e-01, 8.450e-01, 2.570e+00, 6.880e+00, 1.620e+01}}; + } + } + break; + case 72: + { + switch(charge) + { + case 4: + return {{5.220e-01, 1.220e+00, 1.370e+00, 1.680e+00, 3.120e-01}, {1.450e-01, 8.960e-01, 2.740e+00, 6.910e+00, 1.610e+01}}; + } + } + break; + case 73: + { + switch(charge) + { + case 5: + return {{5.690e-01, 1.260e+00, 9.790e-01, 1.290e+00, 5.510e-01}, {1.610e-01, 9.720e-01, 2.760e+00, 5.400e+00, 1.090e+01}}; + } + } + break; + case 74: + { + switch(charge) + { + case 6: + return {{1.810e-01, 8.730e-01, 1.180e+00, 1.480e+00, 5.620e-01}, {1.180e-02, 4.420e-01, 1.520e+00, 4.350e+00, 9.420e+00}}; + } + } + break; + case 76: + { + switch(charge) + { + case 4: + return {{5.860e-01, 1.310e+00, 1.630e+00, 1.710e+00, 5.400e-01}, {1.550e-01, 9.380e-01, 3.190e+00, 7.840e+00, 1.930e+01}}; + } + } + break; + case 77: + { + switch(charge) + { + case 3: + return {{6.920e-01, 1.370e+00, 1.800e+00, 1.970e+00, 8.040e-01}, {1.820e-01, 1.040e+00, 3.470e+00, 8.510e+00, 2.120e+01}}; + case 4: + return {{6.530e-01, 1.290e+00, 1.500e+00, 1.740e+00, 6.830e-01}, {1.740e-01, 9.920e-01, 3.140e+00, 7.220e+00, 1.720e+01}}; + } + } + break; + case 78: + { + switch(charge) + { + case 2: + return {{8.720e-01, 1.680e+00, 2.630e+00, 1.930e+00, 4.750e-01}, {2.230e-01, 1.350e+00, 4.990e+00, 1.360e+01, 3.300e+01}}; + case 4: + return {{5.500e-01, 1.210e+00, 1.620e+00, 1.950e+00, 6.100e-01}, {1.420e-01, 8.330e-01, 2.810e+00, 7.210e+00, 1.770e+01}}; + } + } + break; + case 79: + { + switch(charge) + { + case 1: + return {{8.110e-01, 1.570e+00, 2.630e+00, 2.680e+00, 9.980e-01}, {2.010e-01, 1.180e+00, 4.250e+00, 1.210e+01, 3.440e+01}}; + case 3: + return {{7.220e-01, 1.390e+00, 1.940e+00, 1.940e+00, 6.990e-01}, {1.840e-01, 1.060e+00, 3.580e+00, 8.560e+00, 2.040e+01}}; + } + } + break; + case 80: + { + switch(charge) + { + case 1: + return {{7.960e-01, 1.560e+00, 2.720e+00, 2.760e+00, 1.180e+00}, {1.940e-01, 1.140e+00, 4.210e+00, 1.240e+01, 3.620e+01}}; + case 2: + return {{7.730e-01, 1.490e+00, 2.450e+00, 2.230e+00, 5.700e-01}, {1.910e-01, 1.120e+00, 4.000e+00, 1.080e+01, 2.760e+01}}; + } + } + break; + case 81: + { + switch(charge) + { + case 1: + return {{8.200e-01, 1.570e+00, 2.780e+00, 2.820e+00, 1.310e+00}, {1.970e-01, 1.160e+00, 4.230e+00, 1.270e+01, 3.570e+01}}; + case 3: + return {{8.360e-01, 1.430e+00, 3.940e-01, 2.510e+00, 1.500e+00}, {2.080e-01, 1.200e+00, 2.570e+00, 4.860e+00, 1.350e+01}}; + } + } + break; + case 82: + { + switch(charge) + { + case 2: + return {{7.550e-01, 1.440e+00, 2.480e+00, 2.450e+00, 1.030e+00}, {1.810e-01, 1.050e+00, 3.750e+00, 1.060e+01, 2.790e+01}}; + case 4: + return {{5.830e-01, 1.140e+00, 1.600e+00, 2.060e+00, 6.620e-01}, {1.440e-01, 7.960e-01, 2.580e+00, 6.220e+00, 1.480e+01}}; + } + } + break; + case 83: + { + switch(charge) + { + case 3: + return {{7.080e-01, 1.350e+00, 2.280e+00, 2.180e+00, 7.970e-01}, {1.700e-01, 9.810e-01, 3.440e+00, 9.410e+00, 2.370e+01}}; + case 5: + return {{6.540e-01, 1.180e+00, 1.250e+00, 1.660e+00, 7.780e-01}, {1.620e-01, 9.050e-01, 2.680e+00, 5.140e+00, 1.120e+01}}; + } + } + break; + case 88: + { + switch(charge) + { + case 2: + return {{9.110e-01, 1.650e+00, 2.530e+00, 3.620e+00, 1.580e+00}, {2.040e-01, 1.260e+00, 4.030e+00, 1.260e+01, 3.000e+01}}; + } + } + break; + case 89: + { + switch(charge) + { + case 3: + return {{9.150e-01, 1.640e+00, 2.260e+00, 3.180e+00, 1.250e+00}, {2.050e-01, 1.280e+00, 3.920e+00, 1.130e+01, 2.510e+01}}; + } + } + break; + case 92: + { + switch(charge) + { + case 3: + return {{1.140e+00, 2.480e+00, 3.610e+00, 1.130e+00, 9.000e-01}, {2.500e-01, 1.840e+00, 7.390e+00, 1.800e+01, 2.270e+01}}; + case 4: + return {{1.090e+00, 2.320e+00, 1.200e+01, -9.110e+00, 2.150e+00}, {2.430e-01, 1.750e+00, 7.790e+00, 8.310e+00, 1.650e+01}}; + case 6: + return {{6.870e-01, 1.140e+00, 1.830e+00, 2.530e+00, 9.570e-01}, {1.540e-01, 8.610e-01, 2.580e+00, 7.700e+00, 1.590e+01}}; + } + } + break; + } + + return {{0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}; + } + + /***************************************************************************************/ + Atomic_Coef_cpu atomic_coef_gaussian(const LNL_Coef_cpu& feg) + { + Atomic_Coef_cpu atomic_coef(feg.size(), T(0)); + + for(auto ik = 0; ik < feg.size(); ik++) + { + auto cl = feg.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(0):feg.cnl[ik]/T(4); + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = T(0.5)*c_2Pi2a0*cl*pow(c_pi/cnl, T(3.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_pi*cl/cnl; + atomic_coef.vzp.cnl[ik] = c_pi2/cnl; + } + } + + return atomic_coef; + } + + // 1: doyle and Turner parameterization - 4 Gaussians - [0, 4] + Atomic_Coef_cpu atomic_coef_doyle_neutral_0_4(const dt_int32& Z) + { + auto feg_coef = load_feg_doyle_neutral_0_4(Z); + + auto atomic_coef = atomic_coef_gaussian(feg_coef); + atomic_coef.atomic_pot_parm_typ = eappt_doyle_0_4; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + return atomic_coef; + } + + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + Atomic_Coef_cpu atomic_coef_peng_neutral_0_4(const dt_int32& Z) + { + auto feg_coef = load_feg_peng_neutral_0_4(Z); + + auto atomic_coef = atomic_coef_gaussian(feg_coef); + + atomic_coef.atomic_pot_parm_typ = eappt_peng_0_4; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + return atomic_coef; + } + + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + Atomic_Coef_cpu atomic_coef_peng_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_peng_neutral_0_12(Z); + + if (feg_coef.size()==0) + { + return {}; + } + + auto atomic_coef = atomic_coef_gaussian(feg_coef); + atomic_coef.atomic_pot_parm_typ = eappt_peng_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + return atomic_coef; + } + + // 4: Kirkland parameterization - 3 yukawa + 3 Gaussians - [0, 12] + Atomic_Coef_cpu atomic_coef_kirkland_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_kirkland_neutral_0_12(Z); + + Atomic_Coef_cpu atomic_coef(feg_coef.size(), T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_kirkland_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + for(auto ik = 0; ik < 3; ik++) + { + auto cl = feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?0.0:feg_coef.cnl[ik]; + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*c_pi*cl*cnl; + atomic_coef.pr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi*cl; + atomic_coef.vr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_2pi*cl; + atomic_coef.vzp.cnl[ik] = c_2pi*::sqrt(cnl); + } + } + + for(auto ik = 3; ik < 6; ik++) + { + auto cl = feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(0):feg_coef.cnl[ik]; + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = T(0.5)*c_2Pi2a0*cl*pow(c_pi/cnl, T(3.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_pi*cl/cnl; + atomic_coef.vzp.cnl[ik] = c_pi2/cnl; + } + } + + return atomic_coef; + } + + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + Atomic_Coef_cpu atomic_coef_weickenmeier_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_weickenmeier_neutral_0_12(Z); + + Atomic_Coef_cpu atomic_coef(feg_coef.size(), T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_weickenmeier_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + for(auto ik = 0; ik < 6; ik++) + { + // 1.0/c_2Pi2a0 = 4.0*0.0239336609991378 + auto cl = Z/(c_2Pi2a0*T(3)*(T(1)+feg_coef.cl[ik])); + cl *= (ik>= 3)?feg_coef.cl[ik]:T(1); + + auto cnl = (fcn_is_zero(cl))?0.0:feg_coef.cnl[ik]/T(4); + cl = (fcn_is_zero(cnl))?T(0):cl; + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi*cl; + atomic_coef.vr.cnl[ik] = c_pi/::sqrt(cnl); + + // there is not analytic expression for the projected potential + atomic_coef.vzp.cl[ik] = atomic_coef.vr.cl[ik]; + atomic_coef.vzp.cnl[ik] = atomic_coef.vr.cnl[ik]; + } + } + + return atomic_coef; + } + + // 6: Lobato parameterization - Hydrogen functions - [0, 12] + Atomic_Coef_cpu atomic_coef_lobato_neutral_0_12(const dt_int32& Z) + { + auto feg_coef = load_feg_lobato_neutral_0_12(Z); + + Atomic_Coef_cpu atomic_coef(feg_coef.size(), T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_lobato_0_12; + atomic_coef.Z = Z; + atomic_coef.charge = 0; + + for(auto ik = 0; ik < 5; ik++) + { + auto cl = (fcn_is_zero(feg_coef.cl[ik]))?T(0):feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(1):feg_coef.cnl[ik]; + + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl/cnl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*c_pi2*cl/pow(cnl, T(2.5)); + atomic_coef.pr.cnl[ik] = c_2pi/::sqrt(cnl); + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi2*cl/pow(cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_2pi/::sqrt(cnl); + + atomic_coef.vzp.cl[ik] = 2.0*c_pot_factor*c_pi2*cl/pow(cnl, T(1.5)); + atomic_coef.vzp.cnl[ik] = c_2pi/::sqrt(cnl); + } + + return atomic_coef; + } + + // 10: Peng et al. parameterization for ions - 5 Gaussians - [0, 4] + Atomic_Coef_cpu atomic_coef_peng_ion_0_4(const dt_int32& Z, const dt_int32& charge) + { + auto feg_coef = load_feg_peng_ion_0_4(Z, charge); + + if (fcn_is_zero(feg_coef.cl[0])) + { + return atomic_coef_peng_neutral_0_4(Z); + } + + Atomic_Coef_cpu atomic_coef(feg_coef.size()+1, T(0)); + atomic_coef.atomic_pot_parm_typ = eappt_peng_ion_0_4; + atomic_coef.Z = Z; + atomic_coef.charge = charge; + + for(auto ik = 0; ik < 5; ik++) + { + auto cl = feg_coef.cl[ik]; + auto cnl = (fcn_is_zero(cl))?T(0):feg_coef.cnl[ik]/T(4); + + if (fcn_is_nzero(cl, cnl)) + { + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = T(0.5)*c_2Pi2a0*cl*pow(c_pi/cnl, T(3.5)); + atomic_coef.pr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vr.cl[ik] = c_pot_factor*cl*pow(c_pi/cnl, T(1.5)); + atomic_coef.vr.cnl[ik] = c_pi2/cnl; + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_pi*cl/cnl; + atomic_coef.vzp.cnl[ik] = c_pi2/cnl; + } + } + + // 1/g2 + if (fcn_is_nzero(feg_coef.cl[0])) + { + dt_int32 ik = 5; + T r0 = 2.0; + auto cl = charge/c_2Pi2a0; + auto cnl = pow(c_2pi*r0, -2); + + atomic_coef.feg.cl[ik] = cl; + atomic_coef.feg.cnl[ik] = cnl; + + atomic_coef.fxg.cl[ik] = c_2Pi2a0*cl; + atomic_coef.fxg.cnl[ik] = cnl; + + atomic_coef.pr.cl[ik] = c_2Pi2a0*c_pi*cl*cnl; + atomic_coef.pr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vr.cl[ik] = c_pot_factor*c_pi*cl; + atomic_coef.vr.cnl[ik] = c_2pi*::sqrt(cnl); + + atomic_coef.vzp.cl[ik] = c_pot_factor*c_2pi*cl; + atomic_coef.vzp.cnl[ik] = c_2pi*::sqrt(cnl); + } + + return atomic_coef; + } + }; + + } +#endif \ No newline at end of file diff --git a/src/atomic_fcns_mt.cuh b/src/atomic_fcns_mt.cuh new file mode 100755 index 00000000..29583a67 --- /dev/null +++ b/src/atomic_fcns_mt.cuh @@ -0,0 +1,512 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ATOMIC_FCNS_MT_H + #define ATOMIC_FCNS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "type_traits_mt.cuh" + #include "intrpl_coef.cuh" + #include "quad_data.cuh" + #include "cgpu_vctr.cuh" + #include "atomic_data_mt.cuh" + #include "cgpu_detail_mt.cuh" + #include "cpu_fcns_mt.hpp" + + #ifdef __CUDACC__ + #include "gpu_fcns_mt.cuh" + #endif + + namespace mt + { + #define SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pfcn, ...) \ + switch(atomic_pot_parm_typ) \ + { \ + case eappt_doyle_0_4: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_peng_0_4: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_peng_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_kirkland_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_weickenmeier_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_lobato_0_12: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + case eappt_peng_ion_0_4: \ + { \ + fcn_eval_fcn_coef_lnl(__VA_ARGS__, cgpu_detail_mt::pfcn()); \ + } \ + break; \ + } + + /************************************** feg ********************************************/ + template + void fcn_feg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const pLNL_Coef& coef, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_feg, g, coef, y); + } + + template + void fcn_feg_dfeg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_feg_dfeg, g, coef, y, dy); + } + + /*************************************** fxg *******************************************/ + template + void fcn_fxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const T& Z, const pLNL_Coef& coef, pVctr_32& y) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, cgpu_detail_mt::pFcn_fxg()); + } + break; + } + } + + template + void fcn_fxg_dfxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& g, const T& Z, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(g, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(g, Z, coef, y, dy, cgpu_detail_mt::pFcn_fxg_dfxg()); + } + break; + } + } + + /*************************************** pr ********************************************/ + template + void fcn_pr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_pr, r, coef, y); + } + + template + void fcn_pr_dpr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_pr_dpr, r, coef, y, dy); + } + + /**************************************** vr *******************************************/ + template + void fcn_vr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vr, r, coef, y); + } + + template + void fcn_vr_dvr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vr_dvr, r, coef, y, dy); + } + + /************************************** vz *********************************************/ + template + void fcn_vz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const T& z_0, const T& z_e, const pLNL_Coef& coef, const pQuad_Coef_1d& quad, pVctr_32& y) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vz, r, z_0, z_e, coef, quad, y); + } + + template + void fcn_vz_dvz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const T& z_0, const T& z_e, const pLNL_Coef& coef, const pQuad_Coef_1d& quad, pVctr_32& y, pVctr_32& dy) + { + SWITCH_FCN_EVAL_FCN_COEF_LNL_VCTR(atomic_pot_parm_typ, pFcn_vz_dvz, r, z_0, z_e, coef, quad, y, dy); + } + + /************************************* vzp *********************************************/ + template + void fcn_vzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pQuad_Coef_1d* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, *pquad, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, cgpu_detail_mt::pFcn_vzp()); + } + break; + } + } + + template + void fcn_vzp_dvzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const pVctr_32& r, const pLNL_Coef& coef, pVctr_32& y, pVctr_32& dy, pQuad_Coef_1d* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_peng_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_peng_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_kirkland_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_weickenmeier_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, *pquad, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_lobato_0_12: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + case eappt_peng_ion_0_4: + { + fcn_eval_fcn_coef_lnl(r, coef, y, dy, cgpu_detail_mt::pFcn_vzp_dvzp()); + } + break; + } + } + + /***************************************************************************************/ + /********************************** atomic fcns ****************************************/ + /***************************************************************************************/ + template + class Atomic_Fcns + { + public: + using value_type = T; + + Atomic_Fcns(): pcoef(nullptr) + { + Quad_Data quad_data; + quad_data(eqt_tanh_sinh_int_n1_p1, c_nqz, quad_a_b); // 1: eqt_tanh_sinh_int_n1_p1 -> int_-1^1 f(x) dx + quad_data(eqt_exp_sinh_int_0_pinfty, c_nqz, quad_0_infty); // 2: eqt_exp_sinh_int_0_pinfty -> int_0^infty f(x) dx + + pquad_a_b = quad_a_b; + pquad_0_infty = quad_0_infty; + } + + Atomic_Fcns(Atomic_Coef_cpu& coef): Atomic_Fcns() + { + set_atomic_coef(coef); + } + + void set_atomic_coef(Atomic_Coef_cpu& coef) + { + pcoef = &coef; + } + + /***************************************************************************************/ + T feg(const T& g) + { + return fcn_feg(pcoef->atomic_pot_parm_typ, g, pcoef->feg); + } + + void feg_dfeg(const T& g, T& y, T& dy) + { + fcn_feg_dfeg(pcoef->atomic_pot_parm_typ, g, pcoef->feg, y, dy); + } + + void feg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y) + { + fcn_feg(pcoef->atomic_pot_parm_typ, g, pcoef->feg, y); + } + + void feg_dfeg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_feg_dfeg(pcoef->atomic_pot_parm_typ, g, pcoef->feg, y, dy); + } + + /***************************************************************************************/ + T fxg(const T& g) + { + return fcn_fxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg); + } + + void fxg_dfxg(const T& g, T& y, T& dy) + { + fcn_fxg_dfxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg, y, dy); + } + + void fxg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y) + { + fcn_fxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg, y); + } + + void fxg_dfxg(const pVctr_cpu_32&& g, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_fxg_dfxg(pcoef->atomic_pot_parm_typ, g, pcoef->Z_diff(), pcoef->fxg, y, dy); + } + + /***************************************************************************************/ + T pr(const T& r) + { + return fcn_pr(pcoef->atomic_pot_parm_typ, r, pcoef->pr); + } + + void pr_dpr(const T& r, T& y, T& dy) + { + fcn_pr_dpr(pcoef->atomic_pot_parm_typ, r, pcoef->pr, y, dy); + } + + void pr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_pr(pcoef->atomic_pot_parm_typ, r, pcoef->pr, y); + } + + void pr_dpr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_pr_dpr(pcoef->atomic_pot_parm_typ, r, pcoef->pr, y, dy); + } + + /***************************************************************************************/ + T vr(const T& r) + { + return fcn_vr(pcoef->atomic_pot_parm_typ, r, pcoef->vr); + } + + void vr_dvr(const T& r, T& y, T& dy) + { + fcn_vr_dvr(pcoef->atomic_pot_parm_typ, r, pcoef->vr, y, dy); + } + + void vr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_vr(pcoef->atomic_pot_parm_typ, r, pcoef->vr, y); + } + + void vr_dvr(const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_vr_dvr(pcoef->atomic_pot_parm_typ, r, pcoef->vr, y, dy); + } + + /***************************************************************************************/ + T vz(const T& z_0, const T& z_e, const T& r) + { + return fcn_vz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b); + } + + void vz_dvz(const T& z_0, const T& z_e, const T& r, T& y, T& dy) + { + fcn_vz_dvz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b, y, dy); + } + + void vz(const T& z_0, const T& z_e, const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_vz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b, y); + } + + void vz_dvz(const T& z_0, const T& z_e, const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_vz_dvz(pcoef->atomic_pot_parm_typ, r, z_0, z_e, pcoef->vr, pquad_a_b, y, dy); + } + + /***************************************************************************************/ + T vzp(const T& r) + { + return fcn_vzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, &pquad_0_infty); + } + + void vzp_dvzp(const T& r, T& y, T& dy) + { + fcn_vzp_dvzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, y, dy, &pquad_0_infty); + } + + void vzp(const pVctr_cpu_32&& r, pVctr_cpu_32&& y) + { + fcn_vzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, y, &pquad_0_infty); + } + + void vzp_dvzp(const pVctr_cpu_32&& r, pVctr_cpu_32&& y, pVctr_cpu_32&& dy) + { + fcn_vzp_dvzp(pcoef->atomic_pot_parm_typ, r, pcoef->vzp, y, dy, &pquad_0_infty); + } + + /***************************************************************************************/ + T atomic_radius_rms(const dt_int32& dim) + { + if (fcn_is_zero(pcoef->vr.cl[0])) + { + return T(0); + } + + auto fcn = [&](const T& r) { return (dim == 3)?vr(r):vzp(r); }; + + KS vr_sum = T(0); + KS vr2_sum = T(0); + for(auto ik = 0; ik < quad_0_infty.size(); ik++) + { + const auto r_ik = quad_0_infty.x[ik]; + const auto vr_ik = quad_0_infty.w[ik]*fcn(r_ik)*pow(r_ik, dim-1); + vr_sum += vr_ik; + vr2_sum += vr_ik*r_ik*r_ik; + } + + return ::sqrt(vr2_sum/vr_sum); + } + + T atomic_radius_cutoff(const dt_int32& dim, const T& vr_lim) + { + if (fcn_is_zero(pcoef->vr.cl[0]) || fabs(vr_lim)<1e-8) + { + return T(0); + } + + auto fcn = [&](const T& r) { return ((dim == 3)?vr(r):vzp(r))-vr_lim; }; + + const T r_min = 1e-5; + const T r_max = 25.0; + + return fcn_fd_root(r_min, r_max, 1e-8, 200, fcn); + } + + private: + Atomic_Coef_cpu* pcoef; + + Quad_Coef_1d_cpu quad_a_b; + Quad_Coef_1d_cpu quad_0_infty; + pQuad_Coef_1d_cpu pquad_a_b; + pQuad_Coef_1d_cpu pquad_0_infty; + }; + + } + +#endif \ No newline at end of file diff --git a/src/atomic_vib.hpp b/src/atomic_vib.hpp new file mode 100755 index 00000000..299fbadd --- /dev/null +++ b/src/atomic_vib.hpp @@ -0,0 +1,129 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ATOMIC_VIB_H + #define ATOMIC_VIB_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "r_3d.h" + + namespace mt + { + /**************** atomic vibration model parameters ******************/ + class Atomic_Vib + { + public: + eAtomic_Vib_Mod model; // 1: Still atom model, 2: Absorptive potential model, 3: Frozen phonon model + dt_bool coh_contrib; // true, false + dt_int32 dist; // 1: Gaussian (Phonon distribution) + dt_int32 seed; // random seed (frozen phonon) + dt_bool sgl_conf; // single configuration: true, false + dt_int32 nconf; // if single phonon configuration == true then phonon configuration if not number of frozen phonon configurations + R_3d dim; // atomic vibration dimension (x, y, z) + + dt_int32 iconf_0; // initial configuration + dt_int32 iconf_e; // final configuration + + Atomic_Vib(): model(eavm_still_atom), coh_contrib(false), sgl_conf(false), dist(1), seed(300183), + nconf(1), iconf_0(1), iconf_e(1), dim{true, true, false}{} + + void assign(Atomic_Vib& atomic_vib) + { + if (this != &atomic_vib) + { + model = atomic_vib.model; + coh_contrib = atomic_vib.coh_contrib; + sgl_conf = atomic_vib.sgl_conf; + dist = atomic_vib.dist; + seed = atomic_vib.seed; + nconf = atomic_vib.nconf; + iconf_0 = atomic_vib.iconf_0; + dim = atomic_vib.dim; + } + } + + void set_in_data(const eAtomic_Vib_Mod& model, const dt_bool& coh_contrib, const dt_bool& sgl_conf, const dt_int32& dist, + const dt_int32& seed, const dt_int32& nconf, const dt_int32& iconf_0, const R_3d& dim) + { + this->model = model; + this->coh_contrib = coh_contrib; + this->sgl_conf = sgl_conf; + this->dist = dist; + this->seed = seed; + this->nconf = nconf; + this->iconf_0 = iconf_0; + this->dim = dim; + + set_dep_var(); + } + + void set_dep_var() + { + seed = max(1, seed); + + if (is_avm_frozen_phonon()) + { + nconf = max(1, nconf); + iconf_0 = (sgl_conf)?nconf:1; + iconf_e = nconf; + } + else + { + iconf_0 = iconf_e = nconf = 1; + } + } + + Atomic_Vib& operator=(Atomic_Vib& atomic_vib) + { + assign(atomic_vib); + return *this; + } + + dt_bool is_avm_still_atom() const + { + return mt::is_avm_still_atom(model); + } + + dt_bool is_avm_absorptive_pot() const + { + return mt::is_avm_absorptive_pot(model); + } + + dt_bool is_avm_frozen_phonon() const + { + return mt::is_avm_frozen_phonon(model); + } + + dt_bool is_avm_frozen_phonon_sgl_conf() const + { + return mt::is_avm_frozen_phonon_sgl_conf(model, sgl_conf); + } + + dt_int32 number_conf() + { + return (nconf-iconf_0+1); + } + }; + } + +#endif \ No newline at end of file diff --git a/src/beam_pos_2d.hpp b/src/beam_pos_2d.hpp new file mode 100755 index 00000000..7e82234a --- /dev/null +++ b/src/beam_pos_2d.hpp @@ -0,0 +1,162 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef BEAM_POS_2D_H + #define BEAM_POS_2D_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + #include + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "type_traits_gen.h" + #include "fcns_cgpu_gen.h" + #include "r_2d.h" + #include "r_3d.h" + #include "particles.cuh" + #include "types.cuh" + + namespace mt + { + template + struct Beam_Pos_2d + { + Vctr idx; // index + Vctr, edev_cpu> p; // xy-position + + Beam_Pos_2d() {} + + Beam_Pos_2d(dt_int32 new_size) { resize(new_size); } + + template + void set_in_data(const TVctr& x) + { + dt_int32 n = x.cols; + resize(n); + for(auto ik = 0; ik(x(0, ik), x(1, ik)); + } + } + + template + void set_in_data(const TVctr& x, const TVctr& y) + { + dt_int32 n = min(x.size(), y.size()); + resize(n); + for(auto ik = 0; ik(x[ik], y[ik]); + } + } + + typename Vctr, edev_cpu>::iterator begin() const + { + return p.begin(); + } + + typename Vctr, edev_cpu>::iterator end() const + { + return p.end(); + } + + dt_int32 size() const { return idx.size(); } + + void resize(dt_int32 new_size) + { + idx.resize(new_size); + p.resize(new_size); + } + + void init() + { + thrust::fill(idx.begin(), idx.end(), 0); + thrust::fill(p.begin(), p.end(), R_2d()); + } + + void clear() + { + idx.clear(); + p.clear(); + } + + void shrink_to_fit() + { + idx.shrink_to_fit(); + p.shrink_to_fit(); + } + + void clear_shrink_to_fit() + { + clear(); + shrink_to_fit(); + } + + Vctr x() + { + Vctr x; + x.reserve(p.size()); + for(auto ik = 0; ik y() + { + Vctr y; + y.reserve(p.size()); + for(auto ik = 0; ik + void assign(TBeam_Pos_2d &beam_pos) + { + resize(beam_pos.size()); + thrust::copy(beam_pos.idx.begin(), beam_pos.idx.end(), idx.begin()); + thrust::copy(beam_pos.p.begin(), beam_pos.p.end(), p.begin()); + } + + template + Beam_Pos_2d& operator=(const TBeam_Pos_2d &beam_pos) + { + assign(beam_pos); + return *this; + } + }; + } + +#endif \ No newline at end of file diff --git a/src/blas.cuh b/src/blas.cuh old mode 100644 new mode 100755 index c87c84aa..216dee2c --- a/src/blas.cuh +++ b/src/blas.cuh @@ -1,141 +1,145 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef BLAS_H -#define BLAS_H - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" - -#include -#include -#include - -namespace bs -{ - template - struct GEAM; - - template - struct GEAM - { - public: - using value_type = T; - using TVector_c = mt::Vector; - - const mt::eDevice device; - - GEAM(): device(mt::e_host) {} - }; - - template - struct GEAM - { - public: - using value_type = T; - using TVector = mt::Vector; - - const mt::eDevice device; - - GEAM(): device(mt::e_device) - { - cublasCreate(&handle); - } - - ~GEAM() - { - cublasDestroy(handle); - } - - void operator()(mt::eOP trsa, mt::eOP trsb, int m, int n, T alpha, TVector &A, T beta, TVector &B, TVector &C) - { - cublasOperation_t transa = op_2_cbop(trsa); - cublasOperation_t transb = op_2_cbop(trsb); - - geam(handle, transa, transb, m, n, alpha, A, m, beta, B, m, C, m); - } - - private: - - cublasOperation_t op_2_cbop(mt::eOP op) - { - return static_cast(static_cast(op)-1); - } - - void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, - int m, int n, float alpha, device_vector &A, int lda, float beta, - device_vector &B, int ldb, device_vector &C, int ldc) - { - float *ralpha = reinterpret_cast(&alpha); - float *rbeta = reinterpret_cast(&beta); - - float *rA = reinterpret_cast(raw_pointer_cast(A.data())); - float *rB = reinterpret_cast(raw_pointer_cast(B.data())); - float *rC = reinterpret_cast(raw_pointer_cast(C.data())); - - auto result = cublasSgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); - } - - void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, - int m, int n, double alpha, device_vector &A, int lda, double beta, - device_vector &B, int ldb, device_vector &C, int ldc) - { - double *ralpha = reinterpret_cast(&alpha); - double *rbeta = reinterpret_cast(&beta); - - double *rA = reinterpret_cast(raw_pointer_cast(A.data())); - double *rB = reinterpret_cast(raw_pointer_cast(B.data())); - double *rC = reinterpret_cast(raw_pointer_cast(C.data())); - - cublasDgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); - } - - void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, - int m, int n, complex alpha, device_vector> &A, int lda, complex beta, - device_vector> &B, int ldb, device_vector> &C, int ldc) - { - cuComplex *ralpha = reinterpret_cast(&alpha); - cuComplex *rbeta = reinterpret_cast(&beta); - - cuComplex *rA = reinterpret_cast(raw_pointer_cast(A.data())); - cuComplex *rB = reinterpret_cast(raw_pointer_cast(B.data())); - cuComplex *rC = reinterpret_cast(raw_pointer_cast(C.data())); - - cublasCgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); - } - - void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, - int m, int n, complex alpha, device_vector> &A, int lda, complex beta, - device_vector> &B, int ldb, device_vector> &C, int ldc) - { - cuDoubleComplex *ralpha = reinterpret_cast(&alpha); - cuDoubleComplex *rbeta = reinterpret_cast(&beta); - - cuDoubleComplex *rA = reinterpret_cast(raw_pointer_cast(A.data())); - cuDoubleComplex *rB = reinterpret_cast(raw_pointer_cast(B.data())); - cuDoubleComplex *rC = reinterpret_cast(raw_pointer_cast(C.data())); - - cublasZgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); - } - - cublasHandle_t handle; - }; -} // namespace blas - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef BLAS_H + #define BLAS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "math_mt.h" + #include "types.cuh" + #include "type_traits_gen.h" + + #include + #include + #include + + namespace blass + { + template + struct GEAM; + + template + struct GEAM + { + public: + using value_type = T; + using TVctr_c = mt::Vctr; + + const mt::eDev device; + + GEAM(): device(mt::edev_cpu) {} + }; + + template + struct GEAM + { + public: + using value_type = T; + using TVctr = mt::Vctr; + + const mt::eDev device; + + GEAM(): device(mt::edev_gpu) + { + cublasCreate(&handle); + } + + ~GEAM() + { + cublasDestroy(handle); + } + + void operator()(mt::eOP trsa, mt::eOP trsb, dt_int32 m, dt_int32 n, T alpha, TVctr& A, T beta, TVctr& B, TVctr& C) + { + cublasOperation_t transa = op_2_cbop(trsa); + cublasOperation_t transb = op_2_cbop(trsb); + + geam(handle, transa, transb, m, n, alpha, A, m, beta, B, m, C, m); + } + + private: + + cublasOperation_t op_2_cbop(mt::eOP op) + { + return static_cast(static_cast(op)-1); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_float32 alpha, mt::Vctr& A, dt_int32 lda, dt_float32 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + dt_float32 *ralpha = reinterpret_cast(&alpha); + dt_float32 *rbeta = reinterpret_cast(&beta); + + dt_float32 *rA = reinterpret_cast(A.data()); + dt_float32 *rB = reinterpret_cast(B.data()); + dt_float32 *rC = reinterpret_cast(C.data()); + + auto result = cublasSgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_float64 alpha, mt::Vctr& A, dt_int32 lda, dt_float64 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + dt_float64 *ralpha = reinterpret_cast(&alpha); + dt_float64 *rbeta = reinterpret_cast(&beta); + + dt_float64 *rA = reinterpret_cast(A.data()); + dt_float64 *rB = reinterpret_cast(B.data()); + dt_float64 *rC = reinterpret_cast(C.data()); + + cublasDgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_cfloat32 alpha, mt::Vctr& A, dt_int32 lda, dt_cfloat32 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + cuComplex *ralpha = reinterpret_cast(&alpha); + cuComplex *rbeta = reinterpret_cast(&beta); + + cuComplex *rA = reinterpret_cast(A.data()); + cuComplex *rB = reinterpret_cast(B.data()); + cuComplex *rC = reinterpret_cast(C.data()); + + cublasCgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + void geam(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, + dt_int32 m, dt_int32 n, dt_cfloat64 alpha, mt::Vctr& A, dt_int32 lda, dt_cfloat64 beta, + mt::Vctr& B, dt_int32 ldb, mt::Vctr& C, dt_int32 ldc) + { + cuDoubleComplex *ralpha = reinterpret_cast(&alpha); + cuDoubleComplex *rbeta = reinterpret_cast(&beta); + + cuDoubleComplex *rA = reinterpret_cast(A.data()); + cuDoubleComplex *rB = reinterpret_cast(B.data()); + cuDoubleComplex *rC = reinterpret_cast(C.data()); + + cublasZgeam(handle, transa, transb, m, n, ralpha, rA, lda, rbeta, rB, ldb, rC, ldc); + } + + cublasHandle_t handle; + }; + } // namespace blas + #endif \ No newline at end of file diff --git a/src/border_1d.h b/src/border_1d.h new file mode 100755 index 00000000..193acd10 --- /dev/null +++ b/src/border_1d.h @@ -0,0 +1,171 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "math_mt.h" +#include "const_enum.h" +#include "fcns_cgpu_gen.h" +#include "vctr_cpu.h" + +/* template definition */ +namespace mt +{ + template class Border_Rect_xd; + + template + using iBorder_Rect_xd = Border_Rect_xd; +} + +/* derived class */ +namespace mt +{ + template + using Border_Rect_1d = Border_Rect_xd; + + using iBorder_Rect_1d = Border_Rect_xd; + + using iBorder_Rect_1d_64 = Border_Rect_xd; +} + +/***************************************************************************************/ +/******************************** rectangular border ***********************************/ +/***************************************************************************************/ +namespace mt +{ + template + using Border_Rect_1d = Border_Rect_xd; + + using iBorder_Rect_1d = Border_Rect_xd; + + using iBorder_Rect_1d_64 = Border_Rect_xd; +} + +/* template specialization 1d */ +namespace mt +{ + template + class Border_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T bx_0; // initial x position + T bx_e; // final x position + + /************************************* constructors ************************************/ + CGPU_EXEC + Border_Rect_xd(); + + Border_Rect_xd(const T& bx_0, const T& bx_e); + + template + Border_Rect_xd(const dt_init_list& list); + + template + Border_Rect_xd(const Vctr_cpu& vctr); + + /* copy constructor */ + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border); + + /* converting constructor */ + template + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border); + + /* converting assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border); + + template + CGPU_EXEC + void assign(const Border_Rect_xd& border); + + /***************************************************************************************/ + template + void set_in_data(const U& bx_0, const U& bx_e); + + template + void set_in_data(const dt_init_list& list); + + template + void set_in_data(const Vctr_cpu& vctr); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T bx_sum() const; + + CGPU_EXEC + T bx_min() const; + + CGPU_EXEC + T bx_max() const; + + CGPU_EXEC + T bs_x(const T& bs_x_i) const; + + CGPU_EXEC + T bs(const T& bs_i) const; + + CGPU_EXEC + T bs_min(const T& bs) const; + + CGPU_EXEC + T bs_max(const T& bs) const; + + CGPU_EXEC + T bs_x_h(const T& bs_x) const; + + CGPU_EXEC + T bs_h(const T& bs) const; + + CGPU_EXEC + T rx_c(const T& bs_x) const; + + CGPU_EXEC + T r_c(const T& bs) const; + + CGPU_EXEC + T radius_x(const T& bs_x) const; + + CGPU_EXEC + T radius(const T& bs) const; + + CGPU_EXEC + T radius_x_p(const T& bs_x, const T& p) const; + + CGPU_EXEC + T radius_p(const T& bs, const T& p) const; + + void set_by_sft(const T& bs, const T& dr); + + void sft_bdr(const T& bs, const T& dr); + }; +} + +#include "detail/border_1d.inl" \ No newline at end of file diff --git a/src/border_2d.h b/src/border_2d.h new file mode 100755 index 00000000..67315845 --- /dev/null +++ b/src/border_2d.h @@ -0,0 +1,147 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "r_2d.h" +#include "border_1d.h" + +/* derived class */ +namespace mt +{ + template + using Border_Rect_2d = Border_Rect_xd; + + using iBorder_Rect_2d = Border_Rect_xd; + + using iBorder_Rect_2d_64 = Border_Rect_xd; +} + +/* template specialization 2d */ +namespace mt +{ + template + class Border_Rect_xd: public Border_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T by_0; // initial y position + T by_e; // final y position + + /************************************* constructors ************************************/ + CGPU_EXEC + Border_Rect_xd(); + + Border_Rect_xd(const T& bx_0, const T& bx_e, const T& by_0, const T& by_e); + + template + Border_Rect_xd(const dt_init_list& list); + + template + Border_Rect_xd(const Vctr_cpu& vctr); + + /* copy constructor */ + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border); + + /* converting constructor */ + template + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border); + + /* converting assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border); + + template + CGPU_EXEC + void assign(const Border_Rect_xd& border); + + /***************************************************************************************/ + template + void set_in_data(const U& bx_0, const U& bx_e, const U& by_0, const U& by_e); + + template + void set_in_data(const dt_init_list& list); + + template + void set_in_data(const Vctr_cpu& vctr); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T by_sum() const; + + CGPU_EXEC + T by_min() const; + + CGPU_EXEC + T by_max() const; + + CGPU_EXEC + T bs_y(const T& bs_y_i) const; + + CGPU_EXEC + R_2d bs(const R_2d& bs_i) const; + + CGPU_EXEC + T bs_min(const R_2d& bs) const; + + CGPU_EXEC + T bs_max(const R_2d& bs) const; + + CGPU_EXEC + T bs_y_h(const T& bs_y) const; + + CGPU_EXEC + R_2d bs_h(const R_2d& bs) const; + + CGPU_EXEC + T ry_c(const T& bs_y) const; + + CGPU_EXEC + R_2d r_c(const R_2d& bs) const; + + CGPU_EXEC + T radius_y(const T& bs_y) const; + + CGPU_EXEC + R_2d radius(const R_2d& bs) const; + + CGPU_EXEC + T radius_y_p(const T& bs_y, const T& p) const; + + CGPU_EXEC + R_2d radius_p(const R_2d& bs, const T& p) const; + + void set_by_sft(const R_2d& bs, const R_2d& dr); + + void sft_bdr(const R_2d& bs, const R_2d& dr); + }; +} + +#include "detail/border_2d.inl" \ No newline at end of file diff --git a/src/border_3d.h b/src/border_3d.h new file mode 100755 index 00000000..d03d2d29 --- /dev/null +++ b/src/border_3d.h @@ -0,0 +1,147 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "r_3d.h" +#include "border_2d.h" + +/* derived class */ +namespace mt +{ + template + using Border_Rect_3d = Border_Rect_xd; + + using iBorder_Rect_3d = Border_Rect_xd; + + using iBorder_Rect_3d_64 = Border_Rect_xd; +} + +/* template specialization 3d */ +namespace mt +{ + template + class Border_Rect_xd: public Border_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T bz_0; // initial z position + T bz_e; // final z position + + /************************************* constructors ************************************/ + CGPU_EXEC + Border_Rect_xd(); + + Border_Rect_xd(const T& bx_0, const T& bx_e, const T& by_0, const T& by_e, const T& bz_0, const T& bz_e); + + template + Border_Rect_xd(const dt_init_list& list); + + template + Border_Rect_xd(const Vctr_cpu& vctr); + + /* copy constructor */ + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border); + + /* converting constructor */ + template + CGPU_EXEC + Border_Rect_xd(const Border_Rect_xd& border); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border); + + /* converting assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& operator=(const Border_Rect_xd& border); + + template + CGPU_EXEC + void assign(const Border_Rect_xd& border); + + /***************************************************************************************/ + template + void set_in_data(const U& bx_0, const U& bx_e, const U& by_0, const U& by_e, const U& bz_0, const U& bz_e); + + template + void set_in_data(const dt_init_list& list); + + template + void set_in_data(const Vctr_cpu& vctr); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T bz_sum() const; + + CGPU_EXEC + T bz_min() const; + + CGPU_EXEC + T bz_max() const; + + CGPU_EXEC + T bs_z(const T& bs_z_i) const; + + CGPU_EXEC + R_3d bs(const R_3d& bs_i) const; + + CGPU_EXEC + T bs_min(const R_3d& bs) const; + + CGPU_EXEC + T bs_max(const R_3d& bs) const; + + CGPU_EXEC + T bs_z_h(const T& bs_z) const; + + CGPU_EXEC + R_3d bs_h(const R_3d& bs) const; + + CGPU_EXEC + T rz_c(const T& bs_z) const; + + CGPU_EXEC + R_3d r_c(const R_3d& bs) const; + + CGPU_EXEC + T radius_z(const T& bs_z) const; + + CGPU_EXEC + R_3d radius(const R_3d& bs) const; + + CGPU_EXEC + T radius_z_p(const T& bs_z, const T& p) const; + + CGPU_EXEC + R_3d radius_p(const R_3d& bs, const T& p) const; + + void set_by_sft(const R_3d& bs, const R_3d& dr); + + void sft_bdr(const R_3d& bs, const R_3d& dr); + }; +} + +#include "detail/border_3d.inl" \ No newline at end of file diff --git a/src/box_occ.hpp b/src/box_occ.hpp old mode 100644 new mode 100755 index 8749d3b4..d6b6fbb2 --- a/src/box_occ.hpp +++ b/src/box_occ.hpp @@ -1,676 +1,665 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef BOX_OCC_H -#define BOX_OCC_H - -#include -#include - -#include "types.cuh" -#include "math.cuh" -#include "lin_alg_def.cuh" -#include "atomic_data_mt.hpp" -#include "stream.cuh" - -namespace mt -{ - template - class Box_Occ - { - public: - Box_Occ(): d_min(0), d2_min(0), a_min(0), l_x(0), l_y(0), l_z(0), nx(0), ny(0), nz(0), nxy(0){}; - - void init() - { - thrust::fill(occ.begin(), occ.end(), T(-1)); - } - - void set_input_data(T d_min_i, T lx_i, T ly_i, T lz_i) - { - d_min = d_min_i; - d2_min = pow(d_min, 2); - a_min = d_min/mt::c_3i2; - l_x = lx_i; - l_y = ly_i; - l_z = lz_i; - nx = static_cast(ceil(l_x/a_min)); - ny = static_cast(ceil(l_y/a_min)); - nz = static_cast(ceil(l_z/a_min)); - nxy = nx*ny; - occ.clear(); - occ.resize(nxy*nz, -1); - } - - std::size_t xyz_2_ind(const int &ix, const int &iy, const int &iz) const - { - return (int64_t(iz)*nxy+ int64_t(iy)*nx + int64_t(ix)); - } - - int get_occ(const int &ix, const int &iy, const int &iz) const - { - return occ[xyz_2_ind(ix, iy, iz)]; - } - - void set_occ(const int &ix, const int &iy, const int &iz, const int &val) - { - occ[xyz_2_ind(ix, iy, iz)] = val; - } - - void set_occ(const r3d &r, const int &iatoms) - { - const int ix = static_cast(floor(r.x/a_min)); - const int iy = static_cast(floor(r.y/a_min)); - const int iz = static_cast(floor(r.z/a_min)); - set_occ(ix, iy, iz, iatoms); - } - - std::vector range_loop(const int &k, const int &n_k) - { - if(k==0) - { - return std::vector{k, k+1, k+2}; - } - else if(k==1) - { - return std::vector{k-1, k, k+1, k+2}; - } - else if(k==n_k-1) - { - return std::vector{k-2, k-1, k}; - } - else if(k==n_k-2) - { - return std::vector{k-2, k-1, k, k+1}; - } - else - { - return std::vector{k-2, k-1, k, k+1, k+2}; - } - } - - std::vector range_loop_pbc(const int &k, const int &n_k) - { - if(k==0) - { - return std::vector{n_k-2, n_k-1, k, k+1, k+2}; - } - else if(k==1) - { - return std::vector{n_k-1, k-1, k, k+1, k+2}; - } - else if(k==n_k-1) - { - return std::vector{k-2, k-1, k, 0, 1}; - } - else if(k==n_k-2) - { - return std::vector{k-2, k-1, k, k+1, 0}; - } - else - { - return std::vector{k-2, k-1, k, k+1, k+2}; - } - } - - template - bool check_r_min(TAtom &atoms, const r3d &r) - { - const int ix_i = static_cast(floor(r.x/a_min)); - const int iy_i = static_cast(floor(r.y/a_min)); - const int iz_i = static_cast(floor(r.z/a_min)); - - if (get_occ(ix_i, iy_i, iz_i)>-1) - { - return false; - } - - auto ax = range_loop_pbc(ix_i, nx); - auto ay = range_loop_pbc(iy_i, ny); - auto az = range_loop(iz_i, nz); - - for(auto iz: az) - { - for(auto iy: ay) - { - for(auto ix: ax) - { - auto iatoms = get_occ(ix, iy, iz); - if(iatoms>-1) - { - auto d2 = atoms.norm_pbc_xy(iatoms, r); - if(d2 occ; - }; - - template - class Neigh_2d - { - public: - using value_type = T; - using size_type = std::size_t; - - Neigh_2d(){}; - - template - Neigh_2d(Stream &stream, TVector &x_i, TVector &y_i, Value_type r_neigh_i) - { - operator()(stream, x_i, y_i, r_neigh_i); - } - - size_type size() const {return neigh.size();}; - - vector& operator[](const int i){ return neigh[i]; } - - const vector& operator[](const int i) const { return neigh[i]; } - - template - void operator()(Stream &stream, TVector &x_i, TVector &y_i, Value_type r_neigh_i) - { - const int n_neigh = 16; - r_neigh = r_neigh_i; - - T lx; - x = sft_vector(x_i, lx); - int nx = static_cast(ceil(lx/r_neigh)); - - T ly; - y = sft_vector(y_i, ly); - int ny = static_cast(ceil(ly/r_neigh)); - - // reserve memory - vector> neigh_grid(nx*ny); - for(auto i=0; i(floor(x[i]/r_neigh)); - int iy = static_cast(floor(y[i]/r_neigh)); - neigh_grid[ix*ny+iy].push_back(i); - }; - - auto get_neighbors_sort = [&](T x_i, T y_i, T radius)->vector - { - vector vd_neigh; - vd_neigh.reserve(n_neigh); - - vector r2d_neigh; - r2d_neigh.reserve(n_neigh); - - T radius2 = radius*radius; - - int ix_i = static_cast(floor(x_i/r_neigh)); - int iy_i = static_cast(floor(y_i/r_neigh)); - int ix_0 = max(0, ix_i-1); - int ix_e = min(nx, ix_i+2); - int iy_0 = max(0, iy_i-1); - int iy_e = min(ny, iy_i+2); - - for(auto ix=ix_0; ix &v = neigh_grid[ix*ny+iy]; - for(auto iv=0; iv1) - { - auto first = thrust::make_zip_iterator(thrust::make_tuple(r2d_neigh.begin(), vd_neigh.begin())); - auto last = thrust::make_zip_iterator(thrust::make_tuple(r2d_neigh.end(), vd_neigh.end())); - thrust::sort(first, last); - } - - vd_neigh.shrink_to_fit(); - return vd_neigh; - }; - - // get neighbors - neigh.resize(x.size()); - - auto thr_neighbors_sort = [&](const Range_2d &range) - { - for(auto i=range.ixy_0; i1) - { - int idx = neigh[i][1]; - auto rx = x[idx]-x[i]; - auto ry = y[idx]-y[i]; - r_min += sqrt(rx*rx+ry*ry); - cr_min++; - } - } - r_min /= cr_min; - - T r_neigh_n = ::fmax(2*r_min, 1.25*r_neigh); - // correct outsiders - for(auto i=0; id_max(i)) - // { - // neigh[i] = get_neighbors_sort(x[i], y[i], r_neigh_n); - // } - // } - // }; - - // stream.set_n_act_stream(x.size()); - // stream.set_grid(x.size(), 1); - // stream.exec(thr_neighbors_sort_n); - } - - template - void delete_points(TVector &x_i, TVector &y_i, TGrid &grid_i) - { - const int n_neigh = 16; - T r_neigh = 1.6*grid_i.dR_min(); - - T lx; - x = sft_vector(x_i, lx); - int nx = static_cast(ceil(lx/r_neigh)); - - T ly; - y = sft_vector(y_i, ly); - int ny = static_cast(ceil(ly/r_neigh)); - - // reserve memory - vector> neigh_grid(nx*ny); - for(auto i=0; i(floor(x[i]/r_neigh)); - int iy = static_cast(floor(y[i]/r_neigh)); - neigh_grid[ix*ny+iy].push_back(i); - }; - - auto get_neighbors = [&](T x_i, T y_i, T radius)->vector - { - vector vd_neigh; - vd_neigh.reserve(n_neigh); - - T radius2 = radius*radius; - - int ix_i = static_cast(floor(x_i/r_neigh)); - int iy_i = static_cast(floor(y_i/r_neigh)); - int ix_0 = max(0, ix_i-1); - int ix_e = min(nx, ix_i+2); - int iy_0 = max(0, iy_i-1); - int iy_e = min(ny, iy_i+2); - - for(auto ix=ix_0; ix &v = neigh_grid[ix*ny+iy]; - for(auto iv=0; iv bb(x.size(), true); - - TVector x_o; - x_o.reserve(x.size()); - - TVector y_o; - y_o.reserve(y.size()); - - for(auto i=0; i1) - { - rx = 0; - ry = 0; - for(auto j=0; j0) - { - bb[idx] = false; - } - } - rx /= neigh.size(); - ry /= neigh.size(); - } - x_o.push_back(rx); - y_o.push_back(ry); - } - } - x_i = x_o; - y_i = y_o; - } - - int size(const int &idx) - { - if(idx>=neigh.size()) - { - return 1; - } - - return neigh[idx].size(); - } - - T d_min(const int &idx) - { - T d = r_neigh; - if(idx>=neigh.size()) - { - return d; - } - - if(neigh[idx].size()>1) - { - int i = neigh[idx][1]; - auto rx = x[i]-x[idx]; - auto ry = y[i]-y[idx]; - d = sqrt(rx*rx+ry*ry); - } - return d; - } - - T d_max(const int &idx) - { - T d = r_neigh; - if(idx>=neigh.size()) - { - return d; - } - - if(neigh[idx].size()>1) - { - int i = neigh[idx].back(); - auto rx = x[i]-x[idx]; - auto ry = y[i]-y[idx]; - d = sqrt(rx*rx+ry*ry); - } - return d; - } - - template - T radius_min(const int &idx, TGrid &grid_2d, TVector &Im) - { - T r_min = 2.0*grid_2d.dR_min(); - if(idx>=neigh.size()) - { - return r_min; - } - - auto interp2 = [](const r2d &p, TGrid &grid_2d, TVector &Im)->T - { - auto ix = grid_2d.lb_index_x(p.x); - auto iy = grid_2d.lb_index_y(p.y); - - T f11 = Im[grid_2d.ind_col(ix, iy)]; - T f12 = Im[grid_2d.ind_col(ix, iy+1)]; - T f21 = Im[grid_2d.ind_col(ix+1, iy)]; - T f22 = Im[grid_2d.ind_col(ix+1, iy+1)]; - - T x1 = grid_2d.Rx(ix); - T x2 = grid_2d.Rx(ix+1); - T y1 = grid_2d.Ry(iy); - T y2 = grid_2d.Ry(iy+1); - - T dx1 = p.x-x1; - T dx2 = x2-p.x; - T dy1 = p.y-y1; - T dy2 = y2-p.y; - - T f = (dx2*(f11*dy2 + f12*dy1)+dx1*(f21*dy2 + f22*dy1))/((x2-x1)*(y2-y1)); - return f; - - }; - - if(neigh[idx].size()>1) - { - int i = neigh[idx][1]; - r2d p1(x[idx], y[idx]); - r2d p2(x[i], y[i]); - r2d p12 = r2d(x[i], y[i])-p1; - auto u = normalized(p12); - - T r = p12.module(); - T dr = 0.75*grid_2d.dR_min(); - int nr = static_cast(ceil(r/dr+0.5)); - dr = r/nr; - - T f_min = Im[grid_2d.ixy(p1.x, p1.y)]; - for(auto ir=1; irf) - { - f_min = f; - r_min = d; - } - } - r_min = ::fmax(r_min, 0.5*r); - } - return r_min; - } - - template - TVector radius_min(Stream &stream, TGrid &grid_2d, TVector &Im) - { - TVector radius(x.size()); - - auto thr_radius_min = [&](const Range_2d &range) - { - for(auto idx=range.ixy_0; idx - TVector select(const int &idx, TVector &x, Value_type x_sf=0, Value_type x_sc=1) - { - TVector v; - if(idx>=neigh.size()) - { - return v; - } - - vector &neigh_i = neigh[idx]; - v.reserve(neigh_i.size()); - - for(const auto &in:neigh_i) - { - v.push_back((x[in]-x_sf)/x_sc); - } - return v; - } - - template - Atom_Data_Sp> select(const int &idx, TVector &a, TVector &sigma, TVector &x, TVector &y) - { - Atom_Data_Sp> atom; - if(idx>=neigh.size()) - { - return atom; - } - - vector &neigh_i = neigh[idx]; - atom.reserve(neigh_i.size()); - - for(const auto &in:neigh_i) - { - atom.push_back(x[in], y[in], a[in], sigma[in]); - } - return atom; - } - - template - T min_val(const int &idx, TVector &x) - { - T x_min = 0; - if(idx>=neigh.size()) - { - return x_min; - } - - vector &neigh_i = neigh[idx]; - - x_min = neigh_i[0]; - for(const auto &in:neigh_i) - { - x_min = ::fmin(x_min, x[in]); - } - - return x_min; - } - - template - T mean_val(const int &idx, TVector &x) - { - T x_mean = 0; - if(idx>=neigh.size()) - { - return x_mean; - } - - vector &neigh_i = neigh[idx]; - - for(const auto &in:neigh_i) - { - x_mean += x[in]; - } - x_mean /= neigh_i.size(); - - return x_mean; - } - private: - vector x; - vector y; - vector> neigh; - T r_neigh; - - template - vector sft_vector(TVector &x_i, T &l_m) - { - T d_e = 1e-03; - auto x_minmax = std::minmax_element(x_i.begin(), x_i.end()); - T x_min = *(x_minmax.first)-d_e; - l_m = (*(x_minmax.second)+d_e-x_min); - - vector x; - x.reserve(x_i.size()); - - for(auto i=0; i + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef BOX_OCC_H + #define BOX_OCC_H + + #include "fcns_cgpu_gen.h" + #include "math_mt.h" + #include "r_3d.h" + #include "types.cuh" + #include "particles.cuh" + #include "cgpu_stream.cuh" + + namespace mt + { + template + class Box_Occ_3d + { + public: + Box_Occ_3d(): d2_min(), a_min(), r_0(), nx(), ny(), nz(){}; + + Box_Occ_3d(T d_min, R_3d bs, R_3d r_0 = R_3d()) + { + set_in_data(d_min, bs, r_0); + } + + void set_in_data(T d_min, R_3d bs, R_3d r_0 = R_3d()) + { + d2_min = ::square(d_min); + a_min = d_min/mt::c_3i2; + this->r_0 = r_0; + + nx = fcn_cceil(bs.x/a_min); + ny = fcn_cceil(bs.y/a_min); + nz = fcn_cceil(bs.z/a_min); + + occ.clear(); + occ.shrink_to_fit(); + occ.resize({ny, nx, nz}, -1); + } + + void set(R_3d r, const dt_int32& val) + { + r = (r-r_0)/a_min; + + const auto ix = fcn_cfloor(r.x); + const auto iy = fcn_cfloor(r.y); + const auto iz = fcn_cfloor(r.z); + + occ(iy, ix, iz) = val; + } + + template + dt_bool check_r_min(const TPtc_3d& atoms, R_3d r) + { + const auto r_idx = (r-r_0)/a_min; + + const auto ix_m = fcn_cfloor(r_idx.x); + const auto iy_m = fcn_cfloor(r_idx.y); + const auto iz_m = fcn_cfloor(r_idx.z); + + const auto bb_bound = fcn_chk_bound(ix_m, 0, nx) && fcn_chk_bound(iy_m, 0, ny) && fcn_chk_bound(iz_m, 0, nz); + + if (bb_bound && (occ(iy_m, ix_m, iz_m) > -1)) + { + return false; + } + + const auto ax = range_loop_pbc(ix_m, nx); + const auto ay = range_loop_pbc(iy_m, ny); + const auto az = range_loop(iz_m, nz); + + for(auto iz: az) + { + for(auto ix: ax) + { + for(auto iy: ay) + { + auto iatom = occ(iy, ix, iz); + if (iatom>-1) + { + auto d2 = atoms.norm_2_pbc_xy(iatom, r); + if (d2 r_0; + + Vctr_cpu occ; + private: + T a_min; + T d2_min; + dt_int32 nx; + dt_int32 ny; + dt_int32 nz; + + Vctr_std range_loop(const dt_int32& k, const dt_int32& n_k) + { + if (k==0) + { + return {k, k+1, k+2}; + } + else if (k==1) + { + return {k-1, k, k+1, k+2}; + } + else if (k==n_k-1) + { + return {k-2, k-1, k}; + } + else if (k==n_k-2) + { + return {k-2, k-1, k, k+1}; + } + else + { + return {k-2, k-1, k, k+1, k+2}; + } + } + + Vctr_std range_loop_pbc(const dt_int32& k, const dt_int32& n_k) + { + if (k==0) + { + return {n_k-2, n_k-1, k, k+1, k+2}; + } + else if (k==1) + { + return {n_k-1, k-1, k, k+1, k+2}; + } + else if (k==n_k-1) + { + return {k-2, k-1, k, 0, 1}; + } + else if (k==n_k-2) + { + return {k-2, k-1, k, k+1, 0}; + } + else + { + return {k-2, k-1, k, k+1, k+2}; + } + } + }; + + template + class Neigh_2d + { + public: + using value_type = T; + using size_type = dt_uint64; + + Neigh_2d() {}; + + template + Neigh_2d(Stream& stream, TVctr& x_i, TVctr& y_i, Value_type r_neigh_i) + { + operator()(stream, x_i, y_i, r_neigh_i); + } + + size_type size() const {return neigh.size(); }; + + Vctr_std& operator[](const dt_int32 i){ return neigh[i]; } + + const Vctr_std& operator[](const dt_int32 i) const { return neigh[i]; } + + template + void operator()(Stream& stream, TVctr& x_i, TVctr& y_i, Value_type r_neigh_i) + { + const dt_int32 n_neigh = 16; + r_neigh = r_neigh_i; + + T bs_x; + x = sft_vector(x_i, bs_x); + dt_int32 nx = static_cast(::ceil(bs_x/r_neigh)); + + T bs_y; + y = sft_vector(y_i, bs_y); + dt_int32 ny = static_cast(::ceil(bs_y/r_neigh)); + + // reserve memory + Vctr_std> neigh_grid(nx*ny); + for(auto i=0; i(::floor(x[i]/r_neigh)); + dt_int32 iy = static_cast(::floor(y[i]/r_neigh)); + neigh_grid[ix*ny+iy].push_back(i); + }; + + auto get_neighbors_sort = [&](T x_i, T y_i, T radius)->Vctr_std + { + Vctr_std vd_neigh; + vd_neigh.reserve(n_neigh); + + Vctr_std r2d_neigh; + r2d_neigh.reserve(n_neigh); + + T radius2 = radius*radius; + + dt_int32 ix_i = static_cast(::floor(x_i/r_neigh)); + dt_int32 iy_i = static_cast(::floor(y_i/r_neigh)); + dt_int32 ix_0 = max(0, ix_i-1); + dt_int32 ix_e = min(nx, ix_i+2); + dt_int32 iy_0 = max(0, iy_i-1); + dt_int32 iy_e = min(ny, iy_i+2); + + for(auto ix=ix_0; ix& v = neigh_grid[ix*ny+iy]; + for(auto iv=0; iv1) + { + auto first = thrust::make_zip_iterator(thrust::make_tuple(r2d_neigh.begin(), vd_neigh.begin())); + auto last = thrust::make_zip_iterator(thrust::make_tuple(r2d_neigh.end(), vd_neigh.end())); + thrust::sort(first, last); + } + + vd_neigh.shrink_to_fit(); + return vd_neigh; + }; + + // get neighbors + neigh.resize(x.size()); + + auto thr_neighbors_sort = [&](const iThread_Rect_2d& range) + { + for(auto i=range.ind_0; i1) + { + dt_int32 idx = neigh[i][1]; + auto rx = x[idx]-x[i]; + auto ry = y[idx]-y[i]; + r_min += sqrt(rx*rx+ry*ry); + cr_min++; + } + } + r_min /= cr_min; + + T r_neigh_n = ::fmax(2*r_min, 1.25*r_neigh); + // correct outliers + for(auto i=0; id_max(i)) + // { + // neigh[i] = get_neighbors_sort(x[i], y[i], r_neigh_n); + // } + // } + // }; + + // stream.set_n_stream_act(x.size()); + // stream.set_grid(x.size(), 1); + // stream.exec(thr_neighbors_sort_n); + } + + template + void delete_points(TVctr& x_i, TVctr& y_i, TGrid& grid_i) + { + const dt_int32 n_neigh = 16; + T r_neigh = 1.6*grid_i.dR_min(); + + T bs_x; + x = sft_vector(x_i, bs_x); + dt_int32 nx = static_cast(::ceil(bs_x/r_neigh)); + + T bs_y; + y = sft_vector(y_i, bs_y); + dt_int32 ny = static_cast(::ceil(bs_y/r_neigh)); + + // reserve memory + Vctr_std> neigh_grid(nx*ny); + for(auto i=0; i(::floor(x[i]/r_neigh)); + dt_int32 iy = static_cast(::floor(y[i]/r_neigh)); + neigh_grid[ix*ny+iy].push_back(i); + }; + + auto get_neighbors = [&](T x_i, T y_i, T radius)->Vctr_std + { + Vctr_std vd_neigh; + vd_neigh.reserve(n_neigh); + + T radius2 = radius*radius; + + dt_int32 ix_i = static_cast(::floor(x_i/r_neigh)); + dt_int32 iy_i = static_cast(::floor(y_i/r_neigh)); + dt_int32 ix_0 = max(0, ix_i-1); + dt_int32 ix_e = min(nx, ix_i+2); + dt_int32 iy_0 = max(0, iy_i-1); + dt_int32 iy_e = min(ny, iy_i+2); + + for(auto ix=ix_0; ix& v = neigh_grid[ix*ny+iy]; + for(auto iv=0; iv bb(x.size(), true); + + TVctr x_o; + x_o.reserve(x.size()); + + TVctr y_o; + y_o.reserve(y.size()); + + for(auto i=0; i1) + { + rx = 0; + ry = 0; + for(auto j=0; j0) + { + bb[idx] = false; + } + } + rx /= neigh.size(); + ry /= neigh.size(); + } + x_o.push_back(rx); + y_o.push_back(ry); + } + } + x_i = x_o; + y_i = y_o; + } + + dt_int32 size(const dt_int32& idx) + { + if (idx>=neigh.size()) + { + return 1; + } + + return neigh[idx].size(); + } + + T d_min(const dt_int32& idx) + { + T d = r_neigh; + if (idx>=neigh.size()) + { + return d; + } + + if (neigh[idx].size()>1) + { + dt_int32 i = neigh[idx][1]; + auto rx = x[i]-x[idx]; + auto ry = y[i]-y[idx]; + d = sqrt(rx*rx+ry*ry); + } + return d; + } + + T d_max(const dt_int32& idx) + { + T d = r_neigh; + if (idx>=neigh.size()) + { + return d; + } + + if (neigh[idx].size()>1) + { + dt_int32 i = neigh[idx].back(); + auto rx = x[i]-x[idx]; + auto ry = y[i]-y[idx]; + d = sqrt(rx*rx+ry*ry); + } + return d; + } + + template + T radius_min(const dt_int32& idx, TGrid& grid_2d, TVctr& Im) + { + T r_min = 2.0*grid_2d.dR_min(); + if (idx>=neigh.size()) + { + return r_min; + } + + auto interp2 = [](const R_2d& p, TGrid& grid_2d, TVctr& Im)->T + { + auto ix = grid_2d.rx_2_irx_bfds(p.x); + auto iy = grid_2d.ry_2_iry_bfds(p.y); + + T f11 = Im[grid_2d.sub_2_ind(ix, iy)]; + T f12 = Im[grid_2d.sub_2_ind(ix, iy+1)]; + T f21 = Im[grid_2d.sub_2_ind(ix+1, iy)]; + T f22 = Im[grid_2d.sub_2_ind(ix+1, iy+1)]; + + T x1 = grid_2d.rx(ix); + T x2 = grid_2d.rx(ix+1); + T y1 = grid_2d.ry(iy); + T y2 = grid_2d.ry(iy+1); + + T dx1 = p.x-x1; + T dx2 = x2-p.x; + T dy1 = p.y-y1; + T dy2 = y2-p.y; + + T f = (dx2*(f11*dy2 + f12*dy1)+dx1*(f21*dy2 + f22*dy1))/((x2-x1)*(y2-y1)); + return f; + + }; + + if (neigh[idx].size()>1) + { + dt_int32 i = neigh[idx][1]; + R_2d p1(x[idx], y[idx]); + R_2d p2(x[i], y[i]); + R_2d p12 = R_2d(x[i], y[i])-p1; + auto u = normalize(p12); + + T r = p12.norm(); + T dr = 0.75*grid_2d.dR_min(); + dt_int32 nr = static_cast(::ceil(r/dr+0.5)); + dr = r/nr; + + T f_min = Im[grid_2d.rv_2_ir_bfds(p1.x, p1.y)]; + for(auto ir=1; irf) + { + f_min = f; + r_min = d; + } + } + r_min = ::fmax(r_min, 0.5*r); + } + return r_min; + } + + template + TVctr radius_min(Stream& stream, TGrid& grid_2d, TVctr& Im) + { + TVctr radius(x.size()); + + auto thr_radius_min = [&](const iThread_Rect_2d& range) + { + for(auto idx=range.ind_0; idx + TVctr select(const dt_int32& idx, TVctr& x, Value_type x_sf=0, Value_type x_sc=1) + { + TVctr v; + if (idx>=neigh.size()) + { + return v; + } + + Vctr_std& neigh_i = neigh[idx]; + v.reserve(neigh_i.size()); + + for(const auto &in:neigh_i) + { + v.push_back((x[in]-x_sf)/x_sc); + } + return v; + } + + //template + //Ptc_gauss_2d> select(const dt_int32& idx, TVctr& a, TVctr& sigma, TVctr& x, TVctr& y) + //{ + // Ptc_gauss_2d> atom; + // if (idx>=neigh.size()) + // { + // return atom; + // } + + // Vctr_std& neigh_i = neigh[idx]; + // atom.reserve(neigh_i.size()); + + // for(const auto &in:neigh_i) + // { + // atom.push_back(x[in], y[in], a[in], sigma[in]); + // } + // return atom; + //} + + template + T min_val(const dt_int32& idx, TVctr& x) + { + T x_min = 0; + if (idx>=neigh.size()) + { + return x_min; + } + + Vctr_std& neigh_i = neigh[idx]; + + x_min = neigh_i[0]; + for(const auto &in:neigh_i) + { + x_min = ::fmin(x_min, x[in]); + } + + return x_min; + } + + template + T mean_val(const dt_int32& idx, TVctr& x) + { + T x_mean = 0; + if (idx>=neigh.size()) + { + return x_mean; + } + + Vctr_std& neigh_i = neigh[idx]; + + for(const auto &in:neigh_i) + { + x_mean += x[in]; + } + x_mean /= neigh_i.size(); + + return x_mean; + } + private: + Vctr_std x; + Vctr_std y; + Vctr_std> neigh; + T r_neigh; + + template + Vctr_std sft_vector(TVctr& x_i, T& l_m) + { + T d_e = 1e-03; + auto x_minmax = fcn_minmax_element(x_i.begin(), x_i.end()); + T x_min = *(x_minmax.first)-d_e; + l_m = (*(x_minmax.second)+d_e-x_min); + + Vctr_std x; + x.reserve(x_i.size()); + + for(auto i=0; i - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef CGPU_CLASSES_H -#define CGPU_CLASSES_H - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "cgpu_rand.cuh" - -#ifdef __CUDACC__ - #include - #include - #include -#endif - -#include "cgpu_fcns.cuh" -#include "cpu_fcns.hpp" - -#ifdef __CUDACC__ - #include "gpu_fcns.cuh" -#endif -namespace mt -{ - /**************** Gaussian Conv ***************/ - template - class Gauss_Cv_1d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Gauss_Cv_1d():fft_1d(nullptr){} - - Gauss_Cv_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - set_input_data(fft_1d_i, grid_1d_i); - } - - inline - void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - fft_1d = fft_1d_i; - grid_1d = grid_1d_i; - } - - void set_fft_plan() - { - fft_1d->create_plan_1d(grid_1d.nx, 1); - } - - void operator()(T sigma_r, TVector_c &Im) - { - fft1_shift(grid_1d, Im); - fft_1d->forward(Im); - - gauss_cv_1d(sigma_r, Im); - - fft_1d->inverse(Im); - fft1_shift(grid_1d, Im); - } - - void operator()(T sigma_r, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - - this->operator()(sigma_r, Im_c); - - assign_real(Im_c, Im); - } - - void cleanup() - { - fft_1d->cleanup(); - } - protected: - /************************Host************************/ - template - enable_if_dev_host - gauss_cv_1d(T sigma_r, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - host_device_detail::gauss_cv_1d, TVector_c>(ix, grid_1d, alpha, Im); - } - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - gauss_cv_1d(T sigma_r, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - auto grid_bt = grid_1d.cuda_grid(); - device_detail::gauss_cv_1d, typename TVector_c::value_type><<>>(grid_1d, alpha, Im); - } - #endif - - FFT *fft_1d; - Grid_1d grid_1d; - }; - - template - class Gauss_Cv_2d_BC - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Gauss_Cv_2d_BC():stream(nullptr), fft_2d(nullptr){} - - Gauss_Cv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - } - - void set_fft_plan() - { - fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); - } - - void operator()(T sigma_r, TVector_c &Im) - { - fft2_sft_bc(*stream, grid_2d, Im); - fft_2d->forward(Im); - - gauss_cv_2d_bc(sigma_r, Im); - - fft_2d->inverse(Im); - fft2_sft_bc(*stream, grid_2d, Im); - } - - void operator()(T sigma_r, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - - this->operator()(sigma_r, Im_c); - - assign_real(Im_c, Im); - } - - void cleanup() - { - fft_2d->cleanup(); - } - - protected: - Vector gauss_vector_1d(T alpha) - { - TVector_r fg; - fg.reserve(grid_2d.ny); - - for (auto iy=0; iy < grid_2d.ny; iy++) - { - auto v = exp(-alpha*grid_2d.gy2_shift(iy))/grid_2d.ny_r(); - fg.push_back(v); - } - return fg; - } - - /************************Host************************/ - template - enable_if_dev_host - gauss_cv_2d_bc(T sigma_r, TVector_c &M_g) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - auto fg = gauss_vector_1d(alpha); - - stream->set_n_act_stream(grid_2d.nx); - stream->set_grid(grid_2d.nx, grid_2d.ny); - stream->exec_matrix(host_device_detail::vector_col_x_matrix, TVector_r, TVector_c>, grid_2d, fg, M_g); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - gauss_cv_2d_bc(T sigma_r, TVector_c &M_g) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - auto fg_h = gauss_vector_1d(alpha); - TVector_r fg = fg_h; - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::vector_col_x_matrix, typename TVector_c::value_type><<>>(grid_2d, fg, M_g); - } - #endif - - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - }; - - template - class Gauss_Cv_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Gauss_Cv_2d():stream(nullptr), fft_2d(nullptr){} - - Gauss_Cv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - } - - void set_fft_plan() - { - fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); - } - - void operator()(T sigma_r, TVector_c &Im) - { - fft2_shift(*stream, grid_2d, Im); - fft_2d->forward(Im); - - gauss_cv_2d(sigma_r, Im); - - fft_2d->inverse(Im); - fft2_shift(*stream, grid_2d, Im); - } - - void operator()(T sigma_r, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - - this->operator()(sigma_r, Im_c); - - assign_real(Im_c, Im); - } - - void cleanup() - { - fft_2d->cleanup(); - } - protected: - /************************Host************************/ - template - enable_if_dev_host - gauss_cv_2d(T sigma_r, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - stream->set_n_act_stream(grid_2d.nx); - stream->set_grid(grid_2d.nx, grid_2d.ny); - stream->exec_matrix(host_device_detail::gauss_cv_2d, TVector_c>, grid_2d, alpha, Im); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - gauss_cv_2d(T sigma_r, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::gauss_cv_2d, typename TVector_c::value_type><<>>(grid_2d, alpha, Im); - } - #endif - - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - }; - - /**************** Gaussian Deconv ***************/ - template - class Gauss_Dcv_1d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Gauss_Dcv_1d():fft_1d(nullptr){} - - Gauss_Dcv_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - set_input_data(fft_1d_i, grid_1d_i); - } - - inline - void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - fft_1d = fft_1d_i; - grid_1d = grid_1d_i; - } - - void set_fft_plan() - { - fft_1d->create_plan_1d(grid_1d.nx, 1); - } - - void operator()(T sigma_r, T PSNR, TVector_c &Im) - { - fft1_shift(grid_1d, Im); - fft_1d->forward(Im); - - gauss_dcv_1d(sigma_r, PSNR, Im); - - fft_1d->inverse(Im); - fft1_shift(grid_1d, Im); - } - - void operator()(T sigma_r, T PSNR, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - - this->operator()(sigma_r, PSNR, Im_c); - - assign_real(Im_c, Im); - } - - void cleanup() - { - fft_1d->cleanup(); - } - protected: - /************************Host************************/ - template - enable_if_dev_host - gauss_dcv_1d(T sigma_r, T PSNR, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - host_device_detail::gauss_dcv_1d, TVector_c>(ix, grid_1d, alpha, PSNR, Im); - } - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - gauss_dcv_1d(T sigma_r, T PSNR, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - auto grid_bt = grid_1d.cuda_grid(); - device_detail::gauss_dcv_1d, typename TVector_c::value_type><<>>(grid_1d, alpha, PSNR, Im); - } - #endif - - FFT *fft_1d; - Grid_1d grid_1d; - }; - - template - class Gauss_Dcv_2d_BC - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Gauss_Dcv_2d_BC():stream(nullptr), fft_2d(nullptr){} - - Gauss_Dcv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - } - - void set_fft_plan() - { - fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); - } - - void operator()(T sigma_r, T PSNR, TVector_c &Im) - { - fft2_sft_bc(*stream, grid_2d, Im); - fft_2d->forward(Im); - - gauss_cv_2d_bc(sigma_r, PSNR, Im); - - fft_2d->inverse(Im); - fft2_sft_bc(*stream, grid_2d, Im); - } - - void operator()(T sigma_r, T PSNR, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - - this->operator()(sigma_r, PSNR, Im_c); - - assign_real(Im_c, Im); - } - - void cleanup() - { - fft_2d->cleanup(); - } - - protected: - Vector gauss_vector_1d(T alpha, T PSNR) - { - TVector_r fg; - fg.reserve(grid_2d.ny); - - for (auto iy=0; iy < grid_2d.ny; iy++) - { - auto v = exp(-alpha*grid_2d.gy2_shift(iy)); - fg.push_back(v/((v*v+PSNR)*grid_2d.ny_r())); - } - return fg; - } - - /************************Host************************/ - template - enable_if_dev_host - gauss_cv_2d_bc(T sigma_r, T PSNR, TVector_c &M_g) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - auto fg = gauss_vector_1d(alpha, PSNR); - - stream->set_n_act_stream(grid_2d.nx); - stream->set_grid(grid_2d.nx, grid_2d.ny); - stream->exec_matrix(host_device_detail::vector_col_x_matrix, TVector_r, TVector_c>, grid_2d, fg, M_g); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - gauss_cv_2d_bc(T sigma_r, T PSNR, TVector_c &M_g) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - auto fg_h = gauss_vector_1d(alpha, PSNR); - TVector_r fg = fg_h; - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::vector_col_x_matrix, typename TVector_c::value_type><<>>(grid_2d, fg, M_g); - } - #endif - - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - }; - - template - class Gauss_Dcv_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Gauss_Dcv_2d():stream(nullptr), fft_2d(nullptr){} - - Gauss_Dcv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - } - - void set_fft_plan() - { - fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); - } - - void operator()(T sigma_r, T PSNR, TVector_c &Im) - { - fft2_shift(*stream, grid_2d, Im); - fft_2d->forward(Im); - - gauss_dcv_2d(sigma_r, PSNR, Im); - - fft_2d->inverse(Im); - fft2_shift(*stream, grid_2d, Im); - } - - void operator()(T sigma_r, T PSNR, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - - this->operator()(sigma_r, PSNR, Im_c); - - assign_real(Im_c, Im); - } - - void cleanup() - { - fft_2d->cleanup(); - } - protected: - /************************Host************************/ - template - enable_if_dev_host - gauss_dcv_2d(T sigma_r, T PSNR, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - stream->set_n_act_stream(grid_2d.nx); - stream->set_grid(grid_2d.nx, grid_2d.ny); - stream->exec_matrix(host_device_detail::gauss_dcv_2d, TVector_c>, grid_2d, alpha, PSNR, Im); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - gauss_dcv_2d(T sigma_r, T PSNR, TVector_c &Im) - { - auto alpha = 2*c_Pi2*sigma_r*sigma_r; - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::gauss_dcv_2d, typename TVector_c::value_type><<>>(grid_2d, alpha, PSNR, Im); - } - #endif - - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - }; - - /****************Gauss_Spt***************/ - template - class Gauss_Spt - { - public: - using T_r = T; - using TVector_r = Vector; - - using size_type = std::size_t; - - static const eDevice device = dev; - - Gauss_Spt(): input_gauss_spt(nullptr), stream(nullptr), n_atoms_p(512){} - - void set_input_data(Input_Gauss_Spt *input_gauss_spt_i, Stream *stream_i) - { - input_gauss_spt = input_gauss_spt_i; - stream = stream_i; - - n_atoms_p = (device==e_host)?(stream->size()):512; - - if(device==e_host) - { - int nv = input_gauss_spt->get_nv(); - stream_data.resize(n_atoms_p); - for(auto i = 0; i - enable_if_dev_host - operator()(TVector_r &Im) - { - auto gauss_eval = [](Stream &stream, Grid_2d &grid_2d, - Vector, e_host> &gauss, TVector_r &M_o) - { - if(stream.n_act_stream<= 0) - { - return; - } - - for(auto istream = 0; istream < stream.n_act_stream-1; istream++) - { - stream[istream] = std::thread(std::bind(host_detail::gauss_eval, std::ref(stream), std::ref(grid_2d), std::ref(gauss[istream]), std::ref(M_o))); - } - - host_detail::gauss_eval(stream, grid_2d, gauss[stream.n_act_stream-1], M_o); - - stream.synchronize(); - }; - - mt::fill(*stream, Im, 0.0); - - int iatom_0 = 0; - int iatom_e = input_gauss_spt->atoms.size()-1; - - int iatoms = iatom_0; - while (iatoms <= iatom_e) - { - stream->set_n_act_stream(iatom_e-iatoms+1); - set_gauss_sp(iatoms, stream->n_act_stream, gauss_sp); - - gauss_eval(*stream, input_gauss_spt->grid_2d, gauss_sp, Im); - iatoms += stream->n_act_stream; - } - - stream->synchronize(); - } - - /***********************Device***********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - operator()(TVector_r &Im) - { - auto get_eval_cubic_poly_gridBT = [](int natoms)->Grid_BT - { - Grid_BT grid_bt; - grid_bt.Blk = dim3(natoms, 1, 1); - grid_bt.Thr = dim3(c_thrnxny, c_thrnxny, 1); - - return grid_bt; - }; - - mt::fill(*stream, Im, 0.0); - - int iatom_0 = 0; - int iatom_e = input_gauss_spt->atoms.size()-1; - - int iatoms = iatom_0; - while (iatoms <= iatom_e) - { - int n_atoms = min(n_atoms_p, iatom_e-iatoms+1); - set_gauss_sp(iatoms, n_atoms, gauss_sp); - - auto grid_bt = get_eval_cubic_poly_gridBT(n_atoms); - device_detail::gauss_eval<<>>(input_gauss_spt->grid_2d, gauss_sp, Im); - - iatoms += n_atoms; - } - } - #endif - - Input_Gauss_Spt *input_gauss_spt; - Stream *stream; - private: - int n_atoms_p; - - struct Stream_Data - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = e_host; - - size_type size() const - { - return iv.size(); - } - - void resize(const size_type &new_size) - { - iv.resize(new_size); - v.resize(new_size); - } - - Vector, e_host> iv; - Vector, e_host> v; - }; - - void set_gauss_sp(int iatoms, int n_atoms_p, Vector, dev> &gauss_sp) - { - for(auto istream = 0; istream < n_atoms_p; istream++) - { - gauss_sp_h[istream].x = input_gauss_spt->atoms.x[iatoms]; - gauss_sp_h[istream].y = input_gauss_spt->atoms.y[iatoms]; - gauss_sp_h[istream].a = input_gauss_spt->atoms.a[iatoms]; - gauss_sp_h[istream].alpha = input_gauss_spt->alpha(iatoms); - auto R_max = input_gauss_spt->R_max(iatoms); - auto R2_max = R_max*R_max; - gauss_sp_h[istream].R2_tap = pow(0.85*R_max, 2); - gauss_sp_h[istream].tap_cf = c_i2Pi/(R2_max-gauss_sp_h[istream].R2_tap); - gauss_sp_h[istream].R2_max = R2_max; - gauss_sp_h[istream].set_ix0_ixn(input_gauss_spt->grid_2d, R_max); - gauss_sp_h[istream].set_iy0_iyn(input_gauss_spt->grid_2d, R_max); - if(device==e_host) - { - gauss_sp_h[istream].iv = raw_pointer_cast(stream_data.iv[istream].data()); - gauss_sp_h[istream].v = raw_pointer_cast(stream_data.v[istream].data()); - } - iatoms++; - } - thrust::copy(gauss_sp_h.begin(), gauss_sp_h.end(), gauss_sp.begin()); - } - - Stream_Data stream_data; - Vector, e_host> gauss_sp_h; - Vector, dev> gauss_sp; - }; - - /****************affine transformations***************/ - template - class Sc_2d - { - public: - using T_r = T; - using TVector = Vector; - - static const eDevice device = dev; - - Sc_2d(): stream(nullptr){} - - Sc_2d(Stream *stream_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - grid_2d = grid_2d_i; - } - - /************************Host************************/ - template - enable_if_dev_host - operator()(TVector &M_i, T sxy, TVector &M_o) - { - if(isEqual(sxy, T(1))) - { - M_o = M_i; - } - - int nx_o = get_new_size(grid_2d.nx, sxy); - int ny_o = get_new_size(grid_2d.ny, sxy); - - Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); - - stream->set_n_act_stream(grid_2d_o.nx); - stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); - stream->exec_matrix(host_device_detail::sc_2d, TVector>, grid_2d, M_i, sxy, grid_2d_o, M_o); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - operator()(TVector &M_i, T sxy, TVector &M_o) - { - if(isEqual(sxy, T(1))) - { - M_o = M_i; - } - - int nx_o = max(int(floor(grid_2d.nx*sxy)), 1); - int ny_o = max(int(floor(grid_2d.ny*sxy)), 1); - - Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); - - auto grid_bt = grid_2d_o.cuda_grid(); - device_detail::sc_2d, typename TVector::value_type><<>>(grid_2d, M_i, sxy, grid_2d_o, M_o); - } - #endif - - protected: - Grid_2d grid_2d; - Stream *stream; - }; - - template - class Rot_2d - { - public: - using T_r = T; - using TVector = Vector; - - static const eDevice device = dev; - - Rot_2d(): stream(nullptr){} - - Rot_2d(Stream *stream_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - grid_2d = grid_2d_i; - } - - /************************Host************************/ - template - enable_if_dev_host - operator()(TVector &M_i, T theta, r2d p0, TVector &M_o) - { - if(isZero(theta)) - { - M_o = M_i; - } - - // calculate background - T bg = mean(*stream, M_i); - - Grid_2d grid_2d_o = grid_2d; - - stream->set_n_act_stream(grid_2d_o.nx); - stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); - stream->exec_matrix(host_device_detail::rot_2d, TVector>, grid_2d, M_i, theta, p0, bg, grid_2d_o, M_o); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - operator()(TVector &M_i, T theta, r2d p0, TVector &M_o) - { - if(isZero(theta)) - { - M_o = M_i; - } - - // calculate background - T bg = mean(*stream, M_i); - - Grid_2d grid_2d_o = grid_2d; - - auto grid_bt = grid_2d_o.cuda_grid(); - device_detail::rot_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, bg, grid_2d_o, M_o); - } - #endif - - protected: - Grid_2d grid_2d; - Stream *stream; - }; - - template - class Rot_Sca_sft_2d - { - public: - using T_r = T; - using TVector = Vector; - - static const eDevice device = dev; - - Rot_Sca_sft_2d():stream(nullptr){} - - Rot_Sca_sft_2d(Stream *stream_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - grid_2d = grid_2d_i; - } - - /************************Host************************/ - template - enable_if_dev_host - operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) - { - // calculate background - T bg = mean(*stream, M_i); - - int nx_o = get_new_size(grid_2d.nx, sx); - int ny_o = get_new_size(grid_2d.ny, sy); - - Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); - - stream->set_n_act_stream(grid_2d_o.nx); - stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); - stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) - { - // calculate background - T bg = mean(*stream, M_i); - - int nx_o = max(int(floor(grid_2d.nx*sx)), 1); - int ny_o = max(int(floor(grid_2d.ny*sy)), 1); - - Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); - - auto grid_bt = grid_2d_o.cuda_grid(); - device_detail::rot_sca_sft_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); - } - #endif - - protected: - Grid_2d grid_2d; - Stream *stream; - }; - - template - class Data_Aug_2d - { - public: - using T_r = T; - using TVector = Vector; - - static const eDevice device = dev; - - Data_Aug_2d():stream(nullptr){} - - Data_Aug_2d(Stream *stream_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - grid_2d = grid_2d_i; - } - - /************************Host************************/ - template - enable_if_dev_host - operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, T sim, - int nx_o, int ny_o, TVector &M_o) - { - // calculate maximum - auto M_max = *thrust::max_element(M_i.begin(), M_i.end()); - - // calculate background - auto g_max = grid_2d.gx_last(); - auto g_min = 0.9*g_max; - //T bg = sum_over_Det(*stream, grid_2d, g_min, g_max, M_i); - - T bg = 0.6*mean(*stream, M_i); - - T Rx_0 = p0.x*sx-(nx_o/2)*grid_2d.dRx; - T Ry_0 = p0.y*sy-(ny_o/2)*grid_2d.dRy; - - Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); - grid_2d_o.set_R_0(Rx_0, Ry_0); - - stream->set_n_act_stream(grid_2d_o.nx); - stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); - stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); - - normalized_data(M_o, M_max); - - // add Poisson noise - M_o = add_poiss_nois(*stream, M_o, sim); - - M_max = *thrust::max_element(M_o.begin(), M_o.end()); - normalized_data(M_o, M_max); - } - - protected: - void normalized_data(TVector &M, T M_max) - { - std::for_each(M.begin(), M.end(), [M_max](T &v){ v = (v>0)?v/M_max:0;}); - } - - Grid_2d grid_2d; - Stream *stream; - }; - - template - class Shx_Scy - { - public: - using T_r = T; - using TVector = Vector; - - static const eDevice device = dev; - - Shx_Scy():stream(nullptr){} - - Shx_Scy(Stream *stream_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - grid_2d = grid_2d_i; - } - - template - enable_if_dev_host - operator()(TVector &M_i, r2d af, TVector &M_o) - { - if(isZero(af.x) && isEqual(af.y, T(1))) - { - M_o = M_i; - } - - TVector M_o_t; - TVector *pM_o = &M_o; - - if (M_i.data() == M_o.data()) - { - M_o_t.resize(M_i.size()); - pM_o = &M_o_t; - } - - // calculate background - T bg = mean(*stream, M_i); - - Grid_2d grid_2d_o = grid_2d; - - stream->set_n_act_stream(grid_2d_o.nx); - stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); - stream->exec_matrix(host_device_detail::shx_scy, TVector>, grid_2d, M_i, af.x, af.y, bg, grid_2d_o, *pM_o); - - if (M_i.data() == M_o.data()) - { - M_o.assign(pM_o->begin(), pM_o->end()); - } - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - operator()(TVector &M_i, r2d af, TVector &M_o) - { - if(isZero(af.x) && isEqual(af.y, T(1))) - { - M_o = M_i; - } - - TVector M_o_t; - TVector *pM_o = &M_o; - - if (M_i.data() == M_o.data()) - { - M_o_t.resize(M_i.size()); - pM_o = &M_o_t; - } - - // calculate background - T bg = mean(*stream, M_i); - - Grid_2d grid_2d_o = grid_2d; - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::shx_scy, typename TVector::value_type><<>>(grid_2d, M_i, af.x, af.y, bg, grid_2d_o, *pM_o); - - if (M_i.data() == M_o.data()) - { - M_o.assign(pM_o->begin(), pM_o->end()); - } - } - #endif - - protected: - Grid_2d grid_2d; - Stream *stream; - }; - - /**********************shift*************************/ - template - class Sft_1d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Sft_1d():fft_1d(nullptr){} - - Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - set_input_data(fft_1d_i, grid_1d_i); - } - - inline - void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - fft_1d = fft_1d_i; - grid_1d = grid_1d_i; - } - - void set_fft_plan() - { - fft_1d->create_plan_1d(grid_1d.nx); - } - - void operator()(T xs, TVector_c &Im) - { - fft1_shift(grid_1d, Im); - fft_1d->forward(Im); - exp_g_factor_1d(grid_1d, -c_2Pi*xs, Im, Im); - fft_1d->inverse(Im); - fft1_shift(grid_1d, Im); - } - - void operator()(T xs, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - T Im_min = min_element(Im); - - this->operator()(xs, Im_c); - assign_real(Im_c, Im, Im_min); - } - - void cleanup() - { - fft_1d->cleanup(); - } - - protected: - FFT *fft_1d; - Grid_1d grid_1d; - }; - - template - class Sft_2d_BC - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Sft_2d_BC():stream(nullptr), fft_2d(nullptr){} - - Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - } - - void set_fft_plan() - { - fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); - } - - void operator()(T alpha, TVector_r ys, TVector_c &Im) - { - fft2_sft_bc(*stream, grid_2d, Im); - fft_2d->forward(Im); - exp_g_factor_2d_bc(*stream, grid_2d, -c_2Pi*alpha, ys, Im, Im); - fft_2d->inverse(Im); - fft2_sft_bc(*stream, grid_2d, Im); - } - - void operator()(T alpha, TVector_r ys, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - T Im_min = min_element(Im); - - this->operator()(alpha, ys, Im_c); - assign_real(Im_c, Im, Im_min); - } - - void cleanup() - { - fft_2d->cleanup(); - } - - protected: - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - }; - - template - class Sft_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Sft_2d():stream(nullptr), fft_2d(nullptr){} - - Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - } - - void set_fft_plan() - { - fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); - } - - void operator()(r2d p, TVector_c &Im) - { - fft2_shift(*stream, grid_2d, Im); - fft_2d->forward(Im); - exp_g_factor_2d(*stream, grid_2d, -c_2Pi*p.x, -c_2Pi*p.y, Im, Im); - fft_2d->inverse(Im); - fft2_shift(*stream, grid_2d, Im); - } - - void operator()(r2d p, TVector_r &Im) - { - TVector_c Im_c(Im.begin(), Im.end()); - T Im_min = min_element(Im); - - this->operator()(p, Im_c); - assign_real(Im_c, Im, Im_min); - } - - void cleanup() - { - fft_2d->cleanup(); - } - protected: - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - }; - - /******************phase correlation*****************/ - template - class Pcf_1d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Pcf_1d(): fft_1d(nullptr){} - - Pcf_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - set_input_data(fft_1d_i, grid_1d_i); - } - - inline - void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - fft_1d = fft_1d_i; - grid_1d = grid_1d_i; - - Prime_Num pn; - - int nx = pn(2*grid_1d.nx-1, eDST_Greater_Than); - - grid_1d_e.set_input_data(nx, grid_1d.dRx*nx); - - M_r_c.resize(grid_1d_e.nx); - M_s_c.resize(grid_1d_e.nx); - } - - void set_fft_plan() - { - fft_1d->create_plan_1d(grid_1d.nx, 1); - fft_1d_e.create_plan_1d(grid_1d_e.nx, 1); - } - - void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - Border_1d bd, bool b_pv, TVector_r &M_o) - { - thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); - thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); - - preprocessing(M_r, p, bd, M_r_c); - preprocessing(M_s, p, bd, M_s_c); - - TVector_c &pcf = M_s_c; - - // shift matrix - fft1_shift(grid_1d_e, M_r_c); - fft1_shift(grid_1d_e, M_s_c); - - // fft_1d_e - fft_1d_e.forward(M_r_c); - fft_1d_e.forward(M_s_c); - - pcf_g(M_r_c, M_s_c, sigma_g, pcf); - - fft_1d_e.inverse(pcf); - - // shift pcf - fft1_shift(grid_1d_e, pcf); - - int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; - this->assign_real(pcf, ix_s, M_o, b_pv); - } - - void cleanup() - { - fft_1d->destroy_plan(); - fft_1d_e.cleanup(); - } - - protected: - - void assign_real(TVector_c &M_i, int ix_s, TVector_r &M_o, bool b_pos = false) - { - auto first = M_i.begin() + ix_s; - auto last = first + grid_1d.nx; - - if(b_pos) - { - thrust::transform(first, last, M_o.begin(), functor::assign_max_real(0)); - } - else - { - thrust::transform(first, last, M_o.begin(), functor::assign_real()); - } - } - - /************************Host************************/ - template - enable_if_dev_host - preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) - { - int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; - - Butterworth_1d bw_1d(bd, bd.radius_ptl(p), 32); - - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - host_device_detail::pcf_1d_pp(ix, ix_s, grid_1d, bw_1d, M_i, M_o); - } - } - - template - enable_if_dev_host - pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) - { - Gauss_1d gs_1d(0, sigma_g); - - for (auto ix = 0; ix < grid_1d_e.nx; ix++) - { - host_device_detail::pcf_1d_gaussian(ix, grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); - } - } - - /***********************Device***********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) - { - int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; - - Butterworth_1d bw_1d(bd, bd.radius_ptl(p), 32); - - auto grid_bt = grid_1d.cuda_grid(); - device_detail::pcf_1d_pp, typename TVector_c::value_type><<>>(ix_s, grid_1d, bw_1d, M_i, M_o); - } - - template - enable_if_dev_device - pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) - { - Gauss_1d gs_1d(0, sigma_g); - - auto grid_bt = grid_1d_e.cuda_grid(); - device_detail::pcf_1d_gaussian, typename TVector_c::value_type><<>>(grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); - } - #endif - - TVector_c M_r_c; - TVector_c M_s_c; - - FFT *fft_1d; - Grid_1d grid_1d; - - private: - FFT fft_1d_e; - Grid_1d grid_1d_e; - }; - - template - class Pcf_2d_BC - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Pcf_2d_BC():stream(nullptr), fft_2d(nullptr){} - - Pcf_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - grid_1d.set_input_data(grid_2d.ny, grid_2d.ly); - - Prime_Num pn; - - int ny = pn(2*grid_2d.ny-1, eDST_Greater_Than); - - grid_2d_e.set_input_data(grid_2d.nx, ny, grid_2d.lx, grid_2d.dRy*ny); - grid_1d_e.set_input_data(grid_2d_e.ny, grid_2d_e.ly); - - M_r_c.resize(grid_2d_e.nxy()); - M_s_c.resize(grid_2d_e.nxy()); - } - - void set_fft_plan() - { - fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); - fft_2d_e.create_plan_1d_batch(grid_2d_e.ny, grid_2d_e.nx, stream->size()); - } - - void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - Border_1d bd, bool b_pv, TVector_r &M_o) - { - thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); - thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); - - preprocessing(M_r, p, bd, M_r_c); - preprocessing(M_s, p, bd, M_s_c); - - TVector_c &pcf = M_s_c; - - // shift matrix - fft2_sft_bc(*stream, grid_2d_e, M_r_c); - fft2_sft_bc(*stream, grid_2d_e, M_s_c); - - // fft_2d - fft_2d_e.forward(M_r_c); - fft_2d_e.forward(M_s_c); - - pcf_g(M_r_c, M_s_c, sigma_g, pcf); - fft_2d_e.inverse(pcf); - - // shift pcf - fft2_sft_bc(*stream, grid_2d_e, pcf); - - int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; - this->assign_real(pcf, iy_s, M_o, b_pv); - } - - void cleanup() - { - fft_2d->destroy_plan(); - fft_2d_e.cleanup(); - } - - protected: - - TVector_r gauss_vector_1d(Grid_1d &grid_1d, T sigma_g, bool b_norm = false) - { - Gauss_1d gs_1d(0, sigma_g); - - TVector_r fg; - fg.reserve(grid_1d.nx); - - for (auto ix=0; ix < grid_1d.nx; ix++) - { - T g2 = grid_1d.g2_shift(ix); - T v = gs_1d(g2); - fg.push_back(v); - } - return fg; - } - - /************************Host************************/ - template - enable_if_dev_host - preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) - { - int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; - - auto fh = func_butterworth_1d(grid_1d, bd.radius_ptl(p), 32, false, bd); - - stream->set_n_act_stream(grid_2d.nx); - stream->set_grid(grid_2d.nx, grid_2d.ny); - stream->exec_matrix(host_device_detail::pcf_2d_bc_pp, TVector_r, TVector_c>, iy_s, grid_2d, grid_2d_e, M_i, fh, M_o); - } - - template - enable_if_dev_host - pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) - { - auto fg = gauss_vector_1d(grid_1d_e, sigma_g); - - stream->set_n_act_stream(grid_2d_e.nx); - stream->set_grid(grid_2d_e.nx, grid_2d_e.ny); - stream->exec_matrix(host_device_detail::pcf_2d_bc_gaussian, TVector_r, TVector_c>, grid_2d_e, M_r_c, M_s_c, fg, pcf); - } - - template - enable_if_dev_host - assign_real(TVector_c &M_i, int iy_s, TVector_r &M_o, bool b_pos = false) - { - for(auto ix = 0; ix < grid_2d.nx; ix++) - { - for(auto iy = 0; iy < grid_2d.ny; iy++) - { - int ixy_i = grid_2d_e.ind_col(ix, iy+iy_s); - int ixy_o = grid_2d.ind_col(ix, iy); - auto v = M_i[ixy_i].real(); - M_o[ixy_o] = (!b_pos || (v>0))?v:0; - } - } - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) - { - int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; - - auto fh_h = func_butterworth_1d>(grid_1d, bd.radius_ptl(p), 32, false, bd); - TVector_r fh = fh_h; - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::pcf_2d_bc_pp, typename TVector_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, M_i, fh, M_o); - } - - template - enable_if_dev_device - pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) - { - auto fg_h = gauss_vector_1d(grid_1d_e, sigma_g); - TVector_r fg = fg_h; - - auto grid_bt = grid_2d_e.cuda_grid(); - device_detail::pcf_2d_bc_gaussian, typename TVector_c::value_type><<>>(grid_2d_e, M_r_c, M_s_c, fg, pcf); - } - - template - enable_if_dev_device - assign_real(TVector_c &M_i, int iy_s, TVector_r &M_o, bool b_pos = false) - { - auto grid_bt = grid_2d.cuda_grid(); - device_detail::pcf_2d_bc_assign_real, typename TVector_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, M_i, M_o, b_pos); - } - #endif - - Vector M_r_c; - Vector M_s_c; - - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - Grid_1d grid_1d; - - private: - FFT fft_2d_e; - Grid_2d grid_2d_e; - Grid_1d grid_1d_e; - }; - - template - class Pcf_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - static const eDevice device = dev; - - Pcf_2d():stream(nullptr), fft_2d(nullptr){} - - Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - stream = stream_i; - fft_2d = fft_2d_i; - grid_2d = grid_2d_i; - - M_r_c.resize(grid_2d.nxy()); - M_s_c.resize(grid_2d.nxy()); - } - - void set_fft_plan() - { - fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); - } - - void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - Border_2d bd, bool b_pv, TVector_r &M_o) - { - preprocessing(M_r, p, bd, M_r_c); - preprocessing(M_s, p, bd, M_s_c); - - TVector_c &pcf = M_s_c; - - // shift matrix - fft2_shift(*stream, grid_2d, M_r_c); - fft2_shift(*stream, grid_2d, M_s_c); - - // fft_2d - fft_2d->forward(M_r_c); - fft_2d->forward(M_s_c); - - pcf_g(M_r_c, M_s_c, sigma_g, pcf); - fft_2d->inverse(pcf); - - // shift pcf - fft2_shift(*stream, grid_2d, pcf); - - T pv = (b_pv)?1:-1; - assign_real(pcf, M_o, pv); - } - - void cleanup() - { - fft_2d->cleanup(); - } - - protected: - /************************Host************************/ - template - enable_if_dev_host - preprocessing(TVector_r &M_i, T p, Border_2d &bd, TVector_c &M_o) - { - Butterworth_2d bw_2d(bd, bd.radius_ptl(p), 32); - - stream->set_n_act_stream(grid_2d.nx); - stream->set_grid(grid_2d.nx, grid_2d.ny); - stream->exec_matrix(host_device_detail::pcf_2d_pp, TVector_r, TVector_c>, grid_2d, bw_2d, M_i, M_o); - } - - template - enable_if_dev_host - pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) - { - Gauss_2d gs_2d(0, 0, sigma_g); - - stream->set_n_act_stream(grid_2d.nx); - stream->set_grid(grid_2d.nx, grid_2d.ny); - stream->exec_matrix(host_device_detail::pcf_2d_gaussian, TVector_c>, grid_2d, gs_2d, M_r_c, M_s_c, pcf); - } - - /**********************Device**********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - preprocessing(TVector_r &M_i, T p, Border_2d &bd, TVector_c &M_o) - { - Butterworth_2d bw_2d(bd, bd.radius_ptl(p), 32); - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::pcf_2d_pp, typename TVector_c::value_type><<>>(grid_2d, bw_2d, M_i, M_o); - } - - template - enable_if_dev_device - pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) - { - Gauss_2d gs_2d(0, 0, sigma_g); - - auto grid_bt = grid_2d.cuda_grid(); - device_detail::pcf_2d_gaussian, typename TVector_c::value_type><<< grid_bt.Blk, grid_bt.Thr >>>(grid_2d, gs_2d, M_r_c, M_s_c, pcf); - } - #endif - - Vector M_r_c; - Vector M_s_c; - - Stream *stream; - FFT *fft_2d; - Grid_2d grid_2d; - }; - - /********************find shift**********************/ - template - class Fd_Sft_1d: public Pcf_1d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - Fd_Sft_1d(): Pcf_1d(){} - - Fd_Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i): Pcf_1d() - { - set_input_data(fft_1d_i, grid_1d_i); - } - - inline - void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) - { - Pcf_1d::set_input_data(fft_1d_i, grid_1d_i); - sft_1d.set_input_data(fft_1d_i, grid_1d_i); - } - - T operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, T dx, - Border_1d bd, int nit_pcf) - { - T sigma_r = 1.0/(c_2Pi*sigma_g); - T radius = ::fmax(3*this->grid_1d.dRx, 0.9*sigma_r); - - TVector_r M = M_s; - TVector_r pcf(M.size()); - - if(nonZero(dx)) - { - sft_1d(dx, M); - } - - for (auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); - - // get maximun position - T x_c = host_device_detail::max_pos_1d(this->grid_1d, pcf); - - if(it==nit_pcf-1) - { - x_c = fit_max_pos_1d(this->grid_1d, pcf, x_c, sigma_r, radius); - } - - T dx_t = -(x_c - this->grid_1d.lxh()); - - if(it sft_1d; - }; - - template - class Fd_Sft_2d_BC: public Pcf_2d_BC - { - public: - using TB = std::pair; - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - using TVector_rh = Vector; - using TVector_ch = Vector; - - Fd_Sft_2d_BC(): Pcf_2d_BC() {} - - Fd_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Pcf_2d_BC() - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - Pcf_2d_BC::set_input_data(stream_i, fft_2d_i, grid_2d_i); - gauss_cv_2d_bc.set_input_data(stream_i, fft_2d_i, grid_2d_i); - sft_2d_bc.set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - TVector_rh operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, TVector_rh dx, - Border_2d bd_2d, int nit_pcf) - { - T sigma_r = 1.0/(c_2Pi*sigma_g); - T radius = ::fmax(3*this->grid_1d.dRx, 0.9*sigma_r); - Border_1d bd_1d(bd_2d.ly, bd_2d.yb_0, bd_2d.yb_e); - Peaks peaks(this->grid_1d, &bd_1d); - - TVector_r M_r = M_r_i; - TVector_r M_s = M_s_i; - TVector_r pcf(M_r.size()); - - // Gaussian filter - gauss_cv_2d_bc(sigma_r, M_r); - gauss_cv_2d_bc(sigma_r, M_s); - - const int ix_0 = this->grid_2d.ceil_dRx(bd_2d.x_0()); - const int ix_e = this->grid_2d.floor_dRx(bd_2d.x_e()); - - bool dx_s = false; - for(auto ix=0; ixgrid_1d.nx, T(0)); - - for (auto it=0; it::operator()(M_r, M_s, p, sigma_g, bd_1d, false, pcf); - - // get maximum distance - T d_max = (it==0)?peaks.get_d_max_0(ix_0, ix_e, pcf):peaks.get_d_max(ix_0, ix_e, dx_t); - d_max = ::fmax(sigma_r, d_max); - - for(auto ix=ix_0; ixgrid_1d.nx, pcf.begin()+(ix+1)*this->grid_1d.nx); - - auto py = peaks.find(ix, M_r, M_s, y, d_max); - if(it==nit_pcf-1) - { - py = fit_max_pos_1d(this->grid_1d, y, py, sigma_r, radius); - } - dx_t[ix] = -(py - this->grid_1d.lxh()); - dx[ix] += dx_t[ix]; - } - - // shift by column - if(it gauss_cv_2d_bc; - Sft_2d_BC sft_2d_bc; - - private: - struct Peaks - { - public: - using TVector_ih = Vector; - - Peaks(): y_c(0), bd_1d(nullptr){} - - Peaks(Grid_1d &grid_1d_i, Border_1d *bd_1d_i) - { - set_input_data(grid_1d_i, bd_1d_i); - } - - inline - void set_input_data(Grid_1d &grid_1d_i, Border_1d *bd_1d_i) - { - grid_1d = grid_1d_i; - bd_1d = bd_1d_i; - fft_1d.create_plan_1d(grid_1d.nx, 1); - sft_1d.set_input_data(&fft_1d, grid_1d); - - ix_pk.resize(grid_1d.nx); - x_pk.resize(grid_1d.nx); - y_pk.resize(grid_1d.nx); - } - - T get_d_max_0(int ix_0, int ix_e, TVector_r &pcf) - { - T x_c = grid_1d.lxh(); - TVector_rh dx; - dx.reserve(grid_1d.nx); - - for(auto ix=ix_0; ixdx_max); }); - dx.resize(std::distance(dx.begin(), it)); - - T dx_std = sqrt(variance(dx)); - T d_max = max_element(dx) + 2*dx_std; - - return ::fmax(10*grid_1d.dRx, d_max); - } - - T get_d_max(int ix_0, int ix_e, TVector_rh &dx) - { - TVector_rh dx_h(dx.begin()+ix_0, dx.begin()+ix_e); - return ::fmax(10*grid_1d.dRx, 3*sqrt(variance(dx_h))); - } - - T find(int icol, TVector_r &M_r, TVector_r &M_s, TVector_rh &y, T d_max) - { - const T x_c = grid_1d.lxh(); - y_c = y[grid_1d.nxh]; - - // find peaks - fd_peaks(y); - - // remove peaks - remove_peaks(x_c-d_max, x_c+d_max); - - // return if x_pk is empty - if(empty()) - { - return x_c; - } - - // return if there is only one element - if(size() == 1) - { - return x_pk.front(); - } - - const int ix_max = idx_y_max(); - const int ix_clt = idx_x_clt(); - - // return if closest position is equal to maximum intensity position - // and the maximum intensity is greater than the second maximum intensity - if(fabs(x_pk[ix_max]-x_pk[ix_clt])<1) - { - T y_thr = 0.61*y_pk[ix_max]; - for(auto ix=0; ix grid_1d; - Border_1d *bd_1d; - - FFT fft_1d; - Sft_1d sft_1d; - - T y_c; - - bool empty() const - { - return ix_pk.empty(); - } - - int size() const - { - return ix_pk.size(); - } - - int idx_y_max() const - { - int idx_max = (std::max_element(y_pk.begin(), y_pk.end())-y_pk.begin()); - - return idx_max; - } - - int idx_x_clt() const - { - T x_c = grid_1d.lxh(); - - int idx_clt = 0; - if(x_pk.size()>1) - { - idx_clt = std::min_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)1) - { - idx_clt = std::max_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)y_thr) - { - if((y[ix-1] bd_l = *bd_1d; - bd_l.xb_0 = max(bd_l.xb_0, d_fht); - bd_l.xb_e = max(bd_l.xb_e, d_fht); - - // get indexes - const int ix_0 = grid_1d.ceil_dRx(bd_l.x_0()); - const int ix_e = grid_1d.floor_dRx(bd_l.x_e()); - - // get reference data - TVector_rh yr_b(M_r.begin()+(icol-1)*grid_1d.nx, M_r.begin()+icol*grid_1d.nx); - TVector_rh yr(M_r.begin()+icol*grid_1d.nx, M_r.begin()+(icol+1)*grid_1d.nx); - TVector_rh yr_n(M_r.begin()+(icol+1)*grid_1d.nx, M_r.begin()+(icol+2)*grid_1d.nx); - - // get shifted data - TVector_rh ys_0(M_s.begin()+icol*grid_1d.nx, M_s.begin()+(icol+1)*grid_1d.nx); - - TVector_rh chi2_pk(size()); - - for(auto ix_pk=0; ix_pk - class Fd_Sft_2d: public Pcf_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - Fd_Sft_2d(): Pcf_2d(){} - - Fd_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Pcf_2d() - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - Pcf_2d::set_input_data(stream_i, fft_2d_i, grid_2d_i); - sft_2d.set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - r2d operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, r2d dr, - Border_2d bd, int nit_pcf) - { - T sigma_r = 1.0/(c_2Pi*sigma_g); - T radius = ::fmax(3*this->grid_2d.dR_min(), 0.9*sigma_r); - - TVector_r M = M_s; - TVector_r pcf(M.size()); - - if(nonZero(dr)) - { - sft_2d(dr, M); - } - - for (auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); - - // get maximun position - r2d r_c = host_device_detail::max_pos_2d(this->grid_2d, pcf); - - if(it==nit_pcf-1) - { - r_c = fit_max_pos_2d(this->grid_2d, pcf, r_c, sigma_r, radius); - } - - r2d dr_t = -(r_c - r2d(this->grid_2d.lxh(), this->grid_2d.lyh())); - - if(it sft_2d; - }; - - /*******************Corrrect shift*******************/ - template - class Crt_Sft_1d: public Fd_Sft_1d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - Crt_Sft_1d(): Fd_Sft_1d(){} - - Crt_Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i): - Fd_Sft_1d(fft_1d_i, grid_1d_i){} - - T operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, - Border_1d bd, int nit_pcf) - { - T dx = 0; - dx = Fd_Sft_1d::operator()(M_r_i, M_s_io, p, sigma_g, dx, bd, nit_pcf); - this->sft_1d(dx, M_s_io); - - return dx; - } - }; - - template - class Crt_Sft_2d_BC: public Fd_Sft_2d_BC - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - using TVector_rh = Vector; - using TVector_ch = Vector; - - Crt_Sft_2d_BC(): Fd_Sft_2d_BC(){} - - Crt_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): - Fd_Sft_2d_BC(stream_i, fft_2d_i, grid_2d_i){} - - TVector_rh operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, - Border_2d bd, int nit_pcf) - { - TVector_rh dr(this->grid_2d.ny, T(0)); - dr = Fd_Sft_2d_BC::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); - this->sft_2d_bc(1, dr, M_s_io); - - return dr; - } - }; - - template - class Crt_Sft_2d: public Fd_Sft_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - Crt_Sft_2d(): Fd_Sft_2d(){} - - Crt_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): - Fd_Sft_2d(stream_i, fft_2d_i, grid_2d_i){} - - r2d operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, - Border_2d bd, int nit_pcf) - { - r2d dr(0, 0); - dr = Fd_Sft_2d::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); - this->sft_2d(dr, M_s_io); - - return dr; - } - }; - - /****************calculate Chi^2*****************/ - template - class Chi2_Pcf_2d: public Crt_Sft_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - Chi2_Pcf_2d(): Crt_Sft_2d(){} - - Chi2_Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Crt_Sft_2d() - { - set_input_data(stream_i, fft_2d_i, grid_2d_i); - } - - inline - void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) - { - Crt_Sft_2d::set_input_data(stream_i, fft_2d_i, grid_2d_i); - shx_scy.set_input_data(this->stream, this->grid_2d); - } - - T operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, - r2d af, Border_2d bd, int nit_pcf, r2d &ds) - { - TVector_r M(M_r_i.size()); - shx_scy(M_s_i, af, M); - - // correct shift and set borders - ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); - - // pcf - TVector_r &pcf = M; - Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, true, pcf); - - // cost function - return mean(*(this->stream), pcf); - } - - T operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, - r2d af, Border_2d bd, int nit_pcf, r2d &ds, Vector &coef) - { - TVector_r M(M_r_i.size()); - shx_scy(M_s_i, af, M); - - // correct shift and set borders - ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); - - // pcf - TVector_r &pcf = M; - Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, true, pcf); - - // cost function - auto chi2 = mean(*(this->stream), pcf); - - // get maximun position - r2d r_c = host_device_detail::max_pos_2d(this->grid_2d, pcf); - - // fitting - T sigma_r = 1.0/(c_2Pi*sigma_g); - T radius = ::fmax(3*this->grid_2d.dR_min(), 1.5*sigma_r); - Vector pcf_h = pcf; - coef = fit_ellipt_gauss_2d(this->grid_2d, pcf_h, r_c, sigma_r, radius); - coef[0] = ds.x + this->grid_2d.lxh(); - coef[1] = ds.y + this->grid_2d.lyh(); - - return chi2; - } - - protected: - Shx_Scy shx_scy; - }; - - template - class NM_Shx_Scy: public Chi2_Pcf_2d - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - - NM_Shx_Scy():Chi2_Pcf_2d(), nit_pcf(2){} - - NM_Shx_Scy(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): - Chi2_Pcf_2d(stream_i, fft_2d_i, grid_2d_i), nit_pcf(2){} - - void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - Vector, e_host> &spx, Border_2d bd, int nit_nm) - { - int ic = 1; - - T d_pix_min = this->grid_2d.dg_min(); - T d_min = 0.05*d_pix_min; - T alpha = 1.0; - T beta = 0.5; - T gamma = 2.0; - - for(auto it=0; it ds_r(0, 0); - auto chi2_r = chi2_pcf(M_r, M_s, p, sigma_g, x_r, bd, nit_pcf, ds_r); - - if(chi2_r ds_e(0, 0); - auto chi2_e = chi2_pcf(M_r, M_s, p, sigma_g, x_e, bd, nit_pcf, ds_e); - if(chi2_e(x_e, ds_e, chi2_e); - } - else - { - spx[2] = Afp_2(x_r, ds_r, chi2_r); - } - } - else if(chi2_r(x_r, ds_r, chi2_r); - } - else if(chi2_r ds_rc(0, 0); - auto chi2_rc = chi2_pcf(M_r, M_s, p, sigma_g, x_rc, bd, nit_pcf, ds_rc); - if(chi2_rc(x_rc, ds_rc, chi2_rc); - } - else - { - contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); - } - } - else - { - auto x_wc = x_m + beta*(x_w-x_m); - r2d ds_wc(0, 0); - auto chi2_wc = chi2_pcf(M_r, M_s, p, sigma_g, x_wc, bd, nit_pcf, ds_wc); - if(chi2_wc(x_wc, ds_wc, chi2_wc); - } - else - { - contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); - } - } - } - - } - - void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - r2d &af, Border_2d bd, r2d &ds, int nit_nm) - { - auto spx = set_simplex(M_r, M_s, p, sigma_g, af, ds, bd, nit_nm); - this->operator()(M_r, M_s, p, sigma_g, spx, bd, nit_nm); - - af = spx[0].f; - ds = spx[0].ds; - - // // shear and scaling - // shx_scy(M_s, af, M_s); - // // correct shift - // ds = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds, bd, nit_pcf); - } - - protected: - r2d x_af(const r2d &af, const r2d &r) - { - return r2d(r.x+af.x*r.y, af.y*r.y); - } - - r2d x_iaf(const r2d &af, const r2d &r) - { - return r2d(r.x-af.x*r.y/af.y, r.y/af.y); - } - - Vector, e_host> set_simplex(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - r2d x_0, r2d ds_0, Border_2d &bd, int nit_nm) - { - // global shift - if(isZero(ds_0)) - { - ds_0 = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds_0, bd, nit_pcf); - bd.set_bd(ds_0); - } - - TVector_r M_s_t = M_s; - this->sft_2d(x_iaf(x_0, ds_0), M_s_t); - - // determine coefficients - Vector coef(6); - chi2_pcf(M_r, M_s_t, p, sigma_g, x_0, bd, nit_pcf, ds_0, coef); - - // calculate dd0 - T ff = coef[4]/coef[3]; - ff = (ff<1)?1/ff:ff; - ff = ::fmax(1.05, ff); - - T dd0 = sqrt(1.354e-04*pow(ff-1, 2)+6.622e-4*(ff-1)); - dd0 = ::fmax(dd0, this->grid_2d.dg_min()); - - T sin_t = sin(coef[5]); - T cos_t = cos(coef[5]); - - T sigma_x = pow(cos_t/coef[3], 2)+pow(sin_t/coef[4], 2); - sigma_x = sqrt(1/sigma_x); - - T sigma_y = pow(sin_t/coef[3], 2)+pow(cos_t/coef[4], 2); - sigma_y = sqrt(1/sigma_y); - - T theta = atan2(sigma_y, sigma_x); - - r2d u(dd0*cos(theta), dd0*sin(theta)); - r2d v(-u.y, u.x); - - // set simplex - Vector, e_host> spx(3); - - spx[0].f = x_0; - spx[0].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[0].f, bd, nit_pcf, spx[0].ds); - - spx[1].f = x_0+u; - spx[1].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[1].f, bd, nit_pcf, spx[1].ds); - - spx[2].f = x_0+v; - spx[2].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[2].f, bd, nit_pcf, spx[2].ds); - - // sort simplex - sort(spx); - - return spx; - } - - T chi2_pcf(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - r2d af, Border_2d &bd, int nit_pcf, r2d &ds) - { - return Chi2_Pcf_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, ds); - } - - T chi2_pcf(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - r2d af, Border_2d &bd, int nit_pcf, r2d &ds, Vector &coef) - { - return Chi2_Pcf_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, ds, coef); - } - - void sort(Vector, e_host> &spx) - { - std::sort(spx.begin(), spx.end(), [](const Afp_2 &x, const Afp_2 &y){ return x.chi2, e_host> &spx) - { - auto r0 = spx[0].f; - - r2d dr = spx[1].f - r0; - T d_max = dr.module(); - for(auto i=2; i dr = spx[i].f - r0; - d_max = ::fmax(d_max, dr.module()); - } - return d_max; - } - - T min_length(Vector, e_host> &spx) - { - auto r0 = spx[0].f; - r2d dr = spx[1].f - r0; - T d_min = dr.module(); - for(auto i=2; i dr = spx[i].f - r0; - d_min = ::fmin(d_min, dr.module()); - } - return d_min; - } - - r2d best_centroid(Vector, e_host> &spx) - { - r2d r_c(0, 0); - for(auto i=0; i, e_host> &spx, Border_2d &bd, int nit_pcf) - { - auto p12 = spx[1].f-spx[0].f; - auto p13 = spx[2].f-spx[0].f; - auto mp12 = p12.module(); - auto mp13 = p13.module(); - auto mp_max = ::fmax(mp12, mp13); - - T theta = angle(p12, p13); - - T theta_min = 10; - T theta_0 = theta_min*c_Pi/180; - T theta_e = c_Pi-theta_min*c_Pi/180; - - bool b_m = (mp12theta_e)||b_m) - { - if(b_m && (mp12(-u.y, u.x); - r2d ds_o(0, 0); - auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); - - spx[1] = Afp_2(x_o, ds_o, chi2_o); - } - else - { - T m = max_length(spx); - auto u = p12/module(p12); - auto x_o = spx[0].f + mp_max*r2d(-u.y, u.x); - r2d ds_o(0, 0); - auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); - - spx[2] = Afp_2(x_o, ds_o, chi2_o); - } - - sort(spx); - } - } - - void contract_simplex(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, - Vector, e_host> &spx, Border_2d &bd, int nit_pcf) - { - T ff = 0.5; - - auto p12 = spx[1].f-spx[0].f; - auto p13 = spx[2].f-spx[0].f; - auto mp12 = p12.module(); - auto mp13 = p13.module(); - - if(mp12(-u.y, u.x); - r2d ds_c(0, 0); - auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); - - spx[2] = Afp_2(x_c, ds_c, chi2_c); - } - else - { - auto u = p13/mp13; - auto x_c = spx[0].f + ff*mp12*r2d(-u.y, u.x); - r2d ds_c(0, 0); - auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); - - spx[1] = Afp_2(x_c, ds_c, chi2_c); - } - - sort(spx); - } - - int nit_pcf; - }; - -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_CLASSES_H + #define CGPU_CLASSES_H + + #include "math_mt.h" + #include "types.cuh" + #include "type_traits_gen.h" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + //#include "eval_fit_gaussians.hpp" + #include "cgpu_rand.cuh" + + #ifdef __CUDACC__ + #include + #include + #include + #endif + + #include "in_classes.cuh" + #include "fcns_gpu.h" + #include "fcns_cpu.h" + #include "particles.cuh" + + #ifdef __CUDACC__ + #include "fcns_gpu.h" + #endif + + namespace mt + { + /********************************* Gaussian Conv ***************************************/ + template + class Gauss_Cv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Cv_1d():fft_1d(nullptr) {} + + Gauss_Cv_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, TVctr_c& Im) + { + fcn_fftsft_1d(grid_1d, Im); + fft_1d->forward(Im); + + gauss_cv_1d(sigma_r, Im); + + fft_1d->inverse(Im); + fcn_fftsft_1d(grid_1d, Im); + } + + void operator()(T sigma_r, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_1d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + cgpu_detail::gauss_cv_1d, TVctr_c>(ix, grid_1d, alpha, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_1d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_1d.d_grid_blk(); + gpu_detail::gauss_cv_1d, typename TVctr_c::value_type><<>>(grid_1d, alpha, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Cv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Cv_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Cv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVctr_c& Im) + { + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, Im); + + fft_2d->inverse(Im); + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vctr gauss_vector_1d(T alpha) + { + TVctr_r fg; + fg.reserve(grid_2d.ny); + + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_sft(iy))/grid_2d.ny_r(); + fg.push_back(v); + } + return fg; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_2d_bc(T sigma_r, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_ew_mult_mx_vctr_col, TVctr_r, TVctr_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_2d_bc(T sigma_r, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha); + TVctr_r fg = fg_h; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_ew_mult_mx_vctr_col, typename TVctr_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Cv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Cv_2d():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Cv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVctr_c& Im) + { + if (fcn_is_zero(sigma_r)) + { + return; + } + + fcn_fftsft_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d(sigma_r, Im); + + fft_2d->inverse(Im); + fcn_fftsft_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVctr_r &Im) + { + if (fcn_is_zero(sigma_r)) + { + return; + } + + Im_c.assign(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_2d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::gauss_cv_2d, TVctr_c>, grid_2d, alpha, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_2d(T sigma_r, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::gauss_cv_2d, typename TVctr_c::value_type><<>>(grid_2d, alpha, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + + TVctr_c Im_c; + }; + + /********************************* Gaussian Deconv *************************************/ + template + class Gauss_Dcv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Dcv_1d():fft_1d(nullptr) {} + + Gauss_Dcv_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, T PSNR, TVctr_c& Im) + { + fcn_fftsft_1d(grid_1d, Im); + fft_1d->forward(Im); + + gauss_dcv_1d(sigma_r, PSNR, Im); + + fft_1d->inverse(Im); + fcn_fftsft_1d(grid_1d, Im); + } + + void operator()(T sigma_r, T PSNR, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_dcv_1d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + cgpu_detail::gauss_dcv_1d, TVctr_c>(ix, grid_1d, alpha, PSNR, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_dcv_1d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_1d.d_grid_blk(); + gpu_detail::gauss_dcv_1d, typename TVctr_c::value_type><<>>(grid_1d, alpha, PSNR, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Dcv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Dcv_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Dcv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVctr_c& Im) + { + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vctr gauss_vector_1d(T alpha, T PSNR) + { + TVctr_r fg; + fg.reserve(grid_2d.ny); + + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_sft(iy)); + fg.push_back(v/((v*v+PSNR)*grid_2d.ny_r())); + } + return fg; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_cv_2d_bc(T sigma_r, T PSNR, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha, PSNR); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_ew_mult_mx_vctr_col, TVctr_r, TVctr_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_cv_2d_bc(T sigma_r, T PSNR, TVctr_c& M_g) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha, PSNR); + TVctr_r fg = fg_h; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_ew_mult_mx_vctr_col, typename TVctr_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Dcv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Gauss_Dcv_2d():stream(nullptr), fft_2d(nullptr) {} + + Gauss_Dcv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVctr_c& Im) + { + fcn_fftsft_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_dcv_2d(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fcn_fftsft_2d(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + fcn_assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + gauss_dcv_2d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::gauss_dcv_2d, TVctr_c>, grid_2d, alpha, PSNR, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + gauss_dcv_2d(T sigma_r, T PSNR, TVctr_c& Im) + { + auto alpha = 2*c_pi2*sigma_r*sigma_r; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::gauss_dcv_2d, typename TVctr_c::value_type><<>>(grid_2d, alpha, PSNR, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /******************************* affine transformations ********************************/ + template + class Sd_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Sd_2d(): stream(nullptr) {} + + Sd_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + bg_opt = bg_opt_i; + bg = bg_i; + } + + void generate_dx_dy(T ds_x, T phi_x, T ds_y, T phi_y, dt_int32 seed, TVctr& dx_o, TVctr& dy_o) + { + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + gen.seed(seed); + rnd_n.reset(); + + dx_o = generate_ds(ds_x, phi_x); + dy_o = generate_ds(ds_y, phi_y); + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& dx, TVctr& dy, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::sd_2d, TVctr>, grid_2d, mx_i, dx, dy, bg, mx_o); + + return bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& dx, TVctr& dy, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::sd_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, dx, dy, bg, mx_o); + + return bg; + } + #endif + + protected: + std::mt19937_64 gen; + std::normal_distribution rnd_n; + + Grid_2d grid_2d; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + Vctr generate_ds(T ds, T phi) + { + Vctr ds_v; + ds_v.reserve(grid_2d.ny); + + T a = ds*rnd_n(gen); + ds_v.push_back(a/::sqrt(1.0-phi*phi)); + for(auto iy = 1; iy < grid_2d.ny; iy++) + { + T a = ds*rnd_n(gen); + ds_v.push_back(phi*ds_v.back() + a); + } + return ds_v; + } + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + template + class Sd_nr_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Sd_nr_2d(): stream(nullptr) {} + + Sd_nr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + bg_opt = bg_opt_i; + bg = bg_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, TVctr& mx_o) + { + preprocessing(mx_i, ds_x_i, ds_y_i, parm); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::sd_nr_2d, TVctr, SPar>, grid_2d, mx_i, parm, mx_o); + + return parm.bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, TVctr& mx_o) + { + // preprocessing(ds_x_i, ds_y_i, parm); + // auto d_grid_blk = grid_2d.d_grid_blk(); + // gpu_detail::sd_nr_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, ds_x_i, ds_y_i, mx_o); + + return parm.bg; + } + + #endif + + protected: + struct SPar + { + eFil_Sel_Typ bg_opt; + T bg; + TVctr dx; + TVctr dy; + TVctr ry_s; + Vctr iy; + } parm; + + struct sort_by_first + { + template + CGPU_EXEC + dt_bool operator()(const Ttuple1 &t1, const Ttuple2 &t2) + { + return thrust::get<0>(t1) < thrust::get<0>(t2); + } + }; + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, SPar &parm) + { + // calculate background + parm.bg_opt = bg_opt; + parm.bg = get_bg(mx_i); + + parm.dx = ds_x_i; + parm.dy = ds_y_i; + parm.ry_s.resize(parm.dy.size()); + parm.iy.resize(parm.dy.size()); + + for(auto ik = 0; ik < parm.dy.size(); ik++) + { + parm.ry_s[ik] = grid_2d.ry(ik) + parm.dy[ik]; + parm.iy[ik] = ik; + } + + auto first = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.begin(), parm.iy.begin())); + auto last = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.end(), parm.iy.end())); + + thrust::sort(first, last, sort_by_first()); + } + + /**********************Device**********************/ + // not working yet + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr& mx_i, TVctr& ds_x_i, TVctr& ds_y_i, SPar &parm) + { + // calculate background + parm.bg_opt = bg_opt; + parm.bg = get_bg(mx_i); + + parm.dx = ds_x_i; + parm.dy = ds_y_i; + parm.ry_s.resize(parm.dy.size()); + parm.iy.resize(parm.dy.size()); + + for(auto ik = 0; ik < parm.dy.size(); ik++) + { + parm.ry_s[ik] = grid_2d.ry(ik) + parm.dy[ik]; + parm.iy[ik] = ik; + } + + auto first = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.begin(), parm.iy.begin())); + auto last = thrust::make_zip_iterator(thrust::make_tuple(parm.ry_s.end(), parm.iy.end())); + + thrust::sort(first, last, sort_by_first()); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + template + class Data_Aug_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Data_Aug_2d():stream(nullptr) {} + + Data_Aug_2d(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, T theta, R_2d p0, T sx, T sy, R_2d ps, T sim, + dt_int32 nx_o, dt_int32 ny_o, TVctr& mx_o) + { + // calculate maximum + auto M_max = *thrust::max_element(mx_i.begin(), mx_i.end()); + + // calculate background + auto g_max = grid_2d.gx_back(); + auto g_min = 0.9*g_max; + // T bg = fcn_int_det_ring(*stream, grid_2d, g_min, g_max, mx_i); + + T bg = 0.6*fcn_mean(*stream, mx_i); + + T rx_0 = p0.x*sx-(nx_o/2)*grid_2d.drx; + T ry_0 = p0.y*sy-(ny_o/2)*grid_2d.dry; + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + grid_2d_o.set_r_0(rx_0, ry_0); + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::rot_sca_sft_2d, TVctr>, grid_2d, mx_i, theta, p0, sx, sy, ps, bg, grid_2d_o, mx_o); + + normalized_data(mx_o, M_max); + + // add Poisson noise + mx_o = fcn_add_poiss_nois(*stream, mx_o, sim, -1); + + M_max = *thrust::max_element(mx_o.begin(), mx_o.end()); + normalized_data(mx_o, M_max); + } + + protected: + void normalized_data(TVctr& M, T M_max) + { + std::for_each(M.begin(), M.end(), [M_max](T& v){ v = (v>0)?v/M_max:0; }); + } + + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Interp_rn_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Interp_rn_2d(): stream(nullptr) {} + + Interp_rn_2d(Stream *stream_i, Grid_2d& grid_2d_i, Grid_2d& grid_2d_o, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, grid_2d_o, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, Grid_2d& grid_2d_o, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + grid_2d_mo = grid_2d_o; + bg_opt = bg_opt_i; + bg = bg_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& Rx_i, TVctr& Ry_i, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + stream->set_n_stream_act(grid_2d_mo.nx); + stream->set_grid(grid_2d_mo.nx, grid_2d_mo.ny); + stream->exec_2d(cgpu_detail::intrpl_rg_2d, TVctr>, grid_2d, mx_i, Rx_i, Ry_i, grid_2d_mo, bg, mx_o); + + return bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& Rx_i, TVctr& Ry_i, TVctr& mx_o) + { + // calculate background + T bg = get_bg(mx_i); + + auto d_grid_blk = grid_2d_mo.d_grid_blk(); + gpu_detail::intrpl_rg_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, Rx_i, Ry_i, grid_2d_mo, bg, mx_o); + + return bg; + } + #endif + + protected: + Grid_2d grid_2d; + Grid_2d grid_2d_mo; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + template + class Rs_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Rs_2d(): stream(nullptr) {} + + Rs_2d(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, T sxy, TVctr& mx_o) + { + if (fcn_is_equal(sxy, T(1))) + { + mx_o = mx_i; + } + + dt_int32 nx_o = fcn_sc_size_c(grid_2d.nx, sxy); + dt_int32 ny_o = fcn_sc_size_c(grid_2d.ny, sxy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::sc_2d, TVctr>, grid_2d, mx_i, sxy, grid_2d_o, mx_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, T sxy, TVctr& mx_o) + { + if (fcn_is_equal(sxy, T(1))) + { + mx_o = mx_i; + } + + dt_int32 nx_o = max(dt_int32(::floor(grid_2d.nx*sxy)), 1); + dt_int32 ny_o = max(dt_int32(::floor(grid_2d.ny*sxy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + auto d_grid_blk = grid_2d_o.d_grid_blk(); + gpu_detail::sc_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, sxy, grid_2d_o, mx_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Rot_Sca_sft_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Rot_Sca_sft_2d():stream(nullptr) {} + + Rot_Sca_sft_2d(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, T theta, R_2d p0, T sx, T sy, R_2d ps, TVctr& mx_o) + { + // calculate background + T bg = fcn_mean(*stream, mx_i); + + dt_int32 nx_o = fcn_sc_size_c(grid_2d.nx, sx); + dt_int32 ny_o = fcn_sc_size_c(grid_2d.ny, sy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::rot_sca_sft_2d, TVctr>, grid_2d, mx_i, theta, p0, sx, sy, ps, bg, grid_2d_o, mx_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, T theta, R_2d p0, T sx, T sy, R_2d ps, TVctr& mx_o) + { + // calculate background + T bg = fcn_mean(*stream, mx_i); + + dt_int32 nx_o = max(dt_int32(::floor(grid_2d.nx*sx)), 1); + dt_int32 ny_o = max(dt_int32(::floor(grid_2d.ny*sy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.drx, ny_o*grid_2d.dry); + + auto d_grid_blk = grid_2d_o.d_grid_blk(); + gpu_detail::rot_sca_sft_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, theta, p0, sx, sy, ps, bg, grid_2d_o, mx_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + /************************************ Gradient ******************************************/ + template + class Gradient + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Gradient(): stream(nullptr) {} + + Gradient(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, TVctr& dM_x, TVctr& dM_y) + { + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::gradient, TVctr>, grid_2d, mx_i, dM_x, dM_y); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, TVctr& dM_x, TVctr& dM_y) + { + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::gradient, typename TVctr::value_type><<>>(grid_2d, mx_i, dM_x, dM_y); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + /***************************** 2d affine transformation *********************************/ + template + class AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + AT_2d(): stream(nullptr) {} + + AT_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + grid_2d = grid_2d_i; + bg_opt = bg_opt_i; + bg = bg_i; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(TVctr& mx_i, Mx_2x2 A, R_2d txy, TVctr& mx_o) + { + if (fcn_is_zero(txy) && is_I2x2(A)) + { + mx_o = mx_i; + } + + // calculate background + T bg = get_bg(mx_i); + + A = inv(A); + txy = T(-1)*A*txy; + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::at_2d, TVctr>, grid_2d, mx_i, A, txy, bg, mx_o); + + return bg; + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, Mx_2x2 A, R_2d txy, TVctr& mx_o) + { + if (fcn_is_zero(txy) && is_I2x2(A)) + { + mx_o = mx_i; + } + + // calculate background + T bg = get_bg(mx_i); + + A = inv(A); + txy = T(-1)*A*txy; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::at_2d, typename TVctr::value_type><<>>(grid_2d, mx_i, A, txy, bg, mx_o); + + return bg; + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + eFil_Sel_Typ bg_opt; + T bg; + + T get_bg(TVctr& M) + { + T bg_r = 0; + switch (bg_opt) + { + case efst_min: + bg_r = fcn_min_element(M); + break; + case efst_max: + bg_r = fcn_max_element(M); + break; + case efst_mean: + bg_r = fcn_mean(M); + break; + case efst_min_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_min_element(M)); + break; + case efst_max_mean: + bg_r = 0.5*(fcn_mean(M) + fcn_max_element(M)); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + }; + + /************************************ translation **************************************/ + template + class Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_2d(): AT_2d() {} + + Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = 1.0; + A(2, 1) = 0; + A(1, 2) = 0; + A(2, 2) = 1.0; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + + }; + + /***************************************************************************************/ + template + class Rot_Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Rot_Tr_2d(): AT_2d() {} + + Rot_Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T theta, R_2d pr, R_2d txy, TVctr& mx_o) + { + auto A = fcn_rot_mx_2d(theta); + txy = pr - A*(pr-txy); + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + template + class Tr_Rot_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_Rot_2d(): AT_2d() {} + + Tr_Rot_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T theta, R_2d pr, R_2d txy, TVctr& mx_o) + { + auto A = fcn_rot_mx_2d(theta); + txy = pr - A*pr + txy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + /************************************** scy_shx_tr *************************************/ + template + class Scy_Shx_Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Scy_Shx_Tr_2d(): AT_2d() {} + + Scy_Shx_Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T shx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = 1; + A(2, 1) = 0; + A(1, 2) = shx; + A(2, 2) = scy; + + txy = A*txy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + template + class Tr_Scy_Shx_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_Scy_Shx_2d(): AT_2d() {} + + Tr_Scy_Shx_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T shx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = 1; + A(2, 1) = 0; + A(1, 2) = shx; + A(2, 2) = scy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + /************************************ scy_scx_tr ***************************************/ + template + class Scy_Scx_Tr_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Scy_Scx_Tr_2d(): AT_2d() {} + + Scy_Scx_Tr_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T scx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = scx; + A(2, 1) = 0; + A(1, 2) = 0; + A(2, 2) = scy; + + txy = A*txy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + template + class Tr_Scy_Scx_2d: public AT_2d + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Tr_Scy_Scx_2d(): AT_2d() {} + + Tr_Scy_Scx_2d(Stream *stream_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + this->set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + } + + T operator()(TVctr& mx_i, T scy, T scx, R_2d txy, TVctr& mx_o) + { + Mx_2x2 A; + A(1, 1) = scx; + A(2, 1) = 0; + A(1, 2) = 0; + A(2, 2) = scy; + + T bg = AT_2d::operator()(mx_i, A, txy, mx_o); + + return bg; + } + }; + + /************************************* shift *******************************************/ + template + class Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Sft_1d():fft_1d(nullptr) {} + + Sft_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx); + } + + void operator()(T xs, TVctr_c& Im) + { + fcn_fftsft_1d(grid_1d, Im); + fft_1d->forward(Im); + fcn_exp_g_factor_1d(grid_1d, -c_2pi*xs, Im, Im); + fft_1d->inverse(Im); + fcn_fftsft_1d(grid_1d, Im); + } + + void operator()(T xs, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + T Im_min = fcn_min_element(Im); + + this->operator()(xs, Im_c); + fcn_assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_1d->cleanup(); + } + + protected: + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Sft_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T alpha, TVctr_r ys, TVctr_c& Im) + { + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + fcn_exp_g_factor_2d_bc(*stream, grid_2d, -c_2pi*alpha, ys, Im, Im); + fft_2d->inverse(Im); + fcn_fftsft_bc_2d(*stream, grid_2d, Im); + } + + void operator()(T alpha, TVctr_r ys, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + T Im_min = fcn_min_element(Im); + + this->operator()(alpha, ys, Im_c); + fcn_assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Sft_2d():stream(nullptr), fft_2d(nullptr) {} + + Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(R_2d p, TVctr_c& Im) + { + fcn_fftsft_2d(*stream, grid_2d, Im); + fft_2d->forward(Im); + fcn_exp_g_factor_2d(*stream, grid_2d, T(-c_2pi)*p, Im, Im); + fft_2d->inverse(Im); + fcn_fftsft_2d(*stream, grid_2d, Im); + } + + void operator()(R_2d p, TVctr_r &Im) + { + TVctr_c Im_c(Im.begin(), Im.end()); + T Im_min = fcn_min_element(Im); + + this->operator()(p, Im_c); + fcn_assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /******************************** phase correlation ************************************/ + template + class Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Pcf_1d(): fft_1d(nullptr) {} + + Pcf_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + + PN_Fact pn; + + dt_int32 nx = pn(2*grid_1d.nx-1, edst_greater_than); + + grid_1d_e.set_in_data(nx, grid_1d.drx*nx); + + M_r_c.resize(grid_1d_e.nx); + M_s_c.resize(grid_1d_e.nx); + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + fft_1d_e.create_plan_1d(grid_1d_e.nx, 1); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_1d bd, dt_bool b_pv, TVctr_r& mx_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVctr_c& pcf = M_s_c; + + // shift matrix + fcn_fftsft_1d(grid_1d_e, M_r_c); + fcn_fftsft_1d(grid_1d_e, M_s_c); + + // fft_1d_e + fft_1d_e.forward(M_r_c); + fft_1d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + + fft_1d_e.inverse(pcf); + + // shift pcf + fcn_fftsft_1d(grid_1d_e, pcf); + + dt_int32 ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + this->fcn_assign_real(pcf, ix_s, mx_o, b_pv); + } + + void cleanup() + { + fft_1d->destroy_plan(); + fft_1d_e.cleanup(); + } + + protected: + + void fcn_assign_real(TVctr_c& mx_i, dt_int32 ix_s, TVctr_r& mx_o, dt_bool b_pos = false) + { + auto first = mx_i.begin() + ix_s; + auto last = first + grid_1d.nx; + + if (b_pos) + { + thrust::transform(first, last, mx_o.begin(), cgpu_fctr::assign_max_real(0)); + } + else + { + thrust::transform(first, last, mx_o.begin(), cgpu_fctr::assign_real()); + } + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Wd_Butwth_1d bw_1d(bd, bd.radius_p(p), 32); + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + cgpu_detail::fcn_rs_pcf_1d_dp(ix, ix_s, grid_1d, bw_1d, mx_i, mx_o); + } + } + + template + enable_if_edev_cpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_1d gs_1d(0, sigma_g); + + for(auto ix = 0; ix < grid_1d_e.nx; ix++) + { + cgpu_detail::fcn_fs_pcf_1d_dp(ix, grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + } + + /*************************************** device ****************************************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Wd_Butwth_1d bw_1d(bd, bd.radius_p(p), 32); + + auto d_grid_blk = grid_1d.d_grid_blk(); + gpu_detail::fcn_rs_pcf_1d_dp, typename TVctr_c::value_type><<>>(ix_s, grid_1d, bw_1d, mx_i, mx_o); + } + + template + enable_if_edev_gpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_1d gs_1d(0, sigma_g); + + auto d_grid_blk = grid_1d_e.d_grid_blk(); + gpu_detail::fcn_fs_pcf_1d_dp, typename TVctr_c::value_type><<>>(grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + #endif + + TVctr_c M_r_c; + TVctr_c M_s_c; + + FFT *fft_1d; + Grid_1d grid_1d; + + private: + FFT fft_1d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Pcf_2d_BC():stream(nullptr), fft_2d(nullptr) {} + + Pcf_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + grid_1d.set_in_data(grid_2d.ny, grid_2d.bs_y); + + PN_Fact pn; + + dt_int32 ny = pn(2*grid_2d.ny-1, edst_greater_than); + + grid_2d_e.set_in_data(grid_2d.nx, ny, grid_2d.bs_x, grid_2d.dry*ny); + grid_1d_e.set_in_data(grid_2d_e.ny, grid_2d_e.bs_y); + + M_r_c.resize(grid_2d_e.size()); + M_s_c.resize(grid_2d_e.size()); + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d_e.create_plan_1d_batch(grid_2d_e.ny, grid_2d_e.nx, stream->size()); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_1d bd, dt_bool b_pv, TVctr_r& mx_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVctr_c& pcf = M_s_c; + + // shift matrix + fcn_fftsft_bc_2d(*stream, grid_2d_e, M_r_c); + fcn_fftsft_bc_2d(*stream, grid_2d_e, M_s_c); + + // fft_2d + fft_2d_e.forward(M_r_c); + fft_2d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + fft_2d_e.inverse(pcf); + + // shift pcf + fcn_fftsft_bc_2d(*stream, grid_2d_e, pcf); + + dt_int32 iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + this->fcn_assign_real(pcf, iy_s, mx_o, b_pv); + } + + void cleanup() + { + fft_2d->destroy_plan(); + fft_2d_e.cleanup(); + } + + protected: + + TVctr_r gauss_vector_1d(Grid_1d& grid_1d, T sigma_g, dt_bool b_norm = false) + { + Wd_Gauss_1d gs_1d(0, sigma_g); + + TVctr_r fg; + fg.reserve(grid_1d.nx); + + for(auto ix = 0; ix < grid_1d.nx; ix++) + { + T g2 = grid_1d.g2_sft(ix); + T v = gs_1d(g2); + fg.push_back(v); + } + return fg; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh = fcn_wd_butwth_1d(grid_1d, bd.radius_p(p), 32, false, bd); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::pcf_2d_bc_pp, TVctr_r, TVctr_c>, iy_s, grid_2d, grid_2d_e, mx_i, fh, mx_o); + } + + template + enable_if_edev_cpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + auto fg = gauss_vector_1d(grid_1d_e, sigma_g); + + stream->set_n_stream_act(grid_2d_e.nx); + stream->set_grid(grid_2d_e.nx, grid_2d_e.ny); + stream->exec_2d(cgpu_detail::pcf_2d_bc_gaussian, TVctr_r, TVctr_c>, grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_edev_cpu + fcn_assign_real(TVctr_c& mx_i, dt_int32 iy_s, TVctr_r& mx_o, dt_bool b_pos = false) + { + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + dt_int32 ixy_i = grid_2d_e.sub_2_ind(ix, iy+iy_s); + dt_int32 ixy_o = grid_2d.sub_2_ind(ix, iy); + auto v = mx_i[ixy_i].real(); + mx_o[ixy_o] = (!b_pos || (v>0))?v:0; + } + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_1d& bd, TVctr_c& mx_o) + { + dt_int32 iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh_h = fcn_wd_butwth_1d>(grid_1d, bd.radius_p(p), 32, false, bd); + TVctr_r fh = fh_h; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::pcf_2d_bc_pp, typename TVctr_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, mx_i, fh, mx_o); + } + + template + enable_if_edev_gpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + auto fg_h = gauss_vector_1d(grid_1d_e, sigma_g); + TVctr_r fg = fg_h; + + auto d_grid_blk = grid_2d_e.d_grid_blk(); + gpu_detail::pcf_2d_bc_gaussian, typename TVctr_c::value_type><<>>(grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_edev_gpu + fcn_assign_real(TVctr_c& mx_i, dt_int32 iy_s, TVctr_r& mx_o, dt_bool b_pos = false) + { + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::pcf_2d_bc_assign_real, typename TVctr_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, mx_i, mx_o, b_pos); + } + #endif + + Vctr M_r_c; + Vctr M_s_c; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + Grid_1d grid_1d; + + private: + FFT fft_2d_e; + Grid_2d grid_2d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + static const eDev device = Dev; + + Pcf_2d():stream(nullptr), fft_2d(nullptr) {} + + Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + + af_tr.set_in_data(stream_i, grid_2d_i, bg_opt_i, bg_i); + + M_r_c.resize(grid_2d.size()); + M_s_c.resize(grid_2d.size()); + pcf_r.resize(grid_2d.size()); + + Fit_Ellipt_Gauss_2d.init_variables(grid_2d, 1.0); + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_2d bd, TVctr_r &pcf_o) + { + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + // shift matrix + fcn_fftsft_2d(*stream, grid_2d, M_r_c); + fcn_fftsft_2d(*stream, grid_2d, M_s_c); + + // fft_2d + fft_2d->forward(M_r_c); + fft_2d->forward(M_s_c); + + TVctr_c& pcf_c = M_s_c; + pcf_g(M_r_c, M_s_c, sigma_g, pcf_c); + fft_2d->inverse(pcf_c); + + // shift pcf + fcn_fftsft_2d(*stream, grid_2d, pcf_c); + + fcn_assign_real(pcf_c, pcf_o); + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, Region _Rect_2d bd, TVctr_r &pcf_o) + { + auto &M_s_t = pcf_r; + af_tr(M_s, A, txy, M_s_t); + this->operator()(M_r, M_s_t, p, sigma_g, bd, pcf_o); + } + + T chi_2(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Region _Rect_2d bd) + { + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + // shift matrix + fcn_fftsft_2d(*stream, grid_2d, M_r_c); + fcn_fftsft_2d(*stream, grid_2d, M_s_c); + + // fft_2d + fft_2d->forward(M_r_c); + fft_2d->forward(M_s_c); + + TVctr_c& pcf_c = M_s_c; + pcf_g(M_r_c, M_s_c, sigma_g, pcf_c); + fft_2d->inverse(pcf_c); + + return mt::fcn_mean_abs_real(pcf_c); + } + + T chi_2(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, Region _Rect_2d bd) + { + auto &M_s_t = pcf_r; + af_tr(M_s, A, txy, M_s_t); + return this->chi_2(M_r, M_s_t, p, sigma_g, bd); + } + + T chi_2(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, Vctr& coef) + { + // pcf + this->operator()(M_r, M_s, A, txy, p, sigma_g, bd, this->pcf_r); + + // get coefficients + coef = fit_coef(this->pcf_r, txy, sigma_g, radius); + + return mt::fcn_mean_abs(this->pcf_r); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + + Vctr fit_coef(TVctr_r &pcf_r, R_2d txy, T sigma_g, T radius) + { + // get maximum position + R_2d r_c = Fit_Ellipt_Gauss_2d.fd_max_peak_pos(pcf_r); + + // fitting + T sigma_r = 1.0/(c_2pi*sigma_g); + auto coef = Fit_Ellipt_Gauss_2d.fit(pcf_r, r_c, sigma_r, radius); + coef[0] = txy.x + this->grid_2d.bs_x_h(); + coef[1] = txy.y + this->grid_2d.bs_y_h(); + + return coef; + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_2d& bd, TVctr_c& mx_o) + { + Wd_Butwth_2d bw_2d(bd, bd.radius_p(p), 16); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_rs_pcf_2d_dp, TVctr_r, TVctr_c>, grid_2d, bw_2d, mx_i, mx_o); + } + + template + enable_if_edev_cpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_2d gs_2d(R_2d(), sigma_g); + + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_fs_pcf_2d_dp, TVctr_c>, grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + preprocessing(TVctr_r& mx_i, T p, Region _Rect_2d& bd, TVctr_c& mx_o) + { + Wd_Butwth_2d bw_2d(bd, bd.radius_p(p), 16); + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_rs_pcf_2d_dp, typename TVctr_c::value_type><<>>(grid_2d, bw_2d, mx_i, mx_o); + } + + template + enable_if_edev_gpu + pcf_g(TVctr_c& M_r_c, TVctr_c& M_s_c, T sigma_g, TVctr_c& pcf) + { + Wd_Gauss_2d gs_2d(R_2d(), sigma_g); + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_fs_pcf_2d_dp, typename TVctr_c::value_type><<< d_grid_blk.grid, d_grid_blk.blk >>>(grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + #endif + + Fit_Ellipt_Gauss_2d Fit_Ellipt_Gauss_2d; + + TVctr_c M_r_c; + TVctr_c M_s_c; + TVctr_r pcf_r; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + + AT_2d af_tr; + }; + + /*********************************** find shift ****************************************/ + template + class Fd_Sft_1d: public Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Sft_1d(): Pcf_1d() {} + + Fd_Sft_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i): Pcf_1d() + { + set_in_data(fft_1d_i, grid_1d_i); + } + + inline + void set_in_data(FFT *fft_1d_i, Grid_1d& grid_1d_i) + { + Pcf_1d::set_in_data(fft_1d_i, grid_1d_i); + sft_1d.set_in_data(fft_1d_i, grid_1d_i); + } + + T operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, T dx, + Region _Rect_1d bd, dt_int32 nit_pcf) + { + T sigma_r = 1.0/(c_2pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.drx, 0.9*sigma_r); + + TVctr_r M = M_s; + TVctr_r pcf(M.size()); + + if (fcn_is_nzero(dx)) + { + sft_1d(dx, M); + } + + for(auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); + + // get maximum position + T x_c = cgpu_detail::fd_max_peak_pos(this->grid_1d, pcf); + + if (it==nit_pcf-1) + { + x_c = fit_max_pos_1d(this->grid_1d, pcf, x_c, sigma_r, radius); + } + + T dx_t = -(x_c - this->grid_1d.bs_x_h()); + + if (it sft_1d; + }; + + template + class Fd_Sft_2d_BC: public Pcf_2d_BC + { + public: + using TB = std::pair; + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using TVctr_rh = Vctr; + using TVctr_ch = Vctr; + + Fd_Sft_2d_BC(): Pcf_2d_BC() {} + + Fd_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): Pcf_2d_BC() + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + Pcf_2d_BC::set_in_data(stream_i, fft_2d_i, grid_2d_i); + gauss_cv_2d_bc.set_in_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d_bc.set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + TVctr_rh operator()(TVctr_r &M_r_i, TVctr_r &M_s_i, T p, T sigma_g, TVctr_rh dx, + Region _Rect_2d bd_2d, dt_int32 nit_pcf) + { + T sigma_r = 1.0/(c_2pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.drx, 0.9*sigma_r); + Region _Rect_1d bd_1d(bd_2d.bs_y, bd_2d.yb_0, bd_2d.yb_e); + Peaks peaks(this->grid_1d, &bd_1d); + + TVctr_r M_r = M_r_i; + TVctr_r M_s = M_s_i; + TVctr_r pcf(M_r.size()); + + // Gaussian filter + gauss_cv_2d_bc(sigma_r, M_r); + gauss_cv_2d_bc(sigma_r, M_s); + + const dt_int32 ix_0 = this->grid_2d.rx_2_irx_cds(bd_2d.x_0()); + const dt_int32 ix_e = this->grid_2d.rx_2_irx_fds(bd_2d.x_e()); + + dt_bool dx_s = false; + for(auto ix = 0; ixgrid_1d.nx, T(0)); + + for(auto it=0; it::operator()(M_r, M_s, p, sigma_g, bd_1d, false, pcf); + + // get maximum distance + T d_max = (it==0)?peaks.get_d_max_0(ix_0, ix_e, pcf):peaks.get_d_max(ix_0, ix_e, dx_t); + d_max = ::fmax(sigma_r, d_max); + + for(auto ix=ix_0; ixgrid_1d.nx, pcf.begin()+(ix+1)*this->grid_1d.nx); + + auto py = peaks.find(ix, M_r, M_s, y, d_max); + if (it==nit_pcf-1) + { + py = fit_max_pos_1d(this->grid_1d, y, py, sigma_r, radius); + } + dx_t[ix] = -(py - this->grid_1d.bs_x_h()); + dx[ix] += dx_t[ix]; + } + + // shift by column + if (it gauss_cv_2d_bc; + Sft_2d_BC sft_2d_bc; + + private: + struct Peaks + { + public: + using TVctr_ih = Vctr; + + Peaks(): y_c(0), bd_1d(nullptr) {} + + Peaks(Grid_1d& grid_1d_i, Region _Rect_1d *bd_1d_i) + { + set_in_data(grid_1d_i, bd_1d_i); + } + + inline + void set_in_data(Grid_1d& grid_1d_i, Region _Rect_1d *bd_1d_i) + { + grid_1d = grid_1d_i; + bd_1d = bd_1d_i; + fft_1d.create_plan_1d(grid_1d.nx, 1); + sft_1d.set_in_data(&fft_1d, grid_1d); + + ix_pk.resize(grid_1d.nx); + x_pk.resize(grid_1d.nx); + y_pk.resize(grid_1d.nx); + } + + T get_d_max_0(dt_int32 ix_0, dt_int32 ix_e, TVctr_r &pcf) + { + T x_c = grid_1d.bs_x_h(); + TVctr_rh dx; + dx.reserve(grid_1d.nx); + + for(auto ix=ix_0; ixdx_max); }); + dx.resize(std::distance(dx.begin(), it)); + + T dx_std = ::sqrt(fcn_variance(dx)); + T d_max = fcn_max_element(dx) + 2*dx_std; + + return ::fmax(10*grid_1d.drx, d_max); + } + + T get_d_max(dt_int32 ix_0, dt_int32 ix_e, TVctr_rh &dx) + { + TVctr_rh dx_h(dx.begin()+ix_0, dx.begin()+ix_e); + return ::fmax(10*grid_1d.drx, 3*::sqrt(fcn_variance(dx_h))); + } + + T find(dt_int32 icol, TVctr_r &M_r, TVctr_r &M_s, TVctr_rh &y, T d_max) + { + const T x_c = grid_1d.bs_x_h(); + y_c = y[grid_1d.nx_h]; + + // find peaks + fd_peaks(y); + + // remove peaks + remove_peaks(x_c-d_max, x_c+d_max); + + // return if x_pk is empty + if (empty()) + { + return x_c; + } + + // return if there is only one element + if (size() == 1) + { + return x_pk.front(); + } + + const dt_int32 ix_max = idx_y_max(); + const dt_int32 ix_clt = idx_x_clt(); + + // return if closest position is equal to maximum intensity position + // and the maximum intensity is greater than the second maximum intensity + if (fabs(x_pk[ix_max]-x_pk[ix_clt])<1) + { + T y_thr = 0.61*y_pk[ix_max]; + for(auto ix = 0; ix grid_1d; + Region _Rect_1d *bd_1d; + + FFT fft_1d; + Sft_1d sft_1d; + + T y_c; + + dt_bool empty() const + { + return ix_pk.empty(); + } + + dt_int32 size() const + { + return ix_pk.size(); + } + + dt_int32 idx_y_max() const + { + dt_int32 idx_max = (std::max_element(y_pk.begin(), y_pk.end())-y_pk.begin()); + + return idx_max; + } + + dt_int32 idx_x_clt() const + { + T x_c = grid_1d.bs_x_h(); + + dt_int32 idx_clt = 0; + if (x_pk.size()>1) + { + idx_clt = std::min_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)1) + { + idx_clt = std::max_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)y_thr) + { + if ((y[ix-1] bd_l = *bd_1d; + bd_l.xb_0 = max(bd_l.xb_0, d_fht); + bd_l.xb_e = max(bd_l.xb_e, d_fht); + + // get indexes + const dt_int32 ix_0 = grid_1d.rx_2_irx_cds(bd_l.x_0()); + const dt_int32 ix_e = grid_1d.rx_2_irx_fds(bd_l.x_e()); + + // get reference data + TVctr_rh yr_b(M_r.begin()+(icol-1)*grid_1d.nx, M_r.begin()+icol*grid_1d.nx); + TVctr_rh yr(M_r.begin()+icol*grid_1d.nx, M_r.begin()+(icol+1)*grid_1d.nx); + TVctr_rh yr_n(M_r.begin()+(icol+1)*grid_1d.nx, M_r.begin()+(icol+2)*grid_1d.nx); + + // get shifted data + TVctr_rh ys_0(M_s.begin()+icol*grid_1d.nx, M_s.begin()+(icol+1)*grid_1d.nx); + + TVctr_rh chi2_pk(size()); + + for(auto ix_pk=0; ix_pk + class Fd_Sft_2d: public Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Sft_2d(): Pcf_2d() {} + + Fd_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): Pcf_2d() + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + Pcf_2d::set_in_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d.set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + R_2d operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, R_2d dr, + Region _Rect_2d bd, dt_int32 nit_pcf) + { + T sigma_r = 1.0/(c_2pi*sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 0.9*sigma_r); + + TVctr_r M = M_s; + TVctr_r pcf(M.size()); + + if (fcn_is_nzero(dr)) + { + sft_2d(dr, M); + } + + for(auto it=0; it::operator()(M_r, M, p, sigma_g, bd, pcf); + + // get maximum position + R_2d r_c = this->Fit_Ellipt_Gauss_2d.fd_max_peak_pos(pcf); + + if (it==nit_pcf-1) + { + r_c = this->Fit_Ellipt_Gauss_2d.fit_peak_pos(pcf, r_c, sigma_r, radius); + } + + R_2d dr_t = -(r_c - this->grid_2d.bs_h()); + + if (it sft_2d; + }; + + template + class Fd_Tr_2d: public Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Tr_2d(): Pcf_2d(), b_fit(true) {} + + Fd_Tr_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, + eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0, dt_bool b_fit_i = true): + Pcf_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i), b_fit(b_fit_i) {} + + R_2d operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius_f, Region _Rect_2d bd, dt_int32 nit_pcf) + { + T sigma_r = fcn_sigma_r_2_sigma_g(sigma_g); + radius_f = fcn_set_bound(radius_f, 3*this->grid_2d.dR_min(), sigma_r); + + for(auto it=0; it::operator()(M_r, M_s, A, txy, p, sigma_g, bd, this->pcf_r); + + // get maximum position + R_2d r_c = this->Fit_Ellipt_Gauss_2d.fd_max_peak_pos(this->pcf_r); + + if ((it==nit_pcf-1) & b_fit) + { + r_c = this->Fit_Ellipt_Gauss_2d.fit_peak_pos(this->pcf_r, r_c, sigma_r, radius_f); + } + + txy += -(r_c - this->grid_2d.bs_h()); + } + + return txy; + } + protected: + dt_bool b_fit; + }; + + /******************************** Corrrect shift ***************************************/ + template + class Crt_Sft_1d: public Fd_Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Crt_Sft_1d(): Fd_Sft_1d() {} + + Crt_Sft_1d(FFT *fft_1d_i, Grid_1d& grid_1d_i): + Fd_Sft_1d(fft_1d_i, grid_1d_i) {} + + T operator()(TVctr_r &M_r_i, TVctr_r &M_s_io, T p, T sigma_g, + Region _Rect_1d bd, dt_int32 nit_pcf) + { + T dx = 0; + dx = Fd_Sft_1d::operator()(M_r_i, M_s_io, p, sigma_g, dx, bd, nit_pcf); + this->sft_1d(dx, M_s_io); + + return dx; + } + }; + + template + class Crt_Sft_2d_BC: public Fd_Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using TVctr_rh = Vctr; + using TVctr_ch = Vctr; + + Crt_Sft_2d_BC(): Fd_Sft_2d_BC() {} + + Crt_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): + Fd_Sft_2d_BC(stream_i, fft_2d_i, grid_2d_i) {} + + TVctr_rh operator()(TVctr_r &M_r_i, TVctr_r &M_s_io, T p, T sigma_g, + Region _Rect_2d bd, dt_int32 nit_pcf) + { + TVctr_rh dr(this->grid_2d.ny, T(0)); + dr = Fd_Sft_2d_BC::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d_bc(1, dr, M_s_io); + + return dr; + } + }; + + template + class Crt_Sft_2d: public Fd_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Crt_Sft_2d(): Fd_Sft_2d() {} + + Crt_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): + Fd_Sft_2d(stream_i, fft_2d_i, grid_2d_i) {} + + R_2d operator()(TVctr_r &M_r_i, TVctr_r &M_s_io, T p, T sigma_g, + Region _Rect_2d bd, dt_int32 nit_pcf) + { + R_2d dr(0, 0); + dr = Fd_Sft_2d::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d(dr, M_s_io); + + return dr; + } + }; + + template + class Crt_Tr_2d: public Fd_Tr_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Crt_Tr_2d(): Fd_Tr_2d() {} + + Crt_Tr_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, + eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0, dt_bool b_fit_i = true): + Fd_Tr_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i, b_fit_i) {} + + R_2d operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_pcf, TVctr_r& mx_o) + { + txy = Fd_Tr_2d::operator()(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + this->af_tr(M_s, A, txy, mx_o); + + return txy; + } + }; + + /*********************************** calculate Chi^2 ***********************************/ + template + class Scy_Shx + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Scy_Shx():stream(nullptr) {} + + Scy_Shx(Stream *stream_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + template + enable_if_edev_cpu + operator()(TVctr& mx_i, R_2d af, TVctr& mx_o) + { + if (fcn_is_zero(af.x) && fcn_is_equal(af.y, T(1))) + { + mx_o = mx_i; + } + + TVctr M_o_t; + TVctr *pM_o = &mx_o; + + if (mx_i.data() == mx_o.data()) + { + M_o_t.resize(mx_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = fcn_mean(*stream, mx_i); + + Grid_2d grid_2d_o = grid_2d; + + stream->set_n_stream_act(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_2d(cgpu_detail::shx_scy, TVctr>, grid_2d, mx_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (mx_i.data() == mx_o.data()) + { + mx_o.assign(pM_o->begin(), pM_o->end()); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(TVctr& mx_i, R_2d af, TVctr& mx_o) + { + if (fcn_is_zero(af.x) && fcn_is_equal(af.y, T(1))) + { + mx_o = mx_i; + } + + TVctr M_o_t; + TVctr *pM_o = &mx_o; + + if (mx_i.data() == mx_o.data()) + { + M_o_t.resize(mx_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = fcn_mean(*stream, mx_i); + + Grid_2d grid_2d_o = grid_2d; + + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::shx_scy, typename TVctr::value_type><<>>(grid_2d, mx_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (mx_i.data() == mx_o.data()) + { + mx_o.assign(pM_o->begin(), pM_o->end()); + } + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Chi2_Pcf_Sft_Scy_Shx_2d: public Crt_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Chi2_Pcf_Sft_Scy_Shx_2d(): Crt_Sft_2d() {} + + Chi2_Pcf_Sft_Scy_Shx_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): Crt_Sft_2d() + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + Crt_Sft_2d::set_in_data(stream_i, fft_2d_i, grid_2d_i); + shx_scy.set_in_data(this->stream, this->grid_2d); + } + + T operator()(TVctr_r &M_r_i, TVctr_r &M_s_i, T p, T sigma_g, + R_2d af, Region _Rect_2d bd, dt_int32 nit_pcf, R_2d& ds) + { + TVctr_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVctr_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, pcf); + + // cost function + return fcn_mean(*(this->stream), pcf); + } + + T operator()(TVctr_r &M_r_i, TVctr_r &M_s_i, T p, T sigma_g, + R_2d af, Region _Rect_2d bd, dt_int32 nit_pcf, R_2d& ds, Vctr& coef) + { + TVctr_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVctr_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, pcf); + + // cost function + auto chi2 = fcn_mean(*(this->stream), pcf); + + // get maximum position + R_2d r_c = this->Fit_Ellipt_Gauss_2d.fd_max_peak_pos(pcf); + + // fitting + T sigma_r = mt::fcn_sigma_r_2_sigma_g(sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 1.5*sigma_r); + coef = this->Fit_Ellipt_Gauss_2d.fit(pcf, r_c, sigma_r, radius); + coef[0] = ds.x + this->grid_2d.bs_x_h(); + coef[1] = ds.y + this->grid_2d.bs_y_h(); + + return chi2; + } + + protected: + Scy_Shx shx_scy; + }; + + template + class Chi2_Pcf_2d: public Fd_Tr_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Chi2_Pcf_2d(): Fd_Tr_2d() {} + + Chi2_Pcf_2d(Stream *stream_i, FFT *fft_2d_i, + Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0): + Fd_Tr_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i) {} + + T operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, Region _Rect_2d bd) + { + return this->chi_2(M_r, M_s, p, sigma_g, bd); + } + + T operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, Region _Rect_2d bd) + { + return this->chi_2(M_r, M_s, A, txy, p, sigma_g, bd); + } + + T operator()(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, Vctr& coef) + { + return this->chi_2(M_r, M_s, A, txy, p, sigma_g, radius, bd, coef); + } + + R_2d find_txy(TVctr_r &M_r, TVctr_r &M_s, Mx_2x2 A, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_pcf) + { + return Fd_Tr_2d::operator()(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + } + }; + + template + class Fd_Sft_Scy_Shx_2d: public Chi2_Pcf_Sft_Scy_Shx_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Sft_Scy_Shx_2d():Chi2_Pcf_Sft_Scy_Shx_2d(), nit_pcf(2) {} + + Fd_Sft_Scy_Shx_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i): + Chi2_Pcf_Sft_Scy_Shx_2d(stream_i, fft_2d_i, grid_2d_i), nit_pcf(2) {} + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Vctr, edev_cpu>& spx, Region _Rect_2d bd, dt_int32 nit_nm) + { + dt_int32 ic = 1; + + T d_pix_min = this->grid_2d.dg_min(); + T d_min = 0.05*d_pix_min; + T alpha = 1.0; + T beta = 0.5; + T gamma = 2.0; + + for(auto it=0; it ds_r(0, 0); + auto chi2_r = chi2_pcf(M_r, M_s, p, sigma_g, x_r, bd, nit_pcf, ds_r); + + if (chi2_r ds_e(0, 0); + auto chi2_e = chi2_pcf(M_r, M_s, p, sigma_g, x_e, bd, nit_pcf, ds_e); + if (chi2_e(x_e, ds_e, chi2_e); + } + else + { + spx[2] = Atp_1(x_r, ds_r, chi2_r); + } + } + else if (chi2_r(x_r, ds_r, chi2_r); + } + else if (chi2_r ds_rc(0, 0); + auto chi2_rc = chi2_pcf(M_r, M_s, p, sigma_g, x_rc, bd, nit_pcf, ds_rc); + if (chi2_rc(x_rc, ds_rc, chi2_rc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + else + { + auto x_wc = x_m + beta*(x_w-x_m); + R_2d ds_wc(0, 0); + auto chi2_wc = chi2_pcf(M_r, M_s, p, sigma_g, x_wc, bd, nit_pcf, ds_wc); + if (chi2_wc(x_wc, ds_wc, chi2_wc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + } + + } + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d& af, Region _Rect_2d bd, R_2d& tr, dt_int32 nit_nm) + { + auto spx = set_simplex(M_r, M_s, p, sigma_g, af, tr, bd, nit_nm); + this->operator()(M_r, M_s, p, sigma_g, spx, bd, nit_nm); + + af = spx[0].f; + tr = spx[0].tr; + + // // shear and scaling + // shx_scy(M_s, af, M_s); + // // correct shift + // tr = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, tr, bd, nit_pcf); + } + + protected: + R_2d x_af(const R_2d& af, const R_2d& r) + { + return R_2d(r.x+af.x*r.y, af.y*r.y); + } + + R_2d x_iaf(const R_2d& af, const R_2d& r) + { + return R_2d(r.x-af.x*r.y/af.y, r.y/af.y); + } + + Vctr, edev_cpu> set_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d x_0, R_2d ds_0, Region _Rect_2d& bd, dt_int32 nit_nm) + { + // global shift + if (fcn_is_zero(ds_0)) + { + ds_0 = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds_0, bd, nit_pcf); + // bd.fcn_repl_bdr(ds_0); + } + + TVctr_r M_s_t = M_s; + this->sft_2d(x_iaf(x_0, ds_0), M_s_t); + + // determine coefficients + Vctr coef(6); + chi2_pcf(M_r, M_s_t, p, sigma_g, x_0, bd, nit_pcf, ds_0, coef); + + // calculate dd0 + T ff = coef[4]/coef[3]; + ff = (ff<1)?1/ff:ff; + ff = ::fmax(1.05, ff); + + T dd0 = ::sqrt(1.354e-04*pow(ff-1, 2)+6.622e-4*(ff-1)); + dd0 = ::fmax(dd0, this->grid_2d.dg_min()); + + T sin_t = sin(coef[5]); + T cos_t = cos(coef[5]); + + T sigma_x = pow(cos_t/coef[3], 2)+pow(sin_t/coef[4], 2); + sigma_x = ::sqrt(1/sigma_x); + + T sigma_y = pow(sin_t/coef[3], 2)+pow(cos_t/coef[4], 2); + sigma_y = ::sqrt(1/sigma_y); + + T theta = atan2(sigma_y, sigma_x); + + R_2d u(dd0*cos(theta), dd0*sin(theta)); + R_2d v(-u.y, u.x); + + // set simplex + Vctr, edev_cpu> spx(3); + + spx[0].f = x_0; + spx[0].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[0].f, bd, nit_pcf, spx[0].tr); + + spx[1].f = x_0+u; + spx[1].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[1].f, bd, nit_pcf, spx[1].tr); + + spx[2].f = x_0+v; + spx[2].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[2].f, bd, nit_pcf, spx[2].tr); + + // sort simplex + sort(spx); + + return spx; + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d af, Region _Rect_2d& bd, dt_int32 nit_pcf, R_2d& tr) + { + return Chi2_Pcf_Sft_Scy_Shx_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, tr); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + R_2d af, Region _Rect_2d& bd, dt_int32 nit_pcf, R_2d& tr, Vctr& coef) + { + return Chi2_Pcf_Sft_Scy_Shx_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, tr, coef); + } + + void sort(Vctr, edev_cpu>& spx) + { + std::sort(spx.begin(), spx.end(), [](const Atp_1& x, const Atp_1& y){ return x.chi2, edev_cpu>& spx) + { + auto r0 = spx[0].f; + + R_2d dr = spx[1].f - r0; + T d_max = dr.norm(); + for(auto i=2; i dr = spx[i].f - r0; + d_max = ::fmax(d_max, dr.norm()); + } + return d_max; + } + + T min_length(Vctr, edev_cpu>& spx) + { + auto r0 = spx[0].f; + R_2d dr = spx[1].f - r0; + T d_min = dr.norm(); + for(auto i=2; i dr = spx[i].f - r0; + d_min = ::fmin(d_min, dr.norm()); + } + return d_min; + } + + R_2d best_centroid(Vctr, edev_cpu>& spx) + { + R_2d r_c(0, 0); + for(auto i=0; i, edev_cpu>& spx, Region _Rect_2d& bd, dt_int32 nit_pcf) + { + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.norm(); + auto mp13 = p13.norm(); + auto mp_max = ::fmax(mp12, mp13); + + T theta = angle(p12, p13); + + T theta_min = 10; + T theta_0 = theta_min*c_pi/180; + T theta_e = c_pi-theta_min*c_pi/180; + + dt_bool b_m = (mp12theta_e)||b_m) + { + if (b_m && (mp12(-u.y, u.x); + R_2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[1] = Atp_1(x_o, ds_o, chi2_o); + } + else + { + T m = max_length(spx); + auto u = p12/norm(p12); + auto x_o = spx[0].f + mp_max*R_2d(-u.y, u.x); + R_2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[2] = Atp_1(x_o, ds_o, chi2_o); + } + + sort(spx); + } + } + + void contract_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, + Vctr, edev_cpu>& spx, Region _Rect_2d& bd, dt_int32 nit_pcf) + { + T ff = 0.5; + + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.norm(); + auto mp13 = p13.norm(); + + if (mp12(-u.y, u.x); + R_2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[2] = Atp_1(x_c, ds_c, chi2_c); + } + else + { + auto u = p13/mp13; + auto x_c = spx[0].f + ff*mp12*R_2d(-u.y, u.x); + R_2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[1] = Atp_1(x_c, ds_c, chi2_c); + } + + sort(spx); + } + + dt_int32 nit_pcf; + }; + + template + class Fd_Tr_Scy_Shx_2d:public Chi2_Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Tr_Scy_Shx_2d(): Chi2_Pcf_2d(), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5) {} + + Fd_Tr_Scy_Shx_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0): + Chi2_Pcf_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5) {} + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T& scy, T& shx, R_2d& txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_nm) + { + Simplex spx = spx_0(M_r, M_s, scy, shx, txy, p, sigma_g, radius, bd); + + dt_int32 ic = 1; + + T d_pix_min = this->grid_2d.dg_min(); + T d_min = 0.05*d_pix_min; + + for(auto it = 0; it(x_r, t_r, chi2_r); + } + else + { + auto x_e = x_m + c_e*(x_r - x_m); + auto t_e = find_txy(M_r, M_s, x_e, t_b, p, sigma_g, radius, bd); + auto chi2_e = chi2_pcf(M_r, M_s, x_e, t_e, p, sigma_g, bd); + + spx[2] = (chi2_e(x_e, t_e, chi2_e):Atp_1(x_r, t_r, chi2_r); + } + } + else + { + if (chi2_r(x_r, t_r, chi2_r); + } + + auto x_c = x_m + c_c*(x_r - x_m); + auto t_c = find_txy(M_r, M_s, x_c, t_b, p, sigma_g, radius, bd); + auto chi2_c = chi2_pcf(M_r, M_s, x_c, t_c, p, sigma_g, bd); + + if (chi2_c(x_c, t_c, chi2_c); + } + else + { + shrink_simplex(M_r, M_s, p, sigma_g, radius, bd, spx); + } + } + + spx.sort(); + } + + shx = spx[0].f.x; + scy = spx[0].f.y; + txy = spx[0].tr; + } + + protected: + const dt_int32 nit_pcf; + + const T c_r; + const T c_e; + const T c_c; + const T c_s; + + struct Simplex + { + Simplex() {} + + Simplex(dt_int32 new_size) + { + resize(new_size); + } + + dt_int32 size() const + { + return m_spx.size(); + } + + void resize(dt_int32 new_size) + { + m_spx.resize(new_size); + } + + Atp_1& operator[](const dt_int32 idx) { return m_spx[idx]; } + + const Atp_1& operator[](const dt_int32 idx) const { return m_spx[idx]; } + + void sort() + { + std::sort(m_spx.begin(), m_spx.end(), [](const Atp_1& x, const Atp_1& y) { return x.chi2 < y.chi2; }); + } + + T max_length() + { + auto f0 = m_spx[0].f; + R_2d dr = m_spx[1].f - f0; + T d_max = dr.norm(); + for(auto ik = 2; ik < m_spx.size(); ik++) + { + R_2d dr = m_spx[ik].f - f0; + d_max = ::fmax(d_max, dr.norm()); + } + return d_max; + } + + T min_length() + { + auto f0 = m_spx[0].f; + R_2d dr = m_spx[1].f - f0; + T d_min = dr.norm(); + for(auto ik = 2; ik < m_spx.size(); ik++) + { + R_2d dr = m_spx[ik].f - f0; + d_min = ::fmin(d_min, dr.norm()); + } + return d_min; + } + + R_2d centroid() + { + R_2d r_c(0, 0); + dt_int32 n_spx = m_spx.size()-1; + for(auto ik = 0; ik, edev_cpu> m_spx; + }; + + R_2d find_txy(TVctr_r &M_r, TVctr_r &M_s, R_2d f, R_2d txy, T p, T sigma_g, T radius, Region _Rect_2d& bd) + { + Mx_2x2 A(1, 0, f.x, f.y); + return Chi2_Pcf_2d::find_txy(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, R_2d f, R_2d txy, T p, T sigma_g, Region _Rect_2d& bd) + { + Mx_2x2 A(1, 0, f.x, f.y); + return Chi2_Pcf_2d::operator()(M_r, M_s, A, txy, p, sigma_g, bd); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, R_2d f, R_2d txy, T p, T sigma_g, T radius, + Region _Rect_2d& bd, Vctr& coef) + { + Mx_2x2 A(1, 0, f.x, f.y); + return Chi2_Pcf_2d::operator()(M_r, M_s, A, txy, p, sigma_g, radius, bd, coef); + } + + Simplex spx_0(TVctr_r &M_r, TVctr_r &M_s, T scy, T shx, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd) + { + // global shift + Vctr coef(6); + + auto x_0 = R_2d(shx, scy); + auto t_0 = find_txy(M_r, M_s, x_0, txy, p, sigma_g, radius, bd); + auto chi2_0 = chi2_pcf(M_r, M_s, x_0, t_0, p, sigma_g, radius, bd, coef); + + // bd.fcn_repl_bdr(t_0); + + // calculate dd0 + T ff = coef[4]/coef[3]; + ff = (ff<1)?1/ff:ff; + ff = ::fmax(1.05, ff); + + T dd0 = ::sqrt(1.354e-04*pow(ff - 1, 2) + 6.622e-4*(ff - 1)); + dd0 = ::fmax(dd0, this->grid_2d.dg_min()); + + T sin_t = sin(coef[5]); + T cos_t = cos(coef[5]); + + T sigma_x = pow(cos_t/coef[3], 2) + pow(sin_t/coef[4], 2); + sigma_x = ::sqrt(1/sigma_x); + + T sigma_y = pow(sin_t/coef[3], 2) + pow(cos_t/coef[4], 2); + sigma_y = ::sqrt(1/sigma_y); + + T theta = atan2(sigma_y, sigma_x); + + R_2d u(dd0*cos(theta), dd0*sin(theta)); + R_2d v(-u.y, u.x); + + // set simplex + Simplex spx(3); + + spx[0].f = x_0; + spx[0].tr = t_0; + spx[0].chi2 = chi2_0; + + spx[1].f = x_0 + u; + spx[1].tr = find_txy(M_r, M_s, spx[1].f, t_0, p, sigma_g, radius, bd); + spx[1].chi2 = chi2_pcf(M_r, M_s, spx[1].f, spx[1].tr, p, sigma_g, bd); + + spx[2].f = x_0 + v; + spx[2].tr = find_txy(M_r, M_s, spx[2].f, t_0, p, sigma_g, radius, bd); + spx[2].chi2 = chi2_pcf(M_r, M_s, spx[2].f, spx[2].tr, p, sigma_g, bd); + + spx.sort(); + + return spx; + } + + void orthogonal_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, T radius, + Region _Rect_2d& bd, Simplex &spx) + { + auto x_b = spx[0].f; + auto t_b = spx[0].tr; + + auto p12 = spx[1].f - x_b; + auto p13 = spx[2].f - x_b; + auto mp12 = p12.norm(); + auto mp13 = p13.norm(); + auto mp_max = ::fmax(mp12, mp13); + + T theta = angle(p12, p13); + + T theta_min = 10; + T theta_0 = theta_min*c_pi/180; + T theta_e = c_pi - theta_min*c_pi/180; + + dt_bool b_m = (mp12theta_e) || b_m) + { + if (b_m && (mp12(-u.y, u.x); + auto t_o = find_txy(M_r, M_s, x_o, t_b, p, sigma_g, radius, bd); + auto chi2_o = chi2_pcf(M_r, M_s, x_o, t_o, p, sigma_g, bd); + + spx[1] = Atp_1(x_o, t_o, chi2_o); + } + else + { + auto u = normalize(p12); + auto x_o = x_b + mp_max*R_2d(-u.y, u.x); + auto t_o = find_txy(M_r, M_s, x_o, t_b, p, sigma_g, radius, bd); + auto chi2_o = chi2_pcf(M_r, M_s, x_o, t_o, p, sigma_g, bd); + + spx[2] = Atp_1(x_o, t_o, chi2_o); + } + + spx.sort(); + } + } + + void shrink_simplex(TVctr_r &M_r, TVctr_r &M_s, T p, T sigma_g, T radius, + Region _Rect_2d& bd, Simplex &spx) + { + auto x_b = spx[0].f; + auto t_b = spx[0].tr; + for(auto ik = 1; ik < spx.size(); ik++) + { + auto x_s = x_b + c_s*(spx[ik].f-x_b); + auto t_s = find_txy(M_r, M_s, x_s, t_b, p, sigma_g, radius, bd); + auto chi2_s = chi2_pcf(M_r, M_s, x_s, t_s, p, sigma_g, bd); + + spx[ik] = Atp_1(x_s, t_s, chi2_s); + } + } + }; + + template + class Fd_Tr_Rot_2d:public Chi2_Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + + Fd_Tr_Rot_2d(): Chi2_Pcf_2d(), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5), p_c(0, 0) {} + + Fd_Tr_Rot_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i, eFil_Sel_Typ bg_opt_i=efst_min, T bg_i=0): + Chi2_Pcf_2d(stream_i, fft_2d_i, grid_2d_i, bg_opt_i, bg_i), + nit_pcf(2), c_r(1.0), c_e(2.0), c_c(0.5), c_s(0.5), p_c(grid_2d_i.rx_c(), grid_2d_i.ry_c()) {} + + void operator()(TVctr_r &M_r, TVctr_r &M_s, T& theta, R_2d& txy, + T p, T sigma_g, T radius, Region _Rect_2d bd, dt_int32 nit_nm) + { + Simplex spx = spx_0(M_r, M_s, theta, txy, p, sigma_g, radius, bd); + + T d_min = 0.025*c_deg_2_rad; + + for(auto it = 0; it(x_r, t_r, chi2_r); + } + else + { + auto x_e = x_m + c_e*(x_r - x_m); + auto t_e = find_txy(M_r, M_s, x_e, t_b, p, sigma_g, radius, bd); + auto chi2_e = chi2_pcf(M_r, M_s, x_e, t_e, p, sigma_g, bd); + + spx[1] = (chi2_e(x_e, t_e, chi2_e):Atp_2(x_r, t_r, chi2_r); + } + } + else + { + if (chi2_r(x_r, t_r, chi2_r); + } + + auto x_c = x_m + c_c*(x_r - x_m); + auto t_c = find_txy(M_r, M_s, x_c, t_b, p, sigma_g, radius, bd); + auto chi2_c = chi2_pcf(M_r, M_s, x_c, t_c, p, sigma_g, bd); + + if (chi2_c(x_c, t_c, chi2_c); + } + } + + spx.sort(); + } + + theta = spx[0].theta; + txy = spx[0].tr; + } + + protected: + const dt_int32 nit_pcf; + + const T c_r; + const T c_e; + const T c_c; + const T c_s; + const R_2d p_c; + + struct Simplex + { + Simplex() {} + + Simplex(dt_int32 new_size) + { + resize(new_size); + } + + dt_int32 size() const + { + return m_spx.size(); + } + + void resize(dt_int32 new_size) + { + m_spx.resize(new_size); + } + + Atp_2& operator[](const dt_int32 idx) { return m_spx[idx]; } + + const Atp_2& operator[](const dt_int32 idx) const { return m_spx[idx]; } + + void sort() + { + std::sort(m_spx.begin(), m_spx.end(), [](const Atp_2& x, const Atp_2& y) { return x.chi2 < y.chi2; }); + } + + T max_length() + { + return ::fabs(m_spx[1].theta - m_spx[0].theta); + } + + T min_length() + { + return ::fabs(m_spx[1].theta - m_spx[0].theta); + } + + T centroid() + { + return m_spx[0].theta; + } + + private: + Vctr, edev_cpu> m_spx; + }; + + R_2d find_txy(TVctr_r &M_r, TVctr_r &M_s, T theta, R_2d txy, T p, T sigma_g, T radius, Region _Rect_2d& bd) + { + auto A = fcn_rot_mx_2d(theta); + txy = p_c - A*p_c + txy; + + return Chi2_Pcf_2d::find_txy(M_r, M_s, A, txy, p, sigma_g, radius, bd, nit_pcf); + } + + T chi2_pcf(TVctr_r &M_r, TVctr_r &M_s, T theta, R_2d txy, T p, T sigma_g, Region _Rect_2d& bd) + { + auto A = mt::fcn_rot_mx_2d(theta); + txy = p_c - A*p_c + txy; + + return Chi2_Pcf_2d::operator()(M_r, M_s, A, txy, p, sigma_g, bd); + } + + Simplex spx_0(TVctr_r &M_r, TVctr_r &M_s, T theta, R_2d txy, + T p, T sigma_g, T radius, Region _Rect_2d bd) + { + auto x_0 = theta; + auto t_0 = find_txy(M_r, M_s, x_0, txy, p, sigma_g, radius, bd); + auto chi2_0 = chi2_pcf(M_r, M_s, x_0, t_0, p, sigma_g, bd); + + // set simplex + Simplex spx(2); + + spx[0].theta = x_0; + spx[0].tr = t_0; + spx[0].chi2 = chi2_0; + + spx[1].theta = x_0 + 1.0*c_deg_2_rad; + spx[1].tr = find_txy(M_r, M_s, spx[1].theta, t_0, p, sigma_g, radius, bd); + spx[1].chi2 = chi2_pcf(M_r, M_s, spx[1].theta, spx[1].tr, p, sigma_g, bd); + spx.sort(); + + return spx; + } + }; + + /********************************* calculate d_phi *************************************/ + template + class Opt_Flow + { + public: + using T_r = T; + using TVctr = Vctr; + + static const eDev device = Dev; + + Opt_Flow(): stream(nullptr) {} + + Opt_Flow(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + set_in_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_in_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d& grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + + intrpl_rg_2d.set_in_data(stream, grid_2d, grid_2d); + + gauss_cv_2d.set_in_data(stream, fft_2d_i, grid_2d); + + v_x.resize(grid_2d.size()); + v_y.resize(grid_2d.size()); + + Rx.resize(grid_2d.size()); + Ry.resize(grid_2d.size()); + M.resize(grid_2d.size()); + + } + + void operator()(TVctr& M_s, TVctr& M_m, T alpha, T sigma, dt_int32 n_iter, TVctr& v_xt, TVctr& v_yt) + { + // create rectangular grid + set_regular_grid(Rx, Ry); + + // set initial optical flow + v_x = v_xt; + v_y = v_yt; + + for(auto iter = 0; iter < n_iter; iter++) + { + // create new grid + mt::add(*stream, v_x, Rx); + mt::add(*stream, v_y, Ry); + + // resample distored image in a new grid + intrpl_rg_2d(M_m, Rx, Ry, M); + + // calculate optical flow + fcn_opt_flow(M_s, M, alpha, v_x, v_y); + + // regularization based on convolution + if (fcn_is_nzero(sigma)) + { + gauss_cv_2d(sigma, v_x); + gauss_cv_2d(sigma, v_y); + } + + // add optical flow + mt::add(*stream, v_x, v_xt); + mt::add(*stream, v_y, v_yt); + + } + } + + void set_fft_plan() + { + gauss_cv_2d.set_fft_plan(); + } + + void cleanup() + { + gauss_cv_2d.cleanup(); + } + + protected: + + void set_regular_grid(TVctr& Rx, TVctr& Ry) + { + Vctr Rx_h; + Vctr Ry_h; + + Rx_h.reserve(grid_2d.size()); + Ry_h.reserve(grid_2d.size()); + + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + Rx_h.push_back(grid_2d.rx(ix)); + Ry_h.push_back(grid_2d.ry(iy)); + } + } + + thrust::copy(Rx_h.begin(), Rx_h.end(), Rx.begin()); + thrust::copy(Ry_h.begin(), Ry_h.end(), Ry.begin()); + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + fcn_opt_flow(TVctr& M_s, TVctr& M_m, T alpha, TVctr& v_x, TVctr& v_y) + { + stream->set_n_stream_act(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_2d(cgpu_detail::fcn_opt_flow, TVctr>, grid_2d, M_s, M_m, alpha, v_x, v_y); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + fcn_opt_flow(TVctr& M_s, TVctr& M_m, T alpha, TVctr& v_x, TVctr& v_y) + { + auto d_grid_blk = grid_2d.d_grid_blk(); + gpu_detail::fcn_opt_flow, typename TVctr::value_type><<>>(grid_2d, M_s, M_m, alpha, v_x, v_y); + } + #endif + + Stream *stream; + Grid_2d grid_2d; + + Interp_rn_2d intrpl_rg_2d; + Gauss_Cv_2d gauss_cv_2d; + + TVctr v_x; + TVctr v_y; + + TVctr Rx; + TVctr Ry; + TVctr M; + }; + + } + #endif \ No newline at end of file diff --git a/src/cgpu_detail.cuh b/src/cgpu_detail.cuh new file mode 100755 index 00000000..09d3c7d0 --- /dev/null +++ b/src/cgpu_detail.cuh @@ -0,0 +1,1526 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "kahan_sum.h" +#include "fcns_cgpu_gen.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" + +#include + +namespace mt +{ + /* functors */ + namespace cgpu_fctr + { + template + struct assign_real + { + template + CGPU_EXEC + T operator()(const U& x) const { return x.real(); } + }; + + template + struct assign_max_real + { + const T v_lim; + const T val; + assign_max_real(const T& v_lim, const T& val): v_lim(v_lim), val(val) {} + + CGPU_EXEC + T operator()(const complex& x) const + { + auto x_r = T(x.real()); + return (x_r>=v_lim)?x_r:val; + } + }; + + template + struct assign_abs_real + { + CGPU_EXEC + T operator()(const complex& x) const { return ::abs(x.real()); } + }; + + template + struct assign_abs + { + template + CGPU_EXEC + T operator()(const U& x) const { return ::abs(x); } + }; + + template + struct scale + { + const T w; + scale(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return w*x; } + }; + + template + struct norm_2 + { + template + CGPU_EXEC + T operator()(const U& x) const { return ::norm_2(x); } + }; + + template + struct scale_norm_2 + { + const T w; + scale_norm_2(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return w*::norm_2(x); } + }; + + template + struct add + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return lhs + rhs; } + }; + + template + struct sub + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return lhs - rhs; } + }; + + template + struct add_scale + { + const T w; + add_scale(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w*lhs + rhs; } + }; + + template + struct add_scale_i + { + const T w1; + const T w2; + add_scale_i(T w1, T w2): w1(w1), w2(w2) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w1*lhs + w2*rhs; } + }; + + template + struct add_norm_2 + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return ::norm_2(lhs) + rhs; } + }; + + template + struct add_norm_2_i + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return ::norm_2(lhs) + ::norm_2(rhs); } + }; + + template + struct add_scale_norm_2 + { + const T w; + add_scale_norm_2(T w): w(w) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w*::norm_2(lhs) + rhs; } + }; + + template + struct add_scale_norm_2_i + { + const T w1; + const T w2; + add_scale_norm_2_i(T w1, T w2): w1(w1), w2(w2) {} + + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return w1*::norm_2(lhs) + w2*::norm_2(rhs); } + }; + + template + struct mult + { + template + CGPU_EXEC + T operator()(const U& lhs, const V &rhs) const { return lhs*rhs; } + }; + + template + struct norm_2_sft + { + const T x_sft; + norm_2_sft(T x_sft): x_sft(x_sft) {} + + template + CGPU_EXEC + Tr operator()(const U& x) const { return ::norm_2(x-x_sft); } + }; + + template + struct abs_sft + { + const T x_sft; + abs_sft(T x_sft): x_sft(x_sft) {} + + template + CGPU_EXEC + Tr operator()(const U& x) const { return ::fabs(x-x_sft); } + }; + + template + struct div_sft + { + const T x_sft; + const T x_div; + div_sft(T x_sft, T x_div): x_sft(x_sft), x_div(x_div){} + + template + CGPU_EXEC + T operator()(const U& x) const { return (x-x_sft)/x_div; } + }; + + template + struct less + { + CGPU_EXEC + bool operator()(const T &lhs, const T &rhs) const + { + return lhs < rhs; + } + }; + + template + struct less_soa + { + template + bool operator()(const TTuple1& lhs, const TTuple2& rhs) + { + return thrust::get(lhs) < thrust::get(rhs); + } + }; + + template + struct closest_element + { + const T m_val; + + closest_element(T val): m_val(val) {} + + dt_bool operator()(const T& a, const T& b) + { + const T da = 1e-4; + return fabs(a-m_val-da) + struct binarize + { + const T thr; + binarize(T thr): thr(thr) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return (x + struct threshold_max + { + const T thr; + + threshold_max(T thr): thr(thr) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return fcn_max(thr, x); } + }; + + template + struct threshold_min + { + const T thr; + + threshold_min(T thr): thr(thr) {} + + template + CGPU_EXEC + T operator()(const U& x) const { return fcn_min(thr, x); } + }; + + template + struct anscombe_fwd + { + const T xs; + anscombe_fwd(): xs(T(3.0/8.0)) {} + + template + CGPU_EXEC + T operator()(const U& x) const + { + return fcn_max(T(0), T(2)*::sqrt(x+xs)); + } + }; + + template + struct anscombe_inv + { + const T a; + const T b; + const T c; + const T d; + const T e; + anscombe_inv(): a(T(1.0/4.0)), b(T(::sqrt(3.0/2.0)/4.0)), + c(T(-11.0/8.0)), d(T(5.0*::sqrt(3.0/2.0)/8)), e(T(-1.0/8.0)) {} + + template + CGPU_EXEC + T operator()(const U& x) const + { + if (fcn_is_zero(x)) + { + return fcn_max(T(0), a*x+e); + } + else + { + const T ix = T(1)/x; + return fcn_max(T(0), a*x*x+e+ix*(b+ix*(c+ix*d))); + } + } + }; + + template + struct rad_dist_ind_by_div + { + T r_0; + T dr; + dt_int32 ix_min; + dt_int32 ix_max; + + rad_dist_ind_by_div(T r_0, T dr, dt_int32 ix_min, dt_int32 ix_max): r_0(r_0), dr(dr), ix_min(ix_min), ix_max(ix_max) {} + + CGPU_EXEC + dt_int32 operator()(const T& r) const + { + return fcn_bcfloor((r-r_0)/dr, ix_min, ix_max); + } + }; + + template + struct rad_dist_ind_by_srch + { + T* rv; + dt_int32 ix_min; + dt_int32 ix_max; + + rad_dist_ind_by_srch(T* rv, dt_int32 ix_min, dt_int32 ix_max): rv(rv), ix_min(ix_min), ix_max(ix_max) {} + + CGPU_EXEC + dt_int32 operator()(const T& r) const + { + return fcn_r_2_ir_by_vctr(rv, r, ix_min, ix_max); + } + }; + + } // namespace fctr + + template + void synchronize_every(const dt_int32& i_sync, const dt_int32& n_sync) + { + + } + + template <> + void synchronize_every(const dt_int32& i_sync, const dt_int32& n_sync) + { + #ifdef __CUDACC__ + if (i_sync % n_sync == 0) + { + cudaDeviceSynchronize(); + } + #endif + } + + template + auto fcn_mkzipiter_begin(Args&... args) + { + return thrust::make_zip_iterator(thrust::make_tuple(std::begin(args)...)); + } + + template + auto fcn_mkzipiter_end(Args&... args) + { + return thrust::make_zip_iterator(thrust::make_tuple(std::end(args)...)); + } + + /* unrolled binary search */ + namespace cgpu_detail + { + template + CGPU_EXEC_INL + dt_int32 fcn_unrolled_binary_search_256(const T& x, Ctpr xv) + { + dt_int32 i_0 = 0; + dt_int32 i_e = 255; + + dt_int32 im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 128 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 64 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 32 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 16 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 8 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 4 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 2 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 1 + + return i_0; + } + + template + CGPU_EXEC_INL + dt_int32 fcn_unrolled_binary_search_128(const T& x, Ctpr xv) + { + dt_int32 i_0 = 0; + dt_int32 i_e = 127; + + dt_int32 im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 64 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 32 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 16 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 8 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 4 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 2 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 1 + + return i_0; + } + + template + CGPU_EXEC_INL + dt_int32 fcn_unrolled_binary_search_64(const T& x, Ctpr xv) + { + dt_int32 i_0 = 0; + dt_int32 i_e = 63; + + dt_int32 im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 32 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 16 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 8 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 4 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 2 + im = (i_0 + i_e)>>1; // divide by 2 + if (x < xv[im]) i_e = im; else i_0 = im; // 1 + + return i_0; + } + } + + /* add - assign - crop - norm_2 - fftsft */ + namespace cgpu_detail + { + /***************************************************************************************/ + /**************** Shift zero-frequency component to center of spectrum *****************/ + /***************************************************************************************/ + /* shift matrix respect to nx_h */ + template + CGPU_EXEC_INL + void fcn_fftsft_1d(const dt_int32& ix, const iGrid_1d& igrid, T* mx_io) + { + const auto ix_sft = igrid.sub_2_ind(igrid.nx_h+ix); + thrust::swap(mx_io[ix], mx_io[ix_sft]); + } + + /* shift matrix respect to ny_h */ + template + CGPU_EXEC_INL + void fcn_fftsft_bc_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_io) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + const auto ixy_sft = igrid.sub_2_ind(ix, igrid.ny_h+iy); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_io) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, T* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + } + + /* shift 3d matrix respect to (nx_h, ny_h, nz_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_3d(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const iGrid_3d& igrid, T* mx_io) + { + auto ixy = igrid.sub_2_ind(ix, iy, iz); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(ix, iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, iy, iz); + ixy_sft = igrid.sub_2_ind(ix, igrid.ny_h+iy, igrid.nz_h+iz); + thrust::swap(mx_io[ixy], mx_io[ixy_sft]); + } + + /* shift 3d matrix respect to (nx_h, ny_h, nz_h) */ + template + CGPU_EXEC_INL + void fcn_fftsft_3d(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const iGrid_3d& igrid, T* mx_i, T* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy, iz); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(ix, iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy, iz); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + + ixy = igrid.sub_2_ind(igrid.nx_h+ix, iy, iz); + ixy_sft = igrid.sub_2_ind(ix, igrid.ny_h+iy, igrid.nz_h+iz); + mx_o[ixy] = mx_i[ixy_sft]; + mx_o[ixy_sft] = mx_i[ixy]; + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const T& w, T* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + mx_o[ixy] += w*mx_i[ixy_sft]; + mx_o[ixy_sft] += w*mx_i[ixy]; + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + mx_o[ixy] += w*mx_i[ixy_sft]; + mx_o[ixy_sft] += w*mx_i[ixy]; + } + + /* add, scale, square and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_norm_2_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const U& w, U* mx_o) + { + auto ixy = igrid.sub_2_ind(ix, iy); + auto ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, igrid.ny_h+iy); + mx_o[ixy] += w*::norm_2(mx_i[ixy_sft]); + mx_o[ixy_sft] += w*::norm_2(mx_i[ixy]); + + ixy = igrid.sub_2_ind(ix, igrid.ny_h+iy); + ixy_sft = igrid.sub_2_ind(igrid.nx_h+ix, iy); + mx_o[ixy] += w*::norm_2(mx_i[ixy_sft]); + mx_o[ixy_sft] += w*::norm_2(mx_i[ixy]); + } + + /***************************************************************************************/ + /* Assign and crop */ + template + CGPU_EXEC_INL + void fcn_assign_crop_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, T* mx_o) + { + if (iregion.chk_bound(ix, iy)) + { + mx_o[iregion.sub_2_ind(ix, iy)] = mx_i[igrid.sub_2_ind(ix, iy)]; + } + } + + /* assign, crop and shift */ + template + CGPU_EXEC_INL + void fcn_assign_crop_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, T* mx_o) + { + auto ix_i = ix; + auto iy_i = iy; + + auto ix_s = igrid.nx_h+ix; + auto iy_s = igrid.ny_h+iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] = mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] = mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + + /***************************************************************************************/ + ix_i = ix; + iy_i = igrid.ny_h+iy; + + ix_s = igrid.nx_h+ix; + iy_s = iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] = mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] = mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + } + + /* add, scale, crop and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_crop_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, const T& w, T* mx_o) + { + auto ix_i = ix; + auto iy_i = iy; + + auto ix_s = igrid.nx_h+ix; + auto iy_s = igrid.ny_h+iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + + /***************************************************************************************/ + ix_i = ix; + iy_i = igrid.ny_h+iy; + + ix_s = igrid.nx_h+ix; + iy_s = iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*mx_i[igrid.sub_2_ind(ix_s, iy_s)]; + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*mx_i[igrid.sub_2_ind(ix_i, iy_i)]; + } + } + + /* add, scale, square, crop and shift */ + template + CGPU_EXEC_INL + void fcn_add_sc_norm_2_crop_fftsft_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, T* mx_i, const iRegion_Rect_2d& iregion, const U& w, U* mx_o) + { + auto ix_i = ix; + auto iy_i = iy; + + auto ix_s = igrid.nx_h+ix; + auto iy_s = igrid.ny_h+iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_s, iy_s)]); + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_i, iy_i)]); + } + + /***************************************************************************************/ + ix_i = ix; + iy_i = igrid.ny_h+iy; + + ix_s = igrid.nx_h+ix; + iy_s = iy; + + if (iregion.chk_bound(ix_i, iy_i)) + { + mx_o[iregion.sub_2_ind(ix_i, iy_i)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_s, iy_s)]); + } + + if (iregion.chk_bound(ix_s, iy_s)) + { + mx_o[iregion.sub_2_ind(ix_s, iy_s)] += w*::norm_2(mx_i[igrid.sub_2_ind(ix_i, iy_i)]); + } + } + } + + /* transpose - element wise matrix op vector */ + namespace cgpu_detail + { + /* transpose */ + template + CGPU_EXEC_INL + void fcn_trs_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr mx_o) + { + mx_o[igrid.sub_2_ind_by_d2(ix, iy)] = mx_i[igrid.sub_2_ind(ix, iy)]; + } + + /***************************************************************************************/ + /* element wise addition: matrix + vector row */ + template + CGPU_EXEC_INL + void fcn_ew_add_mx_vctr_row(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] += vctr[ix]; + } + + /* element wise addition: matrix + vector col */ + template + CGPU_EXEC_INL + void fcn_ew_add_mx_vctr_col(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] += vctr[iy]; + } + + /***************************************************************************************/ + /* element wise subtraction: matrix - vector row */ + template + CGPU_EXEC_INL + void fcn_ew_sub_mx_vctr_row(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] -= vctr[ix]; + } + + /* element wise subtraction: matrix - vector col */ + template + CGPU_EXEC_INL + void fcn_ew_sub_mx_vctr_col(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] -= vctr[iy]; + } + + /***************************************************************************************/ + /* element wise multiplication matrix X vector row */ + template + CGPU_EXEC_INL + void fcn_ew_mult_mx_vctr_row(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] *= vctr[ix]; + } + + /* element wise multiplication matrix X vector col */ + template + CGPU_EXEC_INL + void fcn_ew_mult_mx_vctr_col(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, Ctpr vctr, Tpr mx_io) + { + mx_io[grid.sub_2_ind(ix, iy)] *= vctr[iy]; + } + } + + /* aperture functions */ + namespace cgpu_detail + { + template + CGPU_EXEC_INL + void fcn_fermi_aperture(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_cut, const T& alpha, const T& w, U* mx_io) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto g2 = grid.g2_sft(ix, iy); + + mx_io[ixy] *= w*fcn_fermi_lpf(alpha, g2_cut, g2); + } + + template + CGPU_EXEC_INL + void fcn_hard_aperture(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_cut, const T& w, U* mx_io) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto g2 = grid.g2_sft(ix, iy); + + mx_io[ixy] = ((g2 <= g2_cut))?(w*mx_io[ixy]):T(0); + } + } + + /* phase shifts real space*/ + namespace cgpu_detail + { + // phase factor 1d + template + CGPU_EXEC_INL + void fcn_rs_exp_factor_1d(const dt_int32& ix, const Grid_1d& grid, + complex* psi_i, const T& gx, const T& w, complex* psi_o) + { + const auto rx = grid.rx_sft(ix)-grid.rx_c(); + psi_o[ix] = w*psi_i[ix]*euler(gx*rx); + } + + // phase factor 2d by col + template + CGPU_EXEC_INL + void fcn_rs_exp_factor_2d_bc(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const T& alpha, Ctpr gy, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto ry = grid.ry_sft(iy)-grid.ry_c(); + psi_o[ixy] = w*psi_i[ixy]*euler(alpha*gy[ix]*ry); + } + + // phase factor 2d + template + CGPU_EXEC_INL + void fcn_rs_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto rv = grid.rv_sft(ix, iy)-grid.rv_c(); + psi_o[ixy] = w*psi_i[ixy]*euler(g*rv); + } + + // phase factor 2d multipositions + template + CGPU_EXEC_INL + void fcn_rs_mul_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, R_2d* g, const dt_int32& n_g, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto rv = grid.rv_sft(ix, iy)-grid.rv_c(); + + complex exp_sum = 0; + for(auto ig=0; ig + CGPU_EXEC_INL + void fcn_fs_exp_factor_1d(const dt_int32& ix, const Grid_1d& grid, + complex* psi_i, const T& rx, const T& w, complex* psi_o) + { + const auto gx = grid.gx_sft(ix); + psi_o[ix] = w*psi_i[ix]*euler(rx*gx); + } + + template + CGPU_EXEC_INL + void fcn_fs_exp_factor_2d_bc(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const T& alpha, T* ry, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gy = grid.gy_sft(iy); + psi_o[ixy] = w*psi_i[ixy]*euler(alpha*ry[ix]*gy); + } + + template + CGPU_EXEC_INL + void fcn_fs_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& r, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gv = grid.gv_sft(ix, iy); + psi_o[ixy] = w*psi_i[ixy]*euler(r*gv); + } + + template + CGPU_EXEC_INL + void fcn_fs_mul_exp_factor_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, R_2d* r, const dt_int32& n_r, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gv = grid.gv_sft(ix, iy); + + complex exp_sum = 0; + for(auto ir=0; ir + CGPU_EXEC_INL + T fcn_grad_x(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + + if (ix == 0) + { + const auto ixy_f = igrid.sub_2_ind(ix+1, iy); + + return mx_i[ixy_f]-mx_i[ixy]; + } + else if (ix == igrid.nx-1) + { + const auto ixy_b = igrid.sub_2_ind(ix-1, iy); + + return mx_i[ixy]-mx_i[ixy_b]; + } + else + { + const auto ixy_b = igrid.sub_2_ind(ix-1, iy); + const auto ixy_f = igrid.sub_2_ind(ix+1, iy); + + return (mx_i[ixy_f]-mx_i[ixy_b])/T(2); + } + } + + template + CGPU_EXEC_INL + void fcn_grad_x(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr mx_o) + { + mx_o[igrid.sub_2_ind(ix, iy)] = fcn_grad_x(ix, iy, igrid, mx_i); + } + + /***************************************************************************************/ + template + CGPU_EXEC_INL + T fcn_grad_y(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + + if (iy == 0) + { + const auto ixy_f = igrid.sub_2_ind(ix, iy+1); + + return mx_i[ixy_f]-mx_i[ixy]; + } + else if (iy == igrid.ny-1) + { + const auto ixy_b = igrid.sub_2_ind(ix, iy-1); + + return mx_i[ixy]-mx_i[ixy_b]; + } + else + { + const auto ixy_b = igrid.sub_2_ind(ix, iy-1); + const auto ixy_f = igrid.sub_2_ind(ix, iy+1); + + return (mx_i[ixy_f]-mx_i[ixy_b])/T(2); + } + } + + template + CGPU_EXEC_INL + void fcn_grad_y(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr mx_o) + { + mx_o[igrid.sub_2_ind(ix, iy)] = fcn_grad_y(ix, iy, igrid, mx_i); + } + + /***************************************************************************************/ + //template + //CGPU_EXEC_INL + //R_2d fcn_grad(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i) + //{ + // return {fcn_grad_x(ix, iy, igrid, mx_i), fcn_grad_y(ix, iy, igrid, mx_i)}; + //} + + template + CGPU_EXEC_INL + void fcn_grad(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_i, Tpr dm_x, Tpr dm_y) + { + fcn_grad_x(ix, iy, igrid, mx_i, dm_x); + fcn_grad_y(ix, iy, igrid, mx_i, dm_y); + } + } + + /* function multiplication fourier space */ + namespace cgpu_detail + { + #define FCN_MULT_FS_FCN_CGPU(POW, DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_mult_fs_fcn_g##POW##_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, const T& w, Tpr mx_io) \ + { \ + const auto fg = fcn(grid.g##POW##_sft(IDX_ND(DIM))); \ + mx_io[grid.sub_2_ind(IDX_ND(DIM))] *= w*fg; \ + } + + FCN_MULT_FS_FCN_CGPU(, 1); // fcn_mult_fs_fcn_g_1d + FCN_MULT_FS_FCN_CGPU(, 2); // fcn_mult_fs_fcn_g_2d + FCN_MULT_FS_FCN_CGPU(, 3); // fcn_mult_fs_fcn_g_3d + + FCN_MULT_FS_FCN_CGPU(2, 1); // fcn_mult_fs_fcn_g2_1d + FCN_MULT_FS_FCN_CGPU(2, 2); // fcn_mult_fs_fcn_g2_2d + FCN_MULT_FS_FCN_CGPU(2, 3); // fcn_mult_fs_fcn_g2_3d + } + + /* deconvolution */ + namespace cgpu_detail + { + #define FCN_DCV_FS_FCN_CGPU(POW, DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_dcv_fs_fcn_g##POW##_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, const T& psnr, const T& w, Tpr mx_io) \ + { \ + const auto fg = fcn(grid.g##POW##_sft(IDX_ND(DIM))); \ + mx_io[grid.sub_2_ind(IDX_ND(DIM))] *= w*fg/(fg*fg+psnr); \ + } + + FCN_DCV_FS_FCN_CGPU(, 1); // fcn_dcv_fs_fcn_g_1d + FCN_DCV_FS_FCN_CGPU(, 2); // fcn_dcv_fs_fcn_g_2d + FCN_DCV_FS_FCN_CGPU(, 3); // fcn_dcv_fs_fcn_g_3d + + FCN_DCV_FS_FCN_CGPU(2, 1); // fcn_dcv_fs_fcn_g2_1d + FCN_DCV_FS_FCN_CGPU(2, 2); // fcn_dcv_fs_fcn_g2_2d + FCN_DCV_FS_FCN_CGPU(2, 3); // fcn_dcv_fs_fcn_g2_3d + } + + /* window functions */ + namespace cgpu_detail + { + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_xd(const dt_int32& ix, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix)] = fcn.eval_r2(grid.r2(ix, fcn.r)); + //} + // + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_xd(const dt_int32& ix, const dt_int32& iy, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy)] = fcn.eval_r2(grid.r2(ix, iy, fcn.r)); + //} + + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_xd(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy, iz)] = fcn.eval_r2(grid.r2(ix, iy, iz, fcn.r)); + //} + + ///***************************************************************************************/ + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_sft_xd(const dt_int32& ix, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix)] = fcn.eval_r2(grid.r2_sft(ix, fcn.r)); + //} + // + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_sft_xd(const dt_int32& ix, const dt_int32& iy, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy)] = fcn.eval_r2(grid.r2_sft(ix, iy, fcn.r)); + //} + + //template + //CGPU_EXEC_INL + //void fcn_wd_fcn_r2_sft_xd(const dt_int32& ix, const dt_int32& iy, const dt_int32& iz, const Grid_xd& grid, + //const Wd_fcn_xd& fcn, Tpr mx_o) + //{ + // mx_o[grid.sub_2_ind(ix, iy, iz)] = fcn.eval_r2(grid.r2_sft(ix, iy, iz, fcn.r)); + //} + + #define FCN_WD_FCN_CGPU(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_wd_fcn_r2_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, Tpr mx_o) \ + { \ + mx_o[grid.sub_2_ind(IDX_ND(DIM))] = fcn.eval_r2(grid.r2(IDX_ND(DIM), fcn.r)); \ + } + + FCN_WD_FCN_CGPU(1); // fcn_wd_fcn_r2_1d + FCN_WD_FCN_CGPU(2); // fcn_wd_fcn_r2_2d + FCN_WD_FCN_CGPU(3); // fcn_wd_fcn_r2_3d + + #define FCN_WD_FCN_SFT_CGPU(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_wd_fcn_r2_sft_##DIM##d(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + const TFcn& fcn, Tpr mx_o) \ + { \ + mx_o[grid.sub_2_ind(IDX_ND(DIM))] = fcn.eval_r2(grid.r2_sft(IDX_ND(DIM), fcn.r)); \ + } + + FCN_WD_FCN_SFT_CGPU(1); // fcn_wd_fcn_r2_sft_1d + FCN_WD_FCN_SFT_CGPU(2); // fcn_wd_fcn_r2_sft_2d + FCN_WD_FCN_SFT_CGPU(3); // fcn_wd_fcn_r2_sft_3d + } + + /* phase correlation */ + namespace cgpu_detail + { + /****************** pcf data processing real space *******************/ + #define FCN_RS_PCF_XD_DP(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_rs_pcf_##DIM##d_dp(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + Ctpr mx_i, const TFcn& wd, const T& w, Tpr mx_o) \ + { \ + const auto ind_0 = grid.sub_2_ind(IDX_ND(DIM)); \ + const auto ind_n = grid.sub_2_ind_bd(IDX_ND(DIM)+1); \ + mx_o[ind_0] = w*(mx_i[ind_n]-mx_i[ind_0])*wd(grid.r2(IDX_ND(DIM), wd.r_c)); \ + } + + FCN_RS_PCF_XD_DP(1); // fcn_rs_pcf_1d_dp + FCN_RS_PCF_XD_DP(2); // fcn_rs_pcf_2d_dp + FCN_RS_PCF_XD_DP(3); // fcn_rs_pcf_3d_dp + + /**************** mx_o data processing fourier space ******************/ + #define FCN_FS_PCF_XD_DP(DIM) \ + template \ + CGPU_EXEC_INL \ + void fcn_fs_pcf_##DIM##d_dp(IDX_CDEF_ND(DIM), const Grid_##DIM##d& grid, \ + Ctpr mx_1i, Ctpr mx_2i, const TFcn& wd, const T& w, Tpr mx_o) \ + { \ + const auto ind_0 = grid.sub_2_ind(IDX_ND(DIM)); \ + auto z = conj(mx_1i[ind_0])*mx_2i[ind_0]; \ + mx_o[ind_0] = polar(wd(grid.g2_sft(IDX_ND(DIM))), arg(z)); \ + } + + FCN_FS_PCF_XD_DP(1); // fcn_fs_pcf_1d_dp + FCN_FS_PCF_XD_DP(2); // fcn_fs_pcf_2d_dp + FCN_FS_PCF_XD_DP(3); // fcn_fs_pcf_3d_dp + } + + /* optical flow */ + namespace cgpu_detail + { + // https:// en.wikipedia.org/wiki/Optical_flow + template + CGPU_EXEC_INL + void fcn_opt_flow(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& igrid, Ctpr mx_s, Ctpr mx_m, + const T& alpha, Tpr dphi_x, Tpr dphi_y) + { + const auto ixy = igrid.sub_2_ind(ix, iy); + + const auto sm = mx_m[ixy]-mx_s[ixy]; + const auto alpha_sm_2 = ::square(alpha*sm); + + auto dmx_s = fcn_grad(ix, iy, igrid, mx_s); + auto dmx_m = fcn_grad(ix, iy, igrid, mx_m); + + const auto dphi = -sm*(dmx_s/(dmx_s.norm_2() + alpha_sm_2) + dmx_s/(dmx_m.norm_2() + alpha_sm_2)); + + if (isfinite(dphi.x) && isfinite(dphi.y)) + { + dphi_y[ixy] = dphi.x; + dphi_x[ixy] = dphi.y; + } + else + { + dphi_y[ixy] = T(0); + dphi_x[ixy] = T(0); + } + } + } + + /* interpolation poly3 */ + namespace cgpu_detail + { + // calculate interpolation coefficients from its value and derivative + template + CGPU_EXEC_INL + void fcn_vd_2_coef_poly3(const T& dx_ij, const T& y_i, const T& y_j, const T& t_i, const T& t_j, T& c2, T& c3) + { + const auto m_i = (y_j-y_i)/dx_ij; + const auto n_i = t_i + t_j - T(2)*m_i; + + c2 = (m_i-t_i-n_i)/dx_ij; + c3 = n_i/(dx_ij*dx_ij); + } + + // eval polynomial of order 3 + template + CGPU_EXEC_INL + T fcn_eval_poly3(const T& x, Ctpr xv, Ctpr c0, Ctpr c1, Ctpr c2, Ctpr c3) + { + const auto ix = fcn_unrolled_binary_search_128(x, xv); + const auto dx = x - xv[ix]; + + return c0[ix] + (c1[ix] +(c2[ix] + c3[ix]*dx)*dx)*dx; + } + } + + /* bilinear interpolation */ + namespace cgpu_detail + { + /* regular grid bilinear interpolation */ + // https:// en.wikipedia.org/wiki/Bilinear_interpolation + template + CGPU_EXEC_INL + T fcn_intrpl_bl_rg_2d(const R_2d& p, const Grid_2d& grid_i, Tpr mx_i) + { + const auto ix = fcn_set_bound(grid_i.rx_2_irx_fds(p.x), 0, grid_i.nx-2); + const auto iy = fcn_set_bound(grid_i.ry_2_iry_fds(p.y), 0, grid_i.ny-2); + + const auto f11 = mx_i[grid_i.sub_2_ind(ix, iy)]; + const auto f12 = mx_i[grid_i.sub_2_ind(ix, iy+1)]; + const auto f21 = mx_i[grid_i.sub_2_ind(ix+1, iy)]; + const auto f22 = mx_i[grid_i.sub_2_ind(ix+1, iy+1)]; + + const auto x1 = grid_i.rx(ix); + const auto x2 = grid_i.rx(ix+1); + const auto y1 = grid_i.ry(iy); + const auto y2 = grid_i.ry(iy+1); + + const auto dx1 = (p.x-x1)/(x2-x1); + const auto dx2 = (x2-p.x)/(x2-x1); + const auto dy1 = (p.y-y1)/(y2-y1); + const auto dy2 = (y2-p.y)/(y2-y1); + + return dx2*(f11*dy2 + f12*dy1)+dx1*(f21*dy2 + f22*dy1); + }; + + template + CGPU_EXEC_INL + void fcn_intrpl_bl_rg_2d(const dt_int32& ixy, const Grid_2d& grid_i, Ctpr mx_i, + Ctpr vrx, Ctpr vry, const T& bg, Tpr mx_o) + { + R_2d p(vrx[ixy], vry[ixy]); + mx_o[ixy] = (grid_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid_i, mx_i):bg; + }; + + /***************************************************************************************/ + /* non regular grid bilinear interpolation */ + // https:// www.codesd.com/item/bilinear-interpolation-with-non-aligned-entry-points.html + template + CGPU_EXEC_INL + T fcn_intrpl_bl_nrg_2d(const R_2d& p, const R_3d& p1, + const R_3d& p2, const R_3d& p3, const R_3d& p4) + { + const auto a = -p1.x + p3.x; + const auto b = -p1.x + p2.x; + const auto c = p1.x - p2.x - p3.x + p4.x; + const auto d = p.x - p1.x; + const auto e = -p1.y + p3.y; + const auto f = -p1.y + p2.y; + const auto g = p1.y - p2.y - p3.y + p4.y; + const auto h = p.y - p1.y; + + const auto c_x = ::sqrt(T(-4)*(c*e - a*g)*(d*f - b*h) + ::square(b*e - a*f + d*g - c*h)); + const auto c_y = T(2)*(c*e - a*g); + const auto c_z = T(2)*(c*f - b*g); + + T alpha = -(b*e - a*f + d*g - c*h + c_x)/c_y; + T beta = (b*e - a*f - d*g + c*h + c_x)/c_z; + + if ((alpha < T(0)) || (alpha > T(1)) || (beta < T(0)) || (beta > T(1))) + { + alpha = (-b*e + a*f - d*g + c*h + c_x)/c_y; + beta = -(-b*e + a*f + d*g - c*h + c_x)/c_z; + } + + return (T(1) - alpha)*((T(1) - beta)*p1.z + beta*p2.z) + alpha*((T(1) - beta)*p3.z + beta*p4.z); + }; + + template + CGPU_EXEC_INL + void fcn_intrpl_bl_nrg_2d(const dt_int32& ixy, Ctpr vrx_i, Ctpr vry_i, Ctprmx_i, + Ctpr vrx, Ctpr vry, const T& bg, Tpr mx_o) + { + R_2d p(vrx[ixy], vry[ixy]); + // neighboring search algorithm: check out tessellation or MD find neighbors + R_3d p1; + R_3d p2; + R_3d p3; + R_3d p4; + + // how to check out bound for non regular grid? + // mx_o[ixy] = (grid_2d_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, p1, p2, p3, p4, mx_i):bg; + }; + } + + namespace cgpu_detail + { + /* distort regular grid */ + template + CGPU_EXEC_INL + void fcn_distort_mx_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, Ctpr mx, + Ctpr dvx, Ctpr dvy, const T& bg, Tpr mx_o) + { + const R_2d p(grid.rx(ix)+dvx[iy], grid.ry(iy)+dvy[iy]); + mx_o[grid.sub_2_ind(ix, iy)] = (grid.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid, mx):bg; + }; + + /* scan distortion */ + template + CGPU_EXEC_INL + void fcn_sd_nr_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, Ctpr mx, + TPar &parm, Tpr mx_o) + { + const auto ixy = grid.sub_2nd(ix, iy); + const auto ny = grid.ny-2; + const auto nx = grid.nx-2; + + const R_2d p(grid.rx(ix), grid.ry(iy)); + + const auto iy_s1 = fcn_r_2r_b_by_vctr(parm.ry_s, p.y, 0, ny); + const auto iy_s2 = iy_s1 + 1; + + if ((iy_s1 < 0)||(iy_s2 > ny)) + { + mx_o[ixy] = (parm.bg_opt == efst_same_in)?mx[ixy]:parm.bg; + return; + } + + const auto iy_k1 = parm.iy[iy_s1]; + const auto ix_k1 = grid.rx_2rx_fds(p.x - parm.dx[iy_k1]); + const auto iy_k2 = parm.iy[iy_s2]; + const auto ix_k2 = grid.rx_2rx_fds(p.x - parm.dx[iy_k2]); + + if ((ix_k1 < 0)||(ix_k1 > nx)||(ix_k2 < 0)||(ix_k2 > nx)) + { + mx_o[ixy] = (parm.bg_opt == efst_same_in)?mx[ixy]:parm.bg; + return; + } + + const R_3d p1(grid.rx(ix_k1) + parm.dx[iy_k1], parm.ry_s[iy_s1], mx[grid.sub_2nd(ix_k1, iy_k1)]); + const R_3d p4(grid.rx(ix_k1+1) + parm.dx[iy_k1], parm.ry_s[iy_s1], mx[grid.sub_2nd(ix_k1+1, iy_k1)]); + const R_3d p2(grid.rx(ix_k2) + parm.dx[iy_k2], parm.ry_s[iy_s2], mx[grid.sub_2nd(ix_k2, iy_k2)]); + const R_3d p3(grid.rx(ix_k2+1) + parm.dx[iy_k2], parm.ry_s[iy_s2], mx[grid.sub_2nd(ix_k2+1, iy_k2)]); + + /* this must work */ + // mx_o[ixy] = fcn_intrpl_bl_nrg_2d(p, p1, p2, p3, p4, grid); + + auto u = p2-p1; + auto v = p4-p1; + p = p - p1; + T m = v.x*u.y-v.y*u.x; + T alpha = (u.y*p.x-u.x*p.y)/m; + T beta = (-v.y*p.x+v.x*p.y)/m; + + mx_o[ixy] = beta*(alpha*p3.z + (1-alpha)*p2.z) + (1-beta)*(alpha*p4.z + (1-alpha)*p1.z); + }; + + // /* find peak maximum 1d */ + // template + // CGPU_EXEC_INL + // T fd_max_peak_pos(const Grid_1d& grid, Ctpr M) + // { + // const dt_int32 ix_max = thrust::distance(M.begin(), thrust::max_element(M.begin(), M.end())); + + // return grid.rx(ix_max); + // }; + + // /* find peak maximum 2d */ + // template + // CGPU_EXEC FORCE_INLINE + // R_2d fd_max_peak_pos(const Grid_2d& grid, CtprM) + // { + // const dt_int32 ixy_max = thrust::distance(M.begin(), thrust::max_element(M.begin(), M.end())); + // const dt_int32 ix_max, iy_max; + // grid.ind_2_sub(ixy_max, ix_max, iy_max); + + // return {grid.rx(ix_max), grid.ry(iy_max)}; + // }; + + // template + // CGPU_EXEC_INL + // R_2d af_iscale(const R_2d& p, const T& fxy) + // { + // return p/fxy; + // } + + // template + // CGPU_EXEC_INL + // void sc_2d(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid_2d_i, TVctr& mx_i, + // const T& fxy, const Grid_2d& grid_2d_o, TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid_2d_o.rx(ix), grid_2d_o.ry(iy)); + // p = af_iscale(p, fxy); + + // mx_o[grid_2d_o.sub_2_ind(ix, iy)] = fcn_intrpl_bl_rg_2d(p, grid_2d_i, mx_i); + // } + + // template + // CGPU_EXEC_INL + // R_2d af_irot_sca_sft(const T& theta, const R_2d& p0, const T& fx, const T& fy, const R_2d& ps, R_2d p) + // { + // T sin_t, cos_t; + // sincos(theta, &sin_t, &cos_t); + // p.x = (p.x-ps.x)/fx; + // p.y = (p.y-ps.y)/fy; + // p -= p0; + // p = R_2d(cos_t*p.x+sin_t*p.y, -sin_t*p.x+cos_t*p.y); + // p += p0; + // return p; + // } + + // template + // CGPU_EXEC_INL + // void rot_sca_sft_2d(const dt_int32& ix, const dt_int32& iy, const TGrid& grid_2d_i, TVctr& mx_i, + // const T& theta, const R_2d& p0, const T& fx, const T& fy, + // const R_2d& ps, const T& bg, const TGrid& grid_2d_o, TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid_2d_o.rx(ix), grid_2d_o.ry(iy)); + // p = af_irot_sca_sft(theta, p0, fx, fy, ps, p); + + // mx_o[grid_2d_o.sub_2_ind(ix, iy)] = (grid_2d_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid_2d_i, mx_i):bg; + // }; + + // template + // CGPU_EXEC_INL + // void at_2d(const dt_int32& ix, const dt_int32& iy, const iGrid_2d& grid, TVctr& mx_i, + // const Mx_2x2& A, const R_2d& txy, const T& bg, + // TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid.rx(ix), grid.ry(iy)); + // p = A*p+txy; + + // mx_o[grid.sub_2_ind(ix, iy)] = (grid.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid, mx_i):bg; + // }; + + // template + // CGPU_EXEC_INL + // R_2d af_shx_scy(const R_2d& p, const T& a, const T& b) + // { + // return R_2d(p.x+a*p.y, b*p.y); + // } + + // template + // CGPU_EXEC_INL + // void shx_scy(const dt_int32& ix, const dt_int32& iy, const TGrid& grid_2d_i, TVctr& mx_i, + // const T& fx, const T& fy, const T& bg, + // const TGrid& grid_2d_o, TVctr& mx_o) + // { + // using T = T; + + // R_2d p(grid_2d_o.rx(ix), grid_2d_o.ry(iy)); + // p = af_shx_scy(p, fx, fy); + + // mx_o[grid_2d_o.sub_2_ind(ix, iy)] = (grid_2d_i.chk_bound_eps(p))?fcn_intrpl_bl_rg_2d(p, grid_2d_i, mx_i):bg; + // }; + + + // template + // CGPU_EXEC_INL + // void dilate(const dt_int32& ix_i, const dt_int32& iy_i, TVctr& Im_i, TVctr& Im_o) + // { + // dt_int32 ix_0 = max(ix_i+nk0, 0); + // dt_int32 ix_e = min(ix_i+nke, nx_i); + + // dt_int32 iy_0 = max(iy_i+nk0, 0); + // dt_int32 iy_e = min(iy_i+nke, ny_i); + + // for(auto ix = ix_0; ix < ix_e; ix++) + // { + // for(auto iy = iy_0; iy < iy_e; iy++) + // { + // if (Im_i[ix*ny_i+iy]>0.5) + // { + // Im_o[ix_i*ny_i+iy_i] = 1; + // return; + // } + // } + // } + // Im_o[ix_i*ny_i+iy_i] = 0; + // } + } // cgpu_detail +} diff --git a/src/cgpu_detail_mt.cuh b/src/cgpu_detail_mt.cuh new file mode 100755 index 00000000..d94c6088 --- /dev/null +++ b/src/cgpu_detail_mt.cuh @@ -0,0 +1,1811 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_DETAIL_MT_H + #define CGPU_DETAIL_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "type_traits_mt.cuh" + #include "lens.cuh" + #include "energy_loss.cuh" + #include "cgpu_detail.cuh" + + /* pointer to atomic functions */ + namespace mt + { + template + using pFcn_clnl_3_1 = T (*)(const T&, Ctpr, Ctpr); + + template + using pFcn_clnl_3_2 = void (*)(const T&, Ctpr, Ctpr, T&, T&); + + /***************************************************************************************/ + template + using pFcn_clnl_4_1 = T (*)(const T&, const T&, Ctpr, Ctpr); + + template + using pFcn_clnl_4_2 = void (*)(const T&, const T&, Ctpr, Ctpr, T&, T&); + + /***************************************************************************************/ + template + using pFcn_clnl_6_1 = T (*)(const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr); + + template + using pFcn_clnl_6_2 = void (*)(const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr, T&, T&); + + /***************************************************************************************/ + template + using pFcn_clnl_8_1 = T (*)(const T&, const T&, const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr); + + template + using pFcn_clnl_8_2 = void (*)(const T&, const T&, const T&, Ctpr, Ctpr, const dt_int32&, Ctpr, Ctpr, T&, T&); + } + + /* atomic functions */ + namespace mt + { + namespace cgpu_detail_mt + { + template + CGPU_EXEC_INL + T fcn_spt_exp_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_exp_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_gauss_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_gauss_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_lorentzian_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_lorentzian_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_yukawa_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T ix = T(1)/x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_yukawa_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T ix = T(1)/x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_spt_pr_gauss_feg_v(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl) + { + T y = 0; + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + void fcn_spt_pr_gauss_feg_vd(const T& x, const dt_int32& k_0, const dt_int32& k_e, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + if (init) + { + y = dy = 0; + } + + const T x2 = x*x; + + for(auto ik = k_0; ik + CGPU_EXEC_INL + T fcn_int_fx_x0_xe(const T& x, const T& x_0, const T& x_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + const T a = 0.5*(x_e-x_0); + const T b = 0.5*(x_e+x_0); + T s = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + void fcn_int_fx_x0_xe(const T& x, const T& x_0, const T& x_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s1, T& s2, pFcn_clnl_3_2 fcn) + { + const T a = 0.5*(x_e-x_0); + const T b = 0.5*(x_e+x_0); + s1 = s2 = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + T fcn_int_fx_x0_pinfty(const T& x, const T& x_0, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + T s = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + void fcn_int_fx_x0_pinfty(const T& x, const T& x_0, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s1, T& s2, pFcn_clnl_3_2 fcn) + { + s1 = s2 = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + T fcn_int_vz_z0_ze(const T& r, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + const dt_bool split = (z_0<0) && (0 + CGPU_EXEC_INL + void fcn_int_vz_dvz_z0_ze( const T& r, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s, T& ds, pFcn_clnl_3_2 fcn) + { + dt_bool split = (z_0<0) && (0 + CGPU_EXEC_INL + T fcn_int_vz_ninfty_pinfty(const T& r, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, pFcn_clnl_3_1 fcn) + { + const T r2 = r*r; + T s = 0; + + for(auto ik = 0; ik + CGPU_EXEC_INL + void fcn_int_vz_dvz_ninfty_pinfty(const T& r, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& s, T& ds, pFcn_clnl_3_2 fcn) + { + const T r2 = r*r; + s = ds = 0; + + for(auto ik = 0; ik \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + if (Dev==edev_cpu) \ + pfcn = fcn_##cnam; \ + else \ + cudaMemcpyFromSymbol(&pfcn, pgpu_fcn_##cnam, sizeof(pFcn)); \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + + #define pFCN_TEMPLATE_AF_SPEC(cnam, TpFcn, ppt) \ + template \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + if (Dev==edev_cpu) \ + pfcn = fcn_##cnam; \ + else \ + cudaMemcpyFromSymbol(&pfcn, pgpu_fcn_##cnam##_spec, sizeof(pFcn)); \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + #else + #define pFCN_TEMPLATE_AF(cnam, TpFcn) \ + template \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + pfcn = fcn_##cnam; \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + + #define pFCN_TEMPLATE_AF_SPEC(cnam, TpFcn, ppt) \ + template \ + class pFcn_##cnam \ + { \ + public: \ + using pFcn = TpFcn; \ + \ + pFcn_##cnam() \ + { \ + pfcn = fcn_##cnam; \ + } \ + \ + operator pFcn() \ + { \ + return pfcn; \ + } \ + private: \ + pFcn pfcn; \ + } + #endif + + /***************************************************************************************/ + /*************************************** feg *******************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_lorentzian_v(x, 0, 3, cl, cnl) + fcn_spt_gauss_v(x, 3, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_lorentzian_vd(x, 0, 3, cl, cnl, y, dy); + fcn_spt_gauss_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + const T x2 = x*x; + + T y = 0; + + if (fcn_is_zero(x)) + { + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*cnl[ik]; + } + + } + else + { + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*(T(1)-exp(-cnl[ik]*x2)); + } + y = y/x2; + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T x2 = x*x; + + y = dy = 0; + + if (fcn_is_zero(x)) + { + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*cnl[ik]; + } + } + else + { + for(auto ik = 0; ik <6; ik++) + { + const auto t = exp(-cnl[ik]*x2); + y += cl[ik]*(T(1)-t); + dy += cl[ik]*(T(1)-(T(1)+cnl[ik]*x2)*t); + } + y = y/x2; + dy = T(-2)*dy/(x*x2); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + const T x2 = x*x; + + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1) + cnl[ik]*x2); + y += cl[ik]*t*(t + T(1)); + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T x2 = x*x; + + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1) + cnl[ik]*x2); + y += cl[ik]*t*(t + T(1)); + dy += T(-2)*x*cl[ik]*cnl[ik]*t*t*(T(2)*t + T(1)); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_feg(const T& x, Ctpr cl, Ctpr cnl) + { + auto y = fcn_spt_gauss_v(x, 0, 5, cl, cnl); + y += cl[5]/(cnl[5] + x*x); + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_feg_dfeg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + const auto t = T(1)/(cnl[5] + x*x); + const auto yt = cl[5]*t; + y += yt; + dy += T(-2)*x*yt*t; + } + + /***************************************************************************************/ + template + using pFcn_feg1 = pFcn_clnl_3_1; + + #ifdef __CUDACC__ + template + GPU_EXEC pFcn_feg1 pgpu_fcn_feg = fcn_feg; + #endif + + pFCN_TEMPLATE_AF(feg, pFcn_feg1); + + /***************************************************************************************/ + template + using pFcn_feg2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_feg2 pgpu_fcn_feg_dfeg = fcn_feg_dfeg; + + pFCN_TEMPLATE_AF(feg_dfeg , pFcn_feg2); + + /***************************************************************************************/ + /***************************************** fxg *****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_fxg(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_fxg_dfxg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_fxg(const T& x, Ctpr cl, Ctpr cnl) + { + const T x2 = x*x; + + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1)+cnl[ik]*x2); + y += cl[ik]*t*t; + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_fxg_dfxg(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T x2 = x*x; + + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto t = T(1)/(T(1)+cnl[ik]*x2); + const auto yt = cl[ik]*t*t; + y += yt; + dy += cnl[ik]*yt*t; + } + dy = T(-4)*x*dy; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_fxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl) + { + auto y = fcn_feg(x, cl, cnl); + y = Z - x*x*y; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_fxg_dfxg(const T& x, const T& Z, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_feg_dfeg(x, cl, cnl, y, dy); + dy = -x*(T(2)*y + x*dy); + y = Z - x*x*y; + } + + /***************************************************************************************/ + template + using pFcn_fxg1 = pFcn_clnl_4_1; + + template + GPU_EXEC pFcn_fxg1 pgpu_fcn_fxg = fcn_fxg; + + pFCN_TEMPLATE_AF(fxg, pFcn_fxg1); + + template + GPU_EXEC pFcn_clnl_3_1 pgpu_fcn_fxg_spec = fcn_fxg; + + pFCN_TEMPLATE_AF_SPEC(fxg, pFcn_clnl_3_1, eappt_weickenmeier_0_12); + + pFCN_TEMPLATE_AF_SPEC(fxg, pFcn_clnl_3_1, eappt_lobato_0_12); + + /***************************************************************************************/ + template + using pFcn_fxg2 = pFcn_clnl_4_2; + + template + GPU_EXEC pFcn_fxg2 pgpu_fcn_fxg_dfxg = fcn_fxg_dfxg; + + pFCN_TEMPLATE_AF(fxg_dfxg, pFcn_fxg2); + + template + GPU_EXEC pFcn_clnl_3_2 pgpu_fcn_fxg_dfxg_spec = fcn_fxg_dfxg; + + pFCN_TEMPLATE_AF_SPEC(fxg_dfxg, pFcn_clnl_3_2, eappt_weickenmeier_0_12); + + pFCN_TEMPLATE_AF_SPEC(fxg_dfxg, pFcn_clnl_3_2, eappt_lobato_0_12); + + /***************************************************************************************/ + /****************************************** pr *****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_pr_gauss_feg_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_pr_gauss_feg_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_yukawa_v(x, 0, 3, cl, cnl) + fcn_spt_pr_gauss_feg_v(x, 3, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_yukawa_vd(x, 0, 3, cl, cnl, y, dy); + fcn_spt_pr_gauss_feg_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_exp_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_exp_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_pr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_pr_gauss_feg_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_pr_dpr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_pr_gauss_feg_vd(x, 0, 5, cl, cnl, y, dy); + } + + /***************************************************************************************/ + template + using pFcn_pr1 = pFcn_clnl_3_1; + + template + GPU_EXEC pFcn_pr1 pgpu_fcn_pr = fcn_pr; + + pFCN_TEMPLATE_AF(pr, pFcn_pr1); + + /***************************************************************************************/ + template + using pFcn_pr2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_pr2 pgpu_fcn_pr_dpr = fcn_pr_dpr; + + pFCN_TEMPLATE_AF(pr_dpr , pFcn_pr2); + + /***************************************************************************************/ + /***************************************** vr ******************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_yukawa_v(x, 0, 3, cl, cnl) + fcn_spt_gauss_v(x, 3, 6, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_yukawa_vd(x, 0, 3, cl, cnl, y, dy); + fcn_spt_gauss_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + const T ix = T(1)/x; + + T y = 0; + + for(auto ik = 0; ik <6; ik++) + { + y += cl[ik]*erfc(cnl[ik]*x)*ix; + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T c_pii2 = 1.772453850905516027298; + const T ix = T(1)/x; + const T x2 = x*x; + + y = dy = 0; + + for(auto ik = 0; ik <6; ik++) + { + const auto yt = cl[ik]*erfc(cnl[ik]*x)*ix; + y += yt; + dy += (T(-2)*cl[ik]*cnl[ik]*exp(-cnl[ik]*cnl[ik]*x2)/c_pii2-yt)*ix; + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + const T ix = T(1)/x; + + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + y += cl[ik]*exp(-cnl[ik]*x)*ix*(T(2)/cnl[ik] + x); + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + const T ix = T(1)/x; + + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto yt = cl[ik]*exp(-cnl[ik]*x)*ix; + const auto icnl = T(1)/cnl[ik]; + y += yt*(T(2)*icnl + x); + dy += -yt*(T(2)*icnl*ix + T(2) + cnl[ik]*x); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vr(const T& x, Ctpr cl, Ctpr cnl) + { + auto y = fcn_spt_gauss_v(x, 0, 5, cl, cnl); + y += cl[5]*exp(-cnl[5]*x)/x; + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vr_dvr(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + const auto ix = T(1)/x; + const auto yt = cl[5]*exp(-cnl[5]*x)*ix; + y += yt; + dy += -(cnl[5]+ ix)*yt; + } + + /***************************************************************************************/ + template + using pFcn_vr1 = pFcn_clnl_3_1; + + template + GPU_EXEC pFcn_vr1 pgpu_fcn_vr = fcn_vr; + + pFCN_TEMPLATE_AF(vr, pFcn_vr1); + + /***************************************************************************************/ + template + using pFcn_vr2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_vr2 pgpu_fcn_vr_dvr = fcn_vr_dvr; + + pFCN_TEMPLATE_AF(vr_dvr , pFcn_vr2); + + /***************************************************************************************/ + /***************************************** vz ******************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + T fcn_vz(const T& x, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw) + { + return fcn_int_vz_z0_ze(x, z_0, z_e, cl, cnl, n_q, qx, qw, fcn_vr); + } + + template + CGPU_EXEC_INL + void fcn_vz_dvz(const T& x, const T& z_0, const T& z_e, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& y, T& dy) + { + fcn_int_vz_dvz_z0_ze(x, z_0, z_e, cl, cnl, n_q, qx, qw, y, dy, fcn_vr_dvr); + } + + /***************************************************************************************/ + template + using pFcn_vz1 = pFcn_clnl_8_1; + + template + GPU_EXEC pFcn_vz1 pgpu_fcn_vz = fcn_vz; + + pFCN_TEMPLATE_AF(vz, pFcn_vz1); + + /***************************************************************************************/ + template + using pFcn_vz2 = pFcn_clnl_8_2; + + template + GPU_EXEC pFcn_vz2 pgpu_fcn_vz_dvz = fcn_vz_dvz; + + pFCN_TEMPLATE_AF(vz_dvz , pFcn_vz2); + + /***************************************************************************************/ + /****************************************** vzp *****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 4, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_doyle_0_4 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 4, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_4 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + return fcn_spt_gauss_v(x, 0, 5, cl, cnl); + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + T y = 0; + + for(auto ik = 0; ik <3; ik++) + { + y += cl[ik]*bessel_k0(cnl[ik]*x); + } + + y += fcn_spt_gauss_v(x, 3, 6, cl, cnl); + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_kirkland_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + y = dy = 0; + + for(auto ik = 0; ik <3; ik++) + { + y += cl[ik]*bessel_k0(cnl[ik]*x); + dy += -cl[ik]*cnl[ik]*bessel_k1(cnl[ik]*x); + } + + fcn_spt_gauss_vd(x, 3, 6, cl, cnl, y, dy); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw) + { + return fcn_int_vz_ninfty_pinfty(x, cl, cnl, n_q, qx, qw, fcn_vr); + } + + template + CGPU_EXEC_INL + enable_if_eappt_weickenmeier_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, const dt_int32& n_q, Ctpr qx, Ctpr qw, T& y, T& dy) + { + fcn_int_vz_dvz_ninfty_pinfty(x, cl, cnl, n_q, qx, qw, y, dy, fcn_vr_dvr); + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + T y = 0; + + for(auto ik = 0; ik <5; ik++) + { + y += cl[ik]*(T(2)*bessel_k0(cnl[ik]*x)/cnl[ik] + x*bessel_k1(cnl[ik]*x)); + } + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_lobato_0_12 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + y = dy = 0; + + for(auto ik = 0; ik <5; ik++) + { + const auto k0 = bessel_k0(cnl[ik]*x); + const auto k1 = bessel_k1(cnl[ik]*x); + y += cl[ik]*(T(2)*k0/cnl[ik] + x*k1); + dy += -cl[ik]*(cnl[ik]*x*k0 + T(2)*k1); + } + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vzp(const T& x, Ctpr cl, Ctpr cnl) + { + auto y = fcn_spt_gauss_v(x, 0, 5, cl, cnl); + y += cl[5]*bessel_k0(cnl[5]*x); + + return y; + } + + template + CGPU_EXEC_INL + enable_if_eappt_peng_ion_0_4 + fcn_vzp_dvzp(const T& x, Ctpr cl, Ctpr cnl, T& y, T& dy) + { + fcn_spt_gauss_vd(x, 0, 5, cl, cnl, y, dy); + y += cl[5]*bessel_k0(cnl[5]*x); + dy += -cl[5]*cnl[5]*bessel_k1(cnl[5]*x); + } + + /***************************************************************************************/ + template + using pFcn_vzp1 = pFcn_clnl_3_1; + + template + GPU_EXEC pFcn_vzp1 pgpu_fcn_vzp = fcn_vzp; + + pFCN_TEMPLATE_AF(vzp, pFcn_vzp1); + + template + GPU_EXEC pFcn_clnl_6_1 pgpu_fcn_vzp_spec = fcn_vzp; + + pFCN_TEMPLATE_AF_SPEC(vzp, pFcn_clnl_6_1, eappt_weickenmeier_0_12); + + /***************************************************************************************/ + template + using pFcn_vzp2 = pFcn_clnl_3_2; + + template + GPU_EXEC pFcn_vzp2 pgpu_fcn_vzp_dvzp = fcn_vzp_dvzp; + + pFCN_TEMPLATE_AF(vzp_dvzp, pFcn_vzp2); + + template + GPU_EXEC pFcn_clnl_6_2 pgpu_fcn_vzp_dvzp_spec = fcn_vzp_dvzp; + + pFCN_TEMPLATE_AF_SPEC(vzp_dvzp, pFcn_clnl_6_2, eappt_weickenmeier_0_12); + } + } + + /* detector integration */ + namespace mt + { + namespace cgpu_detail_mt + { + /* integration over a detector ring */ + template + CGPU_EXEC_INL + void fcn_int_det_ring(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_min, const T& g2_max, Ctpr mx_i, KS& sum) + { + const auto g2 = grid.g2_sft(ix, iy); + if (mt::fcn_chk_bound(g2, g2_min, g2_max)) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += mx_i[ixy]; + } + } + + /* norm_2 integration over a detector ring */ + template + CGPU_EXEC_INL + void fcn_int_det_ring_norm_2(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& g2_min, const T& g2_max, Ctpr mx_i, KS>& sum) + { + const auto g2 = grid.g2_sft(ix, iy); + if (mt::fcn_chk_bound(g2, g2_min, g2_max)) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += ::norm_2(mx_i[ixy]); + } + } + + /* integration over a detector with sensitivity */ + template + CGPU_EXEC_INL + void fcn_int_det_sen(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + Ctpr sen_i, Ctpr mx_i, KS& sum) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += sen_i[ixy]*mx_i[ixy]; + } + + /* norm_2 integration over a detector with sensitivity */ + template + CGPU_EXEC_INL + void fcn_int_det_sen_norm_2(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + Ctpr> sen_i, Ctpr mx_i, KS>& sum) + { + const auto ixy = grid.sub_2_ind(ix, iy); + sum += sen_i[ixy]*::norm_2(mx_i[ixy]); + } + } + } + + /* wave propagation */ + namespace mt + { + namespace cgpu_detail_mt + { + /* propagate */ + template + CGPU_EXEC_INL + void fcn_fs_propagate(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g_0, const T& w_g2, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto theta = w_g2*grid.g2_sft(ix, iy, g_0); + + psi_o[ixy] = w*psi_i[ixy]*euler(theta); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + CGPU_EXEC_INL + void fcn_fs_propagate_bw_f(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g_0, const T& w_g2, const T& g2_cut, const T& alpha, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto theta = w_g2*grid.g2_sft(ix, iy, g_0); + const auto m = w*fcn_fermi_lpf(alpha, g2_cut, grid.g2_sft(ix, iy)); // bandwith limit does not mater if it includes till illumination + psi_o[ixy] = m*psi_i[ixy]*euler(theta); + } + + /* propagate and bandwith limit using a hard aperture */ + template + CGPU_EXEC_INL + void fcn_fs_propagate_bw_h(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + complex* psi_i, const R_2d& g_0, const T& w_g2, const T& g2_cut, const T& w, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto theta = w_g2*grid.g2_sft(ix, iy, g_0); + const auto m = ((grid.g2_sft(ix, iy) <= g2_cut))?w:T(0); // bandwith limit does not mater if it includes till illumination + psi_o[ixy] = m*psi_i[ixy]*euler(theta); + } + } + } + + /* probe - ctf - pctf */ + namespace mt + { + namespace cgpu_detail_mt + { + /* create probe */ + template + CGPU_EXEC_INL + complex fcn_fs_exp_i_chi(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const Lens& lens, + const R_2d& R, const R_2d& gu) + { + const auto gx = grid.gx_sft(ix) + gu.x; + const auto gy = grid.gy_sft(iy) + gu.y; + const auto g2 = gx*gx + gy*gy; + + complex v = 0; + + if (fcn_chk_bound(g2, lens.g2_inner, lens.g2_outer)) + { + const auto g4 = g2*g2; + const auto g6 = g4*g2; + const auto chi = R.x*gx + R.y*gy + lens.eval_c_10(g2) + lens.eval_c_30(g4) + lens.eval_c_50(g6); + + if (bb_phi) + { + const auto g =::sqrt(g2); + const auto g3 = g2*g; + const auto g5 = g4*g; + const auto phi = atan2(gy, gx); + chi += lens.eval_m(phi) + lens.eval_c_12(g2, phi); + chi += lens.eval_c_21_c_23(g3, phi) + lens.eval_c_32_c_34(g4, phi); + chi += lens.eval_c_41_c_43_c_45(g5, phi) + lens.eval_c_52_c_54_c_56(g6, phi); + } + + v = euler(chi); + } + + return v; + } + + /* create probe */ + template + CGPU_EXEC_INL + void fcn_fs_probe(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const Lens& lens, + const R_2d& r, const R_2d& gu, complex* psi_o) + { + const auto v = fcn_fs_exp_i_chi(ix, iy, grid, lens, r, gu); + + const auto ixy = grid.sub_2_ind(ix, iy); + psi_o[ixy] = v; + } + + /* apply coherent transfer function */ + template + CGPU_EXEC_INL + void fcn_fs_apply_ctf(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, complex* psi_i, + const Lens& lens, const R_2d& gu, complex* psi_o) + { + const auto v = fcn_fs_exp_i_chi(ix, iy, grid, lens, R_2d(), gu); + + const auto ixy = grid.sub_2_ind(ix, iy); + psi_o[ixy] = v*psi_i[ixy]; + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + CGPU_EXEC_INL + void fcn_fs_apply_pctf(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, complex* psi_i, + const Lens& lens, complex* psi_o) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto g2 = grid.g2_sft(ix, iy); + + if (fcn_chk_bound(g2, lens.g2_inner, lens.g2_outer)) + { + const auto c_pi = T(3.141592653589793238463); + + const auto chi = lens.eval_c_10(g2) + lens.eval_c_30(g2*g2); + const auto c_u = c_pi*lens.spt_inc_theta_c*lens.tp_inc_iehwgd; + const auto u = T(1) + T(2)*c_u*c_u*g2; + + const auto c_tp = c_pi*lens.tp_inc_iehwgd*lens.lambda*g2; + const auto tp_inc = T(0.5)*c_tp*c_tp*g2*g2; + + const auto c_spt = c_pi*lens.spt_inc_iehwgd*(lens.c_30*lens.lambda_2*g2-lens.c_10); + const auto spt_inc = c_spt*c_spt*g2; + + const auto st_inc = exp(-(spt_inc + tp_inc)/u); // sqrt(u); + + psi_o[ixy] = psi_i[ixy]*polar(st_inc, chi); + } + else + { + psi_o[ixy] = T(0); + } + } + } + } + + /* transmission function */ + namespace mt + { + namespace cgpu_detail_mt + { + template + CGPU_EXEC_INL + void fcn_trans_fcn(const dt_int32& ix, const iGrid_1d& igrid, Ctpr* vzp_i, const T& w, complex* tfcn_o) + { + const auto ind = igrid.sub_2_ind(ix); + + if (esim == eesim_weak_phase_object) + { + tfcn_o[ind] =complex(T(1), w*vzp_i[ind]); + } + else + { + tfcn_o[ind] =euler(w*vzp_i[ind]); + } + } + } + } + + /* eels */ + namespace mt + { + namespace cgpu_detail_mt + { + template + CGPU_EXEC_INL + void fcn_eels_lorentz_norm_factor(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const T& gc2, const T& ge2, KS& sum) + { + const auto g2 = grid.g2_sft(ix, iy); + if (g2 < gc2) + { + sum += T(1)/(g2 + ge2); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_xyz(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, + const EELS& eels, Tpr> w_x, Tpr> w_y, Tpr> w_z) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_x[ixy] = gx*lorentz*pos; + w_y[ixy] = gy*lorentz*pos; + w_z[ixy] = eels.ge*lorentz*pos; + } + else + { + w_x[ixy] = complex(0); + w_y[ixy] = complex(0); + w_z[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_x(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_x) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_x[ixy] = gx*lorentz*pos; + } + else + { + w_x[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_y(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_y) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_y[ixy] = gy*lorentz*pos; + } + else + { + w_y[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_z(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_z) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = eels.factor/(g2 + eels.ge2); + w_z[ixy] = eels.ge*lorentz*pos; + } + else + { + w_z[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_mn1(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_mn1) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto c_i2i2 = T(0.70710678118654746); + + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = c_i2i2*eels.factor/(g2 + eels.ge2); + w_mn1[ixy] = complex(gx, -gy)*lorentz*pos; + } + else + { + w_mn1[ixy] = complex(0); + } + } + + template + CGPU_EXEC_INL + void fcn_eels_w_mp1(const dt_int32& ix, const dt_int32& iy, const Grid_2d& grid, const EELS& eels, Tpr> w_mp1) + { + const auto ixy = grid.sub_2_ind(ix, iy); + const auto gx = grid.gx_sft(ix); + const auto gy = grid.gy_sft(iy); + const auto g2 = gx*gx + gy*gy; + + if (g2 < eels.gc2) + { + const auto c_i2i2 = T(0.70710678118654746); + + const auto pos = euler(eels.x*gx + eels.y*gy); + const auto lorentz = c_i2i2*eels.factor/(g2 + eels.ge2); + w_mp1[ixy] = complex(gx, gy)*lorentz*pos; + } + else + { + w_mp1[ixy] = complex(0); + } + } + } + } + +#endif diff --git a/src/cgpu_fcns.cuh b/src/cgpu_fcns.cuh old mode 100644 new mode 100755 index 0de54047..488820f5 --- a/src/cgpu_fcns.cuh +++ b/src/cgpu_fcns.cuh @@ -1,3417 +1,89 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef CGPU_FCNS_H -#define CGPU_FCNS_H - -#include -#include - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "lin_alg_def.cuh" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mt -{ - // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 - // Input: E_0(keV), Output: lambda (electron wave) - template - DEVICE_CALLABLE FORCE_INLINE - T get_lambda(const T &E_0) - { - T emass = 510.99906; - T hc = 12.3984244; - T lambda = hc/sqrt(E_0*(2*emass + E_0)); - return lambda; - } - - // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 - // Input: E_0(keV), Output: sigma (Interaction parameter) - template - DEVICE_CALLABLE FORCE_INLINE - T get_sigma(const T &E_0) - { - const T c_Pi = 3.141592653589793238463; - T emass = 510.99906; - T x = (emass + E_0)/(2*emass + E_0); - T sigma = 2*c_Pi*x/(get_lambda(E_0)*E_0); - return sigma; - } - - // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 - // Input: E_0(keV), Output: gamma(relativistic factor) - template - DEVICE_CALLABLE FORCE_INLINE - T get_gamma(const T &E_0) - { - T emass = 510.99906; - T gamma = 1 + E_0/emass; - return gamma; - } - - // Input: theta(mrad), E_0(keV), Output: A^-1 - template - DEVICE_CALLABLE FORCE_INLINE - T rad_2_rAngs(const T &E_0, const T &theta) - { - return sin(theta)/get_lambda(E_0); - } - - // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 - // hwhm: Half width at half maximum - // sigma: Standard deviation - template - DEVICE_CALLABLE FORCE_INLINE - T hwhm_2_sigma(const T &v) - { - T c_hwhm_2_sigma = 0.84932180028801907; // hwhm to sigma 1/(sqrt(2*log(2))) - return v*c_hwhm_2_sigma; - } - - // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 - // fwhm: Full width at half maximum - // sigma: Standard deviation - template - DEVICE_CALLABLE FORCE_INLINE - T fwhm_2_sigma(const T &v) - { - T c_fwhm_2_sigma = 0.42466090014400953; // fwhm to sigma 1/(2*sqrt(2*log(2))) - return v*c_fwhm_2_sigma; - } - - // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 - // iehwgd: e^-1 half-width value of the Gaussian distribution - // sigma: Standard deviation - template - DEVICE_CALLABLE FORCE_INLINE - T iehwgd_2_sigma(const T &v) - { - T c_iehwgd_2_sigma = 0.70710678118654746; // iehwgd to sigma 1/sqrt(2) - return v*c_iehwgd_2_sigma; - } - - // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 - // sigma: Standard deviation - template - DEVICE_CALLABLE FORCE_INLINE - T rad_2_sigma(const T &E_0, const T &theta) - { - T q0 = sin(theta)/get_lambda(E_0); - return iehwgd_2_sigma(q0); - } - - // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 - // Input: E_0(keV), Output: gamma*lambda/c_Potf - template - DEVICE_CALLABLE FORCE_INLINE - T get_Vr_factor(const T &E_0, const T &theta) - { - T c_Potf = 47.877645145863056; - T fPot = get_gamma(E_0)*get_lambda(E_0)/(c_Potf*cos(theta)); - return fPot; - } - - // E. J. Kirkland - Advanced computing in electron microscopy page: 33 - template - DEVICE_CALLABLE FORCE_INLINE - T get_Scherzer_defocus(const T &E_0, const T &c_30) - { - T lambda = get_lambda(E_0); - T n = 1.0; - return -copysign(sqrt((2*n-0.5)*fabs(c_30)*lambda), c_30); - } - - // E. J. Kirkland - Advanced computing in electron microscopy page: 33 - template - DEVICE_CALLABLE FORCE_INLINE - T get_Scherzer_aperture(const T &E_0, const T &c_30) - { - T lambda = get_lambda(E_0); - T n = 1.0; - return pow(4*(2*n-0.5)*lambda/fabs(c_30), 0.25); - } - - // E. J. Kirkland - Advanced computing in electron microscopy page: 33 - template - DEVICE_CALLABLE FORCE_INLINE - void get_Scherzer_conditions(const T &E_0, const T &c_30, T &defocus, T &aperture) - { - defocus = get_Scherzer_defocus(E_0, c_30); - aperture = get_Scherzer_aperture(E_0, c_30); - } - - // new size - template - DEVICE_CALLABLE FORCE_INLINE - int get_new_size(const int &n, T factor) - { - return max(static_cast(ceil(n*factor)), 1); - } - - template - FORCE_INLINE - Vector get_rotation_matrix(const T &theta, const r3d &u0) - { - Vector Rm(9); - T alpha = 1-cos(theta); - alpha = (isZero(alpha)?0:alpha); - T beta = sin(theta); - beta = (isZero(beta)?0:beta); - Rm[0] = 1.0 + alpha*(u0.x*u0.x-1); - Rm[1] = u0.y*u0.x*alpha + u0.z*beta; - Rm[2] = u0.z*u0.x*alpha - u0.y*beta; - - Rm[3] = u0.x*u0.y*alpha - u0.z*beta; - Rm[4] = 1.0 + alpha*(u0.y*u0.y-1); - Rm[5] = u0.z*u0.y*alpha + u0.x*beta; - - Rm[6] = u0.x*u0.z*alpha + u0.y*beta; - Rm[7] = u0.y*u0.z*alpha - u0.x*beta; - Rm[8] = 1.0 + alpha*(u0.z*u0.z-1); - return Rm; - } - - // distance from point to line - template - DEVICE_CALLABLE FORCE_INLINE - T get_dist_from_p2l(const T &a, const T &b, const T &c, const T &x0, const T &y0) - { - return fabs(a*x0+b*y0+c)/sqrt(a*a+b*b); - } - - // calculate intersection points - template - DEVICE_CALLABLE FORCE_INLINE - void get_int_pt_from_p2l(const T &a, const T &b, const T &c, const T &x0, const T &y0, const T &x, const T &y) - { - x = (b*(b*x0-a*y0)-a*c)/(a*a+b*b); - y = -(a*(b*x0-a*y0)-b*c)/(a*a+b*b); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T m_bound(const T &x_0, const T &x, const T &x_e) - { - return max(x_0, min(x, x_e)); - } - - template - void synchronize_every(int i_sync, int n_sync) - { - - } - -#ifdef __CUDACC__ - template <> - void synchronize_every(int i_sync, int n_sync) - { - if(i_sync % n_sync == 0) - { - cudaDeviceSynchronize(); - } - } -#endif - - namespace host_device_detail - { - // Kahan summation algorithm - // https:// en.wikipedia.org/wiki/Kahan_summation_algorithm - template - DEVICE_CALLABLE FORCE_INLINE - void kh_sum(T &sum_v, T v, T &error) - { - v = v - error; - T t = sum_v + v; - error = (t-sum_v)-v; - sum_v = t; - } - - template - inline - T Root_Finder(TFn fn, T x0, T xe, const T Tol = 1e-8, const int itMax = 200) - { - int it = 0; - T x, fx, fxe = fn(xe); - - do - { - x = 0.5*(x0 + xe); - fx = fn(x); - - if(fx*fxe<0) - { - x0 = x; - } - else - { - xe = x; - fxe = fx; - } - it++; - }while((fabs(fx)>Tol) && (it < itMax)); - - return x; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void int_fx_x0_xe(TFn fn, const Value_type &x0, const Value_type &xe, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rq1, Value_type &y) - { - Value_type a = 0.5*(xe-x0); - Value_type b = 0.5*(xe+x0); - Value_type xi, yi; - y = 0; - - for(auto i = 0; i< rq1.m_size; i++) - { - xi = a*rq1.x[i] + b; - fn(xi, rcoef, yi); - y += a*rq1.w[i]*yi; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void int_fx_x0_xe(TFn fn, const Value_type &x0, const Value_type &xe, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rq1, Value_type &y1, Value_type &y2) - { - Value_type a = 0.5*(xe-x0); - Value_type b = 0.5*(xe+x0); - Value_type xi, y1i, y2i; - y1 = y2 = 0; - - for(auto i = 0; i< rq1.m_size; i++) - { - xi = a*rq1.x[i] + b; - fn(xi, rcoef, y1i, y2i); - y1 += a*rq1.w[i]*y1i; - y2 += a*rq1.w[i]*y2i; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void int_fx_x0_pInfty(TFn fn, const Value_type &x0, const Value_type &x, const TrPP_Coef &rcoef, TrQ1&rq1, Value_type &y) - { - using T = Value_type; - T xi, yi; - y = 0; - - for(auto i = 0; i< rq1.m_size; i++) - { - xi = rq1.x[i] + x0; - fn(xi, rcoef, yi); - y += rq1.w[i]*yi; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void int_fx_x0_pInfty(TFn fn, const Value_type &x0, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rq1, Value_type &y1, Value_type &y2) - { - using T = Value_type; - T xi, y1i, y2i; - y1 = y2 = 0; - - for(auto i = 0; i< rq1.m_size; i++) - { - xi = rq1.x[i] + x0; - fn(xi, rcoef, y1i, y2i); - y1 += rq1.w[i]*y1i; - y2 += rq1.w[i]*y2i; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void int_Vz_z0_ze(TFn fn, const Value_type &z0, const Value_type &ze, const Value_type &R, const TrPP_Coef &rcoef, const TrQ1 &rq1, Value_type &y) - { - using T = Value_type; - bool split = (z0<0) && (0 - DEVICE_CALLABLE FORCE_INLINE - void int_Vz_dVz_z0_ze(TFn fn, const Value_type &z0, const Value_type &ze, const Value_type &R, const TrPP_Coef &rcoef, const TrQ1 &rq1, Value_type &y, Value_type &dy) - { - using T = Value_type; - bool split = (z0<0) && (0 - DEVICE_CALLABLE FORCE_INLINE - void int_VR(TFn fn, const Value_type &R, const TrPP_Coef &rcoef, const TrQ1 &rq1, Value_type &y) - { - using T = Value_type; - T zi, ri, yi, R2 = R*R; - y = 0; - for(auto i = 0; i< rq1.m_size; i++) - { - zi = rq1.x[i]; - ri = sqrt(zi*zi + R2); - fn(ri, rcoef, yi); - y += rq1.w[i]*yi; - } - y *= 2; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void int_VR_dVR(TFn fn, const Value_type &R, const TrPP_Coef &rcoef, const TrQ1 &rq1, Value_type &y, Value_type &dy) - { - using T = Value_type; - T zi, ri, yi, dyi, R2 = R*R; - y = dy = 0; - for(auto i = 0; i< rq1.m_size; i++) - { - zi = rq1.x[i]; - ri = sqrt(zi*zi + R2); - fn(ri, rcoef, yi, dyi); - y += rq1.w[i]*yi; - dy += R*rq1.w[i]*dyi/ri; - } - y *= 2; - dy *= 2; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Exponential_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, bool reset = true) - { - if(reset) - { - y = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += rcoef.cl[i]*exp(-rcoef.cnl[i]*x); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Exponential_dExponential_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy, bool reset = true) - { - using T = Value_type; - T yt; - if(reset) - { - y = dy = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += yt = rcoef.cl[i]*exp(-rcoef.cnl[i]*x); - dy += -rcoef.cnl[i]*yt; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Gauss_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, bool reset = true) - { - using T = Value_type; - T x2 = x*x; - if(reset) - { - y = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += rcoef.cl[i]*exp(-rcoef.cnl[i]*x2); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Gauss_dGauss_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy, bool reset = true) - { - using T = Value_type; - T yt, x2 = x*x; - if(reset) - { - y = dy = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += yt = rcoef.cl[i]*exp(-rcoef.cnl[i]*x2); - dy += -2*rcoef.cnl[i]*x*yt; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Lorentzian_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, bool reset = true) - { - using T = Value_type; - T x2 = x*x; - if(reset) - { - y = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += rcoef.cl[i]/(rcoef.cnl[i] + x2); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Lorentzian_dLorentzian_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy, bool reset = true) - { - Value_type t, yt, x2 = x*x; - if(reset) - { - y = dy = 0; - } - for(auto i = n_0; i< n_e; i++) - { - t = 1/(rcoef.cnl[i] + x2); - y += yt = rcoef.cl[i]*t; - dy += -2*x*yt*t; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Yukawa_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, bool reset = true) - { - using T = Value_type; - T ix = 1/x; - if(reset) - { - y = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += rcoef.cl[i]*exp(-rcoef.cnl[i]*x)*ix; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_Yukawa_dYukawa_Fn(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy, bool reset = true) - { - using T = Value_type; - T yt, ix = 1/x; - if(reset) - { - y = dy = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += yt = rcoef.cl[i]*exp(-rcoef.cnl[i]*x)*ix; - dy += -(rcoef.cnl[i]+ ix)*yt; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Gauss_feg(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, bool reset = true) - { - using T = Value_type; - T x2 = x*x; - if(reset) - { - y = 0; - } - for(auto i = n_0; i< n_e; i++) - { - y += (2*x2 - 3/rcoef.cnl[i])*rcoef.cl[i]*exp(-rcoef.cnl[i]*x2); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Gauss_feg(const Value_type &x, const int &n_0, const int &n_e, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy, bool reset = true) - { - using T = Value_type; - T yt, x2 = x*x; - if(reset) - { - y = dy = 0; - } - for(auto i = n_0; i< n_e; i++) - { - yt = rcoef.cl[i]*exp(-rcoef.cnl[i]*x2); - y += (2*x2 - 3/rcoef.cnl[i])*yt; - dy += -2*x*(2*rcoef.cnl[i]*x2 - 5)*yt; - } - } - - /***************************************************************************/ - /***************************************************************************/ - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 4, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 4, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Lorentzian_Fn(x, 0, 3, rcoef, y); - add_Gauss_Fn(x, 3, 6, rcoef, y, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Lorentzian_dLorentzian_Fn(x, 0, 3, rcoef, y, dy); - add_Gauss_dGauss_Fn(x, 3, 6, rcoef, y, dy, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - using T = Value_type; - T x2 = x*x; - - y = 0; - if(nonZero(x)) - { - for(auto i = 0; i< 6; i++) - { - y += rcoef.cl[i]*(1-exp(-rcoef.cnl[i]*x2)); - } - y = y/x2; - } - else - { - for(auto i = 0; i< 6; i++) - { - y += rcoef.cl[i]*rcoef.cnl[i]; - } - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - T t, x2 = x*x; - y = dy = 0; - if(nonZero(x)) - { - for(auto i = 0; i< 6; i++) - { - t = exp(-rcoef.cnl[i]*x2); - y += rcoef.cl[i]*(1-t); - dy += rcoef.cl[i]*(1-(1+rcoef.cnl[i]*x2)*t); - } - y = y/x2; - dy = -2*dy/(x*x2); - } - else - { - for(auto i = 0; i< 6; i++) - { - y += rcoef.cl[i]*rcoef.cnl[i]; - } - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - using T = Value_type; - T t, x2 = x*x; - y = 0; - for(auto i = 0; i< 5; i++) - { - t = 1/(1 + rcoef.cnl[i]*x2); - y += rcoef.cl[i]*t*(t + 1); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - T t, x2 = x*x; - y = dy = 0; - for(auto i = 0; i< 5; i++) - { - t = 1/(1 + rcoef.cnl[i]*x2); - y += rcoef.cl[i]*t*(t + 1); - dy += -2*x*rcoef.cl[i]*rcoef.cnl[i]*t*t*(2*t + 1); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - y += rcoef.cl[5]/(rcoef.cnl[5] + x*x); - - } - - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - T yt, t = 1/(rcoef.cnl[5] + x*x); - y += yt = rcoef.cl[5]*t; - dy += -2*x*yt*t; - } - - /***************************************************************************/ - /***************************************************************************/ - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_Doyle_neutral_0_4(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - feg_Doyle_neutral_0_4(x, rcoef, y); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg_Doyle_neutral_0_4(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - feg_dfeg_Doyle_neutral_0_4(x, rcoef, y, dy); - dy = -x*(2*y + x*dy); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_Peng_neutral_0_4(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - feg_Peng_neutral_0_4(x, rcoef, y); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg_Peng_neutral_0_4(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - feg_dfeg_Peng_neutral_0_4(x, rcoef, y, dy); - dy = -x*(2*y + x*dy); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_Peng_neutral_0_12(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - feg_Peng_neutral_0_12(x, rcoef, y); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg_Peng_neutral_0_12(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - feg_dfeg_Peng_neutral_0_12(x, rcoef, y, dy); - dy = -x*(2*y + x*dy); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_Kirkland_neutral_0_12(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - feg_Kirkland_neutral_0_12(x, rcoef, y); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg_Kirkland_neutral_0_12(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - feg_dfeg_Kirkland_neutral_0_12(x, rcoef, y, dy); - dy = -x*(2*y + x*dy); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 6, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 6, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - using T = Value_type; - T t, x2 = x*x; - y = 0; - for(auto i = 0; i< 5; i++) - { - t = 1/(1+rcoef.cnl[i]*x2); - y += rcoef.cl[i]*t*t; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - T t, yt, x2 = x*x; - y = dy = 0; - for(auto i = 0; i< 5; i++) - { - t = 1/(1+rcoef.cnl[i]*x2); - y += yt = rcoef.cl[i]*t*t; - dy += rcoef.cnl[i]*yt*t; - } - dy = -4*x*dy; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_Peng_ion_0_4(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - feg_Peng_neutral_0_4(x, rcoef, y); - y = Z - x*x*y; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg_Peng_ion_0_4(const int &Z, const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - feg_dfeg_Peng_neutral_0_4(x, rcoef, y, dy); - dy = -x*(2*y + x*dy); - y = Z - x*x*y; - } - /***************************************************************************/ - /***************************************************************************/ - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - Pr_Gauss_feg(x, 0, 4, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - Pr_dPr_Gauss_feg(x, 0, 4, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - Pr_Gauss_feg(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - Pr_dPr_Gauss_feg(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - Pr_dPr_Gauss_feg(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Yukawa_Fn(x, 0, 3, rcoef, y); - Pr_Gauss_feg(x, 3, 6, rcoef, y, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Yukawa_dYukawa_Fn(x, 0, 3, rcoef, y, dy); - Pr_dPr_Gauss_feg(x, 3, 6, rcoef, y, dy, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 6, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 6, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Exponential_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Exponential_dExponential_Fn(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - Pr_Gauss_feg(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - Pr_dPr_Gauss_feg(x, 0, 5, rcoef, y, dy); - } - - /***************************************************************************/ - /***************************************************************************/ - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 4, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 4, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Yukawa_Fn(x, 0, 3, rcoef, y); - add_Gauss_Fn(x, 3, 6, rcoef, y, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Yukawa_dYukawa_Fn(x, 0, 3, rcoef, y, dy); - add_Gauss_dGauss_Fn(x, 3, 6, rcoef, y, dy, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - using T = Value_type; - T ix = 1/x; - y = 0; - - for(auto i = 0; i< 6; i++) - { - y += rcoef.cl[i]*erfc(rcoef.cnl[i]*x)*ix; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - const T c_Pii2 = 1.772453850905516027298; - T yt, ix = 1/x, x2 = x*x; - y = dy = 0; - - for(auto i = 0; i< 6; i++) - { - y += yt = rcoef.cl[i]*erfc(rcoef.cnl[i]*x)*ix; - dy += (-2*rcoef.cl[i]*rcoef.cnl[i]*exp(-rcoef.cnl[i]*rcoef.cnl[i]*x2)/c_Pii2-yt)*ix; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - using T = Value_type; - T ix = 1/x; - y = 0; - for(auto i = 0; i< 5; i++) - { - y += rcoef.cl[i]*exp(-rcoef.cnl[i]*x)*ix*(2/rcoef.cnl[i] + x); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - T yt, icnl, ix = 1/x; - y = dy = 0; - for(auto i = 0; i< 5; i++) - { - yt = rcoef.cl[i]*exp(-rcoef.cnl[i]*x)*ix; - icnl = 1/rcoef.cnl[i]; - y += yt*(2*icnl + x); - dy += -yt*(2*icnl*ix + 2 + rcoef.cnl[i]*x); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - y += rcoef.cl[5]*exp(-rcoef.cnl[5]*x)/x; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - T yt, ix = 1/x; - y += yt = rcoef.cl[5]*exp(-rcoef.cnl[5]*x)*ix; - dy += -(rcoef.cnl[5]+ ix)*yt; - } - - /***************************************************************************/ - /***************************************************************************/ - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 4, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR_Doyle_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 4, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR_Peng_neutral_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR_Peng_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - y = 0; - for(auto i = 0; i< 3; i++) - { - y += rcoef.cl[i]*bessel_k0(rcoef.cnl[i]*x); - } - - add_Gauss_Fn(x, 3, 6, rcoef, y, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR_Kirkland_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - y = dy = 0; - for(auto i = 0; i< 3; i++) - { - y += rcoef.cl[i]*bessel_k0(rcoef.cnl[i]*x); - dy += -rcoef.cl[i]*rcoef.cnl[i]*bessel_k1(rcoef.cnl[i]*x); - } - - add_Gauss_dGauss_Fn(x, 3, 6, rcoef, y, dy, false); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_VR(Vr_Weickenmeier_neutral_0_12, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR_Weickenmeier_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_VR_dVR(Vr_dVr_Weickenmeier_neutral_0_12, x, rcoef, rqz, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - y = 0; - for(auto i = 0; i< 5; i++) - { - y += rcoef.cl[i]*(2*bessel_k0(rcoef.cnl[i]*x)/rcoef.cnl[i] + x*bessel_k1(rcoef.cnl[i]*x)); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR_Lobato_neutral_0_12(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - using T = Value_type; - y = dy = 0; - for(auto i = 0; i< 5; i++) - { - T k0 = bessel_k0(rcoef.cnl[i]*x); - T k1 = bessel_k1(rcoef.cnl[i]*x); - y += rcoef.cl[i]*(2*k0/rcoef.cnl[i] + x*k1); - dy += -rcoef.cl[i]*(rcoef.cnl[i]*x*k0 + 2*k1); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y) - { - add_Gauss_Fn(x, 0, 5, rcoef, y); - y += rcoef.cl[5]*bessel_k0(rcoef.cnl[5]*x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR_Peng_ion_0_4(const Value_type &x, const TrPP_Coef &rcoef, Value_type &y, Value_type &dy) - { - add_Gauss_dGauss_Fn(x, 0, 5, rcoef, y, dy); - y += rcoef.cl[5]*bessel_k0(rcoef.cnl[5]*x); - dy += -rcoef.cl[5]*rcoef.cnl[5]*bessel_k1(rcoef.cnl[5]*x); - } - - /***************************************************************************/ - /***************************************************************************/ - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_Doyle_neutral_0_4(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_Vz_z0_ze(Vr_Doyle_neutral_0_4, z0, ze, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz_Doyle_neutral_0_4(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_Vz_dVz_z0_ze(Vr_dVr_Doyle_neutral_0_4, z0, ze, x, rcoef, rqz, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_Peng_neutral_0_4(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_Vz_z0_ze(Vr_Peng_neutral_0_4, z0, ze, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz_Peng_neutral_0_4(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_Vz_dVz_z0_ze(Vr_dVr_Peng_neutral_0_4, z0, ze, x, rcoef, rqz, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_Peng_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_Vz_z0_ze(Vr_Peng_neutral_0_12, z0, ze, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz_Peng_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_Vz_dVz_z0_ze(Vr_dVr_Peng_neutral_0_12, z0, ze, x, rcoef, rqz, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_Kirkland_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_Vz_z0_ze(Vr_Kirkland_neutral_0_12, z0, ze, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz_Kirkland_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_Vz_dVz_z0_ze(Vr_dVr_Kirkland_neutral_0_12, z0, ze, x, rcoef, rqz, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_Weickenmeier_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_Vz_z0_ze(Vr_Weickenmeier_neutral_0_12, z0, ze, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz_Weickenmeier_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_Vz_dVz_z0_ze(Vr_dVr_Weickenmeier_neutral_0_12, z0, ze, x, rcoef, rqz, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_Lobato_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_Vz_z0_ze(Vr_Lobato_neutral_0_12, z0, ze, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz_Lobato_neutral_0_12(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_Vz_dVz_z0_ze(Vr_dVr_Lobato_neutral_0_12, z0, ze, x, rcoef, rqz, y, dy); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_Peng_ion_0_4(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y) - { - int_Vz_z0_ze(Vr_Peng_ion_0_4, z0, ze, x, rcoef, rqz, y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz_Peng_ion_0_4(const Value_type &z0, const Value_type &ze, const Value_type &x, const TrPP_Coef &rcoef, const TrQ1 &rqz, Value_type &y, Value_type &dy) - { - int_Vz_dVz_z0_ze(Vr_dVr_Peng_ion_0_4, z0, ze, x, rcoef, rqz, y, dy); - } - /***************************************************************************/ - /***************************************************************************/ - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVrir_Doyle_neutral_0_4(const T &r, T *cl, T *cnl, T &Vr, T &dVrir) - { - T r2 = r*r; - - T Vr0 = cl[0]*exp(-cnl[0]*r2); - T Vr1 = cl[1]*exp(-cnl[1]*r2); - T Vr2 = cl[2]*exp(-cnl[2]*r2); - T Vr3 = cl[3]*exp(-cnl[3]*r2); - - Vr = Vr0 + Vr1 + Vr2 + Vr3; - dVrir = -2*(cnl[0]*Vr0 + cnl[1]*Vr1 + cnl[2]*Vr2 + cnl[3]*Vr3); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVrir_Peng_neutral_0_4_12(const T &r, T *cl, T *cnl, T &Vr, T &dVrir) - { - T r2 = r*r; - - T Vr0 = cl[0]*exp(-cnl[0]*r2); - T Vr1 = cl[1]*exp(-cnl[1]*r2); - T Vr2 = cl[2]*exp(-cnl[2]*r2); - T Vr3 = cl[3]*exp(-cnl[3]*r2); - T Vr4 = cl[4]*exp(-cnl[4]*r2); - - Vr = Vr0 + Vr1 + Vr2 + Vr3 + Vr4; - dVrir = -2*(cnl[0]*Vr0 + cnl[1]*Vr1 + cnl[2]*Vr2 + cnl[3]*Vr3 + cnl[4]*Vr4); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVrir_Kirkland_neutral_0_12(const T &r, T *cl, T *cnl, T &Vr, T &dVrir) - { - T ir = 1/r; - T r2 = r*r; - - T Vr0 = cl[0]*exp(-cnl[0]*r)*ir; - T Vr1 = cl[1]*exp(-cnl[1]*r)*ir; - T Vr2 = cl[2]*exp(-cnl[2]*r)*ir; - T Vr3 = cl[3]*exp(-cnl[3]*r2); - T Vr4 = cl[4]*exp(-cnl[4]*r2); - T Vr5 = cl[5]*exp(-cnl[5]*r2); - - Vr = Vr0 + Vr1 + Vr2 + Vr3 + Vr4 + Vr5; - dVrir = -(Vr0*(cnl[0]+ir) + Vr1*(cnl[1]+ir) + Vr2*(cnl[2]+ir) + 2*r*(cnl[3]*Vr3 + cnl[4]*Vr4 + cnl[5]*Vr5))/r; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVrir_Weickenmeier_neutral_0_12(const T &r, T *cl, T *cnl, T &Vr, T &dVrir) - { - T r2 = r*r; - T c_Pii2 = 1.772453850905516027298; - - T Vr0 = cl[0]*erfc(cnl[0]*r); - T Vr1 = cl[1]*erfc(cnl[1]*r); - T Vr2 = cl[2]*erfc(cnl[2]*r); - T Vr3 = cl[3]*erfc(cnl[3]*r); - T Vr4 = cl[4]*erfc(cnl[4]*r); - T Vr5 = cl[5]*erfc(cnl[5]*r); - - Vr = (Vr0 + Vr1 + Vr2 + Vr3 + Vr4 + Vr5)/r; - dVrir = 2*(cl[0]*cnl[0]*exp(-cnl[0]*cnl[0]*r2) + cl[1]*cnl[1]*exp(-cnl[1]*cnl[1]*r2) + cl[2]*cnl[2]*exp(-cnl[2]*cnl[2]*r2)+ - cl[3]*cnl[3]*exp(-cnl[3]*cnl[3]*r2) + cl[4]*cnl[4]*exp(-cnl[4]*cnl[4]*r2) + cl[5]*cnl[5]*exp(-cnl[5]*cnl[5]*r2))/c_Pii2; - dVrir = -(dVrir + Vr)/r2; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVrir_Lobato_neutral_0_12(const T &r, T *cl, T *cnl, T &Vr, T &dVrir) - { - T cnl0r = cnl[0]*r; - T cnl1r = cnl[1]*r; - T cnl2r = cnl[2]*r; - T cnl3r = cnl[3]*r; - T cnl4r = cnl[4]*r; - - T Vr0 = cl[0]*exp(-cnl0r); - T Vr1 = cl[1]*exp(-cnl1r); - T Vr2 = cl[2]*exp(-cnl2r); - T Vr3 = cl[3]*exp(-cnl3r); - T Vr4 = cl[4]*exp(-cnl4r); - - Vr = Vr0*(2/cnl0r+1) + Vr1*(2/cnl1r+1) + Vr2*(2/cnl2r+1) + Vr3*(2/cnl3r+1)+ Vr4*(2/cnl4r+1); - dVrir = -(Vr + Vr0*(cnl0r+1) + Vr1*(cnl1r+1) + Vr2*(cnl2r+1) + Vr3*(cnl3r+1)+ Vr4*(cnl4r+1))/(r*r); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVrir_Peng_ion_0_4(const T &r, T *cl, T *cnl, T &Vr, T &dVrir) - { - T ir = 1/r; - T r2 = r*r; - - T Vr0 = cl[0]*exp(-cnl[0]*r2); - T Vr1 = cl[1]*exp(-cnl[1]*r2); - T Vr2 = cl[2]*exp(-cnl[2]*r2); - T Vr3 = cl[3]*exp(-cnl[3]*r2); - T Vr4 = cl[4]*exp(-cnl[4]*r2); - T Vr5 = cl[5]*exp(-cnl[5]*r)*ir; - - Vr = Vr0 + Vr1 + Vr2 + Vr3 + Vr4 + Vr5; - dVrir = -2*(cnl[0]*Vr0 + cnl[1]*Vr1 + cnl[2]*Vr2 + cnl[3]*Vr3 + cnl[4]*Vr4)-Vr5*(cnl[5]+ir)/r; - } - - template - DEVICE_CALLABLE FORCE_INLINE - int unrolledBinarySearch_c_nR(const T &x0, const T *x) - { - int i0 = 0, ie = c_nR-1; - int im = (i0 + ie)>>1; // divide by 2 - if(x0 < x[im]) ie = im; else i0 = im; // 64 - im = (i0 + ie)>>1; // divide by 2 - if(x0 < x[im]) ie = im; else i0 = im; // 32 - im = (i0 + ie)>>1; // divide by 2 - if(x0 < x[im]) ie = im; else i0 = im; // 16 - im = (i0 + ie)>>1; // divide by 2 - if(x0 < x[im]) ie = im; else i0 = im; // 8 - im = (i0 + ie)>>1; // divide by 2 - if(x0 < x[im]) ie = im; else i0 = im; // 4 - im = (i0 + ie)>>1; // divide by 2 - if(x0 < x[im]) ie = im; else i0 = im; // 2 - im = (i0 + ie)>>1; // divide by 2 - if(x0 < x[im]) ie = im; else i0 = im; // 1 - - return i0; - } - - // cosine tapering - template - DEVICE_CALLABLE FORCE_INLINE - T tapering(const T &x_tap, const T &alpha, const T &x) - { - return (x_tap - DEVICE_CALLABLE FORCE_INLINE - void apply_tapering(const T &x_tap, const T &alpha, const T &x, T &y, T &dy) - { - if(x_tap - DEVICE_CALLABLE FORCE_INLINE - void cubic_poly_coef(const int &iR, TAtom &atom) - { - auto idR = 1.0/(atom.R2[iR+1]-atom.R2[iR]); - auto V = atom.c0[iR]; - auto Vn = atom.c0[iR+1]; - auto dV = atom.c1[iR]; - auto dVn = atom.c1[iR+1]; - auto m = (Vn-V)*idR; - auto n = dV+dVn; - atom.c2[iR] = (3.0*m-n-dV)*idR; - atom.c3[iR] = (n-2.0*m)*idR*idR; - } - - // Cubic polynomial evaluation - template - DEVICE_CALLABLE FORCE_INLINE - T eval_cubic_poly(const T &R2, const TAtom &atom) - { - const int ix = unrolledBinarySearch_c_nR(R2, atom.R2); - - const T dx = R2 - atom.R2[ix]; - return (((atom.c3[ix]*dx + atom.c2[ix])*dx + atom.c1[ix])*dx + atom.c0[ix]); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fft1_shift(const int &ix, const TGrid &grid_1d, TVector &M_io) - { - int ix_shift = grid_1d.iRx_shift(ix); - thrust::swap(M_io[ix], M_io[ix_shift]); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fft2_sft_bc(const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_io) - { - int ixy = grid_2d.ind_col(ix, iy); - int ixy_shift = grid_2d.ind_col(ix, grid_2d.nyh+iy); - thrust::swap(M_io[ixy], M_io[ixy_shift]); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void fft2_shift(const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_io) - { - int ixy = grid_2d.ind_col(ix, iy); - int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); - thrust::swap(M_io[ixy], M_io[ixy_shift]); - - ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); - ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); - thrust::swap(M_io[ixy], M_io[ixy_shift]); - } - - /***************************************************************************/ - template - DEVICE_CALLABLE FORCE_INLINE - void assign_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, - TVector &M_i, TVector &M_o) - { - int ixy = grid_2d.ind_col(ix, iy); - int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); - M_o[ixy] = M_i[ixy_shift]; - M_o[ixy_shift] = M_i[ixy]; - - ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); - ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); - M_o[ixy] = M_i[ixy_shift]; - M_o[ixy_shift] = M_i[ixy]; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_scale_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &w, TVector &M_i, TVector &M_o) - { - int ixy = grid_2d.ind_col(ix, iy); - int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); - - M_o[ixy] += w*M_i[ixy_shift]; - M_o[ixy_shift] += w*M_i[ixy]; - - /***************************************************************************/ - ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); - ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); - - M_o[ixy] += w*M_i[ixy_shift]; - M_o[ixy_shift] += w*M_i[ixy]; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_scale_square_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &w, TVector_1 &M_i, TVector_2 &M_o) - { - int ixy = grid_2d.ind_col(ix, iy); - int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); - - M_o[ixy] += w*::norm(M_i[ixy_shift]); - M_o[ixy_shift] += w*::norm(M_i[ixy]); - - /***************************************************************************/ - ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); - ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); - - M_o[ixy] += w*::norm(M_i[ixy_shift]); - M_o[ixy_shift] += w*::norm(M_i[ixy]); - } - - /***************************************************************************/ - template - DEVICE_CALLABLE FORCE_INLINE - void assign_crop(const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_i, Range_2d &range, TVector &M_o) - { - if(range.chk_bound(ix, iy)) - { - M_o[range.ind_col_o(ix, iy)] = M_i[grid_2d.ind_col(ix, iy)]; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void assign_crop_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_i, Range_2d &range, TVector &M_o) - { - int ix_i = ix; - int iy_i = iy; - - int ix_s = grid_2d.nxh+ix; - int iy_s = grid_2d.nyh+iy; - - if(range.chk_bound(ix_i, iy_i)) - { - M_o[range.ind_col_o(ix_i, iy_i)] = M_i[grid_2d.ind_col(ix_s, iy_s)]; - } - - if(range.chk_bound(ix_s, iy_s)) - { - M_o[range.ind_col_o(ix_s, iy_s)] = M_i[grid_2d.ind_col(ix_i, iy_i)]; - } - - /***************************************************************************/ - ix_i = ix; - iy_i = grid_2d.nyh+iy; - - ix_s = grid_2d.nxh+ix; - iy_s = iy; - - if(range.chk_bound(ix_i, iy_i)) - { - M_o[range.ind_col_o(ix_i, iy_i)] = M_i[grid_2d.ind_col(ix_s, iy_s)]; - } - - if(range.chk_bound(ix_s, iy_s)) - { - M_o[range.ind_col_o(ix_s, iy_s)] = M_i[grid_2d.ind_col(ix_i, iy_i)]; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_scale_crop_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &w, TVector &M_i, Range_2d &range, TVector &M_o) - { - int ix_i = ix; - int iy_i = iy; - - int ix_s = grid_2d.nxh+ix; - int iy_s = grid_2d.nyh+iy; - - if(range.chk_bound(ix_i, iy_i)) - { - M_o[range.ind_col_o(ix_i, iy_i)] += w*M_i[grid_2d.ind_col(ix_s, iy_s)]; - } - - if(range.chk_bound(ix_s, iy_s)) - { - M_o[range.ind_col_o(ix_s, iy_s)] += w*M_i[grid_2d.ind_col(ix_i, iy_i)]; - } - - /***************************************************************************/ - ix_i = ix; - iy_i = grid_2d.nyh+iy; - - ix_s = grid_2d.nxh+ix; - iy_s = iy; - - if(range.chk_bound(ix_i, iy_i)) - { - M_o[range.ind_col_o(ix_i, iy_i)] += w*M_i[grid_2d.ind_col(ix_s, iy_s)]; - } - - if(range.chk_bound(ix_s, iy_s)) - { - M_o[range.ind_col_o(ix_s, iy_s)] += w*M_i[grid_2d.ind_col(ix_i, iy_i)]; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void add_scale_square_crop_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &w, TVector_1 &M_i, Range_2d &range, TVector_2 &M_o) - { - int ix_i = ix; - int iy_i = iy; - - int ix_s = grid_2d.nxh+ix; - int iy_s = grid_2d.nyh+iy; - - if(range.chk_bound(ix_i, iy_i)) - { - M_o[range.ind_col_o(ix_i, iy_i)] += w*::norm(M_i[grid_2d.ind_col(ix_s, iy_s)]); - } - - if(range.chk_bound(ix_s, iy_s)) - { - M_o[range.ind_col_o(ix_s, iy_s)] += w*::norm(M_i[grid_2d.ind_col(ix_i, iy_i)]); - } - - /***************************************************************************/ - ix_i = ix; - iy_i = grid_2d.nyh+iy; - - ix_s = grid_2d.nxh+ix; - iy_s = iy; - - if(range.chk_bound(ix_i, iy_i)) - { - M_o[range.ind_col_o(ix_i, iy_i)] += w*::norm(M_i[grid_2d.ind_col(ix_s, iy_s)]); - } - - if(range.chk_bound(ix_s, iy_s)) - { - M_o[range.ind_col_o(ix_s, iy_s)] += w*::norm(M_i[grid_2d.ind_col(ix_i, iy_i)]); - } - } - - /***************************************************************************/ - template - DEVICE_CALLABLE FORCE_INLINE - void sum_over_Det(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &g2_min, const Value_type &g2_max, const TVector &M_i, Value_type &sum) - { - auto g2 = grid_2d.g2_shift(ix, iy); - if((g2_min <= g2) && (g2 < g2_max)) - { - int ixy = grid_2d.ind_col(ix, iy); - sum += M_i[ixy]; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void sum_square_over_Det(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &g2_min, const Value_type &g2_max, const TVector &M_i, Value_type &sum) - { - auto g2 = grid_2d.g2_shift(ix, iy); - if((g2_min <= g2) && (g2 < g2_max)) - { - int ixy = grid_2d.ind_col(ix, iy); - sum += norm(M_i[ixy]); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void sum_square_over_Det(const int &ix, const int &iy, const TGrid &grid_2d, - const TVector_1 &S_i, const TVector_2 &M_i, Value_type &sum) - { - const int ixy = grid_2d.ind_col(ix, iy); - sum += S_i[ixy] * norm(M_i[ixy]); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void bandwidth_limit(const int &ix, const int &iy, const TGrid &grid_2d, TVector_c &M_io) - { - const int ixy = grid_2d.ind_col(ix, iy); - M_io[ixy] *= grid_2d.bwl_factor_shift(ix, iy)/grid_2d.nxy_r(); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void hard_aperture(const int &ix, const int &iy, const TGrid &grid_2d, const Value_type &g2_max, const Value_type &w, TVector_c &M_io) - { - using T = Value_type; - const int ixy = grid_2d.ind_col(ix, iy); - const auto g2 = grid_2d.g2_shift(ix, iy); - - M_io[ixy] = ((g2 < g2_max))?(T(w)*M_io[ixy]):0; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void propagate(const int &ix, const int &iy, const TGrid &grid_2d, const Value_type &w, - const Value_type &gx_0, const Value_type &gy_0, TVector_c &psi_i, TVector_c &psi_o) - { - const int ixy = grid_2d.ind_col(ix, iy); - const auto m = grid_2d.bwl_factor_shift(ix, iy)/grid_2d.nxy_r(); - const auto theta = w*grid_2d.g2_shift(ix, iy, gx_0, gy_0); - - psi_o[ixy] = polar(m, theta)*psi_i[ixy]; - } - - /********************* phase shifts real space **********************/ - template - DEVICE_CALLABLE FORCE_INLINE - void exp_r_factor_1d(const int &ix, const TGrid &grid_1d, - const Value_type gx, TVector_c &psi_i, TVector_c &psi_o) - { - const auto Rx = grid_1d.Rx_shift(ix)-grid_1d.Rx_c(); - psi_o[ix] = psi_i[ix]*euler(gx*Rx)/grid_1d.nx_r(); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void exp_r_factor_2d_bc(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type alpha, TVector_r &gy, TVector_c &psi_i, TVector_c &psi_o) - { - const int ixy = grid_2d.ind_col(ix, iy); - const auto Ry = grid_2d.Ry_shift(iy)-grid_2d.Ry_c(); - psi_o[ixy] = psi_i[ixy]*euler(alpha*gy[ix]*Ry)/grid_2d.ny_r(); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void exp_r_factor_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &gx, const Value_type &gy, TVector_c &psi_i, TVector_c &psi_o) - { - const int ixy = grid_2d.ind_col(ix, iy); - const auto Rx = grid_2d.Rx_shift(ix)-grid_2d.Rx_c(); - const auto Ry = grid_2d.Ry_shift(iy)-grid_2d.Ry_c(); - psi_o[ixy] = psi_i[ixy]*euler(gx*Rx + gy*Ry)/grid_2d.nxy_r(); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void mul_exp_r_factor_2d(const int &ix, const int &iy, const TGrid &grid_2d, - TVector_r &gx, TVector_r &gy, TVector_c &psi_i, TVector_c &psi_o) - { - using T_c = Value_type; - - const int ixy = grid_2d.ind_col(ix, iy); - const auto Rx = grid_2d.Rx_shift(ix)-grid_2d.Rx_c(); - const auto Ry = grid_2d.Ry_shift(iy)-grid_2d.Ry_c(); - - T_c exp_sup = 0; - for(auto it=0; it - DEVICE_CALLABLE FORCE_INLINE - void exp_g_factor_1d(const int &ix, const TGrid &grid_1d, - const Value_type Rx, TVector_c &psi_i, TVector_c &psi_o) - { - const auto gx = grid_1d.gx_shift(ix); - psi_o[ix] = psi_i[ix]*euler(Rx*gx)/grid_1d.nx_r(); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void exp_g_factor_2d_bc(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type alpha, TVector_r &Ry, TVector_c &psi_i, TVector_c &psi_o) - { - const int ixy = grid_2d.ind_col(ix, iy); - const auto gy = grid_2d.gy_shift(iy); - psi_o[ixy] = psi_i[ixy]*euler(alpha*Ry[ix]*gy)/grid_2d.ny_r(); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void exp_g_factor_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &Rx, const Value_type &Ry, TVector_c &psi_i, TVector_c &psi_o) - { - const int ixy = grid_2d.ind_col(ix, iy); - const auto gx = grid_2d.gx_shift(ix); - const auto gy = grid_2d.gy_shift(iy); - psi_o[ixy] = psi_i[ixy]*euler(Rx*gx + Ry*gy)/grid_2d.nxy_r(); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void mul_exp_g_factor_2d(const int &ix, const int &iy, const TGrid &grid_2d, - TVector_r &Rx, TVector_r &Ry, TVector_c &psi_i, TVector_c &psi_o) - { - using T_c = Value_type; - - const int ixy = grid_2d.ind_col(ix, iy); - const auto gx = grid_2d.gx_shift(ix); - const auto gy = grid_2d.gy_shift(iy); - - T_c exp_sup = 0; - for(auto it=0; it - DEVICE_CALLABLE FORCE_INLINE - complex exp_i_chi(const int &ix, const int &iy, const Grid_2d &grid_2d, const Lens &lens, - const T &x, const T &y, const T &gxu, const T &gyu) - { - auto gx = grid_2d.gx_shift(ix)+gxu; - auto gy = grid_2d.gy_shift(iy)+gyu; - auto g2 = gx*gx + gy*gy; - - complex v = 0; - - if((lens.g2_min <= g2) && (g2 < lens.g2_max)) - { - auto g4 = g2*g2; - auto g6 = g4*g2; - auto chi = x*gx + y*gy + lens.eval_c_10(g2) + lens.eval_c_30(g4) + lens.eval_c_50(g6); - if(lens.is_phi_required()) - { - auto g = sqrt(g2); - auto g3 = g2*g; - auto g5 = g4*g; - auto phi = atan2(gy, gx); - chi += lens.eval_m(phi) + lens.eval_c_12(g2, phi); - chi += lens.eval_c_21_c_23(g3, phi) + lens.eval_c_32_c_34(g4, phi); - chi += lens.eval_c_41_c_43_c_45(g5, phi) + lens.eval_c_52_c_54_c_56(g6, phi); - } - v = euler(chi); - } - - return v; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void probe(const int &ix, const int &iy, const TGrid &grid_2d, const Lens> &lens, - const Value_type &x, const Value_type &y, const Value_type &gxu, - const Value_type &gyu, TVector_c &fPsi_o) - { - auto v = exp_i_chi(ix, iy, grid_2d, lens, x, y, gxu, gyu); - - int ixy = grid_2d.ind_col(ix, iy); - fPsi_o[ixy] = v; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void apply_CTF(const int &ix, const int &iy, const TGrid &grid_2d, const Lens> &lens, - const Value_type &gxu, const Value_type &gyu, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - using T = Value_type; - - T x = 0; - T y = 0; - auto v = exp_i_chi(ix, iy, grid_2d, lens, x, y, gxu, gyu); - - int ixy = grid_2d.ind_col(ix, iy); - fPsi_o[ixy] = v*fPsi_i[ixy]; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void apply_PCTF(const int &ix, const int &iy, const TGrid &grid_2d, const Lens> &lens, - TVector_c &fPsi_i, TVector_c &fPsi_o) - { - using T_r = Value_type; - - const T_r c_Pi = 3.141592653589793238463; - - int ixy = grid_2d.ind_col(ix, iy); - T_r g2 = grid_2d.g2_shift(ix, iy); - - if((lens.g2_min <= g2) && (g2 < lens.g2_max)) - { - T_r chi = g2*(lens.c_c_30*g2 + lens.c_c_10); - T_r c = c_Pi*lens.si_theta_c*lens.ti_iehwgd; - T_r u = 1.0 + c*c*g2; - - c = c_Pi*lens.ti_iehwgd*lens.lambda*g2; - T_r temp_inc = 0.25*c*c; - - c = c_Pi*lens.si_theta_c*(lens.c_30*lens.lambda2*g2 + lens.c_10); - T_r spa_inc = c*c*g2; - - T_r st_inc = exp(-(spa_inc+temp_inc)/u)/sqrt(u); - - fPsi_o[ixy] = fPsi_i[ixy]*polar(st_inc, chi); - } - else - { - fPsi_o[ixy] = 0; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Lorentz_factor(const int &ix, const int &iy, const TGrid &grid_2d, const Value_type &gc2, const Value_type &ge2, Value_type &sum) - { - using T_r = Value_type; - - T_r g2 = grid_2d.g2_shift(ix, iy); - if(g2 < gc2) - { - sum += 1.0/(g2 + ge2); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void kernel_xyz(const int &ix, const int &iy, const TGrid &grid_2d, const EELS> &eels, TVector_c &k_x, TVector_c &k_y, TVector_c &k_z) - { - using T_r = Value_type; - using T_c = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - T_r gx = grid_2d.gx_shift(ix); - T_r gy = grid_2d.gy_shift(iy); - T_r g2 = gx*gx + gy*gy; - - if(g2 < eels.gc2) - { - T_c pos = euler(eels.x*gx + eels.y*gy); - T_r lorentz = eels.factor/(g2 + eels.ge2); - k_x[ixy] = T_c(gx*lorentz, 0)*pos; - k_y[ixy] = T_c(gy*lorentz, 0)*pos; - k_z[ixy] = T_c(eels.ge*lorentz, 0)*pos; - } - else - { - k_x[ixy] = 0; - k_y[ixy] = 0; - k_z[ixy] = 0; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void kernel_x(const int &ix, const int &iy, const TGrid &grid_2d, const EELS> &eels, TVector_c &k_x) - { - using T_r = Value_type; - using T_c = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - T_r gx = grid_2d.gx_shift(ix); - T_r gy = grid_2d.gy_shift(iy); - T_r g2 = gx*gx + gy*gy; - - if(g2 < eels.gc2) - { - T_c pos = euler(eels.x*gx + eels.y*gy); - T_r lorentz = eels.factor/(g2 + eels.ge2); - k_x[ixy] = T_c(gx*lorentz, 0)*pos; - } - else - { - k_x[ixy] = 0; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void kernel_y(const int &ix, const int &iy, const TGrid &grid_2d, const EELS> &eels, TVector_c &k_y) - { - using T_r = Value_type; - using T_c = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - T_r gx = grid_2d.gx_shift(ix); - T_r gy = grid_2d.gy_shift(iy); - T_r g2 = gx*gx + gy*gy; - - if(g2 < eels.gc2) - { - T_c pos = euler(eels.x*gx + eels.y*gy); - T_r lorentz = eels.factor/(g2 + eels.ge2); - k_y[ixy] = T_c(gy*lorentz, 0)*pos; - } - else - { - k_y[ixy] = 0; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void kernel_z(const int &ix, const int &iy, const TGrid &grid_2d, const EELS> &eels, TVector_c &k_z) - { - using T_r = Value_type; - using T_c = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - T_r gx = grid_2d.gx_shift(ix); - T_r gy = grid_2d.gy_shift(iy); - T_r g2 = gx*gx + gy*gy; - - if(g2 < eels.gc2) - { - T_c pos = euler(eels.x*gx + eels.y*gy); - T_r lorentz = eels.factor/(g2 + eels.ge2); - k_z[ixy] = T_c(eels.ge*lorentz, 0)*pos; - } - else - { - k_z[ixy] = 0; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void kernel_mn1(const int &ix, const int &iy, const TGrid &grid_2d, const EELS> &eels, TVector_c &k_mn1) - { - using T_r = Value_type; - using T_c = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - T_r gx = grid_2d.gx_shift(ix); - T_r gy = grid_2d.gy_shift(iy); - T_r g2 = gx*gx + gy*gy; - - if(g2 < eels.gc2) - { - const T_r c_i2i2 = 0.70710678118654746; - - T_c pos = euler(eels.x*gx + eels.y*gy); - T_r lorentz = c_i2i2*eels.factor/(g2 + eels.ge2); - T_c k_x(gx*lorentz, 0); - T_c k_y(0, gy*lorentz); - k_mn1[ixy] = (k_x - k_y)*pos; - } - else - { - k_mn1[ixy] = 0; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void kernel_mp1(const int &ix, const int &iy, const TGrid &grid_2d, const EELS> &eels, TVector_c &k_mp1) - { - using T_r = Value_type; - using T_c = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - T_r gx = grid_2d.gx_shift(ix); - T_r gy = grid_2d.gy_shift(iy); - T_r g2 = gx*gx + gy*gy; - - if(g2 < eels.gc2) - { - const T_r c_i2i2 = 0.70710678118654746; - - T_c pos = euler(eels.x*gx + eels.y*gy); - T_r lorentz = c_i2i2*eels.factor/(g2 + eels.ge2); - T_c k_x(gx*lorentz, 0); - T_c k_y(0, gy*lorentz); - k_mp1[ixy] = (k_x + k_y)*pos; - } - else - { - k_mp1[ixy] = 0; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void trs(const int &ix, const int &iy, const int &ncols, const int &nrows, TVector &M_i, TVector &M_o) - { - int ixy = ix*nrows+iy; - int ixy_t = iy*ncols+ix; - M_o[ixy_t] = M_i[ixy]; - } - - /****************** Gaussian convolution ********************/ - template - DEVICE_CALLABLE FORCE_INLINE - void gauss_cv_1d(const int &ix, const TGrid &grid_1d, - const Value_type &alpha, TVector_c &M_io) - { - auto fg = exp(-alpha*grid_1d.g2_shift(ix)); - M_io[ix] *= fg/grid_1d.nx_r(); - }; - - template - DEVICE_CALLABLE FORCE_INLINE - void gauss_cv_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &alpha, TVector_c &M_io) - { - auto fg = exp(-alpha*grid_2d.g2_shift(ix, iy)); - M_io[grid_2d.ind_col(ix, iy)] *= fg/grid_2d.nxy_r(); - }; - - /****************** Gaussian deconvolution ********************/ - template - DEVICE_CALLABLE FORCE_INLINE - void gauss_dcv_1d(const int &ix, const TGrid &grid_1d, - const Value_type &alpha, const Value_type &PSNR, TVector_c &M_io) - { - auto fg = exp(-alpha*grid_1d.g2_shift(ix)); - M_io[ix] *= fg/((fg*fg+PSNR)*grid_1d.nx_r()); - }; - - template - DEVICE_CALLABLE FORCE_INLINE - void gauss_dcv_2d(const int &ix, const int &iy, const TGrid &grid_2d, - const Value_type &alpha, const Value_type &PSNR, TVector_c &M_io) - { - auto fg = exp(-alpha*grid_2d.g2_shift(ix, iy)); - M_io[grid_2d.ind_col(ix, iy)] *= fg/((fg*fg+PSNR)*grid_2d.nxy_r()); - }; - - /***************** vector col/row x matrix *****************/ - template - DEVICE_CALLABLE FORCE_INLINE - void vector_row_x_matrix(const int &ix, const int &iy, const TGrid &grid_2d, - TVector &Vr, TVector_c &M_io) - { - M_io[grid_2d.ind_row(ix, iy)] *= Vr[ix]; - } - - template - DEVICE_CALLABLE FORCE_INLINE - void vector_col_x_matrix(const int &ix, const int &iy, const TGrid &grid_2d, - TVector &Vc, TVector_c &M_io) - { - M_io[grid_2d.ind_col(ix, iy)] *= Vc[iy]; - } - - /*************** phase correlation functions **************/ - template - DEVICE_CALLABLE FORCE_INLINE - void pcf_1d_pp(const int &ix, const int &ix_s, const TGrid &grid_1d, - const Butterworth_1d> &bw_1d, TVector &M_i, TVector_c &M_o) - { - using T = Value_type; - - int ix_n = (ix+1 - DEVICE_CALLABLE FORCE_INLINE - void pcf_1d_gaussian(const int &ix, const TGrid &grid_1d, const Gauss_1d> &gs_1d, - TVector_c &M_1, TVector_c &M_2, TVector_c &pcf) - { - using T = Value_type; - - auto z = conj(M_1[ix])*M_2[ix]; - T g2 = grid_1d.g2_shift(ix); - T m = gs_1d(g2); - T theta = thrust::arg(z); - pcf[ix] = (ix == 0)?1:thrust::polar(m, theta); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void pcf_2d_bc_pp(const int &ix, const int &iy, const int &iy_s, const TGrid &grid_2d_i, - const TGrid &grid_2d_o, TVector &M_i, TVector &fh, TVector_c &M_o) - { - int ixy_i = grid_2d_i.ind_col(ix, iy); - int iy_n = (iy+1 - DEVICE_CALLABLE FORCE_INLINE - void pcf_2d_bc_gaussian(const int &ix, const int &iy, const TGrid &grid_2d, - TVector_c &M_1, TVector_c &M_2, TVector &fg, TVector_c &pcf) - { - using T = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - auto z = conj(M_1[ixy])*M_2[ixy]; - T m = fg[iy]; - T theta = thrust::arg(z); - pcf[ixy] = (iy == 0)?1:thrust::polar(m, theta); - } - - template - DEVICE_CALLABLE FORCE_INLINE - void pcf_2d_pp(const int &ix, const int &iy, const TGrid &grid_2d, - const Butterworth_2d> &bw_2d, TVector &M_i, TVector_c &M_o) - { - using T = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - int iy_n = (iy+1 - DEVICE_CALLABLE FORCE_INLINE - void pcf_2d_gaussian(const int &ix, const int &iy, const TGrid &grid_2d, - const Gauss_2d> &gs_2d, TVector_c &M_1, TVector_c &M_2, TVector_c &pcf) - { - using T = Value_type; - - int ixy = grid_2d.ind_col(ix, iy); - auto z = conj(M_1[ixy])*M_2[ixy]; - T g2 = grid_2d.g2_shift(ix, iy); - T m = gs_2d(g2); - T theta = thrust::arg(z); - pcf[ixy] = (ixy == 0)?1:thrust::polar(m, theta); - } - - template - DEVICE_CALLABLE FORCE_INLINE - r2d af_iscale(const r2d &p, const T &fxy) - { - return p/fxy; - } - - template - DEVICE_CALLABLE FORCE_INLINE - r2d af_irotate(const T &theta, const r2d &p0, r2d p) - { - T sin_t, cos_t; - sincos(theta, &sin_t, &cos_t); - p -= p0; - p = r2d(cos_t*p.x+sin_t*p.y, -sin_t*p.x+cos_t*p.y); - p += p0; - return p; - } - - template - DEVICE_CALLABLE FORCE_INLINE - r2d af_irot_sca_sft(const T &theta, const r2d &p0, const T &fx, const T &fy, const r2d &ps, r2d p) - { - T sin_t, cos_t; - sincos(theta, &sin_t, &cos_t); - p.x = (p.x-ps.x)/fx; - p.y = (p.y-ps.y)/fy; - p -= p0; - p = r2d(cos_t*p.x+sin_t*p.y, -sin_t*p.x+cos_t*p.y); - p += p0; - return p; - } - - template - DEVICE_CALLABLE FORCE_INLINE - r2d af_shx_scy(const r2d &p, const T &a, const T &b) - { - return r2d(p.x+a*p.y, b*p.y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - Value_type interp_bl_2d(const r2d> &p, const TGrid &grid_2d, TVector &Im) - { - using T = Value_type; - - const int ix = min(grid_2d.nx-2, max(0, grid_2d.floor_dRx(p.x))); - const int iy = min(grid_2d.ny-2, max(0, grid_2d.floor_dRy(p.y))); - - const T f11 = Im[grid_2d.ind_col(ix, iy)]; - const T f12 = Im[grid_2d.ind_col(ix, iy+1)]; - const T f21 = Im[grid_2d.ind_col(ix+1, iy)]; - const T f22 = Im[grid_2d.ind_col(ix+1, iy+1)]; - - const T x1 = grid_2d.Rx(ix); - const T x2 = grid_2d.Rx(ix+1); - const T y1 = grid_2d.Ry(iy); - const T y2 = grid_2d.Ry(iy+1); - - const T dx1 = (p.x-x1)/(x2-x1); - const T dx2 = (x2-p.x)/(x2-x1); - const T dy1 = (p.y-y1)/(y2-y1); - const T dy2 = (y2-p.y)/(y2-y1); - T f = dx2*(f11*dy2 + f12*dy1)+dx1*(f21*dy2 + f22*dy1); - - return f; - }; - - template - DEVICE_CALLABLE FORCE_INLINE - void sc_2d(const int &ix, const int &iy, const TGrid &grid_2d_i, TVector &M_i, - const Value_type &fxy, const TGrid &grid_2d_o, TVector &M_o) - { - using T = Value_type; - - r2d p(grid_2d_o.Rx(ix), grid_2d_o.Ry(iy)); - p = af_iscale(p, fxy); - - M_o[grid_2d_o.ind_col(ix, iy)] = interp_bl_2d(p, grid_2d_i, M_i); - }; - - template - DEVICE_CALLABLE FORCE_INLINE - void rot_2d(const int &ix, const int &iy, const TGrid &grid_2d_i, TVector &M_i, - const Value_type &theta, const r2d> &p0, const Value_type &bg, - const TGrid &grid_2d_o, TVector &M_o) - { - using T = Value_type; - - r2d p(grid_2d_o.Rx(ix), grid_2d_o.Ry(iy)); - p = af_irotate(theta, p0, p); - - M_o[grid_2d_o.ind_col(ix, iy)] = (grid_2d_i.ckb_bound(p))?interp_bl_2d(p, grid_2d_i, M_i):bg; - }; - - template - DEVICE_CALLABLE FORCE_INLINE - void rot_sca_sft_2d(const int &ix, const int &iy, const TGrid &grid_2d_i, TVector &M_i, - const Value_type &theta, const r2d> &p0, const Value_type &fx, const Value_type &fy, - const r2d> &ps, const Value_type &bg, const TGrid &grid_2d_o, TVector &M_o) - { - using T = Value_type; - - r2d p(grid_2d_o.Rx(ix), grid_2d_o.Ry(iy)); - p = af_irot_sca_sft(theta, p0, fx, fy, ps, p); - - M_o[grid_2d_o.ind_col(ix, iy)] = (grid_2d_i.ckb_bound(p))?interp_bl_2d(p, grid_2d_i, M_i):bg; - }; - - template - DEVICE_CALLABLE FORCE_INLINE - void shx_scy(const int &ix, const int &iy, const TGrid &grid_2d_i, TVector &M_i, - const Value_type &fx, const Value_type &fy, const Value_type &bg, - const TGrid &grid_2d_o, TVector &M_o) - { - using T = Value_type; - - r2d p(grid_2d_o.Rx(ix), grid_2d_o.Ry(iy)); - p = af_shx_scy(p, fx, fy); - - M_o[grid_2d_o.ind_col(ix, iy)] = (grid_2d_i.ckb_bound(p))?interp_bl_2d(p, grid_2d_i, M_i):bg; - }; - - template - DEVICE_CALLABLE FORCE_INLINE - Value_type max_pos_1d(const TGrid &grid_1d, TVector &M) - { - int ix_max = thrust::max_element(M.begin(), M.end())-M.begin(); - - return grid_1d.Rx(ix_max); - }; - - template - DEVICE_CALLABLE FORCE_INLINE - r2d> max_pos_2d(const TGrid &grid_2d, TVector &M) - { - using T = Value_type; - - // get maximum index position - int ixy_max = thrust::max_element(M.begin(), M.end())-M.begin(); - int ix_max, iy_max; - grid_2d.col_row(ixy_max, ix_max, iy_max); - - return r2d(grid_2d.Rx(ix_max), grid_2d.Ry(iy_max)); - }; - - // template - // DEVICE_CALLABLE FORCE_INLINE - // void dilate(const int &ix_i, const int &iy_i, TVector &Im_i, TVector &Im_o) - // { - // int ix_0 = max(ix_i+nk0, 0); - // int ixe = min(ix_i+nke, nx_i); - - // int iy_0 = max(iy_i+nk0, 0); - // int iye = min(iy_i+nke, ny_i); - - // for (auto ix = ix_0; ix < ixe; ix++) - // { - // for (auto iy = iy_0; iy < iye; iy++) - // { - // if(Im_i[ix*ny_i+iy]>0.5) - // { - // Im_o[ix_i*ny_i+iy_i] = 1; - // return; - // } - // } - // } - // Im_o[ix_i*ny_i+iy_i] = 0; - // } - } // host_device_detail - - // Electron scattering factors calculation (feg) - template - DEVICE_CALLABLE FORCE_INLINE - void feg(const ePotential_Type &potential_type, const int &charge, const T &g, const rPP_Coef &c_feg, T &y) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::feg_Doyle_neutral_0_4(g, c_feg, y); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::feg_Peng_neutral_0_4(g, c_feg, y); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::feg_Peng_neutral_0_12(g, c_feg, y); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::feg_Kirkland_neutral_0_12(g, c_feg, y); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::feg_Weickenmeier_neutral_0_12(g, c_feg, y); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::feg_Lobato_neutral_0_12(g, c_feg, y); - break; - } - } - else - { - host_device_detail::feg_Peng_ion_0_4(g, c_feg, y); - } - } - - // Electron scattering factor(c_feg, dfeg) where dfg is the first derivative along g - template - DEVICE_CALLABLE FORCE_INLINE - void feg_dfeg(const ePotential_Type &potential_type, const int &charge, const T &g, const rPP_Coef &c_feg, T &y, T &dy) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::feg_dfeg_Doyle_neutral_0_4(g, c_feg, y, dy); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::feg_dfeg_Peng_neutral_0_4(g, c_feg, y, dy); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::feg_dfeg_Peng_neutral_0_12(g, c_feg, y, dy); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::feg_dfeg_Kirkland_neutral_0_12(g, c_feg, y, dy); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::feg_dfeg_Weickenmeier_neutral_0_12(g, c_feg, y, dy); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::feg_dfeg_Lobato_neutral_0_12(g, c_feg, y, dy); - break; - } - } - else - { - host_device_detail::feg_dfeg_Peng_ion_0_4(g, c_feg, y, dy); - } - } - - // Electron scattering factor(fg) - template - DEVICE_CALLABLE FORCE_INLINE - void fxg(const ePotential_Type &potential_type, const int &charge, const int &Z, const T &g, const rPP_Coef &c_fxg, T &y) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::fxg_Doyle_neutral_0_4(Z, g, c_fxg, y); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::fxg_Peng_neutral_0_4(Z, g, c_fxg, y); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::fxg_Peng_neutral_0_12(Z, g, c_fxg, y); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::fxg_Kirkland_neutral_0_12(Z, g, c_fxg, y); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::fxg_Weickenmeier_neutral_0_12(g, c_fxg, y); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::fxg_Lobato_neutral_0_12(g, c_fxg, y); - break; - } - } - else - { - host_device_detail::fxg_Peng_ion_0_4(Z-charge, g, c_fxg, y); - } - } - - // Electron scattering factor(fg, dfg) where dfg is the first derivative along g - template - DEVICE_CALLABLE FORCE_INLINE - void fxg_dfxg(const ePotential_Type &potential_type, const int &charge, const int &Z, const T &g, const rPP_Coef &c_fxg, T &y, T &dy) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::fxg_dfxg_Doyle_neutral_0_4(Z, g, c_fxg, y, dy); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::fxg_dfxg_Peng_neutral_0_4(Z, g, c_fxg, y, dy); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::fxg_dfxg_Peng_neutral_0_12(Z, g, c_fxg, y, dy); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::fxg_dfxg_Kirkland_neutral_0_12(Z, g, c_fxg, y, dy); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::fxg_dfxg_Weickenmeier_neutral_0_12(g, c_fxg, y, dy); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::fxg_dfxg_Lobato_neutral_0_12(g, c_fxg, y, dy); - break; - } - } - else - { - host_device_detail::fxg_dfxg_Peng_ion_0_4(Z-charge, g, c_fxg, y, dy); - } - } - - // Electron density (Pr) - template - DEVICE_CALLABLE FORCE_INLINE - void Pr(const ePotential_Type &potential_type, const int &charge, const T &r, const rPP_Coef &c_Pr, T &y) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::Pr_Doyle_neutral_0_4(r, c_Pr, y); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::Pr_Peng_neutral_0_4(r, c_Pr, y); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::Pr_Peng_neutral_0_12(r, c_Pr, y); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::Pr_Kirkland_neutral_0_12(r, c_Pr, y); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::Pr_Weickenmeier_neutral_0_12(r, c_Pr, y); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::Pr_Lobato_neutral_0_12(r, c_Pr, y); - break; - } - } - else - { - host_device_detail::Pr_Peng_ion_0_4(r, c_Pr, y); - } - } - - // Electron density (c_Pr, dPr) where dPr is the first derivative along r - template - DEVICE_CALLABLE FORCE_INLINE - void Pr_dPr(const ePotential_Type &potential_type, const int &charge, const T &r, const rPP_Coef &c_Pr, T &y, T &dy) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::Pr_dPr_Doyle_neutral_0_4(r, c_Pr, y, dy); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::Pr_dPr_Peng_neutral_0_4(r, c_Pr, y, dy); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::Pr_dPr_Peng_neutral_0_12(r, c_Pr, y, dy); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::Pr_dPr_Kirkland_neutral_0_12(r, c_Pr, y, dy); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::Pr_dPr_Weickenmeier_neutral_0_12(r, c_Pr, y, dy); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::Pr_dPr_Lobato_neutral_0_12(r, c_Pr, y, dy); - break; - } - } - else - { - host_device_detail::Pr_dPr_Peng_ion_0_4(r, c_Pr, y, dy); - } - } - - // Projected_Potential calculation(Vr) - template - DEVICE_CALLABLE FORCE_INLINE - void Vr(const ePotential_Type &potential_type, const int &charge, const T &r, const rPP_Coef &c_Vr, T &y) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::Vr_Doyle_neutral_0_4(r, c_Vr, y); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::Vr_Peng_neutral_0_4(r, c_Vr, y); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::Vr_Peng_neutral_0_12(r, c_Vr, y); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::Vr_Kirkland_neutral_0_12(r, c_Vr, y); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::Vr_Weickenmeier_neutral_0_12(r, c_Vr, y); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::Vr_Lobato_neutral_0_12(r, c_Vr, y); - break; - } - } - else - { - host_device_detail::Vr_Peng_ion_0_4(r, c_Vr, y); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVr(const ePotential_Type &potential_type, const int &charge, const T &r, const rPP_Coef &c_Vr, T &y, T &dy) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::Vr_dVr_Doyle_neutral_0_4(r, c_Vr, y, dy); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::Vr_dVr_Peng_neutral_0_4(r, c_Vr, y, dy); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::Vr_dVr_Peng_neutral_0_12(r, c_Vr, y, dy); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::Vr_dVr_Kirkland_neutral_0_12(r, c_Vr, y, dy); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::Vr_dVr_Weickenmeier_neutral_0_12(r, c_Vr, y, dy); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::Vr_dVr_Lobato_neutral_0_12(r, c_Vr, y, dy); - break; - } - } - else - { - host_device_detail::Vr_dVr_Peng_ion_0_4(r, c_Vr, y, dy); - } - } - - // Projected potential (VR) - template - DEVICE_CALLABLE FORCE_INLINE - void VR(const ePotential_Type &potential_type, const int &charge, const T &R, const rPP_Coef &c_VR, const rQ1 &Qz_0_I, T &y) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::VR_Doyle_neutral_0_4(R, c_VR, y); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::VR_Peng_neutral_0_4(R, c_VR, y); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::VR_Peng_neutral_0_12(R, c_VR, y); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::VR_Kirkland_neutral_0_12(R, c_VR, y); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::VR_Weickenmeier_neutral_0_12(R, c_VR, Qz_0_I, y); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::VR_Lobato_neutral_0_12(R, c_VR, y); - break; - } - } - else - { - host_device_detail::VR_Peng_ion_0_4(R, c_VR, y); - } - } - - // Projected potential (c_VR, dVR) where dVr is the first derivative along R - template - DEVICE_CALLABLE FORCE_INLINE - void VR_dVR(const ePotential_Type &potential_type, const int &charge, const T &R, const rPP_Coef &c_VR, const rQ1 &Qz_0_I, T &y, T &dy) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::VR_dVR_Doyle_neutral_0_4(R, c_VR, y, dy); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::VR_dVR_Peng_neutral_0_4(R, c_VR, y, dy); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::VR_dVR_Peng_neutral_0_12(R, c_VR, y, dy); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::VR_dVR_Kirkland_neutral_0_12(R, c_VR, y, dy); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::VR_dVR_Weickenmeier_neutral_0_12(R, c_VR, Qz_0_I, y, dy); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::VR_dVR_Lobato_neutral_0_12(R, c_VR, y, dy); - break; - } - } - else - { - host_device_detail::VR_dVR_Peng_ion_0_4(R, c_VR, y, dy); - } - } - - // Projected potential (Vz)[z0, ze] - template - DEVICE_CALLABLE FORCE_INLINE - void Vz(const ePotential_Type &potential_type, const int &charge, const T &z0, const T &ze, const T &R, const rPP_Coef &c_Vr, const rQ1 &Qz_a_b, T &y) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::Vz_Doyle_neutral_0_4(z0, ze, R, c_Vr, Qz_a_b, y); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::Vz_Peng_neutral_0_4(z0, ze, R, c_Vr, Qz_a_b, y); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::Vz_Peng_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::Vz_Kirkland_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::Vz_Weickenmeier_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::Vz_Lobato_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y); - break; - } - } - else - { - host_device_detail::Vz_Peng_ion_0_4(z0, ze, R, c_Vr, Qz_a_b, y); - } - } - - // Projected potential (Vz, dVz)[z0, ze] where dVr is the first derivative along R - template - DEVICE_CALLABLE FORCE_INLINE - void Vz_dVz(const ePotential_Type &potential_type, const int &charge, const T &z0, const T &ze, const T &R, const rPP_Coef &c_Vr, const rQ1 &Qz_a_b, T &y, T &dy) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::Vz_dVz_Doyle_neutral_0_4(z0, ze, R, c_Vr, Qz_a_b, y, dy); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::Vz_dVz_Peng_neutral_0_4(z0, ze, R, c_Vr, Qz_a_b, y, dy); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::Vz_dVz_Peng_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y, dy); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::Vz_dVz_Kirkland_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y, dy); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::Vz_dVz_Weickenmeier_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y, dy); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::Vz_dVz_Lobato_neutral_0_12(z0, ze, R, c_Vr, Qz_a_b, y, dy); - break; - } - } - else - { - host_device_detail::Vz_dVz_Peng_ion_0_4(z0, ze, R, c_Vr, Qz_a_b, y, dy); - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - void Vr_dVrir(const T &r, T *cl, T *cnl, T f, T &Vr, T &dVrir) - { - if(charge == 0) - { - switch(potential_type) - { - case ePT_Doyle_0_4: - // 1: Doyle and Turner parameterization - 4 Gaussians - [0, 4] - host_device_detail::Vr_dVrir_Doyle_neutral_0_4(r, cl, cnl, Vr, dVrir); - break; - case ePT_Peng_0_4: - // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] - host_device_detail::Vr_dVrir_Peng_neutral_0_4_12(r, cl, cnl, Vr, dVrir); - break; - case ePT_Peng_0_12: - // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] - host_device_detail::Vr_dVrir_Peng_neutral_0_4_12(r, cl, cnl, Vr, dVrir); - break; - case ePT_Kirkland_0_12: - // 4: Kirkland parameterization - 3 Lorentzian + 3 Gaussians - [0, 12] - host_device_detail::Vr_dVrir_Kirkland_neutral_0_12(r, cl, cnl, Vr, dVrir); - break; - case ePT_Weickenmeier_0_12: - // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] - host_device_detail::Vr_dVrir_Weickenmeier_neutral_0_12(r, cl, cnl, Vr, dVrir); - break; - case ePT_Lobato_0_12: - // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] - host_device_detail::Vr_dVrir_Lobato_neutral_0_12(r, cl, cnl, Vr, dVrir); - break; - } - } - else - { - host_device_detail::Vr_dVrir_Peng_ion_0_4(r, cl, cnl, Vr, dVrir); - } - Vr *= f; - dVrir *= f; - } - - /***************************************************************************/ - /***************************************************************************/ - - namespace functor - { - template - struct transmission_function - { - const eElec_Spec_Int_Model elec_spec_int_model; - - const T w; - transmission_function(T w_i, eElec_Spec_Int_Model ElecSpecIntModel_i): w(w_i), elec_spec_int_model(ElecSpecIntModel_i){} - - template - DEVICE_CALLABLE - complex operator()(const U &x) const - { - T theta = w*x; - return (elec_spec_int_model == eESIM_Weak_Phase_Object)?complex(1.0, theta):euler(theta); - } - }; - - template - struct closest_element - { - const T m_val; - - closest_element(T val): m_val(val) {} - - bool operator()(const T &a, const T &b) - { - const T da = 1e-4; - return fabs(a-m_val-da) - struct assign_real - { - template - DEVICE_CALLABLE - T operator()(const U &x) const { return x.real(); } - }; - - template - struct assign_max_real - { - const T vm; - assign_max_real(T vm_i = T()): vm(vm_i){} - - template - DEVICE_CALLABLE - T operator()(const U &x) const { return ::fmax(vm, x.real()); } - }; - - template - struct scale - { - const T w; - scale(T w_i = T()): w(w_i){} - - template - DEVICE_CALLABLE - T operator()(const U &x) const { return w*x; } - }; - - template - DEVICE_CALLABLE - T norm(const thrust::device_reference< thrust::complex >&x) - { - thrust::complex xx = (thrust::complex)x; - return norm(xx); - } - - template - struct square - { - template - DEVICE_CALLABLE - T operator()(const U &x) const { return norm(x); } - }; - - template - struct square_scale - { - const T w; - square_scale(T w_i = T()): w(w_i){} - - template - DEVICE_CALLABLE - T operator()(const U &x) const { return w*norm(x); } - }; - - template - struct add - { - add(){} - - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const { return lhs + rhs; } - }; - - template - struct multiply - { - multiply(){} - - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const { return lhs*rhs; } - }; - - template - struct add_scale - { - const T w; - add_scale(T w_i = T()): w(w_i){} - - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const{ return w*lhs + rhs; } - }; - - template - struct add_scale_i - { - const T w1; - const T w2; - add_scale_i(T w1_i = T(), T w2_i = T()): w1(w1_i), w2(w2_i){} - - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const{ return w1*lhs + w2*rhs; } - }; - - template - struct add_square - { - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const { return norm(lhs) + rhs; } - }; - - template - struct add_square_i - { - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const { return norm(lhs) + norm(rhs); } - }; - - template - struct add_scale_square - { - const T w; - add_scale_square(T w_i = T()): w(w_i){} - - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const { return w*norm(lhs) + rhs; } - }; - - template - struct add_scale_square_i - { - const T w1; - const T w2; - add_scale_square_i(T w1_i = T(), T w2_i = T()): w1(w1_i), w2(w2_i){} - - template - DEVICE_CALLABLE - T operator()(const U &lhs, const V &rhs) const { return w1*::norm(lhs) + w2*::norm(rhs); } - }; - - template - struct square_dif - { - const T x_mean; - square_dif(T x_mean_i = T()): x_mean(x_mean_i){} - - template - DEVICE_CALLABLE - Tr operator()(const U &x) const { return ::norm(x-x_mean); } - }; - - - template - struct binarize - { - const T thr; - binarize(T thr_i = T()): thr(thr_i){} - - template - DEVICE_CALLABLE - T operator()(const U &x) const { return (x - struct thresholding - { - const T thr; - thresholding(T thr_i = T()): thr(thr_i){} - - template - DEVICE_CALLABLE - T operator()(const U &x) const { return (x - struct anscombe_forward - { - const T xs; - anscombe_forward(): xs(3.0/8.0){} - - template - DEVICE_CALLABLE - T operator()(const U &x) const { return (x<0)?0:2*sqrt(x+xs); } - }; - - template - struct anscombe_inverse - { - const T a; - const T b; - const T c; - const T d; - const T e; - anscombe_inverse(): a(1.0/4.0), b(sqrt(3.0/2.0)/4), - c(-11.0/8.0), d(5*sqrt(3.0/2.0)/8), e(-1.0/8.0){}\ - - template - DEVICE_CALLABLE - T operator()(const U &x) const - { - if(isZero(x)) - { - return ::fmax(0, a*x+e); - } - else - { - T ix = 1.0/x; - return ::fmax(0, a*x*x+e+ix*(b+ix*(c+ix*d))); - } - } - }; - } // namespace functor - - template - Value_type min_element(TVector &x) - { - return *thrust::min_element(x.begin(), x.end()); - } - - template - Value_type min_element(TVector &x, TArg &...arg) - { - return ::fmin(min_element(x), min_element(arg...)); - } - - template - Value_type max_element(TVector &x) - { - return *thrust::max_element(x.begin(), x.end()); - } - - template - Value_type max_element(TVector &x, TArg &...arg) - { - return ::fmax(max_element(x), max_element(arg...)); - } - - template - void minmax_element(TVector &x, Value_type &x_min, Value_type &x_max) - { - auto x_min_max = thrust::minmax_element(x.begin(), x.end()); - x_min = *(x_min_max.first); - x_max = *(x_min_max.second); - } - - template - Value_type mean(TVector &M_i) - { - return thrust::reduce(M_i.begin(), M_i.end())/M_i.size(); - } - - template - void mean_var(TVector &M_i, Value_type &x_mean, Value_type_r &x_var) - { - using T = Value_type; - using T_r = Value_type_r; - - x_mean = mean(M_i); - - x_var = thrust::transform_reduce(M_i.begin(), M_i.end(), - functor::square_dif(x_mean), T_r(0), functor::add()); - - x_var = x_var/M_i.size(); - } - - template - void mean_std(TVector &M_i, Value_type &x_mean, Value_type_r &x_std) - { - mean_var(M_i, x_mean, x_std); - x_std = sqrt(x_std); - } - - template - Value_type_r variance(TVector &M_i) - { - using T = Value_type; - using T_r = Value_type_r; - - T x_mean; - T_r x_var; - mean_var(M_i, x_mean, x_var); - return x_var; - } - - template - void scale(Value_type f, TVector &x) - { - using value_type = Value_type; - thrust::transform(x.begin(), x.end(), x.begin(), functor::scale(f)); - } - - template - enable_if_complex_vector_and_real_vector - assign_real(TVector_c &M_i, TVector_r &M_o) - { - using value_type = Value_type; - - thrust::transform(M_i.begin(), M_i.end(), M_o.begin(), functor::assign_real()); - } - - template - enable_if_complex_vector_and_real_vector - assign_real(TVector_c &M_i, TVector_r &M_o, Value_type M_v) - { - using value_type = Value_type; - - if(M_v>0) - { - thrust::transform(M_i.begin(), M_i.end(), M_o.begin(), functor::assign_max_real(0)); - } - else - { - thrust::transform(M_i.begin(), M_i.end(), M_o.begin(), functor::assign_real()); - } - } - -} // namespace mt - -#endif +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CGPU_FCNS_H + #define CGPU_FCNS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "type_traits_gen.h" + #include "cgpu_vctr.cuh" + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + namespace mt + { + // snr using squared difference + template + Value_type_r fcn_snr_ma2(TVctr& mx_i, TVctr& M_r) + { + using T = Value_type; + + auto ma1_r = fcn_variance(M_r); + + TVctr M_n(mx_i.size()); + for(auto ik = 0; ik + Value_type_r fcn_snr_ma1(TVctr& mx_i, TVctr& M_r) + { + using T = Value_type; + + auto ma1_r = fcn_moment_1a(M_r); + + TVctr M_n(mx_i.size()); + for(auto ik = 0; ik - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef CGPU_RAND_H -#define CGPU_RAND_H - -#include - -#include "math.cuh" -#include "types.cuh" -#include "lin_alg_def.cuh" - -#ifdef __CUDACC__ - #include - #include -#endif - -namespace mt -{ - /******************** Uniform 2d distribution *******************/ - template - struct Rand_2d; - - template - struct Rand_2d - { - public: - using value_type = T; - - static const eDevice device = e_host; - - Rand_2d(): m_seed(300183), m_l_x(1), m_l_y(1), - m_bx(true), m_by(true), rand_x(T(0), T(1)), - rand_y(T(0), T(1)), rand_u(1){} - - void seed(int seed_i, int n_iter=1) - { - m_seed = seed_i; - - gen_u.seed(m_seed); - rand_u.reset(); - - unsigned int seed_x, seed_y; - for(auto ic = 0; ic operator()() - { - return r2d(gen_rand_x(m_l_x), gen_rand_y(m_l_y)); - } - - r2d operator()(const T &x, const T &y) - { - return r2d(gen_rand_x(x), gen_rand_y(y)); - } - - private: - T gen_rand_x(const T &x) - { - return ((m_bx)?(x*rand_x(gen_x)):0); - } - - T gen_rand_y(const T &y) - { - return ((m_by)?(y*rand_y(gen_y)):0); - } - - int m_seed; - T m_l_x; - T m_l_y; - bool m_bx; - bool m_by; - - std::mt19937_64 gen_u; - std::mt19937_64 gen_x; - std::mt19937_64 gen_y; - std::uniform_int_distribution rand_u; - std::uniform_real_distribution rand_x; - std::uniform_real_distribution rand_y; - }; - - /******************** Uniform 3d distribution *******************/ - template - struct Rand_3d; - - template - struct Rand_3d - { - public: - using value_type = T; - - static const eDevice device = e_host; - - Rand_3d(): m_seed(300183), m_l_x(1), m_l_y(1), m_l_z(1), - m_bx(true), m_by(true), m_bz(true), rand_x(T(0), T(1)), - rand_y(T(0), T(1)), rand_z(T(0), T(1)), rand_u(1){} - - void seed(int seed, int n_iter=1) - { - n_iter = max(1, n_iter); - - m_seed = seed; - - gen_u.seed(m_seed); - rand_u.reset(); - - unsigned int seed_x, seed_y, seed_z; - for(auto ic = 0; ic operator()() - { - return r3d(gen_rand_x(m_l_x), gen_rand_y(m_l_y), gen_rand_z(m_l_z)); - } - - r3d operator()(const T &x, const T &y, const T &z) - { - return r3d(gen_rand_x(x), gen_rand_y(y), gen_rand_z(z)); - } - - private: - T gen_rand_x(const T &x) - { - return ((m_bx)?(x*rand_x(gen_x)):0); - } - - T gen_rand_y(const T &y) - { - return ((m_by)?(y*rand_y(gen_y)):0); - } - - T gen_rand_z(const T &z) - { - return ((m_bz)?(z*rand_z(gen_z)):0); - } - - int m_seed; - T m_l_x; - T m_l_y; - T m_l_z; - bool m_bx; - bool m_by; - bool m_bz; - std::mt19937_64 gen_u; - std::mt19937_64 gen_x; - std::mt19937_64 gen_y; - std::mt19937_64 gen_z; - std::uniform_int_distribution rand_u; - std::uniform_real_distribution rand_x; - std::uniform_real_distribution rand_y; - std::uniform_real_distribution rand_z; - }; - - /******************** normal 2d distribution *******************/ - template - struct Randn_2d; - - template - struct Randn_2d - { - public: - using value_type = T; - - static const eDevice device = e_host; - - Randn_2d(): m_seed(300183), m_l_x(1), m_l_y(1), - m_bx(true), m_by(true), randn_x(T(0), T(1)), - randn_y(T(0), T(1)), rand_u(1){} - - void seed(int seed_i, int n_iter=1) - { - m_seed = seed_i; - - gen_u.seed(m_seed); - rand_u.reset(); - - unsigned int seed_x, seed_y; - for(auto ic = 0; ic operator()() - { - return r2d(gen_rand_x(m_l_x), gen_rand_y(m_l_y)); - } - - r2d operator()(const T &x, const T &y) - { - return r2d(gen_rand_x(x), gen_rand_y(y)); - } - - private: - T gen_rand_x(const T &x) - { - return ((m_bx)?(x*randn_x(gen_x)):0); - } - - T gen_rand_y(const T &y) - { - return ((m_by)?(y*randn_y(gen_y)):0); - } - - int m_seed; - T m_l_x; - T m_l_y; - bool m_bx; - bool m_by; - - std::mt19937_64 gen_u; - std::mt19937_64 gen_x; - std::mt19937_64 gen_y; - std::uniform_int_distribution rand_u; - std::normal_distribution randn_x; - std::normal_distribution randn_y; - }; - - /******************** normal 3d distribution *******************/ - template - struct Randn_3d; - - template - struct Randn_3d - { - public: - using value_type = T; - - static const eDevice device = e_host; - - Randn_3d(): m_seed(300183), m_l_x(1), m_l_y(1), m_l_z(1), - m_bx(true), m_by(true), m_bz(true), randn_x(T(0), T(1)), - randn_y(T(0), T(1)), randn_z(T(0), T(1)), rand_u(1){} - - void seed(int seed, int n_iter=1) - { - n_iter = max(1, n_iter); - - m_seed = seed; - - gen_u.seed(m_seed); - rand_u.reset(); - - unsigned int seed_x, seed_y, seed_z; - for(auto ic = 0; ic operator()() - { - return r3d(gen_rand_x(m_l_x), gen_rand_y(m_l_y), gen_rand_z(m_l_z)); - } - - r3d operator()(const T &x, const T &y, const T &z) - { - return r3d(gen_rand_x(x), gen_rand_y(y), gen_rand_z(z)); - } - - private: - T gen_rand_x(const T &x) - { - return ((m_bx)?(x*randn_x(gen_x)):0); - } - - T gen_rand_y(const T &y) - { - return ((m_by)?(y*randn_y(gen_y)):0); - } - - T gen_rand_z(const T &z) - { - return ((m_bz)?(z*randn_z(gen_z)):0); - } - - int m_seed; - T m_l_x; - T m_l_y; - T m_l_z; - bool m_bx; - bool m_by; - bool m_bz; - std::mt19937_64 gen_u; - std::mt19937_64 gen_x; - std::mt19937_64 gen_y; - std::mt19937_64 gen_z; - std::uniform_int_distribution rand_u; - std::normal_distribution randn_x; - std::normal_distribution randn_y; - std::normal_distribution randn_z; - }; - - /***************************************************************/ - - // add Gaussian noise - template - void add_gauss_nois(Stream &stream, TVector &M_i, - Value_type sigma, TVector &M_o) - { - using T = Value_type; - - auto thr_gauss_nois = [&](const Range_2d &range) - { - std::random_device rd; - std::mt19937_64 gen(rd()); - std::normal_distribution randn; - - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - M_o[ixy] = M_i[ixy] + sigma*randn(gen); - } - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(M_i.size(), 1); - stream.exec(thr_gauss_nois); - }; - - // add Gaussian noise - template - TVector add_gauss_nois(Stream &stream, TVector &M_i, - Value_type sigma) - { - using T = Value_type; - - TVector M(M_i.size()); - auto thr_gauss_nois = [&](const Range_2d &range) - { - std::random_device rd; - std::mt19937_64 gen(rd()); - std::normal_distribution randn; - - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - M[ixy] = M_i[ixy] + sigma*randn(gen); - } - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(M_i.size(), 1); - stream.exec(thr_gauss_nois); - - return M; - }; - /***************************************************************/ - // add Poisson noise - template - TVector add_poiss_nois(Stream &stream, TVector &M_i, - Value_type scf) - { - using T = Value_type; - - TVector M(M_i.size()); - auto thr_poiss_nois = [&](const Range_2d &range) - { - std::random_device rd; - std::mt19937_64 gen(rd()); - std::poisson_distribution randp; - - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto x0 = scf*M_i[ixy]; - randp.param(std::poisson_distribution::param_type(x0)); - M[ixy] = randp(gen); - } - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(M_i.size(), 1); - stream.exec(thr_poiss_nois); - - return M; - }; - - // add Poisson noise - template - TVector add_poiss_nois_by_SNR(Stream &stream, TVector &Im_i, - Value_type SNR_i, Value_type &scl_o) - { - using T = Value_type; - - auto get_SNR = [](Stream &stream, TVector &Im, T Im_std, T scf)->T - { - T x_mean = 0; - T x_var = 0; - auto thr_SNR = [&](const Range_2d &range) - { - std::mt19937_64 gen; - std::poisson_distribution rand; - - T x_mean_partial = 0; - T x_var_partial = 0; - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto x0 = scf*Im[ixy]; - rand.param(std::poisson_distribution::param_type(x0)); - auto xn = rand(gen)-x0; - x_mean_partial += xn; - x_var_partial += xn*xn; - } - - stream.stream_mutex.lock(); - x_mean += x_mean_partial; - x_var += x_var_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(Im.size()); - stream.set_grid(1, Im.size()); - stream.exec(thr_SNR); - - x_mean /= Im.size(); - x_var = x_var/Im.size()-x_mean*x_mean; - - return scf*Im_std/sqrt(x_var); - }; - - auto Im_i_std = sqrt(variance(stream, Im_i)); - - T SNR_k = get_SNR(stream, Im_i, Im_i_std, 1); - - T k_0 = 1; - T k_e = 1; - - if(SNR_k= SNR_i); - k_e = 2*k_0; - } - - - // bisection method - int ic = 0; - do - { - scl_o = 0.5*(k_0 + k_e); - auto SNR_k = get_SNR(stream, Im_i, Im_i_std, scl_o); - - if(SNR_k < SNR_i) - { - k_0 = scl_o; - } - else - { - k_e = scl_o; - } - ic++; - } while ((fabs(SNR_i-SNR_k)>0.1) && (ic<10)); - - // add Poisson noise - return add_poiss_nois(stream, Im_i, scl_o); - } - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/const_enum.h b/src/const_enum.h new file mode 100755 index 00000000..1b1ea129 --- /dev/null +++ b/src/const_enum.h @@ -0,0 +1,694 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +#ifdef __CUDACC__ + #include + #include + #include + #include + using thrust::complex; +#else + using std::complex; +#endif + +#include "macros.h" +#include "shape_t.h" + +/*data type */ +using dt_bool = bool; +using dt_int8 = int8_t; +using dt_uint8 = uint8_t; +using dt_int16 = int16_t; +using dt_uint16 = uint16_t; +using dt_int32 = int32_t; +using dt_uint32 = uint32_t; +using dt_int64 = int64_t; +using dt_uint64 = uint64_t; +using dt_float32 = float; +using dt_float64 = double; + +using dt_cint8 = complex; +using dt_cuint8 = complex; +using dt_cint16 = complex; +using dt_cuint16 = complex; +using dt_cint32 = complex; +using dt_cuint32 = complex; +using dt_cint64 = complex; +using dt_cuint64 = complex; +using dt_cfloat32 = complex; +using dt_cfloat64 = complex; + +using dt_std_cint8 = std::complex; +using dt_std_cuint8 = std::complex; +using dt_std_cint16 = std::complex; +using dt_std_cuint16 = std::complex; +using dt_std_cint32 = std::complex; +using dt_std_cuint32 = std::complex; +using dt_std_cint64 = std::complex; +using dt_std_cuint64 = std::complex; +using dt_std_cfloat32 = std::complex; +using dt_std_cfloat64 = std::complex; + +#ifdef __CUDACC__ + using dt_thr_cint8 = thrust::complex; + using dt_thr_cuint8 = thrust::complex; + using dt_thr_cint16 = thrust::complex; + using dt_thr_cuint16 = thrust::complex; + using dt_thr_cint32 = thrust::complex; + using dt_thr_cuint32 = thrust::complex; + using dt_thr_cint64 = thrust::complex; + using dt_thr_cuint64 = thrust::complex; + using dt_thr_cfloat32 = thrust::complex; + using dt_thr_cfloat64 = thrust::complex; +#endif + +/* data type */ +enum eData_Typ +{ + edt_none = 0, edt_bool = 1, + edt_int8 = 2, edt_uint8 = 3, edt_int16 = 4, edt_uint16 = 5, edt_int32 = 6, + edt_uint32 = 7, edt_int64 = 8, edt_uint64 = 9, edt_float32 = 10, edt_float64 = 11, + edt_cint8 = 12, edt_cuint8 = 13, edt_cint16 = 14, edt_cuint16 = 15, edt_cint32 = 16, + edt_cuint32 = 17, edt_cint64 = 18, edt_cuint64 = 19, edt_cfloat32 = 20, edt_cfloat64 = 21, + edt_std_cint8 = 22, edt_std_cuint8 = 23, edt_std_cint16 = 24, edt_std_cuint16 = 25, edt_std_cint32 = 26, + edt_std_cuint32 = 27, edt_std_cint64 = 28, edt_std_cuint64 = 29, edt_std_cfloat32 = 30, edt_std_cfloat64 = 31, + edt_thr_cint8 = 32, edt_thr_cuint8 = 33, edt_thr_cint16 = 34, edt_thr_cuint16 = 35, edt_thr_cint32 = 36, + edt_thr_cuint32 = 37, edt_thr_cint64 = 38, edt_thr_cuint64 = 39, edt_thr_cfloat32 = 40, edt_thr_cfloat64 = 41 +}; + +template +using Ctpr = const T* __restrict__; // const template pointer restrict + +template +using Tpr = T* __restrict__; // template pointer restrict + +template +using dt_init_list = std::initializer_list; + +using dt_init_list_int32 = std::initializer_list; +using dt_init_list_int64 = std::initializer_list; + +using dt_init_list_f32 = std::initializer_list; +using dt_init_list_f64 = std::initializer_list; + +/* physical constants */ +namespace mt +{ + template + const T c_Ha = T(27.2113850656389L); // Hartree to electron-Volt + + template + const T c_a0 = T(0.52917721077817892L); // Bohr radius + + template + const T c_pot_factor = T(47.877645145863056L); // + + template + const T c_2Pi2a0 = T(10.445539456905012L); // 2*pi^2*a0 + + template + const T c_H = T(6.62606876e-34L); // Planck's constant - J s + + template + const T c_bH = T(1.054571596e-34L); // h/(2*pi) - J s + + template + const T c_C = T(2.99792458e+8L); // Velocity of light - m s^-1 + + template + const T c_Qe = T(1.602176462e-19L); // Elementary charge + + template + const T c_me = T(9.10938291e-31L); // Electron rest mass [kg] + + template + const T c_mp = T(1.672621637e-27L); // Proton rest mass [kg] + + template + const T c_KB = T(1.3806504e-23L); // Boltzmann's constant - J K^-1 + + template + const T c_Na = T(6.0221415e+23L); // Avogadro's Number - mol^-1 + + template + const T c_E0 = T(8.854187817e-12L); // Vacuum permittivity +} + +/* pi and power constants */ +namespace mt +{ + template + const T c_E = T(2.7182818284590452354L); // e (base of natural log) + + template + const T c_pi = T(3.141592653589793238463L); // pi + + template + const T c_ipi = T(0.3183098861837906715378L); // 1.0/pi + + template + const T c_i2pi = T(1.570796326794896619231L); // pi/2 + + template + const T c_i3pi = T(1.047197551196597746154L); // pi/3 + + template + const T c_i4pi = T(0.7853981633974483096157L); // pi/4 + + template + const T c_2pi = T(6.283185307179586476925L); // 2*pi + + template + const T c_3pi = T(9.424777960769379715388L); // 3*pi + + template + const T c_4pi = T(12.56637061435917295385L); // 4*pi + + template + const T c_pi2 = T(9.869604401089358618834L); // pi^2 + + template + const T c_pi3 = T(31.00627668029982017548L); // pi^3 + + template + const T c_pi4 = T(97.4090910340024372364L); // pi^4 + + template + const T c_pii2 = T(1.772453850905516027298L); // pi^(1/2) + + template + const T c_pii3 = T(1.46459188756152326302L); // pi^(1/3) + + template + const T c_pii4 = T(1.331335363800389712798L); // pi^(1/4) + + template + const T c_2i2 = T(1.414213562373095048802L); // 2^(1/2) + + template + const T c_3i2 = T(1.732050807568877293527L); // 3^(1/2) + + template + const T c_5i2 = T(2.236067977499789696409L); // 5^(1/2) + + template + const T c_7i2 = T(2.645751311064590590502L); // 7^(1/2) +} + +/* others constants */ +namespace mt +{ + const dt_int32 c_cSynCPU = 5; + + const dt_int32 c_n_atom_typ = 103; + const dt_int32 c_n_atom_ions = 15; + const dt_int32 c_nqz = 128; + const dt_int32 c_nR = 128; + + const dt_float64 c_vr_min = 0.001; // before was 0.015V + + const dt_float64 c_dflt_pos_ee = 1e-04; // position error + + const dt_float32 c_dflt_rms3d = 0.085f; // default 3d root mean squared displacement + const dt_float32 c_dflt_occ = 1.0f; // default occupancy + const dt_int32 c_dflt_tag = 0; // default tag + const dt_int32 c_dflt_charge = 0; // default charge + + const dt_int32 cSizeofI = sizeof(dt_int32); + const dt_int32 cSizeofRD = sizeof(dt_float64); + const dt_int32 cSizeofRF = sizeof(dt_float32); + const dt_int32 cSizeofCD = 2*cSizeofRD; + + const dt_uint64 c_bytes_2_kb = 1024; + const dt_uint64 c_bytes_2_mb = 1024*1024; + const dt_uint64 c_bytes_2_gb = 1024*1024*1024; + + template + const T c_hwhm_2_sigma = T(0.84932180028801907L); // hwhm to sigma 1/(sqrt(2*log(2))) + + template + const T c_fwhm_2_sigma = T(0.42466090014400953L); // fwhm to sigma 1/(2*sqrt(2*log(2))) + + template + const T c_iehwgd_2_sigma = T(0.70710678118654746L); // iehwgd to sigma 1/sqrt(2) + + template + const T c_mrad_2_rad = T(1.0e-03L); // mrad-->rad + + template + const T c_deg_2_rad = T(0.01745329251994329576924L); // degrees-->rad + + template + const T c_mm_2_angs = T(1.0e+07L); // mm-->Angstrom + + template + const T c_eV_2_keV = T(1e-03L); // ev-->keV + + template + const T c_cm3_A3 = T(1e24L); // cm^3 --> A^3 +} + +/* error class and fcns */ +namespace mt +{ + template + CGPU_EXEC + T epsilon_eps(){ return 0; } + + template <> + CGPU_EXEC + dt_float64 epsilon_eps(){ return 10.0*DBL_EPSILON; } + + template <> + CGPU_EXEC + dt_float32 epsilon_eps(){ return 10.0*FLT_EPSILON; } + + template + CGPU_EXEC + T epsilon_abs(){ return 0; } + + template <> + CGPU_EXEC + dt_float64 epsilon_abs(){ return 1e-13; } + + template <> + CGPU_EXEC + dt_float32 epsilon_abs(){ return 1e-5f; } + + template + CGPU_EXEC + T epsilon_rel(){ return 0; } + + template <> + CGPU_EXEC + dt_float64 epsilon_rel(){ return 1e-8; } + + template <> + CGPU_EXEC + dt_float32 epsilon_rel(){ return 1e-4f; } + + + template + struct Epsilon + { + static const T eps; + static const T abs; + static const T rel; + }; + + template + const T Epsilon::eps = 0; + + template + const T Epsilon::abs = 0; + + template + const T Epsilon::rel = 0; + + template <> + const dt_float64 Epsilon::eps = 10.0*DBL_EPSILON; + + template <> + const dt_float64 Epsilon::abs = 1e-13; + + template <> + const dt_float64 Epsilon::rel = 1e-8; + + template <> + const dt_float32 Epsilon::eps = 10.0*FLT_EPSILON; + + template <> + const dt_float32 Epsilon::abs = 1e-5f; + + template <> + const dt_float32 Epsilon::rel = 1e-4f; +} + +/* enumerations */ +namespace mt +{ + /* Dimension*/ + enum eDim + { + edim_1 = 1, edim_2 = 2, edim_3 = 3 + }; + + /* Distribution */ + // 1: uniform, 2: normal, 3: poisson + enum eDist + { + edist_u = 1, edist_n = 2, edist_p = 3 + }; + + /* Device type */ + enum eDev + { + edev_cpu = 1, edev_gpu = 2, edev_cpu_gpu = 3 + }; + + /* functions type */ + enum eFcn_typ + { + efcn_cos_tap = 1, efcn_gauss = 2, efcn_exp = 3, efcn_fermi = 5, efcn_butwth = 6, efcn_hann = 7 + }; + + /* modify vector */ + enum eModify_Vector + { + eMV_yes = 1, eMV_no = 2 + }; + + /* Multem type */ + enum ePrecision + { + eprc_float32 = 1, eprc_float64 = 2 + }; + + /* Show Data type */ + enum eShow_CData + { + escd_creal = 1, escs_cimag = 2, escd_cmod = 3, escd_cphase = 4 + }; + + /** operation mode */ + enum eOperation_Mode + { + eOM_Normal = 1, eOM_Advanced = 2 + }; + + enum eRot_Ctr_Typ + { + erct_none = 0, erct_geometric_ctr = 1, erct_user_def = 2 + }; + + /* real or fourier space */ + enum eSpace + { + esp_real = 1, esp_fourier = 2 + }; + + /* match boder */ + enum eMatch_Bdr + { + emb_none = 0, emb_min = 1, emb_max = 2, emb_minmax = 3 + }; + + /*** output type */ + enum eOutput_Typ + { + eot_matlab = 1, eot_vector = 2 + }; + + /* data sel type */ + enum eDat_Sel_Typ + { + edst_closest = 1, edst_less_than = 2, edst_greater_than = 3, edst_eless_than = 4, edst_egreater_than = 5 + }; + + /* fill sel type */ + enum eFil_Sel_Typ + { + efst_min = 1, efst_max = 2, efst_mean = 3, efst_min_mean = 4, efst_max_mean = 5, efst_user_def = 6, efst_same_in = 7 + }; + + /* structuring element */ + enum eStr_Ele + { + ese_disk = 1, ese_square = 2 + }; + + /** operation */ + enum eOP { + eOP_N = 1, eOP_T = 2, eOP_C = 3 + }; + + /* Exec type */ + enum eET { + eET_Matrix = 1, eET_Vector = 2 + }; + + /* quad_data coefficients */ + + // 1: eqt_tanh_sinh_int_n1_p1 -> int_-1^1 f(x) dx + // 2: eqt_exp_sinh_int_0_pinfty -> int_0^infty f(x) dx + // 3: eqt_exp_exp_int_0_pinfty -> int_0^infty f(x)exp(-x) dx + // 4: eqt_sinh_sinh_int_ninfty_pinfty -> int_-infty^infty f(x) dx + + // 5: eqt_fourier_sin_int_0_pinfty -> int_0^infty f(x)sin(wx) dx + // 6: eqt_fourier_cos_int_0_pinfty -> int_0^infty f(x)Cos(wx) dx + + // 7: eqt_gauss_legendre_int_n1_p1 -> int_-1^1 f(x) dx + + // 8: eqt_gauss_hermite_x0_int_ninfty_pinfty -> int_-infty^infty f(x) x^0 Exp[-x^2] dx + // 9: eqt_gauss_hermite_x1_int_ninfty_pinfty -> int_-infty^infty f(x) |x|^1 Exp[-x^2] dx + // 10: eqt_gauss_hermite_x2_int_ninfty_pinfty -> int_-infty^infty f(x) |x|^2 Exp[-x^2] dx + + // 11: eqt_gauss_laguerre_x0_int_0_pinfty -> int_0^infty f(x) x^0 Exp[-x] dx + // 12: eqt_gauss_laguerre_x1_int_0_pinfty -> int_0^infty f(x) x^1 Exp[-x] dx + // 13: eqt_gauss_laguerre_x2_int_0_pinfty -> int_0^infty f(x) x^2 Exp[-x] dx + // 14: eqt_gauss_laguerre_xi2_int_0_pinfty -> int_0^infty f(x) Exp[-x]/Sqrt[x] dx + + // 15: eqt_legendre -> legendre, (a, b) + // 16: eqt_chebyshev -> (a, b) ((b-x)*(x-a))^(-0.5) + // 17: eqt_gegenbauer -> (a, b) ((b-x)*(x-a))^alpha + // 18: eqt_jacobi -> (a, b) (b-x)^alpha*(x-a)^beta + // 19: eqt_laguerre -> (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 20: eqt_hermite -> (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 21: eqt_exponential -> (a, b) |x-(a+b)/2.0|^alpha + // 22: eqt_rational -> (a, inf) (x-a)^alpha*(x+b)^beta + + enum eQuad_Typ + { + eqt_none = 0, eqt_tanh_sinh_int_n1_p1 = 1, eqt_exp_sinh_int_0_pinfty = 2, eqt_exp_exp_int_0_pinfty = 3, + eqt_sinh_sinh_int_ninfty_pinfty = 4, eqt_fourier_sin_int_0_pinfty = 5, eqt_fourier_cos_int_0_pinfty = 6, + eqt_gauss_legendre_int_n1_p1 = 7, eqt_gauss_hermite_x0_int_ninfty_pinfty = 8, eqt_gauss_hermite_x1_int_ninfty_pinfty = 9, + eqt_gauss_hermite_x2_int_ninfty_pinfty = 10, eqt_gauss_laguerre_x0_int_0_pinfty = 11, eqt_gauss_laguerre_x1_int_0_pinfty = 12, + eqt_gauss_laguerre_x2_int_0_pinfty = 13, eqt_gauss_laguerre_xi2_int_0_pinfty = 14, eqt_legendre = 15, + eqt_chebyshev = 16, eqt_gegenbauer = 17, eqt_jacobi = 18, + eqt_laguerre = 19, eqt_hermite = 20, eqt_exponential = 21, + eqt_rational = 22 + }; +} + +/* constant - enumeration comparison */ +namespace mt +{ + inline + dt_bool is_rot_ctr_none(const eRot_Ctr_Typ &type) + { + return type == mt::erct_none; + } + + inline + dt_bool is_rot_ctr_geometric_ctr(const eRot_Ctr_Typ &type) + { + return type == mt::erct_geometric_ctr; + } + + inline + dt_bool is_rot_ctr_user_def(const eRot_Ctr_Typ &type) + { + return type == mt::erct_user_def; + } +} + +/* R_xd */ +namespace mt +{ + template class R_xtd; + + template + using R_1d = T; + + template + using R_xd = typename std::conditional>::type; +} + +/* pointers functions */ +namespace mt +{ + template + dt_bool fcn_is_null_ptr(T* ptr) + { + return ptr==nullptr; + }; +} + +/* cuda grid and block constants */ +namespace mt +{ + const dt_int32 c_blk_x = 4; + const dt_int32 c_blk_y = 16; + + const dt_int32 c_thr_1d = 256; + + const dt_int32 c_thr_2d_x = 32; + const dt_int32 c_thr_2d_y = 8; + + const dt_int32 c_thr_3d_x = 32; + const dt_int32 c_thr_3d_y = 4; + const dt_int32 c_thr_3d_z = 2; +} + +#ifdef __CUDACC__ + class D_Grid_Blk + { + public: + D_Grid_Blk(): grid(), blk() {} + + D_Grid_Blk(const dim3& grid, const dim3& blk): grid(grid), blk(blk) {} + + D_Grid_Blk(const dt_int32& grid, const dt_int32& blk): grid(grid), blk(blk) {} + + dt_int32 grid_size() + { + return grid.x*grid.y*grid.z; + }; + + dt_int32 blk_size() + { + return blk.x*blk.y*blk.z; + }; + + // shared memory size reduction + dt_int32 smems_red() + { + // when there is only one warp per block, we need to allocate two warps + // worth of shared memory so that we don't index shared memory out of bounds + auto threads = blk_size(); + dt_int32 smems = (threads <= 32) ? 2*threads:threads; + + return smems; + } + + dim3 blk; // Threads + dim3 grid; // Blocks + }; + + // cuda dimension grid + + template + dt_uint32 fcn_cdg(const ST& n, const dt_int32& dn) + { + return static_cast((n + ST(dn)-ST(1))/ST(dn)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_size() + { + return dim3(mt::c_thr_1d); + } + + template + dim3 fcn_cdg_size(const ST& n) + { + return dim3(fcn_cdg(n, mt::c_thr_1d)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_1d() + { + return dim3(mt::c_thr_1d); + } + + template + dim3 fcn_cdg_1d(const ST& n) + { + return dim3(fcn_cdg(n, mt::c_thr_1d)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_2d() + { + return dim3(mt::c_thr_2d_x, mt::c_thr_2d_y); + } + + template + dt_uint32 fcn_cdg_2d_x(const ST& n) + { + return fcn_cdg(n, mt::c_thr_2d_x); + } + + template + dt_uint32 fcn_cdg_2d_y(const ST& n) + { + return fcn_cdg(n, mt::c_thr_2d_y); + } + + template + dim3 fcn_cdg_2d(const ST& nx, const ST& ny) + { + return dim3(fcn_cdg_2d_x(nx), fcn_cdg_2d_y(ny)); + } + + /***************************************************************************************/ + dim3 fcn_cdb_3d() + { + return dim3(mt::c_thr_3d_x, mt::c_thr_3d_y, mt::c_thr_3d_z); + } + + template + dt_uint32 fcn_cdg_3d_x(const ST& n) + { + return fcn_cdg(n, mt::c_thr_3d_x); + } + + template + dt_uint32 fcn_cdg_3d_y(const ST& n) + { + return fcn_cdg(n, mt::c_thr_3d_y); + } + + template + dt_uint32 fcn_cdg_3d_z(const ST& n) + { + return fcn_cdg(n, mt::c_thr_3d_z); + } + + template + dim3 fcn_cdg_3d(const ST& nx, const ST& ny, const ST& nz) + { + return dim3(fcn_cdg_3d_x(nx), fcn_cdg_3d_y(ny), fcn_cdg_3d_z(nz)); + } + + /***************************************************************************************/ + template + void fcn_cuda_malloc(T*& data, const ST& n_data) + { + cudaMalloc((void**)&data, n_data*sizeof(T)); + } + + template + void fcn_cuda_free(T*& data) + { + if (data != nullptr) + { + cudaFree(data); + data = nullptr; + } + } + +#endif \ No newline at end of file diff --git a/src/const_enum_mt.cuh b/src/const_enum_mt.cuh new file mode 100755 index 00000000..46e93950 --- /dev/null +++ b/src/const_enum_mt.cuh @@ -0,0 +1,812 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CONST_ENUM_MT_H + #define CONST_ENUM_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "macros.h" + #include "const_enum.h" + + /*********************************************************************/ + /* enumeration definitions */ + /*********************************************************************/ + namespace mt + { + /*********************** specimen layer position *********************/ + enum eSpec_Lay_Pos + { + eslp_none = 0, eslp_top = 1, eslp_bottom = 2, eslp_middle = 3, eslp_user_def = 4 + }; + + /**************** electron microscopy simulation type *****************/ + enum eEM_Sim_Typ + { + eemst_stem = 11, eemst_istem = 12, + eemst_cbed = 21, eemst_cbei = 22, + eemst_ed = 31, eemst_hrtem = 32, + eemst_ped = 41, eemst_hctem = 42, + eemst_ewfs = 51, eemst_ewrs = 52, + eemst_stem_eels = 61, eemst_istem_eels = 62, + eemst_eftemfs = 71, eemst_eftemrs = 72, + eemst_iwfs = 81, eemst_iwrs = 82, + eemst_ppfs = 91, eemst_pprs = 92, // projected potential + eemst_tffs = 101, eemst_tfrs = 102, // transmission function + eemst_propfs = 111, eemst_proprs = 112 // fcn_propagate + }; + + /*************** electron specimen interaction model ******************/ + enum eElec_Spec_Interact_Mod + { + eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 + }; + + /************************** atomic vibration **************************/ + enum eAtomic_Vib_Mod + { + eavm_still_atom = 1, eavm_absorptive_pot = 2, eavm_frozen_phonon = 3, eavm_user_def = 4 + }; + + /********************* simulation thickness type **********************/ + enum eSim_Thick_Typ + { + estt_whole_spec = 1, estt_through_thick = 2, estt_through_slices = 3 + }; + + /************************ specimen slicing type ***********************/ + enum eSpec_Slic_Typ + { + esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + }; + + /****************** specimen slicing selection type *******************/ + enum eSpec_Slic_Sel_Typ + { + essso_tag = 1, essso_z = 2 + }; + + /*********************** feg parameterization *************************/ + // 1: doyle and Turner parameterization - 4 Gaussians - [0, 4 + // 2: Peng et al. parameterization - 5 Gaussians - [0, 4] + // 3: Peng et al. parameterization - 5 Gaussians - [0, 12] + // 4: Kirkland parameterization - 3 lorentzian + 3 Gaussians - [0, 12] + // 5: Weickenmeier and H.Kohl - a*(1-exp(-bg^2)/g^2 - [0, 12] + // 6: Lobato parameterization - 5 Hydrogen feg - [0, 12] + // 10: Peng et al. parameterization ion - 5 Gaussians - [0, 4] + + enum eAtomic_Pot_Parm_Typ + { + eappt_none = 0, eappt_doyle_0_4 = 1, eappt_peng_0_4 = 2, eappt_peng_0_12 = 3, + eappt_kirkland_0_12 = 4, eappt_weickenmeier_0_12 = 5, eappt_lobato_0_12 = 6, + eappt_peng_ion_0_4 = 10 + }; + + /*********************** incident wave type **************************/ + enum eIncident_Wave_Typ + { + eiwt_plane_wave = 1, eiwt_convergent_wave = 2, eiwt_user_def_Wave = 3, eiwt_auto = 4 + }; + + /************************** zero defocus type *************************/ + enum eZero_Def_Typ + { + ezdt_first = 1, ezdt_middle = 2, ezdt_last = 3, ezdt_user_def = 4 + }; + + /************************** scan pattern type **************************/ + enum eScan_Pat_Typ + { + espt_line = 1, espt_area = 2, espt_user_def = 3 + }; + + /************************* detector type *****************************/ + enum eDetector_Typ + { + edt_circular = 1, edt_radial = 2, edt_matrix = 3 + }; + + /************************ channelling type **************************/ + // 1: single channelling + // 2: mixed channelling + // 3: double channelling + enum eChan_Typ + { + ect_single_chan = 1, ect_mixed_chan = 2, eCT_double_chan = 3 + }; + + /**************************** in atoms ****************************/ + enum eIn_Atoms + { + eIA_yes = 1, eIA_no = 2 + }; + + /************************** slice memory type ************************/ + enum eSlice_Memory_Typ + { + esmt_none = 0, esmt_transmission = 1, esmt_potential = 2 + }; + + /************************ illumination model *************************/ + enum eIllum_Mod + { + eim_none = 0, eim_coherent = 1, eim_partial_coherent = 2, eim_trans_cross_coef = 3, eim_full_integration = 4 + }; + + /*********************** illumination incoherence **********************/ + enum eIllum_Inc + { + eii_none = 0, eii_temporal_spatial = 1, eii_temporal = 2, etst_spatial = 3 + }; + + /************************** lens variable type ***********************/ + enum eLens_Var_Typ + { + eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, + eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, + eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 + }; + + /************************ phonon model output ************************/ + enum eAtomic_Vib_Mod_Output + { + epmo_total = 1, epmo_coherent = 2, epmo_total_coherent = 3 + }; + + /********************* simulation data output ************************/ + enum eEM_Output_Typ + { + eemot_image_tot_coh = 1, eemot_image_tot = 2, + eemot_m2psi_tot_coh = 3, eemot_m2psi_tot = 4, + eemot_m2psi_tot_psi_coh = 5, eemot_psi_coh = 6, + eemot_psi_0 = 7, eemot_V = 8, eemot_trans = 9 + }; + /*********************************************************************/ + /*********************************************************************/ + } + + /*********************************************************************/ + /* enumeration comparison */ + /*********************************************************************/ + + /* specimen layer position */ + namespace mt + { + inline + dt_bool is_spec_lay_top(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_top; + } + + inline + dt_bool is_spec_lay_bottom(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_bottom; + } + + inline + dt_bool is_spec_lay_middle(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_middle; + } + + inline + dt_bool is_spec_lay_user_def(const eSpec_Lay_Pos &type) + { + return type == mt::eslp_user_def; + } + } + + /* electron microscopy simulation type */ + namespace mt + { + inline + dt_bool is_STEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_stem; + } + + inline + dt_bool is_ISTEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_istem; + } + + inline + dt_bool is_CBED(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_cbed; + } + + inline + dt_bool is_CBEI(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_cbei; + } + + inline + dt_bool is_ED(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ed; + } + + inline + dt_bool is_HRTEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_hrtem; + } + + inline + dt_bool is_PED(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ped; + } + + inline + dt_bool is_HCTEM(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_hctem; + } + + inline + dt_bool is_EWFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ewfs; + } + + inline + dt_bool is_EWRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ewrs; + } + + inline + dt_bool is_STEM_EELS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_stem_eels; + } + + inline + dt_bool is_ISTEM_EELS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_istem_eels; + } + + inline + dt_bool is_STEM_ISTEM_EELS(const eEM_Sim_Typ &sim_type) + { + return is_STEM_EELS(sim_type) || is_ISTEM_EELS(sim_type); + } + + inline + dt_bool is_EFTEMFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_eftemfs; + } + + inline + dt_bool is_EFTEMRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_eftemrs; + } + + inline + dt_bool is_EFTEM(const eEM_Sim_Typ &sim_type) + { + return is_EFTEMFS(sim_type) || is_EFTEMRS(sim_type); + } + + inline + dt_bool is_IWFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_iwfs; + } + + inline + dt_bool is_IWRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_iwrs; + } + + inline + dt_bool is_PPFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_ppfs; + } + + inline + dt_bool is_PPRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_pprs; + } + + inline + dt_bool is_TFFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_tffs; + } + + inline + dt_bool is_TFRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_tfrs; + } + + inline + dt_bool is_PropFS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_propfs; + } + + inline + dt_bool is_PropRS(const eEM_Sim_Typ &sim_type) + { + return sim_type == mt::eemst_proprs; + } + + inline + dt_bool is_STEM_ISTEM(const eEM_Sim_Typ &sim_type) + { + return is_STEM(sim_type) || is_ISTEM(sim_type); + } + + inline + dt_bool is_CBED_CBEI(const eEM_Sim_Typ &sim_type) + { + return is_CBED(sim_type) || is_CBEI(sim_type); + } + + inline + dt_bool is_ED_HRTEM(const eEM_Sim_Typ &sim_type) + { + return is_ED(sim_type) || is_HRTEM(sim_type); + } + + inline + dt_bool is_PED_HCTEM(const eEM_Sim_Typ &sim_type) + { + return is_PED(sim_type) || is_HCTEM(sim_type); + } + + inline + dt_bool is_EWFS_EWRS(const eEM_Sim_Typ &sim_type) + { + return is_EWFS(sim_type) || is_EWRS(sim_type); + } + + inline + dt_bool is_EELS_EFTEM(const eEM_Sim_Typ &sim_type) + { + return is_STEM_ISTEM_EELS(sim_type) || is_EFTEM(sim_type); + } + + inline + dt_bool is_IWFS_IWRS(const eEM_Sim_Typ &sim_type) + { + return is_IWFS(sim_type) || is_IWRS(sim_type); + } + + inline + dt_bool is_PPFS_PPRS(const eEM_Sim_Typ &sim_type) + { + return is_PPFS(sim_type) || is_PPRS(sim_type); + } + + inline + dt_bool is_TFFS_TFRS(const eEM_Sim_Typ &sim_type) + { + return is_TFFS(sim_type) || is_TFRS(sim_type); + } + + inline + dt_bool is_PropFS_PropRS(const eEM_Sim_Typ &sim_type) + { + return is_PropFS(sim_type) || is_PropRS(sim_type); + } + + inline + dt_bool is_grid_FS(const eEM_Sim_Typ &sim_type) + { + auto bb = is_CBED(sim_type) || is_ED(sim_type) || is_PED(sim_type) || is_EWFS(sim_type); + bb = bb || is_EFTEMFS(sim_type) || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); + return bb; + } + + inline + dt_bool is_grid_RS(const eEM_Sim_Typ &sim_type) + { + return !is_grid_FS(sim_type); + } + + inline + dt_bool is_simulation_type_FS(const eEM_Sim_Typ &sim_type) + { + auto bb = is_STEM(sim_type) || is_CBED(sim_type) || is_ED(sim_type); + bb = bb || is_PED(sim_type) || is_EWFS(sim_type) || is_STEM_EELS(sim_type); + bb = bb || is_EFTEMFS(sim_type) || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); + return bb; + } + + inline + dt_bool is_simulation_type_RS(const eEM_Sim_Typ &sim_type) + { + return !is_simulation_type_FS(sim_type); + } + + inline + dt_bool is_specimen_required(const eEM_Sim_Typ &sim_type) + { + return !(is_IWFS_IWRS(sim_type) || is_PropFS_PropRS(sim_type)); + } + + inline + dt_bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS(const eEM_Sim_Typ &sim_type) + { + return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEMRS(sim_type); + } + + inline + dt_bool is_CBED_ED_EWFS_PED(const eEM_Sim_Typ &sim_type) + { + return is_CBED(sim_type) || is_ED(sim_type) || is_EWFS(sim_type) || is_PED(sim_type); + } + + inline + dt_bool is_obj_lens_temp_spat(const eEM_Sim_Typ &sim_type) + { + return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEMRS(sim_type); + } + + inline + dt_bool is_cond_lens_temp_spat(const eEM_Sim_Typ &sim_type) + { + return is_STEM_ISTEM(sim_type) || is_CBED_CBEI(sim_type) || is_STEM_ISTEM_EELS(sim_type) || is_EFTEM(sim_type); + } + + inline + eSpace get_simulation_space(const eEM_Sim_Typ &sim_type) + { + return (is_simulation_type_FS(sim_type) || is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS(sim_type))?mt::esp_fourier:mt::esp_real; + } + + inline + dt_bool is_scanning(const eEM_Sim_Typ &sim_type) + { + return is_STEM_ISTEM(sim_type) || is_STEM_ISTEM_EELS(sim_type); + } + } + + /* electron specimen interaction model */ + namespace mt + { + inline + dt_bool is_multislice(const eElec_Spec_Interact_Mod& int_model) + { + return int_model == mt::eesim_multislice; + } + + inline + dt_bool is_phase_object(const eElec_Spec_Interact_Mod& int_model) + { + return int_model == mt::eesim_phase_object; + } + + inline + dt_bool is_weak_phase_object(const eElec_Spec_Interact_Mod& int_model) + { + return int_model == mt::eesim_weak_phase_object; + } + } + + /* atomic vibration */ + namespace mt + { + inline + dt_bool is_avm_still_atom(const eAtomic_Vib_Mod& av_model) + { + return av_model == eavm_still_atom; + } + + inline + dt_bool is_avm_absorptive_pot(const eAtomic_Vib_Mod& av_model) + { + return av_model == eavm_absorptive_pot; + } + + inline + dt_bool is_avm_frozen_phonon(const eAtomic_Vib_Mod& av_model) + { + return av_model == eavm_frozen_phonon; + } + + inline + dt_bool is_avm_frozen_phonon_sgl_conf(const eAtomic_Vib_Mod& av_model, const dt_bool& av_sgl_conf) + { + return is_avm_frozen_phonon(av_model) && av_sgl_conf; + } + } + + /* simulation thickness type */ + namespace mt + { + inline + dt_bool is_sim_whole_spec(const eSim_Thick_Typ& thick_type) + { + return thick_type == estt_whole_spec; + } + + inline + dt_bool is_sim_through_thick(const eSim_Thick_Typ& thick_type) + { + return thick_type == estt_through_thick; + } + + inline + dt_bool is_sim_through_slices(const eSim_Thick_Typ& thick_type) + { + return thick_type == estt_through_slices; + } + } + + /* specimen slicing type */ + namespace mt + { + inline + dt_bool is_spec_slic_by_plns_proj(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt:: esst_plns_proj; + } + + + inline + dt_bool is_spec_slic_by_dz_proj(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_dz_proj; + } + + dt_bool is_spec_slic_by_plns_sub(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt:: esst_plns_sub; + } + + inline + dt_bool is_spec_slic_by_dz_sub(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_dz_sub; + } + + inline + dt_bool is_spec_slic_by_user_def(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_user_def; + } + + inline + dt_bool is_spec_slic_by_auto(const eSpec_Slic_Typ& spec_slic_typ) + { + return spec_slic_typ == mt::esst_auto; + } + + inline + dt_bool is_spec_slic_by_planes(const eSpec_Slic_Typ& spec_slic_typ) + { + return is_spec_slic_by_plns_proj(spec_slic_typ) || is_spec_slic_by_plns_sub(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_plns_proj(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_plns_proj(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_dz_proj(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_dz_proj(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_plns_sub(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_plns_sub(spec_slic_typ); + } + + inline + dt_bool is_spec_slic_by_dz_sub(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ) + { + return mt::is_multislice(int_model) && is_spec_slic_by_dz_sub(spec_slic_typ); + } + + + inline + dt_bool is_spec_slic_planes_sub_whole_spec(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ, const eSim_Thick_Typ& thick_type) + { + return mt::is_spec_slic_by_plns_sub(int_model, spec_slic_typ) && is_sim_whole_spec(thick_type); + } + + inline + dt_bool is_spec_slic_by_dz_sub_whole_spec(const eElec_Spec_Interact_Mod& int_model, const eSpec_Slic_Typ& spec_slic_typ, const eSim_Thick_Typ& thick_type) + { + return mt::is_spec_slic_by_dz_sub(int_model, spec_slic_typ) && is_sim_whole_spec(thick_type); + } + } + + /* specimen slicing selection type */ + namespace mt + { + inline + dt_bool is_spec_slic_sel_typ_by_tag(const eSpec_Slic_Sel_Typ& spec_slic_sel_typ) + { + return spec_slic_sel_typ == essso_tag; + } + + inline + dt_bool is_spec_slic_sel_typ_by_z(const eSpec_Slic_Sel_Typ& spec_slic_sel_typ) + { + return spec_slic_sel_typ == essso_z; + } + + } + + /* incident wave type */ + namespace mt + { + inline + dt_bool is_plane_wave(const eIncident_Wave_Typ& iw_type) + { + return iw_type == eiwt_plane_wave; + } + + inline + dt_bool is_convergent_wave(const eIncident_Wave_Typ& iw_type) + { + return iw_type == eiwt_convergent_wave; + } + + inline + dt_bool is_user_define_wave(const eIncident_Wave_Typ& iw_type) + { + return iw_type == eiwt_user_def_Wave; + } + } + + /* zero defocus type */ + namespace mt + { + inline + dt_bool is_zdt_first(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_first; + } + + inline + dt_bool is_zdt_middle(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_middle; + } + + inline + dt_bool is_zdt_last(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_last; + } + + inline + dt_bool is_zdt_user_def(const eZero_Def_Typ& zero_def_typ) + { + return zero_def_typ == ezdt_user_def; + } + } + + /* detector type */ + namespace mt + { + inline + dt_bool is_detector_circular(const eDetector_Typ& det_type) + { + return det_type == edt_circular; + } + + inline + dt_bool is_detector_radial(const eDetector_Typ& det_type) + { + return det_type == edt_radial; + } + + inline + dt_bool is_detector_matrix(const eDetector_Typ& det_type) + { + return det_type == edt_matrix; + } + } + + /* scan pattern type */ + namespace mt + { + dt_bool is_scan_pat_line(const eScan_Pat_Typ& scan_pat_type) + { + return scan_pat_type == espt_line; + } + + dt_bool is_scan_pat_area(const eScan_Pat_Typ& scan_pat_type) + { + return scan_pat_type == espt_area; + } + + dt_bool is_scan_pat_user_def(const eScan_Pat_Typ& scan_pat_type) + { + return scan_pat_type == espt_user_def; + } + } + + /* mixture */ + namespace mt + { + inline + dt_bool is_EWFS_SC(const eEM_Sim_Typ &sim_type, const eAtomic_Vib_Mod& av_model, const dt_bool& pn_sgl_conf) + { + return is_EWFS(sim_type) && (!is_avm_frozen_phonon(av_model) || is_avm_frozen_phonon_sgl_conf(av_model, pn_sgl_conf)); + } + + inline + dt_bool is_EWRS_SC(const eEM_Sim_Typ &sim_type, const eAtomic_Vib_Mod& av_model, const dt_bool& pn_sgl_conf) + { + return is_EWRS(sim_type) && (!is_avm_frozen_phonon(av_model) || is_avm_frozen_phonon_sgl_conf(av_model, pn_sgl_conf)); + } + + inline + dt_bool is_EWFS_EWRS_SC(const eEM_Sim_Typ &sim_type, const eAtomic_Vib_Mod& av_model, const dt_bool& pn_sgl_conf) + { + return is_EWFS_SC(sim_type, av_model, pn_sgl_conf) || is_EWRS_SC(sim_type, av_model, pn_sgl_conf); + } + + inline + dt_bool is_EWFS_convergent_wave(const eEM_Sim_Typ &sim_type, const eIncident_Wave_Typ &iw_type) + { + return is_EWFS(sim_type) && is_convergent_wave(iw_type); + } + + inline + dt_bool is_EWRS_convergent_wave(const eEM_Sim_Typ &sim_type, const eIncident_Wave_Typ &iw_type) + { + return is_EWRS(sim_type) && is_convergent_wave(iw_type); + } + + inline + dt_bool is_EW_convergent_wave(const eEM_Sim_Typ &sim_type, const eIncident_Wave_Typ &iw_type) + { + return is_EWFS_EWRS(sim_type) && is_convergent_wave(iw_type); + } + + inline + eIncident_Wave_Typ validate_incident_wave_type(const eEM_Sim_Typ &sim_type, eIncident_Wave_Typ iw_type) + { + if (iw_type == eiwt_auto) + { + auto bb = is_scanning(sim_type) || is_CBED_CBEI(sim_type); + bb = bb || ((is_EWFS_EWRS(sim_type) || is_EFTEM(sim_type) || is_IWFS_IWRS(sim_type)) && is_convergent_wave(iw_type)); + iw_type = (bb)?mt::eiwt_convergent_wave:mt::eiwt_plane_wave; + } + + return iw_type; + } + } + +#endif \ No newline at end of file diff --git a/src/cpu_detail.hpp b/src/cpu_detail.hpp new file mode 100755 index 00000000..e960cbbd --- /dev/null +++ b/src/cpu_detail.hpp @@ -0,0 +1,80 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CPU_DETAIL_H + #define CPU_DETAIL_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + + #include "macros.h" + #include "const_enum.h" + #include "math_mt.h" + #include "types.cuh" + #include "type_traits_gen.h" + + namespace mt + { + /* for loops */ + namespace cpu_detail + { + template + void for_loop(const iThread_Rect_1d& range, TFcn& fcn, TArgs& ...arg) + { + for(auto ixy = range.ind_0; ixy < range.ind_e; ixy++) + { + fcn(ixy, arg...); + } + } + + template + void for_loop(const iThread_Rect_2d& range, TFcn& fcn, TArgs& ...arg) + { + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + fcn(ix, iy, arg...); + } + } + } + + template + void for_loop(const iThread_Rect_3d& range, TFcn& fcn, TArgs& ...arg) + { + for(auto iz = range.iz_0; iz < range.iz_e; iz++) + { + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + fcn(ix, iy, iz, arg...); + } + } + } + } + } + + } + +#endif diff --git a/src/cpu_fcns.hpp b/src/cpu_fcns.hpp deleted file mode 100644 index d9d53d2c..00000000 --- a/src/cpu_fcns.hpp +++ /dev/null @@ -1,3834 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef CPU_FCNS_H -#define CPU_FCNS_H - -#include -#include -#include -#include -#include -#include - -#include -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "fft.cuh" -#include "stream.cuh" -#include "lapack.hpp" -#include "lin_alg_def.cuh" -#include "atomic_data_mt.hpp" - -#include "cgpu_fcns.cuh" -#include "quadrature.hpp" - -namespace mt -{ - // median filter 1d - template - TVector ftr_median_1d(Stream &stream, TVector &Im_i, int nkr); - - // median filter 2d - template - TVector ftr_median_2d(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr); - - // wiener filter 1d - template - TVector ftr_wiener_1d(Stream &stream, TVector &Im_i, int nkr); - - // wiener filter 2d - template - TVector ftr_wiener_2d(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr); - - // den poiss - template - TVector ftr_poiss_dnois_1d(Stream &stream, TVector &Im_i, int nkr_w, int nkr_m); - - // get peak signal to noise ratio PSNR - template - Value_type get_PSNR(Stream &stream, TVector &Im_i, TVector &Im_d); - - // gray opening - template - TVector morp_g_open(Stream &stream, int ny_i, int nx_i, TVector &Im_i, int nkr); - - // thresholding - template - TVector thresholding(Stream &stream, TVector &v_i, Value_type thr); - - template - class Neigh_2d; - - namespace host_detail - { - template - void matrix_iter(const Range_2d &range, TFn &fn, TArg &...arg) - { - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - fn(ix, iy, arg...); - } - } - } - - template - void matrix_iter_yx(const Range_2d &range, TFn &fn, TArg &...arg) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - fn(ix, iy, arg...); - } - } - } - - template - void vector_iter(const Range_2d &range, TFn &fn, TArg &...arg) - { - for (auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - fn(ixy, arg...); - } - } - - template - T atom_cost_function(const Grid_2d &grid_2d, const Atom_Sa &atom_Ip, rVector M_i) - { - T sum = 0; - - for (auto ix_0 = 0; ix_0 < atom_Ip.ixn; ix_0++) - { - for (auto iy_0 = 0; iy_0 < atom_Ip.iyn; iy_0++) - { - int ix = ix_0 + atom_Ip.ix_0; - int iy = iy_0 + atom_Ip.iy_0; - - T R2 = grid_2d.R2(ix, iy, atom_Ip.x, atom_Ip.y); - if (R2 < atom_Ip.R2_max) - { - int ixy = grid_2d.ind_col(ix, iy); - T M = M_i[ixy]; - const T V = host_device_detail::eval_cubic_poly(R2, atom_Ip); - sum += (V - 2 * M)*V; - } - } - } - - return sum; - } - - template - void subtract_atom(Stream &stream, const Grid_2d &grid_2d, const Atom_Sa &atom_Ip, rVector M_i) - { - for (auto ix_0 = 0; ix_0 < atom_Ip.ixn; ix_0++) - { - int iyc = 0; - for (auto iy_0 = 0; iy_0 < atom_Ip.iyn; iy_0++) - { - int ix = ix_0 + atom_Ip.ix_0; - int iy = iy_0 + atom_Ip.iy_0; - - T R2 = grid_2d.R2(ix, iy, atom_Ip.x, atom_Ip.y); - if (R2 < atom_Ip.R2_max) - { - int ixy = grid_2d.ind_col(ix, iy); - - const T V = host_device_detail::eval_cubic_poly(R2, atom_Ip); - - atom_Ip.iv[iyc] = ixy; - atom_Ip.v[iyc] = V; - iyc++; - } - } - - stream.stream_mutex.lock(); - for (auto iy_0 = 0; iy_0 < iyc; iy_0++) - { - M_i.V[atom_Ip.iv[iy_0]] -= atom_Ip.v[iy_0]; - } - stream.stream_mutex.unlock(); - } - } - - // Linear projected potential: V and zV - template - void linear_Vz(const Q1, e_host> &qz, TAtom &atom) - { - using T = Value_type; - - for (auto iR = 0; iR < c_nR; iR++) - { - T R2 = atom.R2[iR]; - T V = 0; - T dVir = 0; - - T a = (atom.split) ? (-atom.z0h) : (atom.zeh - atom.z0h); - T b = (atom.split) ? (atom.z0h) : (atom.zeh + atom.z0h); - for (auto ix = 0; ix < qz.size(); ix++) - { - T z = a*qz.x[ix] + b; - T r = sqrt(z*z + R2); - T V0s, dV0s; - Vr_dVrir(r, atom.cl, atom.cnl, a*qz.w[ix], V0s, dV0s); - V += V0s; - dVir += dV0s; - } - - if (atom.split) - { - T a = atom.zeh; - T b = atom.zeh; - for (auto ix = 0; ix < qz.size(); ix++) - { - T z = a*qz.x[ix] + b; - T r = sqrt(z*z + R2); - T V0s, dV0s; - Vr_dVrir(r, atom.cl, atom.cnl, a*qz.w[ix], V0s, dV0s); - V += V0s; - dVir += dV0s; - } - } - - dVir = 0.5*dVir; - - auto R2_tap = atom.R2_tap; - auto tap_cf = atom.tap_cf; - host_device_detail::apply_tapering(R2_tap, tap_cf, R2, V, dVir); - atom.c0[iR] = V; // V_0 - atom.c1[iR] = dVir; // dR2V0 - } - } - - // Get Local interpolation coefficients - template - void cubic_poly_coef(TAtom &atom) - { - for (auto iR = 0; iR < c_nR - 1; iR++) - { - host_device_detail::cubic_poly_coef(iR, atom); - } - } - - // Cubic polynomial evaluation - template - void eval_cubic_poly(Stream &stream, Grid_2d &grid_2d, Atom_Vp &atom, rVector M_o) - { - for (auto ix_0 = 0; ix_0 < atom.nx; ix_0++) - { - int iyc = 0; - for (auto iy_0 = 0; iy_0 < atom.ny; iy_0++) - { - int ix = ix_0 + atom.ix_0; - int iy = iy_0 + atom.iy_0; - const auto R2 = grid_2d.R2(ix, iy, atom.x, atom.y); - - if (R2 < atom.R2_max) - { - const T V = atom.occ*host_device_detail::eval_cubic_poly(R2, atom); - const int ixy = grid_2d.ind_col_pbc_shift(ix, iy); - - atom.iv[iyc] = ixy; - atom.v[iyc] = V; - iyc++; - } - } - - stream.stream_mutex.lock(); - for (auto iy_0 = 0; iy_0 < iyc; iy_0++) - { - M_o.V[atom.iv[iy_0]] += atom.v[iy_0]; - } - stream.stream_mutex.unlock(); - } - } - - // Gaussian evaluation - template - void gauss_eval(Stream &stream, Grid_2d &grid_2d, Gauss_Sp &gauss, rVector M_o) - { - for (auto ix_0 = 0; ix_0 < gauss.nx; ix_0++) - { - int iyc = 0; - for (auto iy_0 = 0; iy_0 < gauss.ny; iy_0++) - { - int ix = ix_0 + gauss.ix_0; - int iy = iy_0 + gauss.iy_0; - - T R2 = grid_2d.R2(ix, iy, gauss.x, gauss.y); - if (R2 < gauss.R2_max) - { - gauss.iv[iyc] = grid_2d.ind_col_pbc(ix, iy); - gauss.v[iyc] = gauss(R2); - iyc++; - } - } - - stream.stream_mutex.lock(); - for (auto iy_0 = 0; iy_0 < iyc; iy_0++) - { - M_o.V[gauss.iv[iy_0]] += gauss.v[iy_0]; - } - stream.stream_mutex.unlock(); - } - } - - template - Value_type Lorentz_factor(Stream &stream, TGrid &grid_2d, EELS> &eels) - { - using T_r = Value_type; - T_r sum = 0; - - auto thr_Lorentz_factor = [&](const Range_2d &range) - { - T_r sum_partial = 0; - matrix_iter(range, host_device_detail::Lorentz_factor, grid_2d, eels.gc2, eels.ge2, sum_partial); - - stream.stream_mutex.lock(); - sum += sum_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_Lorentz_factor); - - return sqrt(eels.occ) / sum; - } - - template - void fit_log_gauss_a_sigma(const TVector &x2_i, const TVector &y_i, Value_type &a1, Value_type &a0) - { - using T = Value_type; - - // get a, sigma - T sx1x1 = 0; - T sx2x2 = 0; - T sx1x2 = 0; - T sx1y = 0; - T sx2y = 0; - for (auto ix = 0; ix < x2_i.size(); ix++) - { - T f = x2_i[ix]; - T x1 = f; - T x2 = 1; - T y = y_i[ix]; - - sx1x1 += x1*x1; - sx2x2 += x2*x2; - sx1x2 += x1*x2; - sx1y += x1*y; - sx2y += x2*y; - } - - T det = sx1x1*sx2x2 - sx1x2*sx1x2; - a1 = (sx2x2*sx1y - sx1x2*sx2y) / det; - a0 = (sx1x1*sx2y - sx1x2*sx1y) / det; - } - - template - void fit_gauss_a_c(const TVector &x2_i, const TVector &y_i, Value_type lambdai, - Value_type sigma, Value_type &a, Value_type &c) - { - using T = Value_type; - - // get a, c - T c_0 = 0.5 / pow(sigma, 2); - T sx1x1 = 0; - T sx2x2 = 0; - T sx1x2 = 0; - T sx1y = 0; - T sx2y = 0; - for (auto ix = 0; ix < x2_i.size(); ix++) - { - T f = exp(-c_0*x2_i[ix]); - T x1 = f; - T x2 = 1; - T y = y_i[ix]; - - sx1x1 += x1*x1; - sx2x2 += x2*x2; - sx1x2 += x1*x2; - sx1y += x1*y; - sx2y += x2*y; - } - T lambda = lambdai*(sx1x1 + sx2x2); - sx1x1 += lambda; - sx2x2 += lambda; - - T det = sx1x1*sx2x2 - sx1x2*sx1x2; - a = (sx2x2*sx1y - sx1x2*sx2y) / det; - c = (sx1x1*sx2y - sx1x2*sx1y) / det; - } - - template - Value_type fit_gauss_a(const TVector &x2_i, const TVector &y_i, Value_type sigma) - { - using T = Value_type; - - // get a = sum xy/sum x^2 - T c_0 = 0.5 / pow(sigma, 2); - - T sx1x1 = 0; - T sx1y = 0; - for (auto ix = 0; ix < x2_i.size(); ix++) - { - T x1 = exp(-c_0*x2_i[ix]); - T y = y_i[ix]; - - sx1x1 += x1*x1; - sx1y += x1*y; - } - - return sx1y / sx1x1; - } - - template - Value_type fit_gauss_sigma(const TVector &x2_i, const TVector &y_i, Value_type a, - Value_type &sigma, Value_type sigma_min, Value_type sigma_max, - int nit, Value_type d_sigma_error) - { - using T = Value_type; - - T sigma_o = sigma; - // get b = sum xy/sum x^2 - for (auto it = 0; it < nit; it++) - { - T c_0 = 0.5 / pow(sigma, 2); - T c_1 = a / pow(sigma, 3); - - T sx1x1 = 0; - T sx1y = 0; - for (auto ix = 0; ix < x2_i.size(); ix++) - { - T f = exp(-c_0*x2_i[ix]); - T x1 = c_1*x2_i[ix] * f; - T y = y_i[ix] - a*f; - - sx1x1 += x1*x1; - sx1y += x1*y; - } - T d_sigma = sx1y / sx1x1; - sigma += d_sigma; - // sigma = min(max(sigma, sigma_min), sigma_max); - - if (sigma <= sigma_min) - { - sigma = sigma_min; - break; - } - - if (sigma >= sigma_max) - { - sigma = sigma_max; - break; - } - - if (fabs(d_sigma / sigma) < d_sigma_error) - { - break; - } - } - - return sigma - sigma_o; - } - - template - Value_type fit_gauss_w_a(const TVector &x2_i, const TVector &y_i, Value_type sigma) - { - using T = Value_type; - - // get a = sum xy/sum x^2 - T c_0 = 0.5 / pow(sigma, 2); - - T sx1x1 = 0; - T sx1y = 0; - for (auto ix = 0; ix < x2_i.size(); ix++) - { - // T w = 1/::fmax(x2_i[ix], 0.001); - T w = x2_i[ix]; - T x1 = exp(-c_0*x2_i[ix]); - T y = w*y_i[ix]; - - sx1x1 += w*x1*x1; - sx1y += x1*y; - } - - return sx1y / sx1x1; - } - - template - Value_type fit_gauss_w_sigma(const TVector &x2_i, const TVector &y_i, Value_type a, - Value_type &sigma, Value_type sigma_min, Value_type sigma_max, - int nit, Value_type d_sigma_error) - { - using T = Value_type; - - T sigma_o = sigma; - // get b = sum xy/sum x^2 - for (auto it = 0; it < nit; it++) - { - T c_0 = 0.5 / pow(sigma, 2); - T c_1 = a / pow(sigma, 3); - - T sx1x1 = 0; - T sx1y = 0; - for (auto ix = 0; ix < x2_i.size(); ix++) - { - // T w = 1/::fmax(x2_i[ix], 0.001); - T w = x2_i[ix]; - T f = exp(-c_0*x2_i[ix]); - T x1 = c_1*x2_i[ix] * f; - T y = y_i[ix] - a*f; - - sx1x1 += w*x1*x1; - sx1y += w*x1*y; - } - T d_sigma = sx1y / sx1x1; - sigma += d_sigma; - - if (sigma <= sigma_min) - { - sigma = sigma_min; - break; - } - - if (sigma >= sigma_max) - { - sigma = sigma_max; - break; - } - - if (fabs(d_sigma / sigma) < d_sigma_error) - { - break; - } - } - - return sigma - sigma_o; - } - - } // host_detail - - /***************************************************************************/ - /***************************************************************************/ - - template - enable_if_host_vector_and_host_vector - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - M_o.assign(M_i.begin(), M_i.end()); - } - - template - typename std::enable_if::value - && is_complex>::value && !std::is_same, Value_type>::value, void>::type - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - Vector, e_host> M_h; - M_i_h = (M_i_h == nullptr) ? &M_h : M_i_h; - - // copy data to the same output type - assign(M_i, *M_i_h); - - // data transfer from CPU to GPU - M_o.assign(M_i_h->begin(), M_i_h->end()); - } - - template - typename std::enable_if::value - && (!is_complex>::value || std::is_same, Value_type>::value), void>::type - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - M_o.assign(M_i.begin(), M_i.end()); - } - - template - enable_if_host_vector - fill(Stream &stream, TVector &M_io, Value_type value_i) - { - auto thr_fill = [&](const Range_2d &range) - { - thrust::fill(M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_e, value_i); - }; - - stream.set_n_act_stream(M_io.size()); - stream.set_grid(1, M_io.size()); - stream.exec(thr_fill); - } - - template - enable_if_host_vector_and_host_vector - scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_scale = [&](const Range_2d &range) - { - thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - M_o.begin() + range.ixy_0, functor::scale(w_i)); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_scale); - } - - template - enable_if_host_vector - scale(Stream &stream, Value_type w_i, TVector &M_io) - { - scale(stream, w_i, M_io, M_io); - } - - template - enable_if_host_vector_and_host_vector - square(Stream &stream, TVector_1 &M_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_square = [&](const Range_2d &range) - { - thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - M_o.begin() + range.ixy_0, functor::square()); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_square); - } - - template - enable_if_host_vector_and_host_vector - square_scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_square_scale = [&](const Range_2d &range) - { - thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - M_o.begin() + range.ixy_0, functor::square_scale(w_i)); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_square_scale); - } - - template - enable_if_host_vector_and_host_vector - add(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_add = [&](const Range_2d &range) - { - thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, - M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add()); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_add); - } - - template - enable_if_host_vector_and_host_vector - add(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) - { - add(stream, M_i, M_io, M_io); - } - - template - enable_if_host_vector_and_host_vector - add_scale(Stream &stream, Value_type w1_i, TVector_1 &M1_i, - Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_add_scale = [&](const Range_2d &range) - { - thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, - M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add_scale_i(w1_i, w2_i)); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_add_scale); - } - - template - enable_if_host_vector_and_host_vector - add_scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) - { - using value_type = Value_type; - auto thr_add_scale = [&](const Range_2d &range) - { - thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_0, functor::add_scale(w_i)); - }; - - stream.set_n_act_stream(M_io.size()); - stream.set_grid(1, M_io.size()); - stream.exec(thr_add_scale); - } - - template - enable_if_host_vector_and_host_vector - add_square(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_add_square = [&](const Range_2d &range) - { - thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, - M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add_square_i()); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_add_square); - } - - template - enable_if_host_vector_and_host_vector - add_square(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) - { - using value_type = Value_type; - auto thr_add_square = [&](const Range_2d &range) - { - thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_0, functor::add_square()); - }; - - stream.set_n_act_stream(M_io.size()); - stream.set_grid(1, M_io.size()); - stream.exec(thr_add_square); - } - - template - enable_if_host_vector_and_host_vector - add_scale_square(Stream &stream, Value_type w1_i, TVector_1 &M1_i, Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_add_scale_square = [&](const Range_2d &range) - { - thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, - M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add_scale_square_i(w1_i, w2_i)); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_add_scale_square); - } - - template - enable_if_host_vector_and_host_vector - add_scale_square(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) - { - using value_type = Value_type; - auto thr_add_scale_square = [&](const Range_2d &range) - { - thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_0, functor::add_scale_square(w_i)); - }; - - stream.set_n_act_stream(M_io.size()); - stream.set_grid(1, M_io.size()); - stream.exec(thr_add_scale_square); - } - - template - enable_if_host_vector_and_host_vector - multiply(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_multiply = [&](const Range_2d &range) - { - thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, - M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::multiply()); - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_multiply); - } - - template - enable_if_host_vector_and_host_vector - multiply(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) - { - multiply(stream, M_i, M_io, M_io); - } - - template - enable_if_host_vector> - sum(Stream &stream, TVector &M_i) - { - using value_type = Value_type; - - value_type sum_total = 0; - value_type sum_ee = 0; - auto thr_sum = [&](const Range_2d &range) - { - auto sum_partial = thrust::reduce(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e); - - stream.stream_mutex.lock(); - host_device_detail::kh_sum(sum_total, sum_partial, sum_ee); - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(1, M_i.size()); - stream.exec(thr_sum); - - return sum_total; - } - - template - enable_if_host_vector> - sum_square(Stream &stream, TVector &M_i) - { - using T_r = Value_type_r; - - T_r sum_total = 0; - T_r sum_ee = 0; - auto thr_sum_square = [&](const Range_2d &range) - { - auto sum_partial = thrust::transform_reduce(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - functor::square(), T_r(0), functor::add()); - - stream.stream_mutex.lock(); - host_device_detail::kh_sum(sum_total, sum_partial, sum_ee); - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(1, M_i.size()); - stream.exec(thr_sum_square); - - return sum_total; - } - - template - enable_if_host_vector> - mean(Stream &stream, TVector &M_i) - { - return sum(stream, M_i) / M_i.size(); - } - - template - enable_if_host_vector - mean_var(Stream &stream, TVector &M_i, Value_type &x_mean, Value_type_r &x_var) - { - using T = Value_type; - using T_r = Value_type_r; - - x_mean = mean(stream, M_i); - - x_var = 0; - auto thr_var = [&](const Range_2d &range) - { - auto x_var_partial = thrust::transform_reduce(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, - functor::square_dif(x_mean), T_r(0), functor::add()); - - stream.stream_mutex.lock(); - x_var += x_var_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(1, M_i.size()); - stream.exec(thr_var); - - x_var = x_var / M_i.size(); - } - - template - enable_if_host_vector> - variance(Stream &stream, TVector &M_i) - { - using T = Value_type; - using T_r = Value_type_r; - - T x_mean; - T_r x_var; - mean_var(stream, M_i, x_mean, x_var); - return x_var; - } - - template - void rescale_data(const Value_type &x_mean, const Value_type &x_std, TVector &x) - { - using T = Value_type; - std::for_each(x.begin(), x.end(), [=](T &v) { v = (v - x_mean) / x_std; }); - } - - template - void rescale_data(const Value_type &x_mean, const Value_type &x_std, TVector &x, TArg &...arg) - { - rescale_data(x_mean, x_std, x); - rescale_data(x_mean, x_std, arg...); - } - - template - Value_type max_std_data(TVector &x) - { - return sqrt(variance(x)); - } - - template - Value_type max_std_data(TVector &x, TArg &...arg) - { - return ::fmax(max_std_data(x), max_std_data(arg...)); - } - - /***********************************************************************/ - template - enable_if_host_vector - exp_r_factor_1d(TGrid &grid_1d, Value_type gx, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - host_device_detail::exp_r_factor_1d(ix, grid_1d, gx, fPsi_i, fPsi_o); - } - } - - template - enable_if_host_vector - exp_r_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, - TVector_r &gy, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::exp_r_factor_2d_bc, grid_2d, alpha, gy, fPsi_i, fPsi_o); - } - - template - enable_if_host_vector - exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Value_type gx, Value_type gy, - TVector_c &fPsi_i, TVector_c &fPsi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::exp_r_factor_2d, grid_2d, gx, gy, fPsi_i, fPsi_o); - } - - template - enable_if_host_vector - mul_exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &gx, - Vector, e_host> &gy, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - using TVector_r = Vector, e_host>; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::mul_exp_r_factor_2d, grid_2d, gx, gy, fPsi_i, fPsi_o); - } - - /***********************************************************************/ - template - enable_if_host_vector - exp_g_factor_1d(TGrid &grid_1d, Value_type x, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - host_device_detail::exp_g_factor_1d(ix, grid_1d, x, fPsi_i, fPsi_o); - } - } - - template - enable_if_host_vector - exp_g_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, - TVector_r &y, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::exp_g_factor_2d_bc, grid_2d, alpha, y, fPsi_i, fPsi_o); - } - - template - enable_if_host_vector - exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Value_type x, Value_type y, - TVector_c &fPsi_i, TVector_c &fPsi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::exp_g_factor_2d, grid_2d, x, y, fPsi_i, fPsi_o); - } - - template - enable_if_host_vector - mul_exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &x, - Vector, e_host> &y, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - using TVector_r = Vector, e_host>; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::mul_exp_g_factor_2d, grid_2d, x, y, fPsi_i, fPsi_o); - } - - /***********************************************************************/ - template - enable_if_host_vector> - atom_cost_function(TGrid &grid_2d, const Atom_Sa> &atom_Ip, TVector_r &M_i) - { - return host_detail::atom_cost_function(grid_2d, atom_Ip, M_i); - } - - template - enable_if_host_vector - subtract_atom(Stream &stream, TGrid &grid_2d, Vector>, e_host> &atom_Ip, TVector_r &M_i) - { - if (stream.n_act_stream <= 0) - { - return; - } - - for (auto istream = 0; istream < stream.n_act_stream; istream++) - { - stream[istream] = std::thread(std::bind(host_detail::subtract_atom, std::ref(stream), std::ref(grid_2d), std::ref(atom_Ip[istream]), std::ref(M_i))); - } - stream.synchronize(); - } - - // Linear projected potential: V and zV - template - enable_if_host - linear_Vz(Stream &stream, ePotential_Type potential_type, TQ1 &qz, TVAtom &vatom) - { - using TAtom = Value_type; - - if (stream.n_act_stream <= 0) - { - return; - } - - auto thr_linear_Vz = [](const ePotential_Type &potential_type, TQ1 &qz, TAtom &atom) - { - if (atom.charge == 0) - { - switch (potential_type) - { - case ePT_Doyle_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Kirkland_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Weickenmeier_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Lobato_0_12: - host_detail::linear_Vz(qz, atom); - break; - } - } - else - { - switch (potential_type) - { - case ePT_Doyle_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Kirkland_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Weickenmeier_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Lobato_0_12: - host_detail::linear_Vz(qz, atom); - break; - } - } - }; - - for (auto istream = 0; istream < stream.n_act_stream - 1; istream++) - { - stream[istream] = std::thread(std::bind(thr_linear_Vz, potential_type, std::ref(qz), std::ref(vatom[istream]))); - } - - thr_linear_Vz(potential_type, qz, vatom[stream.n_act_stream - 1]); - - stream.synchronize(); - } - - // Get Local interpolation coefficients - template - enable_if_host - cubic_poly_coef(Stream &stream, TVAtom &vatom) - { - using TAtom = Value_type; - - if (stream.n_act_stream <= 0) - { - return; - } - - for (auto istream = 0; istream < stream.n_act_stream - 1; istream++) - { - stream[istream] = std::thread(std::bind(host_detail::cubic_poly_coef, std::ref(vatom[istream]))); - } - - host_detail::cubic_poly_coef(vatom[stream.n_act_stream - 1]); - - stream.synchronize(); - } - - template - enable_if_host_vector - fft1_shift(TGrid &grid_1d, TVector &M_io) - { - for (auto ix = 0; ix < grid_1d.nxh; ix++) - { - host_device_detail::fft1_shift(ix, grid_1d, M_io); - } - } - - template - enable_if_host_vector - fft2_sft_bc(Stream &stream, TGrid &grid_2d, TVector &M_io) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.nyh); - stream.exec_matrix(host_device_detail::fft2_sft_bc, grid_2d, M_io); - } - - template - enable_if_host_vector - fft2_shift(Stream &stream, TGrid &grid_2d, TVector &M_io) - { - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec_matrix(host_device_detail::fft2_shift, grid_2d, M_io); - } - - template - enable_if_host_vector> - sum_over_Det(Stream &stream, TGrid &grid_2d, Value_type g_min, Value_type g_max, TVector &M_i) - { - using T_r = Value_type; - using value_type = Value_type; - - T_r g2_min = pow(g_min, 2); - T_r g2_max = pow(g_max, 2); - value_type sum = 0; - - auto thr_sum_over_Det = [&](const Range_2d &range) - { - value_type sum_partial = 0; - host_detail::matrix_iter(range, host_device_detail::sum_over_Det, grid_2d, g2_min, g2_max, M_i, sum_partial); - - stream.stream_mutex.lock(); - sum += sum_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_sum_over_Det); - - return sum; - } - - template - enable_if_host_vector> - sum_square_over_Det(Stream &stream, TGrid &grid_2d, Value_type g_min, Value_type g_max, TVector &M_i) - { - using T_r = Value_type; - - T_r g2_min = pow(g_min, 2); - T_r g2_max = pow(g_max, 2); - T_r sum = 0; - - auto thr_sum_square_over_Det = [&](const Range_2d &range) - { - T_r sum_partial = 0; - host_detail::matrix_iter(range, host_device_detail::sum_square_over_Det, grid_2d, g2_min, g2_max, M_i, sum_partial); - - stream.stream_mutex.lock(); - sum += sum_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_sum_square_over_Det); - - return sum; - } - - template - enable_if_host_vector_and_host_vector> - sum_square_over_Det(Stream &stream, TGrid &grid_2d, TVector_1 &S_i, TVector_2 &M_i) - { - using T_r = Value_type; - - T_r sum = 0; - - auto thr_sum_square_over_Det = [&](const Range_2d &range) - { - T_r sum_partial = 0; - host_detail::matrix_iter(range, host_device_detail::sum_square_over_Det, grid_2d, S_i, M_i, sum_partial); - - stream.stream_mutex.lock(); - sum += sum_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_sum_square_over_Det); - - return sum; - } - - template - enable_if_host_vector - bandwidth_limit(Stream &stream, TGrid &grid_2d, TVector_c &M_io) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::bandwidth_limit, grid_2d, M_io); - } - - template - enable_if_host_vector - hard_aperture(Stream &stream, TGrid &grid_2d, Value_type g_max, Value_type w, TVector_c &M_io) - { - auto g2_max = pow(g_max, 2); - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::hard_aperture, grid_2d, g2_max, w, M_io); - } - - template - enable_if_host_vector - propagate(Stream &stream, TGrid &grid_2d, Value_type w, - Value_type gxu, Value_type gyu, TVector_c &psi_i, TVector_c &psi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::propagate, grid_2d, w, gxu, gyu, psi_i, psi_o); - } - - template - enable_if_host_vector_and_host_vector - transmission_function(Stream &stream, TGrid &grid_2d, eElec_Spec_Int_Model elec_spec_int_model, - Value_type w, TVector_1 &V0_i, TVector_2 &Trans_o) - { - using T_r = Value_type; - - auto thr_transmission_funtion = [&](const Range_2d &range) - { - thrust::transform(V0_i.begin() + range.ixy_0, V0_i.begin() + range.ixy_e, - Trans_o.begin() + range.ixy_0, functor::transmission_function(w, elec_spec_int_model)); - }; - - stream.set_n_act_stream(grid_2d.nxy()); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_transmission_funtion); - } - - template - enable_if_host_vector - probe(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type x, - Value_type y, Value_type gxu, Value_type gyu, TVector_c &fPsi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::probe, grid_2d, lens, x, y, gxu, gyu, fPsi_o); - - auto total = sum_square(stream, fPsi_o); - mt::scale(stream, sqrt(1.0 / total), fPsi_o); - } - - template - enable_if_host_vector - apply_CTF(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type gxu, Value_type gyu, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::apply_CTF, grid_2d, lens, gxu, gyu, fPsi_i, fPsi_o); - } - - template - enable_if_host_vector - apply_PCTF(Stream &stream, TGrid &grid_2d, Lens> &lens, TVector_c &fPsi_i, TVector_c &fPsi_o) - { - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::apply_PCTF, grid_2d, lens, fPsi_i, fPsi_o); - } - - template - enable_if_host_vector - kernel_xyz(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_x, TVector_c &k_y, TVector_c &k_z) - { - eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::kernel_xyz, grid_2d, eels, k_x, k_y, k_z); - - fft_2d.inverse(k_x); - fft_2d.inverse(k_y); - fft_2d.inverse(k_z); - } - - template - enable_if_host_vector - kernel_x(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_x) - { - eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::kernel_x, grid_2d, eels, k_x); - - fft_2d.inverse(k_x); - } - - template - enable_if_host_vector - kernel_y(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_y) - { - eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::kernel_y, grid_2d, eels, k_y); - - fft_2d.inverse(k_y); - } - - template - enable_if_host_vector - kernel_z(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_z) - { - eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::kernel_z, grid_2d, eels, k_z); - - fft_2d.inverse(k_z); - } - - template - enable_if_host_vector - kernel_mn1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_mn1) - { - eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::kernel_mn1, grid_2d, eels, k_mn1); - - fft_2d.inverse(k_mn1); - } - - template - enable_if_host_vector - kernel_mp1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_mp1) - { - eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::kernel_mp1, grid_2d, eels, k_mp1); - - fft_2d.inverse(k_mp1); - } - - /***************************************************************************/ - /***************************************************************************/ - template - enable_if_host_vector_and_host_vector - copy_to_host(Stream &stream, TVector_i &M_i, TVector_o &M_o, - TVector_i *M_i_h = nullptr) - { - mt::assign(M_i, M_o, M_i_h); - } - - template - enable_if_host_vector_and_host_vector - add_scale_to_host(Stream &stream, Value_type w_i, - TVector_i &M_i, TVector_o &M_o, TVector_i *M_i_h = nullptr) - { - mt::add_scale(stream, w_i, M_i, M_o); - } - - template - enable_if_host_vector_and_host_vector - add_scale_square_to_host(Stream &stream, Value_type w_i, - TVector_i &M_i, TVector_o &M_o, TVector_i *M_i_h = nullptr) - { - mt::add_scale_square(stream, w_i, M_i, M_o); - } - - template - enable_if_host_vector_and_host_vector - add_scale_m2psi_psi_to_host(Stream &stream, Value_type w_i, - TVector_c_i &psi_i, TVector_r_o &m2psi_o, TVector_c_o &psi_o, TVector_c_i *psi_i_h = nullptr) - { - mt::add_scale(stream, w_i, psi_i, psi_o); - mt::add_scale_square(stream, w_i, psi_i, m2psi_o); - } - - /***************************************************************************/ - /****************************** Host to Host *******************************/ - /***************************************************************************/ - template - enable_if_host_vector - assign_shift_2d(TGrid &grid_2d, TVector &M_i, TVector &M_o, - Vector, e_host> *M_i_h = nullptr) - { - Stream stream(1); - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec_matrix(host_device_detail::assign_shift_2d, grid_2d, M_i, M_o); - } - - template - enable_if_host_vector - add_scale_shift_2d(TGrid &grid_2d, Value_type w, - TVector &M_i, TVector &M_o, Vector, e_host> *M_i_h = nullptr) - { - Stream stream(1); - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec_matrix(host_device_detail::add_scale_shift_2d, grid_2d, w, M_i, M_o); - } - - template - enable_if_host_vector_and_host_vector - add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, - TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - Stream stream(1); - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec_matrix(host_device_detail::add_scale_square_shift_2d, grid_2d, w, M_i, M_o); - } - - template - enable_if_host_vector - assign_crop(TGrid &grid_2d, TVector &M_i, Range_2d &range, - TVector &M_o, Vector, e_host> *M_i_h = nullptr) - { - Stream stream(1); - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec_matrix(host_device_detail::assign_crop, grid_2d, M_i, range, M_o); - } - - template - enable_if_host_vector - assign_crop_shift_2d(TGrid &grid_2d, TVector &M_i, Range_2d &range, - TVector &M_o, Vector, e_host> *M_i_h = nullptr) - { - Stream stream(1); - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec_matrix(host_device_detail::assign_crop_shift_2d, grid_2d, M_i, range, M_o); - } - - template - enable_if_host_vector - add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, - TVector &M_i, Range_2d &range, TVector &M_o, Vector, e_host> *M_i_h = nullptr) - { - Stream stream(1); - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec_matrix(host_device_detail::add_scale_crop_shift_2d, grid_2d, w, M_i, range, M_o); - } - - template - enable_if_host_vector_and_host_vector - add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, - TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - Stream stream(1); - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec_matrix(host_device_detail::add_scale_square_crop_shift_2d, grid_2d, w, M_i, range, M_o); - } - - /***************************************************************************/ - /**********************************Transpose********************************/ - - template - enable_if_host_vector - trs(Stream &stream, const int &nrows, const int &ncols, TVector &M) - { - TVector M_t(nrows*ncols); - stream.set_n_act_stream(ncols); - stream.set_grid(ncols, nrows); - stream.exec_matrix(host_device_detail::trs, ncols, nrows, M, M_t); - M = M_t; - } - - /***********************Temporal and Spatial quadratures*********************/ - template - void obj_lens_temporal_spatial_quadratures(Lens &lens, Q1 &qt, Q2 &qs) - { - /*********************Temporal quadrature**********************/ - Quadrature quadrature; - quadrature(7, lens.ti_npts, qt); // 7: int_-infty^infty f(x) x^0 Exp[-x^2] dx - std::for_each(qt.w.begin(), qt.w.end(), [](T &v) { v = v / c_Pii2; }); - - /*********************Spatial quadrature**********************/ - qs.reserve((2 * lens.ngxs + 1)*(2 * lens.ngys + 1)); - int iqs = 0; - T sum_w = 0; - T sum_ee = 0; - T alpha = 0.5 / pow(lens.si_sigma, 2); - - for (auto ix = -lens.ngxs; ix <= lens.ngxs; ix++) - { - for (auto iy = -lens.ngys; iy <= lens.ngys; iy++) - { - T gxs = lens.gxs(ix); - T gys = lens.gys(iy); - T g2s = gxs*gxs + gys*gys; - if (g2s < lens.g2_maxs) - { - qs.x.push_back(gxs); - qs.y.push_back(gys); - T v = exp(-alpha*g2s); - qs.w.push_back(v); - host_device_detail::kh_sum(sum_w, v, sum_ee); - } - } - } - qs.resize(iqs); - std::for_each(qs.w.begin(), qs.w.end(), [sum_w](T &v) { v = v / sum_w; }); - } - - template - void cond_lens_temporal_spatial_quadratures(Lens &lens, Q1 &qt, Q2 &qs) - { - /*********************Temporal quadrature**********************/ - bool bb_ti = (lens.ti_npts > 1) && nonZero(lens.ti_sigma); - Quadrature quadrature; - - if (bb_ti) - { - double a = (isZero(lens.ti_sigma))?0:(lens.ti_a/(sqrt(c_2Pi)*lens.ti_sigma)); - double b = (isZero(lens.ti_sigma))?0:(0.5/lens.ti_sigma2()); - double c = (isZero(lens.ti_beta))?0:((1-lens.ti_a)/(2*lens.ti_beta)); - double d = (isZero(lens.ti_beta))?0:(1.0/lens.ti_beta); - - double sigma_t = sqrt(lens.ti_a*lens.ti_sigma2() + 2*(1-lens.ti_a)*lens.ti_beta2()); - double b_q = 0.5/(sigma_t*sigma_t); - - // 26, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - quadrature(26, lens.ti_npts, qt, 0, 0, 0, b_q); - - for (auto it = 0; it < lens.ti_npts; it++) - { - double r = abs(qt.x[it]); // positive - double f = a*exp(-b*r*r + b_q*r*r) + c*exp(-d*r + b_q*r*r); - qt.w[it] *= f; - } - } - else - { - qt.resize(1); - qt.x[0] = 0; - qt.w[0] = 1; - } - - /*********************Spatial quadrature**********************/ - bool bb_si = ((lens.si_rad_npts > 1) || (lens.si_azm_npts > 1)) && (nonZero(lens.si_sigma) || nonZero(lens.si_beta)); - - if(bb_si) - { - double a = (isZero(lens.si_sigma))?0:(lens.si_a/(c_2Pi*lens.si_sigma2())); - double b = (isZero(lens.si_sigma))?0:(0.5/lens.si_sigma2()); - double c = (isZero(lens.si_beta))?0:((1-lens.si_a)/(c_2Pi*lens.si_beta2())); - double d = (isZero(lens.si_beta))?0:(1.0/lens.si_beta); - - double sigma_t = sqrt((2*lens.si_a*lens.si_sigma2()+ 6*(1-lens.si_a)*lens.si_beta2())/6); - double b_q = 1.0/sigma_t; - - // radial part - Q1 qr; - // 25, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - quadrature(25, lens.si_rad_npts, qr, 1, 0, 0, b_q); - - for (auto ir = 0; ir < lens.si_rad_npts; ir++) - { - double r = abs(qr.x[ir]); // positive - double f = a*exp(-b*r*r + b_q*r) + c*exp(-d*r + b_q*r); - qr.w[ir] *= f; - } - - // Azimuth part - Q1 qa; - qa.resize(lens.si_azm_npts); - double h = c_2Pi/lens.si_azm_npts; - for (auto ia = 0; ia < lens.si_azm_npts; ia++) - { - qa.x[ia] = ia*h; - qa.w[ia] = h; - } - - qs.reserve(lens.si_rad_npts*lens.si_azm_npts); - for (auto ir = 0; ir < lens.si_rad_npts; ir++) - { - for (auto ia = 0; ia < lens.si_azm_npts; ia++) - { - double sin_theta, cos_theta; - sincos(qa.x[ia], &sin_theta, &cos_theta); - qs.x.push_back(qr.x[ir]*cos_theta); - qs.y.push_back(qr.x[ir]*sin_theta); - qs.w.push_back(qr.w[ir]*qa.w[ia]); - } - } - } - else - { - qs.resize(1); - qs.x[0] = 0; - qs.y[0] = 0; - qs.w[0] = 1; - } - } - - /***************************************************************************/ - /***************************************************************************/ - // get index (with typ = 0: bottom index for equal values and typ = 1: upper index for equal values) - inline - int getIndex(int ixmin, int ixmax, double *x, int typ, double x0) - { - int ixmid; - switch (typ) - { - case 0: - { - do { - ixmid = (ixmin + ixmax) >> 1; // divide by 2 - if (x0 <= x[ixmid]) - ixmax = ixmid; - else - ixmin = ixmid; - } while ((ixmax - ixmin) > 1); - } - break; - case 1: - { - do { - ixmid = (ixmin + ixmax) >> 1; // divide by 2 - if (x0 < x[ixmid]) - ixmax = ixmid; - else - ixmin = ixmid; - } while ((ixmax - ixmin) > 1); - } - break; - } - - if (x0 == x[ixmax]) - return ixmax; - else - return ixmin; - } - - template - void get_bn(const T &R, const int &nR, const T &dR, const T &R_max, const bool &pbc, int &iR0, int &iRn) - { - int iR_0 = static_cast(floor((R - R_max) / dR)); - int iR_e = static_cast(ceil((R + R_max) / dR)); - - if (!pbc) - { - auto set_Bound = [](const int &i, const int &n)->int { return (i < 0) ? 0 : ((i >= n) ? n - 1 : i); }; - iR_0 = set_Bound(iR_0, nR); - iR_e = set_Bound(iR_e, nR); - } - - iR0 = iR_0; - iRn = (iR_0 == iR_e) ? 0 : iR_e - iR_0 + 1; - } - - template - TVector lsf_poly_n(TVector &x, TVector &y, int n) - { - using T = Value_type; - - int m = x.size(); - n++; // add bias term - - TVector M(m*n); - for (auto in = 0; in < n; in++) - { - for (auto im = 0; im < m; im++) - { - M[in*m + im] = (in == 0) ? 1 : x[im] * M[(in - 1)*m + im]; - } - } - - TVector coef(n); - lapack::GELS gels; - gels(m, n, M.data(), 1, y.data(), coef.data()); - - return coef; - } - - template - void rdf_3d(Atom_Data> &atoms, Value_type r_max, int nr, TVector &r, TVector &rdf) - { - using T = Value_type; - - const T dr = r_max / nr; - for (auto ir = 0; ir < nr; ir++) - { - r[ir] = ir*dr; - } - thrust::fill(rdf.begin(), rdf.end(), T(0)); - - const T r2_max = pow(r_max, 2); - - const int natoms = atoms.size(); - for (int iatoms = 0; iatoms < natoms; iatoms++) - { - const r3d r_i = atoms.to_r3d(iatoms); - for (int iatoms_s = 0; iatoms_s < natoms; iatoms_s++) - { - auto d2 = atoms.norm(iatoms_s, r_i); - if ((iatoms != iatoms_s) && (d2 < r2_max)) - { - auto ir = static_cast(floor(sqrt(d2) / dr)); - rdf[ir] += 1; - } - } - } - - rdf[0] = 0; - for (auto ir = 1; ir < nr; ir++) - { - rdf[ir] = rdf[ir] / (4 * c_Pi*pow(r[ir], 2)*dr); - } - } - - /********************************************************************/ - // get two dimensional Gaussian by row - template - TVector func_gauss_1d(TGrid &grid_1d, Value_type sigma, bool shift, - Border_1d> bd, bool nb = true) - { - using T = Value_type; - - Gauss_1d gauss(bd, sigma, nb); - TVector f(grid_1d.nx); - - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - auto Rx2 = (shift) ? grid_1d.R2_shift(ix, gauss.x_c) : grid_1d.R2(ix, gauss.x_c); - f[ix] = gauss.eval_norm(Rx2); - } - - return f; - } - - // get two dimensional Gaussian Filter - template - TVector func_gauss_2d_bc(Stream &stream, TGrid &grid_2d, Value_type sigma, bool shift, - Border_1d> bd, bool nb = true) - { - using T = Value_type; - - Gauss_1d gauss(bd, sigma, nb); - TVector fy; - fy.reserve(grid_2d.ny); - - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - auto Ry2 = (shift) ? grid_2d.Ry2_shift(iy, gauss.x_c) : grid_2d.Ry2(iy, gauss.x_c); - fy.push_back(gauss.eval_norm(Ry2)); - } - - TVector f(grid_2d.nxy()); - - auto thr_gaussian = [&](const Range_2d &range) - { - for (auto ix = range.ixy_0; ix < range.ixy_e; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - f[grid_2d.ind_col(ix, iy)] = fy[iy]; - } - } - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, 1); - stream.exec(thr_gaussian); - - return f; - } - - // get two dimensional Gaussian Filter - template - TVector func_gauss_2d(Stream &stream, TGrid &grid_2d, Value_type sigma, bool shift, - Border_2d> bd, bool nb = true) - { - using T = Value_type; - - Gauss_2d gauss(bd, sigma, nb); - TVector f(grid_2d.nxy()); - - auto thr_gaussian = [&](const Range_2d &range) - { - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2 = (shift) ? grid_2d.R2_shift(ix, iy, gauss.x_c, gauss.y_c) : grid_2d.R2(ix, iy, gauss.x_c, gauss.y_c); - f[grid_2d.ind_col(ix, iy)] = gauss.eval_norm(R2); - } - } - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_gaussian); - - return f; - } - - /********************************************************************/ - // get one dimensional Hanning Filter - template - TVector func_hanning_1d(TGrid &grid_1d, Value_type k, bool shift, - Border_1d> bd, bool nb = true) - { - using T = Value_type; - - Hanning_1d hann(bd, k, nb); - TVector f(grid_1d.nx); - - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - T Rx = (shift) ? grid_1d.Rx_shift(ix, hann.x_c) : grid_1d.Rx(ix, hann.x_c); - f[ix] = hann.eval_norm(Rx); - } - - return f; - } - - // get two dimensional Hanning by row - template - TVector func_hanning_2d_bc(Stream &stream, TGrid &grid_2d, Value_type k, bool shift, - Border_1d> bd, bool nb = true) - { - using T = Value_type; - - Hanning_1d hann(bd, k, nb); - TVector fy; - fy.reserve(grid_2d.ny); - - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - T Ry = (shift) ? grid_2d.Ry_shift(iy, hann.x_c) : grid_2d.Ry(iy, hann.x_c); - fy.push_back(hann.eval_norm(Ry)); - } - - TVector f(grid_2d.nxy()); - - auto thr_hanning = [&](const Range_2d &range) - { - for (auto ix = range.ixy_0; ix < range.ixy_e; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - f[grid_2d.ind_col(ix, iy)] = fy[iy]; - } - } - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, 1); - stream.exec(thr_hanning); - - return f; - } - - // get two dimensional Hanning Filter - template - TVector func_hanning_2d(Stream &stream, TGrid &grid_2d, Value_type k, bool shift, - Border_2d> bd, bool nb = true) - { - using T = Value_type; - - Hanning_2d hann(bd, k, nb); - TVector f(grid_2d.nxy()); - - auto thr_hanning = [&](const Range_2d &range) - { - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R = (shift) ? grid_2d.R_shift(ix, iy, hann.x_c, hann.y_c) : grid_2d.R(ix, iy, hann.x_c, hann.y_c); - f[grid_2d.ind_col(ix, iy)] = hann.eval_norm(R); - } - } - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_hanning); - - return f; - } - - /********************************************************************/ - // get one dimensional Butterworth Filter - template - TVector func_butterworth_1d(TGrid &grid_1d, Value_type radius, - int n, bool shift, Border_1d> bd, bool nb = true) - { - using T = Value_type; - - Butterworth_1d butwth(bd, radius, n, nb); - TVector f(grid_1d.nx); - - for (auto ix = 0; ix < grid_1d.nx; ix++) - { - auto Rx2 = (shift) ? grid_1d.R2_shift(ix, butwth.x_c) : grid_1d.R2(ix, butwth.x_c); - f[ix] = butwth.eval_norm(Rx2); - } - - return f; - } - - // get two dimensional Butterworth Filter - template - TVector func_butterworth_2d_bc(Stream &stream, TGrid &grid_2d, Value_type radius, - int n, bool shift, Border_1d> bd, bool nb = true) - { - using T = Value_type; - - Butterworth_1d butwth(bd, radius, n, nb); - TVector fy; - - fy.reserve(grid_2d.ny); - - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - auto Ry2 = (shift) ? grid_2d.Ry2_shift(iy, butwth.x_c) : grid_2d.Ry2(iy, butwth.x_c); - fy.push_back(butwth.eval_norm(Ry2)); - } - - TVector f(grid_2d.nxy()); - - auto thr_butterworth = [&](const Range_2d &range) - { - for (auto ix = range.ixy_0; ix < range.ixy_e; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - f[grid_2d.ind_col(ix, iy)] = fy[iy]; - } - } - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, 1); - stream.exec(thr_butterworth); - - return f; - } - - // get two dimensional Butterworth Filter - template - TVector func_butterworth_2d(Stream &stream, TGrid &grid_2d, Value_type radius, - int n, bool shift, Border_2d> bd, bool nb = true) - { - using T = Value_type; - - Butterworth_2d butwth(bd, radius, n, nb); - - TVector f(grid_2d.nxy()); - - auto thr_butterworth = [&](const Range_2d &range) - { - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2 = (shift) ? grid_2d.R2_shift(ix, iy, butwth.x_c, butwth.y_c) : grid_2d.R2(ix, iy, butwth.x_c, butwth.y_c); - f[grid_2d.ind_col(ix, iy)] = butwth.eval_norm(R2); - } - } - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_butterworth); - - return f; - } - - /********************************************************************/ - // get two dimensional radial distribution for regular grid_2d - inline - void rad_dist_2d(int nR, double *R, double *fR, int nRl, double *Rl, double *rl, double *frl, double *cfrl, bool reg, int typ) - { - double Rlmin = Rl[0], Rlmax = Rl[nRl - 1], dRl = Rl[1] - Rl[0]; - - for (auto i = 0; i < nRl - 1; i++) - { - rl[i] = 0.5*(Rl[i] + Rl[i + 1]); - frl[i] = 0.0; - cfrl[i] = 0.0; - } - - int j; - for (auto i = 0; i < nR; i++) - { - if ((Rlmin <= R[i]) && (R[i] < Rlmax)) - { - j = (reg) ? (int)floor((R[i] - Rlmin) / dRl) : getIndex(0, nRl - 1, Rl, 0, R[i]); - frl[j] += fR[i]; - cfrl[j] += 1.0; - } - } - - if (typ == 0) - for (auto i = 0; i < nRl - 1; i++) - { - frl[i] /= ::fmax(1.0, cfrl[i]); - } - } - - template - void rad_dist_2d(TGrid &grid_2d, TVector &Im, Value_type x_i, - Value_type y_i, Value_type radius_i, TVector &rl, TVector &frl) - { - using T = Value_type; - - T dR = grid_2d.dRx; - int nrl = static_cast(floor(radius_i / dR + 0.5)); - T R_max = dR*nrl; - - int ix_0, ixe; - get_bn(x_i, grid_2d.nx, grid_2d.dRx, R_max, grid_2d.pbc_xy, ix_0, ixe); - ixe += ix_0; - - int iy_0, iye; - get_bn(y_i, grid_2d.ny, grid_2d.dRy, R_max, grid_2d.pbc_xy, iy_0, iye); - iye += iy_0; - - // get radial distribution - rl.resize(nrl); - frl.resize(nrl); - TVector cfrl(nrl); - - for (auto ir = 0; ir < rl.size(); ir++) - { - rl[ir] = grid_2d.Rx(ir); - frl[ir] = 0.0; - cfrl[ir] = 0.0; - } - - for (auto ix = ix_0; ix < ixe; ix++) - { - for (auto iy = iy_0; iy < iye; iy++) - { - T R = grid_2d.R(ix, iy, x_i, y_i); - if (R < R_max) - { - auto ir = static_cast(floor(R / dR)); - frl[ir] += Im[grid_2d.ind_col(ix, iy)]; - cfrl[ir] += 1.0; - } - } - } - - for (auto ir = 0; ir < rl.size(); ir++) - { - frl[ir] /= ::fmax(1.0, cfrl[ir]); - } - } - - // cumulative radial distribution - template - void cum_rad_dist_2d(TGrid &grid_2d, TVector &Im, Value_type x_i, - Value_type y_i, Value_type radius_i, TVector &rl, TVector &frl) - { - rad_dist_2d(grid_2d, Im, x_i, y_i, radius_i, rl, frl); - for (auto ir = 1; ir < frl.size(); ir++) - { - frl[ir] += frl[ir - 1]; - } - } - - // mean smooth - template - TVector smooth(TVector &f_i, Value_type nkr) - { - using T = Value_type; - - int nf_i = f_i.size(); - int nk0 = -nkr; - int nke = nkr + 1; - - TVector f_o(nf_i); - - for (auto ix = 0; ix < nf_i; ix++) - { - int it0 = max(ix + nk0, 0); - int ite = min(ix + nke, nf_i); - - T f_mean = 0; - for (auto it = it0; it < ite; it++) - { - f_mean += f_i[it]; - } - - f_o[ix] = f_mean / (ite - it0); - } - - return f_o; - } - - // mean smooth - template - TVector smooth(Stream &stream, TVector &f_i, Value_type nkr) - { - using T = Value_type; - - int nf_i = f_i.size(); - int nk0 = -nkr; - int nke = nkr + 1; - - auto krn_mean = [&](const int &ix_i, TVector &f_i, TVector &f_o) - { - int ix_0 = max(ix_i + nk0, 0); - int ixe = min(ix_i + nke, nf_i); - - T f_mean = 0; - for (auto ix = ix_0; ix < ixe; ix++) - { - f_mean += f_i[ix]; - } - - f_o[ix_i] = f_mean / (ixe - ix_0); - }; - - TVector fv(nf_i); - - auto thr_mean = [&](const Range_2d &range) - { - for (auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - krn_mean(ixy, f_i, fv); - } - }; - - stream.set_n_act_stream(nf_i); - stream.set_grid(1, nf_i); - stream.exec(thr_mean); - - return fv; - } - - /*******************************************************************/ - // add periodic boundary border to the image - template - vector add_PB_border(TGrid &grid_i, TVector_i &image_i, int border_x, int border_y, TGrid &grid_o, TVector_o &image_o) - { - Prime_Num CP; - - auto ix_0 = border_x; - auto nx = CP(grid_i.nx + 2 * border_x, eDST_Greater_Than); - auto ixe = ix_0 + grid_i.nx; - auto bx_l = border_x; - auto bx_r = nx - ixe; - - auto iy_0 = border_y; - auto ny = CP(grid_i.ny + 2 * border_y, eDST_Greater_Than); - auto iye = iy_0 + grid_i.ny; - auto by_t = border_y; - auto by_b = ny - iye; - - grid_o.set_input_data(nx, ny, nx*grid_i.dRx, ny*grid_i.dRy, grid_i.dz, grid_i.bwl, grid_i.pbc_xy); - - image_o.resize(grid_o.nxy()); - - // copy central image - for (auto ix_o = ix_0; ix_o < ixe; ix_o++) - { - for (auto iy_o = iy_0; iy_o < iye; iy_o++) - { - auto ix_i = ix_o - ix_0; - auto iy_i = iy_o - iy_0; - auto ixy_i = grid_i.ind_col(ix_i, iy_i); - auto ixy_o = grid_o.ind_col(ix_o, iy_o); - image_o[ixy_o] = image_i[ixy_i]; - } - } - - // left - for (auto ix_o = 0; ix_o < bx_l; ix_o++) - { - for (auto iy_o = iy_0; iy_o < iye; iy_o++) - { - auto ix_i = 2 * bx_l - ix_o; - auto iy_i = iy_o; - image_o[grid_o.ind_col(ix_o, iy_o)] = image_o[grid_o.ind_col(ix_i, iy_i)]; - } - } - - // right - for (auto ix_o = ixe; ix_o < grid_o.nx; ix_o++) - { - for (auto iy_o = iy_0; iy_o < iye; iy_o++) - { - auto ix_i = ixe - 2 - (ix_o - ixe); - auto iy_i = iy_o; - image_o[grid_o.ind_col(ix_o, iy_o)] = image_o[grid_o.ind_col(ix_i, iy_i)]; - } - } - - // top - for (auto ix_o = 0; ix_o < grid_o.nx; ix_o++) - { - for (auto iy_o = 0; iy_o < by_t; iy_o++) - { - auto ix_i = ix_o; - auto iy_i = 2 * by_t - iy_o; - image_o[grid_o.ind_col(ix_o, iy_o)] = image_o[grid_o.ind_col(ix_i, iy_i)]; - } - } - - // bottom - for (auto ix_o = 0; ix_o < grid_o.nx; ix_o++) - { - for (auto iy_o = iye; iy_o < grid_o.ny; iy_o++) - { - auto ix_i = ix_o; - auto iy_i = iye - 2 - (iy_o - iye); - image_o[grid_o.ind_col(ix_o, iy_o)] = image_o[grid_o.ind_col(ix_i, iy_i)]; - } - } - - vector points = { ix_0, ixe, iy_0, iye }; - - return points; - } - - /*******************************************************************/ - // add periodic boundary border to the image - template - void set_const_border(TGrid &grid_2d, TVector &image, Value_type xb_0, Value_type xb_e, - Value_type yb_0, Value_type yb_e) - { - using T = Value_type; - - int ix_0 = grid_2d.ceil_dRx(xb_0); - int ix_e = grid_2d.nx - grid_2d.ceil_dRx(xb_e); - - int iy_0 = grid_2d.ceil_dRy(yb_0); - int iy_e = grid_2d.ny - grid_2d.ceil_dRy(yb_e); - - T val_s = 0; - T val_ee = 0; - int val_c = 0; - for (auto ix = ix_0; ix < ix_e; ix++) - { - for (auto iy = iy_0; iy < iy_e; iy++) - { - auto v = image[grid_2d.ind_col(ix, iy)]; - host_device_detail::kh_sum(val_s, v, val_ee); - val_c++; - } - } - val_s = val_s / val_c; - - // left - for (auto ix = 0; ix < ix_0; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - image[grid_2d.ind_col(ix, iy)] = val_s; - } - } - - // right - for (auto ix = ix_e; ix < grid_2d.nx; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - image[grid_2d.ind_col(ix, iy)] = val_s; - } - } - - // top - for (auto ix = 0; ix < grid_2d.nx; ix++) - { - for (auto iy = 0; iy < iy_0; iy++) - { - image[grid_2d.ind_col(ix, iy)] = val_s; - } - } - - // bottom - for (auto ix = 0; ix < grid_2d.nx; ix++) - { - for (auto iy = iy_e; iy < grid_2d.ny; iy++) - { - image[grid_2d.ind_col(ix, iy)] = val_s; - } - } - } - - /*******************************************************************/ - // extract region ix_0<=x - TVector_o extract_region_real_part(Stream &stream, int nx_src, int ny_src, - TVector_i &Im_src, int ix0_src, int ixe_src, int iy0_src, int iye_src) - { - auto nx_dst = ixe_src - ix0_src; - auto ny_dst = iye_src - iy0_src; - - TVector_o Im_dst(nx_dst*ny_dst); - - auto thr_extract_region = [&](const Range_2d &range) - { - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - Im_dst[ix*ny_dst + iy] = Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)].real(); - } - } - }; - - stream.set_n_act_stream(nx_dst); - stream.set_grid(nx_dst, ny_dst); - stream.exec(thr_extract_region); - - return Im_dst; - } - - // extract real part of vector - template - TVector_o extract_real_part(Stream &stream, TVector_i &Im_src) - { - TVector_o Im_dst(Im_src.size()); - - auto thr_extract_real = [](const Range_2d &range, TVector_i &Im_src, TVector_o &Im_dst) - { - for (auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - Im_dst[ixy] = Im_src[ixy].real(); - } - }; - - stream.set_n_act_stream(Im_src.size()); - stream.set_grid(Im_src.size(), 1); - stream.exec(thr_extract_real, Im_src, Im_dst); - - return Im_dst; - } - - // extract region ix_0<=x - TVector_o extract_region_abs(Stream &stream, int nx_src, int ny_src, - TVector_i &Im_src, int ix0_src, int ixe_src, int iy0_src, int iye_src) - { - auto nx_dst = ixe_src - ix0_src; - auto ny_dst = iye_src - iy0_src; - - TVector_o Im_dst(nx_dst*ny_dst); - - auto thr_extract_region = [&](const Range_2d &range) - { - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - Im_dst[ix*ny_dst + iy] = fabs(Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)]); - } - } - }; - - stream.set_n_act_stream(nx_dst); - stream.set_grid(nx_dst, ny_dst); - stream.exec(thr_extract_region); - - return Im_dst; - } - - // extract abs of vector - template - TVector_o extract_abs(Stream &stream, TVector_i &Im_src) - { - TVector_o Im_dst(Im_src.size()); - - auto thr_extract_abs = [](const Range_2d &range, TVector_i &Im_src, TVector_o &Im_dst) - { - for (auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - Im_dst[ixy] = fabs(Im_src[ixy]); - } - }; - - stream.set_n_act_stream(Im_src.size()); - stream.set_grid(Im_src.size(), 1); - stream.exec(thr_extract_abs, Im_src, Im_dst); - - return Im_dst; - } - - /*******************************************************************/ - // get weighted position - template - r2d> Rx_Ry_weight(TGrid &grid_2d, TVector &Im, r2d> p_i, Value_type radius_i, bool env) - { - using T = Value_type; - - T dR = grid_2d.dRx; - int nrl = static_cast(floor(radius_i / dR + 0.5)); - T R_max = dR*nrl; - - auto ix_i = static_cast(floor(p_i.x / dR)); - int ix_0 = max(ix_i - nrl, 0); - int ixe = min(ix_i + nrl + 1, grid_2d.nx); - - auto iy_i = static_cast(floor(p_i.y / dR)); - int iy_0 = max(iy_i - nrl, 0); - int iye = min(iy_i + nrl + 1, grid_2d.ny); - - T R2_max = pow(R_max, 2); - - r2d p(0, 0); - - T alpha = 0.5 / pow(R_max, 2); - T wt = 0; - for (auto ix = ix_0; ix < ixe; ix++) - { - for (auto iy = iy_0; iy < iye; iy++) - { - auto R2 = grid_2d.R2(ix, iy, p_i.x, p_i.y); - if (R2 < R2_max) - { - int ixy = grid_2d.ind_col(ix, iy); - auto imv = ((env) ? exp(-alpha*R2) : 1)*Im[ixy]; - p += imv*r2d(grid_2d.Rx(ix), grid_2d.Ry(iy)); - wt += imv; - } - } - } - p /= wt; - - if (module(p - p_i) >= radius_i) - { - p = p_i; - } - - return p; - } - - // fit gaussian 1d - template - TVector fit_gauss_1d(TGrid &grid_1d, TVector &Im_i, Value_type x_i, - Value_type sigma_i, Value_type radius_i) - { - using T = Value_type; - - auto select_cir_reg = [](TGrid &grid_1d, TVector &Im, T x0, - T radius, TVector &Rx, TVector &Ix, T &Rx_sf, T &Rx_sc, T &Ix_sc) - { - T R_max = radius; - T R2_max = pow(R_max, 2); - - auto range = grid_1d.index_range(x0, R_max); - - Rx.clear(); - Rx.reserve(range.ixy_e); - Ix.clear(); - Ix.reserve(range.ixy_e); - - // select circular region - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - if (grid_1d.R2(ix, x0) < R2_max) - { - Rx.push_back(grid_1d.Rx(ix)); - Ix.push_back(Im[ix]); - } - } - - Rx_sf = x0; - Rx_sc = R_max; - - Ix_sc = max_element(Ix); - int m = Ix.size(); - for (auto ix = 0; ix < m; ix++) - { - Rx[ix] = (Rx[ix] - Rx_sf) / Rx_sc; - Ix[ix] = Ix[ix] / Ix_sc; - } - - Rx.shrink_to_fit(); - Ix.shrink_to_fit(); - }; - - TVector Rx, Ix; - T Rx_sf, Rx_sc, Ix_sc; - - select_cir_reg(grid_1d, Im_i, x_i, radius_i, Rx, Ix, Rx_sf, Rx_sc, Ix_sc); - - T sigma = sigma_i / Rx_sc; - - int m = Ix.size(); - int n = 3; - - TVector J(m*n); - TVector d_Ix(m); - - auto get_chi2 = [](TVector &Rx, TVector &Ix, TVector &coef)->T - { - T x0 = coef[0]; - T A = coef[1]; - T alpha = 0.5 / pow(coef[2], 2); - - T chi2 = 0; - T chi2_ee = 0; - const int m = Ix.size(); - for (auto im = 0; im < m; im++) - { - T x = Rx[im] - x0; - T v = Ix[im] - A*exp(-alpha*x*x); - host_device_detail::kh_sum(chi2, v*v, chi2_ee); - } - return chi2; - }; - - auto get_dIx_J = [](TVector &Rx, TVector &Ix, TVector &coef, - TVector &dIx, TVector &J) - { - T x0 = coef[0]; - T A = coef[1]; - T alpha = 0.5 / pow(coef[2], 2); - - T c_x0 = 1.0 / pow(coef[2], 2); - T c_A = 1; - T c_sx = 1.0 / pow(coef[2], 3); - - const int m = Ix.size(); - for (auto im = 0; im < m; im++) - { - T x = Rx[im] - x0; - T v = exp(-alpha*x*x); - T f = A*v; - - J[0 * m + im] = c_x0*x*f; - J[1 * m + im] = c_A*v; - J[2 * m + im] = c_sx*x*x*f; - - dIx[im] = Ix[im] - f; - } - }; - - T dx_max = ::fmax(grid_1d.dRx / Rx_sc, 0.25*::fmin(sigma, radius_i / Rx_sc)); - - vector c_coef_0 = { 0, 1, sigma }; - vector c_coef_min = { -dx_max, 0.5, sigma / 3 }; - vector c_coef_max = { dx_max, 1.25, 3 * sigma }; - - TVector coef_0 = c_coef_0; - TVector coef_min = c_coef_min; - TVector coef_max = c_coef_max; - TVector coef = coef_0; - - T chi2 = get_chi2(Rx, Ix, coef); - - T lambda = 2; - T lambda_f = 2; - - lapack::FLSF flsf; - - const int niter = 100; - for (auto iter = 0; iter < niter; iter++) - { - get_dIx_J(Rx, Ix, coef, d_Ix, J); - - TVector d_coef(n); - TVector D(n); - TVector G(n); - flsf(m, n, J.data(), d_Ix.data(), d_coef.data(), lambda, D.data(), G.data()); - - TVector coef_t = coef; - T rho_f = 0; - T G_max = 0; - for (auto ic = 0; ic < n; ic++) - { - coef_t[ic] += d_coef[ic]; - rho_f += coef_t[ic] * (D[ic] * coef_t[ic] + G[ic]); - G_max = ::fmax(G_max, fabs(G[ic])); - } - - T chi2_t = get_chi2(Rx, Ix, coef_t); - T rho = (chi2 - chi2_t) / rho_f; - - if ((G_max < 5e-7) || fabs(chi2 - chi2_t) < 5e-8) - { - break; - } - - if (rho > 0) - { - coef = coef_t; - - for (auto ic = 0; ic < n; ic++) - { - coef[ic] = min(max(coef[ic], coef_min[ic]), coef_max[ic]); - } - - chi2 = get_chi2(Rx, Ix, coef); - - lambda = (rho > 1e-6) ? (::fmax(lambda / lambda_f, 1e-7)) : lambda; - } - else - { - lambda = ::fmin(lambda*lambda_f, 1e+7); - } - } - - coef[0] = coef[0] * Rx_sc + Rx_sf; - coef[1] = coef[1] * Ix_sc; - coef[2] = coef[2] * Rx_sc; - - return coef; - } - - // fit gaussian 2d - template - TVector fit_ellipt_gauss_2d(TGrid &grid_2d, TVector &Im_i, r2d> p_i, - Value_type sigma_i, Value_type radius_i) - { - using T = Value_type; - using TRegion = Region; - - auto ellipse_var = [](const T &sx, const T &sy, const T &theta, T &a, T &b, T &c) - { - T cos_1t = cos(theta); - T sin_1t = sin(theta); - T cos_2t = cos(2 * theta); - T sin_2t = sin(2 * theta); - - T sx2 = pow(sx, 2); - T sy2 = pow(sy, 2); - - a = 0.5*(cos_1t*cos_1t / sx2 + sin_1t*sin_1t / sy2); - b = 0.5*(sin_1t*sin_1t / sx2 + cos_1t*cos_1t / sy2); - c = 0.5*(-sin_2t / sx2 + sin_2t / sy2); - }; - - auto select_cir_reg = [](TGrid &grid_2d, TVector &Im, r2d p, - T radius, TRegion ®ion) - { - T R_max = radius; - T R2_max = pow(R_max, 2); - T Rl2_max = pow(2.5*grid_2d.dR_min(), 2); - - auto range = grid_2d.index_range(p, R_max); - - region.clear(); - region.reserve(range.ixy_e); - - T I_m = 0; - T I_ee = 0; - int I_c = 0; - // select circular region - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2 = grid_2d.R2(ix, iy, p.x, p.y); - if (R2 < R2_max) - { - T v = Im[grid_2d.ind_col(ix, iy)]; - region.Rx.push_back(grid_2d.Rx(ix)); - region.Ry.push_back(grid_2d.Ry(iy)); - region.Ixy.push_back(v); - if (R2 < Rl2_max) - { - host_device_detail::kh_sum(I_m, v, I_ee); - I_c++; - } - } - - } - } - I_m = I_m / I_c; - - region.R_max = R_max; - region.Rx_sf = p.x; - region.Ry_sf = p.y; - region.Rxy_sc = R_max; - - region.Ixy_sc = (I_m + max_element(region.Ixy)) / 2; - int m = region.Ixy.size(); - for (auto ixy = 0; ixy < m; ixy++) - { - region.Rx[ixy] = (region.Rx[ixy] - region.Rx_sf) / region.Rxy_sc; - region.Ry[ixy] = (region.Ry[ixy] - region.Ry_sf) / region.Rxy_sc; - region.Ixy[ixy] = region.Ixy[ixy] / region.Ixy_sc; - } - - region.Rx.shrink_to_fit(); - region.Ry.shrink_to_fit(); - region.Ixy.shrink_to_fit(); - }; - - auto select_ellip_reg = [&](TGrid &grid_2d, TVector &Im, TVector &coef, - T f0, TRegion ®ion) - { - T x_c = coef[0]; - T y_c = coef[1]; - - T a, b, c; - ellipse_var(coef[3], coef[4], coef[5], a, b, c); - - T d = log(f0); - T dd = c*c - 4 * a*b; - - T radius_y = sqrt(fabs(4 * a*d / dd)); - T radius_x = sqrt(fabs(4 * b*d / dd)); - - T x_0 = x_c - radius_x; - T x_e = x_c + radius_x; - T y_0 = y_c - radius_y; - T y_e = y_c + radius_y; - - int ix_0 = grid_2d.ceil_dRx(x_0); - int ix_e = grid_2d.floor_dRx(x_e) + 1; - - int iy_0 = grid_2d.ceil_dRy(y_0); - int iy_e = grid_2d.floor_dRy(y_e) + 1; - - region.clear(); - region.reserve((ix_e - ix_0)*(iy_e - iy_0)); - - // select circular region - for (auto ix = ix_0; ix < ix_e; ix++) - { - T dx = grid_2d.Rx(ix) - x_c; - T ddy = sqrt(fabs(dd*dx*dx - 4 * b*d)); - - T y_0 = (-c*dx - ddy) / (2 * b) + y_c; - T y_e = (-c*dx + ddy) / (2 * b) + y_c; - - int iy_0 = grid_2d.lb_index_y(y_0); - int iy_e = grid_2d.ub_index_y(y_e) + 1; - - for (auto iy = iy_0; iy < iy_e; iy++) - { - region.Rx.push_back(grid_2d.Rx(ix)); - region.Ry.push_back(grid_2d.Ry(iy)); - region.Ixy.push_back(Im[grid_2d.ind_col(ix, iy)]); - } - } - - region.R_max = max(coef[3], coef[4]); - region.Rx_sf = x_c; - region.Ry_sf = y_c; - region.Rxy_sc = region.R_max; - - region.Ixy_sc = max_element(region.Ixy); - int m = region.Ixy.size(); - for (auto ixy = 0; ixy < m; ixy++) - { - region.Rx[ixy] = (region.Rx[ixy] - region.Rx_sf) / region.Rxy_sc; - region.Ry[ixy] = (region.Ry[ixy] - region.Ry_sf) / region.Rxy_sc; - region.Ixy[ixy] = region.Ixy[ixy] / region.Ixy_sc; - } - - region.shrink_to_fit(); - }; - - TRegion region; - - select_cir_reg(grid_2d, Im_i, p_i, radius_i, region); - - T sigma = sigma_i / region.Rxy_sc; - - auto get_chi2 = [&](TVector &Rx, TVector &Ry, TVector &Ixy, TVector &coef)->T - { - T x_0 = coef[0]; - T y_0 = coef[1]; - - T theta = coef[5]; - - T A = coef[2]; - - T a, b, c; - - ellipse_var(coef[3], coef[4], coef[5], a, b, c); - - T chi2 = 0; - T chi2_ee = 0; - const int m = Ixy.size(); - for (auto im = 0; im < m; im++) - { - T x = Rx[im] - x_0; - T y = Ry[im] - y_0; - T v = Ixy[im] - A*exp(-a*x*x - b*y*y - c*x*y); - host_device_detail::kh_sum(chi2, v*v, chi2_ee); - } - return chi2; - }; - - auto get_dIxy_J = [](TVector &Rx, TVector &Ry, TVector &Ixy, TVector &coef, - TVector &dIxy, TVector &J) - { - T x_0 = coef[0]; - T y_0 = coef[1]; - - T theta = coef[5]; - - T A = coef[2]; - - T cos_1t = cos(theta); - T sin_1t = sin(theta); - T cos_2t = cos(2 * theta); - T sin_2t = sin(2 * theta); - - T sx2 = pow(coef[3], 2); - T sy2 = pow(coef[4], 2); - - T sx3 = pow(coef[3], 3); - T sy3 = pow(coef[4], 3); - - T a = 0.5*(cos_1t*cos_1t / sx2 + sin_1t*sin_1t / sy2); - T b = 0.5*(sin_1t*sin_1t / sx2 + cos_1t*cos_1t / sy2); - T c = 0.5*(-sin_2t / sx2 + sin_2t / sy2); - - const int m = Ixy.size(); - for (auto im = 0; im < m; im++) - { - T x = Rx[im] - x_0; - T y = Ry[im] - y_0; - - T v = exp(-a*x*x - b*y*y - c*x*y); - T f = A*v; - - J[0 * m + im] = (2 * a*x + c*y)*f; - J[1 * m + im] = (2 * b*y + c*x)*f; - J[2 * m + im] = v; - J[3 * m + im] = (pow(cos_1t*x, 2) + pow(sin_1t*y, 2) - sin_2t*x*y)*f / sx3; - J[4 * m + im] = (pow(sin_1t*x, 2) + pow(cos_1t*y, 2) + sin_2t*x*y)*f / sy3; - J[5 * m + im] = (sin_2t*x*x - sin_2t*y*y + 2 * cos_2t*x*y)*f*(0.5 / sx2 - 0.5 / sy2); - - dIxy[im] = Ixy[im] - f; - } - }; - - T dRx = grid_2d.dRx / region.Rxy_sc; - T dRy = grid_2d.dRy / region.Rxy_sc; - - // 0.8 = exp(-0.5*f^2) - T dx = ::fmax(0.668*sigma, 1.5*dRx); - T dy = ::fmax(0.668*sigma, 1.5*dRy); - - T sigma_x_min = ::fmax(sigma / 4, 0.5*dRx); - T sigma_y_min = ::fmax(sigma / 4, 0.5*dRy); - - T sigma_x_max = ::fmin(20 * sigma, grid_2d.lxh() / region.Rxy_sc); - T sigma_y_max = ::fmin(20 * sigma, grid_2d.lyh() / region.Rxy_sc); - - vector c_coef_0 = { 0, 0, 1, sigma, sigma, 0 }; - vector c_coef_min = { -dx, -dy, 0.5, sigma_x_min, sigma_y_min, -T(c_Pi) }; - vector c_coef_max = { dx, dy, 1.5, sigma_x_max, sigma_y_max, T(c_Pi) }; - - TVector coef_0 = c_coef_0; - TVector coef_min = c_coef_min; - TVector coef_max = c_coef_max; - TVector coef = coef_0; - - lapack::FLSF flsf; - - int nit = 4; - for (auto it = 0; it < nit; it++) - { - int m = region.Ixy.size(); - int n = 6; - - TVector J(m*n); - TVector d_Ixy(m); - - T chi2 = get_chi2(region.Rx, region.Ry, region.Ixy, coef); - - T lambda = 2; - T lambda_f = 2; - - const int niter = (it == nit - 1) ? 50 : 12; - for (auto iter = 0; iter < niter; iter++) - { - get_dIxy_J(region.Rx, region.Ry, region.Ixy, coef, d_Ixy, J); - - TVector d_coef(n); - TVector D(n); - TVector G(n); - flsf(m, n, J.data(), d_Ixy.data(), d_coef.data(), lambda, D.data(), G.data()); - - TVector coef_t = coef; - T rho_f = 0; - T G_max = 0; - for (auto ic = 0; ic < n; ic++) - { - coef_t[ic] += d_coef[ic]; - rho_f += coef_t[ic] * (D[ic] * coef_t[ic] + G[ic]); - G_max = ::fmax(G_max, fabs(G[ic])); - } - - T chi2_t = get_chi2(region.Rx, region.Ry, region.Ixy, coef_t); - T rho = (chi2 - chi2_t) / rho_f; - - if ((G_max < 1e-5) || fabs(chi2 - chi2_t) < 1e-7) - { - break; - } - - if (rho > 0) - { - coef = coef_t; - - for (auto ic = 0; ic < n - 1; ic++) - { - coef[ic] = min(max(coef[ic], coef_min[ic]), coef_max[ic]); - } - coef[n - 1] = acos(cos(coef[n - 1])); - - chi2 = get_chi2(region.Rx, region.Ry, region.Ixy, coef); - - lambda = (rho > 1e-6) ? (::fmax(lambda / lambda_f, 1e-7)) : lambda; - } - else - { - lambda = ::fmin(lambda*lambda_f, 1e+7); - } - } - - coef[0] = coef[0] * region.Rxy_sc + region.Rx_sf; - coef[1] = coef[1] * region.Rxy_sc + region.Ry_sf; - coef[2] = coef[2] * region.Ixy_sc; - coef[3] = coef[3] * region.Rxy_sc; - coef[4] = coef[4] * region.Rxy_sc; - - if (it < nit - 1) - { - T radius = ::fmax(coef[3], coef[4]); - radius = ::fmax(radius_i, radius); - - // select_cir_reg(grid_2d, Im_i, r2d(coef[0], coef[1]), radius, region); - - select_ellip_reg(grid_2d, Im_i, coef, 0.6, region); - - // scale - coef[0] = (coef[0] - region.Rx_sf) / region.Rxy_sc; - coef[1] = (coef[1] - region.Ry_sf) / region.Rxy_sc; - coef[2] = coef[2] / region.Ixy_sc; - coef[3] = coef[3] / region.Rxy_sc; - coef[4] = coef[4] / region.Rxy_sc; - - coef_min[0] = -coef[3] / 4; - coef_min[1] = -coef[4] / 4; - coef_min[2] = 0.75*coef[2]; - coef_min[3] = coef[3] / 2; - coef_min[4] = coef[4] / 2; - - coef_max[0] = coef[3] / 4; - coef_max[1] = coef[4] / 4; - coef_max[2] = 1.25*coef[2]; - coef_max[3] = 2 * coef[3]; - coef_max[4] = 2 * coef[4]; - } - } - - return coef; - } - - template - Value_type neighbor_radius(TGrid &grid_i, TVector &Im_i, r2d> p_i, Value_type radius_i) - { - using T = Value_type; - - T R2_max = pow(radius_i, 2); - - int ix_0 = grid_i.lb_index_x(p_i.x - radius_i); - int ixe = grid_i.ub_index_x(p_i.x + radius_i); - - int iy_0 = grid_i.lb_index_y(p_i.y - radius_i); - int iye = grid_i.ub_index_y(p_i.y + radius_i); - - int nrl = grid_i.ceil_dR_min(radius_i); - - // get radial distribution - TVector frl(nrl); - TVector cfrl(nrl); - - T dR = grid_i.dR_min(); - - for (auto ix = ix_0; ix < ixe; ix++) - { - for (auto iy = iy_0; iy < iye; iy++) - { - T R2_d = grid_i.R2(ix, iy, p_i.x, p_i.y); - if (R2_d < R2_max) - { - auto ir = static_cast(floor(sqrt(R2_d) / dR)); - frl[ir] += Im_i[grid_i.ind_col(ix, iy)]; - cfrl[ir] += 1.0; - } - } - } - - for (auto ir = 0; ir < frl.size(); ir++) - { - frl[ir] /= ::fmax(1.0, cfrl[ir]); - } - - frl[0] = ::fmax(frl[0], 1.01*frl[1]); - - frl = smooth(frl, 1); - - // derivative and minimun - int ir0 = frl.size() - 1; - for (auto ir = 0; ir < frl.size() - 1; ir++) - { - if (frl[ir] < frl[ir + 1]) - { - ir0 = ir + 1; - break; - } - } - - int irm = frl.size() - 1; - for (auto ir = ir0; ir < frl.size() - 1; ir++) - { - if (frl[ir] > frl[ir + 1]) - { - irm = ir; - break; - } - } - - return max(2, irm)*dR; - } - - // select circular region - template - Value_type mean_cir_reg(TGrid &grid_i, TVector &Im_i, r2d> p_i, - Value_type radius_i, Value_type bg_i) - { - using T = Value_type; - - T R2_max = radius_i*radius_i; - - auto range = grid_i.index_range(p_i, radius_i); - - // select circular region - T I_mean = 0; - int Ic = 0; - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2_d = grid_i.R2(ix, iy, p_i.x, p_i.y); - if (R2_d < R2_max) - { - I_mean += Im_i[grid_i.ind_col(ix, iy)] - bg_i; - Ic++; - } - } - } - I_mean /= Ic; - return I_mean; - } - - /*******************************************************************/ - template - TVector interp_profile(TGrid &grid_2d, TVector &Im, const r2d> &p1, const r2d> &p2, int nr) - { - TVector v; - - if (!(grid_2d.ckb_bound(p1) && grid_2d.ckb_bound(p2))) - { - return v; - } - - if (module(p1 - p2) < grid_2d.dR_min()) - { - return v; - } - - using T = Value_type; - - auto interp_2d = [](const r2d &p, TGrid &grid_2d, TVector &Im)->T - { - auto ix = grid_2d.lb_index_x(p.x); - auto iy = grid_2d.lb_index_y(p.y); - - T f11 = Im[grid_2d.ind_col(ix, iy)]; - T f12 = Im[grid_2d.ind_col(ix, iy + 1)]; - T f21 = Im[grid_2d.ind_col(ix + 1, iy)]; - T f22 = Im[grid_2d.ind_col(ix + 1, iy + 1)]; - - T x1 = grid_2d.Rx(ix); - T x2 = grid_2d.Rx(ix + 1); - T y1 = grid_2d.Ry(iy); - T y2 = grid_2d.Ry(iy + 1); - - T dx1 = p.x - x1; - T dx2 = x2 - p.x; - T dy1 = p.y - y1; - T dy2 = y2 - p.y; - - T f = (dx2*(f11*dy2 + f12*dy1) + dx1*(f21*dy2 + f22*dy1)) / ((x2 - x1)*(y2 - y1)); - return f; - - }; - - r2d p12 = p2 - p1; - T mp12 = p12.module(); - - nr = (nr <= 0) ? static_cast(ceil(mp12 / grid_2d.dR_min())) : nr; - nr = max(nr, 2); - T dr = mp12 / (nr - 1); - r2d u = dr*normalized(p12); - - v.reserve(nr); - for (auto ir = 0; ir < nr; ir++) - { - r2d p = p1 + T(ir)*u; - v.push_back(interp_2d(p, grid_2d, Im)); - } - return v; - } - - template - void interp_profile(Stream &stream, TGrid &grid_2d, TVector &Im, Value_type bg, r2d> p1, r2d> p2, - TVector &x, TVector &y) - { - x.clear(); - y.clear(); - - if (!(grid_2d.ckb_bound(p1) && grid_2d.ckb_bound(p2))) - { - return; - } - - if (module(p1 - p2) < grid_2d.dR_min()) - { - return; - } - - using T = Value_type; - - auto interp_2d = [](const r2d &p, TGrid &grid_2d, TVector &Im)->T - { - auto ix = grid_2d.lb_index_x(p.x); - auto iy = grid_2d.lb_index_y(p.y); - - T f11 = Im[grid_2d.ind_col(ix, iy)]; - T f12 = Im[grid_2d.ind_col(ix, iy + 1)]; - T f21 = Im[grid_2d.ind_col(ix + 1, iy)]; - T f22 = Im[grid_2d.ind_col(ix + 1, iy + 1)]; - - T x1 = grid_2d.Rx(ix); - T x2 = grid_2d.Rx(ix + 1); - T y1 = grid_2d.Ry(iy); - T y2 = grid_2d.Ry(iy + 1); - - T dx1 = p.x - x1; - T dx2 = x2 - p.x; - T dy1 = p.y - y1; - T dy2 = y2 - p.y; - - T f = (dx2*(f11*dy2 + f12*dy1) + dx1*(f21*dy2 + f22*dy1)) / ((x2 - x1)*(y2 - y1)); - return f; - - }; - - int Ixy_1 = Im[grid_2d.ixy(p1.x, p1.y)]; - int Ixy_2 = Im[grid_2d.ixy(p2.x, p2.y)]; - - r2d p12 = p2 - p1; - T mp12 = p12.module(); - int nr = grid_2d.ceil_dR_min(mp12); - T dr = mp12 / (nr - 1); - r2d u = dr*normalized(p12); - - x.reserve(nr); - y.reserve(nr); - for (auto ir = 0; ir < nr; ir++) - { - x.push_back(ir*dr); - r2d p = p1 + T(ir)*u; - T v = interp_2d(p, grid_2d, Im); - y.push_back(v - bg); - } - } - - // find one maximum in all areas above the thr - template - TVector fd_peaks_vector_typ_1(TVector &x, TVector &y, Value_type y_thr) - { - using T = Value_type; - TVector x_peak(y.size()); - - T x_max = 0; - T y_max = y_thr; - bool bb = y[0] > y_thr; - int ipeak = 0; - for (auto ix = 0; ix < y.size(); ix++) - { - if (y[ix] > y_thr) - { - if (y_max < y[ix]) - { - y_max = y[ix]; - x_max = x[ix]; - } - bb = true; - } - else if (bb) - { - x_peak[ipeak++] = x_max; - y_max = y_thr; - bb = false; - } - } - - if (bb) - { - x_peak[ipeak++] = x_max; - } - - x_peak.resize(ipeak); - x_peak.shrink_to_fit(); - - return x_peak; - } - - // find all maximum in all areas above the thr - template - TVector fd_peaks_vector_typ_2(TVector &x, TVector &y, Value_type y_thr) - { - using T = Value_type; - TVector x_peak; - x_peak.reserve(y.size()); - - for (auto ix = 1; ix < y.size() - 1; ix++) - { - if (y[ix] > y_thr) - { - if ((y[ix - 1] < y[ix]) && (y[ix + 1] < y[ix])) - { - x_peak.push_back(x[ix]); - } - } - } - x_peak.shrink_to_fit(); - - return x_peak; - } - - /*******************************************************************/ - // find peak position 1d - template - enable_if_host_vector> - fit_max_pos_1d(TGrid &grid_1d, TVector &Im, Value_type p_i, - Value_type sigma_i, Value_type radius_i) - { - using T = Value_type; - - auto range = grid_1d.index_range(p_i, radius_i); - int ix_c = grid_1d.floor_dRx(p_i); - - int ix_0 = range.ix_0; - for (auto ix = ix_c - 1; ix >= range.ix_0; ix--) - { - if (Im[ix - 1] > Im[ix]) - { - ix_0 = ix; - break; - } - } - - int ix_e = range.ix_e; - for (auto ix = ix_c + 1; ix <= range.ix_e; ix++) - { - if (Im[ix] < Im[ix + 1]) - { - ix_e = ix; - break; - } - } - - // if there are few points - if (fabs(ix_e - ix_0) <= 3) - { - T x = 0; - T sI = 0; - for (auto ix = ix_0; ix <= ix_e; ix++) - { - x += Im[ix] * grid_1d.Rx(ix); - sI += Im[ix]; - } - x = x / sI; - - return x; - } - - if ((ix_0 = !range.ix_0) || (ix_e = !range.ix_e)) - { - T x_min = grid_1d.Rx(ix_0); - T x_max = grid_1d.Rx(ix_e); - radius_i = ::fmin(p_i - x_min, x_max - p_i); - } - - auto coef = fit_gauss_1d(grid_1d, Im, p_i, sigma_i, radius_i); - - return coef[0]; - } - - // find peak position 2d - template - enable_if_host_vector>> - fit_max_pos_2d(TGrid &grid_2d, TVector &Im, r2d> p_i, - Value_type sigma_i, Value_type radius_i) - { - using T = Value_type; - - auto coef = fit_ellipt_gauss_2d(grid_2d, Im, p_i, sigma_i, radius_i); - return r2d(coef[0], coef[1]); - } - - /*******************************************************************/ - // get projective standard deviation - template - TVector projected_intensity(TGrid &grid_2d, TVector &M_i, Value_type np_min, Value_type delta) - { - using T = Value_type; - - vector> pts_c = { r2d(0, 0), r2d(grid_2d.nx - 1, 0), r2d(grid_2d.nx - 1, grid_2d.ny - 1), r2d(0, grid_2d.ny - 1) }; - - auto n_pp = static_cast(ceil(module(r2d(grid_2d.nx, grid_2d.ny)) + 2)); - TVector y_pt(n_pp); - TVector c_pt(n_pp); - - T cos_d, sin_d; - sincos(delta, &sin_d, &cos_d); - - // get projected points - auto krn_proj_point = [&](const T &cos_d, const T &sin_d, const r2d &p)->r2d - { - return r2d(cos_d*p.x + sin_d*p.y, -sin_d*p.x + cos_d*p.y); - }; - - // get reference corner point - auto p_0 = krn_proj_point(cos_d, sin_d, pts_c[0]); - for (auto ixy = 1; ixy < pts_c.size(); ixy++) - { - auto p_r = krn_proj_point(cos_d, sin_d, pts_c[ixy]); - if (p_0.y > p_r.y) - { - p_0 = p_r; - } - } - - for (auto ix = 0; ix < grid_2d.nx; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - auto ixy = grid_2d.ind_col(ix, iy); - auto p_r = krn_proj_point(cos_d, sin_d, r2d(ix, iy)) - p_0; - auto j = static_cast(floor(p_r.y)); - y_pt[j] += M_i[ixy]; - c_pt[j] += 1; - } - } - - TVector V_o; - V_o.reserve(n_pp); - for (auto j = 0; j < n_pp; j++) - { - if (c_pt[j] > np_min) - { - V_o.push_back(y_pt[j] / c_pt[j]); - } - } - V_o.shrink_to_fit(); - - return V_o; - } - - // get projective standard deviation - template - void PSD(Stream &stream, TGrid &grid_2d, TVector &M_i, Value_type np_min, - Value_type del_0, Value_type del_e, Value_type d_del, TVector &x_o, TVector &y_o) - { - // get number of angles - auto n_delta = static_cast(floor((del_e - del_0) / d_del + 0.5)); - x_o.resize(n_delta); - y_o.resize(n_delta); - - auto thr_psd = [&](const Range_2d &range) - { - for (auto idel = range.ixy_0; idel < range.ixy_e; idel++) - { - auto delta = (del_0 + idel*d_del)*c_Pi / 180; - x_o[idel] = delta * 180 / c_Pi; - - auto pIm = projected_intensity(grid_2d, M_i, np_min, delta); - - y_o[idel] = variance(pIm); - } - }; - - stream.set_n_act_stream(n_delta); - stream.set_grid(1, n_delta); - stream.exec(thr_psd); - } - - // get projective standard deviation - template - TVector PSD_fd_peaks(Stream &stream, TGrid &grid_2d, TVector &M_i, Value_type np_min, - TVector x_i, TVector y_i) - { - using T = Value_type; - - T d_del = fabs(x_i[1] - x_i[0]); - int nr = max(1, static_cast(ceil(3.0 / d_del))); - auto y_f = ftr_median_1d(stream, y_i, nr); - - T y_mean = 0; - T y_max = y_i[0] - y_f[0]; - for (auto ix = 0; ix < y_i.size(); ix++) - { - y_f[ix] = y_i[ix] - y_f[ix]; - y_mean += y_f[ix]; - y_max = max(y_max, y_f[ix]); - } - y_mean /= y_i.size(); - auto y_thr = y_mean + 0.2*(y_mean + y_max); - - auto x_peaks = fd_peaks_vector_typ_1(x_i, y_f, y_thr); - - TVector x_ref, y_ref; - for (auto ix = 0; ix < x_peaks.size(); ix++) - { - auto delta = x_peaks[ix]; - auto delta_0 = delta - d_del; - auto delta_e = delta + d_del; - auto d_delta = 0.1*d_del; - PSD(stream, grid_2d, M_i, np_min, delta_0, delta_e, d_delta, x_ref, y_ref); - std::for_each(y_ref.begin(), y_ref.end(), [](T &y) {y = log(1 + y); }); - auto coef = lsf_poly_n(x_ref, y_ref, 2); - T px = -coef[1] / (2 * coef[2]); - if ((px <= delta_0) || (delta_e <= px)) - { - int idx = std::max_element(y_ref.begin(), y_ref.end()) - y_ref.begin(); - px = x_ref[idx]; - } - x_peaks[ix] = px; - } - - return x_peaks; - } - - // get index to maximun distance - template - int get_dmaxIndex_Point2Line(r2d> p1, r2d> p2, - int ix1, int ix2, TVector &x, TVector &y) - { - using T = Value_type; - - T c1 = p2.y - p1.y; - T c2 = -(p2.x - p1.x); - T c3 = p2.x*p1.y - p2.y*p1.x; - T d = sqrt(c1*c1*+c2*c2); - - c1 /= d; - c2 /= d; - c3 /= d; - - int ix_max = 0; - T dmax = 0; - for (auto ir = ix1; ir < ix2; ir++) - { - T x0 = x[ir]; - T y0 = y[ir]; - T d = fabs(c1*x0 + c2*y0 + c3); - if (d > dmax) - { - dmax = d; - ix_max = ir; - } - } - - return ix_max; - } - - inline - double getLengthCurve(int ix1, int ix2, double *x, double *y) - { - double x1, y1, x2, y2; - double d, dx, dy; - d = 0; - for (auto i = ix1; i < ix2 - 1; i++) - { - x1 = x[i]; y1 = y[i]; - x2 = x[i + 1]; y2 = y[i + 1]; - dx = x2 - x1; dy = y2 - y1; - d = d + sqrt(dx*dx + dy*dy); - } - return d; - } - - inline - double getLengthCurve(int ix1, int ix2, double *x, double *y, double lmax, int &il) - { - double x1, y1, x2, y2; - double l, dx, dy; - if (ix1 < ix2) - { - l = 0; il = ix2; - for (int i = ix1; i < ix2 - 1; i++) - { - x1 = x[i]; y1 = y[i]; - x2 = x[i + 1]; y2 = y[i + 1]; - dx = x2 - x1; dy = y2 - y1; - l = l + sqrt(dx*dx + dy*dy); - if ((lmax > 0) && (l >= lmax)) - { - il = i; - break; - } - } - } - else - { - l = 0; il = ix2; - for (int i = ix1; i > ix2; i--) - { - x1 = x[i - 1]; y1 = y[i - 1]; - x2 = x[i]; y2 = y[i]; - dx = x2 - x1; dy = y2 - y1; - l = l + sqrt(dx*dx + dy*dy); - if ((lmax > 0) && (l >= lmax)) - { - il = i; - break; - } - } - } - return l; - } - - // get information limit for regular grid - template - Value_type info_limit_2d(TGrid &grid_2d, TVector &fM_i) - { - using T = Value_type; - - TVector r, fr; - - // cumulative radial integration - cum_rad_dist_2d(grid_2d, fM_i, grid_2d.lxh(), grid_2d.lyh(), grid_2d.lxh_lyh_min(), r, fr); - - // shift and normalize - T r0 = r[0], fIr0 = fr[0]; - for (auto ir = 0; ir < fr.size(); ir++) - { - r[ir] = (r[ir] - r0) / (r.back() - r0); - fr[ir] = (fr[ir] - fIr0) / (fr.back() - fIr0); - } - - // smooth data - int nkr = max(5, fr.size() / 100); - fr = smooth(fr, nkr); - - r2d p1(r.front(), fr.front()); - r2d p2(r.back(), fr.back()); - - // get maximum curvature point - auto ir_m = get_dmaxIndex_Point2Line(p1, p2, 0, r.size(), r, fr); - - return grid_2d.Rx(ir_m); - } - - template - void unique_vector(TVector &v) - { - using T = Value_type; - - std::sort(v.begin(), v.end()); - v.erase(std::unique(v.begin(), v.end(), mt::isEqual), v.end()); - v.shrink_to_fit(); - } - - template - void match_vectors(InputIterator vr_first, InputIterator vr_last, TVector &vs, Value_type dv) - { - using T = Value_type; - - dv = ::fmax(dv, T(0.1)); - - TVector vr(vr_first, vr_last); - - // find min and max values of vr - T vr_min, vr_max; - minmax_element(vr, vr_min, vr_max); - vr_min -= dv; - vr_max += dv; - - // remove elements of vs outside the range - auto remove = [vr_min, vr_max](T a)->bool - { - return ((a < vr_min) || (a > vr_max)); - }; - vs.erase(std::remove_if(vs.begin(), vs.end(), remove), vs.end()); - - Vector vr_c(vr.size(), true); - int m_size = min(vr.size(), vs.size()); - TVector A_d; - A_d.reserve(m_size); - - for (auto i = 0; i < vs.size(); i++) - { - T val = vs[i]; - auto it = std::min_element(vr.begin(), vr.end(), functor::closest_element(val)); - auto imin = static_cast(it - vr.begin()); - - if (vr_c[imin]) - { - vr_c[imin] = false; - A_d.push_back(*it); - } - } - vs = A_d; - vs.shrink_to_fit(); - } - - /************************ read matlab binary file ***********************/ - template - enable_if_real - read_mat_matrix(std::ifstream &bin_file, int nxy, TVector &matrix) - { - using T_o = Value_type; - - vector vect_r(nxy); - bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T_i)); - - for (auto ik = 0; ik < nxy; ik++) - { - matrix[ik] = T_o(vect_r[ik]); - } - } - - template - enable_if_complex - read_mat_matrix(std::ifstream &bin_file, int nxy, TVector &matrix) - { - using T = Value_type_r; - using T_o = Value_type_r; - - vector vect_r(nxy); - bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T)); - vector vect_i(nxy); - bin_file.read(reinterpret_cast(vect_i.data()), nxy * sizeof(T)); - - auto matrix_ptr = reinterpret_cast*>(matrix.data()); - - for (auto ik = 0; ik < nxy; ik++) - { - matrix_ptr[ik].real(vect_r[ik]); - matrix_ptr[ik].imag(vect_i[ik]); - } - } - - template - void read_mat_binary_matrix(const char *filename, Grid_2d> &grid_2d, TVector &matrix) - { - int nx, ny; - double dx, dy; - int type; - - std::ifstream bin_file(filename, std::ofstream::binary); - bin_file.read(reinterpret_cast(&nx), sizeof(int)); - bin_file.read(reinterpret_cast(&ny), sizeof(int)); - bin_file.read(reinterpret_cast(&dx), sizeof(double)); - bin_file.read(reinterpret_cast(&dy), sizeof(double)); - bin_file.read(reinterpret_cast(&type), sizeof(int)); - - grid_2d.set_input_data(nx, ny, nx*dx, ny*dy); - - auto nxy = nx*ny; - matrix.resize(nxy); - - switch (type) - { - case 1: - { - read_mat_matrix(bin_file, nxy, matrix); - } - break; - case 2: - { - read_mat_matrix(bin_file, nxy, matrix); - } - break; - case 3: - { - read_mat_matrix>(bin_file, nxy, matrix); - } - break; - case 4: - { - read_mat_matrix>(bin_file, nxy, matrix); - } - break; - } - bin_file.close(); - } - /************************ write matlab binary file ***********************/ - template - enable_if_real_host_vector - write_mat_matrix(std::ofstream &bin_file, TVector &matrix) - { - //using T = Value_type; - - //bin_file.write(reinterpret_cast(matrix.data()), matrix.size()*sizeof(T)); - } - - template - enable_if_complex_host_vector - write_mat_matrix(std::ofstream &bin_file, TVector &matrix) - { - //using T = Value_type_r; - - //vector vect_r(nxy); - //vector vect_i(nxy); - //for (auto ik = 0; ik(vect_r.data()), matrix.size()*sizeof(T)); - //bin_file.write(reinterpret_cast(vect_i.data()), matrix.size()*sizeof(T)); - } - - template - void write_mat_binary_matrix(const char *filename, Grid_2d> &grid_2d, TVector &matrix) - { - //int type = matrix_type; - - //std::ofstream bin_file(filename, std::ofstream::binary); - //bin_file.write(reinterpret_cast(&(grid_2d.nx)), sizeof(int)); - //bin_file.write(reinterpret_cast(&(grid_2d.ny)), sizeof(int)); - //bin_file.write(reinterpret_cast(&(grid_2d.dRx)), sizeof(double)); - //bin_file.write(reinterpret_cast(&(grid_2d.dRy)), sizeof(double)); - //bin_file.write(reinterpret_cast(&type), sizeof(int)); - - //switch (type) - //{ - //case 1: - //{ - // write_mat_matrix(bin_file, matrix); - //} - //break; - //case 2: - //{ - // write_mat_matrix(bin_file, matrix); - //} - //break; - //case 3: - //{ - // write_mat_matrix>(bin_file, matrix); - //} - //break; - //case 4: - //{ - // write_mat_matrix>(bin_file, matrix); - //} - //break; - //} - //bin_file.close(); - } - - /************************ extract real vector form complex vector**********************/ - template - void from_complex_to_real(eShow_CData show_data, TVector_c &cdata, TVector_r &data) - { - switch (show_data) - { - case eSCD_CReal: - { - for (auto ixy = 0; ixy < cdata.size(); ixy++) - data[ixy] = cdata[ixy].real(); - } - break; - case eSCD_CImag: - { - for (auto ixy = 0; ixy < cdata.size(); ixy++) - data[ixy] = cdata[ixy].imag(); - } - break; - case eSCD_CMod: - { - for (auto ixy = 0; ixy < cdata.size(); ixy++) - data[ixy] = abs(cdata[ixy]); - } - break; - case eSCD_CPhase: - { - for (auto ixy = 0; ixy < cdata.size(); ixy++) - data[ixy] = arg(cdata[ixy]); - } - break; - } - } -} // namespace mt - -#endif diff --git a/src/cpu_fcns_mt.hpp b/src/cpu_fcns_mt.hpp new file mode 100755 index 00000000..89a23ea6 --- /dev/null +++ b/src/cpu_fcns_mt.hpp @@ -0,0 +1,822 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef CPU_FCNS_MT_H + #define CPU_FCNS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "types_mt.cuh" + #include "type_traits_mt.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_stream.cuh" + #include "quad_data.cuh" + #include "cgpu_detail_mt.cuh" + #include "fcns_cpu.h" + + /* atomic functions */ + namespace mt + { + /*********************************** pFcn_clnl_3_x **********************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx, pFcn_clnl_3_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_3_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /********************************* pFcn_clnl_4_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& c, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx, pFcn_clnl_4_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], c, coef.cl, coef.cnl); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& c, const pLNL_Coef_cpu& coef, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_4_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], c, coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /********************************* pFcn_clnl_6_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx, pFcn_clnl_6_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_6_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + + /********************************* pFcn_clnl_8_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx, pFcn_clnl_8_1 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fx[ix] = fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_cpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, pVctr_cpu_32& fx1, pVctr_cpu_32& fx2, pFcn_clnl_8_2 fcn) + { + for(auto ix = 0; ix < x.m_size; ix++) + { + fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + + /***************************************************************************************/ + /***************************************************************************************/ + /***************************************************************************************/ + #define SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn, ...) \ + switch(atomic_pot_parm_typ) \ + { \ + case eappt_doyle_0_4: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_peng_0_4: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_peng_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_kirkland_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_weickenmeier_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_lobato_0_12: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + case eappt_peng_ion_0_4: \ + { \ + return cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + default: \ + { \ + return 0; \ + } \ + } + + #define SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn, ...) \ + switch(atomic_pot_parm_typ) \ + { \ + case eappt_doyle_0_4: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_peng_0_4: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_peng_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_kirkland_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_weickenmeier_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_lobato_0_12: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + case eappt_peng_ion_0_4: \ + { \ + cgpu_detail_mt::fcn(__VA_ARGS__); \ + } \ + break; \ + } + + /************************************** feg ********************************************/ + template + CPU_EXEC + T fcn_feg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const pLNL_Coef_cpu& coef) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_feg, g, coef.cl, coef.cnl); + } + + template + CPU_EXEC + void fcn_feg_dfeg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_feg_dfeg, g, coef.cl, coef.cnl, y, dy); + } + + /*************************************** fxg *******************************************/ + template + CPU_EXEC + T fcn_fxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const T& Z, const pLNL_Coef_cpu& coef) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_peng_0_4: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_peng_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_kirkland_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + case eappt_weickenmeier_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, coef.cl, coef.cnl); + } + case eappt_lobato_0_12: + { + return cgpu_detail_mt::fcn_fxg(g, coef.cl, coef.cnl); + } + case eappt_peng_ion_0_4: + { + return cgpu_detail_mt::fcn_fxg(g, Z, coef.cl, coef.cnl); + } + default: + { + return 0; + } + } + } + + template + CPU_EXEC + void fcn_fxg_dfxg(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& g, const T& Z, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_4: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_kirkland_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_weickenmeier_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_lobato_0_12: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_ion_0_4: + { + cgpu_detail_mt::fcn_fxg_dfxg(g, Z, coef.cl, coef.cnl, y, dy); + } + break; + } + } + + /*************************************** pr ********************************************/ + template + CPU_EXEC + T fcn_pr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_pr, r, coef.cl, coef.cnl); + } + + template + CPU_EXEC + void fcn_pr_dpr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_pr_dpr, r, coef.cl, coef.cnl, y, dy); + } + + /**************************************** vr *******************************************/ + template + CPU_EXEC + T fcn_vr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_vr, r, coef.cl, coef.cnl); + } + + template + CPU_EXEC + void fcn_vr_dvr(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_vr_dvr, r, coef.cl, coef.cnl, y, dy); + } + + /************************************** vz *********************************************/ + template + CPU_EXEC + T fcn_vz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad) + { + SWITCH_FCN_ATOMIC_V(atomic_pot_parm_typ, fcn_vz, r, z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + + template + CPU_EXEC + void fcn_vz_dvz(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const T& z_0, const T& z_e, const pLNL_Coef_cpu& coef, const pQuad_Coef_1d_cpu& quad, T& y, T& dy) + { + SWITCH_FCN_ATOMIC_VD(atomic_pot_parm_typ, fcn_vz_dvz, r, z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, y, dy); + } + + /************************************* vzp *********************************************/ + template + CPU_EXEC + T fcn_vzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, pQuad_Coef_1d_cpu* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_peng_0_4: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_peng_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_kirkland_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_weickenmeier_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl, pquad->m_size, pquad->x, pquad->w); + } + case eappt_lobato_0_12: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + case eappt_peng_ion_0_4: + { + return cgpu_detail_mt::fcn_vzp(r, coef.cl, coef.cnl); + } + default: + { + return 0; + } + } + } + + template + CPU_EXEC + void fcn_vzp_dvzp(const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, const T& r, const pLNL_Coef_cpu& coef, T& y, T& dy, pQuad_Coef_1d_cpu* pquad = nullptr) + { + switch(atomic_pot_parm_typ) + { + case eappt_doyle_0_4: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_4: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_kirkland_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_weickenmeier_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, pquad->m_size, pquad->x, pquad->w, y, dy); + } + break; + case eappt_lobato_0_12: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + case eappt_peng_ion_0_4: + { + cgpu_detail_mt::fcn_vzp_dvzp(r, coef.cl, coef.cnl, y, dy); + } + break; + } + } + } + + /* detector integration */ + namespace mt + { + template + enable_if_vctr_cpu> + fcn_int_det_ring(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), T(0), cgpu_detail_mt::fcn_int_det_ring, grid, g2_min, g2_max, mx_i.m_data); + } + + template + enable_if_vctr_cpu> + fcn_int_det_ring_norm_2(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), Ur(0), cgpu_detail_mt::fcn_int_det_ring_norm_2, grid, g2_min, g2_max, mx_i.m_data); + } + + template + enable_if_vctr_cpu> + fcn_int_det_sen(Grid_2d& grid, TVctr& sen_i, TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + KS sum_total = U(0); + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), U(0), cgpu_detail_mt::fcn_int_det_sen, grid, sen_i.m_data, mx_i.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu> + fcn_int_det_sen_norm_2(Grid_2d& grid, TVctr_1& sen_i, TVctr_2& mx_i, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + return fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), Ur(0), cgpu_detail_mt::fcn_int_det_sen_norm_2, grid, sen_i.m_data, mx_i.m_data); + } + } + + /* wave propagation */ + namespace mt + { + /* propagate */ + template + enable_if_vctr_cpu + fcn_fs_propagate(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate, grid, psi_i.m_data, g_0, w_g2, w, psi_o.m_data); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + enable_if_vctr_cpu + fcn_fs_propagate_bw_f(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T alpha, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_f, grid, psi_i.m_data, g_0, w_g2, g2_cut, alpha, w, psi_o.m_data); + } + + /* propagate and bandwith limit using a hard aperture */ + template + enable_if_vctr_cpu + fcn_fs_propagate_bw_h(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_h, grid, psi_i.m_data, g_0, w_g2, g2_cut, w, psi_o.m_data); + } + } + + /* probe - ctf - pctf */ + namespace mt + { + template + enable_if_vctr_cpu + fcn_fs_probe(Grid_2d& grid, Lens& lens, R_2d r, R_2d gu, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_probe, grid, lens, r, gu, psi_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_probe, grid, lens, r, gu, psi_o.m_data); + } + + auto tot_intensity = fcn_sum_norm_2(psi_o, pstream); + auto sc_fctr = sqrt(T(1)/tot_intensity); + + fcn_scale(sc_fctr, psi_o, pstream); + } + + template + enable_if_vctr_cpu + fcn_fs_apply_ctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, R_2d gu, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_ctf, grid, psi_i, lens, gu, psi_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_ctf, grid, psi_i, lens, gu, psi_o.m_data); + } + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + enable_if_vctr_cpu + fcn_fs_apply_pctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, R_2d gu, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_pctf, grid, psi_i, lens, gu, psi_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, fcn_fs_apply_pctf, grid, psi_i, lens, gu, psi_o.m_data); + } + } + } + + /* transmission function */ + namespace mt + { + template + enable_if_vctr_cpu_and_vctr_cpu + transmission_fcn(eElec_Spec_Interact_Mod esim, TVctr_1& vzp_i, T w, TVctr_2& tfcn_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + iGrid_1d igrid(vzp_i.size()); + + if (esim==eesim_weak_phase_object) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, cgpu_detail_mt::fcn_trans_fcn, igrid, vzp_i.m_data, w, tfcn_o.m_data); + } + else + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, cgpu_detail_mt::fcn_trans_fcn, igrid, vzp_i.m_data, w, tfcn_o.m_data); + } + } + } + + /* eels */ + namespace mt + { + template + T fcn_eels_lorentz_norm_factor_cpu(Grid_2d& grid, EELS& eels, Stream_cpu* pstream = nullptr) + { + auto sum_total = fcn_stream_exec_xd_krn_reduce(pstream, grid.nx, grid.ny, std::plus>(), T(0),cgpu_detail_mt::fcn_eels_lorentz_norm_factor, grid, eels.gc2, eels.ge2); + + return sqrt(eels.occ)/sum_total; + } + + template + enable_if_vctr_cpu + fcn_eels_w_xyz(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_x, TVctr_c& w_y, TVctr_c& w_z, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_xyz, grid, eels, w_x.m_data, w_y.m_data, w_z.m_data); + + fft.inverse(w_x); + fft.inverse(w_y); + fft.inverse(w_z); + } + + template + enable_if_vctr_cpu + fcn_eels_w_x(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_x, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_x, grid, eels, w_x.m_data); + + fft.inverse(w_x); + } + + template + enable_if_vctr_cpu + fcn_eels_w_y(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_y, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_y, grid, eels, w_y.m_data); + + fft.inverse(w_y); + } + + template + enable_if_vctr_cpu + fcn_eels_w_z(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_z, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_z, grid, eels, w_z.m_data); + + fft.inverse(w_z); + } + + template + enable_if_vctr_cpu + fcn_eels_w_mn1(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_mn1, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mn1, grid, eels, w_mn1.m_data); + + fft.inverse(w_mn1); + } + + template + enable_if_vctr_cpu + fcn_eels_w_mp1(Grid_2d& grid, EELS& eels, FFT_cpu& fft, TVctr_c& w_mp1, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_cpu(grid, eels, pstream); + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mp1, grid, eels, w_mp1.m_data); + + fft.inverse(w_mp1); + } + } + + namespace mt + { + // /***********************Temporal and Spatial quadratures*********************/ + // template + // void obj_lens_temporal_spatial_quadratures(Lens& lens, Quad_Coef_1d& qt, Quad_Coef_2d& qs) + // { + // /*********************Temporal quad_data**********************/ + // Quad_Data quad_data; + // quad_data(7, lens.tp_inc_npts, qt); // 7: int_-infty^infty f(x) x^0 Exp[-x^2] dx + // std::for_each(qt.w.begin(), qt.w.end(), [](T& v) { v = v/c_pii2; }); + + // /*********************Spatial quad_data**********************/ + // qs.reserve((2 * lens.ngxs + 1)*(2 * lens.ngys + 1)); + // dt_int32 iqs = 0; + // T sum_w = 0; + // T sum_ee = 0; + // T alpha = 0.5/pow(lens.spt_inc_sigma, 2); + + // for(auto ix = -lens.ngxs; ix <= lens.ngxs; ix++) + // { + // for(auto iy = -lens.ngys; iy <= lens.ngys; iy++) + // { + // T gxs = lens.gxs(ix); + // T gys = lens.gys(iy); + // T g2s = gxs*gxs + gys*gys; + // if (g2s < lens.g2_outers) + // { + // qs.x.push_back(gxs); + // qs.y.push_back(gys); + // T v = exp(-alpha*g2s); + // qs.w.push_back(v); + // fcn_kh_sum(sum_w, v, sum_ee); + // } + // } + // } + // qs.resize(iqs); + // std::for_each(qs.w.begin(), qs.w.end(), [sum_w](T& v) { v = v/sum_w; }); + // } + + // template + // void cond_lens_temporal_spatial_quadratures(Lens& lens, Quad_Coef_1d& qt, Quad_Coef_2d& qs) + // { + // /*********************Temporal quad_data**********************/ + // dt_bool bb_ti = (lens.tp_inc_npts > 1) && fcn_is_nzero(lens.tp_inc_sigma); + // Quad_Data quad_data; + + // if (bb_ti) + // { + // dt_float64 a = (fcn_is_zero(lens.tp_inc_sigma))?0:(lens.tp_inc_a/(sqrt(c_2pi)*lens.tp_inc_sigma)); + // dt_float64 b = (fcn_is_zero(lens.tp_inc_sigma))?0:(0.5/lens.tp_inc_sigma_2()); + // dt_float64 c = (fcn_is_zero(lens.tp_inc_beta))?0:((1-lens.tp_inc_a)/(2*lens.tp_inc_beta)); + // dt_float64 d = (fcn_is_zero(lens.tp_inc_beta))?0:(1.0/lens.tp_inc_beta); + + // dt_float64 b_q = 0.5/sqrt(lens.tp_inc_a*lens.tp_inc_sigma_2() + 2*(1-lens.tp_inc_a)*lens.tp_inc_beta_2()); + + // // 26, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // quad_data(26, lens.tp_inc_npts, qt, 0, 0, 0, b_q); + + // for(auto it = 0; it < lens.tp_inc_npts; it++) + // { + // dt_float64 r = abs(qt.x[it]); // positive + // dt_float64 f = a*exp(-b*r*r + b_q*r*r) + c*exp(-d*r + b_q*r*r); + // qt.w[it] *= f; + // } + // } + // else + // { + // qt.resize(1); + // qt.x[0] = 0; + // qt.w[0] = 1; + // } + + // /*********************Spatial quad_data**********************/ + // dt_bool bb_si = ((lens.spt_inc_rad_npts > 1) || (lens.spt_inc_azm_npts > 1)) && !fcn_is_zero(lens.spt_inc_sigma, lens.spt_inc_beta); + + // if (bb_si) + // { + // dt_float64 a = (fcn_is_zero(lens.spt_inc_sigma))?0:(lens.spt_inc_a/(c_2pi*lens.spt_inc_sigma_2())); + // dt_float64 b = (fcn_is_zero(lens.spt_inc_sigma))?0:(0.5/lens.spt_inc_sigma_2()); + // dt_float64 c = (fcn_is_zero(lens.spt_inc_beta))?0:((1-lens.spt_inc_a)/(c_2pi*lens.spt_inc_beta_2())); + // dt_float64 d = (fcn_is_zero(lens.spt_inc_beta))?0:(1.0/lens.spt_inc_beta); + + // dt_float64 b_q = 1.0/sqrt((2*lens.spt_inc_a*lens.spt_inc_sigma_2()+ 6*(1-lens.spt_inc_a)*lens.spt_inc_beta_2())/6); + + // // radial part + // Quad_Coef_1d qr; + // // 25, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // quad_data(25, lens.spt_inc_rad_npts, qr, 1, 0, 0, b_q); + + // for(auto ir = 0; ir < lens.spt_inc_rad_npts; ir++) + // { + // dt_float64 r = abs(qr.x[ir]); // positive + // dt_float64 f = a*exp(-b*r*r + b_q*r) + c*exp(-d*r + b_q*r); + // qr.w[ir] *= f; + // } + + // // Azimuth part + // Quad_Coef_1d qa; + // qa.resize(lens.spt_inc_azm_npts); + // dt_float64 h = c_2pi/lens.spt_inc_azm_npts; + // for(auto ia = 0; ia < lens.spt_inc_azm_npts; ia++) + // { + // qa.x[ia] = ia*h; + // qa.w[ia] = h; + // } + + // qs.reserve(lens.spt_inc_rad_npts*lens.spt_inc_azm_npts); + // for(auto ir = 0; ir < lens.spt_inc_rad_npts; ir++) + // { + // for(auto ia = 0; ia < lens.spt_inc_azm_npts; ia++) + // { + // dt_float64 sin_theta, cos_theta; + // sincos(qa.x[ia], &sin_theta, &cos_theta); + // qs.x.push_back(qr.x[ir]*cos_theta); + // qs.y.push_back(qr.x[ir]*sin_theta); + // qs.w.push_back(qr.w[ir]*qa.w[ia]); + // } + // } + // } + // else + // { + // qs.resize(1); + // qs.x[0] = 0; + // qs.y[0] = 0; + // qs.w[0] = 1; + // } + // } + } + +#endif \ No newline at end of file diff --git a/src/cubic_spline.hpp b/src/cubic_spline.hpp deleted file mode 100644 index f87e4cf5..00000000 --- a/src/cubic_spline.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef SPLINE_H -#define SPLINE_H - -#ifdef _MSC_VER -#pragma once -#endif// _MSC_VER - -#include -#include -#include -#include - -#include "traits.cuh" - -namespace mt -{ - // Cubic_Spline interpolation - template - class Cubic_Spline - { - private: - // interpolation parameters - // f(x) = c3*(x-x_i)^3 + c2*(x-x_i)^2 + c1*(x-x_i) + c0 - Vector m_x, m_c3, m_c2, m_c1, m_c0; - public: - template - void set_points(const TVector &x, const TVector &y) - { - assert(x.size() == y.size()); - assert(x.size()>2); - int n =static_cast(x.size()); - - m_x.assign(x.begin(), x.end()); - m_c0.assign(y.begin(), y.end()); - m_c1.resize(n); - m_c2.resize(n); - m_c3.resize(n); - - Vector m_h(n); - Vector m_l(n); - Vector m_mu(n); - Vector m_z(n); - - n--; - - for(auto i = 0; i < n; i++) - { - m_h[i] = m_x[i+1]-m_x[i]; - } - - m_l[0] = 1; - m_mu[0] = 0; - m_z[0] = 0; - - for(auto i = 1; i < n; i++) - { - m_l[i] = 2*(m_x[i+1]-m_x[i-1])-m_h[i-1]*m_mu[i-1]; - m_mu[i] = m_h[i]/m_l[i]; - auto alpha = 3*(m_c0[i+1]-m_c0[i])/m_h[i]-3*(m_c0[i]-m_c0[i-1])/m_h[i-1]; - m_z[i] = (alpha-m_h[i-1]*m_z[i-1])/m_l[i]; - } - - m_l[n] = 1; - m_z[n] = 0; - m_c2[n] = 0; - - for(auto i =n-1; i >= 0; i--) - { - m_c2[i] = m_z[i] - m_mu[i]*m_c2[i+1]; - m_c1[i] = (m_c0[i+1]-m_c0[i])/m_h[i]-m_h[i]*(m_c2[i+1]+2*m_c2[i])/3; - m_c3[i] = (m_c2[i+1]-m_c2[i])/(3*m_h[i]); - } - } - - T operator() (T x) const - { - size_t n =m_x.size(); - // find the closest point m_x[idx] < x, idx = 0 even if x::const_iterator it; - auto it =std::lower_bound(m_x.begin(), m_x.end(), x); - int idx =std::max(int(it-m_x.begin())-1, 0); - - T h =x-m_x[idx]; - return ((m_c3[idx]*h + m_c2[idx])*h + m_c1[idx])*h + m_c0[idx]; - } - - template - void get_coeff(TCI_Coef &ci_coef) - { - ci_coef.c0.assign(m_c0.begin(), m_c0.end()); - ci_coef.c1.assign(m_c1.begin(), m_c1.end()); - ci_coef.c2.assign(m_c2.begin(), m_c2.end()); - ci_coef.c3.assign(m_c3.begin(), m_c3.end()); - } - - template - void eval_function(TVector_1 &x, TVector_2 &y) - { - for(auto i = 0; i - void eval_radial_function(const TGrid &grid_2d, Value_type x, Value_type y, TVector &V) - { - using X = Value_type; - - X r_max = x_max(); - X fr_max = (*this)(r_max); - for(auto ix = 0; ix < grid_2d.nx; ix++) - { - for(auto iy = 0; iy < grid_2d.ny; iy++) - { - X r = grid_2d.R2(ix, iy, x, y); - int ixy = grid_2d.ind_col(ix, iy); - V[ixy] = (r < r_max)?(*this)(r):fr_max; - } - } - } - - double x_min() const - { - return m_x.front(); - } - - double x_max() const - { - return m_x.back(); - } - }; - -} // namespace mt - -#endif diff --git a/src/detail/border_1d.inl b/src/detail/border_1d.inl new file mode 100755 index 00000000..02cf2003 --- /dev/null +++ b/src/detail/border_1d.inl @@ -0,0 +1,263 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "border_1d.h" + +/* template specialization 1d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(): bx_0(0), bx_e(0) {} + + template + Border_Rect_xd::Border_Rect_xd(const T& bx_0, const T& bx_e) + { + set_in_data(bx_0, bx_e); + } + + template + template + Border_Rect_xd::Border_Rect_xd(const dt_init_list& list) + { + set_in_data(list); + } + + template + template + Border_Rect_xd::Border_Rect_xd(const Vctr_cpu& vctr) + { + set_in_data(vctr); + } + + /* copy constructor */ + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& Border_Rect_xd::operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + bx_0 = border.bx_0; + bx_e = border.bx_e; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Border_Rect_xd& Border_Rect_xd::operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + bx_0 = T(border.bx_0); + bx_e = T(border.bx_e); + } + + return *this; + } + + template + template + CGPU_EXEC + void Border_Rect_xd::assign(const Border_Rect_xd& border) + { + *this = border; + } + + /***************************************************************************************/ + template + template + void Border_Rect_xd::set_in_data(const U& bx_0, const U& bx_e) + { + this->bx_0 = bx_0; + this->bx_e = bx_e; + } + + template + template + void Border_Rect_xd::set_in_data(const dt_init_list& list) + { + auto ptr = list.begin(); + + bx_0 = T(ptr[0]); + bx_e = T(ptr[1]); + } + + template + template + void Border_Rect_xd::set_in_data(const Vctr_cpu& vctr) + { + if (vctr.size_32()==1) + { + set_in_data({vctr[0], vctr[0]}); + } + else + { + set_in_data({vctr[0], vctr[1]}); + } + } + + template + CGPU_EXEC + void Border_Rect_xd::clear() + { + bx_0 = T(0); + bx_e = T(0); + } + + template + CGPU_EXEC + T Border_Rect_xd::bx_sum() const + { + return bx_0 + bx_e; + } + + template + CGPU_EXEC + T Border_Rect_xd::bx_min() const + { + return fcn_min(bx_0, bx_e); + } + + template + CGPU_EXEC + T Border_Rect_xd::bx_max() const + { + return fcn_max(bx_0, bx_e); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_x(const T& bs_x_i) const + { + return fcn_max(bs_x_i - bx_sum(), T(0)); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs(const T& bs_i) const + { + return bs_x(bs_i); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_min(const T& bs) const + { + return bs(bs); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_max(const T& bs) const + { + return bs(bs); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_x_h(const T& bs_x) const + { + return this->bs_x(bs_x)/T(2); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_h(const T& bs) const + { + return bs_x_h(bs); + } + + template + CGPU_EXEC + T Border_Rect_xd::rx_c(const T& bs_x) const + { + return bx_0 + bs_x_h(bs_x); + } + + template + CGPU_EXEC + T Border_Rect_xd::r_c(const T& bs) const + { + return rx_c(bs); + } + + template + CGPU_EXEC + T Border_Rect_xd::radius_x(const T& bs_x) const + { + return bs_x_h(bs_x); + } + + template + CGPU_EXEC + T Border_Rect_xd::radius(const T& bs) const + { + return radius_x(bs); + } + + template + CGPU_EXEC + T Border_Rect_xd::radius_x_p(const T& bs_x, const T& p) const + { + return (T(1)-p)*radius_x(bs_x); + } + + template + CGPU_EXEC + T Border_Rect_xd::radius_p(const T& bs, const T& p) const + { + return radius_x_p(bs, p); + } + + template + void Border_Rect_xd::set_by_sft(const T& bs, const T& dr) + { + bx_0 = fcn_set_bound(dr, T(0), bs); + bx_e = fcn_set_bound(bs - dr, T(0), bs); + } + + template + void Border_Rect_xd::sft_bdr(const T& bs, const T& dr) + { + bx_0 = fcn_set_bound(bx_0 + dr, T(0), bs); + bx_e = fcn_set_bound(bx_e - dr, T(0), bs); + } +} diff --git a/src/detail/border_2d.inl b/src/detail/border_2d.inl new file mode 100755 index 00000000..b78968e0 --- /dev/null +++ b/src/detail/border_2d.inl @@ -0,0 +1,288 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "border_2d.h" + +/* template specialization 2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(): Border_Rect_xd(), by_0(0), by_e(0) {} + + template + Border_Rect_xd::Border_Rect_xd(const T& bx_0, const T& bx_e, const T& by_0, const T& by_e) + { + set_in_data(bx_0, bx_e, by_0, by_e); + } + + template + template + Border_Rect_xd::Border_Rect_xd(const dt_init_list& list) + { + set_in_data(list); + } + + template + template + Border_Rect_xd::Border_Rect_xd(const Vctr_cpu& vctr) + { + set_in_data(vctr); + } + + /* copy constructor */ + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& Border_Rect_xd::operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + by_0 = border.by_0; + by_e = border.by_e; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Border_Rect_xd& Border_Rect_xd::operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + by_0 = T(border.by_0); + by_e = T(border.by_e); + } + + return *this; + } + + template + template + CGPU_EXEC + void Border_Rect_xd::assign(const Border_Rect_xd& border) + { + *this = border; + } + + /***************************************************************************************/ + template + template + void Border_Rect_xd::set_in_data(const U& bx_0, const U& bx_e, const U& by_0, const U& by_e) + { + Border_Rect_xd::set_in_data(bx_0, bx_e); + + this->by_0 = by_0; + this->by_e = by_e; + } + + template + template + void Border_Rect_xd::set_in_data(const dt_init_list& list) + { + auto ptr = list.begin(); + + Border_Rect_xd::set_in_data({ptr[0], ptr[1]}); + + by_0 = T(ptr[2]); + by_e = T(ptr[3]); + } + + template + template + void Border_Rect_xd::set_in_data(const Vctr_cpu& vctr) + { + const auto shape = vctr.shape(); + + if (shape[0]==1) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[0], vctr[0], vctr[0]}); + else if (shape[1]<3) + set_in_data({vctr[0], vctr[0], vctr[1], vctr[1]}); + else if (shape[1]<4) + set_in_data({vctr[0], vctr[1], vctr[2], T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3]}); + } + else if (shape[0]==2) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[1], T(0), T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3]}); + } + } + + template + CGPU_EXEC + void Border_Rect_xd::clear() + { + Border_Rect_xd::clear(); + + by_0 = T(0); + by_e = T(0); + } + + template + CGPU_EXEC + T Border_Rect_xd::by_sum() const + { + return by_0 + by_e; + } + + template + CGPU_EXEC + T Border_Rect_xd::by_min() const + { + return fcn_min(by_0, by_e); + } + + template + CGPU_EXEC + T Border_Rect_xd::by_max() const + { + return fcn_max(by_0, by_e); + } + template + CGPU_EXEC + T Border_Rect_xd::bs_y(const T& bs_y_i) const + { + return fcn_max(bs_y_i - by_sum(), T(0)); + } + + template + CGPU_EXEC + R_2d Border_Rect_xd::bs(const R_2d& bs_i) const + { + return {this->bs_x(bs_i.x), bs_y(bs_i.y)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_min(const R_2d& bs) const + { + return fmin(bs(bs)); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_max(const R_2d& bs) const + { + return fmax(bs(bs)); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_y_h(const T& bs_y) const + { + return this->bs_y(bs_y)/T(2); + } + + template + CGPU_EXEC + R_2d Border_Rect_xd::bs_h(const R_2d& bs) const + { + return {this->bs_x_h(bs.x), bs_y_h(bs.y)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::ry_c(const T& bs_y) const + { + return by_0 + bs_y_h(bs_y); + } + + template + CGPU_EXEC + R_2d Border_Rect_xd::r_c(const R_2d& bs) const + { + return {this->rx_c(bs.x), ry_c(bs.y)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::radius_y(const T& bs_y) const + { + return bs_y_h(bs_y); + } + + template + CGPU_EXEC + R_2d Border_Rect_xd::radius(const R_2d& bs) const + { + return {this->radius_x(bs.x), radius_y(bs.y)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::radius_y_p(const T& bs_y, const T& p) const + { + return (T(1)-p)*radius_y(bs_y); + } + + template + CGPU_EXEC + R_2d Border_Rect_xd::radius_p(const R_2d& bs, const T& p) const + { + return {this->radius_x_p(bs.x, p), radius_y_p(bs.y, p)}; + } + + template + void Border_Rect_xd::set_by_sft(const R_2d& bs, const R_2d& dr) + { + Border_Rect_xd::set_by_sft(bs.x, dr.x); + + by_0 = fcn_set_bound(dr.y, T(0), bs.y); + by_e = fcn_set_bound(bs.y - dr.y, T(0), bs.y); + } + + template + void Border_Rect_xd::sft_bdr(const R_2d& bs, const R_2d& dr) + { + Border_Rect_xd::sft_bdr(bs.x, dr.x); + + by_0 = fcn_set_bound(by_0 + dr.y, T(0), bs.y); + by_e = fcn_set_bound(by_e - dr.y, T(0), bs.y); + } +} \ No newline at end of file diff --git a/src/detail/border_3d.inl b/src/detail/border_3d.inl new file mode 100755 index 00000000..65c47e9e --- /dev/null +++ b/src/detail/border_3d.inl @@ -0,0 +1,295 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "border_3d.h" + +/* template specialization 3d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(): Border_Rect_xd(), bz_0(0), bz_e(0) {} + + template + Border_Rect_xd::Border_Rect_xd(const T& bx_0, const T& bx_e, const T& by_0, const T& by_e, const T& bz_0, const T& bz_e) + { + set_in_data(bx_0, bx_e, by_0, by_e, bz_0, bz_e); + } + + template + template + Border_Rect_xd::Border_Rect_xd(const dt_init_list& list) + { + set_in_data(list); + } + + template + template + Border_Rect_xd::Border_Rect_xd(const Vctr_cpu& vctr) + { + set_in_data(vctr); + } + + /* copy constructor */ + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Border_Rect_xd::Border_Rect_xd(const Border_Rect_xd& border) + { + *this = border; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Border_Rect_xd& Border_Rect_xd::operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + bz_0 = border.bz_0; + bz_e = border.bz_e; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Border_Rect_xd& Border_Rect_xd::operator=(const Border_Rect_xd& border) + { + if (this != &border) + { + Border_Rect_xd::operator=(border); + + bz_0 = T(border.bz_0); + bz_e = T(border.bz_e); + } + + return *this; + } + + template + template + CGPU_EXEC + void Border_Rect_xd::assign(const Border_Rect_xd& border) + { + *this = border; + } + + /***************************************************************************************/ + template + template + void Border_Rect_xd::set_in_data(const U& bx_0, const U& bx_e, const U& by_0, const U& by_e, const U& bz_0, const U& bz_e) + { + Border_Rect_xd::set_in_data(bx_0, bx_e, by_0, by_e); + + this->bz_0 = bz_0; + this->bz_e = bz_e; + } + + template + template + void Border_Rect_xd::set_in_data(const dt_init_list& list) + { + auto ptr = list.begin(); + + Border_Rect_xd::set_in_data({ptr[0], ptr[1], ptr[2], ptr[3]}); + + bz_0 = T(ptr[4]); + bz_e = T(ptr[5]); + } + + template + template + void Border_Rect_xd::set_in_data(const Vctr_cpu& vctr) + { + const auto shape = vctr.shape(); + + if (shape[0]==1) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[0], vctr[0], vctr[0], T(0), T(0)}); + else if (shape[1]<3) + set_in_data({vctr[0], vctr[0], vctr[1], vctr[1], T(0), T(0)}); + else if (shape[1]<4) + set_in_data({vctr[0], vctr[0], vctr[1], vctr[1], vctr[2], vctr[2]}); + else if (shape[1]<5) + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], T(0), T(0)}); + else if (shape[1]<6) + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], vctr[4], T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], vctr[4], vctr[5]}); + } + else if (shape[0]==2) + { + if (shape[1]<2) + set_in_data({vctr[0], vctr[1], T(0), T(0), T(0), T(0)}); + else if (shape[1]<3) + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], T(0), T(0)}); + else + set_in_data({vctr[0], vctr[1], vctr[2], vctr[3], vctr[4], vctr[5]}); + } + } + + template + CGPU_EXEC + void Border_Rect_xd::clear() + { + Border_Rect_xd::clear(); + + bz_0 = T(0); + bz_e = T(0); + } + + template + CGPU_EXEC + T Border_Rect_xd::bz_sum() const + { + return bz_0 + bz_e; + } + + template + CGPU_EXEC + T Border_Rect_xd::bz_min() const + { + return fcn_min(bz_0, bz_e); + } + + template + CGPU_EXEC + T Border_Rect_xd::bz_max() const + { + return fcn_max(bz_0, bz_e); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_z(const T& bs_z_i) const + { + return fcn_max(bs_z_i - bz_sum(), T(0)); + } + + template + CGPU_EXEC + R_3d Border_Rect_xd::bs(const R_3d& bs_i) const + { + return {this->bs_x(bs_i.x), this->bs_y(bs_i.y), bs_z(bs_i.z)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_min(const R_3d& bs) const + { + return fmin(bs(bs)); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_max(const R_3d& bs) const + { + return fmax(bs(bs)); + } + + template + CGPU_EXEC + T Border_Rect_xd::bs_z_h(const T& bs_z) const + { + return this->bs_z(bs_z)/T(2); + } + + template + CGPU_EXEC + R_3d Border_Rect_xd::bs_h(const R_3d& bs) const + { + return {this->bs_x_h(bs.x), this->bs_y_h(bs.y), bs_z_h(bs.z)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::rz_c(const T& bs_z) const + { + return bz_0 + bs_z_h(bs_z); + } + + template + CGPU_EXEC + R_3d Border_Rect_xd::r_c(const R_3d& bs) const + { + return {this->rx_c(bs.x), this->ry_c(bs.y), rz_c(bs.z)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::radius_z(const T& bs_z) const + { + return bs_z_h(bs_z); + } + + template + CGPU_EXEC + R_3d Border_Rect_xd::radius(const R_3d& bs) const + { + return {this->radius_x(bs.x), this->radius_y(bs.y), radius_z(bs.z)}; + } + + template + CGPU_EXEC + T Border_Rect_xd::radius_z_p(const T& bs_z, const T& p) const + { + return (T(1)-p)*radius_z(bs_z); + } + + template + CGPU_EXEC + R_3d Border_Rect_xd::radius_p(const R_3d& bs, const T& p) const + { + return {this->radius_x_p(bs.x, p), this->radius_y_p(bs.y, p), radius_z_p(bs.z, p)}; + } + + template + void Border_Rect_xd::set_by_sft(const R_3d& bs, const R_3d& dr) + { + Border_Rect_xd::set_bz_sft({bs.x, bs.y}, {dr.x, dr.y}); + + bz_0 = fcn_set_bound(dr.z, T(0), bs.z); + bz_e = fcn_set_bound(bs.z - dr.z, T(0), bs.z); + } + + template + void Border_Rect_xd::sft_bdr(const R_3d& bs, const R_3d& dr) + { + Border_Rect_xd::sft_bdr({bs.x, bs.y}, {dr.x, dr.y}); + + bz_0 = fcn_set_bound(bz_0 + dr.z, T(0), bs.z); + bz_e = fcn_set_bound(bz_e - dr.z, T(0), bs.z); + } +} \ No newline at end of file diff --git a/src/detail/fcn_butwth.inl b/src/detail/fcn_butwth.inl new file mode 100755 index 00000000..9f845dc4 --- /dev/null +++ b/src/detail/fcn_butwth.inl @@ -0,0 +1,162 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fcn_butwth.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem() : a_1(0), b_1(0), b_2(0) {} + + template + Fcn_Elem::Fcn_Elem(const T& a, const dt_int32& n, const T& radius) + { + set_in_data(a, n, radius); + } + + /* copy constructor */ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + b_2 = parm.b_2; + } + + return *this; + } + + /***************************************************************************************/ + template + void Fcn_Elem::set_in_data(const T& a, const dt_int32& n, const T& radius) + { + a_1 = a; + b_1 = n; + b_2 = ::square(radius); + } + + template + CGPU_EXEC + void Fcn_Elem::clear() + { + a_1 = T(0); + b_1 = dt_int32(0); + b_2 = T(0); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2, const dt_int32& n, const T& radius) const + { + return a_1/(T(1)+pow(r2/::square(radius), n)); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2) const + { + return a_1/(T(1)+pow(r2/b_2, b_1)); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r2(const R_2d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y)}; + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r2(const R_3d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y), eval_r2(r2.z)}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r, const dt_int32& n, const T& radius) const + { + return eval_r2(::square(r), n, radius); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r) const + { + return eval_r2(::square(r)); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r(const R_2d& r) const + { + return eval_r2(square(r)); + } + template + + CGPU_EXEC + R_3d Fcn_Elem::eval_r(const R_3d& r) const + { + return eval_r2(square(r)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r2, const dt_int32& n, const T& radius) const + { + return eval_r2(r2, n, radius); + } + + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r2) const + { + return eval_r2(r2); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::operator()(const R_2d& r2) const + { + return eval_r2(r2); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::operator()(const R_3d& r2) const + { + return eval_r2(r2); + } +} \ No newline at end of file diff --git a/src/detail/fcn_cos_tap.inl b/src/detail/fcn_cos_tap.inl new file mode 100755 index 00000000..21a766fe --- /dev/null +++ b/src/detail/fcn_cos_tap.inl @@ -0,0 +1,165 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fcn_cos_tap.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(): r_tap(0), r_max(0), coef_tap(0){} + + template + Fcn_Elem::Fcn_Elem(const T& r_tap, const T& r_max) + { + set_in_data(r_tap, r_max); + } + + /* copy constructor */ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + r_tap = parm.r_tap; + r_max = parm.r_max; + coef_tap = parm.coef_tap; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + r_tap = T(parm.r_tap); + r_max = T(parm.r_max); + coef_tap = T(parm.coef_tap); + + return *this; + } + + template + template + CGPU_EXEC + void Fcn_Elem::assign(const Fcn_Elem& parm) + { + *this = parm; + } + + /***************************************************************************************/ + template + void Fcn_Elem::set_in_data(const T& r_tap, const T& r_max) + { + this->r_tap = r_tap; + this->r_max = r_max; + + coef_tap = fcn_coef_tap(r_tap, r_max); + } + + template + CGPU_EXEC + void Fcn_Elem::clear() + { + r_tap = T(0); + r_max = T(0); + coef_tap = T(0); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r, const T& r_tap, const T& r_max) const + { + const T coef_tap = fcn_coef_tap(r_tap, r_max); + return fcn_cos_tap(r_tap, coef_tap, r); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r) const + { + return fcn_cos_tap(r_tap, coef_tap, r); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r(const R_2d& r) const + { + return {eval_r(r.x), eval_r(r.y)}; + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r(const R_3d& r) const + { + return {eval_r(r.x), eval_r(r.y), eval_r(r.z)}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r, const T& r_tap, const T& r_max) const + { + return eval_r(r, r_tap, r_max); + } + + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r) const + { + return eval_r(r); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::operator()(const R_2d& r) const + { + return eval_r(r); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::operator()(const R_3d& r) const + { + return eval_r(r); + } +} \ No newline at end of file diff --git a/src/detail/fcn_exp.inl b/src/detail/fcn_exp.inl new file mode 100755 index 00000000..467c351b --- /dev/null +++ b/src/detail/fcn_exp.inl @@ -0,0 +1,159 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fcn_exp.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(): a_1(0), b_1(0) {} + + template + Fcn_Elem::Fcn_Elem(const T& a, const T& beta) + { + set_in_data(a, beta); + } + + /* copy constructor */ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + } + + return *this; + } + + /***************************************************************************************/ + template + void Fcn_Elem::set_in_data(const T& a, const T& beta) + { + a_1 = a; + b_1 = T(1)/(beta); + } + + template + CGPU_EXEC + void Fcn_Elem::clear() + { + a_1 = T(0); + b_1 = T(0); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r, const T& beta) const + { + return a_1*exp(-r/beta); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r) const + { + return a_1*exp(-b_1*r); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r(const R_2d& r) const + { + return {eval_r(r.x), eval_r(r.y)}; + } + + template + CGPU_EXEC + R_3dFcn_Elem:: eval_r(const R_3d& r) const + { + return {eval_r(r.x), eval_r(r.y), eval_r(r.z)}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2, const T& beta) const + { + return eval_r(::sqrt(r2), beta); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2) const + { + return eval_r(::sqrt(r2)); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r2(const R_2d& r2) const + { + return eval_r(::sqrt(r2)); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r2(const R_3d& r2) const + { + return eval_r(::sqrt(r2)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r, const T& beta) const + { + return eval_r(r, beta); + } + + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r) const + { + return eval_r(r); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::operator()(const R_2d& r) const + { + return eval_r(r); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::operator()(const R_3d& r) const + { + return eval_r(r); + } +} diff --git a/src/detail/fcn_fermi.inl b/src/detail/fcn_fermi.inl new file mode 100755 index 00000000..f1ed9160 --- /dev/null +++ b/src/detail/fcn_fermi.inl @@ -0,0 +1,162 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fcn_fermi.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(): a_1(0), b_1(0), b_2(0) {} + + template + Fcn_Elem::Fcn_Elem(const T& a, const T& alpha, const T& radius) + { + set_in_data(a, alpha, radius); + } + + /* copy constructor */ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + b_2 = parm.b_2; + } + + return *this; + } + + /***************************************************************************************/ + template + void Fcn_Elem::set_in_data(const T& a, const T& alpha, const T& radius) + { + a_1 = a; + b_1 = alpha; + b_2 = ::square(radius); + } + + template + CGPU_EXEC + void Fcn_Elem::clear() + { + a_1 = T(0); + b_1 = T(0); + b_2 = T(0); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2, const T& radius) const + { + return a_1/(T(1) + exp(b_1*(r2-::square(radius)))); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2) const + { + return a_1/(T(1) + exp(b_1*(r2-b_2))); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r2(const R_2d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y)}; + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r2(const R_3d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y), eval_r2(r2.z)}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r, const T& radius) const + { + return eval_r2(::square(r), radius); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r) const + { + return eval_r2(::square(r)); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r(const R_2d& r) const + { + return eval_r2(square(r)); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r(const R_3d& r) const + { + return eval_r2(square(r)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r2, const T& radius) const + { + return eval_r2(r2, radius); + } + + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r2) const + { + return eval_r2(r2); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::operator()(const R_2d& r2) const + { + return eval_r2(r2); + } + + template + CGPU_EXEC + R_3dFcn_Elem:: operator()(const R_3d& r2) const + { + return eval_r2(r2); + } +} \ No newline at end of file diff --git a/src/detail/fcn_gauss.inl b/src/detail/fcn_gauss.inl new file mode 100755 index 00000000..3bebd790 --- /dev/null +++ b/src/detail/fcn_gauss.inl @@ -0,0 +1,185 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fcn_gauss.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(): a_1(0), b_1(0) {} + + template + Fcn_Elem::Fcn_Elem(const T& sigma) + { + set_in_data(T(1), sigma); + } + + template + Fcn_Elem::Fcn_Elem(const T& a, const T& sigma) + { + set_in_data(a, sigma); + } + + /* copy constructor */ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + a_1 = T(parm.a_1); + b_1 = T(parm.b_1); + + return *this; + } + + template + template + CGPU_EXEC + void Fcn_Elem::assign(const Fcn_Elem& parm) + { + *this = parm; + } + + /***************************************************************************************/ + template + void Fcn_Elem::set_in_data(const T& a, const T& sigma) + { + a_1 = a; + b_1 = T(1)/(T(2)*sigma*sigma); + } + + template + CGPU_EXEC + void Fcn_Elem::clear() + { + a_1 = T(0); + b_1 = T(0); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2, const T& sigma) const + { + return a_1*exp(-r2/(T(2)*sigma*sigma)); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2) const + { + return a_1*exp(-b_1*r2); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r2(const R_2d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y)}; + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r2(const R_3d& r2) const + { + return {eval_r2(r2.x), eval_r2(r2.y), eval_r2(r2.z)}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r, const T& sigma) const + { + return eval_r2(::square(r), sigma); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r) const + { + return eval_r2(::square(r)); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r(const R_2d& r) const + { + return eval_r2(square(r)); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r(const R_3d& r) const + { + return eval_r2(square(r)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r2, const T& sigma) const + { + return eval_r2(r2, sigma); + } + + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r2) const + { + return eval_r2(r2); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::operator()(const R_2d& r2) const + { + return eval_r2(r2); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::operator()(const R_3d& r2) const + { + return eval_r2(r2); + } +} \ No newline at end of file diff --git a/src/detail/fcn_hann.inl b/src/detail/fcn_hann.inl new file mode 100755 index 00000000..517637cb --- /dev/null +++ b/src/detail/fcn_hann.inl @@ -0,0 +1,159 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fcn_hann.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(): a_1(0), b_1(0) {} + + template + Fcn_Elem::Fcn_Elem(const T& a, const T& l) + { + set_in_data(a, l); + } + + /* copy constructor */ + template + CGPU_EXEC + Fcn_Elem::Fcn_Elem(const Fcn_Elem& parm) + { + *this = parm; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Fcn_Elem& Fcn_Elem::operator=(const Fcn_Elem& parm) + { + if (this != &parm) + { + a_1 = parm.a_1; + b_1 = parm.b_1; + } + + return *this; + } + + /***************************************************************************************/ + template + void Fcn_Elem::set_in_data(const T& a, const T& l) + { + a_1 = a; + b_1 = c_pi/l; + } + + template + CGPU_EXEC + void Fcn_Elem::clear() + { + a_1 = T(0); + b_1 = T(0); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r, const T& l) const + { + return a_1*::square(cos(c_pi*r/l)); // r<=l/2, otherwise 0 + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r(const T& r) const + { + return a_1*::square(cos(b_1*r)); // r<=l/2, otherwise 0 + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r(const R_2d& r) const + { + return {eval_r(r.x), eval_r(r.y)}; + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r(const R_3d& r) const + { + return {eval_r(r.x), eval_r(r.y), eval_r(r.z)}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2, const T& l) const + { + return eval_r(::sqrt(r2), l); + } + + template + CGPU_EXEC + T Fcn_Elem::eval_r2(const T& r2) const + { + return eval_r(::sqrt(r2)); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::eval_r2(const R_2d& r2) const + { + return eval_r(::sqrt(r2)); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::eval_r2(const R_3d& r2) const + { + return eval_r(::sqrt(r2)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r, const T& l) const + { + return eval_r(r, l); + } + + template + CGPU_EXEC + T Fcn_Elem::operator()(const T& r) const + { + return eval_r(r); + } + + template + CGPU_EXEC + R_2d Fcn_Elem::operator()(const R_2d& r) const + { + return eval_r(r); + } + + template + CGPU_EXEC + R_3d Fcn_Elem::operator()(const R_3d& r) const + { + return eval_r(r); + } +} \ No newline at end of file diff --git a/src/detail/fft_cpu.inl b/src/detail/fft_cpu.inl new file mode 100755 index 00000000..051119dc --- /dev/null +++ b/src/detail/fft_cpu.inl @@ -0,0 +1,355 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fft_cpu.h" + +/* cpu fourier transform - dt_float32 */ +namespace mt +{ + FFT::FFT(): plan_forward(nullptr), plan_backward(nullptr) + { + fftwf_init_threads(); + } + + FFT::FFT(const dt_int32& s0, Stream_cpu* pstream): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_1d(s0, n_thread); + } + + FFT::FFT(const dt_int32& s0, const dt_int32& s1, Stream_cpu* pstream): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_2d(s0, s1, n_thread); + } + + FFT::~FFT() + { + destroy_plan(); + } + + void FFT::cleanup() + { + destroy_plan(); + + fftwf_cleanup_threads(); + } + + void FFT::destroy_plan() + { + if (plan_backward == nullptr) + { + return; + } + + fftwf_destroy_plan(plan_forward); + fftwf_destroy_plan(plan_backward); + + plan_backward = plan_forward = nullptr; + } + + void FFT::create_plan_1d(const dt_int32& s0, dt_int32 n_thread) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_1d.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0); + + auto pdata = M.data_cast(); + + plan_forward = fftwf_plan_dft_1d(s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_dft_1d(s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_1d.wisdom"); + } + + void FFT::create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_1d_batch.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_many = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_1d_batch.wisdom"); + } + + void FFT::create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_2d.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + plan_forward = fftwf_plan_dft_2d(s1, s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_dft_2d(s1, s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d.wisdom"); + } + + void FFT::create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_2d_batch.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1*s2); + + auto pdata = M.data_cast(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_many = s2; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d_batch.wisdom"); + } + + void FFT::forward(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftwf_execute_dft(plan_forward, pdata, pdata); + } + + void FFT::inverse(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftwf_execute_dft(plan_backward, pdata, pdata); + } + + void FFT::forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + forward(mx_o); + } + + void FFT::inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + inverse(mx_o); + } +} + +/* cpu fourier transform - dt_float64 */ +namespace mt +{ + FFT::FFT(): plan_forward(nullptr), plan_backward(nullptr) + { + fftw_init_threads(); + } + + FFT::FFT(const dt_int32& s0, Stream_cpu* pstream): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_1d(s0, n_thread); + } + + FFT::FFT(const dt_int32& s0, const dt_int32& s1, Stream_cpu* pstream): FFT() + { + const dt_int32 n_thread = (fcn_is_single_thread(pstream))?1:pstream->size(); + + create_plan_2d(s0, s1, n_thread); + } + + FFT::~FFT() + { + destroy_plan(); + } + + void FFT::cleanup() + { + destroy_plan(); + + fftw_cleanup_threads(); + } + + void FFT::destroy_plan() + { + if (plan_backward == nullptr) + { + return; + } + + fftw_destroy_plan(plan_forward); + fftw_destroy_plan(plan_backward); + + plan_backward = plan_forward = nullptr; + } + + void FFT::create_plan_1d(const dt_int32& s0, dt_int32 n_thread) + { + destroy_plan(); + + fftw_import_wisdom_from_filename("fftw_1d.wisdom"); + + fftw_plan_with_nthreads(n_thread); + + TVctr_c M(s0); + + auto pdata = M.data_cast(); + + plan_forward = fftw_plan_dft_1d(s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_dft_1d(s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftw_export_wisdom_to_filename("fftw_1d.wisdom"); + } + + void FFT::create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + fftw_import_wisdom_from_filename("fftw_1d_batch.wisdom"); + + fftw_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_many = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftw_export_wisdom_to_filename("fftw_1d_batch.wisdom"); + } + + void FFT::create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + fftw_import_wisdom_from_filename("fftw_2d.wisdom"); + + fftw_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1); + + auto pdata = M.data_cast(); + + plan_forward = fftw_plan_dft_2d(s1, s0, pdata, pdata, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_dft_2d(s1, s0, pdata, pdata, FFTW_BACKWARD, FFTW_MEASURE); + + fftw_export_wisdom_to_filename("fftw_2d.wisdom"); + } + + void FFT::create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftw_2d_batch.wisdom"); + + fftwf_plan_with_nthreads(n_thread); + + TVctr_c M(s0*s1*s2); + + auto pdata = M.data_cast(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_many = s2; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_many_dft(rank, n, how_many, pdata, inembed, istride, idist, pdata, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d_batch.wisdom"); + } + + void FFT::forward(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftw_execute_dft(plan_forward, pdata, pdata); + } + + void FFT::inverse(TVctr_c& mx) + { + auto pdata = mx.data_cast(); + + fftw_execute_dft(plan_backward, pdata, pdata); + } + + void FFT::forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + forward(mx_o); + } + + void FFT::inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + if (mx_i.data() != mx_o.data()) + { + mx_o.assign(mx_i.begin(), mx_i.end()); + } + + inverse(mx_o); + } +} \ No newline at end of file diff --git a/src/detail/fft_gpu.inl b/src/detail/fft_gpu.inl new file mode 100755 index 00000000..b3702ee9 --- /dev/null +++ b/src/detail/fft_gpu.inl @@ -0,0 +1,256 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "fft_gpu.h" + +/* gpu fourier transform - dt_float32 */ +namespace mt +{ + FFT::FFT(): plan_forward(0), plan_backward(0) {} + + FFT::FFT(const dt_int32& s0, Stream_gpu* pstream): FFT() + { + create_plan_1d(s0); + } + + FFT::FFT(const dt_int32& s0, const dt_int32& s1, Stream_gpu* pstream): FFT() + { + create_plan_2d(s0, s1); + } + + FFT::~FFT() + { + destroy_plan(); + } + + void FFT::cleanup() + { + destroy_plan(); + } + + void FFT::destroy_plan() + { + if (plan_backward == 0) + { + return; + } + + cudaDeviceSynchronize(); + + cufftDestroy(plan_forward); + plan_backward = plan_forward = 0; + } + + void FFT::create_plan_1d(const dt_int32& s0, dt_int32 n_thread) + { + destroy_plan(); + + cufftPlan1d(&plan_forward, s0, CUFFT_C2C, 1); + + plan_backward = plan_forward; + } + + void FFT::create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_many = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, how_many); + + plan_backward = plan_forward; + } + + void FFT::create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + // https:// docs.nvidia.com/cuda/cufft/index.html + cufftPlan2d(&plan_forward, s1, s0, CUFFT_C2C); + + plan_backward = plan_forward; + } + + void FFT::create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& nz, dt_int32 n_thread) + { + destroy_plan(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_many = nz; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, how_many); + + plan_backward = plan_forward; + } + + void FFT::set_stream(cudaStream_t &stream) + { + cufftSetStream(plan_forward, stream); + } + + void FFT::forward(TVctr_c& mx) + { + forward(mx, mx); + } + + void FFT::inverse(TVctr_c& mx) + { + inverse(mx, mx); + } + + void FFT::forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecC2C(plan_forward, pdata_i, pdata_o, CUFFT_FORWARD); + } + + void FFT::inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecC2C(plan_backward, pdata_i, pdata_o, CUFFT_INVERSE); + } +} + +/* gpu fourier transform - dt_float64 */ +namespace mt +{ + FFT::FFT(): plan_forward(0), plan_backward(0) {} + + FFT::FFT(const dt_int32& s0, Stream_gpu* pstream): FFT() + { + create_plan_1d(s0); + } + + FFT::FFT(const dt_int32& s0, const dt_int32& s1, Stream_gpu* pstream): FFT() + { + create_plan_2d(s0, s1); + } + + FFT::~FFT() + { + destroy_plan(); + } + + void FFT::cleanup() + { + destroy_plan(); + } + + void FFT::destroy_plan() + { + if (plan_backward == 0) + { + return; + } + + cudaDeviceSynchronize(); + + cufftDestroy(plan_forward); + plan_backward = plan_forward = 0; + } + + void FFT::create_plan_1d(const dt_int32& s0, dt_int32 n_thread) + { + destroy_plan(); + + cufftPlan1d(&plan_forward, s0, CUFFT_Z2Z, 1); + + plan_backward = plan_forward; + } + + void FFT::create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + dt_int32 rank = 1; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s0}; // 1d transforms of length s0*s1 + dt_int32 how_mas0 = s1; + dt_int32 idist = s0, odist = s0; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_Z2Z, how_mas0); + + plan_backward = plan_forward; + } + + void FFT::create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread) + { + destroy_plan(); + + // https:// docs.nvidia.com/cuda/cufft/index.html + cufftPlan2d(&plan_forward, s1, s0, CUFFT_Z2Z); + + plan_backward = plan_forward; + } + + void FFT::create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread) + { + destroy_plan(); + + dt_int32 rank = 2; // Dimensionality of the transform (1, 2, or 3). + dt_int32 n[] = {s1, s0}; // 2d transforms of length s0*s1 + dt_int32 how_mas0 = s2; + dt_int32 idist = s0*s1, odist = s0*s1; // distance between two successive in elements in the least significant + dt_int32 istride = 1, ostride = 1; // distance between two elements in the same column + dt_int32 *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_Z2Z, how_mas0); + + plan_backward = plan_forward; + } + + void FFT::forward(TVctr_c& mx) + { + forward(mx, mx); + } + + void FFT::inverse(TVctr_c& mx) + { + inverse(mx, mx); + } + + void FFT::forward(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecZ2Z(plan_forward, pdata_i, pdata_o, CUFFT_FORWARD); + } + + void FFT::inverse(TVctr_c& mx_i, TVctr_c& mx_o) + { + auto pdata_i = mx_i.data_cast(); + auto pdata_o = mx_o.data_cast(); + + cufftExecZ2Z(plan_backward, pdata_i, pdata_o, CUFFT_INVERSE); + } +} \ No newline at end of file diff --git a/src/detail/grid_1d.inl b/src/detail/grid_1d.inl new file mode 100755 index 00000000..bc12d470 --- /dev/null +++ b/src/detail/grid_1d.inl @@ -0,0 +1,728 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "grid_1d.h" + +/* template specialization 1d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Grid_sxd::Grid_sxd(): iGrid_sxd(), bs_x(0), rx_0(0), pbc_x(true), + bwl(false), sli_thick(0), drx(0), dgx(0) {} + + template + Grid_sxd::Grid_sxd(const ST& nx) + { + set_in_data(nx); + } + + template + template + Grid_sxd::Grid_sxd(const U& bs_x, const SU& nx) + { + set_in_data(bs_x, nx); + } + + template + template + Grid_sxd::Grid_sxd(const U& bs_x, const SU& nx, const U& rx_0, + dt_bool pbc_x, dt_bool bwl, U sli_thick) + { + set_in_data(bs_x, nx, rx_0, pbc_x, bwl, sli_thick); + } + + /* copy constructor */ + template + CGPU_EXEC + Grid_sxd::Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Grid_sxd::Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Grid_sxd& Grid_sxd::operator=(const Grid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + bs_x = grid.bs_x; + rx_0 = grid.rx_0; + pbc_x = grid.pbc_x; + bwl = grid.bwl; + sli_thick = grid.sli_thick; + + drx = grid.drx; + dgx = grid.dgx; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Grid_sxd& Grid_sxd::operator=(const Grid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + bs_x = T(grid.bs_x); + rx_0 = T(grid.rx_0); + pbc_x = grid.pbc_x; + bwl = grid.bwl; + sli_thick = T(grid.sli_thick); + + drx = T(grid.drx); + dgx = T(grid.dgx); + + return *this; + } + + template + template + CGPU_EXEC + void Grid_sxd::assign(const Grid_sxd& grid) + { + *this = grid; + } + + /************************ user define conversion operators ****************************/ + template + Grid_sxd::operator iRegion_Rect_xd() const + { + return {ST(0), this->nx}; + } + + /***************************************************************************************/ + template + void Grid_sxd::set_in_data(const ST& nx) + { + set_in_data(T(nx), nx, T(0)); + } + + template + template + void Grid_sxd::set_in_data(const U& bs_x, const SU& nx) + { + set_in_data(T(bs_x), ST(nx), T(0)); + } + + template + template + void Grid_sxd::set_in_data(const U& bs_x, const SU& nx, + const U& rx_0, dt_bool pbc_x, dt_bool bwl, U sli_thick) + { + this->set_size(nx); + + this->bs_x = T(bs_x); + this->rx_0 = T(rx_0); + this->pbc_x = pbc_x; + this->bwl = bwl; + this->sli_thick = T(sli_thick); + + set_dep_var(); + } + + template + void Grid_sxd::set_dep_var() + { + drx = mt::fcn_div(bs_x, this->nx); + dgx = mt::fcn_div(T(1), bs_x); + } + + template + CGPU_EXEC + void Grid_sxd::set_r_0(const T& rx_0) + { + this->rx_0 = rx_0; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::nx_r() const + { + return T(this->nx); + } + + template + CGPU_EXEC + T Grid_sxd::size_r() const + { + return T(this->size()); + } + + template + T Grid_sxd::isize_r() const + { + return T(1)/size_r(); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::bs_x_h() const + { + return T(0.5)*bs_x; + } + + template + CGPU_EXEC + T Grid_sxd::bs_h() const + { + return bs_x_h(); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_c() const + { + return rx_0 + bs_x_h(); + } + + template + CGPU_EXEC + T Grid_sxd::rv_c() const + { + return rx_c(); + } + + /***************************************************************************************/ + // maximum frequency + template + CGPU_EXEC + T Grid_sxd::g_max() const + { + return gx_back(); + } + + // maximum square frequency + template + CGPU_EXEC + T Grid_sxd::g2_max() const + { + return ::square(g_max()); + } + + // maximum allowed frequency + template + CGPU_EXEC + T Grid_sxd::gl_max() const + { + return g_max()*T(2.0/3.0); + } + + // maximum square allowed frequency + template + CGPU_EXEC + T Grid_sxd::gl2_max() const + { + return ::square(gl_max()); + } + + /***************************************************************************************/ + /****************************** Fourier space positions ********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx(const ST& ix) const + { + return T(this->igx(ix))*dgx; + } + + template + CGPU_EXEC + T Grid_sxd::gx2(const ST& ix) const + { + return ::square(gx(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix) const + { + return gx2(ix); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix) const + { + return ::fabs(gx(ix)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx(const ST& ix, const T& gx_0) const + { + return gx(ix) - gx_0; + } + + template + CGPU_EXEC + T Grid_sxd::gx2(const ST& ix, const T& gx_0) const + { + return ::square(gx(ix, gx_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix, const T& gx_0) const + { + return gx2(ix, gx_0); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix, const T& gx_0) const + { + return ::fabs(gx(ix, gx_0)); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_sft(const ST& ix) const + { + return T(this->igx_sft(ix))*dgx; + } + + template + CGPU_EXEC + T Grid_sxd::gx2_sft(const ST& ix) const + { + return ::square(gx_sft(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix) const + { + return gx2_sft(ix); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix) const + { + return ::fabs(gx_sft(ix)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_sft(const ST& ix, const T& gx_0) const + { + return gx_sft(ix) - gx_0; + } + + template + CGPU_EXEC + T Grid_sxd::gx2_sft(const ST& ix, const T& gx_0) const + { + return ::square(gx_sft(ix, gx_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix, const T& gx_0) const + { + return gx2_sft(ix, gx_0); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix, const T& gx_0) const + { + return ::fabs(gx_sft(ix, gx_0)); + } + + /***************************************************************************************/ + /******************************** real space positions *********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx(const ST& ix) const + { + return T(this->irx(ix))*drx + rx_0; + } + + template + CGPU_EXEC + T Grid_sxd::rx2(const ST& ix) const + { + return ::square(rx(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix) const + { + return rx2(ix); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix) const + { + return ::fabs(rx(ix)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx(const ST& ix, const T& x0) const + { + return rx(ix) - x0; + } + + template + CGPU_EXEC + T Grid_sxd::rx2(const ST& ix, const T& x0) const + { + return ::square(rx(ix, x0)); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix, const T& x0) const + { + return rx2(ix, x0); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix, const T& x0) const + { + return ::fabs(rx(ix, x0)); + } + + /***************************************************************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_sft(const ST& ix) const + { + return T(this->irx_sft(ix))*drx + rx_0; + } + + template + CGPU_EXEC + T Grid_sxd::rx2_sft(const ST& ix) const + { + return ::square(rx_sft(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix) const + { + return rx2_sft(ix); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix) const + { + return ::fabs(rx_sft(ix)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_sft(const ST& ix, const T& x0) const + { + return rx_sft(ix) - x0; + } + + template + CGPU_EXEC + T Grid_sxd::rx2_sft(const ST& ix, const T& x0) const + { + return ::square(rx_sft(ix, x0)); + } + + template + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix, const T& x0) const + { + return rx2_sft(ix, x0); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix, const T& x0) const + { + return ::fabs(rx_sft(ix, x0)); + } + + /***************************************************************************************/ + /******************************* from position to index ********************************/ + /***************************************************************************************/ + template + template + void Grid_sxd::ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_n); + } + + template + template + void Grid_sxd::ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_e); + ix_e += ix_0; + } + + /************ fds = floor/division by pixel size ************/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_fd(const T& x) const + { + return fcn_cfloor(x/drx); + } + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bfd(const T& x) const + { + return fcn_set_bound(rx_2_irx_fd(x), ST(0), this->nx-1); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_cd(const T& x) const + { + return fcn_cceil(x/drx); + } + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bcd(const T& x) const + { + return fcn_set_bound(rx_2_irx_cd(x), ST(0), this->nx-1); + } + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_fds(const T& x) const + { + return fcn_cfloor((x - rx_0)/drx); + } + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bfds(const T& x) const + { + return fcn_set_bound(rx_2_irx_fds(x), ST(0), this->nx-1); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_cds(const T& x) const + { + return fcn_cceil((x - rx_0)/drx); + } + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bcds(const T& x) const + { + return fcn_set_bound(rx_2_irx_cds(x), ST(0), this->nx-1); + } + + /************ From position to index by searching ***********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_b(const T& x, ST ix_min, ST ix_max) const + { + if (ix_min == ix_max) + { + ix_min = ST(0); + ix_max = this->nx-1; + } + + return fcn_r_2_ir_b_by_fcn(rx, ix_min, ix_max); + } + + /***************************************************************************************/ + /********************************** check bounds ***************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_front(), rx_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_front(), rx_back()); + } + + /***************************************************************************************/ + /************************************ set bounds ***************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::set_bound_x(const T& x) const + { + return fcn_set_bound(x, rx_front(), rx_back()); + } + + /***************************************************************************************/ + /*********************************** front/back ****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_front() const + { + return gx(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::gx_back() const + { + return gx(this->nx-1); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_front() const + { + return rx(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::rx_back() const + { + return rx(this->nx-1); + } + + /***************************************************************************************/ + /************************************** factors ****************************************/ + /***************************************************************************************/ + /* calculate fermi low-pass filter alpha parameter */ + template + CGPU_EXEC + T Grid_sxd::fermi_lpf_alpha() const + { + return fcn_fermi_lpf_alpha(gl_max(), T(0.25), T(1e-02)); + } + + template + CGPU_EXEC + T Grid_sxd::factor_2pi_rx_ctr(const T& x) const + { + return fcn_n_2pi_sft(x, bs_x_h()); + } + + template + CPU_EXEC + Vctr Grid_sxd::factor_2pi_rv_ctr(const Vctr& rv) const + { + Vctr rv_o(rv.size()); + + for(auto ik = 0; ik + iRegion_Rect_xd Grid_sxd::iregion_rect(const T& r, const T& radius) const + { + return {rx_2_irx_bfds(r - radius), rx_2_irx_bcds(r + radius)}; + } +} + +/* traits */ +namespace mt +{ + template + struct is_grid_1d: std::integral_constant>::value> {}; + + /***************************************************************************************/ + template + struct is_grid_1d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_1d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_grid_1d_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_1d_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_grid_1d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_1d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_grid_1d_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_1d_and_cvctr_gpu = typename std::enable_if::value, V>::type; +} \ No newline at end of file diff --git a/src/detail/grid_2d.inl b/src/detail/grid_2d.inl new file mode 100755 index 00000000..0e410c6b --- /dev/null +++ b/src/detail/grid_2d.inl @@ -0,0 +1,1354 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "grid_2d.h" + +/* template specialization 2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Grid_sxd::Grid_sxd(): iGrid_sxd(), bs_x(0), bs_y(0), + rx_0(0), ry_0(0), pbc_x(true), pbc_y(true), bwl(false), sli_thick(0), + drx(0), dry(0), dgx(0), dgy(0) {} + + template + Grid_sxd::Grid_sxd(const ST& nx, const ST& ny) + { + set_in_data(nx, ny); + } + + template + template + Grid_sxd::Grid_sxd(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny) + { + set_in_data(bs_x, bs_y, nx, ny); + } + + template + template + Grid_sxd::Grid_sxd(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny, const U& rx_0, const U& ry_0, + dt_bool pbc_x, dt_bool pbc_y, dt_bool bwl, U sli_thick) + { + set_in_data(bs_x, bs_y, nx, ny, rx_0, ry_0, pbc_x, pbc_y, bwl, sli_thick); + } + + /* copy constructor */ + template + CGPU_EXEC + Grid_sxd::Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Grid_sxd::Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Grid_sxd& Grid_sxd::operator=(const Grid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + bs_x = grid.bs_x; + bs_y = grid.bs_y; + rx_0 = grid.rx_0; + ry_0 = grid.ry_0; + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + bwl = grid.bwl; + sli_thick = grid.sli_thick; + + drx = grid.drx; + dry = grid.dry; + dgx = grid.dgx; + dgy = grid.dgy; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Grid_sxd& Grid_sxd::operator=(const Grid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + bs_x = T(grid.bs_x); + bs_y = T(grid.bs_y); + rx_0 = T(grid.rx_0); + ry_0 = T(grid.ry_0); + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + bwl = grid.bwl; + sli_thick = T(grid.sli_thick); + + drx = T(grid.drx); + dry = T(grid.dry); + dgx = T(grid.dgx); + dgy = T(grid.dgy); + + return *this; + } + + template + template + CGPU_EXEC + void Grid_sxd::assign(const Grid_sxd& grid) + { + *this = grid; + } + + /************************** user define conversion operators ***************************/ + template + Grid_sxd::operator iRegion_Rect_xd() const + { + return {ST(0), this->nx, ST(0), this->ny}; + } + + /***************************************************************************************/ + template + void Grid_sxd::set_in_data(const ST& nx, const ST& ny) + { + set_in_data(T(nx), T(ny), nx, ny, T(0), T(0)); + } + + template + template + void Grid_sxd::set_in_data(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny) + { + set_in_data(T(bs_x), T(bs_y), ST(nx), ST(ny), T(0), T(0)); + } + + template + template + void Grid_sxd::set_in_data(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny, + const U& rx_0, const U& ry_0, dt_bool pbc_x, dt_bool pbc_y, dt_bool bwl, U sli_thick) + { + this->set_size(nx, ny); + + this->bs_x = T(bs_x); + this->bs_y = T(bs_y); + this->rx_0 = T(rx_0); + this->ry_0 = T(ry_0); + this->pbc_x = pbc_x; + this->pbc_y = pbc_y; + this->bwl = bwl; + this->sli_thick = T(sli_thick); + + set_dep_var(); + } + + template + void Grid_sxd::set_dep_var() + { + drx = mt::fcn_div(bs_x, this->nx); + dry = mt::fcn_div(bs_y, this->ny); + dgx = mt::fcn_div(T(1), bs_x); + dgy = mt::fcn_div(T(1), bs_y); + } + + template + CGPU_EXEC + void Grid_sxd::set_r_0(const T& rx_0, const T& ry_0) + { + this->rx_0 = rx_0; + this->ry_0 = ry_0; + } + + template + CGPU_EXEC + void Grid_sxd::set_r_0(const R_2d& r_0) + { + set_r_0(r_0.x, r_0.y); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::nx_r() const + { + return T(this->nx); + } + + template + CGPU_EXEC + T Grid_sxd::ny_r() const + { + return T(this->ny); + } + + template + CGPU_EXEC + T Grid_sxd::size_r() const + { + return T(this->size()); + } + + template + T Grid_sxd::isize_r() const + { + return T(1)/size_r(); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::bs_x_h() const + { + return T(0.5)*bs_x; + } + + template + CGPU_EXEC + T Grid_sxd::bs_y_h() const + { + return T(0.5)*bs_y; + } + + template + CGPU_EXEC + R_2d Grid_sxd::bs_h() const + { + return {bs_x_h(), bs_y_h()}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::bs_min() const + { + return ::fmin(bs_x, bs_y); + } + + template + CGPU_EXEC + T Grid_sxd::bs_max() const + { + return ::fmax(bs_x, bs_y); + } + + template + CGPU_EXEC + T Grid_sxd::bs_h_min() const + { + return T(0.5)*bs_min(); + } + + template + CGPU_EXEC + T Grid_sxd::bs_h_max() const + { + return T(0.5)*bs_max(); + } + + template + CGPU_EXEC + T Grid_sxd::rx_c() const + { + return rx_0 + bs_x_h(); + } + + template + CGPU_EXEC + T Grid_sxd::ry_c() const + { + return ry_0 + bs_y_h(); + } + + template + CGPU_EXEC + R_2d Grid_sxd::rv_c() const + { + return {rx_c(), ry_c()}; + } + + /***************************************************************************************/ + // maximum frequency + template + CGPU_EXEC + T Grid_sxd::g_max() const + { + return ::fmin(gx_back(), gy_back()); + } + + // maximum square frequency + template + CGPU_EXEC + T Grid_sxd::g2_max() const + { + return ::square(g_max()); + } + + // maximum allowed frequency + template + CGPU_EXEC + T Grid_sxd::gl_max() const + { + return g_max()*T(2.0/3.0); + } + + // maximum square allowed frequency + template + CGPU_EXEC + T Grid_sxd::gl2_max() const + { + return ::square(gl_max()); + } + + template + CGPU_EXEC + T Grid_sxd::r_0_min() const + { + return ::fmin(rx_0, ry_0); + } + + template + CGPU_EXEC + T Grid_sxd::dr_min() const + { + return ::fmin(drx, dry); + } + + template + CGPU_EXEC + T Grid_sxd::dg_min() const + { + return ::fmin(dgx, dgy); + } + + /***************************************************************************************/ + /***************************** Fourier space positions *********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx(const ST& ix) const + { + return T(this->igx(ix))*dgx; + } + + template + CGPU_EXEC + T Grid_sxd::gy(const ST& iy) const + { + return T(this->igy(iy))*dgy; + } + + template + CGPU_EXEC + R_2d Grid_sxd::gv(const ST& ix, const ST& iy) const + { + return {gx(ix), gy(iy)}; + } + + template + CGPU_EXEC + T Grid_sxd::gx2(const ST& ix) const + { + return ::square(gx(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2(const ST& iy) const + { + return ::square(gy(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix, const ST& iy) const + { + return gx2(ix) + gy2(iy); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix, const ST& iy) const + { + return ::sqrt(g2(ix, iy)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx(const ST& ix, const T& gx_0) const + { + return gx(ix) - gx_0; + } + + template + CGPU_EXEC + T Grid_sxd::gy(const ST& iy, const T& gy_0) const + { + return gy(iy) - gy_0; + } + + template + CGPU_EXEC + R_2d Grid_sxd::gv(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return {gx(ix, gx_0), gy(iy, gy_0)}; + } + + template + CGPU_EXEC + R_2d Grid_sxd::gv(const ST& ix, const ST& iy, const R_2d& g_0) const + { + return gv(ix, iy, g_0.x, g_0.y); + } + + template + CGPU_EXEC + T Grid_sxd::gx2(const ST& ix, const T& gx_0) const + { + return ::square(gx(ix, gx_0)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2(const ST& iy, const T& gy_0) const + { + return ::square(gy(iy, gy_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return gx2(ix, gx_0) + gy2(iy, gy_0); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix, const ST& iy, const R_2d& g0) const + { + return gx2(ix, iy, g0.x, g0.y); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return ::sqrt(g2(ix, iy, gx_0, gy_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix, const ST& iy, const R_2d& g0) const + { + return ::sqrt(g2(ix, iy, g0)); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_sft(const ST& ix) const + { + return T(this->igx_sft(ix))*dgx; + } + + template + CGPU_EXEC + T Grid_sxd::gy_sft(const ST& iy) const + { + return T(this->igy_sft(iy))*dgy; + } + + template + CGPU_EXEC + R_2d Grid_sxd::gv_sft(const ST& ix, const ST& iy) const + { + return {gx_sft(ix), gy_sft(iy)}; + } + + template + CGPU_EXEC + T Grid_sxd::gx2_sft(const ST& ix) const + { + return ::square(gx_sft(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2_sft(const ST& iy) const + { + return ::square(gy_sft(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix, const ST& iy) const + { + return gx2_sft(ix) + gy2_sft(iy); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix, const ST& iy) const + { + return ::sqrt(g2_sft(ix, iy)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_sft(const ST& ix, const T& gx_0) const + { + return gx_sft(ix) - gx_0; + } + + template + CGPU_EXEC + T Grid_sxd::gy_sft(const ST& iy, const T& gy_0) const + { + return gy_sft(iy) - gy_0; + } + + template + CGPU_EXEC + R_2d Grid_sxd::gv_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return {gx_sft(ix, gx_0), gy_sft(iy, gy_0)}; + } + + template + CGPU_EXEC + R_2d Grid_sxd::gv_sft(const ST& ix, const ST& iy, const R_2d& g_0) const + { + return gv_sft(ix, iy, g_0.x, g_0.y); + } + + template + CGPU_EXEC + T Grid_sxd::gx2_sft(const ST& ix, const T& gx_0) const + { + return ::square(gx_sft(ix, gx_0)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2_sft(const ST& iy, const T& gy_0) const + { + return ::square(gy_sft(iy, gy_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return gx2_sft(ix, gx_0) + gy2_sft(iy, gy_0); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix, const ST& iy, const R_2d& g0) const + { + return g2_sft(ix, iy, g0.z, g0.y); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const + { + return ::sqrt(g2_sft(ix, iy, gx_0, gy_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix, const ST& iy, const R_2d& g0) const + { + return ::sqrt(g2_sft(ix, iy, g0)); + } + + /***************************************************************************************/ + /******************************* real space positions **********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx(const ST& ix) const + { + return T(this->irx(ix))*drx + rx_0; + } + + template + CGPU_EXEC + T Grid_sxd::ry(const ST& iy) const + { + return T(this->iry(iy))*dry + ry_0; + } + + template + CGPU_EXEC + R_2d Grid_sxd::rv(const ST& ix, const ST& iy) const + { + return {rx(ix), ry(iy)}; + } + + template + CGPU_EXEC + T Grid_sxd::rx2(const ST& ix) const + { + return ::square(rx(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2(const ST& iy) const + { + return ::square(ry(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix, const ST& iy) const + { + return rx2(ix) + ry2(iy); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix, const ST& iy) const + { + return ::sqrt(r2(ix, iy)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx(const ST& ix, const T& x0) const + { + return rx(ix) - x0; + } + + template + CGPU_EXEC + T Grid_sxd::ry(const ST& iy, const T& y0) const + { + return ry(iy) - y0; + } + + template + CGPU_EXEC + R_2d Grid_sxd::rv(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return {rx(ix, x0), ry(iy, y0)}; + } + + template + CGPU_EXEC + R_2d Grid_sxd::rv(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return rv(ix, iy, r_0.x, r_0.y); + } + + template + CGPU_EXEC + T Grid_sxd::rx2(const ST& ix, const T& x0) const + { + return ::square(rx(ix, x0)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2(const ST& iy, const T& y0) const + { + return ::square(ry(iy, y0)); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return rx2(ix, x0) + ry2(iy, y0); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return r2(ix, iy, r_0.x, r_0.y); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return ::sqrt(r2(ix, iy, x0, y0)); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return ::sqrt(r2(ix, iy, r_0)); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_sft(const ST& ix) const + { + return T(this->irx_sft(ix))*drx + rx_0; + } + + template + CGPU_EXEC + T Grid_sxd::ry_sft(const ST& iy) const + { + return T(this->iry_sft(iy))*dry + ry_0; + } + + template + CGPU_EXEC + R_2d Grid_sxd::rv_sft(const ST& ix, const ST& iy) const + { + return {rx_sft(ix), ry_sft(iy)}; + } + + template + CGPU_EXEC + T Grid_sxd::rx2_sft(const ST& ix) const + { + return ::square(rx_sft(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2_sft(const ST& iy) const + { + return ::square(ry_sft(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix, const ST& iy) const + { + return rx2_sft(ix) + ry2_sft(iy); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix, const ST& iy) const + { + return ::sqrt(r2_sft(ix, iy)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_sft(const ST& ix, const T& x0) const + { + return rx_sft(ix) - x0; + } + + template + CGPU_EXEC + T Grid_sxd::ry_sft(const ST& iy, const T& y0) const + { + return ry_sft(iy) - y0; + } + + template + CGPU_EXEC + R_2d Grid_sxd::rv_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return {rx_sft(ix, x0), ry_sft(iy, y0)}; + } + + template + CGPU_EXEC + R_2d Grid_sxd::rv_sft(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return rv_sft(ix, iy, r_0.x, r_0.y); + } + + template + CGPU_EXEC + T Grid_sxd::rx2_sft(const ST& ix, const T& x0) const + { + return ::square(rx_sft(ix, x0)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2_sft(const ST& iy, const T& y0) const + { + return ::square(ry_sft(iy, y0)); + } + + template + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return rx2_sft(ix, x0) + ry2_sft(iy, y0); + } + + template + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return r2_sft(ix, iy, r_0.x, r_0.y); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const + { + return ::sqrt(r2_sft(ix, iy, x0, y0)); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix, const ST& iy, const R_2d& r_0) const + { + return ::sqrt(r2_sft(ix, iy, r_0)); + } + + /***************************************************************************************/ + /***************************** from position to index **********************************/ + /***************************************************************************************/ + template + template + void Grid_sxd::ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_n); + } + + template + template + void Grid_sxd::iy_0_iy_n(const T& y, const T& y_max, SU& iy_0, SU& iy_n) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_n); + } + + template + template + void Grid_sxd::ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_e); + ix_e += ix_0; + } + + template + template + void Grid_sxd::iy_0_iy_e(const T& y, const T& y_max, SU& iy_0, SU& iy_e) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_e); + iy_e += iy_0; + } + + /************ fds = floor/division by pixel size ************/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_fd(const T& x) const + { + return fcn_cfloor(x/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_fd(const T& y) const + { + return fcn_cfloor(y/dry); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_fd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_fd(x), ry_2_iry_fd(y)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_fd_dr_min(const T& x) const + { + return fcn_cfloor(x/dr_min()); + } + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bfd(const T& x) const + { + return fcn_set_bound(rx_2_irx_fd(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bfd(const T& y) const + { + return fcn_set_bound(ry_2_iry_fd(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bfd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bfd(x), ry_2_iry_bfd(y)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_cd(const T& x) const + { + return fcn_cceil(x/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_cd(const T& y) const + { + return fcn_cceil(y/dry); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_cd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_cd(x), ry_2_iry_cd(y)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_cd_dr_min(const T& x) const + { + return static_cast(::ceil(x/dr_min())); + } + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bcd(const T& x) const + { + return fcn_set_bound(rx_2_irx_cd(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bcd(const T& y) const + { + return fcn_set_bound(ry_2_iry_cd(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bcd(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bcd(x), ry_2_iry_bcd(y)); + } + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_fds(const T& x) const + { + return fcn_cfloor((x - rx_0)/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_fds(const T& y) const + { + return fcn_cfloor((y - ry_0)/dry); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_fds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_fds(x), ry_2_iry_fds(y)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_fds_dr_min(const T& x) const + { + return fcn_cfloor((x - r_0_min())/dr_min()); + } + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bfds(const T& x) const + { + return fcn_set_bound(rx_2_irx_fds(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bfds(const T& y) const + { + return fcn_set_bound(ry_2_iry_fds(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bfds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bfds(x), ry_2_iry_bfds(y)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_cds(const T& x) const + { + return fcn_cceil((x - rx_0)/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_cds(const T& y) const + { + return fcn_cceil((y - ry_0)/dry); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_cds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_cds(x), ry_2_iry_cds(y)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_cds_dr_min(const T& x) const + { + return fcn_cceil((x - r_0_min())/dr_min()); + } + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bcds(const T& x) const + { + return fcn_set_bound(rx_2_irx_cds(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bcds(const T& y) const + { + return fcn_set_bound(ry_2_iry_cds(y), ST(0), this->ny-1); + } + + // locate x, y -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bcds(const T& x, const T& y) const + { + return this->sub_2_ind(rx_2_irx_bcds(x), ry_2_iry_bcds(y)); + } + + /************ From position to index by searching ***********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_b(const T& x, ST ix_min, ST ix_max) const + { + if (ix_min == ix_max) + { + ix_min = ST(0); + ix_max = this->nx-1; + } + + return fcn_r_2_ir_b_by_fcn(rx, ix_min, ix_max); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_b(const T& y, ST iy_min, ST iy_max) const + { + if (iy_min == iy_max) + { + iy_min = ST(0); + iy_max = this->ny-1; + } + + return fcn_r_2_ir_b_by_fcn(ry, iy_min, iy_max); + } + + /***************************************************************************************/ + /********************************** check bounds ***************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_front(), rx_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_y(const T& y) const + { + return fcn_chk_bound(y, ry_front(), ry_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound(const R_2d& r) const + { + return chk_bound_x(r.x) && chk_bound_y(r.y); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_front(), rx_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_y_eps(const T& y) const + { + return fcn_chk_bound_eps(y, ry_front(), ry_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_eps(const R_2d& r) const + { + return chk_bound_x_eps(r.x) && chk_bound_y_eps(r.y); + } + + /***************************************************************************************/ + /*********************************** set bounds ****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::set_bound_x(const T& x) const + { + return fcn_set_bound(x, rx_front(), rx_back()); + } + + template + CGPU_EXEC + T Grid_sxd::set_bound_y(const T& y) const + { + return fcn_set_bound(y, ry_front(), ry_back()); + } + + template + CGPU_EXEC + R_2d Grid_sxd::set_bound(const R_2d& r) const + { + return {set_bound_x(r.x), set_bound_y(r.y)}; + } + + /***************************************************************************************/ + /************************************ front/back ***************************************/ + /***************************************************************************************/ + + template CGPU_EXEC + T Grid_sxd::gx_front() const + { + return gx(ST(0)); + } + + template CGPU_EXEC + T Grid_sxd::gx_back() const + { + return gx(this->nx-1); + } + + template CGPU_EXEC + T Grid_sxd::gy_front() const + { + return gy(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::gy_back() const + { + return gy(this->ny-1); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_front() const + { + return rx(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::rx_back() const + { + return rx(this->nx-1); + } + + template + CGPU_EXEC + T Grid_sxd::ry_front() const + { + return ry(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::ry_back() const + { + return ry(this->ny-1); + } + + /***************************************************************************************/ + /*********************************** factors *******************************************/ + /* calculate fermi low-pass filter alpha parameter */ + template + CGPU_EXEC + T Grid_sxd::fermi_lpf_alpha() const + { + return fcn_fermi_lpf_alpha(gl_max(), T(0.25), T(1e-02)); + } + + template + CGPU_EXEC + T Grid_sxd::factor_2pi_rx_ctr(const T& x) const + { + return fcn_n_2pi_sft(x, bs_x_h()); + } + + + template CGPU_EXEC + T Grid_sxd::factor_2pi_ry_ctr(const T& y) const + { + return fcn_n_2pi_sft(y, bs_y_h()); + } + + + template CGPU_EXEC + R_2d Grid_sxd::factor_2pi_rv_ctr(const R_2d& r) const + { + return {factor_2pi_rx_ctr(r.x), factor_2pi_ry_ctr(r.y)}; + } + + + template CPU_EXEC + Vctr, edev_cpu> Grid_sxd::factor_2pi_rv_ctr(const Vctr, edev_cpu>& rv) const + { + Vctr, edev_cpu> rv_o(rv.size()); + + for(auto ik = 0; ik + iRegion_Rect_xd Grid_sxd::iregion_rect(const R_2d& r, const T& radius) const + { + return {rx_2_irx_bfds(r.x - radius), rx_2_irx_bcds(r.x + radius), ry_2_iry_bfds(r.y - radius), ry_2_iry_bcds(r.y + radius)}; + } + + template + iRegion_Rect_xd Grid_sxd::iregion_rect(const R_2d& r, const T& f0, const T& a, const T& b, const T& c) + { + const T d = log(f0); + const T dd = c*c-T(4)*a*b; + + const T radius_x = ::sqrt(T(4)*b*d/dd); + const T radius_y = ::sqrt(T(4)*a*d/dd); + + return {rx_2_irx_bfds(r.x - radius_x), rx_2_irx_bcds(r.x + radius_x), ry_2_iry_bfds(r.y - radius_y), ry_2_iry_bcds(r.y + radius_y)}; + } +} + +/* traits */ +namespace mt +{ + template + struct is_grid_2d: std::integral_constant>::value> {}; + + /***************************************************************************************/ + template + struct is_grid_2d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_2d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_grid_2d_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_2d_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_grid_2d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_2d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_grid_2d_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_2d_and_cvctr_gpu = typename std::enable_if::value, V>::type; +} \ No newline at end of file diff --git a/src/detail/grid_3d.inl b/src/detail/grid_3d.inl new file mode 100755 index 00000000..7b1bcf16 --- /dev/null +++ b/src/detail/grid_3d.inl @@ -0,0 +1,1694 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "grid_3d.h" + +/* template specialization 3d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Grid_sxd::Grid_sxd(): iGrid_sxd(), bs_x(0), bs_y(0), bs_z(0), + rx_0(0), ry_0(0), rz_0(0), pbc_x(true), pbc_y(true), pbc_z(true), bwl(false), sli_thick(0), + drx(0), dry(0), drz(0), dgx(0), dgy(0), dgz(0){} + + template + Grid_sxd::Grid_sxd(const ST& nx, const ST& ny, const ST& nz) + { + set_in_data(nx, ny, nz); + } + + template + template + Grid_sxd::Grid_sxd(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const ST& nz) + { + set_in_data(bs_x, bs_y, bs_z, nx, ny, nz); + } + + template + template + Grid_sxd::Grid_sxd(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz, + const U& rx_0, const U& ry_0, const U& rz_0, dt_bool pbc_x, dt_bool pbc_y, dt_bool pbc_z, dt_bool bwl, U sli_thick) + { + set_in_data(bs_x, bs_y, bs_z, nx, ny, nz, rx_0, ry_0, rz_0, pbc_x, pbc_y, pbc_z, bwl, sli_thick); + } + + /* copy constructor */ + template + CGPU_EXEC + Grid_sxd::Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Grid_sxd::Grid_sxd(const Grid_sxd& grid) + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Grid_sxd& Grid_sxd::operator=(const Grid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + bs_x = grid.bs_x; + bs_y = grid.bs_y; + bs_z = grid.bs_z; + rx_0 = grid.rx_0; + ry_0 = grid.ry_0; + rz_0 = grid.rz_0; + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + pbc_z = grid.pbc_z; + bwl = grid.bwl; + sli_thick = grid.sli_thick; + + drx = grid.drx; + dry = grid.dry; + drz = grid.drz; + dgx = grid.dgx; + dgy = grid.dgy; + dgz = grid.dgz; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Grid_sxd& Grid_sxd::operator=(const Grid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + bs_x = T(grid.bs_x); + bs_y = T(grid.bs_y); + bs_z = T(grid.bs_z); + rx_0 = T(grid.rx_0); + ry_0 = T(grid.ry_0); + rz_0 = T(grid.rz_0); + pbc_x = grid.pbc_x; + pbc_y = grid.pbc_y; + pbc_z = grid.pbc_z; + bwl = grid.bwl; + sli_thick = T(grid.sli_thick); + + drx = T(grid.drx); + dry = T(grid.dry); + drz = T(grid.drz); + dgx = T(grid.dgx); + dgy = T(grid.dgy); + dgz = T(grid.dgz); + + return *this; + } + + template + template + CGPU_EXEC + void Grid_sxd::assign(const Grid_sxd& grid) + { + *this = grid; + } + + /**************** user define conversion operators *******************/ + template + Grid_sxd::operator iRegion_Rect_xd() const + { + return {ST(0), this->nx, ST(0), this->ny, ST(0), this->nz}; + } + + /***************************************************************************************/ + template + void Grid_sxd::set_in_data(const ST& nx, const ST& ny, const ST& nz) + { + set_in_data(T(nx), T(ny), T(nz), nx, ny, nz, T(0), T(0), T(0)); + } + + template + template + void Grid_sxd::set_in_data(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz) + { + set_in_data(T(bs_x), T(bs_y), T(bs_z), ST(nx), ST(ny), ST(nz), T(0), T(0), T(0)); + } + + template + template + void Grid_sxd::set_in_data(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz, + const U& rx_0, const U& ry_0, const U& rz_0, dt_bool pbc_x, dt_bool pbc_y, dt_bool pbc_z, dt_bool bwl, U sli_thick) + { + this->set_size(nx, ny, nz); + + this->bs_x = T(bs_x); + this->bs_y = T(bs_y); + this->bs_z = T(bs_z); + this->rx_0 = T(rx_0); + this->ry_0 = T(ry_0); + this->rz_0 = T(rz_0); + this->pbc_x = pbc_x; + this->pbc_y = pbc_y; + this->pbc_z = pbc_z; + this->bwl = bwl; + this->sli_thick = T(sli_thick); + + set_dep_var(); + } + + template + void Grid_sxd::set_dep_var() + { + drx = mt::fcn_div(bs_x, this->nx); + dry = mt::fcn_div(bs_y, this->ny); + drz = mt::fcn_div(bs_z, this->nz); + dgx = mt::fcn_div(T(1), bs_x); + dgy = mt::fcn_div(T(1), bs_y); + dgz = mt::fcn_div(T(1), bs_z); + } + + template + CGPU_EXEC + void Grid_sxd::set_r_0(const T& rx_0, const T& ry_0, const T& rz_0) + { + this->rx_0 = rx_0; + this->ry_0 = ry_0; + this->rz_0 = rz_0; + } + + template + CGPU_EXEC + void Grid_sxd::set_r_0(const R_3d& r_0) + { + set_r_0(r_0.x, r_0.y, r_0.z); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::nx_r() const + { + return T(this->nx); + } + + template + CGPU_EXEC + T Grid_sxd::ny_r() const + { + return T(this->ny); + } + + template + CGPU_EXEC + T Grid_sxd::nz_r() const + { + return T(this->nz); + } + + template + CGPU_EXEC + T Grid_sxd::size_r() const + { + return T(this->size()); + } + + template + T Grid_sxd::isize_r() const + { + return T(1)/size_r(); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::bs_x_h() const + { + return T(0.5)*bs_x; + } + + template + CGPU_EXEC + T Grid_sxd::bs_y_h() const + { + return T(0.5)*bs_y; + } + + template + CGPU_EXEC + T Grid_sxd::bs_z_h() const + { + return T(0.5)*bs_z; + } + + template + CGPU_EXEC + R_3d Grid_sxd::bs_h() const + { + return {bs_x_h(), bs_y_h(), bs_z_h()}; + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::bs_min() const + { + return ::fmin(bs_x, ::fmin(bs_y, bs_z)); + } + + template + CGPU_EXEC + T Grid_sxd::bs_max() const + { + return ::fmax(bs_x, ::fmax(bs_y, bs_z)); + } + + template + CGPU_EXEC + T Grid_sxd::bs_h_min() const + { + return T(0.5)*bs_min(); + } + + template + CGPU_EXEC + T Grid_sxd::bs_h_max() const + { + return T(0.5)*bs_max(); + } + + template + CGPU_EXEC + T Grid_sxd::rx_c() const + { + return rx_0 + bs_x_h(); + } + + template + CGPU_EXEC + T Grid_sxd::ry_c() const + { + return ry_0 + bs_y_h(); + } + + template + CGPU_EXEC + T Grid_sxd::rz_c() const + { + return rz_0 + bs_z_h(); + } + + template + CGPU_EXEC + R_3d Grid_sxd::rv_c() const + { + return {rx_c(), ry_c(), rz_c()}; + } + + /***************************************************************************************/ + // maximum frequency + template + CGPU_EXEC + T Grid_sxd::g_max() const + { + return ::fmin(gx_back(), ::fmin(gy_back(), gz_back())); + } + + // maximum square frequency + template + CGPU_EXEC + T Grid_sxd::g2_max() const + { + return ::square(g_max()); + } + + // maximum allowed frequency + template + CGPU_EXEC + T Grid_sxd::gl_max() const + { + return g_max()*T(2.0/3.0); + } + + // maximum square allowed frequency + template + CGPU_EXEC + T Grid_sxd::gl2_max() const + { + return ::square(gl_max()); + } + + template + CGPU_EXEC + T Grid_sxd::r_0_min() const + { + return ::fmin(rx_0, ::fmin(ry_0, rz_0)); + } + + template + CGPU_EXEC + T Grid_sxd::dr_min() const + { + return ::fmin(drx, ::fmin(dry, drz)); + } + + template + CGPU_EXEC + T Grid_sxd::dg_min() const + { + return ::fmin(dgx, ::fmin(dgy, dgz)); + } + + /***************************************************************************************/ + /********************************* Fourier space positions *****************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx(const ST& ix) const + { + return T(this->igx(ix))*dgx; + } + + template + CGPU_EXEC + T Grid_sxd::gy(const ST& iy) const + { + return T(this->igy(iy))*dgy; + } + + template + CGPU_EXEC + T Grid_sxd::gz(const ST& iz) const + { + return T(this->igz(iz))*dgz; + } + + template + CGPU_EXEC + R_3d Grid_sxd::gv(const ST& ix, const ST& iy, const ST& iz) const + { + return {gx(ix), gy(iy), gz(iz)}; + } + + template + CGPU_EXEC + T Grid_sxd::gx2(const ST& ix) const + { + return ::square(gx(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2(const ST& iy) const + { + return ::square(gy(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::gz2(const ST& iz) const + { + return ::square(gz(iz)); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix, const ST& iy, const ST& iz) const + { + return gx2(ix) + gy2(iy) + gz2(iz); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(g2(ix, iy, iz)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx(const ST& ix, const T& gx_0) const + { + return gx(ix) - gx_0; + } + + template + CGPU_EXEC + T Grid_sxd::gy(const ST& iy, const T& gy_0) const + { + return gy(iy) - gy_0; + } + + template + CGPU_EXEC + T Grid_sxd::gz(const ST& iz, const T& gz_0) const + { + return gz(iz) - gz_0; + } + + template + CGPU_EXEC + R_3d Grid_sxd::gv(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return {gx(ix, gx_0), gy(iy, gy_0), gz(iz, gz_0)}; + } + + template + CGPU_EXEC + R_3d Grid_sxd::gv(const ST& ix, const ST& iy, const ST& iz, const R_3d& g_0) const + { + return gv(ix, iy, iz, g_0.x, g_0.y, g_0.z); + } + + template + CGPU_EXEC + T Grid_sxd::gx2(const ST& ix, const T& gx_0) const + { + return ::square(gx(ix, gx_0)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2(const ST& iy, const T& gy_0) const + { + return ::square(gy(iy, gy_0)); + } + + template + CGPU_EXEC + T Grid_sxd::gz2(const ST& iz, const T& gz_0) const + { + return ::square(gz(iz, gz_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return gx2(ix, gx_0) + gy2(iy, gy_0) + gz2(iz, gz_0); + } + + template + CGPU_EXEC + T Grid_sxd::g2(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return g2(ix, iy, iz, g0.x, g0.y, g0.z); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return ::sqrt(g2(ix, iy, iz, gx_0, gy_0, gz_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return ::sqrt(g2(ix, iy, iz, g0)); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_sft(const ST& ix) const + { + return T(this->igx_sft(ix))*dgx; + } + + template + CGPU_EXEC + T Grid_sxd::gy_sft(const ST& iy) const + { + return T(this->igy_sft(iy))*dgy; + } + + template + CGPU_EXEC + T Grid_sxd::gz_sft(const ST& iz) const + { + return T(this->igz_sft(iz))*dgz; + } + + template + CGPU_EXEC + R_3d Grid_sxd::gv_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return {gx_sft(ix), gy_sft(iy), gz_sft(iz)}; + } + + template + CGPU_EXEC + T Grid_sxd::gx2_sft(const ST& ix) const + { + return ::square(gx_sft(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2_sft(const ST& iy) const + { + return ::square(gy_sft(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::gz2_sft(const ST& iz) const + { + return ::square(gz_sft(iz)); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return gx2_sft(ix) + gy2_sft(iy) + gz2_sft(iz); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(g2_sft(ix, iy, iz)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_sft(const ST& ix, const T& gx_0) const + { + return gx_sft(ix) - gx_0; + } + + template + CGPU_EXEC + T Grid_sxd::gy_sft(const ST& iy, const T& gy_0) const + { + return gy_sft(iy) - gy_0; + } + + template + CGPU_EXEC + T Grid_sxd::gz_sft(const ST& iz, const T& gz_0) const + { + return gz_sft(iz) - gz_0; + } + + template + CGPU_EXEC + R_3d Grid_sxd::gv_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return {gx_sft(ix, gx_0), gy_sft(iy, gy_0), gz_sft(iz, gz_0)}; + } + + template + CGPU_EXEC + R_3d Grid_sxd::gv_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g_0) const + { + return gv_sft(ix, iy, iz, g_0.x, g_0.y, g_0.z); + } + + template + CGPU_EXEC + T Grid_sxd::gx2_sft(const ST& ix, const T& gx_0) const + { + return ::square(gx_sft(ix, gx_0)); + } + + template + CGPU_EXEC + T Grid_sxd::gy2_sft(const ST& iy, const T& gy_0) const + { + return ::square(gy_sft(iy, gy_0)); + } + + template + CGPU_EXEC + T Grid_sxd::gz2_sft(const ST& iz, const T& gz_0) const + { + return ::square(gz_sft(iz, gz_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return gx2_sft(ix, gx_0) + gy2_sft(iy, gy_0) + gz2_sft(iz, gz_0); + } + + template + CGPU_EXEC + T Grid_sxd::g2_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return g2_sft(ix, iy, iz, g0.x, g0.y, g0.z); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const + { + return ::sqrt(g2_sft(ix, iy, iz, gx_0, gy_0, gz_0)); + } + + template + CGPU_EXEC + T Grid_sxd::g_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const + { + return ::sqrt(g2_sft(ix, iy, iz, g0)); + } + + /***************************************************************************************/ + /********************************* real space positions ********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx(const ST& ix) const + { + return T(this->irx(ix))*drx + rx_0; + } + + template + CGPU_EXEC + T Grid_sxd::ry(const ST& iy) const + { + return T(this->iry(iy))*dry + ry_0; + } + + template + CGPU_EXEC + T Grid_sxd::rz(const ST& iz) const + { + return T(this->irz(iz))*drz + rz_0; + } + + template + CGPU_EXEC + R_3d Grid_sxd::rv(const ST& ix, const ST& iy, const ST& iz) const + { + return {rx(ix), ry(iy), rz(iz)}; + } + + template + CGPU_EXEC + T Grid_sxd::rx2(const ST& ix) const + { + return ::square(rx(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2(const ST& iy) const + { + return ::square(ry(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::rz2(const ST& iz) const + { + return ::square(rz(iz)); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix, const ST& iy, const ST& iz) const + { + return rx2(ix) + ry2(iy) + rz2(iz); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(r2(ix, iy, iz)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx(const ST& ix, const T& x0) const + { + return rx(ix) - x0; + } + + template + CGPU_EXEC + T Grid_sxd::ry(const ST& iy, const T& y0) const + { + return ry(iy) - y0; + } + + template + CGPU_EXEC + T Grid_sxd::rz(const ST& iz, const T& z0) const + { + return rz(iz) - z0; + } + + template + CGPU_EXEC + R_3d Grid_sxd::rv(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return {rx(ix, x0), ry(iy, y0), rz(iz, z0)}; + } + + template + CGPU_EXEC + R_3d Grid_sxd::rv(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return rv(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + template + CGPU_EXEC + T Grid_sxd::rx2(const ST& ix, const T& x0) const + { + return ::square(rx(ix, x0)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2(const ST& iy, const T& y0) const + { + return ::square(ry(iy, y0)); + } + + template + CGPU_EXEC + T Grid_sxd::rz2(const ST& iz, const T& z0) const + { + return ::square(rz(iz, z0)); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return rx2(ix, x0) + ry2(iy, y0) + rz2(iz, z0); + } + + template + CGPU_EXEC + T Grid_sxd::r2(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return r2(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return ::sqrt(r2(ix, iy, iz, x0, y0, z0)); + } + + template + CGPU_EXEC + T Grid_sxd::r(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return ::sqrt(r2(ix, iy, iz, r_0)); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_sft(const ST& ix) const + { + return T(this->irx_sft(ix))*drx + rx_0; + } + + template + CGPU_EXEC + T Grid_sxd::ry_sft(const ST& iy) const + { + return T(this->iry_sft(iy))*dry + ry_0; + } + + template + CGPU_EXEC + T Grid_sxd::rz_sft(const ST& iz) const + { + return T(this->irz_sft(iz))*drz + rz_0; + } + + template + CGPU_EXEC + R_3d Grid_sxd::rv_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return {rx_sft(ix), ry_sft(iy), rz_sft(iz)}; + } + + template + CGPU_EXEC + T Grid_sxd::rx2_sft(const ST& ix) const + { + return ::square(rx_sft(ix)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2_sft(const ST& iy) const + { + return ::square(ry_sft(iy)); + } + + template + CGPU_EXEC + T Grid_sxd::rz2_sft(const ST& iz) const + { + return ::square(rz_sft(iz)); + } + + template + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return rx2_sft(ix) + ry2_sft(iy) + rz2_sft(iz); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix, const ST& iy, const ST& iz) const + { + return ::sqrt(r2_sft(ix, iy, iz)); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_sft(const ST& ix, const T& x0) const + { + return rx_sft(ix) - x0; + } + + template + CGPU_EXEC + T Grid_sxd::ry_sft(const ST& iy, const T& y0) const + { + return ry_sft(iy) - y0; + } + + template + CGPU_EXEC + T Grid_sxd::rz_sft(const ST& iz, const T& z0) const + { + return rz_sft(iz) - z0; + } + + template + CGPU_EXEC + R_3d Grid_sxd::rv_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return {rx_sft(ix, x0), ry_sft(iy, y0), rz_sft(iz, z0)}; + } + + template + CGPU_EXEC + R_3d Grid_sxd::rv_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return rv_sft(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + template + CGPU_EXEC + T Grid_sxd::rx2_sft(const ST& ix, const T& x0) const + { + return ::square(rx_sft(ix, x0)); + } + + template + CGPU_EXEC + T Grid_sxd::ry2_sft(const ST& iy, const T& y0) const + { + return ::square(ry_sft(iy, y0)); + } + + template + CGPU_EXEC + T Grid_sxd::rz2_sft(const ST& iz, const T& z0) const + { + return ::square(rz_sft(iz, z0)); + } + template + + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return rx2_sft(ix, x0) + ry2_sft(iy, y0) + rz2_sft(iz, z0); + } + + template + CGPU_EXEC + T Grid_sxd::r2_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return r2_sft(ix, iy, iz, r_0.x, r_0.y, r_0.z); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const + { + return ::sqrt(r2_sft(ix, iy, iz, x0, y0, z0)); + } + + template + CGPU_EXEC + T Grid_sxd::r_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const + { + return ::sqrt(r2_sft(ix, iy, iz, r_0)); + } + + /***************************************************************************************/ + /****************************** from position to index *********************************/ + /***************************************************************************************/ + template + template + void Grid_sxd::ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_n); + } + + template + template + void Grid_sxd::iy_0_iy_n(const T& y, const T& y_max, SU& iy_0, SU& iy_n) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_n); + } + + template + template + void Grid_sxd::iz_0_iz_n(const T& z, const T& z_max, SU& iz_0, SU& iz_n) const + { + fcn_get_idx_0_idx_n(z, z_max, drz, pbc_z, this->nz-1, iz_0, iz_n); + } + + template + template + void Grid_sxd::ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const + { + fcn_get_idx_0_idx_n(x, x_max, drx, pbc_x, this->nx-1, ix_0, ix_e); + ix_e += ix_0; + } + + template + template + void Grid_sxd::iy_0_iy_e(const T& y, const T& y_max, SU& iy_0, SU& iy_e) const + { + fcn_get_idx_0_idx_n(y, y_max, dry, pbc_y, this->ny-1, iy_0, iy_e); + iy_e += iy_0; + } + + template + template + void Grid_sxd::iz_0_iz_e(const T& z, const T& z_max, SU& iz_0, SU& iz_e) const + { + fcn_get_idx_0_idx_n(z, z_max, drz, pbc_z, this->nz-1, iz_0, iz_e); + iz_e += iz_0; + } + + /*************** fds = floor/division by pixel size ******************/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_fd(const T& x) const + { + return fcn_cfloor(x/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_fd(const T& y) const + { + return fcn_cfloor(y/dry); + } + + // locate z -> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_fd(const T& z) const + { + return fcn_cfloor(z/drz); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_fd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_fd(x), ry_2_iry_fd(y), rz_2_irz_fd(z)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_fd_dr_min(const T& x) const + { + return fcn_cfloor(x/dr_min()); + } + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bfd(const T& x) const + { + return fcn_set_bound(rx_2_irx_fd(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bfd(const T& y) const + { + return fcn_set_bound(ry_2_iry_fd(y), ST(0), this->ny-1); + } + + // locate z-> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_bfd(const T& z) const + { + return fcn_set_bound(rz_2_irz_fd(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bfd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bfd(x), ry_2_iry_bfd(y), rz_2_irz_bfd(z)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_cd(const T& x) const + { + return fcn_cceil(x/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_cd(const T& y) const + { + return fcn_cceil(y/dry); + } + + // locate z -> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_cd(const T& z) const + { + return fcn_cceil(z/drz); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_cd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_cd(x), ry_2_iry_cd(y), rz_2_irz_cd(z)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_cd_dr_min(const T& x) const + { + return static_cast(::ceil(x/dr_min())); + } + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bcd(const T& x) const + { + return fcn_set_bound(rx_2_irx_cd(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bcd(const T& y) const + { + return fcn_set_bound(ry_2_iry_cd(y), ST(0), this->ny-1); + } + + // locate z -> iry + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_bcd(const T& z) const + { + return fcn_set_bound(rz_2_irz_cd(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bcd(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bcd(x), ry_2_iry_bcd(y), rz_2_irz_bcd(z)); + } + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_fds(const T& x) const + { + return fcn_cfloor((x - rx_0)/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_fds(const T& y) const + { + return fcn_cfloor((y - ry_0)/dry); + } + + // locate z -> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_fds(const T& z) const + { + return fcn_cfloor((z - rz_0)/drz); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_fds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_fds(x), ry_2_iry_fds(y), rz_2_irz_fds(z)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_fds_dr_min(const T& x) const + { + return fcn_cfloor((x - r_0_min())/dr_min()); + } + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bfds(const T& x) const + { + return fcn_set_bound(rx_2_irx_fds(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bfds(const T& y) const + { + return fcn_set_bound(ry_2_iry_fds(y), ST(0), this->ny-1); + } + + // locate z -> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_bfds(const T& z) const + { + return fcn_set_bound(rz_2_irz_fds(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bfds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bfds(x), ry_2_iry_bfds(y), rz_2_irz_bfds(z)); + } + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_cds(const T& x) const + { + return fcn_cceil((x - rx_0)/drx); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_cds(const T& y) const + { + return fcn_cceil((y - ry_0)/dry); + } + + // locate z -> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_cds(const T& z) const + { + return fcn_cceil((z - rz_0)/drz); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_cds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_cds(x), ry_2_iry_cds(y), rz_2_irz_cds(z)); + } + + // locate r -> ir using dr_min + template + CGPU_EXEC + ST Grid_sxd::r_2_ir_cds_dr_min(const T& x) const + { + return fcn_cceil((x - r_0_min())/dr_min()); + } + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_bcds(const T& x) const + { + return fcn_set_bound(rx_2_irx_cds(x), ST(0), this->nx-1); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_bcds(const T& y) const + { + return fcn_set_bound(ry_2_iry_cds(y), ST(0), this->ny-1); + } + + // locate z -> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_bcds(const T& z) const + { + return fcn_set_bound(rz_2_irz_cds(z), ST(0), this->nz-1); + } + + // locate x, y, z -> ind + template + CGPU_EXEC + ST Grid_sxd::rv_2_ir_bcds(const T& x, const T& y, const T& z) const + { + return this->sub_2_ind(rx_2_irx_bcds(x), ry_2_iry_bcds(y), rz_2_irz_bcds(z)); + } + + /************ From position to index by searching ***********/ + // locate x -> irx + template + CGPU_EXEC + ST Grid_sxd::rx_2_irx_b(const T& x, ST ix_min, ST ix_max) const + { + if (ix_min == ix_max) + { + ix_min = ST(0); + ix_max = this->nx-1; + } + + return fcn_r_2_ir_b_by_fcn(rx, ix_min, ix_max); + } + + // locate y -> iry + template + CGPU_EXEC + ST Grid_sxd::ry_2_iry_b(const T& y, ST iy_min, ST iy_max) const + { + if (iy_min == iy_max) + { + iy_min = ST(0); + iy_max = this->ny-1; + } + + return fcn_r_2_ir_b_by_fcn(ry, iy_min, iy_max); + } + + // locate z-> irz + template + CGPU_EXEC + ST Grid_sxd::rz_2_irz_b(const T& z, ST iz_min, ST iz_max) const + { + if (iz_min == iz_max) + { + iz_min = ST(0); + iz_max = this->nz-1; + } + + return fcn_r_2_ir_b_by_fcn(rz, iz_min, iz_max); + } + + /***************************************************************************************/ + /********************************* check bounds ****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_front(), rx_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_y(const T& y) const + { + return fcn_chk_bound(y, ry_front(), ry_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_z(const T& z) const + { + return fcn_chk_bound(z, rz_front(), rz_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound(const R_3d& r) const + { + return chk_bound_x(r.x) && chk_bound_y(r.y) && chk_bound_z(r.z); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_front(), rx_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_y_eps(const T& y) const + { + return fcn_chk_bound_eps(y, ry_front(), ry_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_z_eps(const T& z) const + { + return fcn_chk_bound_eps(z, rz_front(), rz_back()); + } + + template + CGPU_EXEC + dt_bool Grid_sxd::chk_bound_eps(const R_3d& r) const + { + return chk_bound_x_eps(r.x) && chk_bound_y_eps(r.y) && chk_bound_z_eps(r.z); + } + + /***************************************************************************************/ + /*********************************** set bounds ****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::set_bound_x(const T& x) const + { + return fcn_set_bound(x, rx_front(), rx_back()); + } + + template + CGPU_EXEC + T Grid_sxd::set_bound_y(const T& y) const + { + return fcn_set_bound(y, ry_front(), ry_back()); + } + + template + CGPU_EXEC + T Grid_sxd::set_bound_z(const T& z) const + { + return fcn_set_bound(z, rz_front(), rz_back()); + } + + template + CGPU_EXEC + R_3d Grid_sxd::set_bound(const R_3d& r) const + { + return {set_bound_x(r.x), set_bound_y(r.y), set_bound_z(r.z)}; + } + + /***************************************************************************************/ + /*********************************** front/back ****************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::gx_front() const + { + return gx(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::gx_back() const + { + return gx(this->nx-1); + } + + template + CGPU_EXEC + T Grid_sxd::gy_front() const + { + return gy(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::gy_back() const + { + return gy(this->ny-1); + } + + template + CGPU_EXEC + T Grid_sxd::gz_front() const + { + return gz(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::gz_back() const + { + return gz(this->nz-1); + } + + /***************************************************************************************/ + template + CGPU_EXEC + T Grid_sxd::rx_front() const + { + return rx(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::rx_back() const + { + return rx(this->nx-1); + } + + template + CGPU_EXEC + T Grid_sxd::ry_front() const + { + return ry(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::ry_back() const + { + return ry(this->ny-1); + } + + template + CGPU_EXEC + T Grid_sxd::rz_front() const + { + return rz(ST(0)); + } + + template + CGPU_EXEC + T Grid_sxd::rz_back() const + { + return rz(this->nz-1); + } + + /***************************************************************************************/ + /************************************* factors *****************************************/ + /***************************************************************************************/ + /* calculate fermi low-pass filter alpha parameter */ + template + CGPU_EXEC + T Grid_sxd::fermi_lpf_alpha() const + { + return fcn_fermi_lpf_alpha(gl_max(), T(0.25), T(1e-02)); + } + + template + CGPU_EXEC + T Grid_sxd::factor_2pi_rx_ctr(const T& x) const + { + return fcn_n_2pi_sft(x, bs_x_h()); + } + + template + CGPU_EXEC + T Grid_sxd::factor_2pi_ry_ctr(const T& y) const + { + return fcn_n_2pi_sft(y, bs_y_h()); + } + + template + CGPU_EXEC + T Grid_sxd::factor_2pi_rz_ctr(const T& z) const + { + return fcn_n_2pi_sft(z, bs_z_h()); + } + + template + CGPU_EXEC + R_3d Grid_sxd::factor_2pi_rv_ctr(const R_3d& r) const + { + return {factor_2pi_rx_ctr(r.x), factor_2pi_ry_ctr(r.y), factor_2pi_rz_ctr(r.z)}; + } + + template + CPU_EXEC + Vctr, edev_cpu> Grid_sxd::factor_2pi_rv_ctr(const Vctr, edev_cpu>& rv) const + { + Vctr, edev_cpu> rv_o(rv.size()); + + for(auto ik = 0; ik + iRegion_Rect_xd Grid_sxd::iregion_rect(const R_3d& r, const T& radius) const + { + return {rx_2_irx_bfds(r.x - radius), rx_2_irx_bcds(r.x + radius), ry_2_iry_bfds(r.y - radius), + ry_2_iry_bcds(r.y + radius), rz_2_irz_bfds(r.z - radius), rz_2_irz_bcds(r.z + radius)}; + } + + template + iRegion_Rect_xd Grid_sxd::iregion_rect(const R_3d& r, const T& f0, const T& a, const T& b, const T& c) + { + const T d = log(f0); + const T dd = c*c-T(4)*a*b; + + const T radius_x = ::sqrt(T(4)*b*d/dd); + const T radius_y = ::sqrt(T(4)*a*d/dd); + const T radius_z = ::sqrt(T(4)*a*d/dd); + + return {nrx_2_irx_bfds(r.x - radius_x), rx_2_irx_bcds(r.x + radius_x), ry_2_iry_bfds(r.y - radius_y), + ry_2_iry_bcds(r.y + radius_y), rz_2_irz_bfds(r.z - radius_z), rz_2_irz_bcds(r.z + radius_z)}; + } +} + + +/* traits */ +namespace mt +{ + template + struct is_grid_3d: std::integral_constant>::value> {}; + + /***************************************************************************************/ + template + struct is_grid_3d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_3d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_grid_3d_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_3d_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_grid_3d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_3d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_grid_3d_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_3d_and_cvctr_gpu = typename std::enable_if::value, V>::type; +} + +/* traits general*/ +namespace mt +{ + template + struct is_grid: std::integral_constant::value || is_grid_2d::value || is_grid_3d::value> {}; + + /***************************************************************************************/ + template + struct is_grid_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_grid_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_grid_and_cvctr_cpu: std::integral_constant::value && is_cvctr_cpu::value> {}; + + template + struct is_grid_and_cvctr_gpu: std::integral_constant::value && is_cvctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_grid_nd_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_nd_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_grid_nd_and_cvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_grid_nd_and_cvctr_gpu = typename std::enable_if::value, V>::type; +} \ No newline at end of file diff --git a/src/detail/igrid_1d.inl b/src/detail/igrid_1d.inl new file mode 100755 index 00000000..ba2b0b8a --- /dev/null +++ b/src/detail/igrid_1d.inl @@ -0,0 +1,312 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "igrid_1d.h" + +/* template specialization igrid 1d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(): nx(0), nx_h(0) {} + + template + iGrid_sxd::iGrid_sxd(const ST& nx): nx(nx), nx_h(nx/ST(2)) {} + + /* copy constructor */ + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /* converting constructor */ + template + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + iGrid_sxd& iGrid_sxd::operator=(const iGrid_sxd& grid) + { + if (this != &grid) + { + nx = grid.nx; + nx_h = grid.nx_h; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + iGrid_sxd& iGrid_sxd::operator=(const iGrid_sxd& grid) + { + nx = ST(grid.nx); + nx_h = ST(grid.nx_h); + + return *this; + } + + template + template + CGPU_EXEC + void iGrid_sxd::assign(const iGrid_sxd& grid) + { + *this = grid; + } + + /***************************************************************************************/ + template + void iGrid_sxd::set_size(const ST& nx) + { + this->nx = nx; + this->nx_h = nx/ST(2); + } + + template + CGPU_EXEC + void iGrid_sxd::clear() + { + nx = 0; + nx_h = 0; + } + + template + CGPU_EXEC + ST iGrid_sxd::size() const + { + return nx; + } + + template + template + CGPU_EXEC + SU iGrid_sxd::nx_cast() const + { + return SU(nx); + } + + template + template + CGPU_EXEC + SU iGrid_sxd::size_cast() const + { + return SU(size()); + } + + template + template + CGPU_EXEC + SU iGrid_sxd::isize_cast() const + { + return SU(1)/size_cast(); + } + + template + dt_shape_st iGrid_sxd::shape() const + { + return {nx, ST(1), ST(1), ST(1)}; + } + + /***************************************************************************************/ + /********************** apply boundary conditions to indices ***************************/ + /*********** https:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn *************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::ind_x_pbc(const ST& ix) const + { + return fcn_ind_pbc(ix, nx); + } + + template + CGPU_EXEC + ST iGrid_sxd::ind_x_bd(const ST& ix) const + { + return fcn_set_bound(ix, ST(0), nx-ST(1)); + } + + template + CGPU_EXEC + void iGrid_sxd::ind_pbc(ST& ix) const + { + ix = ind_x_pbc(ix); + } + + /***************************************************************************************/ + /***************************** subindices -> linear indices ****************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::operator()(const ST& ix) const + { + return ix; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind(const ST& ix) const + { + return ix; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_bd(const ST& ix) const + { + return sub_2_ind(ind_x_bd(ix)); + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_pbc(const ST& ix) const + { + return ind_x_pbc(ix); + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_irv_sft_pbc(ST ix) const + { + ind_pbc(ix); + irx_sft(ix); + + return sub_2_ind(ix); + } + + /***************************************************************************************/ + /**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + template + CGPU_EXEC + void iGrid_sxd::ind_2_sub(const ST& ind, ST& ix) const + { + ix = ind; + } + + /***************************************************************************************/ + /****************************** Fourier space indices **********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::igx(const ST& ix) const + { + return ix-nx_h; + } + /**************************************** shift ****************************************/ + template + CGPU_EXEC + ST iGrid_sxd::igx_sft(const ST& ix) const + { + return (ix + CGPU_EXEC + ST iGrid_sxd::irx(const ST& ix) const + { + return ix; + } + + /*************************************** shift *****************************************/ + template + CGPU_EXEC + ST iGrid_sxd::irx_sft(const ST& ix) const + { + return (ix + dim3 iGrid_sxd::d_blk_size() + { + return fcn_cdb_size(); + } + + template + dim3 iGrid_sxd::d_grid_size(const dim3 d_grid_max) + { + auto grid = fcn_cdg_size(this->m_size); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk_size(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid_size(d_grid_max), d_blk_size()); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_blk() + { + return fcn_cdb_1d(); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid(const dim3 d_grid_max) + { + auto grid = fcn_cdg_1d(this->nx); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid(d_grid_max), d_blk()); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid_h(const dim3 d_grid_max) + { + auto grid = fcn_cdg_1d(this->nx_h); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk_h(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid_h(d_grid_max), d_blk()); + } +#endif +} \ No newline at end of file diff --git a/src/detail/igrid_2d.inl b/src/detail/igrid_2d.inl new file mode 100755 index 00000000..0b53b9e5 --- /dev/null +++ b/src/detail/igrid_2d.inl @@ -0,0 +1,363 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "igrid_2d.h" + +/* template specialization 2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(): iGrid_sxd(), ny(0), ny_h(0) {} + + template + iGrid_sxd::iGrid_sxd(const ST& nx, const ST& ny): iGrid_sxd(nx), ny(ny), ny_h(ny/ST(2)) {} + + /* copy constructor */ + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /* converting constructor */ + template + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + iGrid_sxd& iGrid_sxd::operator=(const iGrid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + + ny = grid.ny; + ny_h = grid.ny_h; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + iGrid_sxd& iGrid_sxd::operator=(const iGrid_sxd& grid) + { + iGrid_sxd::operator=(grid); + + ny = ST(grid.ny); + ny_h = ST(grid.ny_h); + + return *this; + } + + template + template + CGPU_EXEC + void iGrid_sxd::assign(const iGrid_sxd& grid) + { + *this = grid; + } + + /***************************************************************************************/ + template + void iGrid_sxd::set_size(const ST& nx, const ST& ny) + { + iGrid_sxd::set_size(nx); + + this->ny = ny; + this->ny_h = ny/ST(2); + } + + template + CGPU_EXEC + void iGrid_sxd::clear() + { + iGrid_sxd::clear(); + ny = 0; + ny_h = 0; + } + + template + CGPU_EXEC + ST iGrid_sxd::size() const + { + return this->nx*ny; + } + + template + template + CGPU_EXEC + SU iGrid_sxd::ny_cast() const + { + return SU(ny); + } + + template + dt_shape_st iGrid_sxd::shape() const + { + return {ny, this->nx, ST(1), ST(1)}; + } + + /***************************************************************************************/ + /*********************** apply boundary conditions to indices **************************/ + /* https:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn */ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::ind_y_pbc(const ST& iy) const + { + return fcn_ind_pbc(iy, ny); + } + + template + CGPU_EXEC + ST iGrid_sxd::ind_y_bd(const ST& iy) const + { + return fcn_set_bound(iy, ST(0), ny-ST(1)); + } + + template + CGPU_EXEC + void iGrid_sxd::ind_pbc(ST& ix, ST& iy) const + { + ix = this->ind_x_pbc(ix); + iy = ind_y_pbc(iy); + } + + /***************************************************************************************/ + /**************************** subindices -> linear indices *****************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::operator()(const ST& ix, const ST& iy) const + { + return iy + ix*ny; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind(const ST& ix, const ST& iy) const + { + return iy + ix*ny; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_bd(const ST& ix, const ST& iy) const + { + return sub_2_ind(this->ind_x_bd(ix), ind_y_bd(iy)); + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_pbc(const ST& ix, const ST& iy) const + { + return ind_y_pbc(iy) + this->ind_x_pbc(ix)*ny; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_irv_sft_pbc(ST ix, ST iy) const + { + ind_pbc(ix, iy); + irv_sft(ix, iy); + + return sub_2_ind(ix, iy); + } + + /***************************************************************************************/ + /**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + template + CGPU_EXEC + void iGrid_sxd::ind_2_sub(const ST& ind, ST& ix, ST& iy) const + { + ix = ind/ny; + iy = ind - ix*ny; + } + + /***************************************************************************************/ + /******************* subindices to linear indices using 2nd dimension ******************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_by_d2(const ST& ix, const ST& iy) const + { + return iy*this->nx + ix; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_by_d2_pbc(const ST& ix, const ST& iy) const + { + return ind_y_pbc(iy)*this->nx + this->ind_x_pbc(ix); + } + + /***************************************************************************************/ + /****************** linear indices-> subindices using 2nd dimension ********************/ + /***************************************************************************************/ + template + CGPU_EXEC + void iGrid_sxd::ind_2_sub_by_d2(const ST& ind, ST& ix, ST& iy) const + { + iy = ind/this->nx; + ix = ind - iy*this->nx; + } + + /***************************************************************************************/ + /******************************* Fourier space indices *********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::igy(const ST& iy) const + { + return iy - ny_h; + } + + template + CGPU_EXEC + void iGrid_sxd::igv(ST& ix, ST& iy) const + { + ix = this->igx(ix); + iy = igy(iy); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + ST iGrid_sxd::igy_sft(const ST& iy) const + { + return (iy + CGPU_EXEC + void iGrid_sxd::igv_sft(ST& ix, ST& iy) const + { + ix = this->igx_sft(ix); + iy = igy_sft(iy); + } + + /***************************************************************************************/ + /******************************* real space indices ************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::iry(const ST& iy) const + { + return iy; + } + + template + CGPU_EXEC + void iGrid_sxd::irv(ST& ix, ST& iy) const + { + ix = this->irx(ix); + iy = iry(iy); + } + + /***************************************** shift ***************************************/ + template + CGPU_EXEC + ST iGrid_sxd::iry_sft(const ST& iy) const + { + return (iy + CGPU_EXEC + void iGrid_sxd::irv_sft(ST& ix, ST& iy) const + { + ix = this->irx_sft(ix); + iy = iry_sft(iy); + } + +#ifdef __CUDACC__ +template + dim3 iGrid_sxd::d_blk() + { + return fcn_cdb_2d(); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid(const dim3 d_grid_max) + { + auto grid = fcn_cdg_2d(this->ny, this->nx); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid(d_grid_max), d_blk()); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid_h(const dim3 d_grid_max) + { + auto grid = fcn_cdg_2d(this->ny_h, this->nx_h); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk_h(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid_h(d_grid_max), d_blk()); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid_d0_h(const dim3 d_grid_max) + { + auto grid = fcn_cdg_2d(this->ny_h, this->nx); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk_d0_h(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid_d0_h(d_grid_max), d_blk()); + } +#endif +} \ No newline at end of file diff --git a/src/detail/igrid_3d.inl b/src/detail/igrid_3d.inl new file mode 100755 index 00000000..8ba9a479 --- /dev/null +++ b/src/detail/igrid_3d.inl @@ -0,0 +1,372 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "igrid_3d.h" + +/* template specialization 3d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(): iGrid_sxd(), nz(0), nz_h(0) {} + + template + iGrid_sxd::iGrid_sxd(const ST& nx, const ST& ny, const ST& nz): iGrid_sxd(nx, ny), nz(nz), nz_h(nz/ST(2)) {} + + /* copy constructor */ + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /* converting constructor */ + template + template + CGPU_EXEC + iGrid_sxd::iGrid_sxd(const iGrid_sxd& grid): iGrid_sxd() + { + *this = grid; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + iGrid_sxd& iGrid_sxd::operator=(const iGrid_sxd& grid) + { + if (this != &grid) + { + iGrid_sxd::operator=(grid); + nz = grid.nz; + nz_h = grid.nz_h; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + iGrid_sxd& iGrid_sxd::operator=(const iGrid_sxd& grid) + { + iGrid_sxd::operator=(grid); + nz = ST(grid.nz); + nz_h = ST(grid.nz_h); + + return *this; + } + + template + template + CGPU_EXEC + void iGrid_sxd::assign(const iGrid_sxd& grid) + { + *this = grid; + } + + /***************************************************************************************/ + template + void iGrid_sxd::set_size(const ST& nx, const ST& ny, const ST& nz) + { + iGrid_sxd::set_size(nx, ny); + + this->nz = nz; + this->nz_h = nz/ST(2); + } + + template + CGPU_EXEC + void iGrid_sxd::clear() + { + iGrid_sxd::clear(); + nz = 0; + nz_h = 0; + } + + template + CGPU_EXEC + ST iGrid_sxd::size() const + { + return this->nx*this->ny*nz; + } + + template + template + CGPU_EXEC + SU iGrid_sxd::nz_cast() const + { + return SU(nz); + } + + template + dt_shape_st iGrid_sxd::shape() const + { + return {this->ny, this->nx, nz, ST(1)}; + } + + /***************************************************************************************/ + /************************* apply boundary conditions to indices ************************/ + /* https:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn */ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::ind_z_pbc(const ST& iz) const + { + return fcn_ind_pbc(iz, nz); + } + + template + CGPU_EXEC + ST iGrid_sxd::ind_z_bd(const ST& iz) const + { + return fcn_set_bound(iz, ST(0), nz-ST(1)); + } + + template + CGPU_EXEC + void iGrid_sxd::ind_pbc(ST& ix, ST& iy, ST& iz) const + { + ix = ind_x_pbc(ix); + iy = ind_y_pbc(iy); + iz = ind_z_pbc(iz); + } + + /***************************************************************************************/ + /**************************** subindices -> linear indices *****************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::operator()(const ST& ix, const ST& iy, const ST& iz) const + { + return iy + ix*this->ny + iz*this->ny*this->nx; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind(const ST& ix, const ST& iy, const ST& iz) const + { + return iy + ix*this->ny + iz*this->ny*this->nx; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_bd(const ST& ix, const ST& iy, const ST& iz) const + { + return sub_2_ind(this->ind_x_bd(ix), this->ind_y_bd(iy), ind_z_bd(iz)); + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_pbc(const ST& ix, const ST& iy, const ST& iz) const + { + return this->ind_y_pbc(iy) + this->ind_x_pbc(ix)*this->ny + ind_z_pbc(iz)*this->ny*this->nx; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_irv_sft_pbc(ST ix, ST iy, ST iz) const + { + ind_pbc(ix, iy, iz); + irv_sft(ix, iy, iz); + + return sub_2_ind(ix, iy, iz); + } + + /***************************************************************************************/ + /**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + template + CGPU_EXEC + void iGrid_sxd::ind_2_sub(const ST& ind, ST& ix, ST& iy, ST& iz) const + { + iz = ind/(this->ny*this->nx); + iy = ind - iz*this->ny*this->nx; + ix = iy/this->ny; + iy = iy - ix*this->ny; + } + + /***************************************************************************************/ + /******************* subindices to linear indices using 2nd dimension ******************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_by_d2(const ST& ix, const ST& iy, const ST& iz) const + { + return iy*this->nx + ix + iz*this->ny*this->nx; + } + + template + CGPU_EXEC + ST iGrid_sxd::sub_2_ind_by_d2_pbc(const ST& ix, const ST& iy, const ST& iz) const + { + return this->ind_y_pbc(iy)*this->nx + this->ind_x_pbc(ix) + ind_z_pbc(iz)*this->ny*this->nx; + } + + /***************************************************************************************/ + /****************** linear indices-> subindices using 2nd dimension ********************/ + /***************************************************************************************/ + template + CGPU_EXEC + void iGrid_sxd::ind_2_sub_by_d2(const ST& ind, ST& ix, ST& iy, ST& iz) const + { + iz = ind/(this->ny*this->nx); + ix = ind - iz*this->ny*this->nx; + iy = ix/this->nx; + ix = ix - iy*this->nx; + } + + /***************************************************************************************/ + /****************************** Fourier space indices **********************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::igz(const ST& iz) const + { + return iz - nz_h; + } + + template + CGPU_EXEC + void iGrid_sxd::igv(ST& ix, ST& iy, ST& iz) const + { + ix = this->igx(ix); + iy = this->igy(iy); + iz = igz(iz); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + ST iGrid_sxd::igz_sft(const ST& iz) const + { + return (iz + CGPU_EXEC + void iGrid_sxd::igv_sft(ST& ix, ST& iy, ST& iz) const + { + ix = this->igx_sft(ix); + iy = this->igy_sft(iy); + iz = igz_sft(iz); + } + + /***************************************************************************************/ + /******************************* real space indices ************************************/ + /***************************************************************************************/ + template + CGPU_EXEC + ST iGrid_sxd::irz(const ST& iz) const + { + return iz; + } + + template + CGPU_EXEC + void iGrid_sxd::irv(ST& ix, ST& iy, ST& iz) const + { + ix = this->irx(ix); + iy = this->iry(iy); + iz = irz(iz); + } + + /************************************* shift *******************************************/ + template + CGPU_EXEC + ST iGrid_sxd::irz_sft(const ST& iz) const + { + return (iz + CGPU_EXEC + void iGrid_sxd::irv_sft(ST& ix, ST& iy, ST& iz) const + { + ix = this->irx_sft(ix); + iy = this->iry_sft(iy); + iz = irz_sft(iz); + } + +#ifdef __CUDACC__ +template + dim3 iGrid_sxd::d_blk() + { + return fcn_cdb_3d(); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid(const dim3 d_grid_max) + { + auto grid = fcn_cdg_3d(this->ny, this->nx, this->nz); + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid(d_grid_max), d_blk()); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid_h(const dim3 d_grid_max) + { + auto grid = fcn_cdg_3d(this->ny_h, this->nx_h, this->nz_h); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk_h(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid_h(d_grid_max), d_blk()); + } + + /***************************************************************************************/ + template + dim3 iGrid_sxd::d_grid_d0_h(const dim3 d_grid_max) + { + auto grid = fcn_cdg_3d(this->ny_h, this->nx, this->nz); + + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; + + return grid; + } + + template + D_Grid_Blk iGrid_sxd::d_grid_blk_d0_h(const dim3 d_grid_max) + { + return D_Grid_Blk(d_grid_d0_h(d_grid_max), d_blk()); + } +#endif +} \ No newline at end of file diff --git a/src/detail/info_cpu.inl b/src/detail/info_cpu.inl new file mode 100755 index 00000000..6715217c --- /dev/null +++ b/src/detail/info_cpu.inl @@ -0,0 +1,128 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#ifdef _WIN32 + #include +#elif defined __APPLE__ + #include + #include + #include + #include + #include +#else + #include + #include + #include +#endif + +#include +#include +#include +#include +#include + +#include "const_enum.h" +#include "info_cpu.h" + +namespace mt +{ + Cpu_Info::Cpu_Info(): n_proc(0), n_threads(0), + tot_mem(0), free_mem(0) {} + + /* device info */ + namespace dev_info + { + void cpu_tot_free_mem(dt_float64 &tot, dt_float64 &free) + { + const dt_float64 s_bytes_2_mb(c_bytes_2_mb); + + #if defined(_WIN32) + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + GlobalMemoryStatusEx(&status); + free = static_cast(status.ullAvailPhys)/s_bytes_2_mb; + tot = static_cast(status.ullTotalPhys)/s_bytes_2_mb; + + #elif defined(__APPLE__) + dt_int32 mib[2]; + mib[0] = CTL_HW; + mib[1] = HW_MEMSIZE; + uint64_t physicalMem = 0; + dt_uint64 returnSize = sizeof(physicalMem); + sysctl(mib, 2, &physicalMem, &returnSize, NULL, 0); + tot = returnSize/s_bytes_2_mb; + + task_t targetTask = mach_task_self(); + struct task_basic_info ti; + mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT; + task_info(targetTask, TASK_BASIC_INFO_64, (task_info_t) &ti, &count); + free = ti.resident_size/s_bytes_2_mb; + + #else // linux + struct sysinfo memInfo; + sysinfo (&memInfo); + long long totalPhysMem = memInfo.totalram; + totalPhysMem *= memInfo.mem_unit; + long long physMemFree = memInfo.freeram; + physMemFree *= memInfo.mem_unit; + free = static_cast(physMemFree)/s_bytes_2_mb; // check if division by 1MB = 1048576 is necessary + tot = static_cast(totalPhysMem)/s_bytes_2_mb; // check if division by 1MB = 1048576 is necessary + #endif + } + + dt_float64 cpu_free_mem() + { + dt_float64 tot, free; + cpu_tot_free_mem(tot, free); + return free; + } + + dt_float64 cpu_tot_mem() + { + dt_float64 tot, free; + cpu_tot_free_mem(tot, free); + return tot; + } + + mt::Cpu_Info cpu_info() + { + mt::Cpu_Info info; + + #ifdef _WIN32 + SYSTEM_INFO siSysInfo; + GetSystemInfo(&siSysInfo); + info.n_proc = siSysInfo.dwNumberOfProcessors; + + #elif defined(__APPLE__) + dt_int32 count = 0; + dt_uint64 count_len = sizeof(count); + sysctlbyname("hw.logicalcpu", &count, &count_len, NULL, 0); + info.n_proc = count; + + #else // linux + info.n_proc = sysconf(_SC_NPROCESSORS_ONLN); + + #endif + + info.n_threads = std::thread::hardware_concurrency(); + cpu_tot_free_mem(info.tot_mem, info.free_mem); + + return info; + } + } +} \ No newline at end of file diff --git a/src/detail/info_gpu.inl b/src/detail/info_gpu.inl new file mode 100755 index 00000000..225f7bfb --- /dev/null +++ b/src/detail/info_gpu.inl @@ -0,0 +1,131 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +#include "const_enum.h" +#include "info_gpu.h" + +#ifdef __CUDACC__ + #include + #include +#endif + +namespace mt +{ +#ifdef __CUDACC__ + Gpu_Info::Gpu_Info(): id(0), name(""), comp_cap(0), + tot_mem(0), free_mem(0) {} + + /* device info */ + namespace dev_info + { + void gpu_tot_free_mem(dt_float64 &tot, dt_float64 &free, dt_int32 idx) + { + dt_float64 s_bytes_2_mb(c_bytes_2_mb); + + tot = free = 0; + dt_uint64 free_t, tot_t; + if (cudaSuccess == cudaMemGetInfo(&free_t, &tot_t)) + { + free = static_cast(free_t)/s_bytes_2_mb; + tot = static_cast(tot_t)/s_bytes_2_mb; + } + } + + dt_float64 gpu_free_mem() + { + dt_float64 tot, free; + gpu_tot_free_mem(tot, free); + return tot; + } + + dt_float64 gpu_tot_mem() + { + dt_float64 tot=0, free=0; + gpu_tot_free_mem(tot, free); + return free; + } + + dt_bool is_gpu_avbl() + { + dt_bool is_available = false; + try + { + dt_int32 device_count = 0; + cudaError_t error_id = cudaGetDeviceCount(&device_count); + + is_available = !((error_id != cudaSuccess)||(device_count == 0)); + } + catch(...) + { + is_available = false; + } + + return is_available; + } + + dt_int32 gpu_n_avbl() + { + dt_int32 device_count = 0; + cudaError_t error_id = cudaGetDeviceCount(&device_count); + + return (error_id != cudaSuccess)?0:device_count; + } + + std::vector gpu_info() + { + std::vector info; + + if (!is_gpu_avbl()) + { + return info; + } + + dt_int32 device_count = 0; + cudaGetDeviceCount(&device_count); + + info.resize(device_count); + for(auto idev = 0; idev < device_count; idev++) + { + cudaDeviceProp cuda_device_prop; + cudaGetDeviceProperties(&cuda_device_prop, idev); + + info[idev].id = idev; + info[idev].name = cuda_device_prop.name; + info[idev].comp_cap = 10*cuda_device_prop.major+cuda_device_prop.minor; + gpu_tot_free_mem(info[idev].tot_mem, info[idev].free_mem); + } + + // auto compare_fn = [](const Gpu_Info &a, const Gpu_Info &b)->dt_bool + // { + // return a.comp_cap > b.comp_cap; + // }; + // std::sort(info.begin(), info.end(), compare_fn); + + return info; + } + } + #endif +} \ No newline at end of file diff --git a/src/detail/ithread_rect_1d.inl b/src/detail/ithread_rect_1d.inl new file mode 100755 index 00000000..3863b45b --- /dev/null +++ b/src/detail/ithread_rect_1d.inl @@ -0,0 +1,196 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ithread_rect_1d.h" + +/* template specialization 1d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + iThread_Rect_sxd::iThread_Rect_sxd(): ix_0(0), ix_e(0), ind_0(0), ind_e(0), istm(0) {} + + template + iThread_Rect_sxd::iThread_Rect_sxd(const dt_init_list_int32& list): istm(0) + { + auto ptr = list.begin(); + + ix_0 = ptr[0]; + ix_e = ptr[1]; + + ind_0 = ST(0); + ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& ix_0, const ST& ix_e): ix_0(ix_0), ix_e(ix_e), istm(0) + { + ind_0 = ST(0); + ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& nx): ix_0(0), ix_e(nx), istm(0) + { + ind_0 = ST(0); + ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& ind_0, const ST& ind_e) + : ix_0(ix_0), ix_e(ix_e), ind_0(ind_0), ind_e(ind_e), istm(0) {} + + /* copy constructor */ + template + CGPU_EXEC + iThread_Rect_sxd::iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /* converting constructor */ + template + template + CGPU_EXEC + iThread_Rect_sxd::iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& iThread_Rect_sxd::operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + ix_0 = ithread.ix_0; + ix_e = ithread.ix_e; + + ind_0 = ithread.ind_0; + ind_e = ithread.ind_e; + + istm = ithread.istm; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + iThread_Rect_sxd& iThread_Rect_sxd::operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + ix_0 = ST(ithread.ix_0); + ix_e = ST(ithread.ix_e); + + ind_0 = ST(ithread.ind_0); + ind_e = ST(ithread.ind_e); + + istm = ithread.istm; + } + + return *this; + } + + template + template + CGPU_EXEC + void iThread_Rect_sxd::assign(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /***************************************************************************************/ + template + CGPU_EXEC + void iThread_Rect_sxd::clear() + { + ix_0 = ST(0); + ix_e = ST(0); + + ind_0 = ST(0); + ind_e = ST(0); + + istm = 0; + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::nx() const + { + return ix_e - ix_0; + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::size() const + { + return nx(); + } + + template + CGPU_EXEC + dt_bool iThread_Rect_sxd::chk_bound_ix(const ST& ix) const + { + return fcn_chk_bound(ix, ix_0, ix_e); + } + + template + CGPU_EXEC + dt_bool iThread_Rect_sxd::chk_bound(const ST& ix) const + { + return chk_bound_ix(ix); + } + + template + CGPU_EXEC + void iThread_Rect_sxd::apply_bound_ix(const ST& ix_0, const ST& ix_e) + { + this->ix_0 = fcn_set_bound(this->ix_0, ix_0, ix_e); + this->ix_e = fcn_set_bound(this->ix_e, ix_0, ix_e); + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::sub_2_ind(const ST& ix) const + { + return ix-ix_0; + } + + template + CGPU_EXEC + void iThread_Rect_sxd::set_ind(const ST& ind_0, const ST& ind_e) + { + this->ind_0 = ind_0; + this->ind_e = ind_e; + } + + template + void iThread_Rect_sxd::set_ind_asc_order() + { + if (ix_0>ix_e) + { + std::swap(ix_0, ix_e); + } + } +} \ No newline at end of file diff --git a/src/detail/ithread_rect_2d.inl b/src/detail/ithread_rect_2d.inl new file mode 100755 index 00000000..b2d3ed96 --- /dev/null +++ b/src/detail/ithread_rect_2d.inl @@ -0,0 +1,188 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ithread_rect_2d.h" + +/* template specialization 2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + iThread_Rect_sxd::iThread_Rect_sxd(): iThread_Rect_sxd(), iy_0(0), iy_e(0) {} + + template + iThread_Rect_sxd::iThread_Rect_sxd(const dt_init_list_int32& list) + { + auto ptr = list.begin(); + + this->ix_0 = ptr[0]; + this->ix_e = ptr[1]; + this->iy_0 = ptr[2]; + this->iy_e = ptr[3]; + + this->istm = 0; + + this->ind_0 = ST(0); + this->ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e) + : iThread_Rect_sxd(ix_0, ix_e), iy_0(iy_0), iy_e(iy_e) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& nx, const ST& ny) + : iThread_Rect_sxd(nx), iy_0(0), iy_e(ny) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& ind_0, const ST& ind_e) + : iThread_Rect_sxd(ix_0, ix_e, ind_0, ind_e), iy_0(iy_0), iy_e(iy_e) {} + + /* copy constructor */ + template + CGPU_EXEC + iThread_Rect_sxd::iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /* converting constructor */ + template + template + CGPU_EXEC + iThread_Rect_sxd::iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& iThread_Rect_sxd::operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iy_0 = ithread.iy_0; + iy_e = ithread.iy_e; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + iThread_Rect_sxd& iThread_Rect_sxd::operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iy_0 = ST(ithread.iy_0); + iy_e = ST(ithread.iy_e); + } + + return *this; + } + + template + template + CGPU_EXEC + void iThread_Rect_sxd::assign(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /***************************************************************************************/ + template + CGPU_EXEC + void iThread_Rect_sxd::clear() + { + iThread_Rect_sxd::clear(); + + iy_0 = ST(0); + iy_e = ST(0); + } + + + template + CGPU_EXEC + ST iThread_Rect_sxd::ny() const + { + return iy_e - iy_0; + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::size() const + { + return iThread_Rect_sxd::size()*ny(); + } + + template + CGPU_EXEC + dt_bool iThread_Rect_sxd::chk_bound_iy(const ST& iy) const + { + return fcn_chk_bound(iy, iy_0, iy_e); + } + + template + CGPU_EXEC + dt_bool iThread_Rect_sxd::chk_bound(const ST& ix, const ST& iy) const + { + return this->chk_bound_ix(ix) && chk_bound_iy(iy); + } + + template + CGPU_EXEC + void iThread_Rect_sxd::apply_bound_iy(const ST& iy_0, const ST& iy_e) + { + this->iy_0 = fcn_set_bound(this->iy_0, iy_0, iy_e); + this->iy_e = fcn_set_bound(this->iy_e, iy_0, iy_e); + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::sub_2_ind(const ST& ix, const ST& iy) const + { + return (iy-iy_0) + (ix-this->ix_0)*ny(); + } + + template + void iThread_Rect_sxd::set_ind_asc_order() + { + iThread_Rect_sxd::set_ind_asc_order(); + + if (iy_0>iy_e) + { + std::swap(iy_0, iy_e); + } + } +} \ No newline at end of file diff --git a/src/detail/ithread_rect_3d.inl b/src/detail/ithread_rect_3d.inl new file mode 100755 index 00000000..a6dce11b --- /dev/null +++ b/src/detail/ithread_rect_3d.inl @@ -0,0 +1,189 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ithread_rect_3d.h" + +/* template specialization 3d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + iThread_Rect_sxd::iThread_Rect_sxd(): iThread_Rect_sxd(), iz_0(0), iz_e(0) {} + + template + iThread_Rect_sxd::iThread_Rect_sxd(const dt_init_list_int32& list) + { + auto ptr = list.begin(); + + this->ix_0 = ptr[0]; + this->ix_e = ptr[1]; + this->iy_0 = ptr[2]; + this->iy_e = ptr[3]; + this->iz_0 = ptr[4]; + this->iz_e = ptr[5]; + + this->istm = 0; + + this->ind_0 = ST(0); + this->ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& iz_0, const ST& iz_e) + : iThread_Rect_sxd(ix_0, ix_e, iy_0, iy_e), iz_0(iz_0), iz_e(iz_e) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& nx, const ST& ny, const ST& nz) + : iThread_Rect_sxd(nx, ny), iz_0(0), iz_e(nz) + { + this->ind_0 = ST(0); + this->ind_e = size(); + } + + template + iThread_Rect_sxd::iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& iz_0, const ST& iz_e, const ST& ind_0, const ST& ind_e) + : iThread_Rect_sxd(ix_0, ix_e, iy_0, iy_e, ind_0, ind_e), iz_0(iz_0), iz_e(iz_e) {} + + /* copy constructor */ + template + CGPU_EXEC + iThread_Rect_sxd::iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /* converting constructor */ + template + template + CGPU_EXEC + iThread_Rect_sxd::iThread_Rect_sxd(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& iThread_Rect_sxd::operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iz_0 = ithread.iz_0; + iz_e = ithread.iz_e; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + iThread_Rect_sxd& iThread_Rect_sxd::operator=(const iThread_Rect_sxd& ithread) + { + if (this != &ithread) + { + iThread_Rect_sxd::operator=(ithread); + + iz_0 = ST(ithread.iz_0); + iz_e = ST(ithread.iz_e); + } + + return *this; + } + + template + template + CGPU_EXEC + void iThread_Rect_sxd::assign(const iThread_Rect_sxd& ithread) + { + *this = ithread; + } + + /***************************************************************************************/ + template + CGPU_EXEC + void iThread_Rect_sxd::clear() + { + iThread_Rect_sxd::clear(); + + iz_0 = ST(0); + iz_e = ST(0); + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::nz() const + { + return iz_e - iz_0; + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::size() const + { + return iThread_Rect_sxd::size()*nz(); + } + + template + CGPU_EXEC + dt_bool iThread_Rect_sxd::chk_bound_iz(const ST& iz) const + { + return fcn_chk_bound(iz, iz_0, iz_e); + } + + template + CGPU_EXEC + dt_bool iThread_Rect_sxd::chk_bound(const ST& ix, const ST& iy, const ST& iz) const + { + return this->chk_bound_ix(ix) && this->chk_bound_iy(iy) && chk_bound_iz(iz); + } + + template + CGPU_EXEC + void iThread_Rect_sxd::apply_bound_iz(const ST& iz_0, const ST& iz_e) + { + this->iz_0 = fcn_set_bound(this->iz_0, iz_0, iz_e); + this->iz_e = fcn_set_bound(this->iz_e, iz_0, iz_e); + } + + template + CGPU_EXEC + ST iThread_Rect_sxd::sub_2_ind(const ST& ix, const ST& iy, const ST& iz) const + { + return (iy-this->iy_0) + (ix-this->ix_0)*this->ny_s() + (iz-iz_0)*this->ny()*this->nx(); + } + + template + void iThread_Rect_sxd::set_ind_asc_order() + { + iThread_Rect_sxd::set_ind_asc_order(); + + if (iz_0>iz_e) + { + std::swap(iz_0, iz_e); + } + } +} \ No newline at end of file diff --git a/src/detail/kahan_sum.inl b/src/detail/kahan_sum.inl new file mode 100755 index 00000000..4e1d1152 --- /dev/null +++ b/src/detail/kahan_sum.inl @@ -0,0 +1,281 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "kahan_sum.h" + +/* Kahan summation */ +namespace mt +{ + /************************************* constructors ************************************/ + /* Default constructor */ + template + CGPU_EXEC + KS::KS(): m_sum(0), m_error(0) {} + + /* Copy constructor */ + template + CGPU_EXEC + KS::KS(const T& sum, T error): m_sum(sum), m_error(error) {} + + /* Copy constructor */ + template + CGPU_EXEC + KS::KS(const KS& ks) + { + *this = ks; + } + + /* Move constructor */ + template + CGPU_EXEC + KS::KS(KS&& ks) + { + *this = std::move(ks); + } + + /* converting copy constructor */ + template + template + CGPU_EXEC + KS::KS(const KS& ks) + { + *this = ks; + } + + /******************************** assignment operators *********************************/ + /* constructor from r */ + template + CGPU_EXEC + KS& KS::operator=(const T& r) + { + m_sum = r; + m_error = 0; + + return *this; + } + + /* copy assignment operator */ + template + CGPU_EXEC + KS& KS::operator=(const KS& ks) + { + m_sum = ks.m_sum; + m_error = ks.m_error; + + return *this; + } + + /* Move assignment operator */ + template + CGPU_EXEC + KS& KS::operator=(KS&& ks) + { + m_sum = std::move(ks.m_sum); + m_error = std::move(ks.m_error); + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + KS& KS::operator=(const KS& ks) + { + m_sum = T(ks.m_sum); + m_error = T(ks.m_error); + + return *this; + } + + // user define conversion + template + CGPU_EXEC + T KS::operator()() + { + return m_sum; + } + + + // user define conversion + template + CGPU_EXEC + KS::operator T() + { + return m_sum; + } + + /******************* Compound assignment operators *******************/ + template + CGPU_EXEC + KS& KS::operator+=(T r) + { + this->add(r); + + return *this; + } + + template + CGPU_EXEC + KS& KS::operator+=(const KS& r) + { + this->add(r.m_sum); + + return *this; + } + + template + CGPU_EXEC + KS& KS::operator-=(T r) + { + this->add(-r); + + return *this; + } + + template + CGPU_EXEC + KS& KS::operator-=(const KS& r) + { + this->add(-r.m_sum); + + return *this; + } + + template + CGPU_EXEC + KS& KS::operator/=(T r) + { + *this = *this/r; + + return *this; + } + + template + CGPU_EXEC + KS& KS::operator/=(const KS& r) + { + *this = *this/r; + + return *this; + } + + template + CGPU_EXEC + void KS::add(T r) + { + r = r - m_error; + T t = m_sum + r; // m_sum is big, r small, so low-order digits of r are lost. + m_error = (t-m_sum)-r; // (t - m_sum) cancels the high-order part of r;subtracting r recovers negative (low part of r) + m_sum = t; // Algebraically, m_error should always be zero. Beware overly-aggressive optimizing compilers! + + // Next time around, the lost low part will be added to y in a fresh attempt + } +} + +/* unitary operators */ +namespace mt +{ + template + CGPU_EXEC + KS operator-(const KS& r) + { + return {-r.m_sum, r.m_error}; + } +} + +/* binary operators */ +namespace mt +{ + template + CGPU_EXEC + KS operator+(const KS& lhs, const KS& rhs) + { + KS ks(lhs); + ks += rhs; + return ks; + } + + template + CGPU_EXEC + KS operator+(const KS& lhs, const T& rhs) + { + KS ks(lhs); + ks += rhs; + return ks; + } + + template + CGPU_EXEC + KS operator+(const T& lhs, const KS& rhs) + { + KS ks(lhs); + ks += rhs; + return ks; + } + + template + CGPU_EXEC + KS operator-(const KS& lhs, const KS& rhs) + { + KS ks(lhs); + ks -= rhs; + return ks; + } + + template + CGPU_EXEC + KS operator-(const KS& lhs, const T& rhs) + { + KS ks(lhs); + ks -= rhs; + return ks; + } + + template + CGPU_EXEC + KS operator-(const T& lhs, const KS& rhs) + { + KS ks(lhs); + ks -= rhs; + return ks; + } + + template + CGPU_EXEC + T operator/(const KS& lhs, const KS& rhs) + { + return lhs.m_sum/rhs.m_sum; + } + + template + CGPU_EXEC + T operator/(const KS& lhs, const T& rhs) + { + return lhs.m_sum/rhs; + } + + template + CGPU_EXEC + T operator/(const T& lhs, const KS& rhs) + { + return lhs/rhs.m_sum; + } +} \ No newline at end of file diff --git a/src/detail/mx_2x2.inl b/src/detail/mx_2x2.inl new file mode 100755 index 00000000..7972ff58 --- /dev/null +++ b/src/detail/mx_2x2.inl @@ -0,0 +1,531 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "mx_2x2.h" + +/* forward declarations */ +namespace mt +{ + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_2x2& mx); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_2x2& mx); + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_2x2& mx); + + template + CGPU_EXEC + T fmin(const Mx_2x2& mx); + + template + CGPU_EXEC + T fmax(const Mx_2x2& mx); + + template + CGPU_EXEC + T det(const Mx_2x2& mx); + + template + CGPU_EXEC + Mx_2x2 inv(const Mx_2x2& mx); +} + +/* 2x2 matrix */ +namespace mt +{ + /************************************* constructors ************************************/ + /* Default constructor */ + template + CGPU_EXEC + Mx_2x2::Mx_2x2(): m_data{0, 0, 0, 0} {} + + /* constructor */ + template + CGPU_EXEC + Mx_2x2::Mx_2x2(const T& c_11, const T& c_21, const T& c_12, const T& c_22) + { + m_data[0] = c_11; + m_data[1] = c_21; + m_data[2] = c_12; + m_data[3] = c_22; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Mx_2x2::Mx_2x2(const U& c_11, const U& c_21, const U& c_12, const U& c_22) + { + m_data[0] = T(c_11); + m_data[1] = T(c_21); + m_data[2] = T(c_12); + m_data[3] = T(c_22); + } + + /* Copy constructor */ + template + CGPU_EXEC + Mx_2x2::Mx_2x2(const Mx_2x2& mx) + { + *this = mx; + } + + /* Move constructor */ + template + template + CGPU_EXEC + Mx_2x2::Mx_2x2(Mx_2x2&& mx) + { + *this = std::move(mx); + } + + /* converting copy constructor */ + template + template + CGPU_EXEC + Mx_2x2::Mx_2x2(const Mx_2x2& mx) + { + *this = mx; + } + + template + template + CGPU_EXEC + Mx_2x2::Mx_2x2(U* v) + { + m_data[0] = T(v[0]); + m_data[1] = T(v[1]); + m_data[2] = T(v[2]); + m_data[3] = T(v[3]); + } + + /******************************** assignment operators *********************************/ + + /* copy assignment operator */ + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator=(const Mx_2x2& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + } + + return *this; + } + + /* Move assignment operator */ + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator=(Mx_2x2&& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator=(const Mx_2x2& mx) + { + m_data[0] = T(mx.m_data[0]); + m_data[1] = T(mx.m_data[1]); + m_data[2] = T(mx.m_data[2]); + m_data[3] = T(mx.m_data[3]); + + return *this; + } + + /******************* Compound assignment operators *******************/ + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator+=(const Mx_2x2& mx) + { + *this = *this + mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator+=(const U& mx) + { + *this = *this + mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator-=(const Mx_2x2& mx) + { + *this = *this - mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator-=(const U& mx) + { + *this = *this - mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator*=(const Mx_2x2& mx) + { + *this = *this*mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator*=(const U& mx) + { + *this = *this*mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator/=(const Mx_2x2& mx) + { + *this = *this/mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_2x2& Mx_2x2::operator/=(const U& mx) + { + *this = *this/mx; + + return *this; + } + + /************************** Other operators **************************/ + template + dt_int32 Mx_2x2::size() const + { + return 4; + } + + template + CGPU_EXEC_INL + T& Mx_2x2::operator[](const dt_int32 idx) { return m_data[idx]; } + + template + CGPU_EXEC_INL + const T& Mx_2x2::operator[](const dt_int32 idx) const { return m_data[idx]; } + + template + CGPU_EXEC_INL + T& Mx_2x2::operator()(const dt_int32 ir, const dt_int32 ic) { return m_data[ir - 1 + 2*(ic - 1)]; } + + template + CGPU_EXEC_INL + const T& Mx_2x2::operator()(const dt_int32 ir, const dt_int32 ic) const { return m_data[ir - 1 + 2*(ic - 1)]; } + + template + CGPU_EXEC + dt_bool Mx_2x2::fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + template + CGPU_EXEC + dt_bool Mx_2x2::is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + template + CGPU_EXEC + dt_bool Mx_2x2::is_id_mx() const + { + return mt::is_id_mx(*this); + } + + template + CGPU_EXEC + T Mx_2x2::min() const + { + return mt::fmin(*this); + } + + template + CGPU_EXEC + T Mx_2x2::max() const + { + return mt::fmax(*this); + } + + template + CGPU_EXEC + T Mx_2x2::det() const + { + return mt::det(*this); + } + + template + CGPU_EXEC + Mx_2x2 Mx_2x2::inv() const + { + return mt::inv(*this); + } +} + +/* unitary operators */ +namespace mt +{ + template + CGPU_EXEC + Mx_2x2 operator-(const Mx_2x2& mx) + { + return {-mx[0], -mx[1], -mx[2], -mx[3]}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_2x2& mx) + { + return fcn_is_zero(mx[0], mx[1], mx[2], mx[3]); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_2x2& mx) + { + return fcn_is_nzero(mx[0], mx[1], mx[2], mx[3]); + } + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_2x2& mx) + { + return fcn_is_one(mx[0], mx[3]) && fcn_is_zero(mx[1], mx[2]); + } + + template + CGPU_EXEC + T fmin(const Mx_2x2& mx) + { + return ::fmin(mx[0], ::fmin(mx[1], ::fmin(mx[2], mx[3]))); + } + + template + CGPU_EXEC + T fmax(const Mx_2x2& mx) + { + return ::fmax(mx[0], ::fmax(mx[1], ::fmax(mx[2], mx[3]))); + } + + template + CGPU_EXEC + T det(const Mx_2x2& mx) + { + return mx(1, 1)*mx(2, 2) - mx(1, 2)*mx(2, 1); + } + + template + CGPU_EXEC + Mx_2x2 inv(const Mx_2x2& mx) + { + Mx_2x2 mx_inv{mx(2, 2), -mx(2, 1), -mx(1, 2), mx(1, 1)}; + + return mx_inv/det(mx); + } +} + +/* binary operators */ +namespace mt +{ + template > + CGPU_EXEC + Mx_2x2 operator+(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator+(const Mx_2x2& lhs, const U& rhs) + { + return {lhs[0] + rhs, lhs[1] + rhs, lhs[2] + rhs, lhs[3] + rhs}; + } + + template > + CGPU_EXEC + Mx_2x2 operator+(const T& lhs, const Mx_2x2& rhs) + { + return {lhs + rhs[0], lhs + rhs[1], lhs + rhs[2], lhs + rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator-(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator-(const Mx_2x2& lhs, const U& rhs) + { + return {lhs[0] - rhs, lhs[1] - rhs, lhs[2] - rhs, lhs[3] -rhs}; + } + + template > + CGPU_EXEC + Mx_2x2 operator-(const T& lhs, const Mx_2x2& rhs) + { + return {lhs - rhs[0], lhs - rhs[1], lhs - rhs[2], lhs - rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator*(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + Mx_2x2 mx; + + mx[0] = lhs[0]*rhs[0] + lhs[2]*rhs[1]; + mx[1] = lhs[1]*rhs[0] + lhs[3]*rhs[1]; + + mx[2] = lhs[0]*rhs[2] + lhs[2]*rhs[3]; + mx[3] = lhs[1]*rhs[2] + lhs[3]*rhs[3]; + + return mx; + } + + template > + CGPU_EXEC + Mx_2x2 operator*(const Mx_2x2& lhs, const U& rhs) + { + return {lhs[0]*rhs, lhs[1]*rhs, lhs[2]*rhs, lhs[3]*rhs}; + } + + template > + CGPU_EXEC + Mx_2x2 operator*(const T& lhs, const Mx_2x2& rhs) + { + return {lhs*rhs[0], lhs*rhs[1], lhs*rhs[2], lhs*rhs[3]}; + } + + template > + CGPU_EXEC + R_2d operator*(const Mx_2x2& lhs, const R_2d& rhs) + { + return {lhs[0]*rhs.x + lhs[2]*rhs.y, lhs[1]*rhs.x + lhs[3]*rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator*(const R_2d& lhs, const Mx_2x2& rhs) + { + return {lhs.x*rhs[0] + lhs.y*rhs[1], lhs.x*rhs[2] + lhs.y*rhs[3]}; + } + + template > + CGPU_EXEC + Mx_2x2 operator/(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return lhs*inv(rhs); + } + + template > + CGPU_EXEC + Mx_2x2 operator/(const Mx_2x2& lhs, const U& rhs) + { + return {fcn_div(lhs[0], rhs), fcn_div(lhs[1], rhs), fcn_div(lhs[2], rhs), fcn_div(lhs[3], rhs)}; + } + + template > + CGPU_EXEC + Mx_2x2 operator/(const T& lhs, const Mx_2x2& rhs) + { + return {fcn_div(lhs, rhs[0]), fcn_div(lhs, rhs[1]), fcn_div(lhs, rhs[2]), fcn_div(lhs, rhs[3])}; + } + + template > + CGPU_EXEC + Mx_2x2 fmin(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {::fmin(lhs[0], rhs[0]), ::fmin(lhs[1], rhs[1]), ::fmin(lhs[2], rhs[2]), ::fmin(lhs[3], rhs[3])}; + } + + template > + CGPU_EXEC + Mx_2x2 fmax(const Mx_2x2& lhs, const Mx_2x2& rhs) + { + return {::fmax(lhs[0], rhs[0]), ::fmax(lhs[1], rhs[1]), ::fmax(lhs[2], rhs[2]), ::fmax(lhs[3], rhs[3])}; + } +} + +/* traits */ +namespace mt +{ + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_mx_2x2_f64 = std::initializer_list>; +} + +/* other operators */ +namespace mt +{ + template + CGPU_EXEC + Mx_2x2 fcn_rot_mx_2d(const T& theta) + { + T cos_theta, sin_theta; + sincos(theta, &sin_theta, &cos_theta); + + return {cos_theta, sin_theta, -sin_theta, cos_theta}; + } +} \ No newline at end of file diff --git a/src/detail/mx_3x3.inl b/src/detail/mx_3x3.inl new file mode 100755 index 00000000..41d2c946 --- /dev/null +++ b/src/detail/mx_3x3.inl @@ -0,0 +1,619 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "mx_3x3.h" + +/* forward declarations */ +namespace mt +{ + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_3x3& mx); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_3x3& mx); + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_3x3& mx); + + template + CGPU_EXEC + T fmin(const Mx_3x3& mx); + + template + CGPU_EXEC + T fmax(const Mx_3x3& mx); + + template + CGPU_EXEC + T det(const Mx_3x3& mx); + + template + CGPU_EXEC + Mx_3x3 inv(const Mx_3x3& mx); +} + +/* 3x3 matrix */ +namespace mt +{ + /************************************* constructors ************************************/ + /* Default constructor */ + template + CGPU_EXEC + Mx_3x3::Mx_3x3(): m_data{T(), T(), T(), T(), T(), T(), T(), T(), T()} {} + + /* constructor */ + template + CGPU_EXEC + Mx_3x3::Mx_3x3(const T& c_11, const T& c_21, const T& c_31, const T& c_12, + const T& c_22, const T& c_32, const T& c_13, const T& c_23, const T& c_33) + { + m_data[0] = c_11; + m_data[1] = c_21; + m_data[2] = c_31; + m_data[3] = c_12; + m_data[4] = c_22; + m_data[5] = c_32; + m_data[6] = c_13; + m_data[7] = c_23; + m_data[8] = c_33; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Mx_3x3::Mx_3x3(const U& c_11, const U& c_21, const U& c_31, const U& c_12, + const U& c_22, const U& c_32, const U& c_13, const U& c_23, const U& c_33) + { + m_data[0] = T(c_11); + m_data[1] = T(c_21); + m_data[2] = T(c_31); + m_data[3] = T(c_12); + m_data[4] = T(c_22); + m_data[5] = T(c_32); + m_data[6] = T(c_13); + m_data[7] = T(c_23); + m_data[8] = T(c_33); + } + + ///* converting constructor */ + //template + //CGPU_EXEC + //Mx_3x3::Mx_3x3(dt_init_list& list) + //{ + // m_data[0] = T(ptr[0]); + // m_data[1] = T(ptr[1]); + // m_data[2] = T(ptr[2]); + // m_data[3] = T(ptr[3]); + // m_data[4] = T(ptr[4]); + // m_data[5] = T(ptr[5]); + // m_data[6] = T(ptr[6]); + // m_data[7] = T(ptr[7]); + // m_data[8] = T(ptr[8]); + //} + + /* Copy constructor */ + template + CGPU_EXEC + Mx_3x3::Mx_3x3(const Mx_3x3& mx) + { + *this = mx; + } + + /* Move constructor */ + template + template + CGPU_EXEC + Mx_3x3::Mx_3x3(Mx_3x3&& mx) + { + *this = std::move(mx); + } + + /* converting copy constructor */ + template + template + CGPU_EXEC + Mx_3x3::Mx_3x3(const Mx_3x3& mx) + { + *this = mx; + } + + template + template + CGPU_EXEC + Mx_3x3::Mx_3x3(U* v) + { + m_data[0] = T(v[0]); + m_data[1] = T(v[1]); + m_data[2] = T(v[2]); + m_data[3] = T(v[3]); + m_data[4] = T(v[4]); + m_data[5] = T(v[5]); + m_data[6] = T(v[6]); + m_data[7] = T(v[7]); + m_data[8] = T(v[8]); + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator=(const Mx_3x3& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + m_data[4] = mx.m_data[4]; + m_data[5] = mx.m_data[5]; + m_data[6] = mx.m_data[6]; + m_data[7] = mx.m_data[7]; + m_data[8] = mx.m_data[8]; + } + + return *this; + } + + /* Move assignment operator */ + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator=(Mx_3x3&& mx) + { + if (this != &mx) + { + m_data[0] = mx.m_data[0]; + m_data[1] = mx.m_data[1]; + m_data[2] = mx.m_data[2]; + m_data[3] = mx.m_data[3]; + m_data[4] = mx.m_data[4]; + m_data[5] = mx.m_data[5]; + m_data[6] = mx.m_data[6]; + m_data[7] = mx.m_data[7]; + m_data[8] = mx.m_data[8]; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator=(const Mx_3x3& mx) + { + m_data[0] = T(mx.m_data[0]); + m_data[1] = T(mx.m_data[1]); + m_data[2] = T(mx.m_data[2]); + m_data[3] = T(mx.m_data[3]); + m_data[4] = T(mx.m_data[4]); + m_data[5] = T(mx.m_data[5]); + m_data[6] = T(mx.m_data[6]); + m_data[7] = T(mx.m_data[7]); + m_data[8] = T(mx.m_data[8]); + + return *this; + } + + /******************* Compound assignment operators *******************/ + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator+=(const Mx_3x3& mx) + { + *this = *this + mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator+=(const U& mx) + { + *this = *this + mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator-=(const Mx_3x3& mx) + { + *this = *this - mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator-=(const U& mx) + { + *this = *this - mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator*=(const Mx_3x3& mx) + { + *this = *this*mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator*=(const U& mx) + { + *this = *this*mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator/=(const Mx_3x3& mx) + { + *this = *this/mx; + + return *this; + } + + template + template + CGPU_EXEC + Mx_3x3& Mx_3x3::operator/=(const U& mx) + { + *this = *this/mx; + + return *this; + } + + /************************** Other operators **************************/ + template + dt_int32 Mx_3x3::size() const + { + return 9; + } + + template + CGPU_EXEC_INL + T& Mx_3x3::operator[](const dt_int32 idx) { return m_data[idx]; } + + template + CGPU_EXEC_INL + const T& Mx_3x3::operator[](const dt_int32 idx) const { return m_data[idx]; } + + template + CGPU_EXEC_INL + T& Mx_3x3::operator()(const dt_int32 ir, const dt_int32 ic) { return m_data[ir - 1 + 3*(ic - 1)]; } + + template + CGPU_EXEC_INL + const T& Mx_3x3::operator()(const dt_int32 ir, const dt_int32 ic) const { return m_data[ir - 1 + 3*(ic - 1)]; } + + template + CGPU_EXEC + dt_bool Mx_3x3::fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + template + CGPU_EXEC + dt_bool Mx_3x3::is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + template + CGPU_EXEC + dt_bool Mx_3x3::is_id_mx() const + { + return mt::is_id_mx(*this); + } + + template + CGPU_EXEC + T Mx_3x3::min() const + { + return mt::fmin(*this); + } + + template + CGPU_EXEC + T Mx_3x3::max() const + { + return mt::fmax(*this); + } + + template + CGPU_EXEC + T Mx_3x3::det() const + { + return mt::det(*this); + } + + template + CGPU_EXEC + Mx_3x3 Mx_3x3::inv() const + { + return mt::inv(*this); + } +} + +/* unitary operators */ +namespace mt +{ + template + CGPU_EXEC + Mx_3x3 operator-(const Mx_3x3& mx) + { + return {-mx[0], -mx[1], -mx[2], -mx[3], -mx[4], -mx[5], -mx[6], -mx[7], -mx[8]}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const Mx_3x3& mx) + { + return fcn_is_zero(mx[0], mx[1], mx[2], mx[3], mx[4], mx[5], mx[6], mx[7], mx[8]); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const Mx_3x3& mx) + { + return fcn_is_nzero(mx[0], mx[1], mx[2], mx[3], mx[4], mx[5], mx[6], mx[7], mx[8]); + } + + template + CGPU_EXEC + dt_bool is_id_mx(const Mx_3x3& mx) + { + return fcn_is_one(mx[0], mx[4], mx[8]) && fcn_is_zero(mx[1], mx[2], mx[3], mx[5], mx[6], mx[7]); + } + + template + CGPU_EXEC + T fmin(const Mx_3x3& mx) + { + return ::fmin(mx[0], ::fmin(mx[1], ::fmin(mx[2], ::fmin(mx[3], ::fmin(mx[4], ::fmin(mx[5], ::fmin(mx[6], ::fmin(mx[7], mx[8])))))))); + } + + template + CGPU_EXEC + T fmax(const Mx_3x3& mx) + { + return ::fmax(mx[0], ::fmax(mx[1], ::fmax(mx[2], ::fmax(mx[3], ::fmax(mx[4], ::fmax(mx[5], ::fmax(mx[6], ::fmax(mx[7], mx[8])))))))); + } + + template + CGPU_EXEC + T det(const Mx_3x3& mx) + { + T val = mx(1, 1)*mx(2, 2)*mx(3, 3) + mx(1, 2)*mx(2, 3)*mx(3, 1) + mx(1, 3)*mx(2, 1)*mx(3, 2); + val -= mx(1, 3)*mx(2, 2)*mx(3, 1) + mx(1, 2)*mx(2, 1)*mx(3, 3) + mx(1, 1)*mx(2, 3)*mx(3, 2); + + return val; + } + + template + CGPU_EXEC + Mx_3x3 inv(const Mx_3x3& mx) + { + Mx_3x3 mx_inv; + + mx_inv(1, 1) = mx(2, 2)*mx(3, 3) - mx(2, 3)*mx(3, 2); + mx_inv(2, 1) = mx(2, 3)*mx(3, 1) - mx(2, 1)*mx(3, 3); + mx_inv(3, 1) = mx(2, 1)*mx(3, 2) - mx(2, 2)*mx(3, 1); + + mx_inv(1, 2) = mx(1, 3)*mx(3, 2) - mx(1, 2)*mx(3, 3); + mx_inv(2, 2) = mx(1, 1)*mx(3, 3) - mx(1, 3)*mx(3, 1); + mx_inv(3, 2) = mx(1, 2)*mx(3, 1) - mx(1, 1)*mx(3, 2); + + mx_inv(1, 3) = mx(1, 2)*mx(2, 3) - mx(1, 3)*mx(2, 2); + mx_inv(3, 3) = mx(1, 1)*mx(2, 2) - mx(1, 2)*mx(2, 1); + mx_inv(2, 3) = mx(1, 3)*mx(2, 1) - mx(1, 1)*mx(2, 3); + + return mx_inv/det(mx); + } +} + +/* binary operators */ +namespace mt +{ + template > + CGPU_EXEC + Mx_3x3 operator+(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3], + lhs[4] + rhs[4], lhs[5] + rhs[5], lhs[6] + rhs[6], lhs[7] + rhs[7], lhs[8] + rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator+(const Mx_3x3& lhs, const U& rhs) + { + return {lhs[0] + rhs, lhs[1] + rhs, lhs[2] + rhs, lhs[3] + rhs, + lhs[4] + rhs, lhs[5] + rhs, lhs[6] + rhs, lhs[7] + rhs, lhs[8] + rhs}; + } + + template > + CGPU_EXEC + Mx_3x3 operator+(const T& lhs, const Mx_3x3& rhs) + { + return {lhs + rhs[0], lhs + rhs[1], lhs + rhs[2], lhs + rhs[3], + lhs + rhs[4], lhs + rhs[5], lhs + rhs[6], lhs + rhs[7], lhs + rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator-(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3], + lhs[4] - rhs[4], lhs[5] - rhs[5], lhs[6] - rhs[6], lhs[7] - rhs[7], lhs[8] - rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator-(const Mx_3x3& lhs, const U& rhs) + { + return {lhs[0] - rhs, lhs[1] - rhs, lhs[2] - rhs, lhs[3] - rhs, + lhs[4] - rhs, lhs[5] - rhs, lhs[6] - rhs, lhs[7] - rhs, lhs[8] - rhs}; + } + + template > + CGPU_EXEC + Mx_3x3 operator-(const T& lhs, const Mx_3x3& rhs) + { + return {lhs - rhs[0], lhs - rhs[1], lhs - rhs[2], lhs - rhs[3], + lhs - rhs[4], lhs - rhs[5], lhs - rhs[6], lhs - rhs[7], lhs - rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator*(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + Mx_3x3 mx; + + mx[0] = lhs[0]*rhs[0] + lhs[3]*rhs[1] + lhs[6]*rhs[2]; + mx[1] = lhs[1]*rhs[0] + lhs[4]*rhs[1] + lhs[7]*rhs[2]; + mx[2] = lhs[2]*rhs[0] + lhs[5]*rhs[1] + lhs[8]*rhs[2]; + + mx[3] = lhs[0]*rhs[3] + lhs[3]*rhs[4] + lhs[6]*rhs[5]; + mx[4] = lhs[1]*rhs[3] + lhs[4]*rhs[4] + lhs[7]*rhs[5]; + mx[5] = lhs[2]*rhs[3] + lhs[5]*rhs[4] + lhs[8]*rhs[5]; + + mx[6] = lhs[0]*rhs[6] + lhs[3]*rhs[7] + lhs[6]*rhs[8]; + mx[7] = lhs[1]*rhs[6] + lhs[4]*rhs[7] + lhs[7]*rhs[8]; + mx[8] = lhs[2]*rhs[6] + lhs[5]*rhs[7] + lhs[8]*rhs[8]; + + return mx; + } + + template > + CGPU_EXEC + Mx_3x3 operator*(const Mx_3x3& lhs, const U& rhs) + { + return {lhs[0]*rhs, lhs[1]*rhs, lhs[2]*rhs, lhs[3]*rhs, + lhs[4]*rhs, lhs[5]*rhs, lhs[6]*rhs, lhs[7]*rhs, lhs[8]*rhs}; + } + + template > + CGPU_EXEC + Mx_3x3 operator*(const T& lhs, const Mx_3x3& rhs) + { + return {lhs*rhs[0], lhs*rhs[1], lhs*rhs[2], lhs*rhs[3], + lhs*rhs[4], lhs*rhs[5], lhs*rhs[6], lhs*rhs[7], lhs*rhs[8]}; + } + + template > + CGPU_EXEC + R_3d operator*(const Mx_3x3& lhs, const R_3d& rhs) + { + return {lhs[0]*rhs.x + lhs[3]*rhs.y + lhs[6]*rhs.z, + lhs[1]*rhs.x + lhs[4]*rhs.y + lhs[7]*rhs.z, + lhs[2]*rhs.x + lhs[5]*rhs.y + lhs[8]*rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator*(const R_3d& lhs, const Mx_3x3& rhs) + { + return {lhs.x*rhs[0] + lhs.y*rhs[1] + lhs.z*rhs[2], + lhs.x*rhs[3] + lhs.y*rhs[4] + lhs.z*rhs[5], + lhs.x*rhs[6] + lhs.y*rhs[7] + lhs.z*rhs[8]}; + } + + template > + CGPU_EXEC + Mx_3x3 operator/(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return lhs*inv(rhs); + } + + template > + CGPU_EXEC + Mx_3x3 operator/(const Mx_3x3& lhs, const U& rhs) + { + return {fcn_div(lhs[0], rhs), fcn_div(lhs[1], rhs), fcn_div(lhs[2], rhs), fcn_div(lhs[3], rhs), + fcn_div(lhs[4], rhs), fcn_div(lhs[5], rhs), fcn_div(lhs[6], rhs), fcn_div(lhs[7], rhs), fcn_div(lhs[8], rhs)}; + } + + template > + CGPU_EXEC + Mx_3x3 operator/(const T& lhs, const Mx_3x3& rhs) + { + return {fcn_div(lhs, rhs[0]), fcn_div(lhs, rhs[1]), fcn_div(lhs, rhs[2]), fcn_div(lhs, rhs[3]), + fcn_div(lhs, rhs[4]), fcn_div(lhs, rhs[5]), fcn_div(lhs, rhs[6]), fcn_div(lhs, rhs[7]), fcn_div(lhs, rhs[8])}; + } + + template > + CGPU_EXEC + Mx_3x3 fmin(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {::fmin(lhs[0], rhs[0]), ::fmin(lhs[1], rhs[1]), ::fmin(lhs[2], rhs[2]), ::fmin(lhs[3], rhs[3]), + ::fmin(lhs[4], rhs[4]), ::fmin(lhs[5], rhs[5]), ::fmin(lhs[6], rhs[6]), ::fmin(lhs[7], rhs[7]), ::fmin(lhs[8], rhs[8])}; + } + + template > + CGPU_EXEC + Mx_3x3 fmax(const Mx_3x3& lhs, const Mx_3x3& rhs) + { + return {::fmax(lhs[0], rhs[0]), ::fmax(lhs[1], rhs[1]), ::fmax(lhs[2], rhs[2]), ::fmax(lhs[3], rhs[3]), + ::fmax(lhs[4], rhs[4]), ::fmax(lhs[5], rhs[5]), ::fmax(lhs[6], rhs[6]), ::fmax(lhs[7], rhs[7]), ::fmax(lhs[8], rhs[8])}; + } +} + +/* traits */ +namespace mt +{ + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_mx_3x3_f64 = std::initializer_list>; +} + +/* other operators */ +namespace mt +{ + template + CGPU_EXEC + Mx_3x3 fcn_rot_mx_3d(const T& theta, const R_3d& u0) + { + T alpha = T(1)-cos(theta); + alpha = fcn_is_zero(alpha)?0:alpha; + T beta = sin(theta); + beta = fcn_is_zero(beta)?0:beta; + + return {T(1) + alpha*(u0.x*u0.x-T(1)), u0.y*u0.x*alpha + u0.z*beta, u0.z*u0.x*alpha - u0.y*beta, + u0.x*u0.y*alpha - u0.z*beta, T(1) + alpha*(u0.y*u0.y-1), u0.z*u0.y*alpha + u0.x*beta, + u0.x*u0.z*alpha + u0.y*beta, u0.y*u0.z*alpha - u0.x*beta, T(1) + alpha*(u0.z*u0.z-1)}; + } +} \ No newline at end of file diff --git a/src/detail/ptc_atom.inl b/src/detail/ptc_atom.inl new file mode 100755 index 00000000..daf2bf60 --- /dev/null +++ b/src/detail/ptc_atom.inl @@ -0,0 +1,739 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_atom.h" + +/* template Ptc_s_Atom */ +namespace mt +{ + template + Ptc_s_Atom::Ptc_s_Atom():Z(0), Ptc_s_3d_0(), sigma(0), occ(0), tag(0), charge(0) {}; + + template + Ptc_s_Atom::Ptc_s_Atom(const dt_int32& Z, const T& x, const T& y, const T& z, + dt_float32 sigma, dt_float32 occ, dt_int32 tag, dt_int32 charge): + Z(Z), Ptc_s_3d_0(x, y, z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + template + Ptc_s_Atom::Ptc_s_Atom(const dt_int32& Z, const R_3d& r, + dt_float32 sigma, dt_float32 occ, dt_int32 tag, dt_int32 charge): + Z(Z), Ptc_s_3d_0(r.x, r.y, r.z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + /* constructor by pointer */ + template + template + Ptc_s_Atom::Ptc_s_Atom(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol) + { + const auto ip = icol*n_r + idx; + + Z = dt_int32(v[ip + 0*n_r]); // atomic number + this->x = (n_c>1)?T(v[ip + 1*n_r]):T(0); // x-position + this->y = (n_c>2)?T(v[ip + 2*n_r]):T(0); // y-position + this->z = (n_c>3)?T(v[ip + 3*n_r]):T(0); // z-position + + sigma = (n_c>4)?dt_float32(v[ip + 4*n_r]):c_dflt_rms3d; // standard deviation + occ = (n_c>5)?dt_float32(v[ip + 5*n_r]):c_dflt_occ; // occupancy + tag = (n_c>6)?dt_int32(v[ip + 6*n_r]):c_dflt_tag; // tag + charge = (n_c>7)?dt_int32(v[ip + 7*n_r]):c_dflt_charge; // charge + } + + /* copy constructor */ + template + Ptc_s_Atom::Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /* converting constructor */ + template + template + Ptc_s_Atom::Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Ptc_s_Atom& Ptc_s_Atom::operator=(const Ptc_s_Atom& ptc_s) + { + if (this != &ptc_s) + { + Z = ptc_s.Z; + this->x = ptc_s.x; + this->y = ptc_s.y; + this->z = ptc_s.z; + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + + return *this; + } + + /* converting assignment operator */ + template + template + Ptc_s_Atom& Ptc_s_Atom::operator=(const Ptc_s_Atom& ptc_s) + { + assign(ptc_s); + + return *this; + } + + template + template + void Ptc_s_Atom::assign(const Ptc_s_Atom& ptc_s) + { + if ((void*)this != (void*)&ptc_s) + { + Z = ptc_s.Z; + this->x = T(ptc_s.x); + this->y = T(ptc_s.y); + this->z = T(ptc_s.z); + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + } +} + +/* template Ptc_Atom */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Ptc_Atom::Ptc_Atom(): Ptc_R_3d(), cols_used(4), Z_lim(), sigma_lim(), occ_lim(), tag_lim(), charge_lim() {} + + template + template + Ptc_Atom::Ptc_Atom(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy, dt_bool b_statistic) + { + set_ptc(ptc, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + template + Ptc_Atom::Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + template + Ptc_Atom::Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* assignment operator */ + template + Ptc_Atom& Ptc_Atom::operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + template + Ptc_Atom& Ptc_Atom::operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + template + template + void Ptc_Atom::assign(const Ptc_Atom& ptc) + { + if ((void*)this != (void*)&ptc) + { + cols_used = ptc.cols_used; + + Z = ptc.Z; + + Ptc_R_3d::assign(ptc); + + sigma = ptc.sigma; + occ = ptc.occ; + tag = ptc.tag; + charge = ptc.charge; + + Z_lim = ptc.Z_lim; + sigma_lim = ptc.sigma_lim; + occ_lim = ptc.occ_lim; + tag_lim = ptc.tag_lim; + charge_lim = ptc.charge_lim; + } + } + + /***************************************************************************************/ + template + Ptc_Atom::size_type Ptc_Atom::cols() const + { + return 8; + } + + template + void Ptc_Atom::clear() + { + cols_used = 4; + + Z.clear(); + + Ptc_R_3d::clear(); + + sigma.clear(); + occ.clear(); + tag.clear(); + charge.clear(); + + Z_lim = 0; + sigma_lim = 0; + occ_lim = 0; + tag_lim = 0; + charge_lim = 0; + } + + template + void Ptc_Atom::resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.resize(new_size); + + Ptc_R_3d::resize(new_size); + + if (cols_used>4) + sigma.resize(new_size); + + if (cols_used>5) + occ.resize(new_size); + + if (cols_used>6) + tag.resize(new_size); + + if (cols_used>7) + charge.resize(new_size); + } + + template + void Ptc_Atom::reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.reserve(new_size); + + Ptc_R_3d::reserve(new_size); + + if (cols_used>4) + sigma.reserve(new_size); + + if (cols_used>5) + occ.reserve(new_size); + + if (cols_used>6) + tag.reserve(new_size); + + if (cols_used>7) + charge.reserve(new_size); + } + + template + void Ptc_Atom::shrink_to_fit() + { + Z.shrink_to_fit(); + + Ptc_R_3d::shrink_to_fit(); + + sigma.shrink_to_fit(); + occ.shrink_to_fit(); + tag.shrink_to_fit(); + charge.shrink_to_fit(); + } + + template + void Ptc_Atom::push_back(const Ptc_s& ptc_s) + { + Z.push_back(ptc_s.Z); // atomic number + + Ptc_R_3d::push_back(ptc_s); // xyz + + if (cols_used>4) + sigma.push_back(ptc_s.sigma); // standard deviation + + if (cols_used>5) + occ.push_back(ptc_s.occ); // occupancy + + if (cols_used>6) + tag.push_back(abs(ptc_s.tag)); // tag + + if (cols_used>7) + charge.push_back(ptc_s.charge); // charge + } + + template + dt_float32 Ptc_Atom::get_sigma(const size_type& ia) const + { + return (cols_used>4)?sigma[ia]:c_dflt_rms3d; // standard deviation + } + + template + dt_float32 Ptc_Atom::get_occ(const size_type& ia) const + { + return (cols_used>5)?occ[ia]:c_dflt_occ; // occupancy + } + + template + dt_int32 Ptc_Atom::get_tag(const size_type& ia) const + { + return (cols_used>6)?tag[ia]:c_dflt_tag; // tag + } + + template + dt_int32 Ptc_Atom::get_charge(const size_type& ia) const + { + return (cols_used>7)?charge[ia]:c_dflt_charge; // charge + } + + template + Ptc_Atom::Ptc_s Ptc_Atom::get(const size_type& ia) const + { + return {Z[ia], this->x[ia], this->y[ia], this->z[ia], get_sigma(ia), get_occ(ia), get_tag(ia), get_charge(ia)}; + } + + template + void Ptc_Atom::set(const size_type& ia, const Ptc_s& ptc_s) + { + Z[ia] = ptc_s.Z; // atomic number + + Ptc_R_3d::set(ia, ptc_s); // xyz + + if (cols_used>4) // standard deviation + sigma[ia] = ptc_s.sigma; + + if (cols_used>5) // occupancy + occ[ia] = ptc_s.occ; + + if (cols_used>6) // tag + tag[ia] = ptc_s.tag; + + if (cols_used>7) // charge + charge[ia] = ptc_s.charge; + } + + template + template + void Ptc_Atom::set_ptc(const Ptc_Atom& ptc, dt_bool pbc_xy, dt_bool b_statistic) + { + clear(); + cols_used = ptc.cols_used; + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + template + void Ptc_Atom::set_ptc(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy, dt_bool b_statistic) + { + clear(); + cols_used = ptc.s1_32(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, 0, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + template + dt_int32 Ptc_Atom::cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0, dt_int32 is_e) + { + is_e = min(is_e, cols_used); + + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, this->size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), Z.data(), n_data); // atomic number + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->x.data(), n_data); // x-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->y.data(), n_data); // y-position + + if (fcn_chk_bound(3, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->z.data(), n_data); // z-position + + if (fcn_chk_bound(4, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), sigma.data(), n_data); // standard deviation + + if (fcn_chk_bound(5, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), occ.data(), n_data); // occupancy + + if (fcn_chk_bound(6, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), tag.data(), n_data); // tag + + if (fcn_chk_bound(7, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), charge.data(), n_data); // charge + + return is; + } + + // sort by x + template + void Ptc_Atom::sort_by_x() + { + sort_by_idx(1); + } + + // sort by y + template + void Ptc_Atom::sort_by_y() + { + sort_by_idx(2); + } + + // sort by z + template + void Ptc_Atom::sort_by_z() + { + sort_by_idx(3); + } + + // sort by idx + template + void Ptc_Atom::sort_by_idx(const dt_int32 idx) + { + if (cols_used==4) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + case 3: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<3>()); + } + break; + } + } + else if (cols_used==5) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + case 3: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<3>()); + } + break; + case 4: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<4>()); + } + break; + } + } + else if (cols_used==6) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + case 3: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<3>()); + } + break; + case 4: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<4>()); + } + break; + case 5: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<5>()); + } + break; + } + } + else if (cols_used==7) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + case 3: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<3>()); + } + break; + case 4: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<4>()); + } + break; + case 5: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<5>()); + } + break; + case 6: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<6>()); + } + break; + } + } + else if (cols_used==8) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + case 3: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<3>()); + } + break; + case 4: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<4>()); + } + break; + case 5: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<5>()); + } + break; + case 6: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<6>()); + } + break; + case 7: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<7>()); + } + break; + } + } + } + + /***************************************************************************************/ + template + void Ptc_Atom::get_statistic() + { + if (this->empty()) + { + return; + } + + mt::fcn_minmax_element(Z, Z_lim.x, Z_lim.y); + + Ptc_R_3d::get_statistic(); + + sigma_lim.x = c_dflt_rms3d; + sigma_lim.y = c_dflt_rms3d; + + if (cols_used>4) + { + mt::fcn_minmax_element(sigma, sigma_lim.x, sigma_lim.y); + } + + occ_lim.x = c_dflt_occ; + occ_lim.y = c_dflt_occ; + + if (cols_used>5) + { + mt::fcn_minmax_element(occ, occ_lim.x, occ_lim.y); + } + + tag_lim.x = c_dflt_tag; + tag_lim.y = c_dflt_tag; + + if (cols_used>6) + { + mt::fcn_minmax_element(tag, tag_lim.x, tag_lim.y); + } + + charge_lim.x = c_dflt_charge; + charge_lim.y = c_dflt_charge; + + if (cols_used>7) + { + mt::fcn_minmax_element(tag, charge_lim.x, charge_lim.y); + } + + this->bs.z = ::fmax(this->sz.z, this->bs.z); + } + + // max z value within a tag + template + void Ptc_Atom::minmax_z_by_region(const T& tag_v, T& z_min, T& z_max) + { + z_min = 1e20; + z_max = -1e20; + for(auto iz = 0; iz < this->size(); iz++) + { + if (tag[iz]==tag_v) + { + z_max = ::fmax(z_max, this->z[iz]); + z_min = ::fmin(z_min, this->z[iz]); + } + } + } + + template + void Ptc_Atom::remove_ptc_out_z_range(const T& z_0, const T& z_e) + { + mt::remove_ptc_out_z_range(z_0, z_e, *this); + } +} + +/* fcns */ +namespace mt +{ + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& ptc) + { + dt_int32 ia_z = 0; + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + if (mt::fcn_chk_bound(ptc.z[ia], z_0, z_e)) + { + ptc.Z[ia_z] = ptc.Z[ia]; + ptc.x[ia_z] = ptc.x[ia]; + ptc.y[ia_z] = ptc.y[ia]; + ptc.z[ia_z] = ptc.z[ia]; + + if (ptc.cols_used>4) + ptc.sigma[ia_z] = ptc.sigma[ia]; + + if (ptc.cols_used>5) + ptc.occ[ia_z] = ptc.occ[ia]; + + if (ptc.cols_used>6) + ptc.tag[ia_z] = ptc.tag[ia]; + + if (ptc.cols_used>7) + ptc.charge[ia_z] = ptc.charge[ia]; + + ia_z++; + } + } + + ptc.resize(ia_z); + ptc.shrink_to_fit(); + } +} \ No newline at end of file diff --git a/src/detail/ptc_butwth.inl b/src/detail/ptc_butwth.inl new file mode 100755 index 00000000..f47eaaee --- /dev/null +++ b/src/detail/ptc_butwth.inl @@ -0,0 +1,110 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_butwth.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max) + { + set_in_data(r, a, n, radius, r_tap, r_max); + } + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, n, radius, r_tap, r_max, grid); + } + + /* copy constructor */ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Ptc_s_fcn_xd& Ptc_s_fcn_xd::operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, n, radius); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, n, radius, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + template + CGPU_EXEC + T Ptc_s_fcn_xd::eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } +} \ No newline at end of file diff --git a/src/detail/ptc_exp.inl b/src/detail/ptc_exp.inl new file mode 100755 index 00000000..398ba876 --- /dev/null +++ b/src/detail/ptc_exp.inl @@ -0,0 +1,110 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_exp.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max) + { + set_in_data(r, a, beta, r_tap, r_max); + } + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, beta, r_tap, r_max, grid); + } + + /* copy constructor */ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Ptc_s_fcn_xd& Ptc_s_fcn_xd::operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, beta); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, beta, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + template + CGPU_EXEC + T Ptc_s_fcn_xd::eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } +} \ No newline at end of file diff --git a/src/detail/ptc_fermi.inl b/src/detail/ptc_fermi.inl new file mode 100755 index 00000000..b8e80295 --- /dev/null +++ b/src/detail/ptc_fermi.inl @@ -0,0 +1,110 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_fermi.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max) + { + set_in_data(r, a, alpha, radius, r_tap, r_max); + } + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, alpha, radius, r_tap, r_max, grid); + } + + /* copy constructor */ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Ptc_s_fcn_xd& Ptc_s_fcn_xd::operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, alpha, radius); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, alpha, radius, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + template + CGPU_EXEC + T Ptc_s_fcn_xd::eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } +} \ No newline at end of file diff --git a/src/detail/ptc_gauss.inl b/src/detail/ptc_gauss.inl new file mode 100755 index 00000000..36ab1001 --- /dev/null +++ b/src/detail/ptc_gauss.inl @@ -0,0 +1,110 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_gauss.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max) + { + set_in_data(r, a, sigma, r_tap, r_max); + } + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, sigma, r_tap, r_max, grid); + } + + /* copy constructor */ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Ptc_s_fcn_xd& Ptc_s_fcn_xd::operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, sigma); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, sigma, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + template + CGPU_EXEC + T Ptc_s_fcn_xd::eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } +} \ No newline at end of file diff --git a/src/detail/ptc_hann.inl b/src/detail/ptc_hann.inl new file mode 100755 index 00000000..405615fd --- /dev/null +++ b/src/detail/ptc_hann.inl @@ -0,0 +1,110 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_hann.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max) + { + set_in_data(r, a, l, r_tap, r_max); + } + + template + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, l, r_tap, r_max, grid); + } + + /* copy constructor */ + template + CGPU_EXEC + Ptc_s_fcn_xd::Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Ptc_s_fcn_xd& Ptc_s_fcn_xd::operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, l); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + template + void Ptc_s_fcn_xd::set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, l, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + template + CGPU_EXEC + void Ptc_s_fcn_xd::clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + template + CGPU_EXEC + T Ptc_s_fcn_xd::eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } +} \ No newline at end of file diff --git a/src/detail/ptc_r_1d.inl b/src/detail/ptc_r_1d.inl new file mode 100755 index 00000000..b412ad5f --- /dev/null +++ b/src/detail/ptc_r_1d.inl @@ -0,0 +1,467 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_r_1d.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + Ptc_R_xd::Ptc_R_xd(): bs(), x_lim(), r_mean(), r_std(), sz() {} + + template + template + Ptc_R_xd::Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x, dt_bool b_statistic) + { + set_ptc(ptc, icol, bs, pbc_x, b_statistic); + } + + /* copy constructor */ + template + Ptc_R_xd::Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + template + Ptc_R_xd::Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Ptc_R_xd& Ptc_R_xd::operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + template + Ptc_R_xd& Ptc_R_xd::operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + template + void Ptc_R_xd::assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + + x_lim = ptc.x_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + template + dt_shape_st::size_type> Ptc_R_xd::shape() const + { + return {size(), cols(), 1, 1}; + } + + template + typename Ptc_R_xd::size_type Ptc_R_xd::size() const + { + return x.size(); + } + + template + dt_int32 Ptc_R_xd::size_32() const + { + return static_cast(x.size()); + } + + template + typename Ptc_R_xd::size_type Ptc_R_xd::cols() const + { + return 1; + } + + template + dt_bool Ptc_R_xd::empty() const + { + return size() == 0; + } + + template + void Ptc_R_xd::clear() + { + bs = 0; + + x.clear(); + + x_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + template + void Ptc_R_xd::resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + } + + template + void Ptc_R_xd::reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + } + + template + void Ptc_R_xd::shrink_to_fit() + { + x.shrink_to_fit(); + } + + template + void Ptc_R_xd::push_back(const R_1d& r) + { + x.push_back(r); + } + + template + template + void Ptc_R_xd::set_bs(const R_2d& bs) + { + this->bs = bs; + } + + template + R_1d Ptc_R_xd::get(const size_type& ia) const + { + return x[ia]; + } + + template + void Ptc_R_xd::set(const size_type& ia, const R_1d& r) + { + x[ia] = r; + } + + template + R_1d Ptc_R_xd::get_pos(const size_type& ia) const + { + return x[ia]; + } + + template + void Ptc_R_xd::set_pos(const size_type& ia, const R_1d& r) + { + x[ia] = r; + } + + template + template + void Ptc_R_xd::set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_x, dt_bool b_statistic) + { + mt::set_ptc_pbc_xy(ptc, pbc_x, b_statistic, *this); + } + + template + template + void Ptc_R_xd::set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x, dt_bool b_statistic) + { + mt::set_ptc_pbc_xy(ptc, icol, bs, pbc_x, b_statistic, *this); + } + + /* copy data to pointer */ + template + template + dt_int32 Ptc_R_xd::cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0, dt_int32 is_e) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + return is; + } + + // sort by x + template + void Ptc_R_xd::sort_by_x() + { + sort_by_idx(0); + } + + // sort by idx + template + void Ptc_R_xd::sort_by_idx(const dt_int32& idx) + { + auto first = std::begin(this->x); + auto last = std::end(this->x); + + switch(idx) + { + case 0: + { + thrust::sort(x, last, mt::cgpu_fctr::less()); + } + break; + } + } + + /***************************************************************************************/ + template + T Ptc_R_xd::norm_2_pbc_x(const size_type& ia, const R_1d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r = fabs(r); + + r = ::fmin(r, fabs(r-bs)); + + return mt::norm_2(r); + } + + template + T Ptc_R_xd::norm_2_pbc(const size_type& ia, const R_1d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r = fabs(r); + + r = ::fmin(r, fabs(r-bs)); + + return mt::norm_2(r); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia, const R_1d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + template + T Ptc_R_xd::norm_pbc_x(const size_type& ia, const R_1d& r_0) const + { + return ::sqrt(this->norm_2_pbc_x(ia, r_0)); + } + + template + T Ptc_R_xd::norm_pbc(const size_type& ia, const R_1d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + template + T Ptc_R_xd::norm(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + template + T Ptc_R_xd::norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + template + void Ptc_R_xd::get_statistic() + { + mt::fcn_ptc_pos_statistic(*this); + } + + template + void Ptc_R_xd::shift(const R_1d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + template + void Ptc_R_xd::recenter(const R_1d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + template + void Ptc_R_xd::recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + template + void Ptc_R_xd::apply_ltf(const T mx, const R_1d& p) + { + mt::fcn_ptc_pos_apply_ltf(mx, p, *this); + } +} + +/* fcns */ +namespace mt +{ + template + void set_ptc_pbc_x(const Ptc_R_1d& ptc_i, const dt_bool& pbc_x, const dt_bool& b_statistic, Ptc_R_1d& ptc_o) + { + ptc_o.bs = ptc_i.bs; + + if (ptc_i.size()==0) + return; + + if (!pbc_xy) + { + ptc_o = ptc_i; + } + else + { + const U bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < ptc_i.size(); ia++) + { + auto bb_x = fcn_chk_bound(ptc_i.x[ia], U(0), bs_e); + + if (bb_x) + { + ptc_o.push_back(ptc_i.get(ia)); + } + } + + ptc_o.shrink_to_fit(); + } + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + template + void set_ptc_pbc_x(const pVctr_cpu_64& pvctr, const dt_int64& icol, const R_1d& bs, const dt_bool& pbc_x, const dt_bool& b_statistic, Ptc_R_1d& ptc_o) + { + ptc_o.bs = bs; + + if (p_ptc.empty()) + return; + + const auto s_0 = p_ptc.s0(); + const auto s_1 = p_ptc.s1(); + + if (!pbc_xy) + { + for(dt_int64 ia = 0; ia < s_0; ia++) + { + ptc_o.push_back(Ptc_s(p_ptc.data(), s_0, s_1, ia, icol)); + } + } + else + { + auto bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < s_0; ia++) + { + auto r = pvctr(ia, icol); + + if (bb_x) + { + ptc_o.push_back(r); + } + } + } + + ptc_o.shrink_to_fit(); + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + template + void fcn_ptc_pos_statistic(Ptc_R_1d& ptc) + { + if (ptc.empty()) + { + return; + } + + mt::fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + + mt::fcn_mean_std(ptc.x, ptc.r_mean, ptc.r_std); + + ptc.sz = ptc.x_lim.y - ptc.x_lim.x; + } + + template + void fcn_ptc_pos_shift(const R_1d& r_sft, Ptc_R_1d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_1d& bs, Ptc_R_1d& ptc) + { + const R_1d r_sft = (bs-ptc.sz)/T(2) - ptc.x_lim.x; + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const T& mx, const R_1d& p, Ptc_R_1d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r; + } + + fcn_ptc_pos_statistic(ptc); + } +} diff --git a/src/detail/ptc_r_2d.inl b/src/detail/ptc_r_2d.inl new file mode 100755 index 00000000..bf870c4f --- /dev/null +++ b/src/detail/ptc_r_2d.inl @@ -0,0 +1,452 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_r_2d.h" + +/* template specialization 2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Ptc_R_xd::Ptc_R_xd(): bs(), x_lim(), y_lim(), r_mean(), r_std(), sz() {} + + template + template + Ptc_R_xd::Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy, dt_bool b_statistic) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + template + Ptc_R_xd::Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + template + Ptc_R_xd::Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Ptc_R_xd& Ptc_R_xd::operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + template + Ptc_R_xd& Ptc_R_xd::operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + template + void Ptc_R_xd::assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + template + dt_shape_st:: size_type> Ptc_R_xd::shape() const + { + return {size(), cols(), 1, 1}; + } + + template + typename Ptc_R_xd::size_type Ptc_R_xd::size() const + { + return x.size(); + } + + template + dt_int32 Ptc_R_xd::size_32() const + { + return static_cast(x.size()); + } + + template + typename Ptc_R_xd::size_type Ptc_R_xd::cols() const + { + return 2; + } + + template + dt_bool Ptc_R_xd::empty() const + { + return size() == 0; + } + + template + void Ptc_R_xd::clear() + { + bs = 0; + + x.clear(); + y.clear(); + + x_lim = 0; + y_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + template + void Ptc_R_xd::resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + } + + template + void Ptc_R_xd::reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + } + + template + void Ptc_R_xd::shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + } + + template + void Ptc_R_xd::push_back(const R_2d& r) + { + x.push_back(r.x); + y.push_back(r.y); + } + + template + template + void Ptc_R_xd::set_bs(const R_2d& bs) + { + this->bs = bs; + } + + template + R_2d Ptc_R_xd::get(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + template + void Ptc_R_xd::set(const size_type& ia, const R_2d& r) + { + x[ia] = r.x; + y[ia] = r.y; + } + + template + R_2d Ptc_R_xd::get_pos(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + template + void Ptc_R_xd::set_pos(const size_type& ia, const R_2d& r) + { + x[ia] = r.x; + y[ia] = r.y; + } + + template + template + void Ptc_R_xd::set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy, dt_bool b_statistic) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + template + void Ptc_R_xd::set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy, dt_bool b_statistic) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + template + dt_int32 Ptc_R_xd::cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0, dt_int32 is_e) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + return is; + } + + // sort by x + template + void Ptc_R_xd::sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + template + void Ptc_R_xd::sort_by_y() + { + sort_by_idx(1); + } + + // sort by idx + template + void Ptc_R_xd::sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y); + auto last = fcn_mkzipiter_end(this->x, this->y); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + } + } + + /***************************************************************************************/ + template + T Ptc_R_xd::norm_2_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = ::fabs(r.x); + r.y = ::fabs(r.y); + + r.x = ::fmin(r.x, ::fabs(r.x-bs.x)); + r.y = ::fmin(r.y, ::fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + template + T Ptc_R_xd::norm_2_pbc(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia, const R_2d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia, const T& x, const T& y) const + { + return mt::norm_2(get_pos(ia) - R_2d(x, y)); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + template + T Ptc_R_xd::norm_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + template + T Ptc_R_xd::norm_pbc(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + template + T Ptc_R_xd::norm(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + template + T Ptc_R_xd::norm(const size_type& ia, const T& x, const T& y) const + { + return ::sqrt(this->norm_2(ia, x, y)); + } + + template + T Ptc_R_xd::norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + template + void Ptc_R_xd::get_statistic() + { + mt::fcn_ptc_pos_statistic(*this); + } + + template + void Ptc_R_xd::shift(const R_2d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + template + void Ptc_R_xd::recenter(const R_2d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + template + void Ptc_R_xd::recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + template + void Ptc_R_xd::apply_ltf(const Mx_2x2& mx, const R_2d& p) + { + mt::fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + template + void Ptc_R_xd::rotate(const T& theta, const R_2d& p) + { + mt::fcn_ptc_pos_rotate(theta, p, *this); + } +} + +/* fcns 2d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_2d& ptc) + { + if (ptc.empty()) + { + return; + } + + mt::fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + mt::fcn_minmax_element(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + + mt::fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + mt::fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + + ptc.sz = R_2d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_R_2d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_R_2d& ptc) + { + const R_2d r_sft = (bs-ptc.sz)/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_R_2d& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_R_2d& ptc) + { + const auto Rm = fcn_rot_mx_2d(theta); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } +} \ No newline at end of file diff --git a/src/detail/ptc_r_3d.inl b/src/detail/ptc_r_3d.inl new file mode 100755 index 00000000..9ef2a552 --- /dev/null +++ b/src/detail/ptc_r_3d.inl @@ -0,0 +1,509 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "ptc_r_3d.h" + +/* template specialization 3d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Ptc_R_xd::Ptc_R_xd(): bs(), x_lim(), y_lim(), z_lim(), r_mean(), r_std(), sz() {} + + template + template + Ptc_R_xd::Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy, dt_bool b_statistic) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + template + Ptc_R_xd::Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + template + Ptc_R_xd::Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Ptc_R_xd& Ptc_R_xd::operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + template + Ptc_R_xd& Ptc_R_xd::operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + template + void Ptc_R_xd::assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + z = ptc.z; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + z_lim = ptc.z_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + template + dt_shape_st::size_type> Ptc_R_xd::shape() const + { + return {size(), cols(), 1, 1}; + } + + template + typename Ptc_R_xd::size_type Ptc_R_xd::size() const + { + return x.size(); + } + + template + dt_int32 Ptc_R_xd::size_32() const + { + return static_cast(x.size()); + } + + template + typename Ptc_R_xd::size_type Ptc_R_xd::cols() const + { + return 3; + } + + template + dt_bool Ptc_R_xd::empty() const + { + return size() == 0; + } + + template + void Ptc_R_xd::clear() + { + bs = 0; + + x.clear(); + y.clear(); + z.clear(); + + x_lim = 0; + y_lim = 0; + z_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + template + void Ptc_R_xd::resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + z.resize(new_size); + } + + template + void Ptc_R_xd::reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + z.reserve(new_size); + } + + template + void Ptc_R_xd::shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + z.shrink_to_fit(); + } + + template + void Ptc_R_xd::push_back(const R_3d& r) + { + x.push_back(r.x); + y.push_back(r.y); + z.push_back(r.z); + } + + template + template + void Ptc_R_xd::set_bs(const R_3d& bs) + { + this->bs = bs; + } + + template + R_3d Ptc_R_xd::get(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + template + void Ptc_R_xd::set(const size_type& ia, const R_3d& r) + { + x[ia] = r.x; + y[ia] = r.y; + z[ia] = r.z; + } + + template + R_3d Ptc_R_xd::get_pos(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + template + void Ptc_R_xd::set_pos(const size_type& ia, const R_3d& r) + { + x[ia] = r.x; + y[ia] = r.y; + z[ia] = r.z; + } + + template + template + void Ptc_R_xd::set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy, dt_bool b_statistic) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + template + void Ptc_R_xd::set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy, dt_bool b_statistic) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + template + dt_int32 Ptc_R_xd::cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0, dt_int32 is_e) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), z.data(), n_data); // z-position + + return is; + } + + // sort by x + template + void Ptc_R_xd::sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + template + void Ptc_R_xd::sort_by_y() + { + sort_by_idx(1); + } + + // sort by z + template + void Ptc_R_xd::sort_by_z() + { + sort_by_idx(2); + } + + // sort by idx + template + void Ptc_R_xd::sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(this->x, this->y, this->z); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + } + } + + /***************************************************************************************/ + template + T Ptc_R_xd::norm_2_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + template + T Ptc_R_xd::norm_2_pbc(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + r.z = fabs(r.z); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + r.z = ::fmin(r.z, fabs(r.y-bs.z)); + + return mt::norm_2(r); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia, const R_3d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia, const T& x, const T& y, const T& z) const + { + return mt::norm_2(get_pos(ia) - R_3d(x, y, z)); + } + + template + T Ptc_R_xd::norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + template + T Ptc_R_xd::norm_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + template + T Ptc_R_xd::norm_pbc(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + template + T Ptc_R_xd::norm(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + template + T Ptc_R_xd::norm(const size_type& ia, const T& x, const T& y, const T& z) const + { + return ::sqrt(this->norm_2(ia, x, y, z)); + } + + template + T Ptc_R_xd::norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + template + void Ptc_R_xd::get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + template + void Ptc_R_xd::shift(const R_3d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + template + void Ptc_R_xd::recenter(const R_3d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + template + void Ptc_R_xd::recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + template + void Ptc_R_xd::recenter_xy(const R_2d& bs) + { + mt::fcn_ptc_pos_recenter_xy(bs, *this); + } + + template + void Ptc_R_xd::recenter_xy() + { + mt::fcn_ptc_pos_recenter_xy({bs.x, bs.y}, *this); + } + + template + void Ptc_R_xd::apply_ltf(const Mx_3x3& mx, const R_3d& p) + { + mt::fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + template + void Ptc_R_xd::rotate(const T& theta, const R_3d& u_0, const R_3d& p) + { + mt::fcn_ptc_pos_rotate(theta, u_0, p, *this); + } +} + +/* fcns 3d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_3d& ptc) + { + if (ptc.empty()) + { + return; + } + + mt::fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + mt::(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + mt::(ptc.z, ptc.z_lim.x, ptc.z_lim.y); + + mt::fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + mt::fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + mt::fcn_mean_std(ptc.z, ptc.r_mean.z, ptc.r_std.z); + + ptc.sz = R_3d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x, ptc.z_lim.y - ptc.z_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_3d& r_sft, Ptc_R_3d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + ptc.z[ia] += r_sft.z; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_R_3d& ptc) + { + const R_3d r_sft = (bs-ptc.sz)/T(2) - R_3d(ptc.x_lim.x, ptc.y_lim.x, ptc.z_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_R_3d& ptc) + { + const R_2d r_sft = (bs-R_2d(ptc.sz.x, ptc.sz.y))/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift({r_sft.x, r_sft.y, T(0)}, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_R_3d& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_R_3d& ptc) + { + const auto Rm = fcn_rot_mx_3d(theta, u_0); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } +} + diff --git a/src/detail/pvctr.inl b/src/detail/pvctr.inl new file mode 100755 index 00000000..ce434b39 --- /dev/null +++ b/src/detail/pvctr.inl @@ -0,0 +1,768 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is destroy software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "pvctr.h" + +/* macro definition grid-block */ +namespace mt +{ +#define FCNS_IMP_GPU_GRID_BLK_VCTR(TDEF, TEVAL) \ + TDEF \ + dim3 TEVAL::d_blk_size() \ + { \ + return fcn_cdb_size(); \ + } \ + \ + TDEF \ + dim3 TEVAL::d_grid_size(const dim3 d_grid_max) \ + { \ + auto grid = fcn_cdg_size(m_size); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_blk_1d() \ + { \ + return fcn_cdb_1d(); \ + } \ + \ + TDEF \ + dim3 TEVAL::d_grid_1d(const dim3 d_grid_max) \ + { \ + auto grid = fcn_cdg_1d(m_s0); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + TDEF \ + D_Grid_Blk TEVAL::d_grid_blk_1d(const dim3 d_grid_max) \ + { \ + return D_Grid_Blk(d_grid_1d(d_grid_max), d_blk_1d()); \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_grid_1d_h(const dim3 d_grid_max) \ + { \ + auto grid = fcn_cdg_1d(m_s0/2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + \ + return grid; \ + } \ + \ + TDEF \ + D_Grid_Blk TEVAL::d_grid_blk_1d_h(const dim3 d_grid_max) \ + { \ + return D_Grid_Blk(d_grid_1d_h(d_grid_max), d_blk_1d()); \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_blk_2d() \ + { \ + return fcn_cdb_2d(); \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_grid_2d(const dim3 d_grid_max) \ + { \ + auto grid = fcn_cdg_2d(m_s0, m_s1); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + \ + return grid; \ + } \ + \ + TDEF \ + D_Grid_Blk TEVAL::d_grid_blk_2d(const dim3 d_grid_max) \ + { \ + return D_Grid_Blk(d_grid_2d(d_grid_max), d_blk_2d()); \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_grid_2d_h(const dim3 d_grid_max) \ + { \ + auto grid = fcn_cdg_2d(m_s0/2, m_s1/2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + \ + return grid; \ + } \ + \ + TDEF \ + D_Grid_Blk TEVAL::d_grid_blk_2d_h(const dim3 d_grid_max) \ + { \ + return D_Grid_Blk(d_grid_2d_h(d_grid_max), d_blk_2d()); \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_blk_3d() \ + { \ + return fcn_cdb_3d(); \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_grid_3d(const dim3 d_grid_max) \ + { \ + auto grid = fcn_cdg_3d(m_s0, m_s1, m_s2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; \ + \ + return grid; \ + } \ + \ + TDEF \ + D_Grid_Blk TEVAL::d_grid_blk_3d(const dim3 d_grid_max) \ + { \ + return D_Grid_Blk(d_grid_3d(d_grid_max), d_blk_3d()); \ + } \ + \ + /***************************************************************************************/ \ + TDEF \ + dim3 TEVAL::d_grid_3d_h(const dim3 d_grid_max) \ + { \ + auto grid = fcn_cdg_3d(m_s0/2, m_s1/2, m_s2/2); \ + \ + grid.x = (d_grid_max.x > 0)?min(d_grid_max.x, grid.x):grid.x; \ + grid.y = (d_grid_max.y > 0)?min(d_grid_max.y, grid.y):grid.y; \ + grid.z = (d_grid_max.z > 0)?min(d_grid_max.z, grid.z):grid.z; \ + \ + return grid; \ + } \ + \ + TDEF \ + D_Grid_Blk TEVAL::d_grid_blk_h(const dim3 d_grid_max) \ + { \ + return D_Grid_Blk(d_grid_3d_h(d_grid_max), d_blk_3d()); \ + } +} + +/* vector pointer */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + pVctr::pVctr(): m_data(nullptr), m_s0(0), m_s1(1), m_s2(1), m_s3(1), + m_size(0) + { + set_picth(); + } + + template + CPU_EXEC + pVctr::pVctr(T* data, dt_shape_64 shape): m_data(data), + m_s0(ST(shape[0])), m_s1(ST(shape[1])), + m_s2(ST(shape[2])), m_s3(ST(shape[3])), m_size(shape_size()) + { + set_picth(); + } + + template + CGPU_EXEC + pVctr::pVctr(T* data, ST s0): m_data(data), + m_s0(s0), m_s1(1), m_s2(1), m_s3(1), m_size(shape_size()) + { + set_picth(); + } + + template + CGPU_EXEC + pVctr::pVctr(T* data, ST s0, ST s1): m_data(data), + m_s0(s0), m_s1(s1), m_s2(1), m_s3(1), m_size(shape_size()) + { + set_picth(); + } + + template + CGPU_EXEC + pVctr::pVctr(T* data, ST s0, ST s1, ST s2): m_data(data), + m_s0(s0), m_s1(s1), m_s2(s2), m_s3(1), m_size(shape_size()) + { + set_picth(); + } + + template + CGPU_EXEC + pVctr::pVctr(T* data, ST s0, ST s1, ST s2, ST s3): m_data(data), + m_s0(s0), m_s1(s1), m_s2(s2), m_s3(s3), m_size(shape_size()) + { + set_picth(); + } + + /************************** constructors *****************************/ + /* copy constructor */ + template + CGPU_EXEC + pVctr::pVctr(const pVctr& pvctr) + { + *this = pvctr; + } + + /* Move constructor */ + template + CGPU_EXEC + pVctr::pVctr(pVctr&& pvctr) + { + *this = std::move(pvctr); + } + + /* Converting constructor */ + template + template + CPU_EXEC + pVctr::pVctr(const pVctr& pvctr) + { + *this = pvctr; + } + + /* constructor from Vctr */ + template + CPU_EXEC + pVctr:: pVctr(const Vctr& vctr) + { + *this = vctr; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + pVctr& pVctr::operator=(const pVctr& pvctr) + { + if (this != &pvctr) + { + m_data = pvctr.m_data; + m_s0 = pvctr.m_s0; + m_s1 = pvctr.m_s1; + m_s2 = pvctr.m_s2; + m_s3 = pvctr.m_s3; + m_size = pvctr.m_size; + m_pitch_s1 = pvctr.m_pitch_s1; + m_pitch_s2 = pvctr.m_pitch_s2; + m_pitch_s3 = pvctr.m_pitch_s3; + } + + return *this; + } + + /* Move assignment operator */ + template + CGPU_EXEC + pVctr& pVctr::operator=(pVctr&& pvctr) + { + if (this != &pvctr) + { + m_data = pvctr.m_data; + m_s0 = pvctr.m_s0; + m_s1 = pvctr.m_s1; + m_s2 = pvctr.m_s2; + m_s3 = pvctr.m_s3; + m_size = pvctr.m_size; + m_pitch_s1 = pvctr.m_pitch_s1; + m_pitch_s2 = pvctr.m_pitch_s2; + m_pitch_s3 = pvctr.m_pitch_s3; + + pvctr.m_data = nullptr; + pvctr.m_s0 = 0; + pvctr.m_s1 = 0; + pvctr.m_s2 = 0; + pvctr.m_s3 = 0; + pvctr.m_size = 0; + pvctr.m_pitch_s1 = 0; + pvctr.m_pitch_s2 = 0; + pvctr.m_pitch_s3 = 0; + } + + return *this; + } + + /* Converting assignment operator */ + template + template + CPU_EXEC + pVctr& pVctr::operator=(const pVctr& pvctr) + { + m_data = pvctr.m_data; + m_s0 = ST(pvctr.m_s0); + m_s1 = ST(pvctr.m_s1); + m_s2 = ST(pvctr.m_s2); + m_s3 = ST(pvctr.m_s3); + m_size = ST(pvctr.m_size); + m_pitch_s1 = ST(pvctr.m_pitch_s1); + m_pitch_s2 = ST(pvctr.m_pitch_s2); + m_pitch_s3 = ST(pvctr.m_pitch_s3); + + return *this; + } + + /* Assignment operator: Vctr -> pVctr */ + template + CPU_EXEC + pVctr& pVctr::operator=(const Vctr& vctr) + { + m_data = vctr.m_data; + m_s0 = ST(vctr.m_s0); + m_s1 = ST(vctr.m_s1); + m_s2 = ST(vctr.m_s2); + m_s3 = ST(vctr.m_s3); + m_size = ST(vctr.m_size); + m_pitch_s1 = ST(vctr.m_pitch_s1); + m_pitch_s2 = ST(vctr.m_pitch_s2); + m_pitch_s3 = ST(vctr.m_pitch_s3); + + return *this; + } + + /**************** user define conversion operators *******************/ + template + pVctr pVctr::ptr_32() const + { + return pVctr(*this); + } + + template + pVctr pVctr::ptr_64() const + { + return pVctr(*this); + } + + template + pVctr::operator pVctr>() const + { + return pVctr>(*this); + } + + template + CGPU_EXEC + ST pVctr::s0() const + { + return m_s0; + } + + template + CGPU_EXEC + ST pVctr::s1() const + { + return m_s1; + } + + template + CGPU_EXEC + ST pVctr::s2() const + { + return m_s2; + } + + template + CGPU_EXEC + ST pVctr::s3() const + { + return m_s3; + } + + template + CGPU_EXEC + dt_int32 pVctr::s0_32() const + { + return static_cast(m_s0); + } + + template + CGPU_EXEC + dt_int32 pVctr::s1_32() const + { + return static_cast(m_s1); + } + + template + CGPU_EXEC + dt_int32 pVctr::s2_32() const + { + return static_cast(m_s2); + } + + template + CGPU_EXEC + dt_int32 pVctr::s3_32() const + { + return static_cast(m_s3); + } + + template + CGPU_EXEC + dt_int64 pVctr::s0_64() const + { + return static_cast(m_s0); + } + + template + CGPU_EXEC + dt_int64 pVctr::s1_64() const + { + return static_cast(m_s1); + } + + template + CGPU_EXEC + dt_int64 pVctr::s2_64() const + { + return static_cast(m_s2); + } + + template + CGPU_EXEC + dt_int64 pVctr::s3_64() const + { + return static_cast(m_s3); + } + + template + CGPU_EXEC + ST pVctr::s0h() const + { + return m_s0/ST(2); + } + + template + CGPU_EXEC + ST pVctr::s1h() const + { + return m_s1/ST(2); + } + + template + CGPU_EXEC + ST pVctr::s2h() const + { + return m_s2/ST(2); + } + + template + CGPU_EXEC + ST pVctr::s3h() const + { + return m_s3/ST(2); + } + + template + dt_shape_st pVctr::shape() const + { + return {m_s0, m_s1, m_s2, m_s3}; + } + + template + dt_shape_st pVctr::shape_2d_trs() const + { + return {m_s1, m_s0, m_s2, m_s3}; + } + + template + CGPU_EXEC + ST pVctr::shape_size() const + { + return m_s0*max(m_s1, ST(1))*max(m_s2, ST(1))*max(m_s3, ST(1)); + } + + template + CGPU_EXEC + ST pVctr::pitch_s1() const + { + return m_pitch_s1; + } + + template + CGPU_EXEC + ST pVctr::pitch_s2() const + { + return m_pitch_s2; + } + + template + CGPU_EXEC + ST pVctr::pitch_s3() const + { + return m_pitch_s3; + } + + template + CGPU_EXEC + ST pVctr::size() const + { + return m_size; + } + + template + CGPU_EXEC + dt_int32 pVctr::size_32() const + { + return static_cast(m_size); + } + + template + CGPU_EXEC + dt_int64 pVctr::size_64() const + { + return static_cast(m_size); + } + + template + iGrid_1d pVctr::igrid_1d() const + { + return {size_32()}; + } + + template + iGrid_2d pVctr::igrid_2d() const + { + return {s1_32(), s0_32()}; + } + + template + iGrid_3d pVctr::igrid_3d() const + { + return {s1_32(), s0_32(), s2_32()}; + } + + template + iGrid_1d_64 pVctr::igrid_1d_64() const + { + return {size_64()}; + } + + template + iGrid_2d_64 pVctr::igrid_2d_64() const + { + return {s1_64(), s0_64()}; + } + + template + iGrid_3d_64 pVctr::igrid_3d_64() const + { + return {s1_64(), s0_64(), s2_64()}; + } + + template + CGPU_EXEC + dt_bool pVctr::empty() const + { + return m_size == 0; + } + + template + CGPU_EXEC + dt_bool pVctr::is_1d() const + { + return (m_s0 == 1) || (m_s1 == 1); + } + + template + CGPU_EXEC + ST pVctr::sub_2_ind(const ST& ix_0) const + { + return ix_0; + } + + template + CGPU_EXEC + ST pVctr::sub_2_ind(const ST& ix_0, const ST& ix_1) const + { + return ix_0 + m_s0*ix_1; + } + + template + CGPU_EXEC + ST pVctr::sub_2_ind(const ST& ix_0, const ST& ix_1, const ST& ix_2) const + { + return ix_0 + m_s0*(ix_1 + m_s1*ix_2); + } + + template + CGPU_EXEC + ST pVctr::sub_2_ind(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) const + { + return ix_0 + m_s0*(ix_1 + m_s1*(ix_2 + m_s2*ix_3)); + } + + template + CGPU_EXEC + T& pVctr::operator[](const ST& iy) + { + return m_data[iy]; + } + + template + CGPU_EXEC + const T& pVctr::operator[](const ST& iy) const + { + return m_data[iy]; + } + + template + CGPU_EXEC + T& pVctr::operator()(const ST& iy) + { + return m_data[iy]; + } + + template + CGPU_EXEC + const T& pVctr::operator()(const ST& iy) const + { + return m_data[iy]; + } + + template + CGPU_EXEC + T& pVctr::operator()(const ST& ix_0, const ST& ix_1) + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + template + CGPU_EXEC + const T& pVctr::operator()(const ST& ix_0, const ST& ix_1) const + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + template + CGPU_EXEC + T& pVctr::operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + template + CGPU_EXEC + const T& pVctr::operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + template + CGPU_EXEC + T& pVctr::operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + template + CGPU_EXEC + const T& pVctr::operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + template + CGPU_EXEC + T* pVctr::begin() + { + return m_data; + } + + template + CGPU_EXEC + const T* pVctr::begin() const + { + return m_data; + } + + template + CGPU_EXEC + T* pVctr::end() + { + return m_data + m_size; + } + + template + CGPU_EXEC + const T* pVctr::end() const + { + return m_data + m_size; + } + + template + CGPU_EXEC + T* pVctr::data() + { + return m_data; + } + + template + CGPU_EXEC + const T* pVctr::data() const + { + return m_data; + } + + template + template + U pVctr::data_cast() + { + return reinterpret_cast(m_data); + } + + template + template + const U pVctr::data_cast() const + { + return reinterpret_cast(m_data); + } + + template + CGPU_EXEC + T pVctr::front() const + { + return m_data[0]; + } + + template + CGPU_EXEC + T pVctr::back() const + { + return m_data[m_size-1]; + } + +#ifdef __CUDACC__ + FCNS_IMP_GPU_GRID_BLK_VCTR(template , pVctr); +#endif + + template + CGPU_EXEC + void pVctr::set_picth() + { + m_pitch_s1 = m_s0*sizeof(T); + m_pitch_s2 = m_pitch_s1*m_s1; + m_pitch_s3 = m_pitch_s2*m_s2; + } +} \ No newline at end of file diff --git a/src/detail/quad_coef_1d.inl b/src/detail/quad_coef_1d.inl new file mode 100755 index 00000000..46488628 --- /dev/null +++ b/src/detail/quad_coef_1d.inl @@ -0,0 +1,209 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "quad_coef_1d.h" + +/* class pQuad_Coef_1d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + pQuad_Coef_1d::pQuad_Coef_1d(): x(nullptr), w(nullptr), m_size(0) {} + + template + CGPU_EXEC + pQuad_Coef_1d::pQuad_Coef_1d(T* x, T* w, const size_type& size): x(x), w(w), m_size(size) {} + + /* copy constructor */ + template + CGPU_EXEC + pQuad_Coef_1d::pQuad_Coef_1d(const pQuad_Coef_1d& pcoef_quad_1d) + { + *this = pcoef_quad_1d; + } + + /* constructor from Quad_Coef_1d */ + template + pQuad_Coef_1d::pQuad_Coef_1d(const Quad_Coef_1d& coef_quad_1d) + { + *this = coef_quad_1d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + pQuad_Coef_1d& pQuad_Coef_1d::operator=(const pQuad_Coef_1d& pcoef_quad_1d) + { + if (this != &pcoef_quad_1d) + { + x = pcoef_quad_1d.x; + w = pcoef_quad_1d.w; + m_size = pcoef_quad_1d.m_size; + } + + return *this; + } + + /* Assignment operator: Quad_Coef_1d -> pQuad_Coef_1d */ + template + CPU_EXEC + pQuad_Coef_1d& pQuad_Coef_1d::operator=(const Quad_Coef_1d& coef_quad_1d) + { + x = coef_quad_1d.x.data(); + w = coef_quad_1d.w.data(); + m_size = size_type(coef_quad_1d.size()); + + return *this; + } + + template + pQuad_Coef_1d::size_type pQuad_Coef_1d::size() const + { + return m_size; + } +} + +/* class Quad_Coef_1d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Quad_Coef_1d::Quad_Coef_1d(const Vctr_cpu& x, const Vctr_cpu& w): x(x), w(w){} + + template + Quad_Coef_1d::Quad_Coef_1d(const dt_init_list_f64& x, const dt_init_list_f64& w): x(x), w(w) {} + + template + Quad_Coef_1d::Quad_Coef_1d(const size_type& new_size) + { + resize(new_size); + } + + template + Quad_Coef_1d::Quad_Coef_1d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + template + Quad_Coef_1d::Quad_Coef_1d(const Quad_Coef_1d& coef_quad_1d) + { + *this = coef_quad_1d; + } + + /* converting constructor */ + template + template + Quad_Coef_1d::Quad_Coef_1d(const Quad_Coef_1d& coef_quad_1d) + { + *this = coef_quad_1d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Quad_Coef_1d& Quad_Coef_1d::operator=(const Quad_Coef_1d& coef_quad_1d) + { + this->assign(coef_quad_1d); + + return *this; + } + + /* converting assignment operator */ + template + template + Quad_Coef_1d& Quad_Coef_1d::operator=(const Quad_Coef_1d& coef_quad_1d) + { + this->assign(coef_quad_1d); + + return *this; + } + + template + template + void Quad_Coef_1d::assign(const Quad_Coef_1d& coef_quad_1d) + { + x.assign(coef_quad_1d.x); + w.assign(coef_quad_1d.w); + } + + /**************** user define conversion operators *******************/ + template + pQuad_Coef_1d Quad_Coef_1d::ptr() const + { + return pQuad_Coef_1d(*this); + } + + /* user define conversion for pointer Vctr */ + template + Quad_Coef_1d::operator pQuad_Coef_1d() const + { + return pQuad_Coef_1d(*this); + } + + template + void Quad_Coef_1d::fill(const T& val_x, const T& val_w) + { + x.fill(val_x); + w.fill(val_w); + } + + template + Quad_Coef_1d::size_type Quad_Coef_1d::size() const + { + return size_type(x.size()); + } + + template + void Quad_Coef_1d::clear() + { + x.clear(); + w.clear(); + } + + template + void Quad_Coef_1d::reserve(const size_type& new_size) + { + x.reserve(new_size); + w.reserve(new_size); + } + + template + void Quad_Coef_1d::resize(const size_type& new_size) + { + x.resize(new_size); + w.resize(new_size); + } + + template + void Quad_Coef_1d::resize(const size_type& new_size, const T& value) + { + x.resize(new_size, value); + w.resize(new_size, value); + } + + template + void Quad_Coef_1d::shrink_to_fit() + { + x.shrink_to_fit(); + w.shrink_to_fit(); + } +} \ No newline at end of file diff --git a/src/detail/quad_coef_2d.inl b/src/detail/quad_coef_2d.inl new file mode 100755 index 00000000..7ebd1990 --- /dev/null +++ b/src/detail/quad_coef_2d.inl @@ -0,0 +1,220 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "quad_coef_2d.h" + +/* class pQuad_Coef_2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + pQuad_Coef_2d::pQuad_Coef_2d(): x(nullptr), y(nullptr), w(nullptr), m_size(0) {} + + template + CGPU_EXEC + pQuad_Coef_2d::pQuad_Coef_2d(T* x, T* y, T* w, const size_type& size): x(x), y(y), w(w), m_size(size) {} + + /* copy constructor */ + template + CGPU_EXEC + pQuad_Coef_2d::pQuad_Coef_2d(const pQuad_Coef_2d& pcoef_quad_2d) + { + *this = pcoef_quad_2d; + } + + /* constructor from Quad_Coef_2d */ + template + pQuad_Coef_2d::pQuad_Coef_2d(const Quad_Coef_2d& coef_quad_2d) + { + *this = coef_quad_2d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + pQuad_Coef_2d& pQuad_Coef_2d::operator=(const pQuad_Coef_2d& pcoef_quad_2d) + { + if (this != &pcoef_quad_2d) + { + x = pcoef_quad_2d.x; + y = pcoef_quad_2d.y; + w = pcoef_quad_2d.w; + m_size = pcoef_quad_2d.m_size; + } + + return *this; + } + + /* Assignment operator: Quad_Coef_2d -> pQuad_Coef_2d */ + template + CPU_EXEC + pQuad_Coef_2d& pQuad_Coef_2d::operator=(Quad_Coef_2d& coef_quad_2d) + { + x = coef_quad_2d.x.data(); + y = coef_quad_2d.y.data(); + w = coef_quad_2d.w.data(); + m_size = size_type(coef_quad_2d.size()); + + return *this; + } + + template + pQuad_Coef_2d::size_type pQuad_Coef_2d::size() const + { + return m_size; + } +} + +/* class Quad_Coef_2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Quad_Coef_2d::Quad_Coef_2d(const Vctr_cpu& x, const Vctr_cpu& y, const Vctr_cpu& w): + x(x), y(y), w(w){} + + template + Quad_Coef_2d::Quad_Coef_2d(const dt_init_list_f64& x, const dt_init_list_f64& y, const dt_init_list_f64& w): + x(x), y(y), w(w) {} + + template + Quad_Coef_2d::Quad_Coef_2d(const size_type& new_size) + { + resize(new_size); + } + + template + Quad_Coef_2d::Quad_Coef_2d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + template + Quad_Coef_2d::Quad_Coef_2d(const Quad_Coef_2d& coef_quad_2d) + { + *this = coef_quad_2d; + } + + /* converting constructor */ + template + template + Quad_Coef_2d::Quad_Coef_2d(const Quad_Coef_2d& coef_quad_2d) + { + *this = coef_quad_2d; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Quad_Coef_2d& Quad_Coef_2d::operator=(const Quad_Coef_2d& coef_quad_2d) + { + this->assign(coef_quad_2d); + + return *this; + } + + /* converting assignment operator */ + template + template + Quad_Coef_2d& Quad_Coef_2d::operator=(const Quad_Coef_2d& coef_quad_2d) + { + this->assign(coef_quad_2d); + + return *this; + } + + template + template + void Quad_Coef_2d::assign(const Quad_Coef_2d& coef_quad_2d) + { + x.assign(coef_quad_2d.x); + y.assign(coef_quad_2d.y); + w.assign(coef_quad_2d.w); + } + + /**************** user define conversion operators *******************/ + template + pQuad_Coef_2d Quad_Coef_2d::ptr() const + { + return pQuad_Coef_2d(*this); + } + + /* user define conversion for pointer Vctr */ + template + Quad_Coef_2d::operator pQuad_Coef_2d() const + { + return pQuad_Coef_2d(*this); + } + + template + void Quad_Coef_2d::fill(const T& val_x, const T& val_y, const T& val_w) + { + x.fill(val_x); + y.fill(val_y); + w.fill(val_w); + } + + template + Quad_Coef_2d::size_type Quad_Coef_2d::size() const + { + return x.size(); + } + + template + void Quad_Coef_2d::clear() + { + x.clear(); + y.clear(); + w.clear(); + } + + template + void Quad_Coef_2d::reserve(const size_type& new_size) + { + x.reserve(new_size); + y.reserve(new_size); + w.reserve(new_size); + } + + template + void Quad_Coef_2d::resize(const size_type& new_size) + { + x.resize(new_size); + y.resize(new_size); + w.resize(new_size); + } + + template + void Quad_Coef_2d::resize(const size_type& new_size, const T& value) + { + x.resize(new_size, value); + y.resize(new_size, value); + w.resize(new_size, value); + } + + template + void Quad_Coef_2d::shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + w.shrink_to_fit(); + } +} \ No newline at end of file diff --git a/src/detail/quad_data.inl b/src/detail/quad_data.inl new file mode 100755 index 00000000..f388e3b6 --- /dev/null +++ b/src/detail/quad_data.inl @@ -0,0 +1,2687 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "quad_data.h" + +namespace mt +{ + template + template + Quad_Data_T::Quad_Data_T(const eQuad_Typ& quad_typ, const dt_int32& n_quad, Quad_Coef_1d& quad, T alpha, T beta, T a, T b) + { + this->operator()(quad_typ, n_quad, quad, alpha, beta, a, b); + } + + template + template + void Quad_Data_T::operator()(const eQuad_Typ& quad_typ, const dt_int32& n_quad, Quad_Coef_1d& quad, T alpha, T beta, T a, T b) + { + Quad_Coef_1d_cpu quad_t(n_quad); + + if (n_quad <= 1) + { + quad.resize(1); + quad.x[0] = 0; + quad.w[0] = 1; + + return; + } + + switch(quad_typ) + { + // Double exponential quadrature + case eqt_tanh_sinh_int_n1_p1: // int_-1^1 f(x) dx + { + T x_min = T(-1) + Epsilon::eps; + T x_max = T(1) - Epsilon::eps; + + nw_tanh_sinh_int_n1_p1(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_exp_sinh_int_0_pinfty: // int_0^infty f(x) dx + { + T x_min = Epsilon::eps; + //T x_max = 225.0; + T x_max = 1e+5; + + nw_exp_sinh_int_0_pinfty(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_exp_exp_int_0_pinfty: // int_0^infty f(x)exp(-x) dx + { + T x_min = Epsilon::eps; + T x_max = 225.0; + + nw_exp_exp_int_0_pinfty(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_sinh_sinh_int_ninfty_pinfty: // int_-infty^infty f(x) dx + { + T x_min = -225.0; + T x_max = 225.0; + + nw_sinh_sinh_int_ninfty_pinfty(quad_t.size(), x_min, x_max, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_fourier_sin_int_0_pinfty: // int_0^infty f(x)sin(wx) dx + { + T tai = 4.0; + nw_fourier_sin_int_0_pinfty(quad_t.size(), tai, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_fourier_cos_int_0_pinfty: // int_0^infty f(x)Cos(wx) dx + { + T tai = 4.0; + nw_fourier_cos_int_0_pinfty(quad_t.size(), tai, quad_t.x.data(), quad_t.w.data()); + } + break; + // smooth functions + case eqt_gauss_legendre_int_n1_p1: // int_-1^1 f(x) dx + { + nw_gauss_legendre_int_n1_p1(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_hermite_x0_int_ninfty_pinfty: // int_-infty^infty f(x) x^0 Exp[-x^2] dx + { + nw_gauss_hermite_x0_int_ninfty_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_hermite_x1_int_ninfty_pinfty: // int_-infty^infty f(x) |x|^1 Exp[-x^2] dx + { + nw_gauss_hermite_x1_int_ninfty_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_hermite_x2_int_ninfty_pinfty: // int_-infty^infty f(x) |x|^2 Exp[-x^2] dx + { + nw_gauss_hermite_x2_int_ninfty_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_x0_int_0_pinfty: // int_0^infty f(x) x^0 Exp[-x] dx + { + nw_gauss_laguerre_x0_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_x1_int_0_pinfty: // int_0^infty f(x) x^1 Exp[-x] dx + { + nw_gauss_laguerre_x1_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_x2_int_0_pinfty: // int_0^infty f(x) x^2 Exp[-x] dx + { + nw_gauss_laguerre_x2_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gauss_laguerre_xi2_int_0_pinfty: // int_0^infty f(x) Exp[-x]/Sqrt[x] dx + { + nw_gauss_laguerre_xi2_int_0_pinfty(quad_t.size(), quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_legendre: // legendre, (a, b) + { + cgqf(1, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_chebyshev: // chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + { + cgqf(2, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_gegenbauer: // gegenbauer, (a, b) ((b-x)*(x-a))^alpha + { + cgqf(3, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_jacobi: // jacobi, (a, b) (b-x)^alpha*(x-a)^beta + { + cgqf(4, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_laguerre: // generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + { + cgqf(5, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_hermite: // generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + { + cgqf(6, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_exponential: // exponential, (a, b) |x-(a+b)/2.0|^alpha + { + cgqf(7, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + case eqt_rational: // rational, (a, inf) (x-a)^alpha*(x+b)^beta + { + cgqf(8, quad_t.size(), alpha, beta, a, b, quad_t.x.data(), quad_t.w.data()); + } + break; + } + + quad.assign(quad_t); + } + + // 1: int_-1^1 f(x) dx + template + void Quad_Data_T::nw_tanh_sinh_int_n1_p1(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](const T& x)->T + { + return asinh(atanh(x)/c_i2pi); + }; + + const auto t_min = get_limit(x_min); + const auto t_max = get_limit(x_max); + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto t_ik = t_min + T(ix)*h; + const auto tt_ix = c_i2pi*sinh(t_ik); + + px[ix] = tanh(tt_ix); + pw[ix] = h*c_i2pi*cosh(t_ik)/::square(cosh(tt_ix)); + } + } + + // 2: int_0^infty f(x) dx + template + void Quad_Data_T::nw_exp_sinh_int_0_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](T x)->T + { + return asinh(log(x)/c_i2pi); + }; + + const auto t_min = get_limit(x_min); + const auto t_max = get_limit(x_max); + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto f = ((ix==0)||(ix==nx-1))?T(0.5):T(1.0); + const auto t_ik = t_min + T(ix)*h; + + px[ix] = exp(c_i2pi*sinh(t_ik)); + pw[ix] = f*h*c_i2pi*cosh(t_ik)*px[ix]; + } + } + + // 3: int_0^infty f(x)exp(-x) dx + template + void Quad_Data_T::nw_exp_exp_int_0_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](T x, T t, dt_int32 n)->T + { + const auto t_s = log(x); + for(auto ix = 0; ix < n; ix++) + { + const auto exp_t = exp(-t); + t = t - (t - exp_t - t_s)/(T(1) + exp_t); + } + return t; + }; + + auto t_min = -log(-log(x_min)); + t_min = get_limit(x_min, t_min, 5); + + auto t_max = log(x_max); + t_max = get_limit(x_max, t_max, 5); + + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto f = ((ix==0)||(ix==nx-1))?T(0.5):T(1.0); + const auto t_ik = t_min + T(ix)*h; + const auto exp_t_ik = exp(-t_ik); + + px[ix] = exp(t_ik-exp_t_ik); + pw[ix] = f*h*px[ix]*(T(1) + exp_t_ik); + } + } + + // 4: int_-infty^infty f(x) dx + template + void Quad_Data_T::nw_sinh_sinh_int_ninfty_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw) + { + auto get_limit = [](T x)->T + { + return asinh(asin(x)/c_i2pi); + }; + + const auto t_min = get_limit(x_min); + const auto t_max = get_limit(x_max); + const auto h = (t_max-t_min)/T(nx-1); + + for(auto ix = 0; ix < nx; ix++) + { + const auto t_ix = t_min + T(ix)*h; + const auto tt_ix = c_i2pi*sinh(t_ix); + + px[ix] = sinh(tt_ix); + pw[ix] = h*c_i2pi*cosh(t_ix)*cosh(tt_ix); + } + } + //1. Ooura, T. & Mori, M. A robust double exponential formula for Fourier-type integrals. J. Comput. Appl. Math. 112, 229–241 (1999). + // 5: int_0^infty f(x)sin(wx) dx + template + void Quad_Data_T::nw_fourier_sin_int_0_pinfty(const dt_int32& nx, const T& ta, T* px, T* pw) + { + const T h = T(2)*ta/T(nx); + const T M = c_pi/h; + const T k = T(6); + + for(auto ix = 0; ix < nx; ix++) + { + auto t_ix = -ta + T(ix+1)*h; + + if (t_ix == 0 ) + { + const auto phi = T(1)/k; + const auto dphi = T(0.5); + px[ix] = M*phi; + pw[ix] = c_pi*dphi*sin(M*phi); + } + else + { + const auto ut = T(1) - exp(-k*sinh(t_ix)); + const auto phi = t_ix/ut; + const auto dphi = (T(1)+(T(1)+k*t_ix*cosh(t_ix))*(ut-T(1)))/(ut*ut); + + px[ix] = M*phi; + pw[ix] = c_pi*dphi*sin(M*phi); + } + } + } + + // 6: int_0^infty f(x)Cos(wx) dx + template + void Quad_Data_T::nw_fourier_cos_int_0_pinfty(const dt_int32& nx, const T& ta, T* px, T* pw) + { + const T h = T(2)*ta/T(nx); + const T M = c_pi/h; + const T k = T(6); + + for(auto ix = 0; ix < nx; ix++) + { + auto t_ix = -ta + (T(ix)+T(0.5))*h; + + if (t_ix == 0 ) + { + const auto phi = T(1)/k; + const auto dphi = T(0.5); + px[ix] = M*phi; + pw[ix] = c_pi*dphi*cos(M*phi); + } + else + { + const auto ut = T(1) - exp(-k*sinh(t_ix)); + const auto phi = t_ix/ut; + const auto dphi = (T(1)+(T(1)+k*t_ix*cosh(t_ix))*(ut-T(1)))/(ut*ut); + px[ix] = M*phi; + pw[ix] = c_pi*dphi*cos(M*phi); + } + } + } + + // 7: int_-1^1 f(x) dx + template + void Quad_Data_T::nw_gauss_legendre_int_n1_p1(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 1; + dt_int32 n_quad = nx; + T alpha = 0; + T beta = 0; + T a = -1.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 8: int_-infty^infty f(x) x^0 Exp[-x^2] dx + template + void Quad_Data_T::nw_gauss_hermite_x0_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 6; + dt_int32 n_quad = nx; + T alpha = 0; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 9: int_-infty^infty f(x) |x|^1 Exp[-x^2] dx + template + void Quad_Data_T::nw_gauss_hermite_x1_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 6; + dt_int32 n_quad = nx; + T alpha = 1; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 9: int_-infty^infty f(x) |x|^2 Exp[-x^2] dx + template + void Quad_Data_T::nw_gauss_hermite_x2_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 6; + dt_int32 n_quad = nx; + T alpha = 2; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 11: int_0^infty f(x) x^0 Exp[-x] dx + template + void Quad_Data_T::nw_gauss_laguerre_x0_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 5; + dt_int32 n_quad = nx; + T alpha = 0; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 12: int_0^infty f(x) x^1 Exp[-x] dx + template + void Quad_Data_T::nw_gauss_laguerre_x1_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 n_quad = nx; + dt_int32 kind = 5; + T alpha = 1; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 13: int_0^infty f(x) x^2 Exp[-x] dx + template + void Quad_Data_T::nw_gauss_laguerre_x2_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + dt_int32 kind = 5; + dt_int32 n_quad = nx; + T alpha = 2; + T beta = 0; + T a = 0.0; + T b = 1.0; + + cgqf(kind, n_quad, alpha, beta, a, b, px, pw); + } + + // 14: int_0^infty f(x) Exp[-x]/Sqrt[x] dx + template + void Quad_Data_T::nw_gauss_laguerre_xi2_int_0_pinfty(const dt_int32& nx, T* px, T* pw) + { + switch(nx) + { + case 2: + px[0] = 2.7525512860841095e-1;pw[0] = 1.6098281800110257e0; + px[1] = 2.7247448713915890e0;pw[1] = 1.6262567089449035e-1; + break; + case 4: + px[0] = 1.4530352150331709e-1;pw[0] = 1.3222940251164826e0; + px[1] = 1.3390972881263614e0;pw[1] = 4.1560465162978376e-1; + px[2] = 3.9269635013582872e0;pw[2] = 3.4155966014826951e-2; + px[3] = 8.5886356890120343e0;pw[3] = 3.9920814442273524e-4; + break; + case 8: + px[0] = 7.4791882596818270e-2;pw[0] = 1.0158589580332275e0; + px[1] = 6.7724908764928915e-1;pw[1] = 5.6129491705706735e-1; + px[2] = 1.9051136350314284e0;pw[2] = 1.6762008279797166e-1; + px[3] = 3.8094763614849071e0;pw[3] = 2.5760623071019947e-2; + px[4] = 6.4831454286271704e0;pw[4] = 1.8645680172483611e-3; + px[5] = 1.0093323675221343e1;pw[5] = 5.4237201850757630e-5; + px[6] = 1.4972627088426393e1;pw[6] = 4.6419616897304213e-7; + px[7] = 2.1984272840962651e1;pw[7] = 5.3096149480223645e-10; + break; + case 16: + px[0] = 3.7962914575313455e-2;pw[0] = 7.5047670518560479e-1; + px[1] = 3.4220015601094768e-1;pw[1] = 5.5491628460505980e-1; + px[2] = 9.5355315539086550e-1;pw[2] = 3.0253946815328497e-1; + px[3] = 1.8779315076960743e0;pw[3] = 1.2091626191182523e-1; + px[4] = 3.1246010507021443e0;pw[4] = 3.5106857663146861e-2; + px[5] = 4.7067267076675872e0;pw[5] = 7.3097806533088562e-3; + px[6] = 6.6422151797414440e0;pw[6] = 1.0725367310559441e-3; + px[7] = 8.9550013377233902e0;pw[7] = 1.0833168123639965e-4; + px[8] = 1.1677033673975957e1;pw[8] = 7.3011702591247521e-6; + px[9] = 1.4851431341801250e1;pw[9] = 3.1483355850911881e-7; + px[10] = 1.8537743178606694e1;pw[10] = 8.1976643295417932e-9; + px[11] = 2.2821300693525208e1;pw[11] = 1.1866582926793277e-10; + px[12] = 2.7831438211328676e1;pw[12] = 8.4300204226528951e-13; + px[13] = 3.3781970488226166e1;pw[13] = 2.3946880341856973e-15; + px[14] = 4.1081666525491202e1;pw[14] = 1.8463473073036584e-18; + px[15] = 5.0777223877537080e1;pw[15] = 1.4621352854768325e-22; + break; + case 24: + px[0] = 2.5437996585689359e-2;pw[0] = 6.2200206075592616e-1; + px[1] = 2.2910231649262433e-1;pw[1] = 5.0792308532951820e-1; + px[2] = 6.3729027873266879e-1;pw[2] = 3.3840894389128221e-1; + px[3] = 1.2517406323627464e0;pw[3] = 1.8364459415857036e-1; + px[4] = 2.0751129098523806e0;pw[4] = 8.0959353969207698e-2; + px[5] = 3.1110524551477130e0;pw[5] = 2.8889923149962199e-2; + px[6] = 4.3642830769353062e0;pw[6] = 8.3060098239551049e-3; + px[7] = 5.8407332713236080e0;pw[7] = 1.9127846396388306e-3; + px[8] = 7.5477046800234544e0;pw[8] = 3.5030086360234566e-4; + px[9] = 9.4940953300264876e0;pw[9] = 5.0571980554969778e-5; + px[10] = 1.1690695926056073e1;pw[10] = 5.6945173834696962e-6; + px[11] = 1.4150586187285759e1;pw[11] = 4.9373179873395010e-7; + px[12] = 1.6889671928527108e1;pw[12] = 3.2450282717915397e-8; + px[13] = 1.9927425875242462e1;pw[13] = 1.5860934990330765e-9; + px[14] = 2.3287932824879917e1;pw[14] = 5.6305930756763382e-11; + px[15] = 2.7001406056472356e1;pw[15] = 1.4093865163091778e-12; + px[16] = 3.1106464709046565e1;pw[16] = 2.3951797309583587e-14; + px[17] = 3.5653703516328212e1;pw[17] = 2.6303192453168170e-16; + px[18] = 4.0711598185543107e1;pw[18] = 1.7460319202373353e-18; + px[19] = 4.6376979557540133e1;pw[19] = 6.3767746470102769e-21; + px[20] = 5.2795432527283630e1;pw[20] = 1.1129154937804570e-23; + px[21] = 6.0206666963057223e1;pw[21] = 7.3700721603013398e-27; + px[22] = 6.9068601975304369e1;pw[22] = 1.1969225386627757e-30; + px[23] = 8.0556280819950406e1;pw[23] = 1.5871103023654473e-35; + break; + case 32: + px[0] = 1.9127510968446856e-2;pw[0] = 5.4275484988260796e-1; + px[1] = 1.7221572414539558e-1;pw[1] = 4.6598957212535609e-1; + px[2] = 4.7875647727748885e-1;pw[2] = 3.4337168469816740e-1; + px[3] = 9.3948321450073428e-1;pw[3] = 2.1699669861237368e-1; + px[4] = 1.5555082314789380e0;pw[4] = 1.1747996392819887e-1; + px[5] = 2.3283376682103970e0;pw[5] = 5.4406257907377837e-2; + px[6] = 3.2598922564569419e0;pw[6] = 2.1512081019758274e-2; + px[7] = 4.3525345293301410e0;pw[7] = 7.2451739570689175e-3; + px[8] = 5.6091034574961513e0;pw[8] = 2.0726581990151553e-3; + px[9] = 7.0329577982838936e0;pw[9] = 5.0196739702612497e-4; + px[10] = 8.6280298574059291e0;pw[10] = 1.0251858271572549e-4; + px[11] = 1.0398891905552624e1;pw[11] = 1.7576998461700718e-5; + px[12] = 1.2350838217714770e1;pw[12] = 2.5166805020623692e-6; + px[13] = 1.4489986690780274e1;pw[13] = 2.9910658734544941e-7; + px[14] = 1.6823405362953694e1;pw[14] = 2.9302506329522187e-8; + px[15] = 1.9359271087268714e1;pw[15] = 2.3472334846430987e-9; + px[16] = 2.2107070382206007e1;pw[16] = 1.5230434500290903e-10; + px[17] = 2.5077856544198053e1;pw[17] = 7.9183555338954479e-12; + px[18] = 2.8284583194970531e1;pw[18] = 3.2566814614194407e-13; + px[19] = 3.1742543790616606e1;pw[19] = 1.0437247453181695e-14; + px[20] = 3.5469961396173283e1;pw[20] = 2.5601867826448761e-16; + px[21] = 3.9488797123368127e1;pw[21] = 4.7037694213516382e-18; + px[22] = 4.3825886369903902e1;pw[22] = 6.3045091330075628e-20; + px[23] = 4.8514583867416048e1;pw[23] = 5.9657255685597023e-22; + px[24] = 5.3597231826148512e1;pw[24] = 3.8234137666012857e-24; + px[25] = 5.9129027934391951e1;pw[25] = 1.5723595577851821e-26; + px[26] = 6.5184426376135782e1;pw[26] = 3.8582071909299337e-29; + px[27] = 7.1868499359551422e1;pw[27] = 5.0993217982259985e-32; + px[28] = 7.9339086528823201e1;pw[28] = 3.1147812492595276e-35; + px[29] = 8.7856119943133525e1;pw[29] = 6.8422760225114810e-39; + px[30] = 9.7916716426062762e1;pw[30] = 3.3594959802163184e-43; + px[31] = 1.1079926894707576e2;pw[31] = 1.1088644990767160e-48; + break; + case 40: + px[0] = 1.5325663331507189e-2;pw[0] = 4.8767170761442366e-1; + px[1] = 1.3796600174102882e-1;pw[1] = 4.3154989254866095e-1; + px[2] = 3.8343384139288653e-1;pw[2] = 3.3787593855180386e-1; + px[3] = 7.5210508353159711e-1;pw[3] = 2.3396146760859843e-1; + px[4] = 1.2445475511131953e0;pw[4] = 1.4320149538368678e-1; + px[5] = 1.8615258453171583e0;pw[5] = 7.7417199829675957e-2; + px[6] = 2.6040079765974233e0;pw[6] = 3.6931502308855776e-2; + px[7] = 3.4731739113527927e0;pw[7] = 1.5528078810799283e-2; + px[8] = 4.4704262206423379e0;pw[8] = 5.7463950661794487e-3; + px[9] = 5.5974030703416056e0;pw[9] = 1.8686353739223537e-3; + px[10] = 6.8559938552704945e0;pw[10] = 5.3295577338670161e-4; + px[11] = 8.2483578563697614e0;pw[11] = 1.3303482483630581e-4; + px[12] = 9.7769463941849785e0;pw[12] = 2.8992888382259350e-5; + px[13] = 1.1444529069317641e1;pw[13] = 5.5014492548024867e-6; + px[14] = 1.3254224828602629e1;pw[14] = 9.0610711317226041e-7; + px[15] = 1.5209538784718065e1;pw[15] = 1.2908925900239279e-7; + px[16] = 1.7314405960671086e1;pw[16] = 1.5845846578300512e-8; + px[17] = 1.9573243448531832e1;pw[17] = 1.6686111852173423e-9; + px[18] = 2.1991012891259404e1;pw[18] = 1.4999439829316549e-10; + px[19] = 2.4573295756577260e1;pw[19] = 1.1446559437004013e-11; + px[20] = 2.7326384629341011e1;pw[20] = 7.3696996403182414e-13; + px[21] = 3.0257394787336121e1;pw[21] = 3.9750416693969613e-14; + px[22] = 3.3374401770413884e1;pw[22] = 1.7818922081332433e-15; + px[23] = 3.6686612696144794e1;pw[23] = 6.5783240287291484e-17; + px[24] = 4.0204582016183319e1;pw[24] = 1.9793057979240198e-18; + px[25] = 4.3940486724615585e1;pw[25] = 4.7956805512357826e-20; + px[26] = 4.7908482506508098e1;pw[26] = 9.2269421491078646e-22; + px[27] = 5.2125172273284642e1;pw[27] = 1.3868239639057759e-23; + px[28] = 5.6610234272577454e1;pw[28] = 1.5970374396346345e-25; + px[29] = 6.1387282639433491e1;pw[29] = 1.3766914087267507e-27; + px[30] = 6.6485076698107068e1;pw[30] = 8.6356346860439419e-30; + px[31] = 7.1939271994415582e1;pw[31] = 3.8059812200638324e-32; + px[32] = 7.7795048292119587e1;pw[32] = 1.1274385558954499e-34; + px[33] = 8.4111230042098140e1;pw[33] = 2.1190293856555058e-37; + px[34] = 9.0967109281657703e1;pw[34] = 2.3384153996394935e-40; + px[35] = 9.8474564473065897e1;pw[35] = 1.3584866032309069e-43; + px[36] = 1.0680170504629888e2;pw[36] = 3.5284114086777935e-47; + px[37] = 1.1622557258080335e2;pw[37] = 3.1343129875498926e-51; + px[38] = 1.2727662323235295e2;pw[38] = 5.7648218162351852e-52; + px[39] = 1.4132130003237776e2;pw[39] = 5.6256581525587782e-50; + break; + case 48: + px[0] = 1.2784572337116694e-2;pw[0] = 4.4654004699506952e-1; + px[1] = 1.1508148358837804e-1;pw[1] = 4.0322602695846852e-1; + px[2] = 3.1978387827943194e-1;pw[2] = 3.2875926119699403e-1; + px[3] = 6.2710953585675593e-1;pw[3] = 2.4196623372503065e-1; + px[4] = 1.0373867221540579e0;pw[4] = 1.6070790016128415e-1; + px[5] = 1.5510561307962492e0;pw[5] = 9.6279813462180107e-2; + px[6] = 2.1686735147948251e0;pw[6] = 5.2000680542488898e-2; + px[7] = 2.8909130466944233e0;pw[7] = 2.5302750225600317e-2; + px[8] = 3.7185714571096889e0;pw[8] = 1.1083262578877953e-2; + px[9] = 4.6525730143474026e0;pw[9] = 4.3662639521934365e-3; + px[10] = 5.6939754224427003e0;pw[10] = 1.5453916433633038e-3; + px[11] = 6.8439767318335151e0;pw[11] = 4.9083618546105323e-4; + px[12] = 8.1039233766453468e0;pw[12] = 1.3970864889083082e-4; + px[13] = 9.4753194758919079e0;pw[13] = 3.5583611836440579e-5; + px[14] = 1.0959837563734646e1;pw[14] = 8.0964663575545199e-6; + px[15] = 1.2559330947448595e1;pw[15] = 1.6427089095665616e-6; + px[16] = 1.4275847932399555e1;pw[16] = 2.9659388100100142e-7; + px[17] = 1.6111648203063945e1;pw[17] = 4.7547324295148571e-8; + px[18] = 1.8069221710408724e1;pw[18] = 6.7511694622554086e-9; + px[19] = 2.0151310492061653e1;pw[19] = 8.4671875670220449e-10; + px[20] = 2.2360933946965237e1;pw[20] = 9.3520207719701412e-11; + px[21] = 2.4701418206395586e1;pw[21] = 9.0666067491677764e-12; + px[22] = 2.7176430396128092e1;pw[22] = 7.6873634497532554e-13; + px[23] = 2.9790018780757460e1;pw[23] = 5.6775347903386773e-14; + px[24] = 3.2546660035349492e1;pw[24] = 3.6363382609864670e-15; + px[25] = 3.5451315222092618e1;pw[25] = 2.0098102983149713e-16; + px[26] = 3.8509496489187991e1;pw[26] = 9.5336623423732135e-18; + px[27] = 4.1727347097011937e1;pw[27] = 3.8577586536742773e-19; + px[28] = 4.5111738172331784e1;pw[28] = 1.3225902352962134e-20; + px[29] = 4.8670386683149351e1;pw[29] = 3.8125203773751006e-22; + px[30] = 5.2412000646782474e1;pw[30] = 9.1612021970998299e-24; + px[31] = 5.6346459734243123e1;pw[31] = 1.8171931294097668e-25; + px[32] = 6.0485042530508732e1;pw[32] = 2.9424831099483641e-27; + px[33] = 6.4840716257286064e1;pw[33] = 3.8399414135897572e-29; + px[34] = 6.9428511589042573e1;pw[34] = 3.9790937885390546e-31; + px[35] = 7.4266015688703556e1;pw[35] = 3.2177464158769137e-33; + px[36] = 7.9374033184791669e1;pw[36] = 1.9893600118442518e-35; + px[37] = 8.4777491893280191e1;pw[37] = 9.1748033317163899e-38; + px[38] = 9.0506715916613337e1;pw[38] = 3.0635979294223916e-40; + px[39] = 9.6599269661943114e1;pw[39] = 7.1378771235620131e-43; + px[40] = 1.0310272648925973e2;pw[40] = 1.1074129639565051e-45; + px[41] = 1.1007901167333772e2;pw[41] = 1.0766445013940194e-48; + px[42] = 1.1761159733441177e2;pw[42] = 6.0445878630042245e-52; + px[43] = 1.2581828912230779e2;pw[43] = 1.7467465671838054e-55; + px[44] = 1.3487618875613396e2;pw[44] = 2.1867649475035571e-59; + px[45] = 1.4507736943128927e2;pw[45] = 8.9374048433626366e-64; + px[46] = 1.5698162310364024e2;pw[46] = 6.9616827754363648e-69; + px[47] = 1.7203286674516623e2;pw[47] = 7.3843030686139940e-50; + break; + case 56: + px[0] = 1.0966296964922414e-2;pw[0] = 4.1431861461592488e-1; + px[1] = 9.8709503981500921e-2;pw[1] = 3.7958824335151592e-1; + px[2] = 2.7426441281900728e-1;pw[2] = 3.1859560878006560e-1; + px[3] = 5.3776830760580984e-1;pw[3] = 2.4493804875366549e-1; + px[4] = 8.8942785389626524e-1;pw[4] = 1.7245385388352993e-1; + px[5] = 1.3295199945387192e0;pw[5] = 1.1116552769641440e-1; + px[6] = 1.8583931587330957e0;pw[6] = 6.5583934984821083e-2; + px[7] = 2.4764687971240665e0;pw[7] = 3.5397526052325080e-2; + px[8] = 3.1842432594503771e0;pw[8] = 1.7469565741779008e-2; + px[9] = 3.9822900352751187e0;pw[9] = 7.8791146628173459e-3; + px[10] = 4.8712623827436266e0;pw[10] = 3.2454637275858797e-3; + px[11] = 5.8518963752570206e0;pw[11] = 1.2200069198095973e-3; + px[12] = 6.9250144015294926e0;pw[12] = 4.1819509658049854e-4; + px[13] = 8.0915291608577938e0;pw[13] = 1.3059682676732009e-4; + px[14] = 9.3524482027415579e0;pw[14] = 3.7118324819779832e-5; + px[15] = 1.0708879068458080e1;pw[15] = 9.5910914884881867e-6; + px[16] = 1.2162035102064631e1;pw[16] = 2.2503384827035532e-6; + px[17] = 1.3713242009881661e1;pw[17] = 4.7880157280422767e-7; + px[18] = 1.5363945261179596e1;pw[18] = 9.2250198493335919e-8; + px[19] = 1.7115718439020667e1;pw[19] = 1.6069558346408703e-8; + px[20] = 1.8970272669583436e1;pw[20] = 2.5265449989883177e-9; + px[21] = 2.0929467281561854e1;pw[21] = 3.5787741726578897e-10; + px[22] = 2.2995321875320932e1;pw[22] = 4.5577902726623018e-11; + px[23] = 2.5170030015603701e1;pw[23] = 5.2076385947795911e-12; + px[24] = 2.7455974803255672e1;pw[24] = 5.3255665746212511e-13; + px[25] = 2.9855746632650704e1;pw[25] = 4.8619672412277693e-14; + px[26] = 3.2372163504856039e1;pw[26] = 3.9515202575705826e-15; + px[27] = 3.5008294345466858e1;pw[27] = 2.8503559634838643e-16; + px[28] = 3.7767485874979349e1;pw[28] = 1.8187535954103432e-17; + px[29] = 4.0653393704581200e1;pw[29] = 1.0228519632208071e-18; + px[30] = 4.3670018489449905e1;pw[30] = 5.0500039302829468e-20; + px[31] = 4.6821748176145590e1;pw[31] = 2.1793149108595921e-21; + px[32] = 5.0113407645739421e1;pw[32] = 8.1812395526908028e-23; + px[33] = 5.3550317401224539e1;pw[33] = 2.6576488518963704e-24; + px[34] = 5.7138363406574332e1;pw[34] = 7.4271309204470600e-26; + px[35] = 6.0884080798556528e1;pw[35] = 1.7740931536888198e-27; + px[36] = 6.4794755023535346e1;pw[36] = 3.5960724740047246e-29; + px[37] = 6.8878545092128855e1;pw[37] = 6.1357429171822799e-31; + px[38] = 7.3144635233014682e1;pw[38] = 8.7325878464563983e-33; + px[39] = 7.7603423474903333e1;pw[39] = 1.0260913087634106e-34; + px[40] = 8.2266758923044609e1;pw[40] = 9.8379556343138002e-37; + px[41] = 8.7148244251462459e1;pw[41] = 7.5937692877807736e-39; + px[42] = 9.2263627069792685e1;pw[42] = 4.6460504504603365e-41; + px[43] = 9.7631314803869374e1;pw[43] = 2.2125228051355289e-43; + px[44] = 1.0327306509488168e2;pw[44] = 8.0267804054671947e-46; + px[45] = 1.0921493206709584e2;pw[45] = 2.1621413990444480e-48; + px[46] = 1.1548859679336965e2;pw[46] = 4.1913798221383726e-51; + px[47] = 1.2213329501416645e2;pw[47] = 5.6258187814957665e-54; + px[48] = 1.2919871245898944e2;pw[48] = 4.9791444365660730e-57; + px[49] = 1.3674952821727593e2;pw[49] = 2.7270187769624205e-60; + px[50] = 1.4487294472877377e2;pw[50] = 8.4854893562244169e-64; + px[51] = 1.5369207574377554e2;pw[51] = 1.3300105642340421e-67; + px[52] = 1.6339209491703519e2;pw[52] = 8.7671924329217860e-72; + px[53] = 1.7427858611626866e2;pw[53] = 1.8070041919711762e-76; + px[54] = 1.8693771869007120e2;pw[54] = 1.0229121536329777e-48; + px[55] = 2.0288303763687224e2;pw[55] = 7.4032472491198754e-53; + break; + case 64: + px[0] = 9.6008293650696286e-3;pw[0] = 3.8819522372817551e-1; + px[1] = 8.6416074005085619e-2;pw[1] = 3.5954616781559853e-1; + px[2] = 2.4009251326551299e-1;pw[2] = 3.0842087059670877e-1; + px[3] = 4.7072219845762405e-1;pw[3] = 2.4500654632827139e-1; + px[4] = 7.7844358612953627e-1;pw[4] = 1.8021735675289784e-1; + px[5] = 1.1634419969552807e0;pw[5] = 1.2272144200898013e-1; + px[6] = 1.6259502332928078e0;pw[6] = 7.7347909621273805e-2; + px[7] = 2.1662493604094500e0;pw[7] = 4.5108620335648845e-2; + px[8] = 2.7846696577606368e0;pw[8] = 2.4333837728938679e-2; + px[9] = 3.4815917481914229e0;pw[9] = 1.2137724813851775e-2; + px[10] = 4.2574479145349120e0;pw[10] = 5.5956788032115785e-3; + px[11] = 5.1127236148341415e0;pw[11] = 2.3831276289143345e-3; + px[12] = 6.0479592093454125e0;pw[12] = 9.3710307561682273e-4; + px[13] = 7.0637519146269628e0;pw[13] = 3.4002817652561882e-4; + px[14] = 8.1607580024185598e0;pw[14] = 1.1377487520080482e-4; + px[15] = 9.3396952637232506e0;pw[15] = 3.5080971696187810e-5; + px[16] = 1.0601345761568931e1;pw[16] = 9.9598490651819740e-6; + px[17] = 1.1946558899421827e1;pw[17] = 2.6014940064763985e-6; + px[18] = 1.3376254836226536e1;pw[18] = 6.2457459723578062e-7; + px[19] = 1.4891428283653888e1;pw[19] = 1.3769162244308700e-7; + px[20] = 1.6493152726464029e1;pw[20] = 2.7843814305870358e-8; + px[21] = 1.8182585113077513e1;pw[21] = 5.1587944588527896e-9; + px[22] = 1.9960971070661513e1;pw[22] = 8.7463733196968069e-10; + px[23] = 2.1829650707488929e1;pw[23] = 1.3551560975549108e-10; + px[24] = 2.3790065075269629e1;pw[24] = 1.9160633017471715e-11; + px[25] = 2.5843763375899103e1;pw[25] = 2.4684289732011134e-12; + px[26] = 2.7992411011009711e1;pw[26] = 2.8926946423808331e-13; + px[27] = 3.0237798589328330e1;pw[27] = 3.0780994607070916e-14; + px[28] = 3.2581852026749626e1;pw[28] = 2.9684476750277130e-15; + px[29] = 3.5026643897992604e1;pw[29] = 2.5890963186787431e-16; + px[30] = 3.7574406227691570e1;pw[30] = 2.0378664608465850e-17; + px[31] = 4.0227544944021652e1;pw[31] = 1.4440214633856584e-18; + px[32] = 4.2988656261067658e1;pw[32] = 9.1880153546594432e-20; + px[33] = 4.5860545309175844e1;pw[33] = 5.2349151678696223e-21; + px[34] = 4.8846247398170421e1;pw[34] = 2.6627357180671792e-22; + px[35] = 5.1949052380103696e1;pw[35] = 1.2051968064012909e-23; + px[36] = 5.5172532680822943e1;pw[36] = 4.8368069192953299e-25; + px[37] = 5.8520575699338077e1;pw[37] = 1.7145660967538707e-26; + px[38] = 6.1997421439210377e1;pw[38] = 5.3458472401161465e-28; + px[39] = 6.5607706448472386e1;pw[39] = 1.4593090013536809e-29; + px[40] = 6.9356515419807817e1;pw[40] = 3.4702060405641224e-31; + px[41] = 7.3249442163003752e1;pw[41] = 7.1487577917588421e-33; + px[42] = 7.7292662138289202e1;pw[42] = 1.2679827052732978e-34; + px[43] = 8.1493019376821402e1;pw[43] = 1.9233416135935014e-36; + px[44] = 8.5858131478224402e1;pw[44] = 2.4761711159527361e-38; + px[45] = 9.0396517560549849e1;pw[45] = 2.6829949635287387e-40; + px[46] = 9.5117755689162181e1;pw[46] = 2.4235590682611838e-42; + px[47] = 1.0003267864790140e2;pw[47] = 1.8056080277573288e-44; + px[48] = 1.0515362028215433e2;pw[48] = 1.0960434057957593e-46; + px[49] = 1.1049472958850639e2;pw[49] = 5.3454875034721357e-49; + px[50] = 1.1607237715014811e2;pw[50] = 2.0609725041113895e-51; + px[51] = 1.2190568994074218e2;pw[51] = 6.1641547666785974e-54; + px[52] = 1.2801726858944196e2;pw[52] = 1.3986145848103912e-56; + px[53] = 1.3443417070003274e2;pw[53] = 2.3439570024259610e-59; + px[54] = 1.4118929376119792e2;pw[54] = 2.8089345154809745e-62; + px[55] = 1.4832337939847587e2;pw[55] = 2.3123103281927504e-65; + px[56] = 1.5588802451891946e2;pw[56] = 1.2428488323660627e-68; + px[57] = 1.6395040789497031e2;pw[57] = 4.0831715944879700e-72; + px[58] = 1.7260112638093499e2;pw[58] = 7.5024317376094500e-76; + px[59] = 1.8196813220934213e2;pw[59] = 6.8024601738732743e-80; + px[60] = 1.9224396472236875e2;pw[60] = 2.5224989666770768e-84; + px[61] = 2.0374654228943264e2;pw[61] = 9.5158011667265254e-49; + px[62] = 2.1708611403654403e2;pw[62] = 5.3192427849433605e-52; + px[63] = 2.3383975178282573e2;pw[63] = 2.9535559171937292e-66; + break; + case 72: + px[0] = 8.5377530337449248e-3;pw[0] = 3.6646133805754739e-1; + px[1] = 7.6845831749819249e-2;pw[1] = 3.4230533863506727e-1; + px[2] = 2.1349429706226695e-1;pw[2] = 2.9865564028363514e-1; + px[3] = 4.1854784885205123e-1;pw[3] = 2.4337240372556322e-1; + px[4] = 6.9210374777076850e-1;pw[4] = 1.8521384480327197e-1; + px[5] = 1.0342920697248060e0;pw[5] = 1.3161967742383411e-1; + px[6] = 1.4452760476859431e0;pw[6] = 8.7325860377519644e-2; + px[7] = 1.9252525030070945e0;pw[7] = 5.4082218044787982e-2; + px[8] = 2.4744523690138993e0;pw[8] = 3.1257614600552892e-2; + px[9] = 3.0931413102677093e0;pw[9] = 1.6855126430119594e-2; + px[10] = 3.7816204415611087e0;pw[10] = 8.4772081114631611e-3; + px[11] = 4.5402271514220959e0;pw[11] = 3.9753232176891744e-3; + px[12] = 5.3693360356771178e0;pw[12] = 1.7375161592345435e-3; + px[13] = 6.2693599474670913e0;pw[13] = 7.0752789404236957e-4; + px[14] = 7.2407511710366363e0;pw[14] = 2.6830022946769146e-4; + px[15] = 8.2840027276389276e0;pw[15] = 9.4699597895333223e-5; + px[16] = 9.3996498230328796e0;pw[16] = 3.1095207369238697e-5; + px[17] = 1.0588271447314284e1;pw[17] = 9.4930705560516880e-6; + px[18] = 1.1850492139239455e1;pw[18] = 2.6928856004713719e-6; + px[19] = 1.3186983928793866e1;pw[19] = 7.0931074479099719e-7; + px[20] = 1.4598468473558433e1;pw[20] = 1.7336070598064455e-7; + px[21] = 1.6085719406466767e1;pw[21] = 3.9284921495770124e-8; + px[22] = 1.7649564914868501e1;pw[22] = 8.2471566241554238e-9; + px[23] = 1.9290890573464524e1;pw[23] = 1.6025182143590107e-9; + px[24] = 2.1010642456716749e1;pw[24] = 2.8794742979351125e-10; + px[25] = 2.2809830559825846e1;pw[25] = 4.7796759804694583e-11; + px[26] = 2.4689532561396773e1;pw[26] = 7.3213811680310381e-12; + px[27] = 2.6650897965571812e1;pw[27] = 1.0337134692368372e-12; + px[28] = 2.8695152666822676e1;pw[28] = 1.3436626222686719e-13; + px[29] = 3.0823603986900308e1;pw[29] = 1.6058255460718379e-14; + px[30] = 3.3037646240818195e1;pw[30] = 1.7620660009112015e-15; + px[31] = 3.5338766897405687e1;pw[31] = 1.7726340324641576e-16; + px[32] = 3.7728553410174551e1;pw[32] = 1.6323127659605682e-17; + px[33] = 4.0208700806318587e1;pw[33] = 1.3735451099194697e-18; + px[34] = 4.2781020136014409e1;pw[34] = 1.0542790113729066e-19; + px[35] = 4.5447447901312514e1;pw[35] = 7.3672431203789817e-21; + px[36] = 4.8210056604429630e1;pw[36] = 4.6773118965550795e-22; + px[37] = 5.1071066579968236e1;pw[37] = 2.6919741928296506e-23; + px[38] = 5.4032859305501852e1;pw[38] = 1.4012014167408308e-24; + px[39] = 5.7097992421357986e1;pw[39] = 6.5793246486772861e-26; + px[40] = 6.0269216734953006e1;pw[40] = 2.7792387816429709e-27; + px[41] = 6.3549495539818125e1;pw[41] = 1.0530654909535471e-28; + px[42] = 6.6942026647284918e1;pw[42] = 3.5677140725415228e-30; + px[43] = 7.0450267613328067e1;pw[43] = 1.0770556703499718e-31; + px[44] = 7.4077964749136873e1;pw[44] = 2.8865806752335222e-33; + px[45] = 7.7829186638083087e1;pw[45] = 6.8402497184153889e-35; + px[46] = 8.1708363052613987e1;pw[46] = 1.4268974543918404e-36; + px[47] = 8.5720330384148150e1;pw[47] = 2.6077204118485067e-38; + px[48] = 8.9870384983719634e1;pw[48] = 4.1533050523669125e-40; + px[49] = 9.4164346183819770e1;pw[49] = 5.7316992987700021e-42; + px[50] = 9.8608631264982208e1;pw[50] = 6.8102796020749233e-44; + px[51] = 1.0321034529045834e2;pw[51] = 6.9179617811502756e-46; + px[52] = 1.0797738962609581e2;pw[52] = 5.9610219491215519e-48; + px[53] = 1.1291859418950553e2;pw[53] = 4.3190839650906910e-50; + px[54] = 1.1804388018177253e2;pw[54] = 2.6056833265450411e-52; + px[55] = 1.2336446247428126e2;pw[55] = 1.2944535536043246e-54; + px[56] = 1.2889310430876951e2;pw[56] = 5.2287531735186084e-57; + px[57] = 1.3464444208967572e2;pw[57] = 1.6926455724514031e-59; + px[58] = 1.4063540573754781e2;pw[58] = 4.3183461553903832e-62; + px[59] = 1.4688577190557120e2;pw[59] = 8.5145486452100040e-65; + px[60] = 1.5341890608220506e2;pw[60] = 1.2678660729891205e-67; + px[61] = 1.6026278017056644e2;pw[61] = 1.3869468532834784e-70; + px[62] = 1.6745140389442310e2;pw[62] = 1.0778332837412283e-73; + px[63] = 1.7502689981511292e2;pw[63] = 5.7084939874269743e-77; + px[64] = 1.8304262155336948e2;pw[64] = 1.9550707098857624e-80; + px[65] = 1.9156804971323859e2;pw[65] = 4.0440344494888973e-84; + px[66] = 2.0069691105825289e2;pw[66] = 4.6082741548145242e-88; + px[67] = 2.1056162324265798e2;pw[67] = 2.5411102164420924e-92; + px[68] = 2.2136152670104394e2;pw[68] = 5.5818464378910382e-97; + px[69] = 2.3342593022383359e2;pw[69] = 3.8018252344681360e-50; + px[70] = 2.4738731475402643e2;pw[70] = 2.0795745925390798e-53; + px[71] = 2.6488137073545847e2;pw[71] = 5.9029492520141047e-68; + break; + case 80: + px[0] = 7.6866318444038650e-3;pw[0] = 3.4801121234964061e-1; + px[1] = 6.9184104726922287e-2;pw[1] = 3.2728554809172511e-1; + px[2] = 1.9220262418784241e-1;pw[2] = 2.8945683894699143e-1; + px[3] = 3.7678938735594810e-1;pw[3] = 2.4073751764332210e-1; + px[4] = 6.2301531452046157e-1;pw[4] = 1.8826779554366350e-1; + px[5] = 9.3097519935847685e-1;pw[5] = 1.3843298565975990e-1; + px[6] = 1.3007879104323092e0;pw[6] = 9.5693623713172557e-2; + px[7] = 1.7325966449946741e0;pw[7] = 6.2179086370712325e-2; + px[8] = 2.2265692364173354e0;pw[8] = 3.7970908655009312e-2; + px[9] = 2.7828985168491514e0;pw[9] = 2.1788109306695115e-2; + px[10] = 3.4018027370152287e0;pw[10] = 1.1745069517438239e-2; + px[11] = 4.0835260453933245e0;pw[11] = 5.9463917421429804e-3; + px[12] = 4.8283390293501774e0;pw[12] = 2.8268077494244823e-3; + px[13] = 5.6365393211929032e0;pw[13] = 1.2614066531994309e-3; + px[14] = 6.5084522724931878e0;pw[14] = 5.2818895724163281e-4; + px[15] = 7.4444317004794741e0;pw[15] = 2.0746547336341577e-4; + px[16] = 8.4448607107699771e0;pw[16] = 7.6411540013651783e-5; + px[17] = 9.5101526012431861e0;pw[17] = 2.6378489263127714e-5; + px[18] = 1.0640751852419332e1;pw[18] = 8.5315214346510367e-6; + px[19] = 1.1837135210363891e1;pw[19] = 2.5839402017229379e-6; + px[20] = 1.3099812868831478e1;pw[20] = 7.3248237980755977e-7; + px[21] = 1.4429329758155656e1;pw[21] = 1.9423835172306337e-7; + px[22] = 1.5826266949269123e1;pw[22] = 4.8155353038663436e-8; + px[23] = 1.7291243182222957e1;pw[23] = 1.1154712143820550e-8; + px[24] = 1.8824916529679155e1;pw[24] = 2.4126359656654055e-9; + px[25] = 2.0427986207095807e1;pw[25] = 4.8690306206928333e-10; + px[26] = 2.2101194542730669e1;pw[26] = 9.1619835022640038e-11; + px[27] = 2.3845329122181760e1;pw[27] = 1.6061727543126440e-11; + px[28] = 2.5661225123992617e1;pw[28] = 2.6211365629406585e-12; + px[29] = 2.7549767864910021e1;pw[29] = 3.9783127491115241e-13; + px[30] = 2.9511895575734651e1;pw[30] = 5.6106664386726106e-14; + px[31] = 3.1548602431399443e1;pw[31] = 7.3452477074096906e-15; + px[32] = 3.3660941862004724e1;pw[32] = 8.9170156740924202e-16; + px[33] = 3.5850030175103469e1;pw[33] = 1.0027003519531224e-16; + px[34] = 3.8117050523647834e1;pw[34] = 1.0431576805686864e-17; + px[35] = 4.0463257258780339e1;pw[35] = 1.0027987156316190e-18; + px[36] = 4.2889980712201399e1;pw[36] = 8.8958541452840810e-20; + px[37] = 4.5398632459316878e1;pw[37] = 7.2721294867218350e-21; + px[38] = 4.7990711121944935e1;pw[38] = 5.4700089499572571e-22; + px[39] = 5.0667808778260416e1;pw[39] = 3.7798889589128719e-23; + px[40] = 5.3431618058147838e1;pw[40] = 2.3955393929296669e-24; + px[41] = 5.6283940014554144e1;pw[41] = 1.3898975276677134e-25; + px[42] = 5.9226692876193983e1;pw[42] = 7.3686649638685550e-27; + px[43] = 6.2261921804579421e1;pw[43] = 3.5623617964926723e-28; + px[44] = 6.5391809799470289e1;pw[44] = 1.5670671394405450e-29; + px[45] = 6.8618689922287050e1;pw[45] = 6.2579202126857896e-31; + px[46] = 7.1945059037830997e1;pw[46] = 2.2630134382743232e-32; + px[47] = 7.5373593312139102e1;pw[47] = 7.3910051432137950e-34; + px[48] = 7.8907165750162510e1;pw[48] = 2.1738965407946768e-35; + px[49] = 8.2548866113398157e1;pw[49] = 5.7406301865352811e-37; + px[50] = 8.6302023627490826e1;pw[50] = 1.3565280389341554e-38; + px[51] = 9.0170232976927819e1;pw[51] = 2.8582178093556767e-40; + px[52] = 9.4157384193266820e1;pw[52] = 5.3491017715110987e-42; + px[53] = 9.8267697181550113e1;pw[53] = 8.8545200956130098e-44; + px[54] = 1.0250576180568381e2;pw[54] = 1.2905303360994193e-45; + px[55] = 1.0687658467989708e2;pw[55] = 1.6479024314408629e-47; + px[56] = 1.1138564410689640e2;pw[56] = 1.8335510486003441e-49; + px[57] = 1.1603895498763616e2;pw[57] = 1.7670959327066303e-51; + px[58] = 1.2084314603612786e2;pw[58] = 1.4654679930191558e-53; + px[59] = 1.2580555231319460e2;pw[59] = 1.0382012259739465e-55; + px[60] = 1.3093432701495951e2;pw[60] = 6.2325264712640765e-58; + px[61] = 1.3623857771756320e2;pw[61] = 3.1419744937690600e-60; + px[62] = 1.4172853404292507e2;pw[62] = 1.3167216299744360e-62; + px[63] = 1.4741575620660480e2;pw[63] = 4.5348612513885167e-65; + px[64] = 1.5331339750560076e2;pw[64] = 1.2669383082047862e-67; + px[65] = 1.5943653908891510e2;pw[65] = 2.8286860158479256e-70; + px[66] = 1.6580262329068657e2;pw[66] = 4.9608576653838684e-73; + px[67] = 1.7243202402097285e2;pw[67] = 6.6976362308197039e-76; + px[68] = 1.7934881203693207e2;pw[68] = 6.7974784724244015e-79; + px[69] = 1.8658180447952091e2;pw[69] = 5.0405265141181345e-82; + px[70] = 1.9416604151140286e2;pw[70] = 2.6380873260356514e-85; + px[71] = 2.0214492732686698e2;pw[71] = 9.3369329897351393e-89; + px[72] = 2.1057344821155215e2;pw[72] = 2.1169241731154879e-92; + px[73] = 2.1952322632251781e2;pw[73] = 2.8655194931946936e-96; + px[74] = 2.2909090256827742e2;pw[74] = 2.1061692586895640e-100; + px[75] = 2.3941305411072180e2;pw[75] = 7.6547423878179816e-105; + px[76] = 2.5069535780481856e2;pw[76] = 4.5949033294697062e-51; + px[77] = 2.6327773413988054e2;pw[77] = 6.4123032211485360e-55; + px[78] = 2.7781337017790295e2;pw[78] = 2.6355344341971242e-68; + px[79] = 2.9599252372507157e2;pw[79] = 4.2626228488835649e-81; + break; + case 88: + px[0] = 6.9898229051547411e-3;pw[0] = 3.3209344438409325e-1; + px[1] = 6.2911728289785692e-2;pw[1] = 3.1405674898440063e-1; + px[2] = 1.7477326359221082e-1;pw[2] = 2.8086402575909276e-1; + px[3] = 3.4260990879552213e-1;pw[3] = 2.3752476979765092e-1; + px[4] = 5.6647496129652395e-1;pw[4] = 1.8994306166644856e-1; + px[5] = 8.4643962917804553e-1;pw[5] = 1.4361800366234363e-1; + px[6] = 1.1825931561845759e0;pw[6] = 1.0266599963917014e-1; + px[7] = 1.5750429789323641e0;pw[7] = 6.9379346479544336e-2; + px[8] = 2.0239149170256255e0;pw[8] = 4.4316467105237175e-2; + px[9] = 2.5293533968962740e0;pw[9] = 2.6752780145097017e-2; + px[10] = 3.0915217103368590e0;pw[10] = 1.5260575426000781e-2; + px[11] = 3.7106023088564040e0;pw[11] = 8.2241712678339878e-3; + px[12] = 4.3867971351580078e0;pw[12] = 4.1864435774652050e-3; + px[13] = 5.1203279932168699e0;pw[13] = 2.0124922623294288e-3; + px[14] = 5.9114369586294842e0;pw[14] = 9.1338594776452588e-4; + px[15] = 6.7603868311109156e0;pw[15] = 3.9128377994473102e-4; + px[16] = 7.6674616312393195e0;pw[16] = 1.5816991465628900e-4; + px[17] = 8.6329671437874178e0;pw[17] = 6.0313998121755884e-5; + px[18] = 9.6572315102419724e0;pw[18] = 2.1688652721856188e-5; + px[19] = 1.0740605873397186e1;pw[19] = 7.3521662189359001e-6; + px[20] = 1.1883465077219540e1;pw[20] = 2.3485735170662032e-6; + px[21] = 1.3086208425523377e1;pw[21] = 7.0668575490339494e-7; + px[22] = 1.4349260503372554e1;pw[22] = 2.0021570985018051e-7; + px[23] = 1.5673072065538298e1;pw[23] = 5.3385656195939403e-8; + px[24] = 1.7058120996802116e1;pw[24] = 1.3390564636227622e-8; + px[25] = 1.8504913349401250e1;pw[25] = 3.1579273648368550e-9; + px[26] = 2.0013984463479417e1;pw[26] = 6.9984639734477468e-10; + px[27] = 2.1585900177035253e1;pw[27] = 1.4566522851312418e-10; + px[28] = 2.3221258132563997e1;pw[28] = 2.8457916194634976e-11; + px[29] = 2.4920689188374744e1;pw[29] = 5.2152057446839083e-12; + px[30] = 2.6684858943448156e1;pw[30] = 8.9592785232829909e-13; + px[31] = 2.8514469385691634e1;pw[31] = 1.4417973875868243e-13; + px[32] = 3.0410260674566840e1;pw[32] = 2.1719253795631441e-14; + px[33] = 3.2373013070326923e1;pw[33] = 3.0602546728763147e-15; + px[34] = 3.4403549023529919e1;pw[34] = 4.0298283180374064e-16; + px[35] = 3.6502735440116345e1;pw[35] = 4.9551512528428224e-17; + px[36] = 3.8671486139183441e1;pw[36] = 5.6842543746643022e-18; + px[37] = 4.0910764522691699e1;pw[37] = 6.0774264422552206e-19; + px[38] = 4.3221586478743604e1;pw[38] = 6.0500123323576681e-20; + px[39] = 4.5605023542830377e1;pw[39] = 5.6016998994982451e-21; + px[40] = 4.8062206344609867e1;pw[40] = 4.8186081446164731e-22; + px[41] = 5.0594328371429292e1;pw[41] = 3.8463215773862006e-23; + px[42] = 5.3202650084026280e1;pw[42] = 2.8454232488178569e-24; + px[43] = 5.5888503424734049e1;pw[43] = 1.9482724641523455e-25; + px[44] = 5.8653296764206622e1;pw[44] = 1.2329494549301778e-26; + px[45] = 6.1498520339319444e1;pw[45] = 7.2009452095564265e-28; + px[46] = 6.4425752242674225e1;pw[46] = 3.8752556618667624e-29; + px[47] = 6.7436665033270514e1;pw[47] = 1.9184700627092652e-30; + px[48] = 7.0533033048677930e1;pw[48] = 8.7214115374171135e-32; + px[49] = 7.3716740511795214e1;pw[49] = 3.6339711712303267e-33; + px[50] = 7.6989790540440737e1;pw[50] = 1.3850762473413167e-34; + px[51] = 8.0354315186114501e1;pw[51] = 4.8188380976506615e-36; + px[52] = 8.3812586649969540e1;pw[52] = 1.5268836098287974e-37; + px[53] = 8.7367029850170202e1;pw[53] = 4.3955893390762546e-39; + px[54] = 9.1020236546461036e1;pw[54] = 1.1467178326064145e-40; + px[55] = 9.4774981266282465e1;pw[55] = 2.7034989251018274e-42; + px[56] = 9.8634239323895773e1;pw[56] = 5.7430338090994212e-44; + px[57] = 1.0260120728198211e2;pw[57] = 1.0957767689227991e-45; + px[58] = 1.0667932627700808e2;pw[58] = 1.8714704533178499e-47; + px[59] = 1.1087230871918132e2;pw[59] = 2.8505049132116738e-49; + px[60] = 1.1518416899019180e2;pw[60] = 3.8566146717396706e-51; + px[61] = 1.1961925890402067e2;pw[61] = 4.6148622579363381e-53; + px[62] = 1.2418230887717554e2;pw[62] = 4.8611462511088885e-55; + px[63] = 1.2887847598742982e2;pw[63] = 4.4845808683072384e-57; + px[64] = 1.3371340040194700e2;pw[64] = 3.6030988117615386e-59; + px[65] = 1.3869327205088259e2;pw[65] = 2.5057229445134590e-61; + px[66] = 1.4382490994553306e2;pw[66] = 1.4981434219579486e-63; + px[67] = 1.4911585724002039e2;pw[67] = 7.6434036433722766e-66; + px[68] = 1.5457449608379523e2;pw[68] = 3.3000635664912984e-68; + px[69] = 1.6021018761433266e2;pw[69] = 1.1946162455653543e-70; + px[70] = 1.6603344425357073e2;pw[70] = 3.5882216086453966e-73; + px[71] = 1.7205614404012268e2;pw[71] = 8.8381795575894759e-76; + px[72] = 1.7829180043052003e2;pw[72] = 1.7614304684723708e-78; + px[73] = 1.8475590644174345e2;pw[73] = 2.7972091009100451e-81; + px[74] = 1.9146638017638173e2;pw[74] = 3.4772790784565961e-84; + px[75] = 1.9844415134556974e2;pw[75] = 3.3145008476708899e-87; + px[76] = 2.0571394830191976e2;pw[76] = 2.3639811252252232e-90; + px[77] = 2.1330537759040182e2;pw[77] = 1.2252220679209011e-93; + px[78] = 2.2125444306253341e2;pw[78] = 4.4534409258766820e-97; + px[79] = 2.2960574884915661e2;pw[79] = 1.0863817141918454e-100; + px[80] = 2.3841581114398289e2;pw[80] = 1.6822680293726604e-104; + px[81] = 2.4775826014248507e2;pw[81] = 1.5380603201854840e-108; + px[82] = 2.5773247037077271e2;pw[82] = 7.5305256625793262e-113; + px[83] = 2.6847892170878440e2;pw[83] = 1.7204742760900275e-117; + px[84] = 2.8020923651927812e2;pw[84] = 2.4712355922645459e-52; + px[85] = 2.9327329106785954e2;pw[85] = 2.0946397303280510e-50; + px[86] = 3.0834369296097073e2;pw[86] = 9.0428276327931568e-65; + px[87] = 3.2716185523285862e2;pw[87] = 1.9175767652062620e-79; + break; + case 96: + px[0] = 6.4088479693086173e-3;pw[0] = 3.1817720207314518e-1; + px[1] = 5.7682192384603139e-2;pw[1] = 3.0229450239014958e-1; + px[2] = 1.6024254224241131e-1;pw[2] = 2.7286429856942241e-1; + px[3] = 3.1411723962617867e-1;pw[3] = 2.3399502554972005e-1; + px[4] = 5.1934734780450853e-1;pw[4] = 1.9063041737616373e-1; + px[5] = 7.7598771160231075e-1;pw[5] = 1.4752978061991784e-1; + px[6] = 1.0841070382287637e0;pw[6] = 1.0845245228344696e-1; + px[7] = 1.4437879988503862e0;pw[7] = 7.5724332195484464e-2; + px[8] = 1.8551273512731066e0;pw[8] = 5.0214141133917932e-2; + px[9] = 2.3182360841752035e0;pw[9] = 3.1620089370995634e-2; + px[10] = 2.8332395834139107e0;pw[10] = 1.8905681570520517e-2; + px[11] = 3.4002778210128949e0;pw[11] = 1.0731321018794248e-2; + px[12] = 4.0195055675263257e0;pw[12] = 5.7820073860565274e-3; + px[13] = 4.6910926285685173e0;pw[13] = 2.9566179089772504e-3; + px[14] = 5.4152241063968240e0;pw[14] = 1.4345733126805138e-3; + px[15] = 6.1921006875403740e0;pw[15] = 6.6035034249772304e-4; + px[16] = 7.0219389575791665e0;pw[16] = 2.8830782856393540e-4; + px[17] = 7.9049717442979328e0;pw[17] = 1.1936254041747660e-4; + px[18] = 8.8414484905679871e0;pw[18] = 4.6849104586421198e-5; + px[19] = 9.8316356584491658e0;pw[19] = 1.7427730160295739e-5; + px[20] = 1.0875817166154111e1;pw[20] = 6.1427630640308088e-6; + px[21] = 1.1974294859679961e1;pw[21] = 2.0508762851384060e-6; + px[22] = 1.3127389021089503e1;pw[22] = 6.4837954271472021e-7; + px[23] = 1.4335438915616705e1;pw[23] = 1.9403784928607733e-7; + px[24] = 1.5598803379982271e1;pw[24] = 5.4948470407217337e-8; + px[25] = 1.6917861454535469e1;pw[25] = 1.4718810972300389e-8; + px[26] = 1.8293013062091624e1;pw[26] = 3.7279041518397285e-9; + px[27] = 1.9724679736612835e1;pw[27] = 8.9237873517832415e-10; + px[28] = 2.1213305405186056e1;pw[28] = 2.0180598524189019e-10; + px[29] = 2.2759357227090996e1;pw[29] = 4.3094025836606105e-11; + px[30] = 2.4363326494124491e1;pw[30] = 8.6853173406217016e-12; + px[31] = 2.6025729596762688e1;pw[31] = 1.6512638032485222e-12; + px[32] = 2.7747109061202697e1;pw[32] = 2.9598835329453310e-13; + px[33] = 2.9528034662837436e1;pw[33] = 4.9993510953075103e-14; + px[34] = 3.1369104622288073e1;pw[34] = 7.9519688037928626e-15; + px[35] = 3.3270946890755629e1;pw[35] = 1.1903810906669537e-15; + px[36] = 3.5234220532166221e1;pw[36] = 1.6759557500075327e-16; + px[37] = 3.7259617210383481e1;pw[37] = 2.2177113226367451e-17; + px[38] = 3.9347862790659313e1;pw[38] = 2.7561280628581385e-18; + px[39] = 4.1499719065504354e1;pw[39] = 3.2145199936756972e-19; + px[40] = 4.3715985616298953e1;pw[40] = 3.5156800159203487e-20; + px[41] = 4.5997501823253394e1;pw[41] = 3.6025990545465830e-21; + px[42] = 4.8345149037785020e1;pw[42] = 3.4558483324761214e-22; + px[43] = 5.0759852933036353e1;pw[43] = 3.1004532672815943e-23; + px[44] = 5.3242586050143369e1;pw[44] = 2.5990033771037196e-24; + px[45] = 5.5794370560013523e1;pw[45] = 2.0335626660738988e-25; + px[46] = 5.8416281262832383e1;pw[46] = 1.4835853103395276e-26; + px[47] = 6.1109448850337470e1;pw[47] = 1.0080516345867198e-27; + px[48] = 6.3875063459139563e1;pw[48] = 6.3716760141675274e-29; + px[49] = 6.6714378547108836e1;pw[49] = 3.7418231588440592e-30; + px[50] = 6.9628715129163805e1;pw[50] = 2.0389207136140223e-31; + px[51] = 7.2619466413811364e1;pw[51] = 1.0294436657754091e-32; + px[52] = 7.5688102887614222e1;pw[52] = 4.8089946872814419e-34; + px[53] = 7.8836177901563518e1;pw[53] = 2.0753148425343429e-35; + px[54] = 8.2065333821298500e1;pw[54] = 8.2600326269673452e-37; + px[55] = 8.5377308812473848e1;pw[55] = 3.0268879909029589e-38; + px[56] = 8.8773944343613222e1;pw[56] = 1.0193701477126852e-39; + px[57] = 9.2257193501856653e1;pw[57] = 3.1487953377266536e-41; + px[58] = 9.5829130232545822e1;pw[58] = 8.9030283898555212e-43; + px[59] = 9.9491959632139456e1;pw[59] = 2.2991067830207375e-44; + px[60] = 1.0324802944619364e2;pw[60] = 5.4099632013102152e-46; + px[61] = 1.0709984295093964e2;pw[61] = 1.1570760541533550e-47; + px[62] = 1.1105007342943756e2;pw[62] = 2.2434027937343383e-49; + px[63] = 1.1510158049277213e2;pw[63] = 3.9318356145233163e-51; + px[64] = 1.1925742854508090e2;pw[64] = 6.2101615333023767e-53; + px[65] = 1.2352090775068523e2;pw[65] = 8.8106771041998731e-55; + px[66] = 1.2789555793525788e2;pw[66] = 1.1188872437683772e-56; + px[67] = 1.3238519594478634e2;pw[67] = 1.2670287078247711e-58; + px[68] = 1.3699394710135137e2;pw[68] = 1.2741754871478997e-60; + px[69] = 1.4172628154048866e2;pw[69] = 1.1328848065466888e-62; + px[70] = 1.4658705640065854e2;pw[70] = 8.8625846243039034e-65; + px[71] = 1.5158156507410060e2;pw[71] = 6.0683384585205647e-67; + px[72] = 1.5671559503799880e2;pw[72] = 3.6159126920762266e-69; + px[73] = 1.6199549619039953e2;pw[73] = 1.8632314937659433e-71; + px[74] = 1.6742826215197814e2;pw[74] = 8.2452068773611101e-74; + px[75] = 1.7302162771302658e2;pw[75] = 3.1094858299677929e-76; + px[76] = 1.7878418657827880e2;pw[76] = 9.9088925545678630e-79; + px[77] = 1.8472553489864371e2;pw[77] = 2.6428813129457523e-81; + px[78] = 1.9085644794111835e2;pw[78] = 5.8372225441875102e-84; + px[79] = 1.9718909988484638e2;pw[79] = 1.0548005520682382e-86; + px[80] = 2.0373734053112526e2;pw[80] = 1.5381913402837248e-89; + px[81] = 2.1051704829955498e2;pw[81] = 1.7819545894948543e-92; + px[82] = 2.1754658727070438e2;pw[82] = 1.6104009725265265e-95; + px[83] = 2.2484740894787622e2;pw[83] = 1.1114881452557864e-98; + px[84] = 2.3244485984497173e2;pw[84] = 5.7137871484250277e-102; + px[85] = 2.4036928938394857e2;pw[85] = 2.1230825957651528e-105; + px[86] = 2.4865760911996251e2;pw[86] = 5.4979966939612256e-109; + px[87] = 2.5735555421768465e2;pw[87] = 9.4850943127338216e-113; + px[88] = 2.6652108371132283e2;pw[88] = 1.0296088521328023e-116; + px[89] = 2.7622972228180378e2;pw[89] = 6.4585972823499812e-121; + px[90] = 2.8658342409205652e2;pw[90] = 1.7529595043807457e-117; + px[91] = 2.9772635225359436e2;pw[91] = 3.1105665306320562e-130; + px[92] = 3.0987574005931242e2;pw[92] = 2.5102657022454895e-50; + px[93] = 3.2339085777326039e2;pw[93] = 1.1598746411740026e-54; + px[94] = 3.3896263242081578e2;pw[94] = 1.8735722301688603e-68; + px[95] = 3.5838071121369978e2;pw[95] = 3.6413912508706140e-80; + break; + case 104: + px[0] = 5.9170399902629313e-3;pw[0] = 3.0587540675027521e-1; + px[1] = 5.3255375119357608e-2;pw[1] = 2.9174971091826186e-1; + px[2] = 1.4794279594504654e-1;pw[2] = 2.6542237352386527e-1; + px[3] = 2.9000081703620763e-1;pw[3] = 2.3031197872444814e-1; + px[4] = 4.7946174387139034e-1;pw[4] = 1.9060462767137745e-1; + px[5] = 7.1636871330281893e-1;pw[5] = 1.5044217126994679e-1; + px[6] = 1.0007757476986113e0;pw[6] = 1.1324045142276644e-1; + px[7] = 1.3327478229276096e0;pw[7] = 8.1283295752663497e-2; + px[8] = 1.7123609503940247e0;pw[8] = 5.5633427651614899e-2; + px[9] = 2.1397022733730653e0;pw[9] = 3.6305080311286526e-2; + px[10] = 2.6148701779441033e0;pw[10] = 2.2586734959646651e-2; + px[11] = 3.1379744188649923e0;pw[11] = 1.3395115370766690e-2; + px[12] = 3.7091362607801872e0;pw[12] = 7.5717088395729501e-3; + px[13] = 4.3284886352066046e0;pw[13] = 4.0788547539583762e-3; + px[14] = 4.9961763137950506e0;pw[14] = 2.0937112294538550e-3; + px[15] = 5.7123560984218524e0;pw[15] = 1.0239096611160486e-3; + px[16] = 6.4771970287254551e0;pw[16] = 4.7697940575163359e-4; + px[17] = 7.2908806077665737e0;pw[17] = 2.1161778351897556e-4; + px[18] = 8.1536010465584800e0;pw[18] = 8.9399513582116538e-5; + px[19] = 9.0655655282866201e0;pw[19] = 3.5954968465819779e-5; + px[20] = 1.0026994493114549e1;pw[20] = 1.3763471639247608e-5; + px[21] = 1.1038121944556697e1;pw[21] = 5.0135007842022910e-6; + px[22] = 1.2099195778488418e1;pw[22] = 1.7373642266442212e-6; + px[23] = 1.3210478135960773e1;pw[23] = 5.7261651269671511e-7; + px[24] = 1.4372245781092441e1;pw[24] = 1.7944867221251103e-7; + px[25] = 1.5584790505424801e1;pw[25] = 5.3455660388561925e-8; + px[26] = 1.6848419560249673e1;pw[26] = 1.5131821405551822e-8; + px[27] = 1.8163456118553402e1;pw[27] = 4.0690485475645235e-9; + px[28] = 1.9530239768367304e1;pw[28] = 1.0390864670042617e-9; + px[29] = 2.0949127039474128e1;pw[29] = 2.5189139018781987e-10; + px[30] = 2.2420491965594827e1;pw[30] = 5.7944986530631928e-11; + px[31] = 2.3944726684371185e1;pw[31] = 1.2644148134587503e-11; + px[32] = 2.5522242077669684e1;pw[32] = 2.6161135978115952e-12; + px[33] = 2.7153468454962594e1;pw[33] = 5.1301572545741211e-13; + px[34] = 2.8838856282796113e1;pw[34] = 9.5305252540215033e-14; + px[35] = 3.0578876963635225e1;pw[35] = 1.6765288843561763e-14; + px[36] = 3.2374023667684009e1;pw[36] = 2.7912570841914264e-15; + px[37] = 3.4224812221621939e1;pw[37] = 4.3960232489011666e-16; + px[38] = 3.6131782058575501e1;pw[38] = 6.5457287737442617e-17; + px[39] = 3.8095497234064709e1;pw[39] = 9.2097916367430484e-18; + px[40] = 4.0116547513131397e1;pw[40] = 1.2237146175390552e-18; + px[41] = 4.2195549534376423e1;pw[41] = 1.5345540324461345e-19; + px[42] = 4.4333148057213359e1;pw[42] = 1.8150011522883905e-20; + px[43] = 4.6530017299294814e1;pw[43] = 2.0233572060917363e-21; + px[44] = 4.8786862371793691e1;pw[44] = 2.1245357575136396e-22; + px[45] = 5.1104420821036147e1;pw[45] = 2.0995790452740547e-23; + px[46] = 5.3483464285898315e1;pw[46] = 1.9513862776804163e-24; + px[47] = 5.5924800281409502e1;pw[47] = 1.7043065745685083e-25; + px[48] = 5.8429274120167462e1;pw[48] = 1.3975904770003455e-26; + px[49] = 6.0997770984486184e1;pw[49] = 1.0751199957435543e-27; + px[50] = 6.3631218163686521e1;pw[50] = 7.7513543786225607e-29; + px[51] = 6.6330587472631968e1;pw[51] = 5.2326478018346559e-30; + px[52] = 6.9096897869537813e1;pw[52] = 3.3040599143163473e-31; + px[53] = 7.1931218293279340e1;pw[53] = 1.9493708377000895e-32; + px[54] = 7.4834670742938227e1;pw[54] = 1.0734353038941787e-33; + px[55] = 7.7808433625208567e1;pw[55] = 5.5103919609823204e-35; + px[56] = 8.0853745398597933e1;pw[56] = 2.6337753192506890e-36; + px[57] = 8.3971908547179854e1;pw[57] = 1.1705805971768911e-37; + px[58] = 8.7164293921072095e1;pw[58] = 4.8312277173311803e-39; + px[59] = 9.0432345485938809e1;pw[59] = 1.8489404848533130e-40; + px[60] = 9.3777585529775213e1;pw[60] = 6.5514799851540860e-42; + px[61] = 9.7201620382189983e1;pw[61] = 2.1459149564917285e-43; + px[62] = 1.0070614670954704e2;pw[62] = 6.4864747764771309e-45; + px[63] = 1.0429295845890204e2;pw[63] = 1.8061451197301461e-46; + px[64] = 1.0796395453496108e2;pw[64] = 4.6240601087164368e-48; + px[65] = 1.1172114730766026e2;pw[65] = 1.0863042774855916e-49; + px[66] = 1.1556667206386112e2;pw[66] = 2.3367590047772692e-51; + px[67] = 1.1950279753563604e2;pw[67] = 4.5923018372463456e-53; + px[68] = 1.2353193766037873e2;pw[68] = 8.2254183241711378e-55; + px[69] = 1.2765666475539859e2;pw[69] = 1.3393229733255628e-56; + px[70] = 1.3187972432286344e2;pw[70] = 1.9770897715441433e-58; + px[71] = 1.3620405174137066e2;pw[71] = 2.6382340385810416e-60; + px[72] = 1.4063279114988850e2;pw[72] = 3.1724019756972273e-62; + px[73] = 1.4516931689069355e2;pw[73] = 3.4260518574631090e-64; + px[74] = 1.4981725795333762e2;pw[74] = 3.3110336284062607e-66; + px[75] = 1.5458052595568164e2;pw[75] = 2.8523873910804969e-68; + px[76] = 1.5946334731603723e2;pw[76] = 2.1812446026410382e-70; + px[77] = 1.6447030041968208e2;pw[77] = 1.4739245558990479e-72; + px[78] = 1.6960635877321616e2;pw[78] = 8.7573978000268771e-75; + px[79] = 1.7487694138470448e2;pw[79] = 4.5505714966004102e-77; + px[80] = 1.8028797192464818e2;pw[80] = 2.0558561295409975e-79; + px[81] = 1.8584594863812376e2;pw[81] = 8.0232998204915563e-82; + px[82] = 1.9155802752806165e2;pw[82] = 2.6857246723649169e-84; + px[83] = 1.9743212206533502e2;pw[83] = 7.6508024905351989e-87; + px[84] = 2.0347702367824598e2;pw[84] = 1.8386578992442195e-89; + px[85] = 2.0970254864305275e2;pw[85] = 3.6915967746713164e-92; + px[86] = 2.1611971890494698e2;pw[86] = 6.1249132399226474e-95; + px[87] = 2.2274098706028915e2;pw[87] = 8.2946217677700358e-98; + px[88] = 2.2958051962428511e2;pw[88] = 9.0408055705882247e-101; + px[89] = 2.3665455843056904e2;pw[89] = 7.8044833919279015e-104; + px[90] = 2.4398188860512600e2;pw[90] = 5.2375692667980381e-107; + px[91] = 2.5158445479007743e2;pw[91] = 2.6738203410490589e-110; + px[92] = 2.5948818823677792e2;pw[92] = 1.0120749135417976e-113; + px[93] = 2.6772414159918294e2;pw[93] = 2.7544888677231600e-117; + px[94] = 2.7633008621234766e2;pw[94] = 5.1929686996596160e-121; + px[95] = 2.8535282906339674e2;pw[95] = 6.4755792717472659e-125; + px[96] = 2.9485169696486133e2;pw[96] = 5.0218621637969880e-129; + px[97] = 3.0490401093647767e2;pw[97] = 1.9758139579198723e-133; + px[98] = 3.1561417142961915e2;pw[98] = 2.6170200395803803e-134; + px[99] = 3.2712983445040887e2;pw[99] = 2.0394890255436422e-51; + px[100] = 3.3967355383586156e2;pw[100] = 1.9410589620744451e-56; + px[101] = 3.5361350610111344e2;pw[101] = 1.9061593758307076e-70; + px[102] = 3.6965798176808293e2;pw[102] = 9.4662691701560053e-80; + px[103] = 3.8964232774217858e2;pw[103] = 1.1104725813752798e-82; + break; + case 112: + px[0] = 5.4953341803301609e-3;pw[0] = 2.9489826922398073e-1; + px[1] = 4.9459621920962637e-2;pw[1] = 2.8222796178145113e-1; + px[2] = 1.3739680892391444e-1;pw[2] = 2.5849487746587741e-1; + px[3] = 2.6932412751335894e-1;pw[3] = 2.2657942282144552e-1; + px[4] = 4.4526744940170549e-1;pw[4] = 1.9006161252137982e-1; + px[5] = 6.6526131362871422e-1;pw[5] = 1.5256636998998856e-1; + px[6] = 9.2934896392688816e-1;pw[6] = 1.1719118584424322e-1; + px[7] = 1.2375823956108998e0;pw[7] = 8.6135126997093899e-2; + px[8] = 1.5900224121141247e0;pw[8] = 6.0574317417714514e-2; + px[9] = 1.9867386913212612e0;pw[9] = 4.0755803971739961e-2; + px[10] = 2.4278098618726480e0;pw[10] = 2.6233066082736348e-2; + px[11] = 2.9133235896433742e0;pw[11] = 1.6152112426163087e-2; + px[12] = 3.4433766746287615e0;pw[12] = 9.5123620147754134e-3; + px[13] = 4.0180751584974267e0;pw[13] = 5.3577229622045945e-3; + px[14] = 4.6375344431040623e0;pw[14] = 2.8857253991993310e-3; + px[15] = 5.3018794202864780e0;pw[15] = 1.4861359153491582e-3; + px[16] = 6.0112446133054996e0;pw[16] = 7.3169919995809469e-4; + px[17] = 6.7657743303222200e0;pw[17] = 3.4436155411986205e-4; + px[18] = 7.5656228303450516e0;pw[18] = 1.5489520162150497e-4; + px[19] = 8.4109545021192616e0;pw[19] = 6.6578086192592747e-5; + px[20] = 9.3019440564744304e0;pw[20] = 2.7341291782963178e-5; + px[21] = 1.0238776732690826e1;pw[21] = 1.0725583190203260e-5; + px[22] = 1.1221648519494320e1;pw[22] = 4.0183900973494323e-6; + px[23] = 1.2250766391341530e1;pw[23] = 1.4375499392088491e-6; + px[24] = 1.3326348560712631e1;pw[24] = 4.9095191796603443e-7; + px[25] = 1.4448624747189284e1;pw[25] = 1.6002973367034795e-7; + px[26] = 1.5617836464159565e1;pw[26] = 4.9774112595986853e-8; + px[27] = 1.6834237324061373e1;pw[27] = 1.4768543773235768e-8; + px[28] = 1.8098093363150867e1;pw[28] = 4.1791497540829771e-9; + px[29] = 1.9409683386863716e1;pw[29] = 1.1275442160204611e-9; + px[30] = 2.0769299336924940e1;pw[30] = 2.8996675589492684e-10; + px[31] = 2.2177246681458568e1;pw[31] = 7.1055803679543191e-11; + px[32] = 2.3633844829452103e1;pw[32] = 1.6586292637190786e-11; + px[33] = 2.5139427571043608e1;pw[33] = 3.6868289748704489e-12; + px[34] = 2.6694343545222255e1;pw[34] = 7.8011677084046385e-13; + px[35] = 2.8298956736667379e1;pw[35] = 1.5707664005052362e-13; + px[36] = 2.9953647003597728e1;pw[36] = 3.0084617930185426e-14; + px[37] = 3.1658810638663093e1;pw[37] = 5.4788162867425923e-15; + px[38] = 3.3414860965086388e1;pw[38] = 9.4832975673093346e-16; + px[39] = 3.5222228970457193e1;pw[39] = 1.5594657436863047e-16; + px[40] = 3.7081363980789887e1;pw[40] = 2.4352390869127641e-17; + px[41] = 3.8992734377692841e1;pw[41] = 3.6095571137034836e-18; + px[42] = 4.0956828361752369e1;pw[42] = 5.0757642386344912e-19; + px[43] = 4.2974154765518962e1;pw[43] = 6.7680555851412924e-20; + px[44] = 4.5045243919797104e1;pw[44] = 8.5528682924618337e-21; + px[45] = 4.7170648577287264e1;pw[45] = 1.0237779829567897e-21; + px[46] = 4.9350944898013731e1;pw[46] = 1.1601029671831009e-22; + px[47] = 5.1586733501399526e1;pw[47] = 1.2437241818417510e-23; + px[48] = 5.3878640590325199e1;pw[48] = 1.2607163390079573e-24; + px[49] = 5.6227319153038116e1;pw[49] = 1.2075186187234281e-25; + px[50] = 5.8633450249370054e1;pw[50] = 1.0920906578859209e-26; + px[51] = 6.1097744388381858e1;pw[51] = 9.3197543545708300e-28; + px[52] = 6.3620943005294023e1;pw[52] = 7.4991199467470311e-29; + px[53] = 6.6203820046392479e1;pw[53] = 5.6851415515118275e-30; + px[54] = 6.8847183671532207e1;pw[54] = 4.0573989053601805e-31; + px[55] = 7.1551878084912556e1;pw[55] = 2.7237314698332196e-32; + px[56] = 7.4318785505984439e1;pw[56] = 1.7183408111964119e-33; + px[57] = 7.7148828293691083e1;pw[57] = 1.0178497763141794e-34; + px[58] = 8.0042971238764368e1;pw[58] = 5.6554871509106191e-36; + px[59] = 8.3002224040525493e1;pw[59] = 2.9446351279717004e-37; + px[60] = 8.6027643986604472e1;pw[60] = 1.4351943180018244e-38; + px[61] = 8.9120338856236006e1;pw[61] = 6.5407638433990210e-40; + px[62] = 9.2281470070355184e1;pw[62] = 2.7840843888220453e-41; + px[63] = 9.5512256114659083e1;pw[63] = 1.1054661469676639e-42; + px[64] = 9.8813976265183997e1;pw[64] = 4.0894445809546643e-44; + px[65] = 1.0218797464984955e2;pw[65] = 1.4075301928520080e-45; + px[66] = 1.0563566468393243e2;pw[66] = 4.5010556553905317e-47; + px[67] = 1.0915853392266498e2;pw[67] = 1.3353375262485678e-48; + px[68] = 1.1275814938024115e2;pw[68] = 3.6695275610607160e-50; + px[69] = 1.1643616337161760e2;pw[69] = 9.3251810053654335e-52; + px[70] = 1.2019431994181835e2;pw[70] = 2.1876527359441781e-53; + px[71] = 1.2403446195723057e2;pw[71] = 4.7290816436201351e-55; + px[72] = 1.2795853894491414e2;pw[72] = 9.4017744393225470e-57; + px[73] = 1.3196861577960725e2;pw[73] = 1.7154770732070957e-58; + px[74] = 1.3606688233435014e2;pw[74] = 2.8665242731015198e-60; + px[75] = 1.4025566423003982e2;pw[75] = 4.3763989573541065e-62; + px[76] = 1.4453743484248376e2;pw[76] = 6.0897571742385102e-64; + px[77] = 1.4891482875354178e2;pw[77] = 7.7031170730276684e-66; + px[78] = 1.5339065686687570e2;pw[78] = 8.8328749793303574e-68; + px[79] = 1.5796792345012664e2;pw[79] = 9.1539586505379100e-70; + px[80] = 1.6264984541588618e2;pw[80] = 8.5466832132929860e-72; + px[81] = 1.6743987421605101e2;pw[81] = 7.1643610696800221e-74; + px[82] = 1.7234172080122024e2;pw[82] = 5.3721243887414992e-76; + px[83] = 1.7735938419287581e2;pw[83] = 3.5890274005464772e-78; + px[84] = 1.8249718433670430e2;pw[84] = 2.1271822587291959e-80; + px[85] = 1.8775980005795738e2;pw[85] = 1.1132951771397071e-82; + px[86] = 1.9315231313418438e2;pw[86] = 5.1191820200621500e-85; + px[87] = 1.9868025975060599e2;pw[87] = 2.0567744853280919e-87; + px[88] = 2.0434969092759117e2;pw[88] = 7.1772526649596168e-90; + px[89] = 2.1016724393431546e2;pw[89] = 2.1609888032718971e-92; + px[90] = 2.1614022726467649e2;pw[90] = 5.5733711965802891e-95; + px[91] = 2.2227672250383794e2;pw[91] = 1.2214353570041591e-97; + px[92] = 2.2858570743324025e2;pw[92] = 2.2544498870469226e-100; + px[93] = 2.3507720612202630e2;pw[93] = 3.4698364983238705e-103; + px[94] = 2.4176247370399097e2;pw[94] = 4.4037992320193089e-106; + px[95] = 2.4865422630218547e2;pw[95] = 4.5511410854658978e-109; + px[96] = 2.5576693054575381e2;pw[96] = 3.7753744367507348e-112; + px[97] = 2.6311717297716247e2;pw[97] = 2.4729177063662401e-115; + px[98] = 2.7072413844178640e2;pw[98] = 1.2549250228724467e-118; + px[99] = 2.7861024009039942e2;pw[99] = 4.8255791873729851e-122; + px[100] = 2.8680196505406753e2;pw[100] = 1.3697149157065236e-125; + px[101] = 2.9533103485728541e2;pw[101] = 2.7803242111394275e-129; + px[102] = 3.0423603893997241e2;pw[102] = 5.7192111543195200e-133; + px[103] = 3.1356480447692787e2;pw[103] = 2.7224139503928083e-135; + px[104] = 3.2337796045230511e2;pw[104] = 1.4985049959339292e-124; + px[105] = 3.3375453828748506e2;pw[105] = 2.4300435849929846e-132; + px[106] = 3.4480126780658105e2;pw[106] = 1.2259326780033627e-133; + px[107] = 3.5666913087724963e2;pw[107] = 2.4281860924963857e-51; + px[108] = 3.6958574691724203e2;pw[108] = 1.3766733748904064e-55; + px[109] = 3.8392777037966436e2;pw[109] = 5.9376811746370755e-69; + px[110] = 4.0042001600670709e2;pw[110] = 2.6857350954106024e-82; + px[111] = 4.2094130637188611e2;pw[111] = 2.9834955778444689e-81; + break; + case 120: + px[0] = 5.1297391669498222e-3;pw[0] = 2.8502395317547204e-1; + px[1] = 4.6168965558965583e-2;pw[1] = 2.7357523293518048e-1; + px[2] = 1.2825442268012189e-1;pw[2] = 2.5203716182373969e-1; + px[3] = 2.5140012578184619e-1;pw[3] = 2.2286337164152000e-1; + px[4] = 4.1562711419913549e-1;pw[4] = 1.8914288655924106e-1; + px[5] = 6.2096347114179658e-1;pw[5] = 1.5406584277742807e-1; + px[6] = 8.6744435015264118e-1;pw[6] = 1.2044049267022821e-1; + px[7] = 1.1551120082929025e0;pw[7] = 9.0358744219355181e-2; + px[8] = 1.4840158461306763e0;pw[8] = 6.5054591666537773e-2; + px[9] = 1.8542124546240439e0;pw[9] = 4.4943958036852311e-2; + px[10] = 2.2657656690067761e0;pw[10] = 2.9793575056951512e-2; + px[11] = 2.7187466298012132e0;pw[11] = 1.8949643702576734e-2; + px[12] = 3.2132338511001456e0;pw[12] = 1.1563055121878621e-2; + px[13] = 3.7493132962773567e0;pw[13] = 6.7686183318686482e-3; + px[14] = 4.3270784613050146e0;pw[14] = 3.8005184078890596e-3; + px[15] = 4.9466304658754044e0;pw[15] = 2.0467143746931182e-3; + px[16] = 5.6080781525446617e0;pw[16] = 1.0570513354181031e-3; + px[17] = 6.3115381941373083e0;pw[17] = 5.2349052163887461e-4; + px[18] = 7.0571352096725975e0;pw[18] = 2.4856586787767428e-4; + px[19] = 7.8450018890970696e0;pw[19] = 1.1314532553553562e-4; + px[20] = 8.6752791271324176e0;pw[20] = 4.9366594298931427e-5; + px[21] = 9.5481161665738945e0;pw[21] = 2.0642700128290312e-5; + px[22] = 1.0463670751402208e1;pw[22] = 8.2711958203927816e-6; + px[23] = 1.1422109290101294e1;pw[23] = 3.1751663936728944e-6; + px[24] = 1.2423607029605695e1;pw[24] = 1.1675760027782005e-6; + px[25] = 1.3468348240334714e1;pw[25] = 4.1119185727034140e-7; + px[26] = 1.4556526412806197e1;pw[26] = 1.3866304189070192e-7; + px[27] = 1.5688344466361026e1;pw[27] = 4.4765756397348091e-8; + px[28] = 1.6864014970570331e1;pw[28] = 1.3832734889608059e-8; + px[29] = 1.8083760379941373e1;pw[29] = 4.0902585285705370e-9; + px[30] = 1.9347813282585301e1;pw[30] = 1.1571064421471916e-9; + px[31] = 2.0656416663560776e1;pw[31] = 3.1309092427946476e-10; + px[32] = 2.2009824183662284e1;pw[32] = 8.1008838545649928e-11; + px[33] = 2.3408300474481054e1;pw[33] = 2.0037543940941961e-11; + px[34] = 2.4852121450630391e1;pw[34] = 4.7368238655988873e-12; + px[35] = 2.6341574640096350e1;pw[35] = 1.0698826247166949e-12; + px[36] = 2.7876959533749559e1;pw[36] = 2.3081364934421758e-13; + px[37] = 2.9458587955135198e1;pw[37] = 4.7547562946209405e-14; + px[38] = 3.1086784451746349e1;pw[38] = 9.3496621251942795e-15; + px[39] = 3.2761886709081786e1;pw[39] = 1.7543580097101897e-15; + px[40] = 3.4484245988893703e1;pw[40] = 3.1400971154418774e-16; + px[41] = 3.6254227593144597e1;pw[41] = 5.3593522678761522e-17; + px[42] = 3.8072211355316697e1;pw[42] = 8.7188945766817631e-18; + px[43] = 3.9938592160852983e1;pw[43] = 1.3515106234226978e-18; + px[44] = 4.1853780498657202e1;pw[44] = 1.9953021921306626e-19; + px[45] = 4.3818203045742856e1;pw[45] = 2.8044282474471764e-20; + px[46] = 4.5832303287299388e1;pw[46] = 3.7508906971614997e-21; + px[47] = 4.7896542174639558e1;pw[47] = 4.7717681635147569e-22; + px[48] = 5.0011398823707265e1;pw[48] = 5.7712738310619112e-23; + px[49] = 5.2177371257062108e1;pw[49] = 6.6327836836945849e-24; + px[50] = 5.4394977192518312e1;pw[50] = 7.2398182117815891e-25; + px[51] = 5.6664754881904218e1;pw[51] = 7.5012587727931265e-26; + px[52] = 5.8987264003727612e1;pw[52] = 7.3734885029706274e-27; + px[53] = 6.1363086613885492e1;pw[53] = 6.8721443844602975e-28; + px[54] = 6.3792828158948708e1;pw[54] = 6.0691779183687126e-29; + px[55] = 6.6277118556987132e1;pw[55] = 5.0759007367076133e-30; + px[56] = 6.8816613351385211e1;pw[56] = 4.0175221438220706e-31; + px[57] = 7.1411994943637213e1;pw[57] = 3.0072530813297540e-32; + px[58] = 7.4063973911713684e1;pw[58] = 2.1273584216828318e-33; + px[59] = 7.6773290421263832e1;pw[59] = 1.4211829797498313e-34; + px[60] = 7.9540715737672631e1;pw[60] = 8.9590957177462511e-36; + px[61] = 8.2367053847837527e1;pw[61] = 5.3251918761543396e-37; + px[62] = 8.5253143201480774e1;pw[62] = 2.9819503451853612e-38; + px[63] = 8.8199858582884791e1;pw[63] = 1.5717412988204925e-39; + px[64] = 9.1208113125147039e1;pw[64] = 7.7908008505381426e-41; + px[65] = 9.4278860480418384e1;pw[65] = 3.6281971412784443e-42; + px[66] = 9.7413097161138711e1;pw[66] = 1.5859015177178711e-43; + px[67] = 1.0061186506904395e2;pw[67] = 6.4996104375459879e-45; + px[68] = 1.0387625423072283e2;pw[68] = 2.4948970341280962e-46; + px[69] = 1.0720740576078862e2;pw[69] = 8.9593901038397884e-48; + px[70] = 1.1060651507634780e2;pw[70] = 3.0064061869829462e-49; + px[71] = 1.1407483538944766e2;pw[71] = 9.4149529210783543e-51; + px[72] = 1.1761368150763627e2;pw[72] = 2.7480284196099378e-52; + px[73] = 1.2122443397674619e2;pw[73] = 7.4655144872656008e-54; + px[74] = 1.2490854360461544e2;pw[74] = 1.8849778633354656e-55; + px[75] = 1.2866753640979513e2;pw[75] = 4.4167295028366118e-57; + px[76] = 1.3250301904550293e2;pw[76] = 9.5884544111130115e-59; + px[77] = 1.3641668475632833e2;pw[77] = 1.9253846157160579e-60; + px[78] = 1.4041031993368383e2;pw[78] = 3.5697275921210464e-62; + px[79] = 1.4448581134597201e2;pw[79] = 6.0993788510648131e-64; + px[80] = 1.4864515413120591e2;pw[80] = 9.5853191608176058e-66; + px[81] = 1.5289046065375615e2;pw[81] = 1.3825627736640795e-67; + px[82] = 1.5722397034346682e2;pw[82] = 1.8262174400320119e-69; + px[83] = 1.6164806065516658e2;pw[83] = 2.2038494574755515e-71; + px[84] = 1.6616525931033000e2;pw[84] = 2.4237108166704223e-73; + px[85] = 1.7077825801123656e2;pw[85] = 2.4226238499885409e-75; + px[86] = 1.7548992785259882e2;pw[86] = 2.1946080740100573e-77; + px[87] = 1.8030333669777762e2;pw[87] = 1.7962565586872283e-79; + px[88] = 1.8522176883828634e2;pw[88] = 1.3240410388018822e-81; + px[89] = 1.9024874731879046e2;pw[89] = 8.7585968525902169e-84; + px[90] = 1.9538805938846759e2;pw[90] = 5.1800274294960421e-86; + px[91] = 2.0064378563766165e2;pw[91] = 2.7279222749641292e-88; + px[92] = 2.0602033350188195e2;pw[92] = 1.2735953172719079e-90; + px[93] = 2.1152247597090631e2;pw[93] = 5.2465045442237418e-93; + px[94] = 2.1715539653923255e2;pw[94] = 1.8971890062657397e-95; + px[95] = 2.2292474168927554e2;pw[95] = 5.9884763458065071e-98; + px[96] = 2.2883668252968495e2;pw[96] = 1.6399282759538974e-100; + px[97] = 2.3489798764468268e2;pw[97] = 3.8700481929789787e-103; + px[98] = 2.4111610978413709e2;pw[98] = 7.8122606315689856e-106; + px[99] = 2.4749928979224946e2;pw[99] = 1.3379893855632987e-108; + px[100] = 2.5405668221374821e2;pw[100] = 1.9266285323004829e-111; + px[101] = 2.6079850844627440e2;pw[101] = 2.3089140588011642e-114; + px[102] = 2.6773624530027240e2;pw[102] = 2.2768662844496908e-117; + px[103] = 2.7488285964960641e2;pw[103] = 1.8239060669490364e-120; + px[104] = 2.8225310392367891e2;pw[104] = 1.1696325620584706e-123; + px[105] = 2.8986389317085953e2;pw[105] = 5.9089203696565755e-127; + px[106] = 2.9773479340583953e2;pw[106] = 2.3982393520466646e-130; + px[107] = 3.0588866478394910e2;pw[107] = 1.3336608988109749e-133; + px[108] = 3.1435252503773286e2;pw[108] = 1.8554662333955921e-131; + px[109] = 3.2315873437660234e2;pw[109] = 5.6745552433723977e-133; + px[110] = 3.3234666364534706e2;pw[110] = 6.4148023503115847e-132; + px[111] = 3.4196511464296833e2;pw[111] = 1.7690546779468858e-132; + px[112] = 3.5207596053730912e2;pw[112] = 2.3559424075535023e-133; + px[113] = 3.6275986709694166e2;pw[113] = 7.0346860953952109e-133; + px[114] = 3.7412578995211861e2;pw[114] = 8.2581860285237120e-132; + px[115] = 3.8632788878085670e2;pw[115] = 3.8298599230421540e-49; + px[116] = 3.9959862252409562e2;pw[116] = 8.6830434227075531e-52; + px[117] = 4.1432274380983757e2;pw[117] = 7.8569306274869450e-66; + px[118] = 4.3124084763817151e2;pw[118] = 1.0876766815421296e-79; + px[119] = 4.5227326181239169e2;pw[119] = 1.7576416430685541e-80; + break; + case 128: + px[0] = 4.8097546269833893e-3;pw[0] = 2.7607937255104182e-1; + px[1] = 4.3288873981462912e-2;pw[1] = 2.6566783614880718e-1; + px[2] = 1.2025288615546319e-1;pw[2] = 2.4600646227023164e-1; + px[3] = 2.3571334284486281e-1;pw[3] = 2.1920556026860463e-1; + px[4] = 3.8968758351746751e-1;pw[4] = 1.8795185561410056e-1; + px[5] = 5.8219874974842322e-1;pw[5] = 1.5506780698139096e-1; + px[6] = 8.1327580437858389e-1;pw[6] = 1.2310171404959776e-1; + px[7] = 1.0829535555341720e0;pw[7] = 9.4028368962612467e-2; + px[8] = 1.3912726855559166e0;pw[8] = 6.9101651733143485e-2; + px[9] = 1.7382797848958800e0;pw[9] = 4.8857640815463552e-2; + px[10] = 2.1240273910504205e0;pw[10] = 3.3232907130961684e-2; + px[11] = 2.5485740326082378e0;pw[11] = 2.1745560021797622e-2; + px[12] = 3.0119842785032310e0;pw[12] = 1.3687095820753643e-2; + px[13] = 3.5143287925730293e0;pw[13] = 8.2862847528073521e-3; + px[14] = 4.0556843935355590e0;pw[14] = 4.8248404263837572e-3; + px[15] = 4.6361341205079486e0;pw[15] = 2.7017467389205526e-3; + px[16] = 5.2557673042044822e0;pw[16] = 1.4548097345670083e-3; + px[17] = 5.9146796439632562e0;pw[17] = 7.5322752691836494e-4; + px[18] = 6.6129732907647177e0;pw[18] = 3.7493875811399589e-4; + px[19] = 7.3507569364194338e0;pw[19] = 1.7941616616270753e-4; + px[20] = 8.1281459091173179e0;pw[20] = 8.2523935092697431e-5; + px[21] = 8.9452622755461916e0;pw[21] = 3.6480646490280587e-5; + px[22] = 9.8022349498040578e0;pw[22] = 1.5497209992155702e-5; + px[23] = 1.0699199809346890e1;pw[23] = 6.3254880868062279e-6; + px[24] = 1.1636299818232177e1;pw[24] = 2.4804025381841617e-6; + px[25] = 1.2613685157937996e1;pw[25] = 9.3427092817735856e-7; + px[26] = 1.3631513366058145e1;pw[26] = 3.3796972810877498e-7; + px[27] = 1.4689949483195887e1;pw[27] = 1.1739931842906987e-7; + px[28] = 1.5789166208402366e1;pw[28] = 3.9152666460117425e-8; + px[29] = 1.6929344063530748e1;pw[29] = 1.2533919800530000e-8; + px[30] = 1.8110671566903898e1;pw[30] = 3.8508855814103435e-9; + px[31] = 1.9333345416721943e1;pw[31] = 1.1352650067802054e-9; + px[32] = 2.0597570684666645e1;pw[32] = 3.2107610902767967e-10; + px[33] = 2.1903561020192286e1;pw[33] = 8.7096417230648332e-11; + px[34] = 2.3251538866027899e1;pw[34] = 2.2655716245890225e-11; + px[35] = 2.4641735685453456e1;pw[35] = 5.6498933794313194e-12; + px[36] = 2.6074392201953201e1;pw[36] = 1.3504651749637866e-12; + px[37] = 2.7549758651893053e1;pw[37] = 3.0931346162094001e-13; + px[38] = 2.9068095050916087e1;pw[38] = 6.7869387110402112e-14; + px[39] = 3.0629671474800940e1;pw[39] = 1.4262371047812445e-14; + px[40] = 3.2234768355582876e1;pw[40] = 2.8696621621608344e-15; + px[41] = 3.3883676793796597e1;pw[41] = 5.5266882811584044e-16; + px[42] = 3.5576698887764130e1;pw[42] = 1.0185057527135605e-16; + px[43] = 3.7314148080920709e1;pw[43] = 1.7955213298120343e-17; + px[44] = 3.9096349528247114e1;pw[44] = 3.0269510335107605e-18; + px[45] = 4.0923640482958862e1;pw[45] = 4.8782259058116175e-19; + px[46] = 4.2796370704691817e1;pw[46] = 7.5129177544606858e-20; + px[47] = 4.4714902890520744e1;pw[47] = 1.1053212066329750e-20; + px[48] = 4.6679613130253012e1;pw[48] = 1.5528826688231492e-21; + px[49] = 4.8690891387554891e1;pw[49] = 2.0825248019667178e-22; + px[50] = 5.0749142008593753e1;pw[50] = 2.6648208774549398e-23; + px[51] = 5.2854784260017013e1;pw[51] = 3.2523000556521267e-24; + px[52] = 5.5008252898239286e1;pw[52] = 3.7841616175987121e-25; + px[53] = 5.7209998772174173e1;pw[53] = 4.1957539145536696e-26; + px[54] = 5.9460489461728161e1;pw[54] = 4.4310753939163665e-27; + px[55] = 6.1760209954572964e1;pw[55] = 4.4550960738061500e-28; + px[56] = 6.4109663363931410e1;pw[56] = 4.2622210868369363e-29; + px[57] = 6.6509371690352848e1;pw[57] = 3.8781073546455843e-30; + px[58] = 6.8959876630719803e1;pw[58] = 3.3540852993298416e-31; + px[59] = 7.1461740438021006e1;pw[59] = 2.7558487347346862e-32; + px[60] = 7.4015546835750457e1;pw[60] = 2.1498637246741931e-33; + px[61] = 7.6621901991151567e1;pw[61] = 1.5913963136894115e-34; + px[62] = 7.9281435551924119e1;pw[62] = 1.1170819746689115e-35; + px[63] = 8.1994801751454565e1;pw[63] = 7.4310093282819445e-37; + px[64] = 8.4762680588122938e1;pw[64] = 4.6813625515950693e-38; + px[65] = 8.7585779084788683e1;pw[65] = 2.7909522621573202e-39; + px[66] = 9.0464832635170634e1;pw[66] = 1.5735113668960615e-40; + px[67] = 9.3400606444521639e1;pw[67] = 8.3828847876304648e-42; + px[68] = 9.6393897072765977e1;pw[68] = 4.2167560748751703e-43; + px[69] = 9.9445534089129095e1;pw[69] = 2.0010861658834713e-44; + px[70] = 1.0255638184825758e2;pw[70] = 8.9512017753845699e-46; + px[71] = 1.0572734139891817e2;pw[71] = 3.7708148208752655e-47; + px[72] = 1.0895935253759580e2;pw[72] = 1.4945851640195755e-48; + px[73] = 1.1225339602070313e2;pw[73] = 5.5681807795587594e-50; + px[74] = 1.1561049595069244e2;pw[74] = 1.9479151853826422e-51; + px[75] = 1.1903172235315340e2;pw[75] = 6.3918683903792039e-53; + px[76] = 1.2251819396402152e2;pw[76] = 1.9651813087431218e-54; + px[77] = 1.2607108124835155e2;pw[77] = 5.6544197387738892e-56; + px[78] = 1.2969160967477476e2;pw[78] = 1.5207362927895532e-57; + px[79] = 1.3338106327281588e2;pw[79] = 3.8180775856184579e-59; + px[80] = 1.3714078850376025e2;pw[80] = 8.9367191262601894e-61; + px[81] = 1.4097219847981490e2;pw[81] = 1.9473442897375391e-62; + px[82] = 1.4487677757099489e2;pw[82] = 3.9445422891662265e-64; + px[83] = 1.4885608644460317e2;pw[83] = 7.4159150213626314e-66; + px[84] = 1.5291176758849769e2;pw[84] = 1.2919234936181112e-67; + px[85] = 1.5704555137672418e2;pw[85] = 2.0819221394737772e-69; + px[86] = 1.6125926274474058e2;pw[86] = 3.0978378698037742e-71; + px[87] = 1.6555482855162421e2;pw[87] = 4.2480171859192708e-73; + px[88] = 1.6993428571864366e2;pw[88] = 5.3575541752687071e-75; + px[89] = 1.7439979024777800e2;pw[89] = 6.2010829537374423e-77; + px[90] = 1.7895362724065057e2;pw[90] = 6.5720579636670588e-79; + px[91] = 1.8359822205850647e2;pw[91] = 6.3623825304174234e-81; + px[92] = 1.8833615278804584e2;pw[92] = 5.6118813553226041e-83; + px[93] = 1.9317016420706524e2;pw[93] = 4.4976052330512204e-85; + px[94] = 1.9810318347914946e2;pw[94] = 3.2656789300649514e-87; + px[95] = 2.0313833784961355e2;pw[95] = 2.1415773771514337e-89; + px[96] = 2.0827897466747490e2;pw[96] = 1.2642009038210272e-91; + px[97] = 2.1352868412296766e2;pw[97] = 6.6937523730388343e-94; + px[98] = 2.1889132517029559e2;pw[98] = 3.1668515385882014e-96; + px[99] = 2.2437105520529297e2;pw[99] = 1.3331988108895188e-98; + px[100] = 2.2997236419317798e2;pw[100] = 4.9720167074631327e-101; + px[101] = 2.3570011410033001e2;pw[101] = 1.6347801791277616e-103; + px[102] = 2.4155958468639006e2;pw[102] = 4.7134964221305137e-106; + px[103] = 2.4755652697313934e2;pw[103] = 1.1851002424541479e-108; + px[104] = 2.5369722604409365e2;pw[104] = 2.5820543464647026e-111; + px[105] = 2.5998857527081546e2;pw[105] = 4.8417253805291566e-114; + px[106] = 2.6643816464709542e2;pw[106] = 7.7550688581883223e-117; + px[107] = 2.7305438669552003e2;pw[107] = 1.0522110136923271e-119; + px[108] = 2.7984656447262174e2;pw[108] = 1.1982172530332628e-122; + px[109] = 2.8682510765704206e2;pw[109] = 1.1333834975480497e-125; + px[110] = 2.9400170473751538e2;pw[110] = 8.8091250671314200e-129; + px[111] = 3.0138956219582173e2;pw[111] = 5.1031266854191002e-132; + px[112] = 3.0900370572897370e2;pw[112] = 3.7889105113753785e-134; + px[113] = 3.1686136465414833e2;pw[113] = 1.6614242788060531e-135; + px[114] = 3.2498246980378542e2;pw[114] = 3.3159273335592529e-133; + px[115] = 3.3339030932831591e2;pw[115] = 6.6730040001944718e-134; + px[116] = 3.4211240916012430e2;pw[116] = 1.2949575356743615e-133; + px[117] = 3.5118174138517492e2;pw[117] = 9.1532484444758395e-133; + px[118] = 3.6063842559961562e2;pw[118] = 1.9549729552902828e-134; + px[119] = 3.7053219762567725e2;pw[119] = 8.0781662197334676e-122; + px[120] = 3.8092612308026272e2;pw[120] = 3.7898513479231859e-137; + px[121] = 3.9190243416377710e2;pw[121] = 1.0948592196247296e-132; + px[122] = 4.0357221976913419e2;pw[122] = 3.6495237116054534e-50; + px[123] = 4.1609268503849895e2;pw[123] = 7.9553417261007054e-54; + px[124] = 4.2970092632479113e2;pw[124] = 5.8160707456163802e-67; + px[125] = 4.4478945491488902e2;pw[125] = 1.6308626485034593e-79; + px[126] = 4.6211398112631172e2;pw[126] = 8.1797036981379553e-83; + px[127] = 4.8363457770593729e2;pw[127] = 4.4300469125827045e-82; + break; + } + } + + /***************************************************************************************/ + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + template + void Quad_Data_T::cgqf(dt_int32 kind, dt_int32 nt, T alpha, T beta, T a, T b, T t[], T wts[]) + // Purpose: + // + // CGQF computes knots and weights of a Gauss quad_data formula. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // The user may specify the interval (A, B). + // Only simple knots are produced. + // Use routine EIQFS to evaluate this quad_data formula. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data_T, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev Type 1, (a, b) ((b-x)*(x-a))^-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, +oo) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-oo, +oo) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, +oo) (x-a)^alpha*(x+b)^beta + // 9, chebyshev Type 2, (a, b) ((b-x)*(x-a))^(+0.5) + // + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // in, T A, B, the interval endpoints, or other parameters. + // + // Output, T T[NT], the knots. + // Output, T WTS[NT], the weights. + { + dt_int32 *mlt; + dt_int32 *ndx; + // Compute the Gauss quad_data formula for default values of A and B. + cdgqf(kind, nt, alpha, beta, t, wts); + + // Prepare to fcn_scale the quad_data formula to other weight function with valid A and B. + mlt = new dt_int32[nt]; + for(auto i = 0; i < nt; i++) + { + mlt[i] = 1; + } + ndx = new dt_int32[nt]; + + for(auto i = 0; i < nt; i++) + { + ndx[i] = i + 1; + } + scqf(nt, t, mlt, wts, nt, ndx, wts, t, kind, alpha, beta, a, b); + + delete[] mlt; + delete[] ndx; + + return; + } + + template + void Quad_Data_T::cdgqf(dt_int32 kind, dt_int32 nt, T alpha, T beta, T t[], T wts[]) + // Purpose: + // + // CDGQF computes a Gauss quad_data formula with default A, B and simple knots. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine computes all the knots and weights of a Gauss quad_data + // formula with a classical weight function with default values for A and B, + // and only simple knots. + // There are no moments checks and no printing is done. + // Use routine EIQFS to evaluate a quad_data computed by CGQFS. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data_T, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + // + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // Output, T T[NT], the knots. + // Output, T WTS[NT], the weights. + { + T* aj; + T* bj; + T zemu; + + parchk(kind, 2 * nt, alpha, beta); + // Get the jacobi matrix and zero-th moment. + aj = new T[nt]; + bj = new T[nt]; + + zemu = class_matrix(kind, nt, alpha, beta, aj, bj); + // Compute the knots and weights. + sgqf(nt, aj, bj, zemu, t, wts); + + delete[] aj; + delete[] bj; + + return; + } + + template + T Quad_Data_T::class_matrix(dt_int32 kind, dt_int32 m, T alpha, T beta, T aj[], T bj[]) + // Purpose: + // + // CLASS_MATRIX computes the jacobi matrix for a quad_data rule. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine computes the diagonal AJ and sub-diagonal BJ + // elements of the order M tridiagonal symmetric jacobi matrix + // associated with the polynomials orthogonal with respect to + // the weight function specified by KIND. + // + // For weight functions 1-7, M elements are defined in BJ even + // though only M-1 are needed. For weight function 8, BJ(M) is + // set to zero. + // + // The zero-th moment of the weight function is returned in ZEMU. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data_T, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + // + // in, dt_int32 M, the order of the jacobi matrix. + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // Output, T AJ[M], BJ[M], the diagonal and subdiagonal + // of the jacobi matrix. + // Output, T CLASS_MATRIX, the zero-th moment. + { + T a2b2; + T ab; + T aba; + T abi; + T abj; + T abti; + T apone; + dt_int32 i; + T pi = 3.14159265358979323846264338327950; + T temp; + T temp2; + T zemu; + + temp = r8_epsilon(); + + parchk(kind, 2 * m - 1, alpha, beta); + + temp2 = 0.5; + + if (500.0 * temp < fabs(pow(tgamma(temp2), 2) - pi)) + { + // cout << "\n"; + // cout << "CLASS_MATRIX - Fatal error!\n"; + // cout << " Gamma function does not match machine parameters.\n"; + // exit(1); + } + + if (kind == 1) + { + ab = 0.0; + + zemu = 2.0/(ab + 1.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + for(i = 1; i <= m; i++) + { + abi = i + ab * (i % 2); + abj = 2 * i + ab; + bj[i - 1] = ::sqrt(abi * abi/(abj * abj - 1.0)); + } + } + else if (kind == 2) + { + zemu = pi; + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + bj[0] = ::sqrt(0.5); + for(i = 1; i < m; i++) + { + bj[i] = 0.5; + } + } + else if (kind == 3) + { + ab = alpha * 2.0; + zemu = pow(2.0, ab + 1.0) * pow(tgamma(alpha + 1.0), 2) + / tgamma(ab + 2.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + bj[0] = ::sqrt(1.0/(2.0 * alpha + 3.0)); + for(i = 2; i <= m; i++) + { + bj[i - 1] = ::sqrt(i * (i + ab)/(4.0 * pow(i + alpha, 2) - 1.0)); + } + } + else if (kind == 4) + { + ab = alpha + beta; + abi = 2.0 + ab; + zemu = pow(2.0, ab + 1.0) * tgamma(alpha + 1.0) + * tgamma(beta + 1.0)/tgamma(abi); + aj[0] = (beta - alpha)/abi; + bj[0] = ::sqrt(4.0 * (1.0 + alpha) * (1.0 + beta) + / ((abi + 1.0) * abi * abi)); + a2b2 = beta * beta - alpha * alpha; + + for(i = 2; i <= m; i++) + { + abi = 2.0 * i + ab; + aj[i - 1] = a2b2/((abi - 2.0) * abi); + abi = abi * abi; + bj[i - 1] = ::sqrt(4.0 * i * (i + alpha) * (i + beta) * (i + ab) + / ((abi - 1.0) * abi)); + } + } + else if (kind == 5) + { + zemu = tgamma(alpha + 1.0); + + for(i = 1; i <= m; i++) + { + aj[i - 1] = 2.0 * i - 1.0 + alpha; + bj[i - 1] = ::sqrt(i * (i + alpha)); + } + } + else if (kind == 6) + { + zemu = tgamma((alpha + 1.0)/2.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + for(i = 1; i <= m; i++) + { + bj[i - 1] = ::sqrt((i + alpha * (i % 2))/2.0); + } + } + else if (kind == 7) + { + ab = alpha; + zemu = 2.0/(ab + 1.0); + + for(i = 0; i < m; i++) + { + aj[i] = 0.0; + } + + for(i = 1; i <= m; i++) + { + abi = i + ab * (i % 2); + abj = 2 * i + ab; + bj[i - 1] = ::sqrt(abi * abi/(abj * abj - 1.0)); + } + } + else if (kind == 8) + { + ab = alpha + beta; + zemu = tgamma(alpha + 1.0) * tgamma(-(ab + 1.0)) + / tgamma(-beta); + apone = alpha + 1.0; + aba = ab * apone; + aj[0] = -apone/(ab + 2.0); + bj[0] = -aj[0] * (beta + 1.0)/(ab + 2.0)/(ab + 3.0); + for(i = 2; i <= m; i++) + { + abti = ab + 2.0 * i; + aj[i - 1] = aba + 2.0 * (ab + i) * (i - 1); + aj[i - 1] = -aj[i - 1]/abti/(abti - 2.0); + } + + for(i = 2; i <= m - 1; i++) + { + abti = ab + 2.0 * i; + bj[i - 1] = i * (alpha + i)/(abti - 1.0) * (beta + i) + / (abti * abti) * (ab + i)/(abti + 1.0); + } + bj[m - 1] = 0.0; + for(i = 0; i < m; i++) + { + bj[i] = ::sqrt(bj[i]); + } + } + + return zemu; + } + + template + void Quad_Data_T::imtqlx(dt_int32 n, T d[], T e[], T z[]) + // Purpose: + // + // IMTQLX diagonalizes a symmetric tridiagonal matrix. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine is a slightly modified version of the EISPACK routine to + // perform the implicit QL algorithm on a symmetric tridiagonal matrix. + // + // The authors thank the authors of EISPACK for permission to use this + // routine. + // + // It has been modified to produce the product coef_quad_1d' * Z, where Z is an in + // vector and coef_quad_1d is the orthogonal matrix diagonalizing the in matrix. + // The changes consist (essentialy) of applying the orthogonal transformations + // directly to Z as they are generated. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data_T, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Roger Martin, James Wilkinson, + // The Implicit QL Algorithm, + // Numerische Mathematik, + // Volume 12, Number 5, December 1968, pages 377-383. + // + // Parameters: + // + // in, dt_int32 N, the order of the matrix. + // + // in/output, T D(N), the diagonal entries of the matrix. + // On output, the information in D has been overwritten. + // + // in/output, T E(N), the subdiagonal entries of the + // matrix, in entries E(1) through E(N-1). On output, the information in + // E has been overwritten. + // + // in/output, T Z(N). On in, a vector. On output, + // the value of coef_quad_1d' * Z, where coef_quad_1d is the matrix that diagonalizes the + // in symmetric tridiagonal matrix. + { + T b; + T c; + T f; + T g; + dt_int32 i; + dt_int32 ii; + dt_int32 itn = 30; + dt_int32 j; + dt_int32 k; + dt_int32 l; + dt_int32 m; + dt_int32 mml; + T p; + T prec; + T r; + T s; + + prec = r8_epsilon(); + + if (n == 1) + { + return; + } + + e[n - 1] = 0.0; + + for(l = 1;l <= n;l++) + { + j = 0; + for( ; ; ) + { + for(m = l;m <= n;m++) + { + if (m == n) + { + break; + } + + if (fabs(e[m - 1]) <= prec * (fabs(d[m - 1]) + fabs(d[m]))) + { + break; + } + } + p = d[l - 1]; + if (m == l) + { + break; + } + if (itn <= j) + { + // cout << "\n"; + // cout << "IMTQLX - Fatal error!\n"; + // cout << " Iteration limit exceeded\n"; + // exit(1); + } + + j = j + 1; + g = (d[l] - p)/(2.0 * e[l - 1]); + r = ::sqrt(g * g + 1.0); + g = d[m - 1] - p + e[l - 1]/(g + fabs(r) * r8_sign(g)); + s = 1.0; + c = 1.0; + p = 0.0; + mml = m - l; + + for(ii = 1; ii <= mml; ii++) + { + i = m - ii; + f = s * e[i - 1]; + b = c * e[i - 1]; + + if (fabs(g) <= fabs(f)) + { + c = g/f; + r = ::sqrt(c * c + 1.0); + e[i] = f * r; + s = 1.0/r; + c = c * s; + } + else + { + s = f/g; + r = ::sqrt(s * s + 1.0); + e[i] = g * r; + c = 1.0/r; + s = s * c; + } + g = d[i] - p; + r = (d[i - 1] - g) * s + 2.0 * c * b; + p = s * r; + d[i] = g + p; + g = c * r - b; + f = z[i]; + z[i] = s * z[i - 1] + c * f; + z[i - 1] = c * z[i - 1] - s * f; + } + d[l - 1] = d[l - 1] - p; + e[l - 1] = g; + e[m - 1] = 0.0; + } + } + // + // Sorting. + // + for(ii = 2; ii <= m; ii++) + { + i = ii - 1; + k = i; + p = d[i - 1]; + + for(j = ii; j <= n; j++) + { + if (d[j - 1] < p) + { + k = j; + p = d[j - 1]; + } + } + + if (k != i) + { + d[k - 1] = d[i - 1]; + d[i - 1] = p; + p = z[i - 1]; + z[i - 1] = z[k - 1]; + z[k - 1] = p; + } + } + return; + } + + template + void Quad_Data_T::parchk(dt_int32 kind, dt_int32 m, T alpha, T beta) + // Purpose: + // + // PARCHK checks parameters ALPHA and BETA for classical weight functions. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data_T, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + // + // in, dt_int32 M, the order of the highest moment to + // be calculated. This value is only needed when KIND = 8. + // + // in, T ALPHA, BETA, the parameters, if required + // by the value of KIND. + { + T tmp; + + if (kind <= 0) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " KIND <= 0.\n"; + // exit(1); + } + + // check ALPHA for gegenbauer, jacobi, laguerre, hermite, exponential. + if (3 <= kind && alpha <= -1.0) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " 3 <= KIND and ALPHA <= -1.\n"; + // exit(1); + } + + // check BETA for jacobi. + if (kind == 4 && beta <= -1.0) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " KIND == 4 and BETA <= -1.0.\n"; + // exit(1); + } + + // check ALPHA and BETA for rational. + if (kind == 8) + { + tmp = alpha + beta + m + 1.0; + if (0.0 <= tmp || tmp <= beta) + { + // cout << "\n"; + // cout << "PARCHK - Fatal error!\n"; + // cout << " KIND == 8 but condition on ALPHA and BETA fails.\n"; + // exit(1); + } + } + return; + } + + template + void Quad_Data_T::scqf(dt_int32 nt, T t[], dt_int32 mlt[], T wts[], dt_int32 nwts, dt_int32 ndx[], + T swts[], T st[], dt_int32 kind, T alpha, T beta, T a, T b) + // Purpose: + // + // SCQF scales a quad_data formula to a nonstandard interval. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // The arrays WTS and SWTS may coincide. + // The arrays T and ST may coincide. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data_T, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // in, T T[NT], the original knots. + // in, dt_int32 MLT[NT], the multiplicity of the knots. + // in, T WTS[NWTS], the weights. + // in, dt_int32 NWTS, the number of weights. + // in, dt_int32 NDX[NT], used to index the array WTS. + // For more details see the comments in CAWIQ. + // + // Output, T SWTS[NWTS], the scaled weights. + // Output, T ST[NT], the scaled knots. + // + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev Type 1, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, +oo) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-oo, +oo) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, +oo) (x-a)^alpha*(x+b)^beta + // 9, chebyshev Type 2, (a, b) ((b-x)*(x-a))^(+0.5) + // + // in, T ALPHA, the value of Alpha, if needed. + // in, T BETA, the value of Beta, if needed. + // in, T A, B, the interval endpoints. + { + T al; + T be; + dt_int32 i; + dt_int32 k; + dt_int32 l; + T p; + T shft; + T slp; + T temp; + T tmp; + + temp = r8_epsilon(); + + parchk(kind, 1, alpha, beta); + + if (kind == 1) + { + al = 0.0; + be = 0.0; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 2) + { + al = -0.5; + be = -0.5; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 3) + { + al = alpha; + be = alpha; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 4) + { + al = alpha; + be = beta; + + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 5) + { + if (b <= 0.0) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " B <= 0\n"; + // exit(1); + } + shft = a; + slp = 1.0/b; + al = alpha; + be = 0.0; + } + else if (kind == 6) + { + if (b <= 0.0) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " B <= 0.\n"; + // exit(1); + } + shft = a; + slp = 1.0/::sqrt(b); + al = alpha; + be = 0.0; + } + else if (kind == 7) + { + al = alpha; + be = 0.0; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + else if (kind == 8) + { + if (a + b <= 0.0) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " A + B <= 0.\n"; + // exit(1); + } + shft = a; + slp = a + b; + al = alpha; + be = beta; + } + else if (kind == 9) + { + al = 0.5; + be = 0.5; + if (fabs(b - a) <= temp) + { + // cout << "\n"; + // cout << "SCQF - Fatal error!\n"; + // cout << " |B - A| too small.\n"; + // exit(1); + } + shft = (a + b)/2.0; + slp = (b - a)/2.0; + } + + p = pow(slp, al + be + 1.0); + + for(k = 0;k < nt;k++) + { + st[k] = shft + slp * t[k]; + l = abs(ndx[k]); + + if (l != 0) + { + tmp = p; + for(i = l - 1; i <= l - 1 + mlt[k] - 1; i++) + { + swts[i] = wts[i] * tmp; + tmp = tmp * slp; + } + } + } + return; + } + + template + void Quad_Data_T::sgqf(dt_int32 nt, T aj[], T bj[], T zemu, T t[], T wts[]) + // Purpose: + // + // SGQF computes knots and weights of a Gauss Quad_Data_T formula. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // This routine computes all the knots and weights of a Gauss quad_data + // formula with simple knots from the jacobi matrix and the zero-th + // moment of the weight function, using the Golub-Welsch technique. + // + // Reference: + // + // Sylvan Elhay, Jaroslav Kautsky, + // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of + // Interpolatory Quad_Data_T, + // ACM Transactions on Mathematical Software, + // Volume 13, Number 4, December 1987, pages 399-415. + // + // Parameters: + // + // in, dt_int32 NT, the number of knots. + // + // in, T AJ[NT], the diagonal of the jacobi matrix. + // + // in/output, T BJ[NT], the subdiagonal of the jacobi + // matrix, in entries 1 through NT-1. On output, BJ has been overwritten. + // + // in, T ZEMU, the zero-th moment of the weight function. + // + // Output, T T[NT], the knots. + // + // Output, T WTS[NT], the weights. + { + dt_int32 i; + + // Exit if the zero-th moment is not positive. + if (zemu <= 0.0) + { + // cout << "\n"; + // cout << "SGQF - Fatal error!\n"; + // cout << " ZEMU <= 0.\n"; + // exit(1); + } + + // Set up vectors for IMTQLX. + for(i = 0; i < nt; i++) + { + t[i] = aj[i]; + } + wts[0] = ::sqrt(zemu); + for(i = 1; i < nt; i++) + { + wts[i] = 0.0; + } + + // Diagonalize the jacobi matrix. + imtqlx(nt, t, bj, wts); + + for(i = 0; i < nt; i++) + { + wts[i] = wts[i] * wts[i]; + } + + return; + } + + template + T Quad_Data_T::r8_epsilon() + // Purpose: + // + // R8_EPSILON returns the R8 roundoff unit. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // Reference: + // + // Discussion: + // + // The roundoff unit is a number R which is a power of 2 with the + // property that, to the precision of the computer's arithmetic, + // 1 < 1 + R + // but + // 1 = ( 1 + R/2 ) + // + // Parameters: + // + // Output, T R8_EPSILON, the R8 round-off unit. + { + const T value = 2.220446049250313E-016; + + return value; + } + + template + T Quad_Data_T::r8_huge() + // Purpose: + // + // R8_HUGE returns a "huge" R8. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Discussion: + // + // The value returned by this function is NOT required to be the + // maximum representable R8. This value varies from machine to machine, + // from compiler to compiler, and may cause problems when being printed. + // We simply want a "very large" but non-infinite number. + // + // Parameters: + // + // Output, T R8_HUGE, a "huge" R8 value. + { + T value; + + value = 1.0E+30; + + return value; + } + + template + T Quad_Data_T::r8_sign(T x) + // Purpose: + // + // R8_SIGN returns the sign of an R8. + // + // Author: + // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. + // C++ version by John Burkardt. + // + // Licensing: + // + // This code is distributed under the GNU LGPL license. + // + // Parameters: + // + // in, T X, the number whose sign is desired. + // Output, T R8_SIGN, the sign of X. + { + T value; + + if (x < 0.0) + { + value = -1.0; + } + else + { + value = 1.0; + } + return value; + } +} \ No newline at end of file diff --git a/src/detail/r_2d.inl b/src/detail/r_2d.inl new file mode 100755 index 00000000..60033d1c --- /dev/null +++ b/src/detail/r_2d.inl @@ -0,0 +1,789 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "r_2d.h" + +/* forward declarations */ +namespace mt +{ + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_2d& r); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_2d& r); + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_2d& r); + + template + CGPU_EXEC + R_2d floor(const R_2d& r); + + template + CGPU_EXEC + R_2d ceil(const R_2d& r); + + template + CGPU_EXEC + R_2d round(const R_2d& r); + + template + CGPU_EXEC + T fmin(const R_2d& r); + + template + CGPU_EXEC + T fmax(const R_2d& r); + + template + CGPU_EXEC + T norm_2(const R_2d& r); + + template + CGPU_EXEC + T norm(const R_2d& r); + + template + CGPU_EXEC + R_2d normalize(const R_2d& r); +} + +/* R_2d */ +namespace mt +{ + /************************************* constructors ************************************/ + /* Default constructor */ + template + CGPU_EXEC + R_xtd::R_xtd(): x(T()), y(T()) {} + + /* constructor by initializer list */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const dt_init_list& list) + { + auto ptr = list.begin(); + + x = T(ptr[0]); + y = T(ptr[1]); + } + + /* constructor by pointer */ + template + template + CGPU_EXEC + R_xtd::R_xtd(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol) + { + const auto ip = icol*n_r + idx; + + x = T(v[ip + 0*n_r]); + y = (n_c>1)?T(v[ip + 1*n_r]):T(0); + } + + /* constructor by pointer */ + template + template + CPU_EXEC + R_xtd::R_xtd(U* v) + { + x = T(v[0]); + y = T(v[1]); + } + + /* constructor by pointer */ + template + template + CPU_EXEC + R_xtd::R_xtd(U* v, const dt_int32& n_v) + { + x = (n_v>0)?T(v[0]):T(0); + y = (n_v>1)?T(v[1]):T(0); + } + + /* constructor a R_2d with an x */ + template + CGPU_EXEC + R_xtd::R_xtd(const T& x): x(x), y(T()) {} + + /* converting constructor: R_2d with an x */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const U& x): x(T(x)), y(T()) {} + + /* constructor a R_2d from its x and y parts */ + template + CGPU_EXEC + R_xtd::R_xtd(const T& x, const T& y): x(x), y(y) {} + + /* converting constructor: R_2d from its x and y parts */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const U& x, const U& y): x(T(x)), y(T(y)) {} + + /* Copy constructor */ + template + CGPU_EXEC + R_xtd::R_xtd(const R_xtd& r): x(r.x), y(r.y) {} + + /* Move constructor */ + template + CGPU_EXEC + R_xtd::R_xtd(R_xtd&& r): x(std::move(r.x)), y(std::move(r.y)) {} + + /* converting copy constructor */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const R_xtd& r): x(T(r.x)), y(T(r.y)) {} + + /******************************** assignment operators *********************************/ + /*Assign x and set y to 0 */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const T& x) + { + this->x = x; + this->y = T(0); + + return *this; + } + + /* Convert and assign x and set y to 0 */ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const U& x) + { + this->x = T(x); + this->y = T(0); + + return *this; + } + + /* copy assignment operator */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const R_xtd& r) + { + x = r.x; + y = r.y; + + return *this; + } + + /* Move assignment operator */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(R_xtd&& r) + { + if (this != &r) + { + x = std::move(r.x); + y = std::move(r.y); + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const R_xtd& r) + { + x = T(r.x); + y = T(r.y); + + return *this; + } + +#ifdef __CUDACC__ + /* Assignment operator from thrust::complex */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const thrust::complex& r) + { + x = r.real(); + y = r.imag(); + + return *this; + } + + /* converting assignment operator from thrust::complex */ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const thrust::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + + return *this; + } +#endif + + /* Assignment operator from std::complex */ + template + CPU_EXEC + R_xtd& R_xtd::operator=(const std::complex& r) + { + x = r.real(); + y = r.imag(); + + return *this; + } + + /* converting assignment operator from std::complex */ + template + template + CPU_EXEC + R_xtd& R_xtd::operator=(const std::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + + return *this; + } + + /******************* Compound assignment operators *******************/ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator+=(const R_xtd& r) + { + *this = *this + r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator+=(const U& r) + { + *this = *this + r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator-=(const R_xtd& r) + { + *this = *this - r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator-=(const U& r) + { + *this = *this - r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator*=(const R_xtd& r) + { + *this = *this*r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator*=(const U& r) + { + *this = *this*r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator/=(const R_xtd& r) + { + *this = *this/r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator/=(const U& r) + { + *this = *this/r; + + return *this; + } + + /************************** Other operators **************************/ + template + CGPU_EXEC + dt_bool R_xtd::fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + template + CGPU_EXEC + dt_bool R_xtd::is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + template + CGPU_EXEC + dt_bool R_xtd::is_one() const + { + return mt::fcn_is_one(*this); + } + + template + CGPU_EXEC + R_xtd R_xtd::floor() const + { + return mt::floor(*this); + } + + template + CGPU_EXEC + R_xtd R_xtd::ceil() const + { + return mt::ceil(*this); + } + + template + CGPU_EXEC + R_xtd R_xtd::round() const + { + return mt::round(*this); + } + + template + CGPU_EXEC + T R_xtd::min() const + { + return mt::fmin(*this); + } + + template + CGPU_EXEC + T R_xtd::max() const + { + return mt::fmax(*this); + } + + template + CGPU_EXEC + T R_xtd::norm_2() const + { + return mt::norm_2(*this); + } + + template + CGPU_EXEC + T R_xtd::norm() const + { + return mt::norm(*this); + } + + template + CGPU_EXEC + void R_xtd::normalize() + { + *this = mt::normalize(*this); + } + + template + CGPU_EXEC + void R_xtd::fill(const T& v) + { + x = y = v; + } + + template + CGPU_EXEC + void R_xtd::assign_nzero(const R_xtd& r) + { + x = r.x; + y = (fcn_is_nzero(r.y))?r.y:r.x; + } +} + +/* unitary operators */ +namespace mt +{ + template + CGPU_EXEC + R_2d operator-(const R_2d& r) + { + return {-r.x, -r.y}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_2d& r) + { + return fcn_is_zero(r.x, r.y); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_2d& r) + { + return fcn_is_nzero(r.x, r.y); + } + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_2d& r) + { + return fcn_is_one(r.x, r.y); + } + + template + CGPU_EXEC + R_2d floor(const R_2d& r) + { + return {::floor(r.x), ::floor(r.y)}; + } + + template + CGPU_EXEC + R_2d ceil(const R_2d& r) + { + return {::ceil(r.x), ::ceil(r.y)}; + } + + template + CGPU_EXEC + R_2d round(const R_2d& r) + { + return {::round(r.x), ::round(r.y)}; + } + + template + CGPU_EXEC + T fmin(const R_2d& r) + { + return ::fmin(r.x, r.y); + } + + template + CGPU_EXEC + T fmax(const R_2d& r) + { + return ::fmax(r.x, r.y); + } + + template + CGPU_EXEC + R_2d square(const R_2d& r) + { + return {r.x*r.x, r.y*r.y}; + } + + template + CGPU_EXEC + R_2d sqrt(const R_2d& r) + { + return {::sqrt(r.x), ::sqrt(r.y)}; + } + + template + CGPU_EXEC + T norm_2(const R_2d& r) + { + return r.x*r.x + r.y*r.y; + } + + template + CGPU_EXEC + T norm(const R_2d& r) + { + return ::sqrt(norm_2(r)); + } + + template + CGPU_EXEC + R_2d normalize(const R_2d& r) + { + return fcn_div(r, r.norm()); + } + + template + CGPU_EXEC + R_2d fill_nzero(R_2d r) + { + r.x = r.x; + r.y = (fcn_is_nzero(r.y))?r.y:r.x; + + return r; + } +} + +/* binary operators */ +namespace mt +{ + template > + CGPU_EXEC + R_2d operator+(const R_2d& lhs, const R_2d& rhs) + { + return {lhs.x + rhs.x, lhs.y + rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator+(const R_2d& lhs, const U& rhs) + { + return {lhs.x + rhs, lhs.y + rhs}; + } + + template > + CGPU_EXEC + R_2d operator+(const T& lhs, const R_2d& rhs) + { + return {lhs+ rhs.x, lhs + rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator-(const R_2d& lhs, const R_2d& rhs) + { + return {lhs.x - rhs.x, lhs.y - rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator-(const R_2d& lhs, const U& rhs) + { + return {lhs.x - rhs, lhs.y - rhs}; + } + + template > + CGPU_EXEC + R_2d operator-(const T& lhs, const R_2d& rhs) + { + return {lhs - rhs.x, lhs - rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator*(const R_2d& lhs, const R_2d& rhs) + { + return {lhs.x*rhs.x, lhs.y*rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator*(const R_2d& lhs, const U& rhs) + { + return {lhs.x*rhs, lhs.y*rhs}; + } + + template > + CGPU_EXEC + R_2d operator*(const T& lhs, const R_2d& rhs) + { + return {lhs*rhs.x, lhs*rhs.y}; + } + + template > + CGPU_EXEC + R_2d operator/(const R_2d& lhs, const R_2d& rhs) + { + return {fcn_div(lhs.x, rhs.x), fcn_div(lhs.y, rhs.y)}; + } + + template > + CGPU_EXEC + R_2d operator/(const R_2d& lhs, const U& rhs) + { + return {fcn_div(lhs.x, rhs), fcn_div(lhs.y, rhs)}; + } + + template > + CGPU_EXEC + R_2d operator/(const T& lhs, const R_2d& rhs) + { + return {fcn_div(lhs, rhs.x), fcn_div(lhs, rhs.y)}; + } + + template > + CGPU_EXEC + R_2d fmin(const R_2d& lhs, const R_2d& rhs) + { + return {::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y)}; + } + + template > + CGPU_EXEC + R_2d fmax(const R_2d& lhs, const R_2d& rhs) + { + return {::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y)}; + } + + template > + CGPU_EXEC + X dot(const R_2d& lhs, const R_2d& rhs) + { + return lhs.x*rhs.x + lhs.y*rhs.y; + } + + template > + CGPU_EXEC + X angle(const R_2d& lhs, const R_2d& rhs) + { + X m = ::sqrt(lhs.norm_2()*rhs.norm_2()); + return ::acos(fcn_div(dot(lhs, rhs), m)); + } +} + +/* traits */ +namespace mt +{ + template + struct is_r_2d: std::integral_constant>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value> {}; + + template + using enable_if_r_2d = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_r_2d_f64 = std::initializer_list>; +} + +/* data copy */ +namespace mt +{ + // (dst, src): cpu -> cpu: R_2d + template + enable_if_real_real + memcpy_pos_cpu_cpu(R_2d* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, Ts* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + pcpu_dst[ik]= R_2d(pcpu_src[ik + 0*n_size], pcpu_src[ik + 1*n_size]); + } + } + + // (dst, src): cpu: R_2d -> cpu + template + enable_if_real_real + memcpy_pos_cpu_cpu(Td* pcpu_dst, const R_2d* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_2d* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + const auto& r_2d = pcpu_src[ik]; + + pcpu_dst[ip + 0*n_size] = Td(r_2d.x); + pcpu_dst[ip + 1*n_size] = Td(r_2d.y); + } + } + +#ifdef __CUDACC__ + // (dst, src): gpu: R_2d -> cpu + template + enable_if_real_real + memcpy_pos_gpu_cpu(Td* pcpu_dst, const R_2d* pgpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_2d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_2d)); + + if (pcpu_jk == nullptr) + { + R_2d* pcpu_t = new R_2d[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_t, n_size, icol); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_jk, n_size, icol); + } + } + + // (dst, src): cpu -> gpu: R_2d + template + enable_if_real_real + memcpy_pos_cpu_gpu(R_2d* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_2d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_2d)); + + if (pcpu_jk == nullptr) + { + R_2d* pcpu_t = new R_2d[n_size]; + memcpy_pos_cpu_cpu(pcpu_t, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_pos_cpu_cpu(pcpu_jk, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } +#endif +} + +/* other operators */ +namespace mt +{ + // distance from point to line + template + CGPU_EXEC_INL + T fcn_pt_2_ln_dist(const T& a, const T& b, const T& c, const R_2d& r_0) + { + return fcn_pt_2_ln_dist(a, b, c, r_0.x, r_0.y); + } + + // calculate intersection from point to line + template + CGPU_EXEC_INL + R_2d fcn_pt_2_ln_intxn_2d(const T& a, const T& b, const T& c, const R_2d& r_0) + { + R_2d r; + fcn_pt_2_ln_intxn_2d(a, b, c, r_0.x, r_0.y, r.x, r.y); + + return r; + } +} \ No newline at end of file diff --git a/src/detail/r_3d.inl b/src/detail/r_3d.inl new file mode 100755 index 00000000..fd2cda0e --- /dev/null +++ b/src/detail/r_3d.inl @@ -0,0 +1,826 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#include "r_3d.h" + +/* forward declarations */ +namespace mt +{ + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_3d& r); + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_3d& r); + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_3d& r); + + template + CGPU_EXEC + R_3d floor(const R_3d& r); + + template + CGPU_EXEC + R_3d ceil(const R_3d& r); + + template + CGPU_EXEC + R_3d round(const R_3d& r); + + template + CGPU_EXEC + T fmin(const R_3d& r); + + template + CGPU_EXEC + T fmax(const R_3d& r); + + template + CGPU_EXEC + T norm_2(const R_3d& r); + + template + CGPU_EXEC + T norm(const R_3d& r); + + template + CGPU_EXEC + R_3d normalize(const R_3d& r); +} + +/* R_3d */ +namespace mt +{ + /************************************* constructors ************************************/ + /* Default constructor */ + template + CGPU_EXEC + R_xtd::R_xtd(): x(T()), y(T()), z(T()) {} + + /* converting constructor by initializer list */ + template + template + CPU_EXEC + R_xtd::R_xtd(const dt_init_list& list) + { + auto ptr = list.begin(); + + x = T(ptr[0]); + y = T(ptr[1]); + z = T(ptr[2]); + } + + /* constructor by pointer */ + template + template + CPU_EXEC + R_xtd::R_xtd(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol) + { + const auto ip = icol*n_r + idx; + + x = T(v[ip + 0*n_r]); + y = (n_c>1)?T(v[ip + 1*n_r]):T(0); + z = (n_c>2)?T(v[ip + 2*n_r]):T(0); + } + + /* constructor by pointer */ + template + template + CPU_EXEC + R_xtd::R_xtd(U* v) + { + x = T(v[0]); + y = T(v[1]); + z = T(v[2]); + } + + /* constructor by pointer */ + template + template + CPU_EXEC + R_xtd::R_xtd(U* v, const dt_int32& n_v) + { + x = (n_v>0)?T(v[0]):T(0); + y = (n_v>1)?T(v[1]):T(0); + z = (n_v>2)?T(v[2]):T(0); + } + + /* constructor a R_3d with an x part */ + template + CGPU_EXEC + R_xtd::R_xtd(const T& x): x(x), y(T()), z(T()) {} + + /* converting constructor: R_3d with an x part */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const U& x): x(T(x)), y(T()), z(T()) {} + + /* constructor a R_3d from its x and y parts */ + template + CGPU_EXEC + R_xtd::R_xtd(const T& x, const T& y): x(x), y(y), z(T()) {} + + /* converting constructor: R_3d from its x and y parts */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const U& x, const U& y): x(T(x)), y(T(y)), z(T()) {} + + /* constructor a R_3d from its x, y and z parts */ + template + CGPU_EXEC + R_xtd::R_xtd(const T& x, const T& y, const T& z): x(x), y(y), z(z) {} + + /* converting constructor: R_3d from its x, y and z parts */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const U& x, const U& y, const U& z): x(T(x)), y(T(y)), z(T(z)) {} + + /* copy constructor */ + template + CGPU_EXEC + R_xtd::R_xtd(const R_xtd& r): x(r.x), y(r.y), z(r.z) {} + + /* Move constructor */ + template + CGPU_EXEC + R_xtd::R_xtd(R_xtd&& r): x(std::move(r.x)), y(std::move(r.y)), z(std::move(r.z)) {} + + /* converting copy constructor */ + template + template + CGPU_EXEC + R_xtd::R_xtd(const R_xtd& r): x(T(r.x)), y(T(r.y)), z(T(r.z)) {} + + /******************************** assignment operators *********************************/ + /* Assign x and set y to 0 */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const T& x) + { + this->x = x; + this->y = T(0); + this->z = T(0); + + return *this; + } + + /* Convert and assign x and set y to 0 */ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const U& x) + { + this->x = T(x); + this->y = T(0); + this->z = T(0); + + return *this; + } + + /* copy assignment operator */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const R_xtd& r) + { + x = r.x; + y = r.y; + z = r.z; + + return *this; + } + + /* Move assignment operator */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(R_xtd&& r) + { + if (this != &r) + { + x = std::move(r.x); + y = std::move(r.y); + z = std::move(r.z); + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const R_xtd& r) + { + x = T(r.x); + y = T(r.y); + z = T(r.z); + + return *this; + } + + /* Assignment operator from R_2d */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const R_2d& r) + { + x = r.x; + y = r.y; + z = T(0); + + return *this; + } + + /* converting assignment operator from R_2d */ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const R_2d& r) + { + x = T(r.x); + y = T(r.y); + z = T(0); + + return *this; + } + +#ifdef __CUDACC__ + /* Assignment operator from thrust::complex */ + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const thrust::complex& r) + { + x = r.real(); + y = r.imag(); + z = T(0); + + return *this; + } + + /* converting assignment operator from thrust::complex */ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator=(const thrust::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + z = T(0); + + return *this; + } +#endif + + /* Assignment operator from std::complex */ + template + CPU_EXEC + R_xtd& R_xtd::operator=(const std::complex& r) + { + x = r.real(); + y = r.imag(); + z = T(0); + + return *this; + } + + /* converting assignment operator from std::complex */ + template + template + CPU_EXEC + R_xtd& R_xtd::operator=(const std::complex& r) + { + x = T(r.real()); + y = T(r.imag()); + z = T(0); + + return *this; + } + + /******************* Compound assignment operators *******************/ + template + template + CGPU_EXEC + R_xtd& R_xtd::operator+=(const R_xtd& r) + { + *this = *this + r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator+=(const U& r) + { + *this = *this + r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator-=(const R_xtd& r) + { + *this = *this - r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator-=(const U& r) + { + *this = *this - r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator*=(const R_xtd& r) + { + *this = *this*r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator*=(const U& r) + { + *this = *this*r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator/=(const R_xtd& r) + { + *this = *this/r; + + return *this; + } + + template + template + CGPU_EXEC + R_xtd& R_xtd::operator/=(const U& r) + { + *this = *this/r; + + return *this; + } + + /************************** Other operators **************************/ + template + CGPU_EXEC + dt_bool R_xtd::fcn_is_zero() const + { + return mt::fcn_is_zero(*this); + } + + template + CGPU_EXEC + dt_bool R_xtd::is_nzero() const + { + return mt::fcn_is_nzero(*this); + } + + template + CGPU_EXEC + dt_bool R_xtd::is_one() const + { + return mt::fcn_is_one(*this); + } + + template + CGPU_EXEC + R_2d R_xtd::floor() const + { + return mt::floor(*this); + } + + template + CGPU_EXEC + R_2d R_xtd::ceil() const + { + return mt::ceil(*this); + } + + template + CGPU_EXEC + R_2d R_xtd::round() const + { + return mt::round(*this); + } + + template + CGPU_EXEC + T R_xtd::min() const + { + return mt::fmin(*this); + } + + template + CGPU_EXEC + T R_xtd::max() const + { + return mt::fmax(*this); + } + + template + CGPU_EXEC + T R_xtd::norm_2() const + { + return mt::norm_2(*this); + } + + template + CGPU_EXEC + T R_xtd::norm() const + { + return mt::norm(*this); + } + + template + CGPU_EXEC + void R_xtd::normalize() + { + *this = mt::normalize(*this); + } + + template + CGPU_EXEC + void R_xtd::fill(const T& v) + { + x = y = z = v; + } +} + +/* unitary operators */ +namespace mt +{ + template + CGPU_EXEC + R_3d operator-(const R_3d& r) + { + return {-r.x, -r.y, -r.z}; + } + + template + CGPU_EXEC + dt_bool fcn_is_zero(const R_3d& r) + { + return fcn_is_zero(r.x, r.y, r.z); + } + + template + CGPU_EXEC + dt_bool fcn_is_nzero(const R_3d& r) + { + return fcn_is_nzero(r.x, r.y, r.z); + } + + template + CGPU_EXEC + dt_bool fcn_is_one(const R_3d& r) + { + return fcn_is_one(r.x, r.y, r.z); + } + + template + CGPU_EXEC + R_3d floor(const R_3d& r) + { + return {::floor(r.x), ::floor(r.y), ::floor(r.z)}; + } + + template + CGPU_EXEC + R_3d ceil(const R_3d& r) + { + return {::ceil(r.x), ::ceil(r.y), ::ceil(r.z)}; + } + + template + CGPU_EXEC + R_3d round(const R_3d& r) + { + return {::round(r.x), ::round(r.y), ::round(r.z)}; + } + + template + CGPU_EXEC + T fmin(const R_3d& r) + { + return ::fmin(r.x, ::fmin(r.y, r.z)); + } + + template + CGPU_EXEC + T fmax(const R_3d& r) + { + return ::fmax(r.x, ::fmax(r.y, r.z)); + } + + template + CGPU_EXEC + R_3d square(const R_3d& r) + { + return {r.x*r.x, r.y*r.y, r.z*r.z}; + } + + template + CGPU_EXEC + R_3d sqrt(const R_3d& r) + { + return {::sqrt(r.x), ::sqrt(r.y), ::sqrt(r.z)}; + } + + template + CGPU_EXEC + T norm_2(const R_3d& r) + { + return r.x*r.x + r.y*r.y + r.z*r.z; + } + + template + CGPU_EXEC + T norm(const R_3d& r) + { + return ::sqrt(norm_2(r)); + } + + template + CGPU_EXEC + R_3d normalize(const R_3d& r) + { + return fcn_div(r, r.norm()); + } + + template + CGPU_EXEC + R_3d fill_nzero(R_3d r) + { + r.x = r.x; + r.y = (fcn_is_nzero(r.y))?r.y:r.x; + r.z = (fcn_is_nzero(r.z))?r.z:r.y; + + return r; + } +} + +/* binary operators */ +namespace mt +{ + template > + CGPU_EXEC + R_3d operator+(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator+(const R_3d& lhs, const U& rhs) + { + return {lhs.x + rhs, lhs.y + rhs, lhs.z + rhs}; + } + + template > + CGPU_EXEC + R_3d operator+(const T& lhs, const R_3d& rhs) + { + return {lhs+ rhs.x, lhs + rhs.y, lhs + rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator-(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator-(const R_3d& lhs, const U& rhs) + { + return {lhs.x - rhs, lhs.y - rhs, lhs.z - rhs}; + } + + template > + CGPU_EXEC + R_3d operator-(const T& lhs, const R_3d& rhs) + { + return {lhs - rhs.x, lhs - rhs.y, lhs - rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator*(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator*(const R_3d& lhs, const U& rhs) + { + return {lhs.x*rhs, lhs.y*rhs, lhs.z*rhs}; + } + + template > + CGPU_EXEC + R_3d operator*(const T& lhs, const R_3d& rhs) + { + return {lhs*rhs.x, lhs*rhs.y, lhs*rhs.z}; + } + + template > + CGPU_EXEC + R_3d operator/(const R_3d& lhs, const R_3d& rhs) + { + return {fcn_div(lhs.x, rhs.x), fcn_div(lhs.y, rhs.y), fcn_div(lhs.z, rhs.z)}; + } + + template > + CGPU_EXEC + R_3d operator/(const R_3d& lhs, const U& rhs) + { + return {fcn_div(lhs.x, rhs), fcn_div(lhs.y, rhs), fcn_div(lhs.z, rhs)}; + } + + template > + CGPU_EXEC + R_3d operator/(const T& lhs, const R_3d& rhs) + { + return {fcn_div(lhs, rhs.x), fcn_div(lhs, rhs.y), fcn_div(lhs, rhs.z)}; + } + + template > + CGPU_EXEC + R_3d fmin(const R_3d& lhs, const R_3d& rhs) + { + return {::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y), ::fmin(lhs.z, rhs.z)}; + } + + template > + CGPU_EXEC + R_3d fmax(const R_3d& lhs, const R_3d& rhs) + { + return {::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y), ::fmax(lhs.z, rhs.z)}; + } + + template > + CGPU_EXEC + X dot(const R_3d& lhs, const R_3d& rhs) + { + return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; + } + + template > + CGPU_EXEC + R_3d cross(const R_3d& lhs, const R_3d& rhs) + { + return {lhs.y*rhs.z-lhs.z*rhs.y, lhs.z*rhs.x-lhs.x*rhs.z, lhs.x*rhs.y-lhs.y*rhs.x}; + } + + template > + CGPU_EXEC + X angle(const R_3d& lhs, const R_3d& rhs) + { + X m = ::sqrt(lhs.norm_2()*rhs.norm_2()); + return ::acos(fcn_div(dot(lhs, rhs), m)); + } +} + +/* traits */ +namespace mt +{ + template + struct is_r_3d: std::integral_constant>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value || + std::is_same>::value || std::is_same>::value> {}; + + template + using enable_if_r_3d = typename std::enable_if::value, U>::type; + + template + struct is_r_nd: std::integral_constant::value || is_r_3d::value> {}; + + template + using enable_if_r_nd = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + /******************************** initializer list *************************************/ + /***************************************************************************************/ + using dt_init_list_r_3d_f64 = std::initializer_list>; +} + +/* data copy */ +namespace mt +{ + /***************************************************************************************/ + // (dst, src): cpu -> cpu: R_3d + template + enable_if_real_real + memcpy_pos_cpu_cpu(R_3d* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, Ts* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + pcpu_dst[ik]= R_3d(pcpu_src[ik + 0*n_size], pcpu_src[ik + 1*n_size], pcpu_src[ik + 2*n_size]); + } + } + + // (dst, src): cpu: R_3d -> cpu + template + enable_if_real_real + memcpy_pos_cpu_cpu(Td* pcpu_dst, const R_3d* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_3d* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + const auto ip = icol*n_size + ik; + const auto& r_3d = pcpu_src[ik]; + + pcpu_dst[ip + 0*n_size] = Td(r_3d.x); + pcpu_dst[ip + 1*n_size] = Td(r_3d.y); + pcpu_dst[ip + 2*n_size] = Td(r_3d.z); + } + } + +#ifdef __CUDACC__ + // (dst, src): gpu: R_3d -> cpu + template + enable_if_real_real + memcpy_pos_gpu_cpu(Td* pcpu_dst, const R_3d* pgpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_3d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_3d)); + + if (pcpu_jk == nullptr) + { + R_3d* pcpu_t = new R_3d[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_t, n_size, icol); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_pos_cpu_cpu(pcpu_dst, pcpu_jk, n_size, icol); + } + } + + // (dst, src): cpu -> gpu: R_3d + template + enable_if_real_real + memcpy_pos_cpu_gpu(R_3d* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, dt_uint64 icol=0, R_3d* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(R_3d)); + + if (pcpu_jk == nullptr) + { + R_3d* pcpu_t = new R_3d[n_size]; + memcpy_pos_cpu_cpu(pcpu_t, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_pos_cpu_cpu(pcpu_jk, pcpu_src, n_size, icol); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } +#endif + +/************************** other operators **************************/ + +} \ No newline at end of file diff --git a/src/detail/range_1d.inl b/src/detail/range_1d.inl new file mode 100755 index 00000000..97b7562d --- /dev/null +++ b/src/detail/range_1d.inl @@ -0,0 +1,110 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "range_1d.h" + +/* template specialization 1d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Range_xd::Range_xd(): ix_0(0), nx(0) {} + + template + Range_xd::Range_xd(const ST& ix_0, const ST& nx) : ix_0(ix_0), nx(nx) {} + + /* copy constructor */ + template + CGPU_EXEC + Range_xd::Range_xd(const Range_xd& range) + { + *this = range; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Range_xd::Range_xd(const Range_xd& range) + { + *this = range; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Range_xd& Range_xd::operator=(const Range_xd& range) + { + if (this != &range) + { + ix_0 = range.ix_0; + nx = range.nx; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Range_xd& Range_xd::operator=(const Range_xd& range) + { + if (this != &range) + { + ix_0 = ST(range.ix_0); + nx = ST(range.nx); + } + + return *this; + } + + template + template + CGPU_EXEC + void Range_xd::assign(const Range_xd& range) + { + *this = range; + } + + /***************************************************************************************/ + template + template + void Range_xd::set_in_data(const SU& ix_0, const SU& nx) + { + this->ix_0 = ST(ix_0); + this->nx = ST(nx); + } + + template + template + void Range_xd::set_in_data(const T& r, const T& r_max, const Grid_1d& grid) + { + grid.ix_0_ix_n(r, r_max, ix_0, nx); + } + + template + CGPU_EXEC + void Range_xd::clear() + { + ix_0 = ST(0); + nx = ST(0); + } +} \ No newline at end of file diff --git a/src/detail/range_2d.inl b/src/detail/range_2d.inl new file mode 100755 index 00000000..3701276c --- /dev/null +++ b/src/detail/range_2d.inl @@ -0,0 +1,120 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "range_2d.h" + +/* template specialization 2d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Range_xd::Range_xd(): Range_xd(), iy_0(0), ny(0) {} + + template + Range_xd::Range_xd(const ST& ix_0, const ST& nx, const ST& iy_0, const ST& ny) + : Range_xd(ix_0, nx), iy_0(iy_0), ny(ny) {} + + /* copy constructor */ + template + CGPU_EXEC + Range_xd::Range_xd(const Range_xd& range) + { + *this = range; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Range_xd::Range_xd(const Range_xd& range) + { + *this = range; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Range_xd& Range_xd::operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iy_0 = range.iy_0; + ny = range.ny; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Range_xd& Range_xd::operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iy_0 = ST(range.iy_0); + ny = ST(range.ny); + } + + return *this; + } + + template + template + CGPU_EXEC + void Range_xd::assign(const Range_xd& range) + { + *this = range; + } + + /***************************************************************************************/ + template + template + void Range_xd::set_in_data(const SU& ix_0, const SU& nx, const SU& iy_0, const SU& ny) + { + Range_xd::set_in_data(ix_0, nx); + + this->iy_0 = ST(iy_0); + this->ny = ST(ny); + } + + template + template + void Range_xd::set_in_data(const R_2d& r, const T& r_max, const Grid_2d& grid) + { + grid.ix_0_ix_n(r.x, r_max, this->ix_0, this->nx); + grid.iy_0_iy_n(r.y, r_max, iy_0, ny); + } + + template + CGPU_EXEC + void Range_xd::clear() + { + Range_xd::clear(); + + iy_0 = ST(0); + ny = ST(0); + } +} \ No newline at end of file diff --git a/src/detail/range_3d.inl b/src/detail/range_3d.inl new file mode 100755 index 00000000..aadaa3b6 --- /dev/null +++ b/src/detail/range_3d.inl @@ -0,0 +1,121 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "range_3d.h" + +/* template specialization 3d */ +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Range_xd::Range_xd(): Range_xd(), iz_0(0), nz(0) {} + + template + Range_xd::Range_xd(const ST& ix_0, const ST& nx, const ST& iy_0, const ST& ny, const ST& iz_0, const ST& nz) + : Range_xd(ix_0, nx, iy_0, ny), iz_0(iz_0), nz(nz) {} + + /* copy constructor */ + template + CGPU_EXEC + Range_xd::Range_xd(const Range_xd& range) + { + *this = range; + } + + /* converting constructor */ + template + template + CGPU_EXEC + Range_xd::Range_xd(const Range_xd& range) + { + *this = range; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Range_xd&Range_xd:: operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iz_0 = range.iz_0; + nz = range.nz; + } + + return *this; + } + + /* converting assignment operator */ + template + template + CGPU_EXEC + Range_xd& Range_xd::operator=(const Range_xd& range) + { + if (this != &range) + { + Range_xd::operator=(range); + + iz_0 = ST(range.iz_0); + nz = ST(range.nz); + } + + return *this; + } + + template + template + CGPU_EXEC + void Range_xd::assign(const Range_xd& range) + { + *this = range; + } + + /***************************************************************************************/ + template + template + void Range_xd::set_in_data(const SU& ix_0, const SU& nx, const SU& iy_0, const SU& ny, const SU& iz_0, const SU& nz) + { + Range_xd::set_in_data(ix_0, nx, iy_0, ny); + + this->iz_0 = ST(iz_0); + this->nz = ST(nz); + } + + template + template + void Range_xd::set_in_data(const R_3d& r, const T& r_max, const Grid_3d& grid) + { + grid.ix_0_ix_n(r.x, r_max, this->ix_0, this->nx); + grid.iy_0_iy_n(r.y, r_max, this->iy_0, this->ny); + grid.iz_0_iz_n(r.z, r_max, iz_0, nz); + } + + template + CGPU_EXEC + void Range_xd::clear() + { + Range_xd::clear(); + + iz_0 = ST(0); + nz = ST(0); + } +} \ No newline at end of file diff --git a/src/detail/rnd_1d_cpu.inl b/src/detail/rnd_1d_cpu.inl new file mode 100755 index 00000000..39d00b6b --- /dev/null +++ b/src/detail/rnd_1d_cpu.inl @@ -0,0 +1,263 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "rnd_1d_cpu.h" + +/* 1d distribution */ +namespace mt +{ + template + Rnd_xd::Rnd_xd(dt_uint64 seed, dt_int32 n_iter): Gen_seed(seed), m_sc{1}, m_sft{0} + { + set_seed(seed, n_iter); + } + + template + void Rnd_xd::set_in_data(const dt_uint64& seed, const T& sc, const T& sft, dt_int32 n_iter) + { + set_seed(seed, n_iter); + set_sc_sft(sc, sft); + } + + template + void Rnd_xd::set_seed(dt_uint64 seed, dt_int32 n_iter) + { + auto gen_seed = this->seed_1d(seed, n_iter); + + rnd.set_seed(gen_seed); + } + + template + void Rnd_xd::set_sc_sft(const T& sc, const T& sft) + { + m_sc = sc; + m_sft = sft; + } + + template + T Rnd_xd::operator()() + { + return rnd(m_sc, m_sft); + } + + template + T Rnd_xd::operator()(const T& sc) + { + return rnd(sc); + } + + template + T Rnd_xd::operator()(const T& sc, const T& sft) + { + return rnd(sc, sft); + } +} + +/* fcns */ +namespace mt +{ + // add uniform noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_unif_nois(TVctr_i& mx_i, Value_type sc, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream) + { + using T = Value_type; + auto seed = seed_i; + + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + Gen_seed gen_seed(seed); + Vctr_uint64_cpu vctr_seed = gen_seed((pstream==nullptr)?1:pstream->size()); + + const T a = -sc; + const T b = T(2)*sc; + + auto thr_add_nois = [a, b, &mx_i, &vctr_seed, &mx_o](const iThread_Rect_1d& range) + { + Rndu_1d_cpu rnd(vctr_seed[range.istm]); + + for(auto ind = range.ind_0; ind < range.ind_e; ind++) + { + mx_o[ind] = rnd(b, T(mx_i[ind]) + a); + } + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_nois); + }; + + // add gaussian noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_gauss_nois(TVctr_i& mx_i, Value_type sigma, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream) + { + using T = Value_type; + auto seed = seed_i; + + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + Gen_seed gen_seed(seed); + Vctr_uint64_cpu vctr_seed = gen_seed((pstream==nullptr)?1:pstream->size()); + + auto thr_add_nois = [sigma, &mx_i, &vctr_seed, &mx_o](const iThread_Rect_1d& range) + { + Rndn_1d_cpu rnd(vctr_seed[range.istm]); + + for(auto ind = range.ind_0; ind < range.ind_e; ind++) + { + mx_o[ind] = rnd(sigma, T(mx_i[ind])); + } + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_nois); + }; + + + // add poisson noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_poiss_nois(TVctr_i& mx_i, double sc_i, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream) + { + using T = Value_type; + auto seed = seed_i; + auto sc = T(sc_i); + + if (seed<1) + { + std::random_device rd; + seed = rd(); + } + + Gen_seed gen_seed(seed); + Vctr_uint64_cpu vctr_seed = gen_seed((pstream==nullptr)?1:pstream->size()); + + auto thr_add_nois = [sc, &mx_i, &vctr_seed, &mx_o](const iThread_Rect_1d& range) + { + Rndp_1d_cpu rnd(vctr_seed[range.istm]); + + for(auto ind = range.ind_0; ind < range.ind_e; ind++) + { + mx_o[ind] = rnd(T(mx_i[ind])*sc); + } + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_nois); + }; + + //// add Poisson noise + //template + //TVctr add_poiss_nois_by_SNR(Stream& stream, TVctr& Im_i, + // Value_type SNR_i, Value_type& scl_o) + //{ + // using T = Value_type; + + // auto get_SNR = [](Stream& stream, TVctr& Im, T Im_std, T scf)->T + // { + // T x_mean = 0; + // T x_var = 0; + // auto thr_SNR = [&](const iThread_Rect_2d& range) + // { + // std::mt19937_64 gen; + // std::poisson_distribution rand; + + // T x_mean_partial = 0; + // T x_var_partial = 0; + // for(auto ixy = range.ind_0; ixy < range.ind_e; ixy++) + // { + // auto x0 = scf*Im[ixy]; + // rand.param(std::poisson_distribution::param_type(x0)); + // auto xn = rand(gen)-x0; + // x_mean_partial += xn; + // x_var_partial += xn*xn; + // } + + // stream.stream_mutex.lock(); + // x_mean += x_mean_partial; + // x_var += x_var_partial; + // stream.stream_mutex.unlock(); + // }; + + // stream.set_n_stream_act(Im.size()); + // stream.set_grid(1, Im.size()); + // stream.exec(thr_SNR); + + // x_mean /= Im.size(); + // x_var = x_var/Im.size()-x_mean*x_mean; + + // return scf*Im_std/sqrt(x_var); + // }; + + // auto Im_i_std = sqrt(fcn_variance(stream, Im_i)); + + // T SNR_k = get_SNR(stream, Im_i, Im_i_std, 1); + + // T k_0 = 1; + // T k_e = 1; + + // if (SNR_k= SNR_i); + // k_e = 2*k_0; + // } + + + // // bisection method + // dt_int32 ic = 0; + // do + // { + // scl_o = 0.5*(k_0 + k_e); + // auto SNR_k = get_SNR(stream, Im_i, Im_i_std, scl_o); + + // if (SNR_k < SNR_i) + // { + // k_0 = scl_o; + // } + // else + // { + // k_e = scl_o; + // } + // ic++; + // } while ((fabs(SNR_i-SNR_k)>0.1) && (ic<10)); + + // // add Poisson noise + // return fcn_add_poiss_nois(stream, Im_i, scl_o); + //} + +} \ No newline at end of file diff --git a/src/detail/rnd_2d_cpu.inl b/src/detail/rnd_2d_cpu.inl new file mode 100755 index 00000000..c0d866d8 --- /dev/null +++ b/src/detail/rnd_2d_cpu.inl @@ -0,0 +1,89 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "rnd_2d_cpu.h" + +/* 2d distribution */ +namespace mt +{ + template + Rnd_xd::Rnd_xd(dt_uint64 seed, dt_int32 n_iter): Gen_seed(seed), + m_sc{1, 1}, m_b_dim{true, true} + { + set_seed(seed, n_iter); + } + + template + void Rnd_xd::set_in_data(const dt_uint64& seed, const R_2d& sc, const R_2d& sft, dt_int32 n_iter) + { + set_seed(seed, n_iter); + set_sc_sft(sc, sft); + } + + template + void Rnd_xd::set_seed(dt_uint64 seed, dt_int32 n_iter) + { + auto gen_seed = this->seed_2d(seed, n_iter); + + rnd_x.set_seed(gen_seed.x); + rnd_y.set_seed(gen_seed.y); + } + + template + void Rnd_xd::set_sc_sft(const R_2d& sc, const R_2d& sft) + { + m_sc = sc; + m_sft = sft; + } + + template + void Rnd_xd::set_act_dim(const R_2d& b_dim) + { + m_b_dim = b_dim; + } + + template + R_2d Rnd_xd::operator()() + { + return this->operator()(m_sc, m_sft); + } + + template + R_2d Rnd_xd::operator()(const R_2d& sc) + { + return gen_rnd(sc); + } + + template + R_2d Rnd_xd::operator()(const R_2d& sc, const R_2d& sft) + { + return gen_rnd(sc, sft); + } + + template + R_2d Rnd_xd::gen_rnd(const R_2d& sc) + { + return {(m_b_dim.x)?(rnd_x(sc.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y)):T(0)}; + } + + template + R_2d Rnd_xd::gen_rnd(const R_2d& sc, const R_2d& sft) + { + return {(m_b_dim.x)?(rnd_x(sc.x, sft.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y, sft.y)):T(0)}; + } +} \ No newline at end of file diff --git a/src/detail/rnd_3d_cpu.inl b/src/detail/rnd_3d_cpu.inl new file mode 100755 index 00000000..422fa008 --- /dev/null +++ b/src/detail/rnd_3d_cpu.inl @@ -0,0 +1,90 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "rnd_3d_cpu.h" + +/* 3d distribution */ +namespace mt +{ + template + Rnd_xd::Rnd_xd(dt_uint64 seed, dt_int32 n_iter): Gen_seed(seed), + m_sc{1, 1, 1}, m_sft{0, 0, 0}, m_b_dim{true, true, true} + { + set_seed(seed, n_iter); + } + + template + void Rnd_xd::set_in_data(const dt_uint64& seed, const R_3d& sc, const R_3d& sft, dt_int32 n_iter) + { + set_seed(seed, n_iter); + set_sc_sft(sc, sft); + } + + template + void Rnd_xd::set_seed(dt_uint64 seed, dt_int32 n_iter=1) + { + auto gen_seed = this->seed_3d(seed, n_iter); + + rnd_x.set_seed(gen_seed.x); + rnd_y.set_seed(gen_seed.y); + rnd_z.set_seed(gen_seed.z); + } + + template + void Rnd_xd::set_sc_sft(const R_3d& sc, const R_3d& sft) + { + m_sc = sc; + m_sft = sft; + } + + template + void Rnd_xd::set_act_dim(const R_3d& b_dim) + { + m_b_dim = b_dim; + } + + template + R_3d Rnd_xd::operator()() + { + return this->operator()(m_sc, m_sft); + } + + template + R_3d Rnd_xd::operator()(const R_3d& sc) + { + return gen_rnd(sc); + } + + template + R_3d Rnd_xd::operator()(const R_3d& sc, const R_3d& sft) + { + return gen_rnd(sc, sft); + } + + template + R_3d Rnd_xd::gen_rnd(const R_3d& sc) + { + return {(m_b_dim.x)?(rnd_x(sc.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y)):T(0), (m_b_dim.z)?(rnd_z(sc.z)):T(0)}; + } + + template + R_3d Rnd_xd::gen_rnd(const R_3d& sc, const R_3d& sft) + { + return {(m_b_dim.x)?(rnd_x(sc.x, sft.x)):T(0), (m_b_dim.y)?(rnd_y(sc.y, sft.y)):T(0), (m_b_dim.z)?(rnd_z(sc.z, sft.z)):T(0)}; + } +} \ No newline at end of file diff --git a/src/detail/rnd_cpu.inl b/src/detail/rnd_cpu.inl new file mode 100755 index 00000000..651e0a57 --- /dev/null +++ b/src/detail/rnd_cpu.inl @@ -0,0 +1,157 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "rnd_cpu.h" + +/* class template random distribution */ +namespace mt +{ + template + void Rnd_Dist::set_seed(const dt_uint64& seed) + { + gen.seed(seed); + rnd.reset(); + } + + template + void Rnd_Dist::reset_rnd() + { + rnd.reset(); + } + + template + T Rnd_Dist::operator()(const T& x) + { + return x*rnd(gen); + } + + template + T Rnd_Dist::operator()(const T& x, const T& sft) + { + return this->operator()(x) + sft; + } +} + +/* template specialization random distribution Poisson */ +namespace mt +{ + template + void Rnd_Dist::set_seed(const dt_uint64& seed) + { + gen.seed(seed); + rnd.reset(); + } + + template + void Rnd_Dist::reset_rnd() + { + rnd.reset(); + } + + template + T Rnd_Dist::operator()(const T& x) + { + rnd.param(Dist_type::param_type(x)); + + return T(rnd(gen)); + } + + template + T Rnd_Dist::operator()(const T& x, const T& sft) + { + return this->operator()(x) + sft; + } +} + +/* class generation seed */ +namespace mt +{ + Gen_seed::Gen_seed(dt_uint64 seed): m_seed(seed), rnd_u(1) + { + set_seed(seed); + } + + dt_uint64 Gen_seed::seed_1d(dt_uint64 seed, dt_int32 n_iter) + { + set_seed(seed); + + return iseed(n_iter); + } + + R_2d Gen_seed::seed_2d(dt_uint64 seed, dt_int32 n_iter) + { + set_seed(seed); + + return {iseed(n_iter), iseed(n_iter)}; + } + + R_3d Gen_seed::seed_3d(dt_uint64 seed, dt_int32 n_iter) + { + set_seed(seed); + + return {iseed(n_iter), iseed(n_iter), iseed(n_iter)}; + } + + dt_uint64 Gen_seed::operator()() + { + return rnd_u(gen_u); + } + + Vctr_uint64_cpu Gen_seed::operator()(const dt_int32& n_spl) + { + Vctr_uint64_cpu vctr; + vctr.reserve(n_spl); + for(auto ik=0; ik + using enable_if_dist_p = typename std::enable_if::type; + + template + using enable_ifn_dist_p = typename std::enable_if::type; +} \ No newline at end of file diff --git a/src/detail/shape_t.inl b/src/detail/shape_t.inl new file mode 100755 index 00000000..78a4cddf --- /dev/null +++ b/src/detail/shape_t.inl @@ -0,0 +1,170 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "shape_t.h" + +/************************************* constructors ************************************/ +template +dt_shape_st::dt_shape_st(): dim_max(4) +{ + for (int32_t ik=0; ik +template +dt_shape_st::dt_shape_st(const U& s0): dt_shape_st() +{ + m_data[0] = T(s0); +} + +template +template +dt_shape_st::dt_shape_st(const U& s0, const V& s1): dt_shape_st() +{ + m_data[0] = T(s0); + m_data[1] = T(s1); +} + +template +template +dt_shape_st::dt_shape_st(const U& s0, const V& s1, const X& s2): dt_shape_st() +{ + m_data[0] = T(s0); + m_data[1] = T(s1); + m_data[2] = T(s2); +} + +template +template +dt_shape_st::dt_shape_st(const U& s0, const V& s1, const X& s2, const Y& s3): dt_shape_st() +{ + m_data[0] = T(s0); + m_data[1] = T(s1); + m_data[2] = T(s2); + m_data[3] = T(s3); +} + +/* copy constructor */ +template +dt_shape_st::dt_shape_st(const dt_shape_st& shape): dt_shape_st() +{ + *this = shape; +} + +/* converting constructor */ +template +template +dt_shape_st::dt_shape_st(const dt_shape_st& shape): dt_shape_st() +{ + *this = shape; +} + +/******************************** assignment operators *********************************/ +/* copy assignment operator */ +template +dt_shape_st& dt_shape_st::operator=(const dt_shape_st& shape) +{ + for (int32_t ik=0; ik +template +dt_shape_st& dt_shape_st::operator=(const dt_shape_st& shape) +{ + for (int32_t ik=0; ik +T& dt_shape_st::operator[](const int32_t& iy) +{ + return m_data[iy]; +} + +template +const T& dt_shape_st::operator[](const int32_t& iy) const +{ + return m_data[iy]; +} + +template +T* dt_shape_st::data() +{ + return m_data; +} + +template +const T* dt_shape_st::data() const +{ + return m_data; +} + +template +T dt_shape_st::size() +{ + return T(dim_max); +} + +template +T dt_shape_st::shape_size() +{ + T ss = 1; + for (int32_t ik=0; ik +void dt_shape_st::swap(const int32_t& ind_0, const int32_t& ind_e) +{ + std::swap(m_data[ind_0], m_data[ind_e]); +} + +template +T dt_shape_st::dim() const +{ + int32_t ik_0 = dim_max - 1; + int32_t ic = 0; + for (int32_t ik=ik_0; ik>1; ik--) + { + if (m_data[ik]<2) + { + ic++; + } + else + break; + } + + return T(dim_max-ic); +} \ No newline at end of file diff --git a/src/detail/stream_cpu.inl b/src/detail/stream_cpu.inl new file mode 100755 index 00000000..416bcb37 --- /dev/null +++ b/src/detail/stream_cpu.inl @@ -0,0 +1,607 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "stream_cpu.h" + +/* template specialization cpu stream */ +namespace mt +{ + Stream::Stream(): shape(), n_stream(0), n_stream_act(0), stream(nullptr) {} + + Stream::Stream(const dt_int32& n_stream): Stream() + { + resize(n_stream); + } + + Stream::Stream(const dt_int32& n_stream, const dt_shape& shape): Stream() + { + resize(n_stream); + set_grid(shape); + } + + Stream::~Stream(){ + cleanup(); + n_stream = n_stream_act = 0; + } + + dt_int32 Stream::size() const + { + return n_stream; + } + + dt_bool Stream::is_single_thread() const + { + return n_stream < 2; + } + + void Stream::resize(const dt_int32& n_stream) + { + cleanup(); + + this->n_stream = (n_stream<1)?1:n_stream; + + if (this->n_stream > 1) + { + stream = new std::thread[this->n_stream-1]; + } + + set_n_stream_act(size()); + } + + std::thread& Stream::operator[](const dt_int32& iy) + { + return stream[iy]; + } + + const std::thread& Stream::operator[](const dt_int32& iy) const + { + return stream[iy]; + } + + void Stream::synchronize() + { + cleanup(); + + if (n_stream > 1) + { + stream = new std::thread[n_stream-1]; + } + } + + void Stream::set_n_stream_act(const dt_int32& n_stream_act) + { + this->n_stream_act = (n_stream_act<0)?0:min(size(), n_stream_act); + } + + void Stream::set_grid(const dt_shape& shape) + { + this->shape = shape; + } + + void Stream::set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(nx); + } + + void Stream::set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx); + } + + void Stream::set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx, nz); + } + + template + enable_if_edim_1> + Stream::get_ithread_rect_xd(dt_int32 istm) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + ithread_rect.ix_0 = istm*qsiz; + ithread_rect.ix_e = (istm+1)*qsiz; + + if (istm == n_stream_act-1) + { + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + ithread_rect.ix_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_2> + Stream::get_ithread_rect_xd(dt_int32 istm) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnx = shape[1]/n_stream_act; + ithread_rect.ix_0 = istm*qnx; + ithread_rect.ix_e = (istm+1)*qnx; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.ix_e += (shape[1] - qnx*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_3> + Stream::get_ithread_rect_xd(dt_int32 istm) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnz = shape[2]/n_stream_act; + ithread_rect.iz_0 = istm*qnz; + ithread_rect.iz_e = (istm+1)*qnz; + ithread_rect.ix_0 = 0; + ithread_rect.ix_e = shape[1]; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.iz_e += (shape[2] - qsiz*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + /***************************************************************************************/ + template + enable_if_edim_1 + Stream::exec_xd_krn(const dt_int32& nx, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx); + + if (n_stream_act < 1) + { + return; + } + + auto thr_fcn = [&](const iThread_Rect_xd& ithread) + { + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + fcn(ind, arg...); + } + }; + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(thr_fcn, std::move(get_ithread_rect_xd(istm))); + } + + thr_fcn(std::move(get_ithread_rect_xd(n_stream_act-1))); + + synchronize(); + } + + template + enable_if_edim_2 + Stream::exec_xd_krn(const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx, ny); + + if (n_stream_act < 1) + { + return; + } + + auto thr_fcn = [&](const iThread_Rect_xd& ithread) + { + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, arg...); + } + } + }; + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(thr_fcn, std::move(get_ithread_rect_xd(istm))); + } + + thr_fcn(std::move(get_ithread_rect_xd(n_stream_act-1))); + + synchronize(); + } + + template + enable_if_edim_3 + Stream::exec_xd_krn(const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nz), nx, ny, nz); + + if (n_stream_act < 1) + { + return; + } + + auto thr_fcn = [&](const iThread_Rect_xd& ithread) + { + for(auto iz = ithread.iz_0; iz < ithread.iz_e; iz++) + { + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, iz, arg...); + } + } + } + }; + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(thr_fcn, std::move(get_ithread_rect_xd(istm))); + } + + thr_fcn(std::move(get_ithread_rect_xd(n_stream_act-1))); + + synchronize(); + } + + /***************************************************************************************/ + template + enable_if_edim_1 + Stream::exec_xd_fcn(const dt_int32& nx, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx); + + if (n_stream_act < 1) + { + return; + } + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(fcn, get_ithread_rect_xd(istm), std::ref(arg)...)); + } + + fcn(get_ithread_rect_xd(n_stream_act-1), std::ref(arg)...); + + synchronize(); + } + + template + enable_if_edim_2 + Stream::exec_xd_fcn(const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nx), nx, ny); + + if (n_stream_act < 1) + { + return; + } + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(fcn, get_ithread_rect_xd(istm), std::ref(arg)...)); + } + + fcn(get_ithread_rect_xd(n_stream_act-1), std::ref(arg)...); + + synchronize(); + } + + template + enable_if_edim_3 + Stream::exec_xd_fcn(const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs& ...arg) + { + set_n_stream_act_grid(min(size(), nz), nx, ny, nz); + + if (n_stream_act < 1) + { + return; + } + + for(auto istm = 0; istm < n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(fcn, get_ithread_rect_xd(istm), std::ref(arg)...)); + } + + fcn(get_ithread_rect_xd(n_stream_act-1), std::ref(arg)...); + + synchronize(); + } + + void Stream::cleanup() + { + if ((n_stream <= 0) || (stream==nullptr)) + { + return; + } + + for(auto i = 0; i < n_stream-1; i++) + { + if (stream[i].joinable()) + { + stream[i].join(); + } + } + + delete [] stream; + stream = nullptr; + }; +} + +/* stream functions */ +namespace mt +{ + dt_bool fcn_is_single_thread(Stream_cpu* pstream) + { + return (pstream == nullptr)?true:pstream->is_single_thread(); + } +} + +/* kernel execution functions */ +namespace mt +{ + template + enable_if_edim_1 + fcn_stream_exec_xd_krn(Stream_cpu* pstream, const dt_int32& nx, TFcn& fcn, TArgs&& ...arg) + { + if (pstream == nullptr) + { + Stream_cpu stream(1); + stream.exec_xd_krn(nx, fcn, arg...); + } + else + { + pstream->exec_xd_krn(nx, fcn, arg...); + } + } + + template + enable_if_edim_2 + fcn_stream_exec_xd_krn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs&& ...arg) + { + if (pstream == nullptr) + { + Stream_cpu stream(1); + stream.exec_xd_krn(nx, ny, fcn, arg...); + } + else + { + pstream->exec_xd_krn(nx, ny, fcn, arg...); + } + } + + template + enable_if_edim_3 + fcn_stream_exec_xd_krn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs&& ...arg) + { + if (pstream == nullptr) + { + Stream_cpu stream(1); + stream.exec_xd_krn(nx, ny, nz, fcn, arg...); + } + else + { + pstream->exec_xd_krn(nx, ny, nz, fcn, arg...); + } + } +} + +/* kernel reduction execution functions */ +namespace mt +{ + template + enable_if_edim_1 + fcn_stream_exec_xd_krn_reduce(Stream_cpu* pstream, const dt_int32& nx, TOp&& fcn_op, T v_0, TFcn& fcn, TArgs&& ...arg) + { + auto thr_fcn = [](const iThread_Rect_xd& ithread, TFcn& fcn, TArgs&& ...arg, std::vector& vctr) + { + KS v_part = vctr[ithread.istm]; + + for(auto ind = ithread.ind_0; ind < ithread.ind_e; ind++) + { + fcn(ind, arg..., v_part); + } + + vctr[ithread.istm] = v_part; + }; + + T v_tot = v_0; + + if (fcn_is_single_thread(pstream)) + { + std::vector vctr(1, v_0); + thr_fcn(iThread_Rect_xd(nx), fcn, arg..., vctr); + v_tot = vctr[0]; + } + else + { + std::vector vctr(pstream->size(), v_0); + pstream->exec_xd_fcn(nx, thr_fcn, fcn, arg..., vctr); + + // run remainder operations + for(auto ik=0; ik + enable_if_edim_2 + fcn_stream_exec_xd_krn_reduce(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, TOp&& fcn_op, T v_0, TFcn& fcn, TArgs&& ...arg) + { + auto thr_fcn = [](const iThread_Rect_xd& ithread, TFcn& fcn, TArgs&& ...arg, std::vector& vctr) + { + KS v_part = vctr[ithread.istm]; + + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, arg..., v_part); + } + } + + vctr[ithread.istm] = v_part; + }; + + T v_tot = v_0; + + if (fcn_is_single_thread(pstream)) + { + std::vector vctr(1, v_0); + thr_fcn(iThread_Rect_xd(nx, ny), fcn, arg..., vctr); + v_tot = vctr[0]; + } + else + { + std::vector vctr(pstream->size(), v_0); + pstream->exec_xd_fcn(nx, ny, thr_fcn, fcn, arg..., vctr); + + // run remainder operations + for(auto ik=0; ik + enable_if_edim_3 + fcn_stream_exec_xd_krn_reduce(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TOp&& fcn_op, T v_0, TFcn& fcn, TArgs&& ...arg) + { + auto thr_fcn = [](const iThread_Rect_xd& ithread, TFcn& fcn, TArgs&& ...arg, std::vector& vctr) + { + KS v_part = vctr[ithread.istm]; + + for(auto iz = ithread.iz_0; iz < ithread.iz_e; iz++) + { + for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + { + for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + { + fcn(ix, iy, iz, arg..., v_part); + } + } + } + + vctr[ithread.istm] = v_part; + }; + + T v_tot = v_0; + + if (fcn_is_single_thread(pstream)) + { + std::vector vctr(1, v_0); + thr_fcn(iThread_Rect_xd(nx, ny, nz), fcn, arg..., vctr); + v_tot = vctr[0]; + } + else + { + std::vector vctr(pstream->size(), v_0); + pstream->exec_xd_fcn(nx, ny, nz, thr_fcn, fcn, arg..., vctr); + + // run remainder operations + for(auto ik=0; ik + enable_if_edim_1 + fcn_stream_exec_xd_fcn(Stream_cpu* pstream, const dt_int32& nx, TFcn& fcn, TArgs&& ...arg) + { + if (fcn_is_single_thread(pstream)) + { + fcn(iThread_Rect_xd(nx), std::ref(arg)...); + } + else + { + pstream->exec_xd_fcn(nx, fcn, arg...); + } + } + + template + enable_if_edim_2 + fcn_stream_exec_xd_fcn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs&& ...arg) + { + if (fcn_is_single_thread(pstream)) + { + fcn(iThread_Rect_xd(nx, ny), std::ref(arg)...); + } + else + { + pstream->exec_xd_fcn(nx, ny, fcn, arg...); + } + } + + template + enable_if_edim_3 + fcn_stream_exec_xd_fcn(Stream_cpu* pstream, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs&& ...arg) + { + if (fcn_is_single_thread(pstream)) + { + fcn(iThread_Rect_xd(nx, ny, nz), std::ref(arg)...); + } + else + { + pstream->exec_xd_fcn(nx, ny, nz, fcn, arg...); + } + } +} \ No newline at end of file diff --git a/src/detail/stream_gpu.inl b/src/detail/stream_gpu.inl new file mode 100755 index 00000000..bf831d5d --- /dev/null +++ b/src/detail/stream_gpu.inl @@ -0,0 +1,205 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "stream_gpu.h" + +/* template specialization gpu stream */ +namespace mt +{ +#ifdef __CUDACC__ + Stream::Stream(): shape(), n_stream(0), n_stream_act(0) {} + + Stream::Stream(const dt_int32& n_stream): Stream() + { + resize(n_stream); + } + + Stream::Stream(const dt_int32& n_stream, const dt_shape& shape): Stream() + { + resize(n_stream); + set_grid(shape); + } + + Stream::~Stream() + { + cleanup(); + n_stream = n_stream_act = 0; + } + + dt_int32 Stream::size() const + { + return static_cast(stream.size()); + } + + void Stream::resize(const dt_int32& n_stream) + { + this->n_stream = max(1, n_stream); + + cleanup(); + + stream.resize(this->n_stream); + + for(auto i = 0; i < this->n_stream; i++) + { + cudaStreamCreate(&(stream[i])); + } + + set_n_stream_act(size()); + } + + cudaStream_t& Stream::operator[](const dt_int32& iy) + { + return stream[iy]; + } + + const cudaStream_t& Stream::operator[](const dt_int32& iy) const + { + return stream[iy]; + } + + void Stream::synchronize() + { + cudaDeviceSynchronize(); + } + + void Stream::set_n_stream_act(const dt_int32& n_stream_act) + { + this->n_stream_act = (n_stream_act<0)?0:min(size(), n_stream_act); + } + + void Stream::set_grid(const dt_shape& shape) + { + this->shape = shape; + } + + void Stream::set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(nx); + } + + void Stream::set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx); + } + + void Stream::set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz) + { + set_n_stream_act(n_stream_act); + shape = dt_shape(ny, nx, nz); + } + + template + enable_if_edim_1> + Stream::get_ithread_rect_xd(dt_int32 istm) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + ithread_rect.ix_0 = istm*qsiz; + ithread_rect.ix_e = (istm+1)*qsiz; + + if (istm == n_stream_act-1) + { + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + ithread_rect.ix_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_2> + Stream::get_ithread_rect_xd(dt_int32 istm) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnx = shape[1]/n_stream_act; + ithread_rect.ix_0 = istm*qnx; + ithread_rect.ix_e = (istm+1)*qnx; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.ix_e += (shape[1] - qnx*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + template + enable_if_edim_3> + Stream::get_ithread_rect_xd(dt_int32 istm) + { + iThread_Rect_xd ithread_rect; + + ithread_rect.istm = istm; + auto sz = shape.shape_size(); + auto qsiz = sz/n_stream_act; + ithread_rect.ind_0 = istm*qsiz; + ithread_rect.ind_e = (istm+1)*qsiz; + + auto qnz = shape[2]/n_stream_act; + ithread_rect.iz_0 = istm*qnz; + ithread_rect.iz_e = (istm+1)*qnz; + ithread_rect.ix_0 = 0; + ithread_rect.ix_e = shape[1]; + ithread_rect.iy_0 = 0; + ithread_rect.iy_e = shape[0]; + + if (istm == n_stream_act-1) + { + ithread_rect.iz_e += (shape[2] - qsiz*n_stream_act); + ithread_rect.ind_e += (sz - qsiz*n_stream_act); + } + + return ithread_rect; + } + + void Stream::cleanup() + { + if (stream.empty()) + { + return; + } + + cudaDeviceSynchronize(); + + for(auto istm = 0; istm < stream.size(); istm++) + { + cudaStreamDestroy(stream[istm]); + } + + stream.clear(); + } +#endif +} diff --git a/src/detail/system_config.inl b/src/detail/system_config.inl new file mode 100755 index 00000000..33cb715b --- /dev/null +++ b/src/detail/system_config.inl @@ -0,0 +1,179 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "vctr_cpu.h" +#include "info_cpu.h" +#include "info_gpu.h" + +#include "system_config.h" + +namespace mt +{ + System_Config::System_Config(): precision(eprc_float64), device(edev_cpu), cpu_n_proc(1), + cpu_n_thread(1), gpu_n_stream(1), gpu_n_avbl(0), n_stream(1), idx_0(0) {} + + System_Config::System_Config(const System_Config &system_config) + { + *this = system_config; + } + + System_Config& System_Config::operator=(const System_Config &system_config) + { + precision = system_config.precision; + device = system_config.device; + cpu_n_proc = system_config.cpu_n_proc; + cpu_n_thread = system_config.cpu_n_thread; + gpu_device = system_config.gpu_device; + gpu_n_stream = system_config.gpu_n_stream; + n_stream = system_config.n_stream; + idx_0 = system_config.idx_0; + gpu_n_avbl = system_config.gpu_n_avbl; + + return *this; + } + + void System_Config::set_dep_var() + { + // check precision + if (!(is_float32() || is_float64())) + { + precision = eprc_float32; + } + + // check cpu or gpu + if (!(is_cpu() || is_gpu())) + { + device = edev_cpu; + } + if (is_gpu()) + { + #ifdef __CUDACC__ + if (!dev_info::is_gpu_avbl()) + { + device = edev_cpu; + gpu_n_avbl = 0; + } + else + { + cpu_n_thread = 1; + gpu_n_avbl = dev_info::gpu_n_avbl(); + for(auto gpu_ind=0; gpu_ind +* +* Multem is destroy software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "vctr_cpu.h" + +/* vector copy */ +namespace mt +{ + template class Vctr; + + // (dst, src): cpu -> cpu + template + void vctr_cpy(Vctr& vctr_cpu_dst, const Vctr& vctr_cpu_src, Ts* pvctr_cpu_jk = nullptr) + { + memcpy_cpu_cpu(vctr_cpu_dst.data(), vctr_cpu_src.data(), vctr_cpu_src.size(), pvctr_cpu_jk); + } + +#ifdef __CUDACC__ + // (dst, src): gpu -> cpu + template + void vctr_cpy(Vctr& vctr_cpu_dst, const Vctr& vctr_gpu_src, Ts* pvctr_cpu_jk = nullptr) + { + memcpy_gpu_cpu(vctr_cpu_dst.data(), vctr_gpu_src.data(), vctr_gpu_src.size(), pvctr_cpu_jk); + } + + // (dst, src): cpu -> gpu + template + void vctr_cpy(Vctr& vctr_gpu_dst, const Vctr& vctr_cpu_src, Td* pvctr_cpu_jk = nullptr) + { + memcpy_cpu_gpu(vctr_gpu_dst.data(), vctr_cpu_src.data(), vctr_cpu_src.size(), pvctr_cpu_jk); + } + + // (dst, src): gpu -> gpu + template + void vctr_cpy(Vctr& vctr_gpu_dst, const Vctr& vctr_gpu_src, Td* pvctr_cpu_jk = nullptr) + { + memcpy_gpu_gpu(vctr_gpu_dst.data(), vctr_gpu_src.data(), vctr_gpu_src.size(), pvctr_cpu_jk); + } +#endif +} + +/* cpu vector */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Vctr::Vctr(): m_data(nullptr), m_s0(0), m_s1(1), m_s2(1), m_s3(1), + m_size(shape_size()), m_capacity(0) + { + set_picth(); + } + + template + Vctr::Vctr(const dt_init_list_f64& data): Vctr() + { + assign(data.begin(), data.end()); + } + + template + Vctr::Vctr(size_type s0): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1) }); + } + + template + Vctr::Vctr(size_type s0, const T& value): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1) }, value); + } + + template + Vctr::Vctr(const dt_shape_st& shape): Vctr() + { + resize(shape); + } + + template + Vctr::Vctr(const dt_shape_st& shape, const T& value): Vctr() + { + resize(shape, value); + } + + /* copy constructor */ + template + Vctr::Vctr(const Vctr& vctr): Vctr() + { + *this = vctr; + } + + /* Move constructor */ + template + Vctr::Vctr(Vctr&& vctr): Vctr() + { + *this = std::move(vctr); + } + + /* converting constructor */ + template + template + Vctr::Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + template + Vctr::Vctr(U* first, U* last): Vctr() + { + assign(first, last); + } + + template + template + Vctr::Vctr(U *p, dt_int64 n_p, dt_int64 icol): Vctr() + { + set_pos_from_cpu_ptr(p, n_p, icol); + } + + template + template + Vctr::Vctr(const std::vector& vctr): Vctr() + { + assign(vctr); + } + + // from cpu pVctr to Vctr + template + template + Vctr::Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } + +#ifdef __CUDACC__ +template + template + Vctr::Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + template + Vctr::Vctr(const thrust::host_vector& vctr): Vctr() + { + assign(vctr); + } + + template + template + Vctr::Vctr(const thrust::device_vector& vctr): Vctr() + { + assign(vctr); + } + + // from gpu pVctr to Vctr + template + template + Vctr::Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } +#endif + template + Vctr::~Vctr() + { + destroy(); + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Vctr& Vctr::operator=(const Vctr& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + delete[] m_data; + + m_data = new T[vctr.m_capacity]; + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size()); + + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + } + + return *this; + } + + /* Move assignment operator */ + template + Vctr& Vctr::operator=(Vctr&& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + delete[] m_data; + + m_data = vctr.m_data; + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s2 = vctr.m_s2; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + + vctr.m_data = nullptr; + vctr.m_s0 = 0; + vctr.m_s1 = 0; + vctr.m_s2 = 0; + vctr.m_s3 = 0; + vctr.m_size = 0; + vctr.m_capacity = 0; + vctr.m_pitch_s1 = 0; + vctr.m_pitch_s2 = 0; + vctr.m_pitch_s3 = 0; + } + + return *this; + } + + /* converting assignment operator */ + template + template + Vctr& Vctr::operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + template + Vctr& Vctr::operator=(const std::vector& vctr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size()); + + return *this; + } + +#ifdef __CUDACC__ +template + template + Vctr& Vctr::operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + template + Vctr& Vctr::operator=(const thrust::host_vector& vctr) + { + assign(vctr); + + return *this; + } + + template + template + Vctr& Vctr::operator=(const thrust::device_vector& vctr) + { + assign(vctr); + + return *this; + } +#endif + + template + template + void Vctr::assign(const Vctr& vctr, U* pvctr_cpu) + { + if ((void*)this != (void*)&vctr) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + } + + template + template + void Vctr::assign(U* first, U* last) + { + if ((void*)m_data != (void*)first) + { + auto m_size_i = std::distance(first, last); + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, first, m_size); + } + } + } + + // from cpu pVctr to Vctr + template + template + void Vctr::assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_cpu_cpu(m_data, pvctr.data(), m_size); + } + +#ifdef __CUDACC__ + template + template + void Vctr::assign(const thrust::device_ptr& first, const thrust::device_ptr& last, U* pvctr_cpu) + { + auto m_size_i = thrust::distance(first, last); + + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_cpu(m_data, (U*)first.get(), m_size, pvctr_cpu); + } + } + + // from gpu pVctr to Vctr + template + template + void Vctr::assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_gpu_cpu(m_data, pvctr.data(), m_size); + } +#endif + + template + template + void Vctr::assign(const std::vector& vctr, U* pvctr_cpu) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + +#ifdef __CUDACC__ + template + template + void Vctr::assign(const Vctr& vctr, U* pvctr_cpu) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + + template + template + void Vctr::assign(const thrust::host_vector& vctr, U* pvctr_cpu) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_cpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + + template + template + void Vctr::assign(const thrust::device_vector& vctr, U* pvctr_cpu) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_cpu(m_data, (U*)vctr.data().get(), vctr.size(), pvctr_cpu); + } +#endif + /**************** user define conversion operators *******************/ + template + pVctr_cpu_32 Vctr::ptr_32() const + { + return pVctr_cpu_32(*this); + } + + template + pVctr_cpu_64 Vctr::ptr_64() const + { + return pVctr_cpu_64(*this); + } + + template + Vctr::operator pVctr_cpu_32() const + { + return pVctr_cpu_32(*this); + } + + template + Vctr::operator pVctr_cpu_64() const + { + return pVctr_cpu_64(*this); + } + + /* user define conversion */ + template + Vctr::operator std::vector() const + { + std::vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion in which T is the complemented precision */ + template + template + Vctr::operator std::vector() const + { + std::vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + +#ifdef __CUDACC__ + /* user define conversion to output type std::vector> */ + template + template + Vctr::operator std::vector>() const + { + std::vector> vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion to output type std::vector> */ + template + template + Vctr::operator std::vector>() const + { + std::vector>vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + /* user define conversion */ + template + Vctr::operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion in which T is the complemented precision */ + template + template + Vctr::operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion to output type thrust::host_vector> */ + template + template + Vctr::operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion to output type thrust::host_vector> */ + template + template + Vctr::operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_cpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + /* user define conversion */ + template + Vctr::operator thrust::device_vector() const + { + thrust::device_vector vctr(m_size); + memcpy_cpu_gpu((T*)vctr.data().get(), m_data, m_size); + + return vctr; + } + + /* user define conversion in which T is the complemented precision */ + template + template + Vctr::operator thrust::device_vector() const + { + thrust::device_vector vctr(m_size); + memcpy_cpu_gpu((U*)vctr.data().get(), m_data, m_size); + + return vctr; + } +#endif + /***************************************************************************************/ + template + template + void Vctr::cpy_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_cpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_to_cpu_ptr(U* first, U* last, T* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_cpu_cpu(first, m_data, n_data, pvctr_cpu); + } + +#ifdef __CUDACC__ + template + template + void Vctr::cpy_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_cpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_to_gpu_ptr(U* first, U* last, U* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_cpu_gpu(first, m_data, n_data, pvctr_cpu); + } +#endif + + /***************************************************************************************/ + template + template + void Vctr::cpy_real_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_real_cpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_real_to_cpu_ptr(U* first, U* last, T* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_real_cpu_cpu(first, m_data, n_data, pvctr_cpu); + } + +#ifdef __CUDACC__ + template + template + void Vctr::cpy_real_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_real_cpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_real_to_gpu_ptr(U* first, U* last, U* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_real_cpu_gpu(first, m_data, n_data, pvctr_cpu); + } +#endif + + /***************************************************************************************/ + template + template + void Vctr::cpy_imag_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_imag_cpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_imag_to_cpu_ptr(U* first, U* last, T* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_imag_cpu_cpu(first, m_data, n_data, pvctr_cpu); + } + +#ifdef __CUDACC__ + template + template + void Vctr::cpy_imag_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_imag_cpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_imag_to_gpu_ptr(U* first, U* last, U* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_imag_cpu_gpu(first, m_data, n_data, pvctr_cpu); + } +#endif + + /***************************************************************************************/ + template + template + void Vctr::set_pos_from_cpu_ptr(U *p, size_type n_p, dt_int64 icol) + { + resize({n_p}); + + memcpy_pos_cpu_cpu(m_data, p, size(), icol); + } + + template + template + void Vctr::cpy_pos_to_cpu_ptr(U *p, size_type icol) + { + memcpy_pos_cpu_cpu(p, m_data, size(), icol); + } + + /***************************************************************************************/ + template + void Vctr::resize(const dt_shape_st& shape) + { + this->allocate(shape); + } + + template + void Vctr::resize(const dt_shape_st& shape, const T& value) + { + auto m_size_t = m_size; + this->allocate(shape); + std::fill(this->begin()+m_size_t, this->end(), value); + } + + template + void Vctr::reserve(const dt_shape_st& shape) + { + this->allocate(shape, true); + } + + template + void Vctr::shrink_to_fit() + { + if (m_size < m_capacity) + { + if (m_size > 0) + { + /* allocate memory and transfer data */ + T* data_tmp = new T[m_size]; + memcpy_cpu_cpu(data_tmp, m_data, m_size); + delete[] m_data; + + m_data = data_tmp; + data_tmp = nullptr; + } + else + { + delete[] m_data; + m_data = nullptr; + } + + m_capacity = m_size; + + if (shape().dim()==2) + { + if (m_s1==1) + m_s0 = m_size; + + if (m_s0==1) + m_s1 = m_size; + } + } + } + + template + template + void Vctr::push_back(const U& val) + { + if (m_size >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_type(1), 2*m_size); + else + shape[1] *= size_type(2); + } + else + { + shape[2] *= size_type(2); + } + } + else + { + shape[3] *= size_type(2); + } + + this->allocate(shape, true); + } + + m_data[m_size++] = T(val); + } + + template + template + void Vctr::push_back(const Vctr& vctr) + { + const size_type size_new = m_size + vctr.size(); + + if (size_new >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_new, 2*shape[0]); + else + shape[1] = max(size_new/shape[0], 2*shape[1]); + } + else + { + shape[2] = max(size_new/(shape[0]*shape[1]), 2*shape[2]); + } + } + else + { + shape[3] = max(size_new/(shape[0]*shape[1]*shape[2]), 2*shape[3]); + } + + this->allocate(shape, true); + } + + memcpy_cpu_cpu(m_data + m_size, vctr.data(), vctr.size()); + + m_size = size_new; + } + + template + void Vctr::pop_back() + { + if (m_size >= 1) + { + m_size--; + } + } + + template + void Vctr::fill(T val) + { + std::fill(this->begin(), this->end(), val); + } + + /***************************************************************************************/ + template + typename Vctr::size_type Vctr::s0() const + { + return m_s0; + } + + template + typename Vctr::size_type Vctr::s1() const + { + return m_s1; + } + + template + typename Vctr::size_type Vctr::s2() const + { + return m_s2; + } + + template + typename Vctr::size_type Vctr::s3() const + { + return m_s2; + } + + template + dt_int32 Vctr::s0_32() const + { + return static_cast(m_s0); + } + + template + dt_int32 Vctr::s1_32() const + { + return static_cast(m_s1); + } + + template + dt_int32 Vctr::s2_32() const + { + return static_cast(m_s2); + } + + template + dt_int32 Vctr::s3_32() const + { + return static_cast(m_s3); + } + + template + dt_int64 Vctr::s0_64() const + { + return static_cast(m_s0); + } + + template + dt_int64 Vctr::s1_64() const + { + return static_cast(m_s1); + } + + template + dt_int64 Vctr::s2_64() const + { + return static_cast(m_s2); + } + + template + dt_int64 Vctr::s3_64() const + { + return static_cast(m_s3); + } + + template + typename Vctr::size_type Vctr::s0h() const + { + return m_s0/size_type(2); + } + + template + typename Vctr::size_type Vctr::s1h() const + { + return m_s1/size_type(2); + } + + template + typename Vctr::size_type Vctr::s2h() const + { + return m_s2/size_type(2); + } + + template + typename Vctr::size_type Vctr::s3h() const + { + return m_s3/size_type(2); + } + + template + dt_shape_st::size_type> Vctr::shape() const + { + return {m_s0, m_s1, m_s2, m_s3}; + } + + template + dt_shape_st::size_type> Vctr::shape_2d_trs() const + { + return {m_s1, m_s0, m_s2, m_s3}; + } + + template + typename Vctr::size_type Vctr::shape_size() const + { + return m_s0*max(m_s1, size_type(1))*max(m_s2, size_type(1))*max(m_s3, size_type(1)); + } + + template + typename Vctr::size_type Vctr::pitch_s1() const + { + return m_pitch_s1; + } + + template + typename Vctr::size_type Vctr::pitch_s2() const + { + return m_pitch_s2; + } + + template + typename Vctr::size_type Vctr::pitch_s3() const + { + return m_pitch_s3; + } + + template + typename Vctr::size_type Vctr::size() const + { + return m_size; + } + + template + dt_int32 Vctr::size_32() const + { + return static_cast(m_size); + } + + template + dt_int64 Vctr::size_64() const + { + return static_cast(m_size); + } + + template + iGrid_1d Vctr::igrid_1d() const + { + return {size_32()}; + } + + template + iGrid_2d Vctr::igrid_2d() const + { + return {s1_32(), s0_32()}; + } + + template + iGrid_3d Vctr::igrid_3d() const + { + return {s1_32(), s0_32(), s2_32()}; + } + + template + iGrid_1d_64 Vctr::igrid_1d_64() const + { + return {size_64()}; + } + + template + iGrid_2d_64 Vctr::igrid_2d_64() const + { + return {s1_64(), s0_64()}; + } + + template + iGrid_3d_64 Vctr::igrid_3d_64() const + { + return {s1_64(), s0_64(), s2_64()}; + } + + template + typename Vctr::size_type Vctr::capacity() const + { + return m_capacity; + } + + template + dt_bool Vctr::empty() const + { + return m_size == 0; + } + + template + dt_bool Vctr::is_1d() const + { + return (m_s0 == 1) || (m_s1 == 1); + } + + template + void Vctr::clear() + { + m_size = 0; + } + + template + void Vctr::clear_shrink_to_fit() + { + destroy(); + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0) const + { + return ix_0; + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0, const size_type& ix_1) const + { + return ix_0 + m_s0*ix_1; + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + { + return ix_0 + m_s0*(ix_1 + m_s1*ix_2); + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + { + return ix_0 + m_s0*(ix_1 + m_s1*(ix_2 + m_s2*ix_3)); + } + + template + T& Vctr::operator[](const size_type& iy) + { + return m_data[iy]; + } + + template + const T& Vctr::operator[](const size_type& iy) const + { + return m_data[iy]; + } + + template + T& Vctr::operator()(const size_type& iy) + { + return m_data[iy]; + } + + template + const T& Vctr::operator()(const size_type& iy) const + { + return m_data[iy]; + } + + template + T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1) + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + template + const T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1) const + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + template + T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + template + const T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + } + + template + T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + template + const T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + { + return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + } + + template + T* Vctr::begin() + { + return m_data; + } + + template + const T* Vctr::begin() const + { + return m_data; + } + + template + T* Vctr::end() + { + return m_data + m_size; + } + + template + const T* Vctr::end() const + { + return m_data + m_size; + } + + template + T* Vctr::data() + { + return m_data; + } + + template + const T* Vctr::data() const + { + return m_data; + } + + template + template + U Vctr::data_cast() + { + return reinterpret_cast(m_data); + } + + template + template + const U Vctr::data_cast() const + { + return reinterpret_cast(m_data); + } + + template + T& Vctr::front() + { + return m_data[0]; + } + + template + const T& Vctr::front() const + { + return m_data[0]; + } + + template + T& Vctr::back() + { + return m_data[m_size-1]; + } + + template + const T& Vctr::back() const + { + return m_data[m_size-1]; + } + + // set shape + template + void Vctr::set_shape(const dt_shape_st& shape) + { + m_s0 = max(shape[0], size_type(0)); + m_s1 = max(shape[1], size_type(1)); + m_s2 = max(shape[2], size_type(1)); + m_s3 = max(shape[3], size_type(1)); + + set_picth(); + } + + template + void Vctr::trs_shape_2d() + { + set_shape({m_s1, m_s0, m_s2, m_s3}); + } + + template + template + void Vctr::set_shape(const Vctr& vctr, dt_bool bb_size) + { + this->set_shape(vctr.shape(), bb_size); + } + +#ifdef __CUDACC__ + FCNS_IMP_GPU_GRID_BLK_VCTR(template , Vctr); +#endif + + template + void Vctr::set_picth() + { + m_pitch_s1 = m_s0*sizeof(T); + m_pitch_s2 = m_pitch_s1*m_s1; + m_pitch_s3 = m_pitch_s2*m_s2; + } + + template + void Vctr::set_capacity(size_type size_r) + { + m_capacity = max(m_capacity, size_r); + } + + template + void Vctr::set_shape_cstr(dt_shape_st& shape) + { + shape[0] = max(shape[0], size_type(0)); + shape[1] = max(shape[1], size_type(1)); + shape[2] = max(shape[2], size_type(1)); + shape[3] = max(shape[3], size_type(1)); + } + + // reallocate and copy memory + template + void Vctr::allocate(dt_shape_st shape, dt_bool bb_reserve) + { + set_shape_cstr(shape); + + auto size_r = shape[0]*shape[1]*shape[2]*shape[3]; + + if (size_r == 0) + { + return; + } + + if (m_size == 0) + { + if (m_data != nullptr) + { + delete[] m_data; + } + + m_data = new T[size_r]; + } + else if (size_r>m_capacity) + { + /*allocate memory and transfer data */ + T* data_tmp = new T[size_r]; + memcpy_cpu_cpu(data_tmp, m_data, m_size); + + if (m_data != nullptr) + { + delete[] m_data; + } + + m_data = data_tmp; + data_tmp = nullptr; + } + + this->set_shape(shape); + if (!bb_reserve) + { + m_size = size_r; + } + this->set_capacity(size_r); + } + + // destroy memory on the device + template + void Vctr::init() + { + m_data = nullptr; + m_s0 = 0; m_s1 = m_s2 = m_s3 = 1; + m_pitch_s1 = m_pitch_s2 = m_pitch_s3 = 0; + m_size = 0; + m_capacity = 0; + } + + // destroy memory on the device + template + void Vctr::destroy() + { + if (m_data != 0) + { + delete[] m_data; + } + + init(); + } + +} + +/* traits */ +namespace mt +{ + template + struct is_vctr_cpu_r_2d: std::integral_constant::value && is_r_2d::value> {}; + + template + struct is_vctr_cpu_r_2d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_r_2d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_cpu_r_2d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + struct is_vctr_cpu_r_3d: std::integral_constant::value && is_r_3d::value> {}; + + template + struct is_vctr_cpu_r_3d_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_r_3d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_cpu_r_3d_and_vctr_cpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + struct is_vctr_cpu_r_nd: std::integral_constant::value && is_r_nd::value> {}; + + template + struct is_vctr_cpu_r_nd_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_r_nd = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_cpu_r_nd_and_vctr_cpu = typename std::enable_if::value, V>::type; +} \ No newline at end of file diff --git a/src/detail/vctr_gpu.inl b/src/detail/vctr_gpu.inl new file mode 100755 index 00000000..f4490b46 --- /dev/null +++ b/src/detail/vctr_gpu.inl @@ -0,0 +1,1276 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is destroy software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "vctr_gpu.h" + +/* gpu vector */ +namespace mt +{ + /************************************* constructors ************************************/ + template + Vctr::Vctr(): m_data(nullptr), m_s0(0), m_s1(1), m_s2(1), m_s3(1), + m_size(shape_size()), m_capacity(0) + { + set_picth(); + } + + template + Vctr::Vctr(const dt_init_list_f64& data): Vctr() + { + assign(data.begin(), data.end()); + } + + template + Vctr::Vctr(size_type s0): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1) }); + } + + template + Vctr::Vctr(size_type s0, const T& value): Vctr() + { + resize({ s0, size_type(1), size_type(1), size_type(1)}, value); + } + + template + Vctr::Vctr(const dt_shape_st& shape): Vctr() + { + resize(shape); + } + + template + Vctr::Vctr(const dt_shape_st& shape, const T& value): Vctr() + { + resize(shape, value); + } + + /* copy constructor */ + template + Vctr::Vctr(const Vctr& vctr): Vctr() + { + *this = vctr; + } + + /* Move constructor */ + template + Vctr::Vctr(Vctr&& vctr): Vctr() + { + *this = std::move(vctr); + } + + /* converting constructor */ + template + template + Vctr::Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + template + Vctr::Vctr(U* first, U* last): Vctr() + { + assign(first, last); + } + + template + template + Vctr::Vctr(U *p, dt_int64 n_p, size_type icol): Vctr() + { + set_pos_from_cpu_ptr(p, n_p, icol); + } + + template + template + Vctr::Vctr(const std::vector& vctr): Vctr() + { + assign(vctr); + } + + // from gpu pVctr to Vctr + template + template + Vctr::Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } + + // from cpu pVctr to Vctr + template + template + Vctr::Vctr(const pVctr& pvctr): Vctr() + { + assign(pvctr); + } + + template + template + Vctr::Vctr(const Vctr& vctr): Vctr() + { + assign(vctr); + } + + template + template + Vctr::Vctr(const thrust::host_vector& vctr): Vctr() + { + assign(vctr); + } + + template + template + Vctr::Vctr(const thrust::device_vector& vctr): Vctr() + { + assign(vctr); + } + + template + Vctr::~Vctr() + { + destroy(); + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + Vctr& Vctr::operator=(const Vctr& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + fcn_cuda_free(m_data); + + fcn_cuda_malloc(m_data, vctr.m_capacity); + + memcpy_gpu_gpu(m_data, vctr.data(), vctr.size()); + + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s2 = vctr.m_s2; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + } + + return *this; + } + + /* Move assignment operator */ + template + Vctr& Vctr::operator=(Vctr&& vctr) + { + if (vctr.m_data == nullptr) + { + destroy(); + } + else if (this != &vctr) + { + fcn_cuda_free(m_data); + + m_data = vctr.m_data; + m_s0 = vctr.m_s0; + m_s1 = vctr.m_s1; + m_s2 = vctr.m_s2; + m_s3 = vctr.m_s3; + m_size = vctr.m_size; + m_capacity = vctr.m_capacity; + m_pitch_s1 = vctr.m_pitch_s1; + m_pitch_s2 = vctr.m_pitch_s2; + m_pitch_s3 = vctr.m_pitch_s3; + + vctr.m_data = nullptr; + vctr.m_s0 = 0; + vctr.m_s1 = 0; + vctr.m_s2 = 0; + vctr.m_s3 = 0; + vctr.m_size = 0; + vctr.m_capacity = 0; + vctr.m_pitch_s1 = 0; + vctr.m_pitch_s2 = 0; + vctr.m_pitch_s3 = 0; + } + + return *this; + } + + /* converting assignment operator */ + template + template + Vctr& Vctr::operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + template + Vctr& Vctr::operator=(const std::vector& vctr) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, vctr.data(), vctr.size()); + + return *this; + } + + template + template + Vctr& Vctr::operator=(const Vctr& vctr) + { + assign(vctr); + + return *this; + } + + template + template + Vctr& Vctr::operator=(const thrust::host_vector& vctr) + { + assign(vctr); + + return *this; + } + + template + template + Vctr& Vctr::operator=(const thrust::device_vector& vctr) + { + assign(vctr); + + return *this; + } + + template + template + void Vctr::assign(const Vctr& vctr, T* pvctr_cpu) + { + if ((void*)this != (void*)&vctr) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + } + + template + template + void Vctr::assign(U* first, U* last) + { + if ((void*)m_data != (void*)first) + { + auto m_size_i = std::distance(first, last); + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, first, m_size); + } + } + } + + // from gpu pVctr to Vctr + template + template + void Vctr::assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_gpu_gpu(m_data, pvctr.data(), m_size); + } + + template + template + void Vctr::assign(const thrust::device_ptr& first, const thrust::device_ptr& last, T* pvctr_cpu) + { + auto m_size_i = thrust::distance(first, last); + if (m_size_i>0) + { + auto m_size = size_type(m_size_i); + resize({ m_size, size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_gpu(m_data, (U*)first.get(), m_size, pvctr_cpu); + } + } + + // from cpu pVctr to Vctr + template + template + void Vctr::assign(const pVctr& pvctr) + { + resize(pvctr.shape()); + memcpy_cpu_gpu(m_data, pvctr.data(), m_size); + } + + template + template + void Vctr::assign(const std::vector& vctr, T* pvctr_cpu) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + + template + template + void Vctr::assign(const Vctr& vctr, T* pvctr_cpu) + { + this->allocate(vctr.shape()); + vctr_cpy(*this, vctr, pvctr_cpu); + } + + template + template + void Vctr::assign(const thrust::host_vector& vctr, T* pvctr_cpu) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_cpu_gpu(m_data, vctr.data(), vctr.size(), pvctr_cpu); + } + + template + template + void Vctr::assign(const thrust::device_vector& vctr, T* pvctr_cpu) + { + resize({ size_type(vctr.size()), size_type(1), size_type(1), size_type(1) }); + memcpy_gpu_gpu(m_data, (T*)vctr.data().get(), vctr.size(), pvctr_cpu); + } + + /**************** user define conversion operators *******************/ + template + pVctr_gpu_32 Vctr::ptr_32() const + { + + return pVctr_gpu_32(*this); + } + + template + pVctr_gpu_64 Vctr::ptr_64() const + { + + return pVctr_gpu_64(*this); + } + + /* user define conversion for pointer Vctr */ + template + Vctr::operator pVctr_gpu_32() const + { + return pVctr_gpu_32(*this); + } + + template + Vctr::operator pVctr_gpu_64() const + { + return pVctr_gpu_64(*this); + } + + /* user define conversion */ + template + Vctr::operator std::vector() const + { + std::vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion in which T is the complemented precision */ + template + template + Vctr::operator std::vector() const + { + std::vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion to output type std::vector> */ + template + template + Vctr::operator std::vector>() const + { + std::vector> vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + return vctr; + } + + /* user define conversion to output type std::vector> */ + template + template + Vctr::operator std::vector>() const + { + std::vector>vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + return vctr; + } + + /* user define conversion */ + template + Vctr::operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion in which T is the complemented precision */ + template + template + Vctr::operator thrust::host_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion to output type thrust::host_vector> */ + template + template + Vctr::operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /* user define conversion to output type thrust::host_vector> */ + template + template + Vctr::operator thrust::host_vector>() const + { + thrust::host_vector> vctr(m_size); + memcpy_gpu_cpu(vctr.data(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + /* user define conversion */ + template + Vctr::operator thrust::device_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_gpu((T*)vctr.data().get(), m_data, m_size); + return vctr; + } + + /* user define conversion in which T is the complemented precision */ + template + template + Vctr::operator thrust::device_vector() const + { + thrust::host_vector vctr(m_size); + memcpy_gpu_gpu((U*)vctr.data().get(), m_data, m_size); + + return vctr; + } + + /***************************************************************************************/ + template + template + void Vctr::cpy_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_gpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_to_cpu_ptr(U* first, U* last, T* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_gpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_gpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_to_gpu_ptr(U* first, U* last, U* pvctr_cpu) + { + auto n_data = thrust::distance(first, last); + memcpy_gpu_gpu(first, m_data, n_data, pvctr_cpu); + } + + /***************************************************************************************/ + template + template + void Vctr::cpy_real_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_real_gpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_real_to_cpu_ptr(U* first, U* last, T* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_real_gpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_real_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_real_gpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_real_to_gpu_ptr(U* first, U* last, U* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_real_gpu_gpu(first, m_data, n_data, pvctr_cpu); + } + + /***************************************************************************************/ + template + template + void Vctr::cpy_imag_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_imag_gpu_cpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_imag_to_cpu_ptr(U* first, U* last, T* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_imag_gpu_cpu(first, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_imag_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu) + { + n_data = std::min(m_size, n_data); + memcpy_imag_gpu_gpu(pdata, m_data, n_data, pvctr_cpu); + } + + template + template + void Vctr::cpy_imag_to_gpu_ptr(U* first, U* last, U* pvctr_cpu) + { + auto n_data = std::distance(first, last); + memcpy_imag_gpu_gpu(first, m_data, n_data, pvctr_cpu); + } + + /***************************************************************************************/ + template + template + void Vctr::set_pos_from_cpu_ptr(U *p, size_type n_p, dt_int64 icol) + { + resize({n_p}); + + memcpy_pos_cpu_gpu(m_data, p, size(), icol); + } + + template + template + void Vctr::cpy_pos_to_cpu_ptr(U *p, size_type icol) + { + memcpy_pos_gpu_cpu(p, m_data, size(), icol); + } + + /***************************************************************************************/ + template + void Vctr::resize(const dt_shape_st& shape) + { + this->allocate(shape); + } + + template + void Vctr::resize(const dt_shape_st& shape, const T& value) + { + auto m_size_t = m_size; + this->allocate(shape); + thrust::fill(this->begin()+m_size_t, this->end(), value); + } + + template + void Vctr::reserve(const dt_shape_st& shape) + { + this->allocate(shape, true); + } + + template + void Vctr::shrink_to_fit() + { + if (m_size < m_capacity) + { + if (m_size > 0) + { + /* allocate memory and transfer data */ + T* data_tmp = nullptr; + fcn_cuda_malloc(data_tmp, m_size); + memcpy_gpu_gpu(data_tmp, m_data, m_size); + fcn_cuda_free(m_data); + + m_data = data_tmp; + data_tmp = nullptr; + } + else + { + fcn_cuda_free(m_data); + } + + m_capacity = m_size; + + if (shape().dim()==2) + { + if (m_s1==1) + m_s0 = m_size; + + if (m_s0==1) + m_s1 = m_size; + } + } + } + + template + template + void Vctr::push_back(const U& val) + { + if (m_size >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_type(1), 2*m_size); + else + shape[1] *= size_type(2); + } + else + { + shape[2] *= size_type(2); + } + } + else + { + shape[3] *= size_type(2); + } + + this->allocate(shape, true); + } + + memcpy_cpu_gpu(m_data + m_size, &val, 1); + + m_size++; + } + + template + template + void Vctr::push_back(const Vctr& vctr) + { + const size_type size_new = m_size + vctr.size(); + + if (size_new >= m_capacity) + { + dt_shape_st shape{m_s0, m_s1, m_s2, m_s3}; + + if (m_s3 == 1) + { + if (m_s2 == 1) + { + if (m_s1 == 1) + shape[0] = max(size_new, 2*shape[0]); + else + shape[1] = max(size_new/shape[0], 2*shape[1]); + } + else + { + shape[2] = max(size_new/(shape[0]*shape[1]), 2*shape[2]); + } + } + else + { + shape[3] = max(size_new/(shape[0]*shape[1]*shape[2]), 2*shape[3]); + } + + this->allocate(shape, true); + } + + memcpy_cpu_gpu(m_data + m_size, vctr.data(), vctr.size()); + + m_size = size_new; + } + + template + void Vctr::pop_back() + { + if (m_size >= 1) + { + m_size--; + } + } + + template + void Vctr::fill(T val) + { + thrust::fill(this->begin(), this->end(), val); + } + + /***************************************************************************************/ + template + typename Vctr::size_type Vctr::s0() const + { + return m_s0; + } + + template + typename Vctr::size_type Vctr::s1() const + { + return m_s1; + } + + template + typename Vctr::size_type Vctr::s2() const + { + return m_s2; + } + + template + typename Vctr::size_type Vctr::s3() const + { + return m_s2; + } + + template + dt_int32 Vctr::s0_32() const + { + return static_cast(m_s0); + } + + template + dt_int32 Vctr::s1_32() const + { + return static_cast(m_s1); + } + + template + dt_int32 Vctr::s2_32() const + { + return static_cast(m_s2); + } + + template + dt_int32 Vctr::s3_32() const + { + return static_cast(m_s3); + } + + template + dt_int64 Vctr::s0_64() const + { + return static_cast(m_s0); + } + + template + dt_int64 Vctr::s1_64() const + { + return static_cast(m_s1); + } + + template + dt_int64 Vctr::s2_64() const + { + return static_cast(m_s2); + } + + template + dt_int64 Vctr::s3_64() const + { + return static_cast(m_s3); + } + + template + typename Vctr::size_type Vctr::s0h() const + { + return m_s0/size_type(2); + } + + template + typename Vctr::size_type Vctr::s1h() const + { + return m_s1/size_type(2); + } + + template + typename Vctr::size_type Vctr::s2h() const + { + return m_s2/size_type(2); + } + + template + typename Vctr::size_type Vctr::s3h() const + { + return m_s3/size_type(2); + } + + template + dt_shape_st::size_type> Vctr::shape() const + { + return {m_s0, m_s1, m_s2, m_s3}; + } + + template + dt_shape_st::size_type> Vctr::shape_2d_trs() const + { + return {m_s1, m_s0, m_s2, m_s3}; + } + + template + typename Vctr::size_type Vctr::shape_size() const + { + return m_s0*max(m_s1, size_type(1))*max(m_s2, size_type(1))*max(m_s3, size_type(1)); + } + + template + typename Vctr::size_type Vctr::pitch_s1() const + { + return m_pitch_s1; + } + + template + typename Vctr::size_type Vctr::pitch_s2() const + { + return m_pitch_s2; + } + + template + typename Vctr::size_type Vctr::pitch_s3() const + { + return m_pitch_s3; + } + + template + typename Vctr::size_type Vctr::size() const + { + return m_size; + } + + template + dt_int32 Vctr::size_32() const + { + return static_cast(m_size); + } + + template + dt_int64 Vctr::size_64() const + { + return static_cast(m_size); + } + + template + iGrid_1d Vctr::igrid_1d() const + { + return {size_32()}; + } + + template + iGrid_2d Vctr::igrid_2d() const + { + return {s1_32(), s0_32()}; + } + + template + iGrid_3d Vctr::igrid_3d() const + { + return {s1_32(), s0_32(), s2_32()}; + } + + template + iGrid_1d_64 Vctr::igrid_1d_64() const + { + return {size_64()}; + } + + template + iGrid_2d_64 Vctr::igrid_2d_64() const + { + return {s1_64(), s0_64()}; + } + + template + iGrid_3d_64 Vctr::igrid_3d_64() const + { + return {s1_64(), s0_64(), s2_64()}; + } + + template + typename Vctr::size_type Vctr::capacity() const + { + return m_capacity; + } + + template + dt_bool Vctr::empty() const + { + return m_size == 0; + } + + template + dt_bool Vctr::is_1d() const + { + return (m_s0 == 1) || (m_s1 == 1); + } + + template + void Vctr::clear() + { + m_size = 0; + } + + template + void Vctr::clear_shrink_to_fit() + { + destroy(); + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0) const + { + return ix_0; + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0, const size_type& ix_1) const + { + return ix_0 + m_s0*ix_1; + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + { + return ix_0 + m_s0*(ix_1 + m_s1*ix_2); + } + + template + typename Vctr::size_type Vctr::sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + { + return ix_0 + m_s0*(ix_1 + m_s1*(ix_2 + m_s2*ix_3)); + } + + //template + // T& Vctr::operator[](const size_type& iy) + // { + // return m_data[iy]; + // } + + //template + // const T& Vctr::operator[](const size_type& iy) const + // { + // return m_data[iy]; + // } + + //template + // T& Vctr::operator()(const size_type& iy) + // { + // return m_data[iy]; + // } + + //template + // const T& Vctr::operator()(const size_type& iy) const + // { + // return m_data[iy]; + // } + + //template + // T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1) + // { + // return m_data[sub_2_ind(ix_0, ix_1)]; + // } + + //template + // const T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1) const + // { + // return m_data[sub_2_ind(ix_0, ix_1)]; + // } + + //template + // T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + // } + + //template + // const T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2)]; + // } + + // T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + // } + + //template + // const T& Vctr::operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const + // { + // return m_data[sub_2_ind(ix_0, ix_1, ix_2, ix_3)]; + // } + + template + thrust::device_ptr Vctr::begin() noexcept + { + return thrust::device_ptr(m_data); + } + + template + const thrust::device_ptr Vctr::begin() const + { + return thrust::device_ptr(m_data); + } + + template + thrust::device_ptr Vctr::end() noexcept + { + return thrust::device_ptr(m_data) + m_size; + } + + template + const thrust::device_ptr Vctr::end() const + { + return thrust::device_ptr(m_data) + m_size; + } + + template + T* Vctr::data() + { + return m_data; + } + + template + const T* Vctr::data() const + { + return m_data; + } + + template + template + U Vctr::data_cast() + { + return reinterpret_cast(m_data); + } + + template + template + const U Vctr::data_cast() const + { + return reinterpret_cast(m_data); + } + + //template + // T& Vctr::front() + // { + // return m_data[0]; + // } + + //template + // const T& Vctr::front() const + // { + // return m_data[0]; + // } + + //template + // T& Vctr::back(){ + // return m_data[m_size-1]; + // } + + //template + // const T& Vctr::back() const + // { + // return m_data[m_size-1]; + // } + + // set shape + template + void Vctr::set_shape(const dt_shape_st& shape) + { + m_s0 = max(shape[0], size_type(0)); + m_s1 = max(shape[1], size_type(1)); + m_s2 = max(shape[2], size_type(1)); + m_s3 = max(shape[3], size_type(1)); + + set_picth(); + } + + template + void Vctr::trs_shape_2d() + { + set_shape({m_s1, m_s0, m_s2, m_s3}); + } + + template + template + void Vctr::set_shape(const Vctr& vctr, dt_bool bb_size) + { + this->set_shape(vctr.shape(), bb_size); + } + + FCNS_IMP_GPU_GRID_BLK_VCTR(template , Vctr); + + template + void Vctr::set_picth() + { + m_pitch_s1 = m_s0*sizeof(T); + m_pitch_s2 = m_pitch_s1*m_s1; + m_pitch_s3 = m_pitch_s2*m_s2; + } + + template + void Vctr::set_capacity(size_type size_r) + { + m_capacity = max(m_capacity, size_r); + } + + template + void Vctr::set_shape_cstr(dt_shape_st& shape) + { + shape[0] = max(shape[0], size_type(0)); + shape[1] = max(shape[1], size_type(1)); + shape[2] = max(shape[2], size_type(1)); + shape[3] = max(shape[3], size_type(1)); + } + + // reallocate and copy memory + template + void Vctr::allocate(dt_shape_st shape, dt_bool bb_reserve) + { + set_shape_cstr(shape); + + auto size_r = shape[0]*shape[1]*shape[2]*shape[3]; + + if (size_r == 0) + { + return; + } + + if (m_size == 0) + { + fcn_cuda_free(m_data); + + fcn_cuda_malloc(m_data, size_r); + } + else if (size_r>m_capacity) + { + // allocate memory and transfer data + T* data_tmp = nullptr; + fcn_cuda_malloc(data_tmp, size_r); + memcpy_gpu_gpu(data_tmp, m_data, m_size); + fcn_cuda_free(m_data); + + m_data = data_tmp; + data_tmp = nullptr; + } + + this->set_shape(shape); + if (!bb_reserve) + { + m_size = size_r; + } + this->set_capacity(size_r); + } + + // initialization + template + void Vctr::init() + { + m_data = nullptr; + m_s0 = 0; m_s1 = m_s2 = m_s3 = 1; + m_pitch_s1 = m_pitch_s2 = m_pitch_s3 = 0; + m_size = 0; + m_capacity = 0; + } + + // destroy memory on the device + template + void Vctr::destroy() + { + if (m_data != nullptr) + { + fcn_cuda_free(m_data); + } + + init(); + } +#endif +} + +/* derived class */ +namespace mt +{ +#ifdef __CUDACC__ + template + struct is_vctr_gpu_r_2d: std::integral_constant::value && is_r_2d::value> {}; + + template + struct is_vctr_gpu_r_2d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_gpu_r_2d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu_r_2d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + struct is_vctr_gpu_r_3d: std::integral_constant::value && is_r_3d::value> {}; + + template + struct is_vctr_gpu_r_3d_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_gpu_r_3d = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu_r_3d_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + struct is_vctr_gpu_r_nd: std::integral_constant::value && is_r_nd::value> {}; + + template + struct is_vctr_gpu_r_nd_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + using enable_if_vctr_gpu_r_nd = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu_r_nd_and_vctr_cpu = typename std::enable_if::value, V>::type; +} \ No newline at end of file diff --git a/src/detail/wd_butwth.inl b/src/detail/wd_butwth.inl new file mode 100755 index 00000000..9f004992 --- /dev/null +++ b/src/detail/wd_butwth.inl @@ -0,0 +1,57 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "wd_butwth.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(): Wdb_fcn_xd() {} + + template + Wd_fcn_xd::Wd_fcn_xd(const R_xd& r, const dt_int32& n, const T& r_wd, const T& r_max) + { + set_in_data(r, n, r_wd, r_max); + } + + /* copy constructor */ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Wd_fcn_xd& Wd_fcn_xd::operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + template + void Wd_fcn_xd::set_in_data(const R_xd& r, const dt_int32& n, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), n, r_wd); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } +} \ No newline at end of file diff --git a/src/detail/wd_exp.inl b/src/detail/wd_exp.inl new file mode 100755 index 00000000..809184d3 --- /dev/null +++ b/src/detail/wd_exp.inl @@ -0,0 +1,57 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "wd_exp.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(): Wdb_fcn_xd() {} + + template + Wd_fcn_xd::Wd_fcn_xd(const R_xd& r, const T& beta, const T& r_wd, const T& r_max) + { + set_in_data(r, beta, r_wd, r_max); + } + + /* copy constructor */ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Wd_fcn_xd& Wd_fcn_xd::operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + template + void Wd_fcn_xd::set_in_data(const R_xd& r, const T& beta, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), beta); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } +} \ No newline at end of file diff --git a/src/detail/wd_fcn.inl b/src/detail/wd_fcn.inl new file mode 100755 index 00000000..6f0e73ec --- /dev/null +++ b/src/detail/wd_fcn.inl @@ -0,0 +1,107 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "wd_fcn.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Wdb_fcn_xd::Wdb_fcn_xd(): Fcn_Elem(), r(), r_wd_2(0), r_max_2(0), sft(0), sc(1) {} + + /* copy constructor */ + template + CGPU_EXEC + Wdb_fcn_xd::Wdb_fcn_xd(const Wdb_fcn_xd& wd) + { + *this = wd; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Wdb_fcn_xd& Wdb_fcn_xd::operator=(const Wdb_fcn_xd& wd) + { + if (this != &wd) + { + Fcn_Elem::operator=(wd); + + r = wd.r; + r_wd_2 = wd.r_wd_2; + r_max_2 = wd.r_max_2; + sft = wd.sft; + sc = wd.sc; + } + + return *this; + } + + template + CGPU_EXEC + void Wdb_fcn_xd::assign(const Wdb_fcn_xd& wd) + { + *this = wd; + } + + /***************************************************************************************/ + template + CGPU_EXEC + void Wdb_fcn_xd::clear() + { + Fcn_Elem::clear(); + + r = T(0); + r_wd_2 = T(0); + r_max_2 = T(0); + sft = T(0); + sc = T(1); + } + + template + CGPU_EXEC + T Wdb_fcn_xd::eval_r2(const T& r2) const + { + return (r2::eval_r2(r2) - sft)/sc):T(0); + } + + template + CGPU_EXEC + T Wdb_fcn_xd::eval_r2(const R_2d& r2) const + { + return eval_r2(r2.x)*eval_r2(r2.y); + } + + template + CGPU_EXEC + T Wdb_fcn_xd::eval_r2(const R_3d& r2) const + { + return eval_r2(r2.x)*eval_r2(r2.y)*eval_r2(r2.z); + } + + template + void Wdb_fcn_xd::set_in_data(const R_xd& r, const T& r_wd, const T& r_max) + { + this->r = r; + r_wd_2 = ::square(r_wd); + r_max_2 = ::square(r_max); + sft = Fcn_Elem::eval_r2(r_max_2); + sc = Fcn_Elem::eval_r2(r_wd_2) - sft; + } +} \ No newline at end of file diff --git a/src/detail/wd_fermi.inl b/src/detail/wd_fermi.inl new file mode 100755 index 00000000..d495da00 --- /dev/null +++ b/src/detail/wd_fermi.inl @@ -0,0 +1,57 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "wd_fermi.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(): Wdb_fcn_xd() {} + + template + Wd_fcn_xd::Wd_fcn_xd(const R_xd& r, const T& alpha, const T& r_wd, const T& r_max) + { + set_in_data(r, alpha, r_wd, r_max); + } + + /* copy constructor */ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Wd_fcn_xd& Wd_fcn_xd::operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + template + void Wd_fcn_xd::set_in_data(const R_xd& r, const T& alpha, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), alpha, r_wd); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } +} \ No newline at end of file diff --git a/src/detail/wd_gauss.inl b/src/detail/wd_gauss.inl new file mode 100755 index 00000000..5f7fb0c2 --- /dev/null +++ b/src/detail/wd_gauss.inl @@ -0,0 +1,57 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "wd_gauss.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(): Wdb_fcn_xd() {} + + template + Wd_fcn_xd::Wd_fcn_xd(const R_xd& r, const T& sigma, const T& r_wd, const T& r_max) + { + set_in_data(r, sigma, r_wd, r_max); + } + + /* copy constructor */ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Wd_fcn_xd& Wd_fcn_xd::operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + template + void Wd_fcn_xd::set_in_data(const R_xd& r, const T& sigma, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), sigma); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } +} \ No newline at end of file diff --git a/src/detail/wd_hann.inl b/src/detail/wd_hann.inl new file mode 100755 index 00000000..8a749942 --- /dev/null +++ b/src/detail/wd_hann.inl @@ -0,0 +1,57 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#include "wd_hann.h" + +namespace mt +{ + /************************************* constructors ************************************/ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(): Wdb_fcn_xd() {} + + template + Wd_fcn_xd::Wd_fcn_xd(const R_xd& r, const T& l, const T& r_wd, const T& r_max) + { + set_in_data(r, l, r_wd, r_max); + } + + /* copy constructor */ + template + CGPU_EXEC + Wd_fcn_xd::Wd_fcn_xd(const Wd_fcn_xd& wd): Wdb_fcn_xd(wd){} + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + template + CGPU_EXEC + Wd_fcn_xd& Wd_fcn_xd::operator=(const Wdb_fcn_xd& wd) + { + Wdb_fcn_xd::operator=(wd); + + return *this; + } + + /***************************************************************************************/ + template + void Wd_fcn_xd::set_in_data(const R_xd& r, const T& l, const T& r_wd, const T& r_max) + { + Fcn_Elem::set_in_data(T(1), l); + Wdb_fcn_xd::set_in_data(r, r_wd, r_max); + } +} \ No newline at end of file diff --git a/src/device_functions.cuh b/src/device_functions.cuh new file mode 100755 index 00000000..d9479a69 --- /dev/null +++ b/src/device_functions.cuh @@ -0,0 +1,2142 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef DEVICE_FUNCTIONS_H +#define DEVICE_FUNCTIONS_H + +#include +#include +#include + +#include "math.cuh" +#include "types.cuh" +#include "traits.cuh" +#include "stream.cuh" +#include "fft.cuh" +#include "blas.cuh" + +#include +#include +#include +#include + +#include "host_device_functions.cuh" +#include "host_functions.hpp" + +#define reduce_array_256(tid, sum, Mshare) \ + { \ + Mshare[tid] = sum; \ + __syncthreads(); \ + if(tid < 128) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 128]; \ + } \ + __syncthreads(); \ + if(tid < 64) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 64]; \ + } \ + __syncthreads(); \ + if(tid < 32) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 32]; \ + } \ + __syncthreads(); \ + if(tid < 16) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 16]; \ + } \ + __syncthreads(); \ + if(tid < 8) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 8]; \ + } \ + __syncthreads(); \ + if(tid < 4) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 4]; \ + } \ + __syncthreads(); \ + if(tid < 2) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 2]; \ + } \ + __syncthreads(); \ + if(tid < 1) \ + { \ + Mshare[tid] = sum = sum + Mshare[tid + 1]; \ + } \ + __syncthreads(); \ + } + +#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600 +#else + __device__ __forceinline__ + double atomicAdd(double *address, double val) + { + unsigned long long int* address_as_ull = (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + + do + { + assumed = old; + old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val +__longlong_as_double(assumed))); + } while (assumed != old); + + return __longlong_as_double(old); + } +#endif + +namespace mt +{ + namespace device_detail + { + // modify + template + __global__ void atom_cost_function(Grid_2d grid_2d, Atom_Sa atom_Ip, rVector M_i, rVector Mp_o) + { + __shared__ T Mshare[c_thrnxny*c_thrnxny]; + + int tid = threadIdx.x + threadIdx.y*blockDim.x; + + T sum = 0; + + int ix_0 = threadIdx.y + blockIdx.y*blockDim.y; + while (ix_0 < atom_Ip.ixn) + { + int iy_0 = threadIdx.x + blockIdx.x*blockDim.x; + while (iy_0 < atom_Ip.iyn) + { + int ix = ix_0 + atom_Ip.ix_0; + int iy = iy_0 + atom_Ip.iy_0; + + T R2 = grid_2d.R2(ix, iy, atom_Ip.x, atom_Ip.y); + if (R2 < atom_Ip.R2_max) + { + int ixy = grid_2d.ind_col(ix, iy); + T M = M_i[ixy]; + const T V = host_device_detail::eval_cubic_poly(R2, atom_Ip); + sum += (V-2*M)*V; + } + iy_0 += blockDim.x*gridDim.x; + } + ix_0 += blockDim.y*gridDim.y; + } + reduce_array_256(tid, sum, Mshare); + + if(tid == 0) + { + Mp_o[tid] = sum; + } + } + + template + __global__ void subtract_atom(Grid_2d grid_2d, Atom_Sa atom_Ip, rVector M_i) + { + int ix_0 = threadIdx.y + blockIdx.y*blockDim.y; + while (ix_0 < atom_Ip.ixn) + { + int iy_0 = threadIdx.x + blockIdx.x*blockDim.x; + while (iy_0 < atom_Ip.iyn) + { + int ix = ix_0 + atom_Ip.ix_0; + int iy = iy_0 + atom_Ip.iy_0; + + T R2 = grid_2d.R2(ix, iy, atom_Ip.x, atom_Ip.y); + if (R2 < atom_Ip.R2_max) + { + int ixy = grid_2d.ind_col(ix, iy); + const T V = host_device_detail::eval_cubic_poly(R2, atom_Ip); + + atomicAdd(&(M_i.V[ixy]), V); + // atomicAdd(&(M_i.V[ixy]), V); + } + iy_0 += blockDim.x*gridDim.x; + } + ix_0 += blockDim.y*gridDim.y; + } + } + + // Linear projected potential: V and zV + template + __global__ void linear_Vz(rQ1> qz, TAtom atom) + { + using T = Value_type; + + __shared__ T V0s[c_nqz]; + __shared__ T dV0s[c_nqz]; + + int ix = threadIdx.x, iR = blockIdx.x; + + T x = qz.x[ix]; + T w = qz.w[ix]; + T R2 = atom.R2[iR]; + T V, dVir; + + T a = (atom.split)?(-atom.z0h):(atom.zeh-atom.z0h); + T b = (atom.split)?(atom.z0h):(atom.zeh+atom.z0h); + T z = a*x + b; + T r = sqrt(z*z + R2); + Vr_dVrir(r, atom.cl, atom.cnl, a*w, V, dVir); + + V0s[ix] = V; + dV0s[ix] = dVir; + + if (atom.split) + { + a = atom.zeh; + b = atom.zeh; + z = a*x + b; + r = sqrt(z*z + R2); + Vr_dVrir(r, atom.cl, atom.cnl, a*w, V, dVir); + + V = V0s[ix] += V; + dVir = dV0s[ix] += dVir; + } + + __syncthreads(); + + if(ix < 64) + { + V0s[ix] = V = V + V0s[ix + 64]; + dV0s[ix] = dVir = dVir + dV0s[ix + 64]; + } + __syncthreads(); + + if(ix < 32) + { + V0s[ix] = V = V + V0s[ix + 32]; + dV0s[ix] = dVir = dVir + dV0s[ix + 32]; + } + __syncthreads(); + + if(ix < 16) + { + V0s[ix] = V = V + V0s[ix + 16]; + dV0s[ix] = dVir = dVir + dV0s[ix + 16]; + } + __syncthreads(); + + if(ix < 8) + { + V0s[ix] = V = V + V0s[ix + 8]; + dV0s[ix] = dVir = dVir + dV0s[ix + 8]; + } + __syncthreads(); + + if(ix < 4) + { + V0s[ix] = V = V + V0s[ix + 4]; + dV0s[ix] = dVir = dVir + dV0s[ix + 4]; + } + __syncthreads(); + + if(ix < 2) + { + V0s[ix] = V = V + V0s[ix + 2]; + dV0s[ix] = dVir = dVir + dV0s[ix + 2]; + } + __syncthreads(); + + if(ix < 1) + { + V0s[ix] = V = V + V0s[ix + 1]; + dV0s[ix] = dVir = dVir + dV0s[ix + 1]; + } + __syncthreads(); + + if(ix == 0 ) + { + dVir = 0.5*dVir; + + auto R2_tap = atom.R2_tap; + auto tap_cf = atom.tap_cf; + host_device_detail::apply_tapering(R2_tap, tap_cf, R2, V, dVir); + atom.c0[iR] = V; // V_0 + atom.c1[iR] = dVir; // dR2V0 + } + } + + // Get Local interpolation coefficients + template + __global__ void cubic_poly_coef(TAtom atom) + { + int iR = threadIdx.x; + + if (iR < c_nR-1) + { + host_device_detail::cubic_poly_coef(iR, atom); + } + } + + // Cubic polynomial evaluation + template + __global__ void eval_cubic_poly(Grid_2d grid_2d, rVector> atoms, rVector M_o) + { + auto atom = atoms.V[blockIdx.x]; + + int ix_t = threadIdx.y; + while (ix_t < atom.nx) + { + int ix = atom.ix_0+ix_t; + + int iy_t = threadIdx.x; + while (iy_t < atom.ny) + { + int iy = atom.iy_0+iy_t; + const auto R2 = grid_2d.R2(ix, iy, atom.x, atom.y); + + if (R2 < atom.R2_max) + { + const T V = atom.occ*host_device_detail::eval_cubic_poly(R2, atom); + const int ixy = grid_2d.ind_col_pbc_shift(ix, iy); + + atomicAdd(&(M_o.V[ixy]), V); + } + + iy_t += blockDim.x; + } + ix_t += blockDim.y; + } + } + + // Gaussian evaluation + template + __global__ void gauss_eval(Grid_2d grid_2d, rVector> atoms, rVector M_o) + { + const auto gauss = atoms.V[blockIdx.x]; + + int ix_t = threadIdx.y; + while (ix_t < gauss.nx) + { + int ix = gauss.ix_0+ix_t; + + int iy_t = threadIdx.x; + while (iy_t < gauss.ny) + { + int iy = gauss.iy_0+iy_t; + auto R2 = grid_2d.R2(ix, iy, gauss.x, gauss.y); + + if (R2 < gauss.R2_max) + { + int ixy = grid_2d.ind_col_pbc(ix, iy); + atomicAdd(&(M_o.V[ixy]), gauss(R2)); + } + + iy_t += blockDim.x; + } + ix_t += blockDim.y; + } + } + + // Shift matrix respect to nxh + template + __global__ void fft1_shift(TGrid grid_1d, rVector M_io) + { + int ix = threadIdx.x + blockIdx.x*blockDim.x; + + if(ix < grid_1d.nxh) + { + host_device_detail::fft1_shift(ix, grid_1d, M_io); + } + } + + // Shift matrix respect to nyh + template + __global__ void fft2_sft_bc(TGrid grid_2d, rVector M_io) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.nyh)) + { + host_device_detail::fft2_sft_bc(ix, iy, grid_2d, M_io); + } + } + + // Shift matrix respect to (nxh, nyh) + template + __global__ void fft2_shift(TGrid grid_2d, rVector M_io) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::fft2_shift(ix, iy, grid_2d, M_io); + } + } + + /***************************************************************************/ + // Shift matrix respect to (nxh, nyh) + template + __global__ void assign_shift_2d(TGrid grid_2d, rVector M_i, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::fft2_shift(ix, iy, grid_2d, M_i, M_o); + } + } + + // add, scale, crop and shift + template + __global__ void add_scale_shift_2d(TGrid grid_2d, T w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + // add, scale, square, crop and shift + template + __global__ void add_scale_square_shift_2d(TGrid grid_2d, T2 w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_square_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + // Assign and crop + template + __global__ void assign_crop(TGrid grid_2d, rVector M_i, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::assign_crop(ix, iy, grid_2d, M_i, M_o); + } + } + + // crop and shift + template + __global__ void assign_crop_shift_2d(TGrid grid_2d, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::assign_crop_shift_2d(ix, iy, grid_2d, M_i, range, M_o); + } + } + + // add, scale, crop and shift + template + __global__ void add_scale_crop_shift_2d(TGrid grid_2d, T w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_crop_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + // add, scale, square, crop and shift + template + __global__ void add_scale_square_crop_shift_2d(TGrid grid_2d, T2 w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_square_crop_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + /***************************************************************************/ + // sum over the detector + template + __global__ void sum_over_Det(TGrid grid_2d, Value_type g2_min, Value_type g2_max, rVector M_i, rVector Mp_o) + { + __shared__ T Mshare[c_thrnxny*c_thrnxny]; + + int tid = threadIdx.x + threadIdx.y*blockDim.x; + int bid = blockIdx.x + blockIdx.y*gridDim.x; + + int iy_0 = threadIdx.x + blockIdx.x*blockDim.x; + int ix_0 = threadIdx.y + blockIdx.y*blockDim.y; + + T sum = 0; + + int ix = ix_0; + while (ix < grid_2d.nx) + { + int iy = iy_0; + while (iy < grid_2d.ny) + { + host_device_detail::sum_over_Det(ix, iy, grid_2d, g2_min, g2_max, M_i, sum); + iy += blockDim.x*gridDim.x; + } + ix += blockDim.y*gridDim.y; + } + reduce_array_256(tid, sum, Mshare); + + if(tid == 0) + { + Mp_o[bid] = sum; + } + } + + // sum over the detector + template + __global__ void sum_square_over_Det(TGrid grid_2d, Value_type g2_min, Value_type g2_max, rVector M_i, rVector> Mp_o) + { + using T_r = Value_type; + + __shared__ T_r Mshare[c_thrnxny*c_thrnxny]; + + int tid = threadIdx.x + threadIdx.y*blockDim.x; + int bid = blockIdx.x + blockIdx.y*gridDim.x; + + int iy_0 = threadIdx.x + blockIdx.x*blockDim.x; + int ix_0 = threadIdx.y + blockIdx.y*blockDim.y; + + T_r sum = 0; + + int ix = ix_0; + while (ix < grid_2d.nx) + { + int iy = iy_0; + while (iy < grid_2d.ny) + { + host_device_detail::sum_square_over_Det(ix, iy, grid_2d, g2_min, g2_max, M_i, sum); + iy += blockDim.x*gridDim.x; + } + ix += blockDim.y*gridDim.y; + } + + reduce_array_256(tid, sum, Mshare); + + if(tid == 0) + { + Mp_o[bid] = sum; + } + } + + // sum over the detector + template + __global__ void sum_square_over_Det(TGrid grid_2d, rVector> S_i, rVector M_i, rVector> Mp_o) + { + using T_r = Value_type; + + __shared__ T_r Mshare[c_thrnxny*c_thrnxny]; + + int tid = threadIdx.x + threadIdx.y*blockDim.x; + int bid = blockIdx.x + blockIdx.y*gridDim.x; + + int iy_0 = threadIdx.x + blockIdx.x*blockDim.x; + int ix_0 = threadIdx.y + blockIdx.y*blockDim.y; + + T_r sum = 0; + + int ix = ix_0; + while (ix < grid_2d.nx) + { + int iy = iy_0; + while (iy < grid_2d.ny) + { + host_device_detail::sum_square_over_Det(ix, iy, grid_2d, S_i, M_i, sum); + iy += blockDim.x*gridDim.x; + } + ix += blockDim.y*gridDim.y; + } + + reduce_array_256(tid, sum, Mshare); + + if(tid == 0) + { + Mp_o[bid] = sum; + } + } + + // Anti-Aliasing, scale with cut-off (2/3)g_max + template + __global__ void bandwidth_limit(TGrid grid_2d, rVector M_io) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::bandwidth_limit(ix, iy, grid_2d, M_io); + } + } + + template + __global__ void hard_aperture(TGrid grid_2d, Value_type g2_max, Value_type w, rVector M_io) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::hard_aperture(ix, iy, grid_2d, g2_max, w, M_io); + } + } + + // Propagate + template + __global__ void propagate(TGrid grid_2d, Value_type w, + Value_type gxu, Value_type gyu, rVector psi_i, rVector psi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::propagate(ix, iy, grid_2d, w, gxu, gyu, psi_i, psi_o); + } + } + + /***********************************************************************/ + // phase factor 1d + template + __global__ void exp_r_factor_1d(TGrid grid_1d, Value_type gx, rVector psi_i, rVector psi_o) + { + int ix = threadIdx.x + blockIdx.x*blockDim.x; + + if(ix < grid_1d.nx) + { + host_device_detail::exp_r_factor_1d(ix, grid_1d, gx, psi_i, psi_o); + } + } + + // phase factor 2d by col + template + __global__ void exp_r_factor_2d_bc(TGrid grid_2d, Value_type alpha, + rVector> gy, rVector psi_i, rVector psi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::exp_r_factor_2d_bc(ix, iy, grid_2d, alpha, gy, psi_i, psi_o); + } + } + + // phase factor 2d + template + __global__ void exp_r_factor_2d(TGrid grid_2d, Value_type gx, + Value_type gy, rVector psi_i, rVector psi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::exp_r_factor_2d(ix, iy, grid_2d, gx, gy, psi_i, psi_o); + } + } + + // phase factor 2d + template + __global__ void mul_exp_r_factor_2d(TGrid grid_2d, rVector> gx, + rVector> gy, rVector psi_i, rVector psi_o) + { + using Tr = Value_type; + + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::mul_exp_r_factor_2d(ix, iy, grid_2d, gx, gy, psi_i, psi_o); + } + } + + /***********************************************************************/ + // phase factor 1d + template + __global__ void exp_g_factor_1d(TGrid grid_1d, Value_type Rx, rVector psi_i, rVector psi_o) + { + int ix = threadIdx.x + blockIdx.x*blockDim.x; + + if(ix < grid_1d.nx) + { + host_device_detail::exp_g_factor_1d(ix, grid_1d, Rx, psi_i, psi_o); + } + } + + // phase factor 2d by col + template + __global__ void exp_g_factor_2d_bc(TGrid grid_2d, Value_type alpha, + rVector> Ry, rVector psi_i, rVector psi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::exp_g_factor_2d_bc(ix, iy, grid_2d, alpha, Ry, psi_i, psi_o); + } + } + + // phase factor 2d + template + __global__ void exp_g_factor_2d(TGrid grid_2d, Value_type Rx, + Value_type Ry, rVector psi_i, rVector psi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::exp_g_factor_2d(ix, iy, grid_2d, Rx, Ry, psi_i, psi_o); + } + } + + // phase factor 2d + template + __global__ void mul_exp_g_factor_2d(TGrid grid_2d, rVector> Rx, + rVector> Ry, rVector psi_i, rVector psi_o) + { + using Tr = Value_type; + + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::mul_exp_g_factor_2d(ix, iy, grid_2d, Rx, Ry, psi_i, psi_o); + } + } + + /***********************************************************************/ + // Convergent incident wave in Fourier space + template + __global__ void probe(TGrid grid_2d, Lens> lens, + Value_type x, Value_type y, Value_type gxu, Value_type gyu, rVector fPsi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::probe(ix, iy, grid_2d, lens, x, y, gxu, gyu, fPsi_o); + } + } + + // Apply Coherent transfer function + template + __global__ void apply_CTF(TGrid grid_2d, Lens> lens, + Value_type gxu, Value_type gyu, rVector fPsi_i, rVector fPsi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::apply_CTF(ix, iy, grid_2d, lens, gxu, gyu, fPsi_i, fPsi_o); + } + } + + // Partially coherent transfer function, linear image model and weak phase_components object + template + __global__ void apply_PCTF(TGrid grid_2d, Lens> lens, rVector fPsi_i, rVector fPsi_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::apply_PCTF(ix, iy, grid_2d, lens, fPsi_i, fPsi_o); + } + } + + // sum over the detector + template + __global__ void norm_factor_lorentz(Grid_2d grid_2d, T gc2, T ge2, rVector Mp_o) + { + __shared__ T Mshare[c_thrnxny*c_thrnxny]; + + int tid = threadIdx.x + threadIdx.y*blockDim.x; + int bid = blockIdx.x + blockIdx.y*gridDim.x; + + int iy_0 = threadIdx.x + blockIdx.x*blockDim.x; + int ix_0 = threadIdx.y + blockIdx.y*blockDim.y; + + T sum = 0; + + int ix = ix_0; + while (ix < grid_2d.nx) + { + int iy = iy_0; + while (iy < grid_2d.ny) + { + host_device_detail::Lorentz_factor(ix, iy, grid_2d, gc2, ge2, sum); + iy += blockDim.x*gridDim.x; + } + ix += blockDim.y*gridDim.y; + } + + reduce_array_256(tid, sum, Mshare); + + if(tid == 0) + { + Mp_o[bid] = sum; + } + } + + template + Value_type Lorentz_factor(Stream &stream, TGrid &grid_2d, EELS> &eels) + { + device_vector> sum_v(c_thrnxny*c_thrnxny); + + auto grid_bt = grid_2d.cuda_grid(dim3(c_thrnxny, c_thrnxny)); + + norm_factor_lorentz><<>>(grid_2d, eels.gc2, eels.ge2, sum_v); + + return sqrt(eels.occ)/thrust::reduce(sum_v.begin(), sum_v.end()); + } + + template + __global__ void kernel_xyz(TGrid grid_2d, EELS> eels, + rVector k_x, rVector k_y, rVector k_z) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::kernel_xyz(ix, iy, grid_2d, eels, k_x, k_y, k_z); + } + } + + template + __global__ void kernel_x(TGrid grid_2d, EELS> eels, rVector k_x) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::kernel_x(ix, iy, grid_2d, eels, k_x); + } + } + + template + __global__ void kernel_y(TGrid grid_2d, EELS> eels, rVector k_y) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::kernel_y(ix, iy, grid_2d, eels, k_y); + } + } + + template + __global__ void kernel_z(TGrid grid_2d, EELS> eels, rVector k_z) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::kernel_z(ix, iy, grid_2d, eels, k_z); + } + } + + template + __global__ void kernel_mn1(TGrid grid_2d, EELS> eels, rVector k_mn1) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::kernel_mn1(ix, iy, grid_2d, eels, k_mn1); + } + } + + template + __global__ void kernel_mp1(TGrid grid_2d, EELS> eels, rVector k_mp1) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::kernel_mp1(ix, iy, grid_2d, eels, k_mp1); + } + } + + // trs + template + __global__ void trs(int ncols, int nrows, rVector M_i, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < ncols)&&(iy < nrows)) + { + host_device_detail::trs(ix, iy, ncols, nrows, M_i, M_o); + } + } + + // vector column x matrix + template + __global__ void vector_col_x_matrix(TGrid grid_2d, rVector> fg, + rVector M_io) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::vector_col_x_matrix(ix, iy, grid_2d, fg, M_io); + } + } + + // Gaussian convolution + template + __global__ void gauss_cv_1d(TGrid grid_1d, Value_type alpha, + rVector M_io) + { + int ix = threadIdx.x + blockIdx.x*blockDim.x; + + if(ix < grid_1d.nx) + { + host_device_detail::gauss_cv_1d(ix, grid_1d, alpha, M_io); + } + } + + // Gaussian convolution + template + __global__ void gauss_cv_2d(TGrid grid_2d, + Value_type alpha, rVector M_io) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::gauss_cv_2d(ix, iy, grid_2d, alpha, M_io); + } + } + + // Gaussian convolution + template + __global__ void gauss_dcv_1d(TGrid grid_1d, Value_type alpha, + Value_type PSNR, rVector M_io) + { + int ix = threadIdx.x + blockIdx.x*blockDim.x; + + if(ix < grid_1d.nx) + { + host_device_detail::gauss_dcv_1d(ix, grid_1d, alpha, PSNR, M_io); + } + } + + // Gaussian deconvolution + template + __global__ void gauss_dcv_2d(TGrid grid_2d, + Value_type alpha, Value_type PSNR, rVector M_io) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::gauss_dcv_2d(ix, iy, grid_2d, alpha, PSNR, M_io); + } + } + + // pcf_1d preprocessing + template + __global__ void pcf_1d_pp(int ix_s, TGrid grid_1d, Butterworth_1d> bw_1d, + rVector> M_i, rVector M_o) + { + int ix = threadIdx.x + blockIdx.x*blockDim.x; + + if(ix < grid_1d.nx) + { + host_device_detail::pcf_1d_pp(ix, ix_s, grid_1d, bw_1d, M_i, M_o); + } + } + + // gaussian 1d envelope + template + __global__ void pcf_1d_gaussian(TGrid grid_1d, Gauss_1d> gs_1d, + rVector M_1, rVector M_2, rVector pcf) + { + int ix = threadIdx.x + blockIdx.x*blockDim.x; + + if(ix < grid_1d.nx) + { + host_device_detail::pcf_1d_gaussian(ix, grid_1d, gs_1d, M_1, M_2, pcf); + } + } + + // pcf_2d by col preprocessing + template + __global__ void pcf_2d_bc_pp(int iy_s, TGrid grid_2d_i, TGrid grid_2d_o, + rVector> M_i, rVector> fh, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d_i.nx)&&(iy < grid_2d_i.ny)) + { + host_device_detail::pcf_2d_bc_pp(ix, iy, iy_s, grid_2d_i, grid_2d_o, M_i, fh, M_o); + } + } + + // gaussian 2d by col envelope + template + __global__ void pcf_2d_bc_gaussian(TGrid grid_2d, rVector M_1, rVector M_2, + rVector> fg, rVector pcf) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::pcf_2d_bc_gaussian(ix, iy, grid_2d, M_1, M_2, fg, pcf); + } + } + + // gaussian 2d by col envelope + template + __global__ void pcf_2d_bc_assign_real(int iy_s, TGrid grid_2d_i, TGrid grid_2d_o, + rVector M_i, rVector> M_o, bool b_pos) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d_i.nx)&&(iy < grid_2d_i.ny)) + { + int ixy_i = grid_2d_o.ind_col(ix, iy+iy_s); + int ixy_o = grid_2d_i.ind_col(ix, iy); + auto v = M_i[ixy_i].real(); + M_o[ixy_o] = (!b_pos || (v>0))?v:0; + } + } + + // pcf_2d preprocessing + template + __global__ void pcf_2d_pp(TGrid grid_2d, Butterworth_2d> bw_2d, + rVector> M_i, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::pcf_2d_pp(ix, iy, grid_2d, bw_2d, M_i, M_o); + } + } + + // gaussian 2d envelope + template + __global__ void pcf_2d_gaussian(TGrid grid_2d, Gauss_2d> gs_2d, + rVector M_1, rVector M_2, rVector pcf) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::pcf_2d_gaussian(ix, iy, grid_2d, gs_2d, M_1, M_2, pcf); + } + } + + // scaling xy + template + __global__ void sc_2d(TGrid grid_2d_i, rVector M_i, T fxy, TGrid grid_2d_o, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) + { + host_device_detail::sc_2d(ix, iy, grid_2d_i, M_i, fxy, grid_2d_o, M_o); + } + } + + // rotate xy + template + __global__ void rot_2d(TGrid grid_2d_i, rVector M_i, T theta, r2d p0, + T bg, TGrid grid_2d_o, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) + { + host_device_detail::rot_2d(ix, iy, grid_2d_i, M_i, theta, p0, bg, grid_2d_o, M_o); + } + } + + // rotate, scale and shift xy + template + __global__ void rot_sca_sft_2d(TGrid grid_2d_i, rVector M_i, T theta, r2d p0, + T fx, T fy, r2d ps, T bg, TGrid grid_2d_o, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) + { + host_device_detail::rot_sca_sft_2d(ix, iy, grid_2d_i, M_i, theta, p0, fx, fy, ps, bg, grid_2d_o, M_o); + } + } + + // x-shear and y-scaling + template + __global__ void shx_scy(TGrid grid_2d_i, rVector M_i, T fx, T fy, T bg, TGrid grid_2d_o, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) + { + host_device_detail::shx_scy(ix, iy, grid_2d_i, M_i, fx, fy, bg, grid_2d_o, M_o); + } + } + + } // namespace device_detail + + template + enable_if_device_vector_and_device_vector + assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + M_o.assign(M_i.begin(), M_i.end()); + } + + template + enable_if_device_vector + fill(Stream &stream, TVector &M_io, Value_type value_i) + { + thrust::fill(M_io.begin(), M_io.end(), value_i); + } + + template + enable_if_device_vector_and_device_vector + scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M_i.begin(), M_i.end(), M_o.begin(), functor::scale(w_i)); + } + + template + enable_if_device_vector + scale(Stream &stream, Value_type w_i, TVector &M_io) + { + scale(stream, w_i, M_io, M_io); + } + + template + enable_if_device_vector_and_device_vector + square(Stream &stream, TVector_1 &M_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M_i.begin(), M_i.end(), M_o.begin(), functor::square()); + } + + template + enable_if_device_vector_and_device_vector + square_scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M_i.begin(), M_i.end(), M_o.begin(), functor::square_scale(w_i)); + } + + template + enable_if_device_vector_and_device_vector + add(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M1_i.begin(), M1_i.end(), M2_i.begin(), M_o.begin(), functor::add()); + } + + template + enable_if_device_vector_and_device_vector + add(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) + { + add(stream, M_i, M_io, M_io); + } + + template + enable_if_device_vector_and_device_vector + add_scale(Stream &stream, Value_type w1_i, TVector_1 &M1_i, + Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M1_i.begin(), M1_i.end(), M2_i.begin(), M_o.begin(), functor::add_scale_i(w1_i, w2_i)); + } + + template + enable_if_device_vector_and_device_vector + add_scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) + { + using value_type = Value_type; + thrust::transform(M_i.begin(), M_i.end(), M_io.begin(), M_io.begin(), functor::add_scale(w_i)); + } + + template + enable_if_device_vector_and_device_vector + add_square(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M1_i.begin(), M1_i.end(), M2_i.begin(), M_o.begin(), functor::add_square_i()); + } + + template + enable_if_device_vector_and_device_vector + add_square(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) + { + using value_type = Value_type; + thrust::transform(M_i.begin(), M_i.end(), M_io.begin(), M_io.begin(), functor::add_square()); + } + + template + enable_if_device_vector_and_device_vector + add_scale_square(Stream &stream, Value_type w1_i, TVector_1 &M1_i, Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M1_i.begin(), M1_i.end(), M2_i.begin(), M_o.begin(), functor::add_scale_square_i(w1_i, w2_i)); + } + + template + enable_if_device_vector_and_device_vector + add_scale_square(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) + { + using value_type = Value_type; + thrust::transform(M_i.begin(), M_i.end(), M_io.begin(), M_io.begin(), functor::add_scale_square(w_i)); + } + + template + enable_if_device_vector_and_device_vector + multiply(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) + { + using value_type = Value_type; + thrust::transform(M1_i.begin(), M1_i.end(), M2_i.begin(), M_o.begin(), functor::multiply()); + } + + template + enable_if_device_vector_and_device_vector + multiply(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) + { + multiply(stream, M_i, M_io, M_io); + } + + template + enable_if_device_vector> + sum(Stream &stream, TVector &M_i) + { + return thrust::reduce(M_i.begin(), M_i.end()); + } + + template + enable_if_device_vector> + sum_square(Stream &stream, TVector &M_i) + { + using T_r = Value_type_r; + return thrust::transform_reduce(M_i.begin(), M_i.end(), + functor::square(), T_r(0), functor::add()); + } + + template + enable_if_device_vector> + mean(Stream &stream, TVector &M_i) + { + return sum(stream, M_i)/M_i.size(); + } + + template + enable_if_device_vector + mean_var(Stream &stream, TVector &M_i, Value_type &x_mean, Value_type_r &x_var) + { + using T = Value_type; + using T_r = Value_type_r; + + x_mean = mean(stream, M_i); + x_var = thrust::transform_reduce(M_i.begin(), M_i.begin(), functor::square_dif(x_mean), T_r(0), functor::add()); + + x_var = x_var/M_i.size(); + } + + template + enable_if_device_vector> + variance(Stream &stream, TVector &M_i) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_var; + mean_var(stream, M_i, x_mean, x_var); + return x_var; + } + + /***********************************************************************/ + template + enable_if_device_vector + exp_r_factor_1d(TGrid &grid_1d, Value_type gx, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_1d.cuda_grid(); + + device_detail::exp_r_factor_1d<<>>(grid_1d, gx, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + exp_r_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, + TVector_r &gy, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::exp_r_factor_2d_bc<<>>(grid_2d, alpha, gy, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Value_type gx, Value_type gy, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::exp_r_factor_2d<<>>(grid_2d, gx, gy, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + mul_exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &gxh, + Vector, e_host> &gyh, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + + Vector, e_device> gx = gxh; + Vector, e_device> gy = gyh; + device_detail::mul_exp_r_factor_2d<<>>(grid_2d, gx, gy, fPsi_i, fPsi_o); + } + + /***********************************************************************/ + template + enable_if_device_vector + exp_g_factor_1d(TGrid &grid_1d, Value_type x, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_1d.cuda_grid(); + + device_detail::exp_g_factor_1d<<>>(grid_1d, x, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + exp_g_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, + TVector_r &y, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::exp_g_factor_2d_bc<<>>(grid_2d, alpha, y, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Value_type x, Value_type y, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::exp_g_factor_2d<<>>(grid_2d, x, y, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + mul_exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &xh, + Vector, e_host> &yh, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + + Vector, e_device> x = xh; + Vector, e_device> y = yh; + device_detail::mul_exp_g_factor_2d<<>>(grid_2d, x, y, fPsi_i, fPsi_o); + } + + /***********************************************************************/ + template + enable_if_device_vector> + atom_cost_function(TGrid &grid_2d, const Atom_Sa> &atom_Ip, TVector_r &M_i) + { + TVector_r sum_v(1); + + Grid_BT grid_bt; + grid_bt.Blk = dim3(); + grid_bt.Thr = dim3(c_thrnxny, c_thrnxny); + + device_detail::atom_cost_function<<>>(grid_2d, atom_Ip, M_i, sum_v); + return sum_v[0]; + } + + template + enable_if_device_vector + subtract_atom(Stream &stream, TGrid &grid_2d, Vector>, e_host> &atom_Ip, TVector_r &M_i) + { + if(stream.n_act_stream<= 0) + { + return; + } + + for(auto istream = 0; istream < stream.n_act_stream; istream++) + { + Grid_BT grid_bt; + grid_bt.Blk = dim3(); + grid_bt.Thr = dim3(c_thrnxny, c_thrnxny); + + device_detail::subtract_atom<<>>(grid_2d, atom_Ip[istream], M_i); + } + } + + // Linear projected potential: V and zV + template + enable_if_device + linear_Vz(Stream &stream, ePotential_Type potential_type, TQ1 &qz, TVAtom &vatom) + { + using TAtom = Value_type; + + if(stream.n_act_stream<= 0) + { + return; + } + + auto str_linear_Vz = [](cudaStream_t &stream, const ePotential_Type &potential_type, TQ1 &qz, TAtom &atom) + { + if(atom.charge == 0) + { + switch(potential_type) + { + case ePT_Doyle_0_4: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Peng_0_4: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Peng_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Kirkland_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Weickenmeier_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Lobato_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + } + } + else + { + switch(potential_type) + { + case ePT_Doyle_0_4: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Peng_0_4: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Peng_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Kirkland_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Weickenmeier_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + case ePT_Lobato_0_12: + device_detail::linear_Vz<<>>(qz, atom); + break; + } + } + }; + + for(auto istream = 0; istream < stream.n_act_stream; istream++) + { + str_linear_Vz(stream[istream], potential_type, qz, vatom[istream]); + } + } + + // Get Local interpolation coefficients + template + enable_if_device + cubic_poly_coef(Stream &stream, TVAtom &vatom) + { + using TAtom = Value_type; + + if(stream.n_act_stream<= 0) + { + return; + } + + for(auto istream = 0; istream < stream.n_act_stream; istream++) + { + device_detail::cubic_poly_coef<<>>(vatom[istream]); + } + } + + template + enable_if_device_vector + fft1_shift(TGrid &grid_1d, TVector &M_io) + { + auto grid_bt = grid_1d.cuda_grid_h(); + + device_detail::fft1_shift<<>>(grid_1d, M_io); + } + + template + enable_if_device_vector + fft2_sft_bc(Stream &stream, TGrid &grid_2d, TVector &M_io) + { + auto grid_bt = grid_2d.cuda_grid(dim3((grid_2d.nyh+c_thrnxny-1)/c_thrnxny, (grid_2d.nx+c_thrnxny-1)/c_thrnxny)); + + device_detail::fft2_sft_bc<<>>(grid_2d, M_io); + } + + template + enable_if_device_vector + fft2_shift(Stream &stream, TGrid &grid_2d, TVector &M_io) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::fft2_shift<<>>(grid_2d, M_io); + } + + + template + enable_if_device_vector> + sum_over_Det(Stream &stream, TGrid &grid_2d, Value_type g_min, Value_type g_max, TVector &M_i) + { + TVector sum_v(c_thrnxny*c_thrnxny); + + auto grid_bt = grid_2d.cuda_grid(dim3(c_thrnxny, c_thrnxny)); + + device_detail::sum_over_Det<<>>(grid_2d, pow(g_min, 2), pow(g_max, 2), M_i, sum_v); + return mt::sum(stream, sum_v); + } + + template + enable_if_device_vector> + sum_square_over_Det(Stream &stream, TGrid &grid_2d, Value_type g_min, Value_type g_max, TVector &M_i) + { + device_vector> sum_t(c_thrnxny*c_thrnxny, 0); + + auto grid_bt = grid_2d.cuda_grid(dim3(c_thrnxny, c_thrnxny)); + + device_detail::sum_square_over_Det<<>>(grid_2d, pow(g_min, 2), pow(g_max, 2), M_i, sum_t); + return sum(stream, sum_t); + } + + template + enable_if_device_vector_and_device_vector> + sum_square_over_Det(Stream &stream, TGrid &grid_2d, TVector_1 &S_i, TVector_2 &M_i) + { + device_vector> sum_t(c_thrnxny*c_thrnxny, 0); + + auto grid_bt = grid_2d.cuda_grid(dim3(c_thrnxny, c_thrnxny)); + + device_detail::sum_square_over_Det<<>>(grid_2d, S_i, M_i, sum_t); + return sum(stream, sum_t); + } + + template + enable_if_device_vector + bandwidth_limit(Stream &stream, TGrid &grid_2d, TVector_c &M_io) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::bandwidth_limit<<>>(grid_2d, M_io); + } + + template + enable_if_device_vector + hard_aperture(Stream &stream, TGrid &grid_2d, Value_type g_max, Value_type w, TVector_c &M_io) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::hard_aperture<<>>(grid_2d, pow(g_max, 2), w, M_io); + } + + template + enable_if_device_vector + propagate(Stream &stream, TGrid &grid_2d, Value_type w, + Value_type gxu, Value_type gyu, TVector_c &psi_i, TVector_c &psi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + device_detail::propagate<<>>(grid_2d, w, gxu, gyu, psi_i, psi_o); + } + + template + enable_if_device_vector_and_device_vector + transmission_function(Stream &stream, TGrid &grid_2d, eElec_Spec_Int_Model elec_spec_int_model, + Value_type w, TVector_1 &V0_i, TVector_2 &Trans_o) + { + using T_r = Value_type; + + thrust::transform(V0_i.begin(), V0_i.end(), Trans_o.begin(), + functor::transmission_function(w, elec_spec_int_model)); + } + + template + enable_if_device_vector + probe(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type x, + Value_type y, Value_type gxu, Value_type gyu, TVector_c &fPsi_o) + { + using T_r = Value_type; + + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::probe<<>>(grid_2d, lens, x, y, gxu, gyu, fPsi_o); + + auto total = sum_square(stream, fPsi_o); + scale(stream, sqrt(1.0/total), fPsi_o); + } + + template + enable_if_device_vector + apply_CTF(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type gxu, Value_type gyu, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + device_detail::apply_CTF<<>>(grid_2d, lens, gxu, gyu, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + apply_PCTF(Stream &stream, TGrid &grid_2d, Lens> &lens, TVector_c &fPsi_i, TVector_c &fPsi_o) + { + auto grid_bt = grid_2d.cuda_grid(); + device_detail::apply_PCTF<<>>(grid_2d, lens, fPsi_i, fPsi_o); + } + + template + enable_if_device_vector + kernel_xyz(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_device> &fft_2d, TVector_c &k_x, TVector_c &k_y, TVector_c &k_z) + { + eels.factor = device_detail::Lorentz_factor(stream, grid_2d, eels); + + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::kernel_xyz<<>>(grid_2d, eels, k_x, k_y, k_z); + + fft_2d.inverse(k_x); + fft_2d.inverse(k_y); + fft_2d.inverse(k_z); + } + + template + enable_if_device_vector + kernel_x(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_device> &fft_2d, TVector_c &k_x) + { + eels.factor = device_detail::Lorentz_factor(stream, grid_2d, eels); + + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::kernel_x<<>>(grid_2d, eels, k_x); + + } + + template + enable_if_device_vector + kernel_y(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_device> &fft_2d, TVector_c &k_y) + { + eels.factor = device_detail::Lorentz_factor(stream, grid_2d, eels); + + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::kernel_y<<>>(grid_2d, eels, k_y); + + fft_2d.inverse(k_y); + } + + template + enable_if_device_vector + kernel_z(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_device> &fft_2d, TVector_c &k_z) + { + eels.factor = device_detail::Lorentz_factor(stream, grid_2d, eels); + + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::kernel_z<<>>(grid_2d, eels, k_z); + + fft_2d.inverse(k_z); + } + + template + enable_if_device_vector + kernel_mn1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_device> &fft_2d, TVector_c &k_mn1) + { + eels.factor = device_detail::Lorentz_factor(stream, grid_2d, eels); + + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::kernel_mn1<<>>(grid_2d, eels, k_mn1); + + fft_2d.inverse(k_mn1); + } + + template + enable_if_device_vector + kernel_mp1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_device> &fft_2d, TVector_c &k_mp1) + { + eels.factor = device_detail::Lorentz_factor(stream, grid_2d, eels); + + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::kernel_mp1<<>>(grid_2d, eels, k_mp1); + + fft_2d.inverse(k_mp1); + } + + /***************************************************************************/ + /***************************************************************************/ + template + typename std::enable_if::value + && is_complex>::value && !std::is_same, Value_type>::value, void>::type + copy_to_host(Stream &stream, TVector_i &M_i, TVector_o &M_o, + Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + // copy data from host to host + copy_to_host(stream, *M_i_h, M_o); + } + + template + typename std::enable_if::value + && (!is_complex>::value || std::is_same, Value_type>::value), void>::type + copy_to_host(Stream &stream, TVector_i &M_i, TVector_o &M_o, + Vector, e_host> *M_i_h = nullptr) + { + M_o.assign(M_i.begin(), M_i.end()); + } + + template + enable_if_device_vector_and_host_vector + add_scale_to_host(Stream &stream, Value_type w_i, + TVector_i &M_i, TVector_o &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + // add and scale + mt::add_scale_to_host(stream, w_i, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_square_to_host(Stream &stream, Value_type w_i, + TVector_i &M_i, TVector_o &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_square_to_host(stream, w_i, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_m2psi_psi_to_host(Stream &stream, Value_type w_i, + TVector_c_i &psi_i, TVector_r_o &m2psi_o, TVector_c_o &psi_o, Vector, e_host> *psi_i_h = nullptr) + { + Vector, e_host> M_h; + psi_i_h = (psi_i_h == nullptr)?&M_h:psi_i_h; + + // data transfer from GPU to CPU + psi_i_h->assign(psi_i.begin(), psi_i.end()); + + mt::add_scale_m2psi_psi_to_host(stream, w_i, *psi_i_h, m2psi_o, psi_o); + } + + /***************************************************************************/ + /*************************** Device to Device ******************************/ + /***************************************************************************/ + template + enable_if_device_vector + assign_shift_2d(TGrid &grid_2d, TVector &M_i, TVector &M_o, + Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::assign_shift_2d<<>>(grid_2d, M_i, M_o); + } + + template + enable_if_device_vector + add_scale_shift_2d(TGrid &grid_2d, Value_type w, + TVector &M_i, TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_shift_2d<<>>(grid_2d, w, M_i, M_o); + } + + template + enable_if_device_vector_and_device_vector + add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_square_shift_2d<<>>(grid_2d, w, M_i, M_o); + } + + template + enable_if_device_vector + assign_crop(TGrid &grid_2d, TVector &M_i, Range_2d &range, + TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::assign_crop_shift_2d<<>>(grid_2d, M_i, range, M_o); + } + + template + enable_if_device_vector + assign_crop_shift_2d(TGrid &grid_2d, TVector &M_i, Range_2d &range, + TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::assign_crop_shift_2d<<>>(grid_2d, M_i, range, M_o); + } + + template + enable_if_device_vector + add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector &M_i, Range_2d &range, TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_crop_shift_2d<<>>(grid_2d, w, M_i, range, M_o); + } + + template + enable_if_device_vector_and_device_vector + add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_square_crop_shift_2d<<>>(grid_2d, w, M_i, range, M_o); + } + + /***************************************************************************/ + /***************************** Device to Host ******************************/ + /***************************************************************************/ + template + enable_if_device_vector_and_host_vector + assign_shift_2d(TGrid &grid_2d, TVector_1 &M_i, TVector_2 &M_o, + Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::assign_shift_2d(grid_2d, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_square_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + assign_crop(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::assign_crop(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_device_vector_and_host_vector + assign_crop_shift_2d(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::assign_crop_shift_2d(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_square_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + /***************************************************************************/ + /***************************** Host to Device ******************************/ + /***************************************************************************/ + template + enable_if_host_vector_and_device_vector + assign_shift_2d(TGrid &grid_2d, TVector_1 &M_i, TVector_2 &M_o, + Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::assign_shift_2d(grid_2d, *M_i_h, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_square_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_host_vector_and_device_vector + assign_crop(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::assign_crop(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_host_vector_and_device_vector + assign_crop_shift_2d(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::assign_crop_shift_2d(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_square_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + /***************************************************************************/ + /***************************************************************************/ + template + enable_if_device_vector + trs(Stream &stream, const int &nrows, const int &ncols, TVector &M) + { + Grid_BT grid_bt; + grid_bt.Blk = dim3((nrows+c_thrnxny-1)/c_thrnxny, (ncols+c_thrnxny-1)/c_thrnxny); + grid_bt.Thr = dim3(c_thrnxny, c_thrnxny); + + TVector M_t(nrows*ncols); + device_detail::trs<<>>(ncols, nrows, M, M_t); + M = M_t; + } + + + /*******************************************************************/ + // find peak position 1d + template + enable_if_device_vector> + fit_max_pos_1d(TGrid &grid_1d, TVector &Im, Value_type p_i, + Value_type sigma_i, Value_type radius_i) + { + using T = Value_type; + + Vector Im_h = Im; + return fit_max_pos_1d(grid_1d, Im_h, p_i, sigma_i, radius_i); + } + + // find peak position 2d + template + enable_if_device_vector>> + fit_max_pos_2d(TGrid &grid_2d, TVector &Im, r2d> p_i, + Value_type sigma_i, Value_type radius_i) + { + using T = Value_type; + + Vector Im_h = Im; + return fit_max_pos_2d(grid_2d, Im_h, p_i, sigma_i, radius_i); + } + + inline + bool is_gpu_available() + { + bool is_available = false; + try + { + int device_count = 0; + cudaError_t error_id = cudaGetDeviceCount(&device_count); + + is_available = !((error_id != cudaSuccess)||(device_count == 0)); + } + catch(...) + { + is_available = false; + } + + return is_available; + } + + inline + int number_of_gpu_available() + { + int device_count = 0; + cudaError_t error_id = cudaGetDeviceCount(&device_count); + + if (error_id != cudaSuccess) + { + device_count = 0; + } + return (device_count>0)?device_count:0; + } + +} // namespace mt + +#endif diff --git a/src/energy_loss.cuh b/src/energy_loss.cuh old mode 100644 new mode 100755 index 46d97947..709d8f6e --- a/src/energy_loss.cuh +++ b/src/energy_loss.cuh @@ -1,98 +1,276 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef ENERGY_LOSS_H -#define ENERGY_LOSS_H - -#include "types.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "input_multislice.cuh" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" -#include "cgpu_fcns.cuh" - -namespace mt -{ - template - class Energy_Loss - { - public: - using T_r = T; - using T_c = complex; - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i, FFT *fft2_i) - { - input_multislice = input_multislice_i; - stream = stream_i; - fft_2d = fft2_i; - - if(input_multislice->eels_fr.m_selection>2) - { - kernel.resize(3); - } - else - { - kernel.resize(1); - } - - for(auto ikn = 0; ikngrid_2d.nxy()); - } - - } - - void set_atom_type(EELS &eels) - { - if(eels.m_selection>2) - { - mt::kernel_xyz(*stream, input_multislice->grid_2d, eels, *fft_2d, kernel[0], kernel[1], kernel[2]); - } - else if(eels.m_selection == -2) - { - mt::kernel_x(*stream, input_multislice->grid_2d, eels, *fft_2d, kernel[0]); - } - else if(eels.m_selection == -1) - { - mt::kernel_mn1(*stream, input_multislice->grid_2d, eels, *fft_2d, kernel[0]); - } - else if(eels.m_selection == 0) - { - mt::kernel_z(*stream, input_multislice->grid_2d, eels, *fft_2d, kernel[0]); - } - else if(eels.m_selection == 1) - { - mt::kernel_mp1(*stream, input_multislice->grid_2d, eels, *fft_2d, kernel[0]); - } - else if(eels.m_selection == 2) - { - mt::kernel_y(*stream, input_multislice->grid_2d, eels, *fft_2d, kernel[0]); - } - } - - Vector, e_host> kernel; - private: - Input_Multislice *input_multislice; - Stream *stream; - FFT *fft_2d; - }; - -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ENERGY_LOSS_H + #define ENERGY_LOSS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "type_traits_gen.h" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "fcns_cgpu_gen.h" + // #include "in_classes.cuh" + // #include "fcns_cpu.h" + // #include "fcns_gpu.h" + // #include "fcns_gpu.h" + + namespace mt + { + template + class EELS + { + public: + using value_type = T; + + eSpace space; // real or reciprocal space + + T E_0; // incident energy + dt_int32 m_sel; // selection rule + T coll_angle; // collection angle(rad) + eChan_Typ chan_type; // channelling type + T g_coll; // collection angle(recirpocal Angstroms) + + dt_int32 Z; // atomic type + T x; // x position + T y; // y position + T occ; // y occupancy + T E_loss; // energy loss + T ge; // relativistic corrected effective scattering momentum transfer + T ge2; // ge square + T gc; // ge cut-off at the Bethe Ridge + T gc2; // gc square + T lrtz_factor; // lorentz factor = sum 1/(g^2+ge^2) + + /************************************* constructors ************************************/ + EELS(): space(esp_real), E_0(0), m_sel(0), coll_angle(0), chan_type(eCT_double_chan), + g_coll(0), lrtz_factor(1), Z(0), x(0), y(0), occ(0), E_loss(0), ge(0), ge2(0), gc(0), gc2(0){} + + /* copy constructor */ + EELS(const EELS& eels) + { + *this = eels; + } + + /* converting constructor */ + template + EELS(const EELS& eels) + { + *this = eels; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + EELS& operator=(const EELS& eels) + { + if (this != &eels) + { + space = eels.space; + + E_0 = eels.E_0; + m_sel = eels.m_sel; + coll_angle = eels.coll_angle; + chan_type = eels.chan_type; + g_coll = eels.g_coll; + + Z = eels.Z; + x = eels.x; + y = eels.y; + occ = eels.occ; + E_loss = eels.E_loss; + ge = eels.ge; + ge2 = eels.ge2; + gc = eels.gc; + gc2 = eels.gc2; + lrtz_factor = eels.lrtz_factor; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + EELS& operator=(const EELS& eels) + { + space = eels.space; + + E_0 = T(eels.E_0); + m_sel = eels.m_sel; + coll_angle = T(eels.coll_angle); + chan_type = eels.chan_type; + g_coll = T(eels.g_coll); + + Z = eels.Z; + x = T(eels.x); + y = T(eels.y); + occ = T(eels.occ); + E_loss = T(eels.E_loss); + ge = T(eels.ge); + ge2 = T(eels.ge2); + gc = T(eels.gc); + gc2 = T(eels.gc2); + lrtz_factor = T(eels.lrtz_factor); + + return *this; + } + + template + void assign(const EELS& eels) + { + *this = eels; + } + + /***************************************************************************************/ + void set_in_data(const eSpace& space, const T& E_0, dt_int32 m_sel, const T& coll_angle, eChan_Typ chan_type, const dt_int32& Z, const T& E_loss) + { + this->space = space; + this->E_0 = E_0; + this->m_sel = m_sel; + set_coll_angle(coll_angle); + this->chan_type = chan_type; + + this->Z = Z; + set_e_loss(E_loss); + } + + void set_coll_angle(const T& coll_angle) + { + this->coll_angle = coll_angle; + g_coll = coll_angle/fcn_lambda(E_0); + } + + void set_e_loss(const T& E_loss) + { + const auto gamma = fcn_gamma(E_0); + const auto lambda = fcn_lambda(E_0); + + auto theta = theta_efect(E_loss, E_0); + ge = theta/(lambda*gamma*gamma); + ge2 = pow(gamma*ge, 2); + gc = sqrt(T(2)*theta)/lambda; + gc2 = pow(gc, 2); + } + + // effective scattering angle + T theta_efect(const T& E_loss, const T& E_0) + { + const auto emass = T(510.99906); + const auto x = (emass + E_0)/(T(2)*emass + E_0); + return E_loss*x/E_0; + } + + dt_bool is_Single_Chan() const + { + return chan_type == ect_single_chan; + } + + dt_bool is_Mixed_Chan() const + { + return chan_type == ect_mixed_chan; + } + + dt_bool is_Double_Chan() const + { + return chan_type == eCT_double_chan; + } + + dt_bool is_real_space() const + { + return space == esp_real; + } + + dt_bool is_reciprocal_space() const + { + return space == esp_fourier; + } + }; + + /* + template + class Energy_Loss + { + public: + using T_r = T; + using T_c = complex; + + void set_in_data(Multem_In_Parm *multem_in_parm, Stream *stream, FFT *fft2) + { + this->multem_in_parm = multem_in_parm; + this->stream = stream; + this->fft_2d = fft2; + + if (multem_in_parm->eels_fr.m_sel>2) + { + kernel.resize(3); + } + else + { + kernel.resize(1); + } + + for(auto ikn = 0; ikngrid_2d.size()); + } + + } + + void set_atom_type(EELS& eels) + { + if (eels.m_sel>2) + { + mt::fcn_eels_w_xyz(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0], kernel[1], kernel[2]); + } + else if (eels.m_sel == -2) + { + mt::fcn_eels_w_x(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == -1) + { + mt::fcn_eels_w_mn1(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == 0) + { + mt::fcn_eels_w_z(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == 1) + { + mt::fcn_eels_w_mp1(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + else if (eels.m_sel == 2) + { + mt::fcn_eels_w_y(*stream, multem_in_parm->grid_2d, eels, *fft_2d, kernel[0]); + } + } + + Vctr, edev_cpu> kernel; + private: + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + }; + */ + } + #endif \ No newline at end of file diff --git a/src/fcn_butwth.h b/src/fcn_butwth.h new file mode 100755 index 00000000..71f35272 --- /dev/null +++ b/src/fcn_butwth.h @@ -0,0 +1,116 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" + +/* template definition */ +namespace mt +{ +#ifndef FCN_ELEM_DEC + #define FCN_ELEM_DEC + template class Fcn_Elem; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Fcn_Butwth = Fcn_Elem; +} + +namespace mt +{ + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + dt_int32 b_1; + T b_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(); + + Fcn_Elem(const T& a, const dt_int32& n, const T& radius); + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + /***************************************************************************************/ + void set_in_data(const T& a, const dt_int32& n, const T& radius); + + CGPU_EXEC + void clear(); + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const dt_int32& n, const T& radius) const; + + CGPU_EXEC + T eval_r2(const T& r2) const; + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const; + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const; + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const dt_int32& n, const T& radius) const; + + CGPU_EXEC + T eval_r(const T& r) const; + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const; + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const; + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r2, const dt_int32& n, const T& radius) const; + + CGPU_EXEC + T operator()(const T& r2) const; + + CGPU_EXEC + R_2d operator()(const R_2d& r2) const; + + CGPU_EXEC + R_3d operator()(const R_3d& r2) const; + }; +} + +#include "detail/fcn_butwth.inl" \ No newline at end of file diff --git a/src/fcn_cos_tap.h b/src/fcn_cos_tap.h new file mode 100755 index 00000000..f5076688 --- /dev/null +++ b/src/fcn_cos_tap.h @@ -0,0 +1,118 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" + +/* template definition */ +namespace mt +{ +#ifndef FCN_ELEM_DEC + #define FCN_ELEM_DEC + template class Fcn_Elem; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Fcn_Cos_Tap = Fcn_Elem; +} + +namespace mt +{ + template + class Fcn_Elem + { + public: + using value_type = T; + + T r_tap; + T r_max; + T coef_tap; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(); + + Fcn_Elem(const T& r_tap, const T& r_max); + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm); + + /* converting constructor */ + template + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + /* converting assignment operator */ + template + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + template + CGPU_EXEC + void assign(const Fcn_Elem& parm); + + /***************************************************************************************/ + void set_in_data(const T& r_tap, const T& r_max); + + CGPU_EXEC + void clear(); + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& r_tap, const T& r_max) const; + + CGPU_EXEC + T eval_r(const T& r) const; + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const; + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const; + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r, const T& r_tap, const T& r_max) const; + + CGPU_EXEC + T operator()(const T& r) const; + + CGPU_EXEC + R_2d operator()(const R_2d& r) const; + + CGPU_EXEC + R_3d operator()(const R_3d& r) const; + }; +} + + +#include "detail/fcn_cos_tap.inl" \ No newline at end of file diff --git a/src/fcn_exp.h b/src/fcn_exp.h new file mode 100755 index 00000000..6d846e9e --- /dev/null +++ b/src/fcn_exp.h @@ -0,0 +1,115 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" + +/* template definition */ +namespace mt +{ +#ifndef FCN_ELEM_DEC + #define FCN_ELEM_DEC + template class Fcn_Elem; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Fcn_Exp = Fcn_Elem; +} + +namespace mt +{ + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(); + + Fcn_Elem(const T& a, const T& beta); + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + /***************************************************************************************/ + void set_in_data(const T& a, const T& beta); + + CGPU_EXEC + void clear(); + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& beta) const; + + CGPU_EXEC + T eval_r(const T& r) const; + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const; + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const; + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& beta) const; + + CGPU_EXEC + T eval_r2(const T& r2) const; + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const; + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const; + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r, const T& beta) const; + + CGPU_EXEC + T operator()(const T& r) const; + + CGPU_EXEC + R_2d operator()(const R_2d& r) const; + + CGPU_EXEC + R_3d operator()(const R_3d& r) const; + }; +} + +#include "detail/fcn_exp.inl" \ No newline at end of file diff --git a/src/fcn_fermi.h b/src/fcn_fermi.h new file mode 100755 index 00000000..af294ae8 --- /dev/null +++ b/src/fcn_fermi.h @@ -0,0 +1,116 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" + +/* template definition */ +namespace mt +{ +#ifndef FCN_ELEM_DEC + #define FCN_ELEM_DEC + template class Fcn_Elem; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Fcn_Fermi = Fcn_Elem; +} + +namespace mt +{ + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + T b_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(); + + Fcn_Elem(const T& a, const T& alpha, const T& radius); + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + /***************************************************************************************/ + void set_in_data(const T& a, const T& alpha, const T& radius); + + CGPU_EXEC + void clear(); + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& radius) const; + + CGPU_EXEC + T eval_r2(const T& r2) const; + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const; + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const; + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& radius) const; + + CGPU_EXEC + T eval_r(const T& r) const; + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const; + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const; + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r2, const T& radius) const; + + CGPU_EXEC + T operator()(const T& r2) const; + + CGPU_EXEC + R_2d operator()(const R_2d& r2) const; + + CGPU_EXEC + R_3d operator()(const R_3d& r2) const; + }; +} + +#include "detail/fcn_fermi.inl" \ No newline at end of file diff --git a/src/fcn_gauss.h b/src/fcn_gauss.h new file mode 100755 index 00000000..f9a31a48 --- /dev/null +++ b/src/fcn_gauss.h @@ -0,0 +1,125 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" + +/* template definition */ +namespace mt +{ +#ifndef FCN_ELEM_DEC + #define FCN_ELEM_DEC + template class Fcn_Elem; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Fcn_Gauss = Fcn_Elem; +} + +namespace mt +{ + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(); + + Fcn_Elem(const T& sigma); + + Fcn_Elem(const T& a, const T& sigma); + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm); + + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + /* converting assignment operator */ + template + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + template + CGPU_EXEC + void assign(const Fcn_Elem& parm); + + /***************************************************************************************/ + void set_in_data(const T& a, const T& sigma); + + CGPU_EXEC + void clear(); + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& sigma) const; + + CGPU_EXEC + T eval_r2(const T& r2) const; + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const; + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const; + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& sigma) const; + + CGPU_EXEC + T eval_r(const T& r) const; + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const; + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const; + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r2, const T& sigma) const; + + CGPU_EXEC + T operator()(const T& r2) const; + + CGPU_EXEC + R_2d operator()(const R_2d& r2) const; + + CGPU_EXEC + R_3d operator()(const R_3d& r2) const; + }; +} + +#include "detail/fcn_gauss.inl" \ No newline at end of file diff --git a/src/fcn_hann.h b/src/fcn_hann.h new file mode 100755 index 00000000..92793dc2 --- /dev/null +++ b/src/fcn_hann.h @@ -0,0 +1,116 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" + +/* template definition */ +namespace mt +{ +#ifndef FCN_ELEM_DEC + #define FCN_ELEM_DEC + template class Fcn_Elem; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Fcn_Hann = Fcn_Elem; +} + +namespace mt +{ + // https:// en.wikipedia.org/wiki/Hann_function + template + class Fcn_Elem + { + public: + using value_type = T; + + T a_1; + T b_1; + + /************************************* constructors ************************************/ + CGPU_EXEC + Fcn_Elem(); + + Fcn_Elem(const T& a, const T& l); + + /* copy constructor */ + CGPU_EXEC + Fcn_Elem(const Fcn_Elem& parm); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Fcn_Elem& operator=(const Fcn_Elem& parm); + + /***************************************************************************************/ + void set_in_data(const T& a, const T& l); + + CGPU_EXEC + void clear(); + + /***************************************************************************************/ + CGPU_EXEC + T eval_r(const T& r, const T& l) const; + + CGPU_EXEC + T eval_r(const T& r) const; + + CGPU_EXEC + R_2d eval_r(const R_2d& r) const; + + CGPU_EXEC + R_3d eval_r(const R_3d& r) const; + + /***************************************************************************************/ + CGPU_EXEC + T eval_r2(const T& r2, const T& l) const; + + CGPU_EXEC + T eval_r2(const T& r2) const; + + CGPU_EXEC + R_2d eval_r2(const R_2d& r2) const; + + CGPU_EXEC + R_3d eval_r2(const R_3d& r2) const; + + /***************************************************************************************/ + CGPU_EXEC + T operator()(const T& r, const T& l) const; + + CGPU_EXEC + T operator()(const T& r) const; + + CGPU_EXEC + R_2d operator()(const R_2d& r) const; + + CGPU_EXEC + R_3d operator()(const R_3d& r) const; + }; +} + +#include "detail/fcn_hann.inl" \ No newline at end of file diff --git a/src/fcns_cgpu_gen.h b/src/fcns_cgpu_gen.h new file mode 100755 index 00000000..985bcee2 --- /dev/null +++ b/src/fcns_cgpu_gen.h @@ -0,0 +1,963 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "macros.h" +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" + +/********************************* simple functions ************************************/ +/********** static member function are not supported for the cuda compiler *************/ +/***************************************************************************************/ +//template +//CGPU_EXEC +//T fill_nzero(const T& r) // for R_2d and R_3d compatibility +//{ +// return r; +//} + + +/* is equal */ +namespace mt +{ + template + CGPU_EXEC_INL + dt_bool fcn_is_equal(const T& a, const T& b) + { + return a == b; + } + + template <> + CGPU_EXEC_INL + dt_bool fcn_is_equal(const dt_int32& a, const dt_int32& b) + { + return a == b; + } + + template <> + CGPU_EXEC_INL + dt_bool fcn_is_equal(const dt_float32 &a, const dt_float32 &b) + { + const dt_float32 eps_abs = 1e-5f; + const dt_float32 eps_rel = 1e-4f; + + // check if the numbers are really close -- needed when comparing numbers near zero. + dt_float32 diff = fabs(a - b); + if (diff <= eps_abs) + return true; + + // otherwise fall back to Knuth's algorithm + return diff <= ((fabs(a) + CGPU_EXEC_INL + dt_bool fcn_is_equal(const dt_float64 &a, const dt_float64 &b) + { + const dt_float64 eps_abs = 1e-13; + const dt_float64 eps_rel = 1e-8; + + // check if the numbers are really close -- needed when comparing numbers near zero. + dt_float64 diff = fabs(a - b); + if (diff <= eps_abs) + return true; + + // otherwise fall back to Knuth's algorithm + return diff <= ((fabs(a) + CGPU_EXEC_INL + dt_bool fcn_is_zero(const T& x) + { + return fcn_is_equal(x, T(0)); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_zero(const T& x, const TArg&... arg) + { + return fcn_is_zero(x) && fcn_is_zero(arg...); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_nzero(const T& x) + { + return !fcn_is_equal(x, T(0)); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_nzero(const T& x, const TArg&... arg) + { + return fcn_is_nzero(x) && fcn_is_nzero(arg...); + } +} + +/* is one */ +namespace mt +{ + template + CGPU_EXEC_INL + dt_bool fcn_is_one(const T& x) + { + return fcn_is_equal(x, T(1)); + } + + template + CGPU_EXEC_INL + dt_bool fcn_is_one(const T& x, const TArg&... arg) + { + return fcn_is_one(x) && fcn_is_one(arg...); + } +} + +/* if else zero */ +namespace mt +{ + template + CGPU_EXEC + T fcn_set_zero_eps(const T& x) + { + return (fcn_is_zero(x))?T(0):x; + } + + template + CGPU_EXEC + T fcn_ifzero(const T& x, const T& x_t, const T& x_f) + { + return (fcn_is_zero(x))?x_t:x_f; + } + + template + CGPU_EXEC + T fcn_ifnzero(const T& x, const T& x_t, const T& x_f) + { + return (fcn_is_nzero(x))?x_t:x_f; + } +} + +/* div/min/max */ +namespace mt +{ + template + CGPU_EXEC + T fcn_div(const T& x, const U& y) + { + return (fcn_is_zero(y))?T(0):x/static_cast(y); + } + + template + CGPU_EXEC + T fcn_min(const T& x, const T& y) + { + return (x + CGPU_EXEC + T fcn_max(const T& x, const T& y) + { + return (x>y)?x:y; + } +} + +/* check bounds */ +namespace mt +{ + template + CGPU_EXEC + dt_bool fcn_chk_bound(const T& x, const T& x_min, const T& x_max) + { + return (x_min <= x) && (x < x_max); + } + + // template + // CGPU_EXEC + // dt_bool fcn_chk_bound(const T& x, const T& x_min, const T& x_max, const TArg&... arg) + // { + // return fcn_chk_bound(x, x_min, x_max) && fcn_chk_bound(x, arg...); + // } + + template + CGPU_EXEC + dt_bool fcn_chk_bound_eps(const T& x, const T& x_min, const T& x_max) + { + const T eps = epsilon_abs(); + return (x_min - eps <= x) && (x < x_max + eps); + } + + template + CGPU_EXEC + dt_bool fcn_chk_bound_eps(const T& x, const T& x_min, const T& x_max, const TArg&... arg) + { + return fcn_chk_bound_eps(x, x_min, x_max) && fcn_chk_bound_eps(arg...); + } +} + +/* set bounds */ +namespace mt +{ + template + CGPU_EXEC + enable_if_float + fcn_set_bound(const T& x, const T& x_min, const T& x_max) + { + return ::fmax(x_min, ::fmin(x_max, x)); + } + + template + CGPU_EXEC + enable_if_int + fcn_set_bound(const T& x, const T& x_min, const T& x_max) + { + return (x<=x_min)?x_min:(x>=x_max)?x_max:x; + } +} + +/* locate index: floor/ceil/pbc */ +namespace mt +{ + // ! apply periodic boundary conditions to index + template + CGPU_EXEC + ST fcn_ind_pbc(const ST& ix, const ST& nx) + { + return ix - static_cast(::floor(T(ix)/T(nx)))*nx; + } + + // ! cast floor + template + CGPU_EXEC + ST fcn_cfloor(const T& x) + { + return static_cast(::floor(x)); + } + + // ! cast ceil + template + CGPU_EXEC + ST fcn_cceil(const T& x) + { + return static_cast(::ceil(x)); + } + + // ! bound cast floor + template + CGPU_EXEC + U fcn_bcfloor(const T& x, const U& ix_min, const U& ix_max) + { + return fcn_set_bound(fcn_cfloor(x), ix_min, ix_max); + } + + // ! bound cast ceil + template + CGPU_EXEC + U fcn_bcceil(const T& x, const U& ix_min, const U& ix_max) + { + return fcn_set_bound(fcn_cceil(x), ix_min, ix_max); + } + + // get index and distance + template + CGPU_EXEC + void fcn_get_idx_0_idx_n(const T& x, const T& x_max, const T& dx, const dt_bool& pbc, const ST& nx, ST& ix_0, ST& ix_n) + { + ix_0 = fcn_cfloor((x - x_max)/dx); + auto ix_e = fcn_cceil((x + x_max)/dx); + + if (!pbc) + { + ix_0 = fcn_set_bound(ix_0, ST(0), nx); + ix_e = fcn_set_bound(ix_e, ST(0), nx); + } + + ix_n = (ix_0 == ix_e)?ST(0):(ix_e - ix_0 + 1); + } +} + +/* index search */ +namespace mt +{ + template + CGPU_EXEC + dt_int32 fcn_r_2_ir_b_by_fcn(TFcn fcn, const T& x, dt_int32 ix_min, dt_int32 ix_max) + { + do + { + const dt_int32 ix_m = (ix_min + ix_max) >> 1; // divide by 2 + + if (x <= fcn(ix_m)) + ix_max = ix_m; + else + ix_min = ix_m; + } while ((ix_max - ix_min) > 1); + + if (x >= fcn(ix_max)) + return ix_max; + else + return ix_min; + } + + template + CGPU_EXEC + dt_int32 fcn_r_2_ir_by_vctr(T* xv, const T& x, dt_int32 ix_min, dt_int32 ix_max) + { + do { + const dt_int32 ix_m = (ix_min + ix_max) >> 1; // divide by 2 + + if (x <= xv[ix_m]) + ix_max = ix_m; + else + ix_min = ix_m; + } while ((ix_max - ix_min) > 1); + + if (x >= xv[ix_max]) + return ix_max; + else + return ix_min; + } + + template + CGPU_EXEC + dt_int32 fcn_r_2_ir_b_by_vctr(T* xv, const T& x, dt_int32 ix_min, dt_int32 ix_max) + { + if (x > xv[ix_max]) + return -2; + else if (x < x[ix_min]) + return -1; + + return fcn_r_2_ir_by_vctr(xv, x, ix_min, ix_max); + } +} + +/* find root */ +namespace mt +{ + template + CGPU_EXEC + T fcn_fd_root(T x_0, T x_e, const T& Tol, const dt_int32& it_max, TFcn fcn) + { + dt_int32 it = 0; + T x, fx, fx_e = fcn(x_e); + + do + { + x = 0.5*(x_0 + x_e); + fx = fcn(x); + + if (fx*fx_e<0) + { + x_0 = x; + } + else + { + x_e = x; + fx_e = fx; + } + it++; + } while ((::fabs(fx)>Tol) && (it < it_max)); + + return x; + } +} + +/* point 2 line 2d*/ +namespace mt +{ + // ax + by + c = 0 + // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line + + // distance from point to line + template + CGPU_EXEC + T fcn_pt_2_ln_dist(const T& a, const T& b, const T& c, const T& x0, const T& y0) + { + return ::fabs(a*x0 + b*y0 + c)/::sqrt(a*a + b*b); + } + + // calculate intersection from point to line + template + CGPU_EXEC + void fcn_pt_2_ln_intxn_2d(const T& a, const T& b, const T& c, const T& x0, const T& y0, const T& x, const T& y) + { + auto m = ::sqrt(a*a + b*b); + + x = (b*(b*x0-a*y0)-a*c)/m; + y = -(a*(b*x0-a*y0)-b*c)/m; + } +} + +/* length of curve */ +namespace mt +{ + template + CGPU_EXEC + T fcn_get_len_crv(dt_int32 ix_0, dt_int32 ix_e, Ctpr x, Ctpr y) + { + T ln = 0; + for(auto ik = ix_0; ik < ix_e-1; ik++) + { + const T dx = x[ik + 1] - x[ik]; + const T dy = y[ik + 1] - y[ik]; + ln = ln + ::sqrt(dx*dx + dy*dy); + } + + return ln; + } + + template + CGPU_EXEC + T fcn_get_len_crv(dt_int32 ix_0, dt_int32 ix_e, Ctpr x, Ctpr y, const T& ln_max, dt_int32& iln) + { + T ln = 0; + + if (ix_0 < ix_e) + { + iln = ix_e; + for(auto ik = ix_0; ik < ix_e-1; ik++) + { + const T dx = x[ik + 1] - x[ik]; + const T dy = y[ik + 1] - y[ik]; + ln = ln + ::sqrt(dx*dx + dy*dy); + if ((ln_max > 0) && (ln >= ln_max)) + { + iln = ik; + break; + } + } + } + else + { + iln = ix_e; + for(auto ik = ix_0; ik > ix_e; ik--) + { + const T dx = x[ik] - x[ik-1]; + const T dy = y[ik] - y[ik-1]; + ln = ln + ::sqrt(dx*dx + dy*dy); + if ((ln_max > 0) && (ln >= ln_max)) + { + iln = ik; + break; + } + } + } + + return ln; + } + + // get index to maximum distance + template + CGPU_EXEC + T fcn_get_max_crv_2_ln_dist(const T& x_1, const T& y_1, const T& x_2, const T& y_2, dt_int32 ix_0, dt_int32 ix_e, Tpr x, Tpr y, dt_int32& ind_max) + { + const T m = ::sqrt(::square(x_2 - x_1) + ::square(y_2 - y_1)); + const T a = (y_2 - y_1)/m; + const T b = -(x_2 - x_1)/m; + const T c = (x_2*y_1 - y_2*x_1)/m; + + T d_max = 0; + ind_max = 0; + for(auto ik = ix_0; ik < ix_e; ik++) + { + const T d = ::fabs(a*x[ik] + b*y[ik] + c); + if (d > d_max) + { + d_max = d; + ind_max = ik; + } + } + + return d_max; + } +} + +/* Kahan summation algorithm*/ +namespace mt +{ + // https:// en.wikipedia.org/wiki/Kahan_summation_algorithm + template + CGPU_EXEC + void fcn_kh_sum(T& sum, T val, T& error) + { + val = val - error; + const auto t = sum + val; + error = (t-sum) - val; + sum = t; + } +} + +/* tapering/cosine */ +namespace mt +{ + // ! calculate fermi low-pass filter alpha parameter + template + CGPU_EXEC + T fcn_coef_tap(const T& r_tap, const T& r_max) + { + // y = cos(coef_tap*(x-x_tap)) + const auto c_i2pi = T(1.570796326794896619231); // pi/2 + return (fcn_is_equal(r_tap, r_max))?T(0):c_i2pi/(r_max - r_tap); + } + + // ! calculate fermi low-pass filter alpha parameter + template + CGPU_EXEC + T fcn_fermi_lpf_alpha(const T& r_cut, const T& dr_0=T(0.25), const T& fr_0=T(1e-02)) + { + // y = 1/(1+exp(alpha*(x^2-x_c^2))) + return log(T(1)/fr_0-T(1))/(::square(r_cut+dr_0)-::square(r_cut)); + } + + // ! fermi low-pass filter value + template + CGPU_EXEC + T fcn_fermi_lpf(const T& alpha, const T& gl2_max, const T& g2) + { + // y = 1/(1+exp(alpha*(x^2-x_c^2))) + return T(1)/(T(1) + ::exp(alpha*(g2 - gl2_max))); + } + + // ! cosine tapering + template + CGPU_EXEC + T fcn_cos_tap(const T& x_tap, const T& coef_tap, const T& x) + { + return (x + CGPU_EXEC + void fcn_apply_cos_tap(const T& x_tap, const T& coef_tap, const T& x, T& y, T& dy) + { + if (x_tap FFT ->exp(2*pi^2*sigma_r^2*g^2) + template + CGPU_EXEC + T fcn_sigma_r_2_sigma_g(const T& sigma_g) + { + return T(1)/(T(6.283185307179586476925)*sigma_g); + } + + // ! plane wave exponential factor + template + CGPU_EXEC + T fcn_n_2pi_sft(const T& x, const T& x_c) + { + return -T(6.283185307179586476925)*(x-x_c); + } + + // in: E_0(keV), Output: lambda (electron wave): Angs + // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 + template + CGPU_EXEC + T fcn_lambda(const T& E_0) + { + const auto emass = T(510.99906); + const auto hc = T(12.3984244); + + return hc/::sqrt(E_0*(T(2)*emass + E_0)); + } + + // in: E_0(keV), Output: gamma(relativistic factor): unitless + // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 + template + CGPU_EXEC + T fcn_gamma(const T& E_0) + { + const auto emass = T(510.99906); + + return T(1) + E_0/emass; + } + + // in: E_0(keV), Output: sigma (Interaction parameter): radians/(kV - Angs) + // E. J. Kirkland - Advanced computing in electron microscopy page: 79 + template + CGPU_EXEC + T fcn_elec_interact_parm_kva(const T& E_0) + { + const auto c_2pi = T(6.283185307179586476925); + const auto emass = T(510.99906); + T x = (emass + E_0)/(T(2)*emass + E_0); + + return c_2pi*x/(fcn_lambda(E_0)*E_0); + } + + // in: E_0(keV), Theta, Output: sigma = gamma*lambda/c_pot_factor: radians/(V - Angs), where c_pot_factor = 47.877645145863056 + // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13, 79, 120 + + template + CGPU_EXEC + T fcn_transf_exp_factor(const T& E_0, const T& theta) + { + return T(1e-3)*fcn_elec_interact_parm_kva(E_0)/::cos(theta); + } + + // reciprocal Angs to radians + // in: theta(mrad), E_0(keV), Output: Angs^-1 + template + CGPU_EXEC + T fcn_rangs_2_rad(const T& E_0, const T& rAngs) + { + return ::asin(rAngs*fcn_lambda(E_0)); + } + + // in: theta(mrad), E_0(keV), Output: Angs^-1 + template + CGPU_EXEC + T fcn_rad_2_rangs(const T& E_0, const T& theta) + { + return ::sin(theta)/fcn_lambda(E_0); + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // hwhm: Half width at half maximum + // sigma: standard deviation + template + CGPU_EXEC + T fcn_hwhm_2_sigma(const T& v) + { + const auto c_hwhm_2_sigma = T(0.84932180028801907); // hwhm to sigma 1/(sqrt(2*log(2))) + + return v*c_hwhm_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // fwhm: Full width at half maximum + // sigma: standard deviation + template + CGPU_EXEC + T fcn_fwhm_2_sigma(const T& v) + { + const auto c_fwhm_2_sigma = T(0.42466090014400953); // fwhm to sigma 1/(2*sqrt(2*log(2))) + + return v*c_fwhm_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // iehwgd: e^-1 half-width value of the Gaussian distribution + // sigma: standard deviation + template + CGPU_EXEC + T fcn_iehwgd_2_sigma(const T& v) + { + const auto c_iehwgd_2_sigma = T(0.70710678118654746); // iehwgd to sigma 1/sqrt(2) + + return v*c_iehwgd_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // sigma: standard deviation + template + CGPU_EXEC + T fcn_rad_2_sigma(const T& E_0, const T& theta) + { + const auto q0 = fcn_rad_2_rangs(E_0, theta); + return fcn_iehwgd_2_sigma(q0); + } + + // E. J. Kirkland - Advanced computing in electron microscopy page: 33 + template + CGPU_EXEC + T fcn_scherzer_defocus(const T& E_0, const T& c_30, T n=1.0) + { + n = ::fmax(n, 1); + const auto lambda = fcn_lambda(E_0); + + return -::copysign(::sqrt((T(2)*n-T(0.5))*::fabs(c_30)*lambda), c_30); + } + + // E. J. Kirkland - Advanced computing in electron microscopy page: 33 + template + CGPU_EXEC + T fcn_scherzer_aperture(const T& E_0, const T& c_30, T n=1.0) + { + n = ::fmax(n, 1); + const auto lambda = fcn_lambda(E_0); + return ::pow(T(4)*(T(2)*n-T(0.5))*lambda/::fabs(c_30), T(0.25)); + } + + // E. J. Kirkland - Advanced computing in electron microscopy page: 33 + template + CGPU_EXEC + void fcn_scherzer_conditions(const T& E_0, const T& c_30, T& defocus, T& aperture) + { + defocus = fcn_scherzer_defocus(E_0, c_30); + + aperture = fcn_scherzer_aperture(E_0, c_30); + } +} + +namespace mt +{ + // ceil - scale size + template + CGPU_EXEC + dt_int32 fcn_sc_size_c(const dt_int32& n, T factor) + { + return max(dt_int32(::ceil(n*factor)), 1); + } + + // ! next power of 2 + CGPU_EXEC + dt_uint64 fcn_next_pow2(dt_uint32 x) + { + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return ++x; + } + + // from bytes to mb + template + CGPU_EXEC + dt_float64 fcn_size_mb(const dt_int64& n) + { + return static_cast(n*sizeof(T)/dt_float64(c_bytes_2_mb)); + } + + // select background option + template + T fcn_select_bg(const eFil_Sel_Typ& bg_opt, const T& v_min, const T& v_max, const T& v_mean, T bg =0) + { + T bg_r = 0; + + switch (bg_opt) + { + case efst_min: + bg_r = v_min; + break; + case efst_max: + bg_r = v_max; + break; + case efst_mean: + bg_r = v_mean; + break; + case efst_min_mean: + bg_r = (v_mean + v_min)/T(2); + break; + case efst_max_mean: + bg_r = (v_mean + v_max)/T(2); + break; + case efst_user_def: + bg_r = bg; + break; + } + + return bg_r; + } + + template + dt_init_list fcn_read_col(T* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + switch(n_c) + { + case 1: + { + return {T(v[ip + 0*n_r])}; + } + case 2: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r])}; + } + case 3: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r])}; + } + case 4: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r])}; + } + case 5: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r])}; + } + case 6: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r])}; + } + case 7: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r])}; + } + case 8: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r]), T(v[ip + 7*n_r])}; + } + case 9: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r]), T(v[ip + 7*n_r]), T(v[ip + 8*n_r])}; + } + case 10: + { + return {T(v[ip + 0*n_r]), T(v[ip + 1*n_r]), T(v[ip + 2*n_r]), T(v[ip + 3*n_r]), T(v[ip + 4*n_r]), T(v[ip + 5*n_r]), T(v[ip + 6*n_r]), T(v[ip + 7*n_r]), T(v[ip + 8*n_r]), T(v[ip + 9*n_r])}; + } + } + } + +} + +/* strings */ +namespace mt +{ + static inline + std::vector fcn_str_split(const std::string& s, char delimiter) + { + std::vector string_elems; + std::istringstream tokenStream(s); + std::string token; + + while (std::getline(tokenStream, token, delimiter)) + { + string_elems.push_back(token); + } + return string_elems; + } + + // to lowercase (in place) + static inline + void fcn_str_2_lower_ip(std::string& str) + { + std::for_each(str.begin(), str.end(), [](auto &v){ v = tolower(v); }); + } + + // to lowercase + static inline + std::string fcn_str_2_lower(std::string str) + { + fcn_str_2_lower_ip(str); + return str; + } + + // to uppercase (in place) + static inline + void fcn_str_2_upper_ip(std::string& str) + { + std::for_each(str.begin(), str.end(), [](auto &v){ v = toupper(v); }); + } + + // to uppercase + static inline + std::string fcn_str_2_upper(std::string str) + { + fcn_str_2_upper_ip(str); + return str; + } + + // trim from start (in place) + static inline + void fcn_str_ltrim_ip(std::string &s) { + s.erase(s.begin(), std::find_if (s.begin(), s.end(), [](dt_int32 ch) + { + return !std::isspace(ch); + })); + } + + // trim from start + static inline + std::string fcn_str_ltrim(std::string s) + { + fcn_str_ltrim_ip(s); + return s; + } + + // trim from end (in place) + static inline + void fcn_str_rtrim_ip(std::string &s) + { + s.erase(std::find_if(s.rbegin(), s.rend(), [](dt_int32 ch) + { + return !std::isspace(ch); + }).base(), s.end()); + } + + // trim from end + static inline + std::string fcn_rtrim(std::string s) + { + fcn_str_rtrim_ip(s); + return s; + } + + // trim from both ends (in place) + static inline + void fcn_str_trim_ip_ip(std::string &s) + { + fcn_str_ltrim_ip(s); + fcn_str_rtrim_ip(s); + } + + // trim from both ends + static inline + std::string fcn_str_trim(std::string s) + { + fcn_str_trim_ip_ip(s); + return s; + } + + // Compare string + static inline + dt_bool fcn_str_cmp(const std::string &s1, const std::string &s2) + { + return (s1.find(s2) != std::string::npos); + } + + void fcn_str_rem_char_not_of(std::string &str, std::string chars) + { + str.erase(remove_if (str.begin(), str.end(), [chars](const auto& v){ return std::all_of(chars.begin(), chars.end(), [v](const auto& a){return a != v; }); }), str.end() ); + } + + void fcn_str_rem_char_of(std::string &str, std::string chars) + { + str.erase(remove_if (str.begin(), str.end(), [chars](const auto& v){ return std::any_of(chars.begin(), chars.end(), [v](const auto& a){return a == v; }); }), str.end() ); + } + +} \ No newline at end of file diff --git a/src/fcns_cpu.h b/src/fcns_cpu.h new file mode 100755 index 00000000..ef8e011e --- /dev/null +++ b/src/fcns_cpu.h @@ -0,0 +1,3151 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "vctr_cpu.h" +#include "kahan_sum.h" +#include "stream_cpu.h" +#include "fft_cpu.h" +#include "fcns_cgpu_gen.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" +#include "cgpu_detail.cuh" +#include "cpu_detail.hpp" +#include "border_2d.h" +#include "region.cuh" +#include "types.cuh" +#include "wd_gauss.h" +#include "wd_exp.h" +#include "wd_fermi.h" +#include "wd_butwth.h" +#include "wd_hann.h" + +/* vector functions */ +namespace mt +{ + /***************************************************************************************/ + template + enable_if_cvctr_cpu_and_rvctr_cpu + fcn_assign_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_real = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin(), cgpu_fctr::assign_real()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_real); + } + + template + enable_if_cvctr_cpu_and_rvctr_cpu + fcn_assign_max_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_max_real = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::assign_max_real(M_v, M_v)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_max_real); + } + + template + enable_if_cvctr_and_rvctr + fcn_assign_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + if (M_v>0) + { + fcn_assign_max_real(mx_i, T(0), mx_o, pstream); + } + else + { + fcn_assign_real(mx_i, mx_o, pstream); + } + } + + template + enable_if_cvctr_cpu_and_rvctr_cpu + fcn_assign_abs_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_abs_real = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::assign_abs_real()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_abs_real); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_assign_abs(TVctr_c& mx_i, TVctr_r& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_assign_abs = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, mx_o.begin() + ithread.ind_0, cgpu_fctr::assign_abs()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_assign_abs); + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu + fcn_fill(TVctr& mx_io, Value_type val, Stream_cpu* pstream = nullptr) + { + auto thr_fill = [&](const iThread_Rect_1d& ithread) + { + thrust::fill(mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_e, val); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_fill); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_scale(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_o.begin() + ithread.ind_0, cgpu_fctr::scale(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_scale); + } + + template + enable_if_vctr_cpu + fcn_scale(const Value_type& w_i, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, cgpu_fctr::scale(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_scale); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_norm_2(TVctr_1& mx_i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_o.begin() + ithread.ind_0, cgpu_fctr::norm_2()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_scale_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_o.begin() + ithread.ind_0, cgpu_fctr::scale_norm_2(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_scale_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_sub(TVctr_1&& mx_1i, TVctr_1&& mx_2i, TVctr_2&& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::sub()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add(TVctr_1&& mx_1i, TVctr_1&& mx_2i, TVctr_2&& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_sub = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_sub); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add(TVctr_1&& mx_i, TVctr_2&& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add); + } + + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale(Value_type w1_i, TVctr_1& mx_1i, + Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add_scale_i(w1_i, w2_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_scale); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add_scale(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add_scale); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_norm_2(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add_norm_2_i()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_norm_2(TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add_norm_2()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale_norm_2(Value_type w1_i, TVctr_1& mx_1i, Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::add_scale_norm_2_i(w1_i, w2_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_add_scale_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_add_scale_norm_2 = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::add_scale_norm_2(w_i)); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_add_scale_norm_2); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_mult(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_mult = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_1i.begin() + ithread.ind_0, mx_1i.begin() + ithread.ind_e, + mx_2i.begin() + ithread.ind_0, mx_o.begin() + ithread.ind_0, cgpu_fctr::mult()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_o.size_32(), thr_mult); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_mult(TVctr_1& mx_i, TVctr_2& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_mult = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_0, cgpu_fctr::mult()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_mult); + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu + fcn_div_sft(Value_type mx_sft, Value_type mx_div, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + auto thr_div_sft = [&](const iThread_Rect_1d& ithread) + { + thrust::transform(mx_io.begin() + ithread.ind_0, mx_io.begin() + ithread.ind_e, mx_io.begin() + ithread.ind_0, cgpu_fctr::div_sft(mx_sft, mx_div));; + }; + + fcn_stream_exec_xd_fcn(pstream, mx_io.size_32(), thr_div_sft); + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu> + fcn_sum(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + KS sum_total = T(0); + + if (pstream == nullptr) + { + sum_total = thrust::reduce(mx_i.begin(), mx_i.end()); + } + else + { + auto thr_sum = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_norm_2(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::norm_2(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_norm_2 = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::norm_2(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_norm_2); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::norm_2_sft(x_sft), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_norm_2_sft = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::norm_2_sft(x_sft), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_norm_2_sft); + } + + return sum_total; + } + + template + enable_if_cvctr_cpu> + fcn_sum_max_real(TVctr& mx_i, Value_type_r v_min, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::assign_max_real(v_min, T_r(0)), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_max_real = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::assign_max_real(v_min, T_r(0)), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_max_real); + } + + return sum_total; + } + + template + enable_if_cvctr_cpu> + fcn_sum_abs_real(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::assign_abs_real(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_abs_real = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::assign_abs_real(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_abs_real); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_abs(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::assign_abs(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_abs = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::assign_abs(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_abs); + } + + return sum_total; + } + + template + enable_if_vctr_cpu> + fcn_sum_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + KS sum_total = T_r(0); + + if (pstream == nullptr) + { + sum_total = thrust::transform_reduce(mx_i.begin(), mx_i.end(), cgpu_fctr::abs_sft(), T_r(0), cgpu_fctr::add()); + } + else + { + auto thr_sum_abs_sft = [&](const iThread_Rect_1d& ithread) + { + auto sum_partial = thrust::transform_reduce(mx_i.begin() + ithread.ind_0, mx_i.begin() + ithread.ind_e, + cgpu_fctr::abs_sft(), T_r(0), cgpu_fctr::add()); + + pstream->stream_mutex.lock(); + sum_total += sum_partial; + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(mx_i.size_32(), thr_sum_abs_sft); + } + + return sum_total; + } + + /***************************************************************************************/ + /* calculate mean */ + template + enable_if_vctr_cpu> + fcn_mean(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum(mx_i, pstream)/T(mx_i.size()); + } + + /* calculate mean of the norm square */ + template + enable_if_vctr_cpu> + fcn_mean_norm_2(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2(mx_i, pstream)/T_r(mx_i.size()); + } + + /* calculate mean of the shifted norm square */ + template + enable_if_vctr_cpu> + fcn_mean_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + template + enable_if_cvctr_cpu> + fcn_mean_max_real(TVctr& mx_i, Value_type_r v_min, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_max_real(mx_i, v_min, pstream)/T(mx_i.size()); + } + + template + enable_if_cvctr_cpu> + fcn_mean_abs_real(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_abs_real(mx_i, pstream)/T(mx_i.size()); + } + + template + enable_if_vctr_cpu> + fcn_mean_abs(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_abs(mx_i, pstream)/T(mx_i.size()); + } + + template + enable_if_vctr_cpu> + fcn_mean_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_cpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_abs_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + /***************************************************************************************/ + /* calculate mean and variance */ + template + enable_if_vctr_cpu + fcn_mean_var(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_var, Stream_cpu* pstream = nullptr) + { + x_mean = fcn_mean(mx_i, pstream); + x_var = fcn_mean_norm_2_sft(mx_i, x_mean, pstream); + } + + /* calculate mean and standard deviation */ + template + enable_if_vctr_cpu + fcn_mean_std(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_std, Stream_cpu* pstream = nullptr) + { + fcn_mean_var(mx_i, x_mean, x_std, pstream); + x_std = ::sqrt(x_std); + } + + // mean and first absolute moment + template + enable_if_vctr_cpu + fcn_mean_moment_1a(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_ma1, Stream_cpu* pstream = nullptr) + { + x_mean = fcn_mean(mx_i, pstream); + x_ma1 = fcn_mean_abs_sft(mx_i, x_mean, pstream); + } + + /* variance */ + template + enable_if_vctr_cpu> + fcn_variance(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_var; + fcn_mean_var(mx_i, x_mean, x_var, pstream); + + return x_var; + } + + /* standard deviation */ + template + enable_if_vctr_cpu> + fcn_std(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + auto x_var = fcn_variance(mx_i, pstream); + + return ::sqrt(x_var); + } + + // first absolute moment + template + enable_if_vctr_cpu> + fcn_moment_1a(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_ma1; + fcn_mean_moment_1a(mx_i, x_mean, x_ma1, pstream); + + return x_ma1; + } + + /***************************************************************************************/ + /* minimum element of a vector */ + template + enable_if_vctr_cpu> + fcn_min_element(const TVctr& x, Stream_cpu* pstream = nullptr) + { + auto x_min = x[0]; + + if (pstream == nullptr) + { + x_min = *thrust::min_element(x.begin(), x.end()); + } + else + { + auto thr_min = [&](const iThread_Rect_1d& ithread) + { + auto x_min_partial = *thrust::min_element(x.begin() + ithread.ind_0, x.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + x_min = fcn_min(x_min, x_min_partial); + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(x.size_32(), thr_min); + } + + return x_min; + } + + /* maximum element of a vector */ + template + enable_if_vctr_cpu> + fcn_max_element(const TVctr& x, Stream_cpu* pstream = nullptr) + { + auto x_max = x[0]; + + if (pstream == nullptr) + { + x_max = *thrust::max_element(x.begin(), x.end()); + } + else + { + auto thr_max = [&](const iThread_Rect_1d& ithread) + { + auto x_max_partial = *thrust::max_element(x.begin() + ithread.ind_0, x.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + x_max = fcn_max(x_max, x_max_partial); + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(x.size_32(), thr_max); + } + + return x_max; + } + + /* minimum and maximum element of a vector */ + template + enable_if_vctr_cpu + fcn_minmax_element(const TVctr& x, Value_type& x_min, Value_type& x_max, Stream_cpu* pstream = nullptr) + { + x_min = x[0]; + x_max = x[0]; + + if (pstream == nullptr) + { + auto x_min_max = thrust::minmax_element(x.begin(), x.end()); + x_min = *(x_min_max.first); + x_max = *(x_min_max.second); + } + else + { + auto thr_min_max = [&](const iThread_Rect_1d& ithread) + { + auto x_min_max_partial = thrust::minmax_element(x.begin() + ithread.ind_0, x.begin() + ithread.ind_e); + + pstream->stream_mutex.lock(); + x_min = fcn_min(x_min, *(x_min_max_partial.first)); + x_max = fcn_max(x_max, *(x_min_max_partial.second)); + pstream->stream_mutex.unlock(); + }; + + pstream->exec_xd_fcn(x.size_32(), thr_min_max); + } + } +} + +/* add - assign - crop - norm_2 - fftsft */ +namespace mt +{ + /* shift matrix respect to nx_h */ + template + enable_if_vctr_cpu + fcn_fftsft_1d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_1d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, cgpu_detail::fcn_fftsft_1d, igrid, mx_io.m_data); + } + + /* shift matrix respect to ny_h */ + template + enable_if_vctr_cpu + fcn_fftsft_bc_2d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny_h, cgpu_detail::fcn_fftsft_bc_2d, igrid, mx_io.m_data); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + //enable_if_vctr_cpu + void fcn_fftsft_2d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + // function fcn_fftsft_2d is overloading + void (*pfcn_fftsft_2d)(const dt_int32&, const dt_int32&, const iGrid_2d&, T*) = &cgpu_detail::fcn_fftsft_2d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, pfcn_fftsft_2d, igrid, mx_io.m_data); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + enable_if_vctr_cpu + fcn_fftsft_2d(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + // function fcn_fftsft_2d is overloading + void (*pfcn_fftsft_2d)(const dt_int32&, const dt_int32&, const iGrid_2d&, T*, T*) = &cgpu_detail::fcn_fftsft_2d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, pfcn_fftsft_2d, igrid, mx_i.m_data, mx_o.m_data); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_cpu + fcn_fftsft_3d(TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_3d(); + + // function fcn_fftsft_3d is overloading + void (*pfcn_fftsft_3d)(const dt_int32&, const dt_int32&, const iGrid_3d&, T*) = &cgpu_detail::fcn_fftsft_3d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, igrid.nz_h, pfcn_fftsft_3d, igrid, mx_io.m_data); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_cpu + fcn_fftsft_3d(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_3d(); + + // function fcn_fftsft_3d is overloading + void (*pfcn_fftsft_3d)(const dt_int32&, const dt_int32&, const iGrid_3d&, T*, T*) = &cgpu_detail::fcn_fftsft_3d; + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, igrid.nz_h, pfcn_fftsft_3d, igrid, mx_i.m_data, mx_o.m_data); + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + enable_if_vctr_cpu + fcn_add_sc_fftsft_2d(TVctr& mx_i, Value_type w, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_fftsft_2d, igrid, mx_i.m_data, w, mx_o.m_data); + } + + /* add, scale, square and shift */ + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_sc_norm_2_fftsft_2d(TVctr_1& mx_i, Value_type w, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_fftsft_2d, igrid, mx_i.m_data, w, mx_o.m_data); + } + + /***************************************************************************************/ + /* assign and crop */ + template + enable_if_vctr_cpu + fcn_assign_crop_2d(TVctr& mx_i, TVctr& mx_o, iRegion_Rect_2d& iregion, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_assign_crop_2d, igrid, mx_i.m_data, iregion, mx_o.m_data); + } + + /* assign, crop and shift */ + template + enable_if_vctr_cpu + fcn_assign_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_assign_crop_fftsft_2d, igrid, mx_i.m_data, iregion, mx_o.m_data); + } + + /* add, scale, crop and shift */ + template + enable_if_vctr_cpu + fcn_add_sc_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h,cgpu_detail::fcn_add_sc_crop_fftsft_2d, igrid, mx_i.m_data, iregion, w, mx_o.m_data); + } + + /* add, scale, square, crop and shift */ + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_sc_norm_2_crop_fftsft_2d(TVctr_1& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr_2& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_crop_fftsft_2d, igrid, mx_i.m_data, iregion, w, mx_o.m_data); + } +} + +/* transpose - element wise matrix op vector */ +namespace mt +{ + /* transpose */ + template + enable_if_vctr_cpu>> + fcn_trs_2d(TVctr& mx_i, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + Vctr_cpu mx_t(mx_i.shape_2d_trs()); + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d, igrid, mx_i.m_data, mx_t.m_data); + + return mx_t; + } + + /* transpose */ + template + enable_if_vctr_cpu + fcn_trs_2d(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + if (&mx_i != &mx_o) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d, igrid, mx_i.m_data, mx_o.m_data); + } + else + { + Vctr_cpu mx_t(mx_i.shape_2d_trs()); + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d, igrid, mx_i.m_data, mx_t.m_data); + mx_t.cpy_to_cpu_ptr(mx_o.m_data, mx_o.size()); + } + + } + + /* element wise addition: matrix + vector*/ + template + enable_if_vctr_cpu + fcn_ew_add_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_col, igrid, vctr.m_data, mx_io.m_data); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_row, igrid, vctr.m_data, mx_io.m_data); + } + } + + /* element wise subtraction: matrix - vector */ + template + enable_if_vctr_cpu + fcn_ew_sub_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_col, igrid, vctr.m_data, mx_io.m_data); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_row, igrid, vctr.m_data, mx_io.m_data); + } + } + + /* element wise multiplication matrix X vector */ + template + enable_if_vctr_cpu + fcn_ew_mult_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_col, igrid, vctr.m_data, mx_io.m_data); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_row, igrid, vctr.m_data, mx_io.m_data); + } + } +} + +/* aperture functions */ +namespace mt +{ + template + enable_if_vctr_cpu + fcn_fermi_aperture(Grid_2d& grid, T g2_cut, T alpha, T w, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fermi_aperture, grid, g2_cut, alpha, w, mx_io.m_data); + } + + template + enable_if_vctr_cpu + fcn_hard_aperture(Grid_2d& grid, T g2_cut, T w, TVctr& mx_io, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_hard_aperture, grid, g2_cut, w, mx_io.m_data); + } +} + +/* phase shifts real space*/ +namespace mt +{ + template + enable_if_vctr_cpu + fcn_rs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T gx, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_rs_exp_factor_1d, grid, psi_i.m_data, gx, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &gy, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d_bc, grid, alpha, psi_i.m_data, gy.m_data, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu + fcn_rs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d g, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d, grid, psi_i.m_data, g, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& g, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_mul_exp_factor_2d, grid, psi_i.m_data, g.m_data, w, psi_o.m_data); + } +} + +/* phase shifts fourier space*/ +namespace mt +{ + template + enable_if_vctr_cpu + fcn_fs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T rx, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_fs_exp_factor_1d, grid, psi_i.m_data, rx, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_fs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &ry, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d_bc, grid, alpha, psi_i.m_data, ry.m_data, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu + fcn_fs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d r, T w, TVctr& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d, grid, psi_i.m_data, r, w, psi_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_fs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& r, T w, TVctr_c& psi_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_mul_exp_factor_2d, grid, psi_i.m_data, r.m_data, w, psi_o.m_data); + } +} + +/* gradient */ +namespace mt +{ + template + enable_if_vctr_cpu + fcn_grad_x(TVctr& mx_i, TVctr& dmx_x, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_grad_x, igrid, mx_i.m_data, dmx_x.m_data); + } + + template + enable_if_vctr_cpu + fcn_grad_y(TVctr& mx_i, TVctr& dmx_y, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_grad_y, igrid, mx_i.m_data, dmx_y.m_data); + } + + template + enable_if_vctr_cpu + fcn_grad(TVctr& mx_i, TVctr& dmx_x, TVctr& dmx_y, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_grad, igrid, mx_i.m_data, dmx_x.m_data, dmx_y.m_data); + } +} + +/* function multiplication fourier space */ +namespace mt +{ + #define FCN_MULT_FS_FCN_CPU(FN, FCN, POW, DIM) \ + template \ + enable_if_vctr_cpu \ + fcn_mult_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, T w, TVctr_c& mx_io, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_mult_fs_fcn_g##POW##_##DIM##d>, grid, fcn, w, mx_io.m_data); \ + } + + /* gaussian */ + FCN_MULT_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 1); // fcn_mult_fs_gauss_1d + FCN_MULT_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 2); // fcn_mult_fs_gauss_2d + FCN_MULT_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 3); // fcn_mult_fs_gauss_3d + + /* exponential */ + FCN_MULT_FS_FCN_CPU(exp, Fcn_Exp, , 1); // fcn_mult_fs_exp_1d + FCN_MULT_FS_FCN_CPU(exp, Fcn_Exp, , 2); // fcn_mult_fs_exp_2d + FCN_MULT_FS_FCN_CPU(exp, Fcn_Exp, , 3); // fcn_mult_fs_exp_3d + + /* fermi */ + FCN_MULT_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 1); // fcn_mult_fs_fermi_1d + FCN_MULT_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 2); // fcn_mult_fs_fermi_2d + FCN_MULT_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 3); // fcn_mult_fs_fermi_3d + + /* butterworth */ + FCN_MULT_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 1); // fcn_mult_fs_butwth_1d + FCN_MULT_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 2); // fcn_mult_fs_butwth_2d + FCN_MULT_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 3); // fcn_mult_fs_butwth_3d + + /* hann */ + FCN_MULT_FS_FCN_CPU(hann, Fcn_Hann, , 1); // fcn_mult_fs_hann_1d + FCN_MULT_FS_FCN_CPU(hann, Fcn_Hann, , 2); // fcn_mult_fs_hann_2d + FCN_MULT_FS_FCN_CPU(hann, Fcn_Hann, , 3); // fcn_mult_fs_hann_3d +} + +/* convolution */ +namespace mt +{ + #define FCN_CV_FS_FCN_CPU(FN, FCN, POW, DIM) \ + template \ + enable_if_cvctr_cpu \ + fcn_cv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_cpu& fft, FCN& fcn, TVctr_c& mx_io, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_mult_fs_fcn_g##POW##_##DIM##d>, grid, fcn, w, mx_io.m_data); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_CV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 1); // fcn_cv_fs_gauss_1d + FCN_CV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 2); // fcn_cv_fs_gauss_2d + FCN_CV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 3); // fcn_cv_fs_gauss_3d + + /* exponential convolution */ + FCN_CV_FS_FCN_CPU(exp, Fcn_Exp, , 1); // fcn_cv_fs_exp_1d + FCN_CV_FS_FCN_CPU(exp, Fcn_Exp, , 2); // fcn_cv_fs_exp_2d + FCN_CV_FS_FCN_CPU(exp, Fcn_Exp, , 3); // fcn_cv_fs_exp_3d + + /* fermi convolution */ + FCN_CV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 1); // fcn_cv_fs_fermi_1d + FCN_CV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 2); // fcn_cv_fs_fermi_2d + FCN_CV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 3); // fcn_cv_fs_fermi_3d + + /* butterworth convolution */ + FCN_CV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 1); // fcn_cv_fs_butwth_1d + FCN_CV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 2); // fcn_cv_fs_butwth_2d + FCN_CV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 3); // fcn_cv_fs_butwth_3d + + /* hann convolution */ + FCN_CV_FS_FCN_CPU(hann, Fcn_Hann, , 1); // fcn_cv_fs_hann_1d + FCN_CV_FS_FCN_CPU(hann, Fcn_Hann, , 2); // fcn_cv_fs_hann_2d + FCN_CV_FS_FCN_CPU(hann, Fcn_Hann, , 3); // fcn_cv_fs_hann_3d +} + +/* deconvolution */ +namespace mt +{ + #define FCN_DCV_FS_FCN_CPU(FN, FCN, POW, DIM) \ + template \ + enable_if_cvctr_cpu \ + fcn_dcv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_cpu& fft, FCN& fcn, T psnr, TVctr_c& mx_io, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_dcv_fs_fcn_g##POW##_##DIM##d>, grid, fcn, psnr, w, mx_io.m_data); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_DCV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 1); // fcn_dcv_fs_gauss_1d + FCN_DCV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 2); // fcn_dcv_fs_gauss_2d + FCN_DCV_FS_FCN_CPU(gauss, Fcn_Gauss, 2, 3); // fcn_dcv_fs_gauss_3d + + /* exponential convolution */ + FCN_DCV_FS_FCN_CPU(exp, Fcn_Exp, , 1); // fcn_dcv_fs_exp_1d + FCN_DCV_FS_FCN_CPU(exp, Fcn_Exp, , 2); // fcn_dcv_fs_exp_2d + FCN_DCV_FS_FCN_CPU(exp, Fcn_Exp, , 3); // fcn_dcv_fs_exp_3d + + /* fermi convolution */ + FCN_DCV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 1); // fcn_dcv_fs_fermi_1d + FCN_DCV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 2); // fcn_dcv_fs_fermi_2d + FCN_DCV_FS_FCN_CPU(fermi, Fcn_Fermi, 2, 3); // fcn_dcv_fs_fermi_3d + + /* butterworth convolution */ + FCN_DCV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 1); // fcn_dcv_fs_butwth_1d + FCN_DCV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 2); // fcn_dcv_fs_butwth_2d + FCN_DCV_FS_FCN_CPU(butwth, Fcn_Butwth, 2, 3); // fcn_dcv_fs_butwth_3d + + /* hann convolution */ + FCN_DCV_FS_FCN_CPU(hann, Fcn_Hann, , 1); // fcn_dcv_fs_hann_1d + FCN_DCV_FS_FCN_CPU(hann, Fcn_Hann, , 2); // fcn_dcv_fs_hann_2d + FCN_DCV_FS_FCN_CPU(hann, Fcn_Hann, , 3); // fcn_dcv_fs_hann_3d +} + +/* window functions */ +namespace mt +{ + //template + //enable_if_vctr_cpu + //fcn_wd_fcn_xd(Grid_xd& grid, Wd_fcn_xd& fcn, dt_bool sft, TVctr& mx_o, Stream_cpu* pstream = nullptr) + //{ + // using U = Value_type; + // + // if (sft) + // { + // fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_sft_xd, grid, fcn, mx_o.m_data); + // } + // else + // { + // fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_xd, grid, fcn, mx_o.m_data) + // } + //} + + // FCN_WD_FCN_CPU(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + // FCN_WD_FCN_CPU(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + // FCN_WD_FCN_CPU(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + // FCN_WD_FCN_CPU(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + // FCN_WD_FCN_CPU(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + // FCN_WD_FCN_CPU(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + // FCN_WD_FCN_CPU(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + // FCN_WD_FCN_CPU(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + // FCN_WD_FCN_CPU(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + // FCN_WD_FCN_CPU(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + // FCN_WD_FCN_CPU(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + // FCN_WD_FCN_CPU(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + // FCN_WD_FCN_CPU(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + // FCN_WD_FCN_CPU(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + // FCN_WD_FCN_CPU(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d + + #define FCN_WD_FCN_CPU(FN, FCN, DIM) \ + template \ + enable_if_vctr_cpu \ + fcn_wd_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, dt_bool sft, TVctr& mx_o, Stream_cpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + if (sft) \ + { \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_sft_##DIM##d>, grid, fcn, mx_o.m_data); \ + } \ + else \ + { \ + fcn_stream_exec_xd_krn(pstream, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_##DIM##d>, grid, fcn, mx_o.m_data); \ + } \ + } + + FCN_WD_FCN_CPU(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + FCN_WD_FCN_CPU(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + FCN_WD_FCN_CPU(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + FCN_WD_FCN_CPU(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + FCN_WD_FCN_CPU(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + FCN_WD_FCN_CPU(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + FCN_WD_FCN_CPU(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + FCN_WD_FCN_CPU(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + FCN_WD_FCN_CPU(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + FCN_WD_FCN_CPU(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + FCN_WD_FCN_CPU(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + FCN_WD_FCN_CPU(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + FCN_WD_FCN_CPU(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + FCN_WD_FCN_CPU(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + FCN_WD_FCN_CPU(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d +} + +/* phase correlation */ +namespace mt +{ + /****************** pcf data processing real space *******************/ + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Butwth_1d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_rs_pcf_1d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Butwth_2d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_rs_pcf_2d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_rs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Butwth_3d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_rs_pcf_3d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + /***************** pcf data processing fourier space *****************/ + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Gauss_1d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, cgpu_detail::fcn_fs_pcf_1d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Gauss_2d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_fs_pcf_2d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Gauss_3d& fcn, T w, TVctr_c& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_fs_pcf_3d_dp, grid, mx_i.m_data, fcn, w, mx_o.m_data); + } +} + +/* optical flow */ +namespace mt +{ + template + enable_if_vctr_cpu + fcn_opt_flow(TVctr& mx_s, TVctr& mx_m, T alpha, TVctr& dphi_x, TVctr& dphi_y, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + auto igrid = mx_s.igrid_2d(); + + fcn_stream_exec_xd_krn(pstream, igrid.nx, igrid.ny, cgpu_detail::fcn_opt_flow, igrid, mx_s.m_data, mx_m.m_data, alpha, dphi_x.m_data, dphi_y.m_data); + } +} + +/* bilinear interpolation */ +namespace mt +{ + template + enable_if_vctr_cpu + fcn_intrpl_bl_rg_2d(Grid_2d& grid, TVctr& mx_i, TVctr& vx, TVctr& vy, T bg, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using U = Value_type; + + fcn_stream_exec_xd_krn(pstream, grid.nx, grid.ny, cgpu_detail::fcn_intrpl_bl_rg_2d, grid, mx_i.m_data, vx.m_data, vy.m_data, bg, mx_o.m_data); + } +} + +/* histogram */ +namespace mt +{ + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_hist(const TVctr_1& vctr, const Value_type& n_bins, TVctr_2& y, TVctr_2& x) + { + using T1 = Value_type; + using T2 = Value_type; + using size_type = Size_type; + + T1 vctr_min = 0; + T1 vctr_max = 0; + fcn_minmax_element(vctr, vctr_min, vctr_max); + auto dv = dt_float64(vctr_max-vctr_min)/dt_float64(n_bins); + + fcn_fill(y, T2(0)); + + const auto vctr_size = vctr.size(); + + for(size_type iv = 0; iv< vctr_size; iv++) + { + auto val = dt_float64(vctr[iv]); + auto iy = fcn_bcfloor((val - dt_float64(vctr_min))/dv, size_type(0), size_type(n_bins-1)); + y[iy]++; + } + + for(size_type ix = 0; ix < n_bins; ix++) + { + x[ix] = T2(vctr_min + dt_float64(ix)*dv); + } + } +} + +/* anscombe transform */ +namespace mt +{ + /* forward anscombe transform */ + template + enable_if_vctr_cpu + fcn_anscombe(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto thr_anscombe_fwd = [](const iThread_Rect_1d& ithread, pVctr_cpu_32& mx_i, pVctr_cpu_32& mx_o) + { + thrust::transform(mx_i.begin()+ithread.ind_0, mx_i.begin()+ithread.ind_e, + mx_o.begin()+ithread.ind_0, cgpu_fctr::anscombe_fwd()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_i.size_32(), thr_anscombe_fwd, mx_i.ptr_32(), mx_o.ptr_32()); + } + + /* forward anscombe transform */ + template + enable_if_vctr_cpu + fcn_anscombe_inv(TVctr& mx_i, TVctr& mx_o, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto thr_anscombe_inv = [](const iThread_Rect_1d& ithread, pVctr_cpu_32& mx_i, pVctr_cpu_32& mx_o) + { + thrust::transform(mx_i.begin()+ithread.ind_0, mx_i.begin()+ithread.ind_e, + mx_o.begin()+ithread.ind_0, cgpu_fctr::anscombe_inv()); + }; + + fcn_stream_exec_xd_fcn(pstream, mx_i.size_32(), thr_anscombe_inv, mx_i.ptr_32(), mx_o.ptr_32()); + } +} + +/* border */ +namespace mt +{ + /* replace border */ + template + enable_if_vctr_cpu>> + fcn_repl_bdr(TVctr& mx_i, iBorder_Rect_2d& iborder, eFil_Sel_Typ bg_opt=efst_min, Value_type bg=0, Stream_cpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + iRegion_Rect_2d iregion({iborder.bx_0, igrid.nx - iborder.bx_e, iborder.by_0, igrid.ny - iborder.by_e}); + + dt_int32 ic = 0; + T v_min = mx_i(iregion.ry_0, iregion.rx_0); + T v_max = v_min; + KS v_mean = 0; + + Vctr_cpu mx_o(mx_i); + + if (bg_opt<6) + { + for(auto ix = iregion.rx_0; ix < iregion.rx_e; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto v = mx_i(iy, ix); + v_min = fcn_min(v_min, v); + v_max = fcn_max(v_max, v); + v_mean += dt_float64(v); + ic++; + } + } + v_mean = v_mean/T(ic); + } + + auto val_f = fcn_select_bg(bg_opt, v_min, v_max, T(v_mean()), bg); + + // left + for(auto ix = 0; ix < iregion.rx_0; ix++) + { + for(auto iy = 0; iy < igrid.ny; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + // right + for(auto ix = iregion.rx_e; ix < igrid.nx; ix++) + { + for(auto iy = 0; iy < igrid.ny; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + // top + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = 0; iy < iregion.ry_0; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + // bottom + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = iregion.ry_e; iy < igrid.ny; iy++) + { + mx_o(iy, ix) = val_f; + } + } + + return mx_o; + } + + /* add pbc border */ + template + enable_if_vctr_cpu>> + fcn_add_pbdr(TVctr& mx_i, iBorder_Rect_2d& iborder) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + iRegion_Rect_2d iregion({iborder.bx_0, igrid.nx + iborder.bx_0, iborder.by_0, igrid.ny + iborder.by_0}); + + Vctr_cpu mx_o(dt_shape(igrid.ny + iborder.by_sum(), igrid.nx + iborder.bx_sum())); + igrid.set_size(mx_o.s1_32(), mx_o.s0_32()); + + // copy central mx_i + for(auto ix = iregion.rx_0; ix < iregion.rx_e; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto ix_i = ix - iregion.rx_0; + const auto iy_i = iy - iregion.ry_0; + mx_o(iy, ix) = mx_i(iy_i, ix_i); + } + } + + // left + for(auto ix = 0; ix < iregion.rx_0; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto ix_i = 2*iregion.rx_0 - ix; + mx_o(iy, ix) = mx_o(iy, ix_i); + } + } + + // right + for(auto ix = iregion.rx_e; ix < igrid.nx; ix++) + { + for(auto iy = iregion.ry_0; iy < iregion.ry_e; iy++) + { + const auto ix_i = max(0, iregion.rx_e - 1 - (ix - iregion.rx_e)); + mx_o(iy, ix) = mx_o(iy, ix_i); + } + } + + // top + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = 0; iy < iregion.ry_0; iy++) + { + const auto iy_i = 2*iregion.ry_0 - iy; + mx_o(iy, ix) = mx_o(iy_i, ix); + } + } + + // bottom + for(auto ix = 0; ix < igrid.nx; ix++) + { + for(auto iy = iregion.ry_e; iy < igrid.ny; iy++) + { + const auto iy_i = max(0, iregion.ry_e - 1 - (iy - iregion.ry_e)); + mx_o(iy, ix) = mx_o(iy_i, ix); + } + } + + return mx_o; + } +} + +/* radial distribution */ +namespace mt +{ + // radial distribution: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist(TVctr& r_i, TVctr& fr_i, Value_type r_0, Value_type r_e, + dt_int32 n_r, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ, const TFcn& fcn) + { + using T = Value_type; + + const T dr = (r_e-r_0)/T(n_r); + + for(auto ir = 0; ir < n_r; ir++) + { + rl_o[ir] = r_0 + T(ir)*dr; + frl_o[ir] = T(0); + cfrl_o[ir] = T(0); + } + + for(auto ir = 0; ir < r_i.size(); ir++) + { + const auto r = r_i[ir]; + if (fcn_chk_bound(r, r_0, r_e)) + { + const auto ik = fcn(r); + frl_o[ik] += fr_i[ir]; + cfrl_o[ik] += T(1); + } + } + + if ((typ == 0) || (typ == 2)) + { + for(auto ir = 0; ir < n_r; ir++) + { + frl_o[ir] /= fcn_max(T(1), cfrl_o[ir]); + } + } + + if (typ > 1) + { + for(auto ir = 1; ir < n_r; ir++) + { + frl_o[ir] += frl_o[ir - 1]; + } + } + } + + // radial distribution by division: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist_by_div(TVctr& r_i, TVctr& fr_i, Value_type r_0, Value_type r_e, + dt_int32 n_r, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + const T dr = (r_e-r_0)/T(n_r); + + cgpu_fctr::rad_dist_ind_by_div fcn(r_0, dr, 0, n_r-1); + + fcn_rad_dist(r_i, fr_i, r_0, r_e, n_r, rl_o, frl_o, cfrl_o, typ, fcn); + } + + // radial distribution by search: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist_by_srch(TVctr& r_i, TVctr& fr_i, Value_type r_0, Value_type r_e, + dt_int32 n_r, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + + cgpu_fctr::rad_dist_ind_by_srch fcn(rl_o.data(), 0, n_r-1); + + fcn_rad_dist(r_i, fr_i, r_0, r_e, n_r, rl_o, frl_o, cfrl_o, typ, fcn); + } +} + +/* radial distribution 2d */ +namespace mt +{ + // radial distribution 2d: typ = 0; % 0: sum(v)/n, 1: sum(v), 2: cumsum(sum(v)/n), 3: cumsum(sum(v)) + template + enable_if_vctr_cpu + fcn_rad_dist_2d(Grid_2d>& grid, TVctr& mx_i, R_2d> p_c, + Value_type radius_i, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ, const TFcn& fcn) + { + using T = Value_type; + + dt_int32 ix_0, ix_e; + grid.ix_0_ix_e(p_c.x, radius_i, ix_0, ix_e); + + dt_int32 iy_0, iy_e; + grid.iy_0_iy_e(p_c.y, radius_i, iy_0, iy_e); + + const auto r2_max = ::square(radius_i); + const auto dr = grid.drx; + + for(auto ir = 0; ir < rl_o.size(); ir++) + { + rl_o[ir] = grid.rx(ir); + frl_o[ir] = T(0); + cfrl_o[ir] = T(0); + } + + for(auto ix = ix_0; ix < ix_e; ix++) + { + for(auto iy = iy_0; iy < iy_e; iy++) + { + const auto r2 = grid.r2(ix, iy, p_c); + if (r2 < r2_max) + { + const auto ir = fcn(::sqrt(r2)); + frl_o[ir] += mx_i[grid.sub_2_ind(ix, iy)]; + cfrl_o[ir] += T(1); + } + } + } + + if ((typ == 0) || (typ == 2)) + { + for(auto ir = 0; ir < rl_o.size(); ir++) + { + frl_o[ir] /= fcn_max(T(1), cfrl_o[ir]); + } + } + + if (typ > 1) + { + for(auto ir = 1; ir < rl_o.size(); ir++) + { + frl_o[ir] += frl_o[ir - 1]; + } + } + } + + + // radial distribution 2d by division + template + enable_if_vctr_cpu + fcn_rad_dist_2d_by_div(Grid_2d>& grid, TVctr& mx_i, R_2d> p_c, + Value_type radius_i, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + + cgpu_fctr::rad_dist_ind_by_div fcn(0, grid.drx, 0, rl_o.size()-1); + + fcn_rad_dist_2d(grid, mx_i, p_c, radius_i, rl_o, frl_o, cfrl_o, typ, fcn); + } + + // radial distribution 2d by search + template + enable_if_vctr_cpu + fcn_rad_dist_2d_by_srch(Grid_2d>& grid, TVctr& mx_i, R_2d> p_c, + Value_type radius_i, TVctr& rl_o, TVctr& frl_o, TVctr& cfrl_o, dt_int32 typ) + { + using T = Value_type; + + cgpu_fctr::rad_dist_ind_by_srch fcn(rl_o.data(), 0, rl_o.size()-1); + + fcn_rad_dist_2d(grid, mx_i, p_c, radius_i, rl_o, frl_o, cfrl_o, typ, fcn); + } +} + +/* information limit for regular grid */ +namespace mt +{ + /* filter mean */ + namespace cpu_fcn_image + { + /* 1d */ + template + enable_if_vctr_cpu + fltr_mean_1d(TVctr& mx_i, dt_int32 n_kr, TVctr& mx_o, Stream_cpu* pstream); + } + + template + Value_type fcn_info_lim_2d(TGrid& grid, TVctr& mx_i) + { + using T = Value_type; + + const auto r_c = grid.bs_h(); + const auto radius = grid.bs_h_min(); + const auto n_r = fcn_min(grid.nx_h, grid.ny_h); + + Vctr_cpu r(n_r); + Vctr_cpu fr(n_r); + Vctr_cpu cfr(n_r); + + // cumulative radial integration + fcn_rad_dist_2d_by_div(grid, mx_i.ptr_64(), r_c, grid.bs_h_min(), r.ptr_64(), fr.ptr_64(), cfr.ptr_64(), 2); + + // shift and normalize + const T r_0 = r.front(); + const T fr_0 = fr.front(); + const T dr = r.back() - r_0; + const T dfr = fr.back() - fr_0; + for(auto ir = 0; ir < fr.size(); ir++) + { + r[ir] = (r[ir] - r_0)/dr; + fr[ir] = (fr[ir] - fr_0)/dfr; + } + + // fcn_smooth_mean_1d data + const dt_int32 nkr = max(5, fr.size()/100); + cpu_fcn_image::fltr_mean_1d(fr, nkr, cfr); + fr = cfr; + + // get maximum curvature point + dt_int32 ir_m = 0; + auto d_max = fcn_get_max_crv_2_ln_dist(r.front(), fr.front(), r.back(), fr.back(), 0, r.size(), r.data(), fr.data(), ir_m); + + return grid.rx(ir_m); + } +} + +/* unique / match vector */ +namespace mt +{ + template + enable_if_vctr_cpu + fcn_uniq_vctr(TVctr& vctr) + { + using T = Value_type; + + std::sort(vctr.begin(), vctr.end()); + const auto size = std::distance(vctr.begin(), std::unique(vctr.begin(), vctr.end(), mt::fcn_is_equal)); + + if (vctr.s0()==1) + { + vctr.resize({1, size}); + } + else + { + vctr.resize({size, 1}); + } + } + + template + enable_if_vctr_cpu + fcn_match_vctr(InputIterator v_first, InputIterator v_last, TVctr& vs, Value_type dv=0.1) + { + using T = Value_type; + + TVctr vr(v_first, v_last); + + // find min and max values + T v_min, v_max; + fcn_minmax_element(vr, v_min, v_max); + + // add tolerance + v_min -= dv; + v_max += dv; + + // remove elements of vs outside the ithread + auto fcn_rm = [v_min, v_max](T a)->dt_bool + { + return ((a < v_min) || (a > v_max)); + }; + + const auto size = std::distance(vr.begin(), std::remove_if(vs.begin(), vs.end(), fcn_rm)); + vr.resize(size); + + vs.erase(std::remove_if(vs.begin(), vs.end(), fcn_rm), vs.end()); + + Vctr v_c(vr.size(), true); + dt_int32 m_size = min(vr.size(), vs.size()); + TVctr A_d; + A_d.reserve(m_size); + + for(auto i = 0; i < vs.size(); i++) + { + T val = vs[i]; + auto it = std::min_element(vr.begin(), vr.end(), cgpu_fctr::closest_element(val)); + auto imin = static_cast(it - vr.begin()); + + if (v_c[imin]) + { + v_c[imin] = false; + A_d.push_back(*it); + } + } + vs = A_d; + vs.shrink_to_fit(); + } +} + +namespace mt +{ + // /***************************************************************************************/ + // /***************************************************************************************/ + // template + // enable_if_vctr_cpu_and_vctr_cpu + // cpy_to_host(Stream_cpu& stream, TVctr_i &mx_i, TVctr_o &mx_o, + // TVctr_i *M_i_h = nullptr) + // { + // mt::assign(mx_i, mx_o, M_i_h); + // } + + // template + // enable_if_vctr_cpu_and_vctr_cpu + // add_sc_to_host(Stream_cpu& stream, Value_type w_i, + // TVctr_i &mx_i, TVctr_o &mx_o, TVctr_i *M_i_h = nullptr) + // { + // mt::add_scale(stream, w_i, mx_i, mx_o); + // } + + // template + // enable_if_vctr_cpu_and_vctr_cpu + // add_sc_square_to_host(Stream_cpu& stream, Value_type w_i, + // TVctr_i &mx_i, TVctr_o &mx_o, TVctr_i *M_i_h = nullptr) + // { + // mt::add_scale_norm_2(stream, w_i, mx_i, mx_o); + // } + + // template + // enable_if_vctr_cpu_and_vctr_cpu + // add_sc_m2psi_psi_to_host(Stream_cpu& stream, Value_type w_i, + // TVctr_c_i &psi_i, TVctr_r_o &m2psi_o, TVctr_c_o &psi_o, TVctr_c_i *psi_i_h = nullptr) + // { + // mt::add_scale(stream, w_i, psi_i, psi_o); + // mt::add_scale_norm_2(stream, w_i, psi_i, m2psi_o); + // } + // /***************************************************************************************/ + // /***************************************************************************************/ + // template + // TVctr lsf_poly_n(TVctr& x, TVctr& y, dt_int32 n) + // { + // using T = Value_type; + + // dt_int32 m = x.size(); + // n++; // add bias term + + // TVctr M(m*n); + // for(auto in = 0; in < n; in++) + // { + // for(auto im = 0; im < m; im++) + // { + // M[in*m + im] = (in == 0)?1:x[im] * M[(in - 1)*m + im]; + // } + // } + + // TVctr coef(n); + // lapack::GELS gels; + // gels(m, n, M.data(), 1, y.data(), coef.data()); + + // return coef; + // } + + // /***************************************************************************************/ + // // extract region ix_0<=x + // TVctr_o extract_region_real_part(Stream_cpu& stream, dt_int32 nx_src, dt_int32 ny_src, + // TVctr_i &Im_src, dt_int32 ix0_src, dt_int32 ixe_src, dt_int32 iy0_src, dt_int32 iye_src) + // { + // auto nx_dst = ixe_src - ix0_src; + // auto ny_dst = iye_src - iy0_src; + + // TVctr_o Im_dst(nx_dst*ny_dst); + + // auto thr_extract_region = [&](const iRegion_Rect_2d& ithread) + // { + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + // { + // Im_dst[ix*ny_dst + iy] = Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)].real(); + // } + // } + // }; + + // stream.set_n_stream_act(nx_dst); + // stream.set_grid(nx_dst, ny_dst); + // stream.exec_xd_fcn(thr_extract_region); + + // return Im_dst; + // } + + // // extract real part of vector + // template + // TVctr_o extract_real_part(Stream_cpu& stream, TVctr_i &Im_src) + // { + // TVctr_o Im_dst(Im_src.size()); + + // auto thr_extract_real = [](const iThread_Rect_2d& ithread, TVctr_i &Im_src, TVctr_o &Im_dst) + // { + // for(auto ixy = ithread.ind_0; ixy < ithread.ind_e; ixy++) + // { + // Im_dst[ixy] = Im_src[ixy].real(); + // } + // }; + + // stream.set_n_stream_act(Im_src.size()); + // stream.set_grid(Im_src.size(), 1); + // stream.exec_xd_fcn(thr_extract_real, Im_src, Im_dst); + + // return Im_dst; + // } + + // // extract region ix_0<=x + // TVctr_o extract_region_abs(Stream_cpu& stream, dt_int32 nx_src, dt_int32 ny_src, + // TVctr_i &Im_src, dt_int32 ix0_src, dt_int32 ixe_src, dt_int32 iy0_src, dt_int32 iye_src) + // { + // auto nx_dst = ixe_src - ix0_src; + // auto ny_dst = iye_src - iy0_src; + + // TVctr_o Im_dst(nx_dst*ny_dst); + + // auto thr_extract_region = [&](const iThread_Rect_2d& ithread) + // { + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + // { + // Im_dst[ix*ny_dst + iy] = fabs(Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)]); + // } + // } + // }; + + // stream.set_n_stream_act(nx_dst); + // stream.set_grid(nx_dst, ny_dst); + // stream.exec_xd_fcn(thr_extract_region); + + // return Im_dst; + // } + + // // extract abs of vector + // template + // TVctr_o extract_abs(Stream_cpu& stream, TVctr_i &Im_src) + // { + // TVctr_o Im_dst(Im_src.size()); + + // auto thr_extract_abs = [](const iThread_Rect_2d& ithread, TVctr_i &Im_src, TVctr_o &Im_dst) + // { + // for(auto ixy = ithread.ind_0; ixy < ithread.ind_e; ixy++) + // { + // Im_dst[ixy] = fabs(Im_src[ixy]); + // } + // }; + + // stream.set_n_stream_act(Im_src.size()); + // stream.set_grid(Im_src.size(), 1); + // stream.exec_xd_fcn(thr_extract_abs, Im_src, Im_dst); + + // return Im_dst; + // } + + // /***************************************************************************************/ + // // get weighted position + // template + // R_2d> Rx_Ry_weight(TGrid& grid_2d, TVctr& Im, R_2d> p_i, Value_type radius_i, dt_bool env) + // { + // using T = Value_type; + + // T dR = grid_2d.drx; + // dt_int32 nrl = static_cast(::floor(radius_i/dR + 0.5)); + // T R_max = dR*nrl; + + // auto ix_i = static_cast(::floor(p_i.x/dR)); + // dt_int32 ix_0 = max(ix_i - nrl, 0); + // dt_int32 ix_e = min(ix_i + nrl + 1, grid_2d.nx); + + // auto iy_i = static_cast(::floor(p_i.y/dR)); + // dt_int32 iy_0 = max(iy_i - nrl, 0); + // dt_int32 iy_e = min(iy_i + nrl + 1, grid_2d.ny); + + // T R2_max = pow(R_max, 2); + + // R_2d p(0, 0); + + // T alpha = 0.5/pow(R_max, 2); + // T wt = 0; + // for(auto ix = ix_0; ix < ix_e; ix++) + // { + // for(auto iy = iy_0; iy < iy_e; iy++) + // { + // auto R2 = grid_2d.r2(ix, iy, p_i.x, p_i.y); + // if (R2 < R2_max) + // { + // dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + // auto imv = ((env)?exp(-alpha*R2):1)*Im[ixy]; + // p += imv*R_2d(grid_2d.rx(ix), grid_2d.ry(iy)); + // wt += imv; + // } + // } + // } + // p /= wt; + + // if (norm(p - p_i) >= radius_i) + // { + // p = p_i; + // } + + // return p; + // } + + // // fit gaussian 1d + // template + // TVctr fit_gauss_1d(TGrid& grid_1d, TVctr& Im_i, Value_type x_i, + // Value_type sigma_i, Value_type radius_i) + // { + // using T = Value_type; + + // auto select_cir_reg = [](TGrid& grid_1d, TVctr& Im, T x0, + // T radius, TVctr& Rx, TVctr& Ix, T& Rx_sf, T& Rx_sc, T& Ix_sc) + // { + // T R_max = radius; + // T R2_max = pow(R_max, 2); + + // auto ithread = grid_1d.region_ind(x0, R_max); + + // Rx.clear(); + // Rx.reserve(ithread.ind_e); + // Ix.clear(); + // Ix.reserve(ithread.ind_e); + + // // select circular region + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // if (grid_1d.r2(ix, x0) < R2_max) + // { + // Rx.push_back(grid_1d.rx(ix)); + // Ix.push_back(Im[ix]); + // } + // } + + // Rx_sf = x0; + // Rx_sc = R_max; + + // Ix_sc = fcn_max_element(Ix); + // dt_int32 m = Ix.size(); + // for(auto ix = 0; ix < m; ix++) + // { + // Rx[ix] = (Rx[ix] - Rx_sf)/Rx_sc; + // Ix[ix] = Ix[ix]/Ix_sc; + // } + + // Rx.shrink_to_fit(); + // Ix.shrink_to_fit(); + // }; + + // TVctr Rx, Ix; + // T Rx_sf, Rx_sc, Ix_sc; + + // select_cir_reg(grid_1d, Im_i, x_i, radius_i, Rx, Ix, Rx_sf, Rx_sc, Ix_sc); + + // T sigma = sigma_i/Rx_sc; + + // dt_int32 m = Ix.size(); + // dt_int32 n = 3; + + // TVctr J(m*n); + // TVctr d_Ix(m); + + // auto get_chi2 = [](TVctr& Rx, TVctr& Ix, TVctr& coef)->T + // { + // T x0 = coef[0]; + // T A = coef[1]; + // T alpha = 0.5/pow(coef[2], 2); + + // T chi2 = 0; + // T chi2_ee = 0; + // const dt_int32 m = Ix.size(); + // for(auto im = 0; im < m; im++) + // { + // T x = Rx[im] - x0; + // T v = Ix[im] - A*exp(-alpha*x*x); + // fcn_kh_sum(chi2, v*v, chi2_ee); + // } + // return chi2; + // }; + + // auto get_dIx_J = [](TVctr& Rx, TVctr& Ix, TVctr& coef, + // TVctr& dIx, TVctr& J) + // { + // T x0 = coef[0]; + // T A = coef[1]; + // T alpha = 0.5/pow(coef[2], 2); + + // T c_x0 = 1.0/pow(coef[2], 2); + // T c_A = 1; + // T c_sx = 1.0/pow(coef[2], 3); + + // const dt_int32 m = Ix.size(); + // for(auto im = 0; im < m; im++) + // { + // T x = Rx[im] - x0; + // T v = exp(-alpha*x*x); + // T f = A*v; + + // J[0 * m + im] = c_x0*x*f; + // J[1 * m + im] = c_A*v; + // J[2 * m + im] = c_sx*x*x*f; + + // dIx[im] = Ix[im] - f; + // } + // }; + + // T dx_max = ::fmax(grid_1d.drx/Rx_sc, 0.25*::fmin(sigma, radius_i/Rx_sc)); + + // vector c_coef_0 = { 0, 1, sigma }; + // vector c_coef_min = { -dx_max, 0.5, sigma/3 }; + // vector c_coef_max = { dx_max, 1.25, 3 * sigma }; + + // TVctr coef_0 = c_coef_0; + // TVctr coef_min = c_coef_min; + // TVctr coef_max = c_coef_max; + // TVctr coef = coef_0; + + // T chi2 = get_chi2(Rx, Ix, coef); + + // T lambda = 2; + // T lambda_f = 2; + + // lapack::LSF_1 fls_1; + + // const dt_int32 niter = 100; + // for(auto iter = 0; iter < niter; iter++) + // { + // get_dIx_J(Rx, Ix, coef, d_Ix, J); + + // TVctr d_coef(n); + // TVctr D(n); + // TVctr G(n); + // fls_1(m, n, J.data(), d_Ix.data(), d_coef.data(), lambda, D.data(), G.data()); + + // TVctr coef_t = coef; + // T rho_f = 0; + // T G_max = 0; + // for(auto ic = 0; ic < n; ic++) + // { + // coef_t[ic] += d_coef[ic]; + // rho_f += coef_t[ic] * (D[ic] * coef_t[ic] + G[ic]); + // G_max = ::fmax(G_max, fabs(G[ic])); + // } + + // T chi2_t = get_chi2(Rx, Ix, coef_t); + // T rho = (chi2 - chi2_t)/rho_f; + + // if ((G_max < 5e-7) || fabs(chi2 - chi2_t) < 5e-8) + // { + // break; + // } + + // if (rho > 0) + // { + // coef = coef_t; + + // for(auto ic = 0; ic < n; ic++) + // { + // coef[ic] = min(max(coef[ic], coef_min[ic]), coef_max[ic]); + // } + + // chi2 = get_chi2(Rx, Ix, coef); + + // lambda = (rho > 1e-6)?(::fmax(lambda/lambda_f, 1e-7)):lambda; + // } + // else + // { + // lambda = ::fmin(lambda*lambda_f, 1e+7); + // } + // } + + // coef[0] = coef[0] * Rx_sc + Rx_sf; + // coef[1] = coef[1] * Ix_sc; + // coef[2] = coef[2] * Rx_sc; + + // return coef; + // } + + // template + // Value_type neighbor_radius(TGrid& grid_i, TVctr& Im_i, R_2d> p_i, Value_type radius_i) + // { + // using T = Value_type; + + // T R2_max = pow(radius_i, 2); + + // dt_int32 ix_0 = grid_i.rx_2_irx_bfds(p_i.x - radius_i); + // dt_int32 ix_e = grid_i.rx_2_irx_bcds(p_i.x + radius_i); + + // dt_int32 iy_0 = grid_i.ry_2_iry_bfds(p_i.y - radius_i); + // dt_int32 iy_e = grid_i.ry_2_iry_bcds(p_i.y + radius_i); + + // dt_int32 nrl = grid_i.r_2_ir_cds_dr_min(radius_i); + + // // get radial distribution + // TVctr frl(nrl); + // TVctr cfrl(nrl); + + // T dR = grid_i.dR_min(); + + // for(auto ix = ix_0; ix < ix_e; ix++) + // { + // for(auto iy = iy_0; iy < iy_e; iy++) + // { + // T R2_d = grid_i.r2(ix, iy, p_i.x, p_i.y); + // if (R2_d < R2_max) + // { + // auto ir = static_cast(::floor(::sqrt(R2_d)/dR)); + // frl[ir] += Im_i[grid_i.sub_2_ind(ix, iy)]; + // cfrl[ir] += 1.0; + // } + // } + // } + + // for(auto ir = 0; ir < frl.size(); ir++) + // { + // frl[ir] /= ::fmax(1.0, cfrl[ir]); + // } + + // frl[0] = ::fmax(frl[0], 1.01*frl[1]); + + // frl = fcn_smooth_mean_1d(frl, 1); + + // // derivative and minimum + // dt_int32 ir0 = frl.size() - 1; + // for(auto ir = 0; ir < frl.size() - 1; ir++) + // { + // if (frl[ir] < frl[ir + 1]) + // { + // ir0 = ir + 1; + // break; + // } + // } + + // dt_int32 irm = frl.size() - 1; + // for(auto ir = ir0; ir < frl.size() - 1; ir++) + // { + // if (frl[ir] > frl[ir + 1]) + // { + // irm = ir; + // break; + // } + // } + + // return max(2, irm)*dR; + // } + + // // select circular region + // template + // Value_type mean_cir_reg(TGrid& grid_i, TVctr& Im_i, R_2d> p_i, + // Value_type radius_i, Value_type bg_i) + // { + // using T = Value_type; + + // T R2_max = radius_i*radius_i; + + // auto ithread = grid_i.region_ind(p_i, radius_i); + + // // select circular region + // T I_mean = 0; + // dt_int32 Ic = 0; + // for(auto ix = ithread.ix_0; ix < ithread.ix_e; ix++) + // { + // for(auto iy = ithread.iy_0; iy < ithread.iy_e; iy++) + // { + // T R2_d = grid_i.r2(ix, iy, p_i.x, p_i.y); + // if (R2_d < R2_max) + // { + // I_mean += Im_i[grid_i.sub_2_ind(ix, iy)] - bg_i; + // Ic++; + // } + // } + // } + // I_mean /= Ic; + // return I_mean; + // } + + // /***************************************************************************************/ + // template + // TVctr intrplprofile(TGrid& grid_2d, TVctr& Im, const R_2d>& p1, const R_2d>& p2, dt_int32 nr) + // { + // TVctr v; + + // if (!(grid_2d.chk_bound_eps(p1) && grid_2d.chk_bound_eps(p2))) + // { + // return v; + // } + + // if (norm(p1 - p2) < grid_2d.dR_min()) + // { + // return v; + // } + + // using T = Value_type; + + // auto fcn_intrpl_bl_rg_2d = [](const R_2d& p, TGrid& grid_2d, TVctr& Im)->T + // { + // auto ix = grid_2d.rx_2_irx_bfds(p.x); + // auto iy = grid_2d.ry_2_iry_bfds(p.y); + + // T f11 = Im[grid_2d.sub_2_ind(ix, iy)]; + // T f12 = Im[grid_2d.sub_2_ind(ix, iy + 1)]; + // T f21 = Im[grid_2d.sub_2_ind(ix + 1, iy)]; + // T f22 = Im[grid_2d.sub_2_ind(ix + 1, iy + 1)]; + + // T x1 = grid_2d.rx(ix); + // T x2 = grid_2d.rx(ix + 1); + // T y1 = grid_2d.ry(iy); + // T y2 = grid_2d.ry(iy + 1); + + // T dx1 = p.x - x1; + // T dx2 = x2 - p.x; + // T dy1 = p.y - y1; + // T dy2 = y2 - p.y; + + // T f = (dx2*(f11*dy2 + f12*dy1) + dx1*(f21*dy2 + f22*dy1))/((x2 - x1)*(y2 - y1)); + // return f; + + // }; + + // R_2d p12 = p2 - p1; + // T mp12 = p12.norm(); + + // nr = (nr <= 0)?static_cast(::ceil(mp12/grid_2d.dR_min())):nr; + // nr = max(nr, 2); + // T dr = mp12/(nr - 1); + // R_2d u = dr*normalize(p12); + + // v.reserve(nr); + // for(auto ir = 0; ir < nr; ir++) + // { + // R_2d p = p1 + T(ir)*u; + // v.push_back(fcn_intrpl_bl_rg_2d(p, grid_2d, Im)); + // } + // return v; + // } + + // template + // void intrplprofile(Stream_cpu& stream, TGrid& grid_2d, TVctr& Im, Value_type bg, R_2d> p1, R_2d> p2, + // TVctr& x, TVctr& y) + // { + // x.clear(); + // y.clear(); + + // if (!(grid_2d.chk_bound_eps(p1) && grid_2d.chk_bound_eps(p2))) + // { + // return; + // } + + // if (norm(p1 - p2) < grid_2d.dR_min()) + // { + // return; + // } + + // using T = Value_type; + + // auto fcn_intrpl_bl_rg_2d = [](const R_2d& p, TGrid& grid_2d, TVctr& Im)->T + // { + // auto ix = grid_2d.rx_2_irx_bfds(p.x); + // auto iy = grid_2d.ry_2_iry_bfds(p.y); + + // T f11 = Im[grid_2d.sub_2_ind(ix, iy)]; + // T f12 = Im[grid_2d.sub_2_ind(ix, iy + 1)]; + // T f21 = Im[grid_2d.sub_2_ind(ix + 1, iy)]; + // T f22 = Im[grid_2d.sub_2_ind(ix + 1, iy + 1)]; + + // T x1 = grid_2d.rx(ix); + // T x2 = grid_2d.rx(ix + 1); + // T y1 = grid_2d.ry(iy); + // T y2 = grid_2d.ry(iy + 1); + + // T dx1 = p.x - x1; + // T dx2 = x2 - p.x; + // T dy1 = p.y - y1; + // T dy2 = y2 - p.y; + + // T f = (dx2*(f11*dy2 + f12*dy1) + dx1*(f21*dy2 + f22*dy1))/((x2 - x1)*(y2 - y1)); + // return f; + + // }; + + // dt_int32 Ixy_1 = Im[grid_2d.rv_2_ir_bfds(p1.x, p1.y)]; + // dt_int32 Ixy_2 = Im[grid_2d.rv_2_ir_bfds(p2.x, p2.y)]; + + // R_2d p12 = p2 - p1; + // T mp12 = p12.norm(); + // dt_int32 nr = grid_2d.r_2_ir_cds_dr_min(mp12); + // T dr = mp12/(nr - 1); + // R_2d u = dr*normalize(p12); + + // x.reserve(nr); + // y.reserve(nr); + // for(auto ir = 0; ir < nr; ir++) + // { + // x.push_back(ir*dr); + // R_2d p = p1 + T(ir)*u; + // T v = fcn_intrpl_bl_rg_2d(p, grid_2d, Im); + // y.push_back(v - bg); + // } + // } + + // // find one maximum in all areas above the thr + // template + // TVctr fd_peaks_vector_typ_1(TVctr& x, TVctr& y, Value_type y_thr) + // { + // using T = Value_type; + // TVctr x_peak(y.size()); + + // T x_max = 0; + // T y_max = y_thr; + // dt_bool bb = y[0] > y_thr; + // dt_int32 ipeak = 0; + // for(auto ix = 0; ix < y.size(); ix++) + // { + // if (y[ix] > y_thr) + // { + // if (y_max < y[ix]) + // { + // y_max = y[ix]; + // x_max = x[ix]; + // } + // bb = true; + // } + // else if (bb) + // { + // x_peak[ipeak++] = x_max; + // y_max = y_thr; + // bb = false; + // } + // } + + // if (bb) + // { + // x_peak[ipeak++] = x_max; + // } + + // x_peak.resize(ipeak); + // x_peak.shrink_to_fit(); + + // return x_peak; + // } + + // // find all maximum in all areas above the thr + // template + // TVctr fd_peaks_vector_typ_2(TVctr& x, TVctr& y, Value_type y_thr) + // { + // using T = Value_type; + // TVctr x_peak; + // x_peak.reserve(y.size()); + + // for(auto ix = 1; ix < y.size() - 1; ix++) + // { + // if (y[ix] > y_thr) + // { + // if ((y[ix - 1] < y[ix]) && (y[ix + 1] < y[ix])) + // { + // x_peak.push_back(x[ix]); + // } + // } + // } + // x_peak.shrink_to_fit(); + + // return x_peak; + // } + + // /***************************************************************************************/ + // // find peak position 1d + // template + // enable_if_vctr_cpu> + // fit_max_pos_1d(TGrid& grid_1d, TVctr& Im, Value_type p_i, + // Value_type sigma_i, Value_type radius_i) + // { + // using T = Value_type; + + // auto ithread = grid_1d.region_ind(p_i, radius_i); + // dt_int32 ix_c = grid_1d.rx_2_irx_fds(p_i); + + // dt_int32 ix_0 = ithread.ix_0; + // for(auto ix = ix_c - 1; ix >= ithread.ix_0; ix--) + // { + // if (Im[ix - 1] > Im[ix]) + // { + // ix_0 = ix; + // break; + // } + // } + + // dt_int32 ix_e = ithread.ix_e; + // for(auto ix = ix_c + 1; ix <= ithread.ix_e; ix++) + // { + // if (Im[ix] < Im[ix + 1]) + // { + // ix_e = ix; + // break; + // } + // } + + // // if there are few points + // if (fabs(ix_e - ix_0) <= 3) + // { + // T x = 0; + // T sI = 0; + // for(auto ix = ix_0; ix <= ix_e; ix++) + // { + // x += Im[ix] * grid_1d.rx(ix); + // sI += Im[ix]; + // } + // x = x/sI; + + // return x; + // } + + // if ((ix_0 = !ithread.ix_0) || (ix_e = !ithread.ix_e)) + // { + // T x_min = grid_1d.rx(ix_0); + // T x_max = grid_1d.rx(ix_e); + // radius_i = ::fmin(p_i - x_min, x_max - p_i); + // } + + // auto coef = fit_gauss_1d(grid_1d, Im, p_i, sigma_i, radius_i); + + // return coef[0]; + // } + + // /***************************************************************************************/ + // // get projective standard deviation + // template + // TVctr projected_intensity(TGrid& grid_2d, TVctr& mx_i, Value_type np_min, Value_type delta) + // { + // using T = Value_type; + + // vector> pts_c = { R_2d(0, 0), R_2d(grid_2d.nx - 1, 0), R_2d(grid_2d.nx - 1, grid_2d.ny - 1), R_2d(0, grid_2d.ny - 1) }; + + // auto n_pp = static_cast(::ceil(norm(R_2d(grid_2d.nx, grid_2d.ny)) + 2)); + // TVctr y_pt(n_pp); + // TVctr c_pt(n_pp); + + // T cos_d, sin_d; + // sincos(delta, &sin_d, &cos_d); + + // // get projected points + // auto krn_proj_point = [&](const T& cos_d, const T& sin_d, const R_2d& p)->R_2d + // { + // return R_2d(cos_d*p.x + sin_d*p.y, -sin_d*p.x + cos_d*p.y); + // }; + + // // get reference corner point + // auto p_0 = krn_proj_point(cos_d, sin_d, pts_c[0]); + // for(auto ixy = 1; ixy < pts_c.size(); ixy++) + // { + // auto p_r = krn_proj_point(cos_d, sin_d, pts_c[ixy]); + // if (p_0.y > p_r.y) + // { + // p_0 = p_r; + // } + // } + + // for(auto ix = 0; ix < grid_2d.nx; ix++) + // { + // for(auto iy = 0; iy < grid_2d.ny; iy++) + // { + // auto ixy = grid_2d.sub_2_ind(ix, iy); + // auto p_r = krn_proj_point(cos_d, sin_d, R_2d(ix, iy)) - p_0; + // auto j = static_cast(::floor(p_r.y)); + // y_pt[j] += mx_i[ixy]; + // c_pt[j] += 1; + // } + // } + + // TVctr V_o; + // V_o.reserve(n_pp); + // for(auto j = 0; j < n_pp; j++) + // { + // if (c_pt[j] > np_min) + // { + // V_o.push_back(y_pt[j]/c_pt[j]); + // } + // } + // V_o.shrink_to_fit(); + + // return V_o; + // } + + // // get projective standard deviation + // template + // void PSD(Stream_cpu& stream, TGrid& grid_2d, TVctr& mx_i, Value_type np_min, + // Value_type del_0, Value_type del_e, Value_type d_del, TVctr& x_o, TVctr& y_o) + // { + // // get number of angles + // auto n_delta = static_cast(::floor((del_e - del_0)/d_del + 0.5)); + // x_o.resize(n_delta); + // y_o.resize(n_delta); + + // auto thr_psd = [&](const iThread_Rect_2d& ithread) + // { + // for(auto idel = ithread.ind_0; idel < ithread.ind_e; idel++) + // { + // auto delta = (del_0 + idel*d_del)*c_pi/180; + // x_o[idel] = delta * 180/c_pi; + + // auto pIm = projected_intensity(grid_2d, mx_i, np_min, delta); + + // y_o[idel] = fcn_variance(pIm); + // } + // }; + + // stream.set_n_stream_act(n_delta); + // stream.set_grid(n_delta); + // stream.exec_xd_fcn(thr_psd); + // } + + // // get projective standard deviation + // template + // TVctr PSD_fd_peaks(Stream_cpu& stream, TGrid& grid_2d, TVctr& mx_i, Value_type np_min, + // TVctr x_i, TVctr y_i) + // { + // using T = Value_type; + + // T d_del = fabs(x_i[1] - x_i[0]); + // dt_int32 nr = max(1, static_cast(::ceil(3.0/d_del))); + // auto y_f = fltr_median_1d(stream, y_i, nr); + + // T y_mean = 0; + // T y_max = y_i[0] - y_f[0]; + // for(auto ix = 0; ix < y_i.size(); ix++) + // { + // y_f[ix] = y_i[ix] - y_f[ix]; + // y_mean += y_f[ix]; + // y_max = max(y_max, y_f[ix]); + // } + // y_mean /= y_i.size(); + // auto y_thr = y_mean + 0.2*(y_mean + y_max); + + // auto x_peaks = fd_peaks_vector_typ_1(x_i, y_f, y_thr); + + // TVctr x_ref, y_ref; + // for(auto ix = 0; ix < x_peaks.size(); ix++) + // { + // auto delta = x_peaks[ix]; + // auto delta_0 = delta - d_del; + // auto delta_e = delta + d_del; + // auto d_delta = 0.1*d_del; + // PSD(stream, grid_2d, mx_i, np_min, delta_0, delta_e, d_delta, x_ref, y_ref); + // std::for_each(y_ref.begin(), y_ref.end(), [](T& y) {y = log(1 + y); }); + // auto coef = lsf_poly_n(x_ref, y_ref, 2); + // T px = -coef[1]/(2 * coef[2]); + // if ((px <= delta_0) || (delta_e <= px)) + // { + // dt_int32 idx = std::max_element(y_ref.begin(), y_ref.end()) - y_ref.begin(); + // px = x_ref[idx]; + // } + // x_peaks[ix] = px; + // } + + // return x_peaks; + // } + // /************************ read matlab binary file ***********************/ + // template + // enable_if_float + // read_mat_matrix(std::ifstream &bin_file, dt_int32 nxy, TVctr& matrix) + // { + // using T_o = Value_type; + + // vector vect_r(nxy); + // bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T_i)); + + // for(auto ik = 0; ik < nxy; ik++) + // { + // matrix[ik] = T_o(vect_r[ik]); + // } + // } + + // template + // enable_if_cfloat + // read_mat_matrix(std::ifstream &bin_file, dt_int32 nxy, TVctr& matrix) + // { + // using T = Value_type_r; + // using T_o = Value_type_r; + + // vector vect_r(nxy); + // bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T)); + // vector vect_i(nxy); + // bin_file.read(reinterpret_cast(vect_i.data()), nxy * sizeof(T)); + + // auto matrix_ptr = reinterpret_cast*>(matrix.data()); + + // for(auto ik = 0; ik < nxy; ik++) + // { + // matrix_ptr[ik].real(vect_r[ik]); + // matrix_ptr[ik].imag(vect_i[ik]); + // } + // } + + // template + // void read_mat_binary_matrix(const char *filename, Grid_2d>& grid_2d, TVctr& matrix) + // { + // dt_int32 nx, ny; + // dt_float64 dx, dy; + // dt_int32 type; + + // std::ifstream bin_file(filename, std::ofstream::binary); + // bin_file.read(reinterpret_cast(&nx), sizeof(dt_int32)); + // bin_file.read(reinterpret_cast(&ny), sizeof(dt_int32)); + // bin_file.read(reinterpret_cast(&dx), sizeof(dt_float64)); + // bin_file.read(reinterpret_cast(&dy), sizeof(dt_float64)); + // bin_file.read(reinterpret_cast(&type), sizeof(dt_int32)); + + // grid_2d.set_in_data(nx, ny, nx*dx, ny*dy); + + // auto nxy = nx*ny; + // matrix.resize(nxy); + + // switch (type) + // { + // case 1: + // { + // read_mat_matrix(bin_file, nxy, matrix); + // } + // break; + // case 2: + // { + // read_mat_matrix(bin_file, nxy, matrix); + // } + // break; + // case 3: + // { + // read_mat_matrix>(bin_file, nxy, matrix); + // } + // break; + // case 4: + // { + // read_mat_matrix>(bin_file, nxy, matrix); + // } + // break; + // } + // bin_file.close(); + // } + // /************************ write matlab binary file ***********************/ + // template + // enable_if_real_vctr_cpu + // write_mat_matrix(std::ofstream &bin_file, TVctr& matrix) + // { + // // using T = Value_type; + + // // bin_file.write(reinterpret_cast(matrix.data()), matrix.size()*sizeof(T)); + // } + + // template + // enable_if_cfloat_vctr_cpu + // write_mat_matrix(std::ofstream &bin_file, TVctr& matrix) + // { + // // using T = Value_type_r; + + // // vector vect_r(nxy); + // // vector vect_i(nxy); + // // for(auto ik = 0; ik(vect_r.data()), matrix.size()*sizeof(T)); + // // bin_file.write(reinterpret_cast(vect_i.data()), matrix.size()*sizeof(T)); + // } + + // template + // void write_mat_binary_matrix(const char *filename, Grid_2d>& grid_2d, TVctr& matrix) + // { + // // dt_int32 type = matrix_type; + + // // std::ofstream bin_file(filename, std::ofstream::binary); + // // bin_file.write(reinterpret_cast(&(grid_2d.nx)), sizeof(dt_int32)); + // // bin_file.write(reinterpret_cast(&(grid_2d.ny)), sizeof(dt_int32)); + // // bin_file.write(reinterpret_cast(&(grid_2d.drx)), sizeof(dt_float64)); + // // bin_file.write(reinterpret_cast(&(grid_2d.dry)), sizeof(dt_float64)); + // // bin_file.write(reinterpret_cast(&type), sizeof(dt_int32)); + + // // switch (type) + // // { + // // case 1: + // // { + // // write_mat_matrix(bin_file, matrix); + // // } + // // break; + // // case 2: + // // { + // // write_mat_matrix(bin_file, matrix); + // // } + // // break; + // // case 3: + // // { + // // write_mat_matrix>(bin_file, matrix); + // // } + // // break; + // // case 4: + // // { + // // write_mat_matrix>(bin_file, matrix); + // // } + // // break; + // // } + // // bin_file.close(); + // } + + // /************************ extract real vector form complex vector**********************/ + // template + // void from_complex_to_real(eShow_CData show_data, TVctr_c& cdata, TVctr_r &data) + // { + // switch (show_data) + // { + // case escd_creal: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = cdata[ixy].real(); + // } + // break; + // case escs_cimag: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = cdata[ixy].imag(); + // } + // break; + // case escd_cmod: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = abs(cdata[ixy]); + // } + // break; + // case escd_cphase: + // { + // for(auto ixy = 0; ixy < cdata.size(); ixy++) + // data[ixy] = arg(cdata[ixy]); + // } + // break; + // } + // } +} + +namespace mt +{ + // /***************************************************************************************/ + // template + // enable_if_vctr_cpu> + // atom_cost_function(TGrid& grid_2d, const Atom_Sa>& atom_Ip, TVctr_r& mx_i) + // { + // return cpu_detail::atom_cost_function(grid_2d, atom_Ip, mx_i); + // } + + // template + // enable_if_vctr_cpu + // subtract_atom(Stream_cpu& stream, TGrid& grid_2d, Vctr>, edev_cpu>& atom_Ip, TVctr_r& mx_i) + // { + // if (stream.n_stream_act <= 0) + // { + // return; + // } + + // for(auto istm = 0; istm < stream.n_stream_act; istm++) + // { + // stream[istm] = std::thread(std::bind(cpu_detail::subtract_atom, std::ref(stream), std::ref(grid_2d), std::ref(atom_Ip[istm]), std::ref(mx_i))); + // } + // stream.synchronize(); + // } + + // // Linear projected potential: V and zV + // template + // enable_if_host + // linear_Vz(Stream_cpu& stream, eAtomic_Pot_Parm_Typ atomic_pot_parm_typ, TQ1 &qz, TVAtom &vatom) + // { + // using TAtom = Value_type; + + // if (stream.n_stream_act <= 0) + // { + // return; + // } + + // auto thr_linear_Vz = [](const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, TQ1 &qz, TAtom &atom) + // { + // if (atom.charge == 0) + // { + // switch (atomic_pot_parm_typ) + // { + // case eappt_doyle_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_kirkland_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_weickenmeier_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_lobato_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // } + // } + // else + // { + // switch (atomic_pot_parm_typ) + // { + // case eappt_doyle_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_4: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_peng_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_kirkland_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_weickenmeier_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // case eappt_lobato_0_12: + // cpu_detail::linear_Vz(qz, atom); + // break; + // } + // } + // }; + + // for(auto istm = 0; istm < stream.n_stream_act - 1; istm++) + // { + // stream[istm] = std::thread(std::bind(thr_linear_Vz, atomic_pot_parm_typ, std::ref(qz), std::ref(vatom[istm]))); + // } + + // thr_linear_Vz(atomic_pot_parm_typ, qz, vatom[stream.n_stream_act - 1]); + + // stream.synchronize(); + // } + + // // Get local interpolation coefficients + // template + // enable_if_host + // fcn_vd_2_coef_poly3(Stream_cpu& stream, TVAtom &vatom) + // { + // using TAtom = Value_type; + + // if (stream.n_stream_act <= 0) + // { + // return; + // } + + // for(auto istm = 0; istm < stream.n_stream_act - 1; istm++) + // { + // stream[istm] = std::thread(std::bind(cpu_detail::fcn_vd_2_coef_poly3, std::ref(vatom[istm]))); + // } + + // cpu_detail::fcn_vd_2_coef_poly3(vatom[stream.n_stream_act - 1]); + + // stream.synchronize(); + // } +} \ No newline at end of file diff --git a/src/fcns_gpu.h b/src/fcns_gpu.h new file mode 100755 index 00000000..646eb11c --- /dev/null +++ b/src/fcns_gpu.h @@ -0,0 +1,1333 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +// #if defined __CUDACC__ && !defined GPU_FCNS_H +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "types.cuh" +#include "type_traits_gen.h" +#include "vctr_gpu.h" +#include "stream_gpu.h" +#include "fft_gpu.h" +#include "fcns_gpu.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" +#include "gpu_detail.cuh" + +/* vector functions */ +namespace mt +{ + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_assign_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_real()); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_assign_max_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_max_real(M_v, M_v)); + } + + template + enable_if_cvctr_and_rvctr + fcn_assign_real(TVctr_c& mx_i, Value_type M_v, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + if (M_v>0) + { + fcn_assign_max_real(mx_i, T(0), mx_o, pstream); + } + else + { + fcn_assign_real(mx_i, mx_o, pstream); + } + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_assign_abs_real(TVctr_c& mx_i, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_abs_real()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_assign_abs(TVctr_c& mx_i, TVctr_r& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::assign_abs()); + } + + /***************************************************************************************/ + template + enable_if_vctr_gpu + fcn_fill(TVctr& mx_io, Value_type val, Stream_gpu* pstream = nullptr) + { + thrust::fill(mx_io.begin(), mx_io.end(), val); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_scale(const Value_type& w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::scale(w_i)); + } + + template + enable_if_vctr_gpu + fcn_scale(const Value_type& w_i, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_io.begin(), mx_io.end(), mx_io.begin(), cgpu_fctr::scale(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_norm_2(TVctr_1& mx_i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::norm_2()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_o.begin(), cgpu_fctr::scale_norm_2(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_sub(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::sub()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add(TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale(Value_type w1_i, TVctr_1& mx_1i, + Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add_scale_i(w1_i, w2_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add_scale(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_norm_2(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add_norm_2_i()); + + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_norm_2(TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add_norm_2()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale_norm_2(Value_type w1_i, TVctr_1& mx_1i, + Value_type w2_i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::add_scale_norm_2_i(w1_i, w2_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_scale_norm_2(Value_type w_i, TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::add_scale_norm_2(w_i)); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_mult(TVctr_1& mx_1i, TVctr_1& mx_2i, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_1i.begin(), mx_1i.end(), mx_2i.begin(), mx_o.begin(), cgpu_fctr::mult()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_mult(TVctr_1& mx_i, TVctr_2& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_i.begin(), mx_i.end(), mx_io.begin(), mx_io.begin(), cgpu_fctr::mult()); + } + + /***************************************************************************************/ + template + enable_if_vctr_gpu + fcn_div_sft(Value_type mx_sft, Value_type mx_div, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + thrust::transform(mx_io.begin(), mx_io.end(), mx_io.begin(), cgpu_fctr::div_sft(mx_sft, mx_div)); + } + + /***************************************************************************************/ + template + enable_if_vctr_gpu> + fcn_sum(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + return thrust::reduce(mx_i.begin(), mx_i.end()); + } + + template + enable_if_vctr_gpu> + fcn_sum_norm_2(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::norm_2(), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu> + fcn_sum_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::norm_2_sft(x_sft), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_cvctr_gpu> + fcn_sum_max_real(TVctr& mx_i, Value_type_r v_min, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::assign_max_real(v_min, T_r(0)), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_cvctr_gpu> + fcn_sum_abs_real(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::assign_abs_real(), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu> + fcn_sum_abs(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::assign_abs(), T_r(0), cgpu_fctr::add()); + } + + template + enable_if_vctr_gpu> + fcn_sum_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + return thrust::transform_reduce(mx_i.begin(), mx_i.end(), + cgpu_fctr::abs_sft(), T_r(0), cgpu_fctr::add()); + } + + /***************************************************************************************/ + /* calculate mean */ + template + enable_if_vctr_gpu> + fcn_mean(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum(mx_i, pstream)/T(mx_i.size()); + } + + /* calculate mean of the norm square */ + template + enable_if_vctr_gpu> + fcn_mean_norm_2(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2(mx_i, pstream)/T_r(mx_i.size()); + } + + /* calculate mean of the shifted norm square */ + template + enable_if_vctr_gpu> + fcn_mean_norm_2_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_norm_2_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + template + enable_if_cvctr_gpu> + fcn_mean_max_real(TVctr& mx_i, Value_type_r v_min, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_max_real(mx_i, v_min, pstream)/T(mx_i.size()); + } + + template + enable_if_cvctr_gpu> + fcn_mean_abs_real(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + return fcn_sum_abs_real(mx_i, pstream)/T(mx_i.size()); + } + + template + enable_if_vctr_gpu> + fcn_mean_abs(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_abs(mx_i, pstream)/T_r(mx_i.size()); + } + + template + enable_if_vctr_gpu> + fcn_mean_abs_sft(TVctr& mx_i, Value_type x_sft, Stream_gpu* pstream = nullptr) + { + using T_r = Value_type_r; + return fcn_sum_abs_sft(mx_i, x_sft, pstream)/T_r(mx_i.size()); + } + + /***************************************************************************************/ + /* calculate mean and variance */ + template + enable_if_vctr_gpu + fcn_mean_var(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_var, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + x_mean = fcn_mean(mx_i, pstream); + x_var = fcn_mean_norm_2_sft(mx_i, x_mean, pstream); + } + + /* calculate mean and standard deviation */ + template + enable_if_vctr_gpu + fcn_mean_std(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_std, Stream_gpu* pstream = nullptr) + { + fcn_mean_var(mx_i, x_mean, x_std, pstream); + x_std = sqrt(x_std); + } + + // mean and first absolute moment + template + enable_if_vctr_gpu + fcn_mean_moment_1a(TVctr& mx_i, Value_type& x_mean, Value_type_r& x_ma1, Stream_gpu* pstream = nullptr) + { + x_mean = fcn_mean(mx_i, pstream); + x_ma1 = fcn_mean_abs_sft(mx_i, x_mean, pstream); + } + + /* variance */ + template + enable_if_vctr_gpu> + fcn_variance(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_var; + fcn_mean_var(mx_i, x_mean, x_var, pstream); + + return x_var; + } + + /* standard deviation */ + template + enable_if_vctr_gpu> + fcn_std(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + auto x_var = fcn_variance(mx_i, pstream); + + return sqrt(x_var); + } + + // first absolute moment + template + enable_if_vctr_gpu> + fcn_moment_1a(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using T_r = Value_type_r; + + T x_mean; + T_r x_ma1; + fcn_mean_moment_1a(mx_i, x_mean, x_ma1, pstream); + + return x_ma1; + } + + /***************************************************************************************/ + /* minimum element of a vector */ + template + enable_if_vctr_gpu> + fcn_min_element(const TVctr& x, Stream_gpu* pstream = nullptr) + { + return *thrust::min_element(x.begin(), x.end()); + } + + /* maximum element of a vector */ + template + enable_if_vctr_gpu> + fcn_max_element(const TVctr& x, Stream_gpu* pstream = nullptr) + { + return *thrust::max_element(x.begin(), x.end()); + } + + /* minimum and maximum element of a vector */ + template + enable_if_vctr_gpu + fcn_minmax_element(const TVctr& x, Value_type& x_min, Value_type& x_max, Stream_gpu* pstream = nullptr) + { + auto x_min_max = thrust::minmax_element(x.begin(), x.end()); + x_min = *(x_min_max.first); + x_max = *(x_min_max.second); + } +} + +/* add - assign - crop - norm_2 - fftsft */ +namespace mt +{ + /* shift matrix respect to nx_h */ + template + enable_if_vctr_gpu + fcn_fftsft_1d(TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_1d(); + + gpu_detail::fcn_fftsft_1d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to ny_h */ + template + enable_if_vctr_gpu + fcn_fftsft_bc_2d(TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + gpu_detail::fcn_fftsft_bc_2d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_2d(TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + gpu_detail::fcn_fftsft_2d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_2d(TVctr& mx_i, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_fftsft_2d<<>>(igrid, mx_i.ptr_32(), mx_o.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_3d( TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_3d(); + + gpu_detail::fcn_fftsft_3d<<>>(igrid, mx_io.ptr_32()); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + enable_if_vctr_gpu + fcn_fftsft_3d(TVctr& mx_i, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_3d(); + + gpu_detail::fcn_fftsft_3d<<>>(igrid, mx_i.ptr_32(), mx_o.ptr_32()); + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + enable_if_vctr_gpu + fcn_add_sc_fftsft_2d(TVctr& mx_i, Value_type w, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_fftsft_2d<<>>(igrid, mx_i.ptr_32(), w, mx_o.ptr_32()); + } + + /* add, scale, square and shift */ + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_sc_norm_2_fftsft_2d(TVctr_1& mx_i, Value_type w, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_norm_2_fftsft_2d<<>>(igrid, mx_i.ptr_32(), w, mx_o.ptr_32()); + } + + /***************************************************************************************/ + /* assign and crop */ + template + enable_if_vctr_gpu + fcn_assign_crop_2d(TVctr& mx_i, TVctr& mx_o, iRegion_Rect_2d& iregion, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_assign_crop_2d<<>>(igrid, mx_i.ptr_32(), iregion, mx_o.ptr_32()); + } + + /* assign, crop and shift */ + template + enable_if_vctr_gpu + fcn_assign_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_assign_crop_fftsft_2d<<>>(igrid, mx_i.ptr_32(), iregion, mx_o.ptr_32()); + } + + /* add, scale, crop and shift */ + template + enable_if_vctr_gpu + fcn_add_sc_crop_fftsft_2d(TVctr& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_crop_fftsft_2d<<>>(igrid, mx_i.ptr_32(), iregion, w, mx_o.ptr_32()); + } + + /* add, scale, square, crop and shift */ + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_add_sc_norm_2_crop_fftsft_2d(TVctr_1& mx_i, iRegion_Rect_2d& iregion, Value_type w, TVctr_2& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + using U = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_add_sc_norm_2_crop_fftsft_2d<<>>(igrid, mx_i.ptr_32(), iregion, w, mx_o.ptr_32()); + } +} + +/* transpose - element wise matrix op vector */ +namespace mt +{ + /* transpose */ + template + enable_if_vctr_gpu>> + fcn_trs_2d(TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + Vctr_gpu mx_t(mx_i.shape_2d_trs()); + gpu_detail::fcn_trs_2d<<>>(igrid, mx_i.ptr_32(), mx_t.ptr_32()); + + return mx_t; + } + + /* transpose */ + template + enable_if_vctr_gpu + fcn_trs_2d(TVctr& mx_i, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + if (&mx_i != &mx_o) + { + gpu_detail::fcn_trs_2d<<>>(igrid, mx_i.ptr_32(), mx_o.ptr_32()); + } + else + { + Vctr_gpu mx_t(mx_i.shape_2d_trs()); + gpu_detail::fcn_trs_2d<<>>(igrid, mx_i.ptr_32(), mx_t.ptr_32()); + mx_t.cpy_to_gpu_ptr(mx_o.m_data, mx_o.size()); + } + } + + /* element wise addition: matrix + vector*/ + template + enable_if_vctr_gpu + fcn_ew_add_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + gpu_detail::fcn_ew_add_mx_vctr_col<<>>(igrid, vctr, mx_io.ptr_32()); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + gpu_detail::fcn_ew_add_mx_vctr_row<<>>(igrid, vctr, mx_io.ptr_32()); + } + } + + /* element wise subtraction: matrix - vector */ + template + enable_if_vctr_gpu + fcn_ew_sub_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + gpu_detail::fcn_ew_sub_mx_vctr_col<<>>(igrid, vctr, mx_io.ptr_32()); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + gpu_detail::fcn_ew_sub_mx_vctr_row<<>>(igrid, vctr, mx_io.ptr_32()); + } + } + + /* element wise multiplication matrix X vector */ + template + enable_if_vctr_gpu + fcn_ew_mult_mx_vctr(TVctr& vctr, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_io.igrid_2d(); + + if ((vctr.m_s0=mx_io.m_s0) && (vctr.m_s1==1)) + { + gpu_detail::fcn_ew_mult_mx_vctr_col<<>>(igrid, vctr, mx_io.ptr_32()); + } + else if ((vctr.m_s0==1) && (vctr.m_s1==mx_io.m_s1) ) + { + gpu_detail::fcn_ew_mult_mx_vctr_row<<>>(igrid, vctr, mx_io.ptr_32()); + } + } +} + +/* aperture functions */ +namespace mt +{ + template + enable_if_vctr_gpu + fcn_fermi_aperture(Grid_2d& grid, T g2_cut, T alpha, T w, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fermi_aperture<<>>(grid, g2_cut, alpha, w, mx_io.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_hard_aperture(Grid_2d& grid, T g2_cut, T w, TVctr& mx_io, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_hard_aperture<<>>(grid, g2_cut, w, mx_io.ptr_32()); + } +} + +/* phase shifts real space*/ +namespace mt +{ + template + enable_if_vctr_gpu + fcn_rs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T gx, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_exp_factor_1d<<>>(grid, psi_i.ptr_32(), gx, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &gy, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_exp_factor_2d_bc<<>>(grid, alpha, psi_i.ptr_32(), gy.ptr_32(), w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_rs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d g, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_exp_factor_2d<<>>(grid, psi_i.ptr_32(), g, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& g, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_mul_exp_factor_2d<<>>(grid, psi_i.ptr_32(), g.ptr_32(), w, psi_o.ptr_32()); + } +} + +/* phase shifts fourier space */ +namespace mt +{ + template + enable_if_vctr_gpu + fcn_fs_exp_factor_1d(Grid_1d& grid, TVctr& psi_i, T rx, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_exp_factor_1d<<>>(grid, psi_i.ptr_32(), rx, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_fs_exp_factor_2d_bc(Grid_2d& grid, TVctr_c& psi_i, T alpha, TVctr_r &ry, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_exp_factor_2d_bc<<>>(grid, alpha, psi_i.ptr_32(), ry.ptr_32(), w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_fs_exp_factor_2d(Grid_2d& grid, TVctr& psi_i, R_2d r, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_exp_factor_2d<<>>(grid, psi_i.ptr_32(), r, w, psi_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_fs_mul_exp_factor_2d(Grid_2d& grid, TVctr_c& psi_i, TVctr_r& r, T w, TVctr_c& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_mul_exp_factor_2d<<>>(grid, psi_i.ptr_32(), r.ptr_32(), w, psi_o.ptr_32()); + } +} + +/* gradient */ +namespace mt +{ + template + enable_if_vctr_gpu + fcn_grad_x(TVctr& mx_i, TVctr& dmx_x, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_grad_x<<>>(igrid, mx_i.ptr_32(), dmx_x.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_grad_y(TVctr& mx_i, TVctr& dmx_y, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_grad_y<<>>(igrid, mx_i.ptr_32(), dmx_y.ptr_32()); + } + + template + enable_if_vctr_gpu + fcn_grad(TVctr& mx_i, TVctr& dmx_x, TVctr& dmx_y, Stream_gpu* pstream = nullptr) + { + using T = Value_type; + + auto igrid = mx_i.igrid_2d(); + + gpu_detail::fcn_grad<<>>(igrid, mx_i.ptr_32(), dmx_x.ptr_32(), dmx_y.ptr_32()); + } +} + +/* function multiplication fourier space */ +namespace mt +{ + #define FCN_MULT_FS_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_vctr_gpu \ + fcn_mult_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, T w, TVctr_c& mx_io, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + gpu_detail::fcn_mult_fs_##FN##_##DIM##d<<>>(grid, fcn, w, mx_io.ptr_32()); \ + } + + /* gaussian */ + FCN_MULT_FS_FCN_GPU(gauss, Fcn_Gauss, 1); // fcn_mult_fs_gauss_1d + FCN_MULT_FS_FCN_GPU(gauss, Fcn_Gauss, 2); // fcn_mult_fs_gauss_2d + FCN_MULT_FS_FCN_GPU(gauss, Fcn_Gauss, 3); // fcn_mult_fs_gauss_3d + + /* exponential */ + FCN_MULT_FS_FCN_GPU(exp, Fcn_Exp, 1); // fcn_mult_fs_exp_1d + FCN_MULT_FS_FCN_GPU(exp, Fcn_Exp, 2); // fcn_mult_fs_exp_2d + FCN_MULT_FS_FCN_GPU(exp, Fcn_Exp, 3); // fcn_mult_fs_exp_3d + + /* fermi */ + FCN_MULT_FS_FCN_GPU(fermi, Fcn_Fermi, 1); // fcn_mult_fs_fermi_1d + FCN_MULT_FS_FCN_GPU(fermi, Fcn_Fermi, 2); // fcn_mult_fs_fermi_2d + FCN_MULT_FS_FCN_GPU(fermi, Fcn_Fermi, 3); // fcn_mult_fs_fermi_3d + + /* butterworth */ + FCN_MULT_FS_FCN_GPU(butwth, Fcn_Butwth, 1); // fcn_mult_fs_butwth_1d + FCN_MULT_FS_FCN_GPU(butwth, Fcn_Butwth, 2); // fcn_mult_fs_butwth_2d + FCN_MULT_FS_FCN_GPU(butwth, Fcn_Butwth, 3); // fcn_mult_fs_butwth_3d + + /* hann */ + FCN_MULT_FS_FCN_GPU(hann, Fcn_Hann, 1); // fcn_mult_fs_hann_1d + FCN_MULT_FS_FCN_GPU(hann, Fcn_Hann, 2); // fcn_mult_fs_hann_2d + FCN_MULT_FS_FCN_GPU(hann, Fcn_Hann, 3); // fcn_mult_fs_hann_3d +} + +/* convolution */ +namespace mt +{ + #define FCN_CV_FS_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_cvctr_gpu \ + fcn_cv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_gpu& fft, FCN& fcn, TVctr_c& mx_io, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + fcn_mult_fs_##FN##_##DIM##d(grid, fcn, w, mx_io, pstream); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_CV_FS_FCN_GPU(gauss, Fcn_Gauss, 1); // fcn_cv_fs_gauss_1d + FCN_CV_FS_FCN_GPU(gauss, Fcn_Gauss, 2); // fcn_cv_fs_gauss_2d + FCN_CV_FS_FCN_GPU(gauss, Fcn_Gauss, 3); // fcn_cv_fs_gauss_3d + + /* exponential convolution */ + FCN_CV_FS_FCN_GPU(exp, Fcn_Exp, 1); // fcn_cv_fs_exp_1d + FCN_CV_FS_FCN_GPU(exp, Fcn_Exp, 2); // fcn_cv_fs_exp_2d + FCN_CV_FS_FCN_GPU(exp, Fcn_Exp, 3); // fcn_cv_fs_exp_3d + + /* fermi convolution */ + FCN_CV_FS_FCN_GPU(fermi, Fcn_Fermi, 1); // fcn_cv_fs_fermi_1d + FCN_CV_FS_FCN_GPU(fermi, Fcn_Fermi, 2); // fcn_cv_fs_fermi_2d + FCN_CV_FS_FCN_GPU(fermi, Fcn_Fermi, 3); // fcn_cv_fs_fermi_3d + + /* butterworth convolution */ + FCN_CV_FS_FCN_GPU(butwth, Fcn_Butwth, 1); // fcn_cv_fs_butwth_1d + FCN_CV_FS_FCN_GPU(butwth, Fcn_Butwth, 2); // fcn_cv_fs_butwth_2d + FCN_CV_FS_FCN_GPU(butwth, Fcn_Butwth, 3); // fcn_cv_fs_butwth_3d + + /* hann convolution */ + FCN_CV_FS_FCN_GPU(hann, Fcn_Hann, 1); // fcn_cv_fs_hann_1d + FCN_CV_FS_FCN_GPU(hann, Fcn_Hann, 2); // fcn_cv_fs_hann_2d + FCN_CV_FS_FCN_GPU(hann, Fcn_Hann, 3); // fcn_cv_fs_hann_3d +} + +/* deconvolution */ +namespace mt +{ + #define FCN_DCV_FS_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_cvctr_gpu \ + fcn_dcv_fs_##FN##_##DIM##d(Grid_##DIM##d& grid, FFT_gpu& fft, FCN& fcn, T psnr, TVctr_c& mx_io, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + fft.forward(mx_io); \ + \ + const T w = grid.isize_r(); \ + \ + gpu_detail::fcn_dcv_fs_##FN##_##DIM##d<<>>(grid, fcn, psnr, w, mx_io.ptr_32()); \ + \ + fft.inverse(mx_io); \ + fcn_fftsft_##DIM##d(mx_io, pstream); \ + } + + /* gaussian convolution */ + FCN_DCV_FS_FCN_GPU(gauss, Fcn_Gauss, 1); // fcn_dcv_fs_gauss_1d + FCN_DCV_FS_FCN_GPU(gauss, Fcn_Gauss, 2); // fcn_dcv_fs_gauss_2d + FCN_DCV_FS_FCN_GPU(gauss, Fcn_Gauss, 3); // fcn_dcv_fs_gauss_3d + + /* exponential convolution */ + FCN_DCV_FS_FCN_GPU(exp, Fcn_Exp, 1); // fcn_dcv_fs_exp_1d + FCN_DCV_FS_FCN_GPU(exp, Fcn_Exp, 2); // fcn_dcv_fs_exp_2d + FCN_DCV_FS_FCN_GPU(exp, Fcn_Exp, 3); // fcn_dcv_fs_exp_3d + + /* fermi convolution */ + FCN_DCV_FS_FCN_GPU(fermi, Fcn_Fermi, 1); // fcn_dcv_fs_fermi_1d + FCN_DCV_FS_FCN_GPU(fermi, Fcn_Fermi, 2); // fcn_dcv_fs_fermi_2d + FCN_DCV_FS_FCN_GPU(fermi, Fcn_Fermi, 3); // fcn_dcv_fs_fermi_3d + + /* butterworth convolution */ + FCN_DCV_FS_FCN_GPU(butwth, Fcn_Butwth, 1); // fcn_dcv_fs_butwth_1d + FCN_DCV_FS_FCN_GPU(butwth, Fcn_Butwth, 2); // fcn_dcv_fs_butwth_2d + FCN_DCV_FS_FCN_GPU(butwth, Fcn_Butwth, 3); // fcn_dcv_fs_butwth_3d + + /* hann convolution */ + FCN_DCV_FS_FCN_GPU(hann, Fcn_Hann, 1); // fcn_dcv_fs_hann_1d + FCN_DCV_FS_FCN_GPU(hann, Fcn_Hann, 2); // fcn_dcv_fs_hann_2d + FCN_DCV_FS_FCN_GPU(hann, Fcn_Hann, 3); // fcn_dcv_fs_hann_3d +} + +/* window functions */ +namespace mt +{ + #define FCN_WD_FCN_GPU(FN, FCN, DIM) \ + template \ + enable_if_vctr_gpu \ + fcn_wd_##FN##_##DIM##d(Grid_##DIM##d& grid, FCN& fcn, dt_bool sft, TVctr& mx_o, Stream_gpu* pstream = nullptr) \ + { \ + using U = Value_type; \ + \ + if (sft) \ + { \ + gpu_detail::fcn_wd_##FN##_##DIM##d<<>>(grid, fcn, mx_o.ptr_32()); \ + } \ + else \ + { \ + gpu_detail::fcn_wd_##FN##_##DIM##d<<>>(grid, fcn, mx_o.ptr_32()); \ + } \ + } + + FCN_WD_FCN_GPU(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + FCN_WD_FCN_GPU(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + FCN_WD_FCN_GPU(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + FCN_WD_FCN_GPU(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + FCN_WD_FCN_GPU(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + FCN_WD_FCN_GPU(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + FCN_WD_FCN_GPU(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + FCN_WD_FCN_GPU(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + FCN_WD_FCN_GPU(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + FCN_WD_FCN_GPU(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + FCN_WD_FCN_GPU(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + FCN_WD_FCN_GPU(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + FCN_WD_FCN_GPU(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + FCN_WD_FCN_GPU(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + FCN_WD_FCN_GPU(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d +} + +/* phase correlation */ +namespace mt +{ + /****************** pcf data processing real space *******************/ + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Butwth_1d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_pcf_1d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Butwth_2d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_pcf_2d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_vctr_gpu_and_vctr_gpu + fcn_rs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Butwth_3d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_rs_pcf_3d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + /***************** pcf data processing fourier space *****************/ + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_1d_dp(Grid_1d& grid, TVctr_r& mx_i, Wd_Gauss_1d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_pcf_1d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_2d_dp(Grid_2d& grid, TVctr_r& mx_i, Wd_Gauss_2d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_pcf_2d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } + + template + enable_if_cvctr_gpu_and_vctr_rgpu + fcn_fs_pcf_3d_dp(Grid_3d& grid, TVctr_r& mx_i, Wd_Gauss_3d& fcn, T w, TVctr_c& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_fs_pcf_3d_dp<<>>(grid, mx_i.ptr_32(), fcn, w, mx_o.ptr_32()); + } +} + +/* optical flow */ +namespace mt +{ + template + enable_if_vctr_gpu + fcn_opt_flow(TVctr& mx_s, TVctr& mx_m, T alpha, TVctr& dphi_x, TVctr& dphi_y, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto igrid = mx_s.igrid_2d(); + + gpu_detail::fcn_opt_flow<<>>(igrid, mx_s.ptr_32(), mx_m.ptr_32(), alpha, dphi_x.ptr_32(), dphi_y.ptr_32()); + } +} + +/* bilinear interpolation */ +namespace mt +{ + template + enable_if_vctr_gpu + fcn_intrpl_bl_rg_2d(Grid_2d& grid, TVctr& mx_i, TVctr& vx, TVctr& vy, T bg, TVctr& mx_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail::fcn_intrpl_bl_rg_2d<<>>(grid, mx_i.ptr_32(), vx.ptr_32(), vy.ptr_32(), bg, mx_o.ptr_32()); + } +} + +namespace mt +{ +// /***************************************************************************************/ +// template +// enable_if_vctr_gpu> +// atom_cost_function(Grid_2d& grid, const Atom_Sa>& atom_Ip, TVctr_r& mx_i) +// { +// TVctr_r sum_v(1); + +// D_Grid_Blk d_grid_blk; +// d_grid_blk.grid = dim3(); +// d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + +// gpu_detail::atom_cost_function<<>>(grid_2d, atom_Ip, mx_i.ptr_32(), sum_v); +// return sum_v[0]; +// } + +// template +// enable_if_vctr_gpu +// subtract_atom(Grid_2d& grid, Vctr>, edev_cpu>& atom_Ip, TVctr_r& mx_i) +// { +// if (stream.n_stream_act<= 0) +// { +// return; +// } + +// for(auto istm = 0; istm < stream.n_stream_act; istm++) +// { +// D_Grid_Blk d_grid_blk; +// d_grid_blk.grid = dim3(); +// d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + +// gpu_detail::subtract_atom<<>>(grid_2d, atom_Ip[istm], mx_i); +// } +// } + +// // Linear projected potential: V and zV +// template +// enable_if_device +// linear_Vz(eAtomic_Pot_Parm_Typ atomic_pot_parm_typ, TQ1 &qz, TVAtom &vatom) +// { +// using TAtom = Value_type; + +// if (stream.n_stream_act<= 0) +// { +// return; +// } + +// auto str_linear_Vz = [](cudaStream_t &stream, const eAtomic_Pot_Parm_Typ& atomic_pot_parm_typ, TQ1 &qz, TAtom &atom) +// { +// if (atom.charge == 0) +// { +// switch(atomic_pot_parm_typ) +// { +// case eappt_doyle_0_4: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_peng_0_4: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_peng_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_kirkland_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_weickenmeier_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_lobato_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// } +// } +// else +// { +// switch(atomic_pot_parm_typ) +// { +// case eappt_doyle_0_4: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_peng_0_4: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_peng_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_kirkland_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_weickenmeier_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// case eappt_lobato_0_12: +// gpu_detail::linear_Vz<<>>(qz, atom); +// break; +// } +// } +// }; + +// for(auto istm = 0; istm < stream.n_stream_act; istm++) +// { +// str_linear_Vz(stream[istm], atomic_pot_parm_typ, qz, vatom[istm]); +// } +// } + +// // Get local interpolation coefficients +// template +// enable_if_device +// fcn_vd_2_coef_poly3(TVAtom &vatom) +// { +// using TAtom = Value_type; + +// if (stream.n_stream_act<= 0) +// { +// return; +// } + +// for(auto istm = 0; istm < stream.n_stream_act; istm++) +// { +// gpu_detail::fcn_vd_2_coef_poly3<<>>(vatom[istm]); +// } +// } +// +// template +// typename std::enable_if::value +// && is_cfloat>::value && !std::is_same, Value_type>::value, void>::type +// cpy_to_host(Stream& stream, TVctr_i &mx_i, TVctr_o &mx_o, +// Vctr, edev_cpu> *M_i_h = nullptr) +// { +// Vctr, edev_cpu> M_h; +// M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + +// // data transfer from GPU to CPU +// M_i_h->assign(mx_i.begin(), mx_i.end()); + +// // copy data from CPU to CPU +// cpy_to_host(stream, *M_i_h, mx_o.ptr_32()); +// } + +// template +// typename std::enable_if::value +// && (!is_cfloat>::value || std::is_same, Value_type>::value), void>::type +// cpy_to_host(Stream& stream, TVctr_i &mx_i, TVctr_o &mx_o, +// Vctr, edev_cpu> *M_i_h = nullptr) +// { +// mx_o.assign(mx_i.begin(), mx_i.end()); +// } + +// template +// enable_if_vctr_gpu_and_vctr_cpu +// add_sc_to_host(Stream& stream, Value_type w_i, +// TVctr_i &mx_i, TVctr_o &mx_o, Vctr, edev_cpu> *M_i_h = nullptr) +// { +// Vctr, edev_cpu> M_h; +// M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + +// // data transfer from GPU to CPU +// M_i_h->assign(mx_i.begin(), mx_i.end()); + +// // add and scale +// mt::add_sc_to_host(stream, w_i, *M_i_h, mx_o.ptr_32()); +// } + +// template +// enable_if_vctr_gpu_and_vctr_cpu +// add_sc_square_to_host(Stream& stream, Value_type w_i, +// TVctr_i &mx_i, TVctr_o &mx_o, Vctr, edev_cpu> *M_i_h = nullptr) +// { +// Vctr, edev_cpu> M_h; +// M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + +// // data transfer from GPU to CPU +// M_i_h->assign(mx_i.begin(), mx_i.end()); + +// mt::add_sc_square_to_host(stream, w_i, *M_i_h, mx_o.ptr_32()); +// } + +// template +// enable_if_vctr_gpu_and_vctr_cpu +// add_sc_m2psi_psi_to_host(Stream& stream, Value_type w_i, +// TVctr_c_i &psi_i, TVctr_r_o &m2psi_o, TVctr_c_o &psi_o, Vctr, edev_cpu> *psi_i_h = nullptr) +// { +// Vctr, edev_cpu> M_h; +// psi_i_h = (psi_i_h == nullptr)?&M_h:psi_i_h; + +// // data transfer from GPU to CPU +// psi_i_h->assign(psi_i.begin(), psi_i.end()); + +// mt::add_sc_m2psi_psi_to_host(stream, w_i, *psi_i_h, m2psi_o, psi_o); +// } +// /***************************************************************************************/ +// // find peak position 1d +// template +// enable_if_vctr_gpu> +// fit_max_pos_1d(TGrid& grid_1d, TVctr& Im, Value_type p_i, +// Value_type sigma_i, Value_type radius_i) +// { +// using T = Value_type; + +// Vctr Im_h = Im; +// return fit_max_pos_1d(grid_1d, Im_h, p_i, sigma_i, radius_i); +// } + +// inline +// D_Grid_Blk d_grid_blk(dt_int32 nx, dt_int32 ny, dt_int32 gpu_device, dt_int32 n_thread) +// { +// dt_int32 n_SMs; +// cudaDeviceGetAttribute(&n_SMs, cudaDevAttrMultiProcessorCount, gpu_device); + +// dt_int32 n_thr_SMs; +// cudaDeviceGetAttribute(&n_thr_SMs, cudaDevAttrMaxThreadsPerMultiProcessor, gpu_device); + +// dt_int32 n_thr_blk; +// cudaDeviceGetAttribute(&n_thr_blk, cudaDevAttrMaxThreadsPerBlock, gpu_device); + +// dt_int32 tnr_nxy = c_thr_2d_x*c_thr_2d_y; +// dt_int32 blk_max = 8*max(1, n_thr_SMs/(tnr_nxy*n_thread))*n_SMs; +// dt_int32 blk_x = (ny+c_thr_2d_x-1)/c_thr_2d_x; +// dt_int32 blk_y = (nx+c_thr_2d_y-1)/c_thr_2d_y; +// dt_float64 f = sqrt(dt_float64(blk_max)/dt_float64(blk_x*blk_y)); +// blk_x = max(c_blk_x, static_cast(f*blk_x)); +// blk_y = max(c_blk_y, static_cast(f*blk_y)); + +// D_Grid_Blk d_grid_blk; +// d_grid_blk.grid = dim3(blk_x, blk_y); +// d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + +// return d_grid_blk; +// } +} \ No newline at end of file diff --git a/src/fft_cpu.h b/src/fft_cpu.h new file mode 100755 index 00000000..f23617ae --- /dev/null +++ b/src/fft_cpu.h @@ -0,0 +1,141 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include + +#include "macros.h" +#include "const_enum.h" +#include "math_mt.h" +#include "vctr_cpu.h" +#include "stream_cpu.h" + +/* forward declaration */ +namespace mt +{ +#ifndef FFT_H + #define FFT_H + template class FFT; +#endif +} + +/* derive classes */ +namespace mt +{ + template + using FFT_cpu = FFT; + + template + using FFT_gpu = FFT; + +} + +/* cpu fourier transform - dt_float32 */ +namespace mt +{ + template <> + class FFT + { + public: + using value_type = dt_float32; + static const eDev device = edev_cpu; + + using TVctr_c = Vctr, edev_cpu>; + + FFT(); + + FFT(const dt_int32& s0, Stream_cpu* pstream = nullptr); + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_cpu* pstream = nullptr); + + ~FFT(); + + void cleanup(); + + void destroy_plan(); + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1); + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread=1); + + void forward(TVctr_c& mx); + + void inverse(TVctr_c& mx); + + void forward(TVctr_c& mx_i, TVctr_c& mx_o); + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o); + + private: + fftwf_plan plan_forward; + fftwf_plan plan_backward; + }; +} + +/* cpu fourier transform - dt_float64 */ +namespace mt +{ + template <> + class FFT + { + public: + using value_type = dt_float64; + static const eDev device = edev_cpu; + + using TVctr_c = Vctr, edev_cpu>; + + FFT(); + + FFT(const dt_int32& s0, Stream_cpu* pstream = nullptr); + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_cpu* pstream = nullptr); + + ~FFT(); + + void cleanup(); + + void destroy_plan(); + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1); + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread=1); + + void forward(TVctr_c& mx); + + void inverse(TVctr_c& mx); + + void forward(TVctr_c& mx_i, TVctr_c& mx_o); + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o); + + private: + fftw_plan plan_forward; + fftw_plan plan_backward; + }; +} + +#include "detail/fft_cpu.inl" \ No newline at end of file diff --git a/src/fft_gpu.h b/src/fft_gpu.h new file mode 100755 index 00000000..3fbdb53a --- /dev/null +++ b/src/fft_gpu.h @@ -0,0 +1,139 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +#include "macros.h" +#include "const_enum.h" +#include "math_mt.h" +#include "vctr_gpu.h" +#include "stream_gpu.h" + +/* forward declaration */ +namespace mt +{ +#ifndef FFT_H + #define FFT_H + template class FFT; +#endif +} + +#ifdef __CUDACC__ +/* gpu fourier transform - dt_float32 */ +namespace mt +{ + template <> + class FFT + { + public: + using value_type = dt_float32; + static const eDev device = edev_gpu; + + using TVctr_c = Vctr, edev_gpu>; + + FFT(); + + FFT(const dt_int32& s0, Stream_gpu* pstream = nullptr); + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_gpu* pstream = nullptr); + + ~FFT(); + + void cleanup(); + + void destroy_plan(); + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1); + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& nz, dt_int32 n_thread=1); + + void set_stream(cudaStream_t &stream); + + void forward(TVctr_c& mx); + + void inverse(TVctr_c& mx); + + void forward(TVctr_c& mx_i, TVctr_c& mx_o); + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o); + + private: + cufftHandle plan_forward; + cufftHandle plan_backward; + }; +} + +/* gpu fourier transform - dt_float64 */ +namespace mt +{ + template <> + class FFT + { + public: + using value_type = dt_float64; + static const eDev device = edev_gpu; + + using TVctr_c = Vctr, edev_gpu>; + + FFT(); + + FFT(const dt_int32& s0, Stream_gpu* pstream = nullptr); + + FFT(const dt_int32& s0, const dt_int32& s1, Stream_gpu* pstream = nullptr); + + ~FFT(); + + void cleanup(); + + void destroy_plan(); + + void create_plan_1d(const dt_int32& s0, dt_int32 n_thread=1); + + void create_plan_1d_batch(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d(const dt_int32& s0, const dt_int32& s1, dt_int32 n_thread=1); + + void create_plan_2d_batch(const dt_int32& s0, const dt_int32& s1, const dt_int32& s2, dt_int32 n_thread=1); + + void forward(TVctr_c& mx); + + void inverse(TVctr_c& mx); + + void forward(TVctr_c& mx_i, TVctr_c& mx_o); + + void inverse(TVctr_c& mx_i, TVctr_c& mx_o); + + private: + cufftHandle plan_forward; + cufftHandle plan_backward; + }; +} + +#include "detail/fft_gpu.inl" + +#endif \ No newline at end of file diff --git a/src/fftw3.h b/src/fftw3.h old mode 100644 new mode 100755 index d3313960..aa0a2dcb --- a/src/fftw3.h +++ b/src/fftw3.h @@ -1,415 +1,415 @@ -/* - * Copyright (c) 2003, 2007-14 Matteo Frigo - * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology - * - * The following statement of license applies *only* to this header file, - * and *not* to the other files distributed with FFTW or derived therefrom: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/***************************** NOTE TO USERS ********************************* - * - * THIS IS A HEADER FILE, NOT A MANUAL - * - * If you want to know how to use FFTW, please read the manual, - * online at http:// www.fftw.org/doc/ and also included with FFTW. - * For a quick start, see the manual's tutorial section. - * - * (Reading header files to learn how to use a library is a habit - * stemming from code lacking a proper manual. Arguably, it's a - * *bad* habit in most cases, because header files can contain - * interfaces that are not part of the public, stable API.) - * - ****************************************************************************/ - -#ifndef FFTW3_H -#define FFTW3_H - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* If is included, use the C99 complex type. Otherwise - define a type bit-compatible with C99 complex */ -#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) -# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C -#else -# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] -#endif - -#define FFTW_CONCAT(prefix, name) prefix ## name -#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) -#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) -#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) -#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) - -/* IMPORTANT: for Windows compilers, you should add a line -*/ -#define FFTW_DLL -/* - here and in kernel/ifftw.h if you are compiling/using FFTW as a - DLL, in order to do the proper importing/exporting, or - alternatively compile with -DFFTW_DLL or the equivalent - command-line flag. This is not necessary under MinGW/Cygwin, where - libtool does the imports/exports automatically. */ -#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) - /* annoying Windows syntax for shared-library declarations */ -# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ -# define FFTW_EXTERN extern __declspec(dllexport) -# else /* user is calling FFTW; import symbol */ -# define FFTW_EXTERN extern __declspec(dllimport) -# endif -#else -# define FFTW_EXTERN extern -#endif - -enum fftw_r2r_kind_do_not_use_me { - FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, - FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, - FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 -}; - -struct fftw_iodim_do_not_use_me { - int n; /* dimension size */ - int is; /* input stride */ - int os; /* output stride */ -}; - -#include /* for ptrdiff_t */ -struct fftw_iodim64_do_not_use_me { - ptrdiff_t n; /* dimension size */ - ptrdiff_t is; /* input stride */ - ptrdiff_t os; /* output stride */ -}; - -typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *); -typedef int (*fftw_read_char_func_do_not_use_me)(void *); - -/* - huge second-order macro that defines prototypes for all API - functions. We expand this macro for each supported precision - - X: name-mangling macro - R: real data type - C: complex data type -*/ - -#define FFTW_DEFINE_API(X, R, C) \ - \ -FFTW_DEFINE_COMPLEX(R, C); \ - \ -typedef struct X(plan_s) *X(plan); \ - \ -typedef struct fftw_iodim_do_not_use_me X(iodim); \ -typedef struct fftw_iodim64_do_not_use_me X(iodim64); \ - \ -typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ - \ -typedef fftw_write_char_func_do_not_use_me X(write_char_func); \ -typedef fftw_read_char_func_do_not_use_me X(read_char_func); \ - \ -FFTW_EXTERN void X(execute)(const X(plan) p); \ - \ -FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \ - C *in, C *out, int sign, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \ - unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \ - C *in, C *out, int sign, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \ - C *in, C *out, int sign, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \ - int howmany, \ - C *in, const int *inembed, \ - int istride, int idist, \ - C *out, const int *onembed, \ - int ostride, int odist, \ - int sign, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \ - int howmany_rank, \ - const X(iodim) *howmany_dims, \ - C *in, C *out, \ - int sign, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ - int howmany_rank, \ - const X(iodim) *howmany_dims, \ - R *ri, R *ii, R *ro, R *io, \ - unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \ - const X(iodim64) *dims, \ - int howmany_rank, \ - const X(iodim64) *howmany_dims, \ - C *in, C *out, \ - int sign, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \ - const X(iodim64) *dims, \ - int howmany_rank, \ - const X(iodim64) *howmany_dims, \ - R *ri, R *ii, R *ro, R *io, \ - unsigned flags); \ - \ -FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \ -FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ - R *ro, R *io); \ - \ -FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \ - int howmany, \ - R *in, const int *inembed, \ - int istride, int idist, \ - C *out, const int *onembed, \ - int ostride, int odist, \ - unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \ - R *in, C *out, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n, R *in, C *out, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \ - R *in, C *out, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \ - int n2, \ - R *in, C *out, unsigned flags); \ - \ - \ -FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \ - int howmany, \ - C *in, const int *inembed, \ - int istride, int idist, \ - R *out, const int *onembed, \ - int ostride, int odist, \ - unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \ - C *in, R *out, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n, C *in, R *out, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \ - C *in, R *out, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \ - int n2, \ - C *in, R *out, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ - int howmany_rank, \ - const X(iodim) *howmany_dims, \ - R *in, C *out, \ - unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ - int howmany_rank, \ - const X(iodim) *howmany_dims, \ - C *in, R *out, \ - unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \ - int rank, const X(iodim) *dims, \ - int howmany_rank, \ - const X(iodim) *howmany_dims, \ - R *in, R *ro, R *io, \ - unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \ - int rank, const X(iodim) *dims, \ - int howmany_rank, \ - const X(iodim) *howmany_dims, \ - R *ri, R *ii, R *out, \ - unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \ - const X(iodim64) *dims, \ - int howmany_rank, \ - const X(iodim64) *howmany_dims, \ - R *in, C *out, \ - unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \ - const X(iodim64) *dims, \ - int howmany_rank, \ - const X(iodim64) *howmany_dims, \ - C *in, R *out, \ - unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \ - int rank, const X(iodim64) *dims, \ - int howmany_rank, \ - const X(iodim64) *howmany_dims, \ - R *in, R *ro, R *io, \ - unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \ - int rank, const X(iodim64) *dims, \ - int howmany_rank, \ - const X(iodim64) *howmany_dims, \ - R *ri, R *ii, R *out, \ - unsigned flags); \ - \ -FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ -FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ - \ -FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \ - R *in, R *ro, R *io); \ -FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \ - R *ri, R *ii, R *out); \ - \ -FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \ - int howmany, \ - R *in, const int *inembed, \ - int istride, int idist, \ - R *out, const int *onembed, \ - int ostride, int odist, \ - const X(r2r_kind) *kind, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \ - const X(r2r_kind) *kind, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \ - X(r2r_kind) kind, unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ - X(r2r_kind) kind0, X(r2r_kind) kind1, \ - unsigned flags); \ -FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \ - R *in, R *out, X(r2r_kind) kind0, \ - X(r2r_kind) kind1, X(r2r_kind) kind2, \ - unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ - int howmany_rank, \ - const X(iodim) *howmany_dims, \ - R *in, R *out, \ - const X(r2r_kind) *kind, unsigned flags); \ - \ -FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \ - int howmany_rank, \ - const X(iodim64) *howmany_dims, \ - R *in, R *out, \ - const X(r2r_kind) *kind, unsigned flags); \ - \ -FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \ - \ -FFTW_EXTERN void X(destroy_plan)(X(plan) p); \ -FFTW_EXTERN void X(forget_wisdom)(void); \ -FFTW_EXTERN void X(cleanup)(void); \ - \ -FFTW_EXTERN void X(set_timelimit)(double t); \ - \ -FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \ -FFTW_EXTERN int X(init_threads)(void); \ -FFTW_EXTERN void X(cleanup_threads)(void); \ -FFTW_EXTERN void X(make_planner_thread_safe)(void); \ - \ -FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \ -FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \ -FFTW_EXTERN char *X(export_wisdom_to_string)(void); \ -FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \ - void *data); \ -FFTW_EXTERN int X(import_system_wisdom)(void); \ -FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \ -FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \ -FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \ -FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \ - \ -FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \ -FFTW_EXTERN void X(print_plan)(const X(plan) p); \ -FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \ - \ -FFTW_EXTERN void *X(malloc)(size_t n); \ -FFTW_EXTERN R *X(alloc_real)(size_t n); \ -FFTW_EXTERN C *X(alloc_complex)(size_t n); \ -FFTW_EXTERN void X(free)(void *p); \ - \ -FFTW_EXTERN void X(flops)(const X(plan) p, \ - double *add, double *mul, double *fmas); \ -FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \ -FFTW_EXTERN double X(cost)(const X(plan) p); \ - \ -FFTW_EXTERN int X(alignment_of)(R *p); \ -FFTW_EXTERN const char X(version)[]; \ -FFTW_EXTERN const char X(cc)[]; \ -FFTW_EXTERN const char X(codelet_optim)[]; - - -/* end of FFTW_DEFINE_API macro */ - -FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) -FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) -FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) - -/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64 - for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */ -#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \ - && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \ - && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__)) -# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) -/* note: __float128 is a typedef, which is not supported with the _Complex - keyword in gcc, so instead we use this ugly __attribute__ version. - However, we can't simply pass the __attribute__ version to - FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer - types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */ -# undef FFTW_DEFINE_COMPLEX -# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C -# endif -FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex) -#endif - -#define FFTW_FORWARD (-1) -#define FFTW_BACKWARD (+1) - -#define FFTW_NO_TIMELIMIT (-1.0) - -/* documented flags */ -#define FFTW_MEASURE (0U) -#define FFTW_DESTROY_INPUT (1U << 0) -#define FFTW_UNALIGNED (1U << 1) -#define FFTW_CONSERVE_MEMORY (1U << 2) -#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ -#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ -#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ -#define FFTW_ESTIMATE (1U << 6) -#define FFTW_WISDOM_ONLY (1U << 21) - -/* undocumented beyond-guru flags */ -#define FFTW_ESTIMATE_PATIENT (1U << 7) -#define FFTW_BELIEVE_PCOST (1U << 8) -#define FFTW_NO_DFT_R2HC (1U << 9) -#define FFTW_NO_NONTHREADED (1U << 10) -#define FFTW_NO_BUFFERING (1U << 11) -#define FFTW_NO_INDIRECT_OP (1U << 12) -#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ -#define FFTW_NO_RANK_SPLITS (1U << 14) -#define FFTW_NO_VRANK_SPLITS (1U << 15) -#define FFTW_NO_VRECURSE (1U << 16) -#define FFTW_NO_SIMD (1U << 17) -#define FFTW_NO_SLOW (1U << 18) -#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) -#define FFTW_ALLOW_PRUNING (1U << 20) - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* FFTW3_H */ +/* + * Copyright (c) 2003, 2007-14 Matteo Frigo + * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology + * + * The following statement of license applies *only* to this header file, + * and *not* to the other files distributed with FFTW or derived therefrom: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************** NOTE TO USERS ********************************* + * + * THIS IS A HEADER FILE, NOT A MANUAL + * + * If you want to know how to use FFTW, please read the manual, + * online at http:// www.fftw.org/doc/ and also included with FFTW. + * For a quick start, see the manual's tutorial section. + * + * (Reading header files to learn how to use a library is a habit + * stemming from code lacking a proper manual. Arguably, it's a + * *bad* habit in most cases, because header files can contain + * interfaces that are not part of the public, stable API.) + * + ****************************************************************************/ + +#ifndef FFTW3_H +#define FFTW3_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* If is included, use the C99 complex type. Otherwise + define a type bit-compatible with C99 complex */ +#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C +#else +# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] +#endif + +#define FFTW_CONCAT(prefix, name) prefix ## name +#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) +#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) +#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) +#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) + +/* IMPORTANT: for Windows compilers, you should add a line +*/ +#define FFTW_DLL +/* + here and in kernel/ifftw.h if you are compiling/using FFTW as a + DLL, in order to do the proper importing/exporting, or + alternatively compile with -DFFTW_DLL or the equivalent + command-line flag. This is not necessary under MinGW/Cygwin, where + libtool does the imports/exports automatically. */ +#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) + /* annoying Windows syntax for shared-library declarations */ +# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ +# define FFTW_EXTERN extern __declspec(dllexport) +# else /* user is calling FFTW; import symbol */ +# define FFTW_EXTERN extern __declspec(dllimport) +# endif +#else +# define FFTW_EXTERN extern +#endif + +enum fftw_r2r_kind_do_not_use_me { + FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, + FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, + FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 +}; + +struct fftw_iodim_do_not_use_me { + int n; /* dimension size */ + int is; /* input stride */ + int os; /* output stride */ +}; + +#include /* for ptrdiff_t */ +struct fftw_iodim64_do_not_use_me { + ptrdiff_t n; /* dimension size */ + ptrdiff_t is; /* input stride */ + ptrdiff_t os; /* output stride */ +}; + +typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *); +typedef int (*fftw_read_char_func_do_not_use_me)(void *); + +/* + huge second-order macro that defines prototypes for all API + functions. We expand this macro for each supported precision + + X: name-mangling macro + R: real data type + C: complex data type +*/ + +#define FFTW_DEFINE_API(X, R, C) \ + \ +FFTW_DEFINE_COMPLEX(R, C); \ + \ +typedef struct X(plan_s) *X(plan); \ + \ +typedef struct fftw_iodim_do_not_use_me X(iodim); \ +typedef struct fftw_iodim64_do_not_use_me X(iodim64); \ + \ +typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ + \ +typedef fftw_write_char_func_do_not_use_me X(write_char_func); \ +typedef fftw_read_char_func_do_not_use_me X(read_char_func); \ + \ +FFTW_EXTERN void X(execute)(const X(plan) p); \ + \ +FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \ + C *in, C *out, int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \ +FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ + R *ro, R *io); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n, R *in, C *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \ + R *in, C *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \ + int n2, \ + R *in, C *out, unsigned flags); \ + \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n, C *in, R *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \ + C *in, R *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \ + int n2, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ +FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ + \ +FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \ + R *in, R *ro, R *io); \ +FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \ + R *ri, R *ii, R *out); \ + \ +FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \ + X(r2r_kind) kind, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ + X(r2r_kind) kind0, X(r2r_kind) kind1, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \ + R *in, R *out, X(r2r_kind) kind0, \ + X(r2r_kind) kind1, X(r2r_kind) kind2, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \ + \ +FFTW_EXTERN void X(destroy_plan)(X(plan) p); \ +FFTW_EXTERN void X(forget_wisdom)(void); \ +FFTW_EXTERN void X(cleanup)(void); \ + \ +FFTW_EXTERN void X(set_timelimit)(double t); \ + \ +FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \ +FFTW_EXTERN int X(init_threads)(void); \ +FFTW_EXTERN void X(cleanup_threads)(void); \ +FFTW_EXTERN void X(make_planner_thread_safe)(void); \ + \ +FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \ +FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \ +FFTW_EXTERN char *X(export_wisdom_to_string)(void); \ +FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \ + void *data); \ +FFTW_EXTERN int X(import_system_wisdom)(void); \ +FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \ +FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \ +FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \ +FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \ + \ +FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \ +FFTW_EXTERN void X(print_plan)(const X(plan) p); \ +FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \ + \ +FFTW_EXTERN void *X(malloc)(size_t n); \ +FFTW_EXTERN R *X(alloc_real)(size_t n); \ +FFTW_EXTERN C *X(alloc_complex)(size_t n); \ +FFTW_EXTERN void X(free)(void *p); \ + \ +FFTW_EXTERN void X(flops)(const X(plan) p, \ + double *add, double *mul, double *fmas); \ +FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \ +FFTW_EXTERN double X(cost)(const X(plan) p); \ + \ +FFTW_EXTERN int X(alignment_of)(R *p); \ +FFTW_EXTERN const char X(version)[]; \ +FFTW_EXTERN const char X(cc)[]; \ +FFTW_EXTERN const char X(codelet_optim)[]; + + +/* end of FFTW_DEFINE_API macro */ + +FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) +FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) +FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) + +/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64 + for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */ +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \ + && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \ + && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__)) +# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +/* note: __float128 is a typedef, which is not supported with the _Complex + keyword in gcc, so instead we use this ugly __attribute__ version. + However, we can't simply pass the __attribute__ version to + FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer + types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */ +# undef FFTW_DEFINE_COMPLEX +# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C +# endif +FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex) +#endif + +#define FFTW_FORWARD (-1) +#define FFTW_BACKWARD (+1) + +#define FFTW_NO_TIMELIMIT (-1.0) + +/* documented flags */ +#define FFTW_MEASURE (0U) +#define FFTW_DESTROY_INPUT (1U << 0) +#define FFTW_UNALIGNED (1U << 1) +#define FFTW_CONSERVE_MEMORY (1U << 2) +#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ +#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ +#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ +#define FFTW_ESTIMATE (1U << 6) +#define FFTW_WISDOM_ONLY (1U << 21) + +/* undocumented beyond-guru flags */ +#define FFTW_ESTIMATE_PATIENT (1U << 7) +#define FFTW_BELIEVE_PCOST (1U << 8) +#define FFTW_NO_DFT_R2HC (1U << 9) +#define FFTW_NO_NONTHREADED (1U << 10) +#define FFTW_NO_BUFFERING (1U << 11) +#define FFTW_NO_INDIRECT_OP (1U << 12) +#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ +#define FFTW_NO_RANK_SPLITS (1U << 14) +#define FFTW_NO_VRANK_SPLITS (1U << 15) +#define FFTW_NO_VRECURSE (1U << 16) +#define FFTW_NO_SIMD (1U << 17) +#define FFTW_NO_SLOW (1U << 18) +#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) +#define FFTW_ALLOW_PRUNING (1U << 20) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* FFTW3_H */ diff --git a/src/fxeg_data.hpp b/src/fxeg_data.hpp old mode 100644 new mode 100755 index 7ab0f894..bcf02f59 --- a/src/fxeg_data.hpp +++ b/src/fxeg_data.hpp @@ -1,24540 +1,816 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef FXEG_DATA_H -#define FXEG_DATA_H - -#ifdef _MSC_VER -#pragma once -#endif// _MSC_VER - -#include "math.cuh" -#include "types.cuh" - -class fxeg_Tabulated_Data{ - public: - void ReadTabData(int Z_i, int Type_i, int dng_i, int &n_o, double *g_o, double *g2_o, double *fx_o, double *fe_o) - { - - switch(Type_i) - { - case 0: - { - fxegActaCrys(Z_i); - } - break; - case 1: - { - fxegRez(Z_i); - } - break; - case 2: - { - fxegKirkland(Z_i); - } - break; - case 3: - { - fxegLobato(Z_i); - } - break; - } - - if(dng_i == 0 ) - { - dng_i = 1; - } - - int i = 0, j = 0; - - while (j0) - { - feg[i] = (Z-fxg[i])/(mt::c_2Pi2a0*g2[i]); - } - } - - g.resize(ng); - g2.resize(ng); - fxg.resize(ng); - feg.resize(ng); - } - - void fxegLobato(int Z) - { - - } - - mt::Vector g; - mt::Vector g2; - mt::Vector feg; - mt::Vector fxg; -}; - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef FXEG_DATA_H + #define FXEG_DATA_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "cgpu_vctr.cuh" + + namespace mt + { + template + class fxeg_Data + { + public: + + fxeg_Data(const dt_int32& typ, const dt_int32& Z, dt_int32 dng, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + operator()(typ, Z, dng, g, fxg, feg); + } + + void operator()(const dt_int32& typ, const dt_int32& Z, dt_int32 dng, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + switch(typ) + { + case 1: + { + load_fxeg_kirkland(Z, g, fxg, feg); + } + break; + case 2: + { + load_fxeg_lobato(Z, g, fxg, feg); + } + break; + } + + dng = max(1, dng); + + if (dng==1) + { + return; + } + + dt_int32 ig = 0; + dt_int32 ik = 0; + + while (ig < g.size()) + { + g[ik] = g[ig]; + fxg[ik] = fxg[ig]; + feg[ik] = feg[ig]; + + ig += dng; + ik++; + } + + g.resize(ik); + fxg.resize(ik); + feg.resize(ik); + } + + private: + void load_fxeg_kirkland(const dt_int32& Z, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + switch(Z) + { + case 1: + { + g = Vctr_cpu({0.0000000000000000e+00, 5.0000000000000003e-02, 1.0000000000000001e-01, 1.5000000000000002e-01, 2.0000000000000001e-01, 2.5000000000000000e-01, 3.0000000000000004e-01, 3.5000000000000003e-01, 4.0000000000000002e-01, 4.5000000000000001e-01, 5.0000000000000000e-01, 5.5000000000000004e-01, 6.0000000000000009e-01, 6.5000000000000002e-01, 7.0000000000000007e-01, 7.5000000000000000e-01, 8.0000000000000004e-01, 8.5000000000000009e-01, 9.0000000000000002e-01, 9.5000000000000007e-01, 1.0000000000000000e+00, 1.0500000000000000e+00, 1.1000000000000001e+00, 1.1500000000000001e+00, 1.2000000000000002e+00, 1.2500000000000000e+00, 1.3000000000000000e+00, 1.3500000000000001e+00, 1.4000000000000001e+00, 1.4500000000000002e+00, 1.5000000000000000e+00, 1.5500000000000000e+00, 1.6000000000000001e+00, 1.6500000000000001e+00, 1.7000000000000002e+00, 1.7500000000000000e+00, 1.7999999999999998e+00, 1.8499999999999999e+00, 1.8999999999999999e+00, 1.9500000000000000e+00, 2.0000000000000000e+00, 2.0499999999999998e+00, 2.0999999999999996e+00, 2.1499999999999999e+00, 2.2000000000000002e+00, 2.2500000000000000e+00, 2.2999999999999998e+00, 2.3499999999999996e+00, 2.3999999999999999e+00, 2.4500000000000002e+00, 2.5000000000000000e+00, 2.5499999999999998e+00, 2.6000000000000001e+00, 2.6499999999999999e+00, 2.7000000000000002e+00, 2.7500000000000000e+00, 2.7999999999999998e+00, 2.8500000000000001e+00, 2.8999999999999999e+00, 2.9500000000000002e+00, 3.0000000000000000e+00, 3.0499999999999998e+00, 3.1000000000000001e+00, 3.1499999999999999e+00, 3.2000000000000002e+00, 3.2500000000000000e+00, 3.2999999999999998e+00, 3.3500000000000001e+00, 3.3999999999999999e+00, 3.4500000000000002e+00, 3.5000000000000000e+00}); + fxg = Vctr_cpu({1.0000000000000000e+00, 9.8632305882146931e-01, 9.4693449431522780e-01, 8.8633888266404548e-01, 8.1081751005624991e-01, 7.2710935171612368e-01, 6.4129284612105375e-01, 5.5811420076772189e-01, 4.8078069526412032e-01, 4.1109116523666106e-01, 3.4973752174225664e-01, 2.9664389797585239e-01, 2.5126541911343342e-01, 2.1281605988549140e-01, 1.8042458218770130e-01, 1.5323114063569815e-01, 1.3044056400490822e-01, 1.1134671897585470e-01, 9.5339049733758591e-02, 8.1899049191269432e-02, 7.0591706678070243e-02, 6.1055010645627322e-02, 5.2989260870033097e-02, 4.6147102560467279e-02, 4.0324686038064640e-02, 3.5354064709704515e-02, 3.1096789143846087e-02, 2.7438581628507139e-02, 2.4284948842277231e-02, 2.1557588759807365e-02, 1.9191458882981287e-02, 1.7132389020261554e-02, 1.5335139128426002e-02, 1.3761819146890376e-02, 1.2380602387067150e-02, 1.1164676602016449e-02, 1.0091387392769066e-02, 9.1415372965883562e-03, 8.2988109947624063e-03, 7.5493028247337795e-03, 6.8811274161826828e-03, 6.2840979969970810e-03, 5.7494599057461293e-03, 5.2696692457298404e-03, 4.8382085391719138e-03, 4.4494327835947738e-03, 4.0984405522127504e-03, 3.7809657774127946e-03, 3.4932866598361241e-03, 3.2321487940852357e-03, 2.9947001265890577e-03, 2.7784357862813153e-03, 2.5811511740829116e-03, 2.4009019783462399e-03, 2.2359700128773063e-03, 2.0848339618541214e-03, 1.9461442698720168e-03, 1.8187015418536596e-03, 1.7014379217915681e-03, 1.5934010053713723e-03, 1.4937399127832802e-03, 1.4016932071572960e-03, 1.3165783932337139e-03, 1.2377827718729815e-03, 1.1647554602571618e-03, 1.0970004163124516e-03, 1.0340703299472009e-03, 9.7556126393818577e-04, 9.2110794435402944e-04, 8.7037961480902445e-04, 8.2307638103044142e-04}); + feg = Vctr_cpu({5.2917721077817892e-01, 5.2374283721610537e-01, 5.0802072888340088e-01, 4.8361362625383103e-01, 4.5278295755871933e-01, 4.1800142448896865e-01, 3.8156335147101500e-01, 3.4533697651742540e-01, 3.1067047020286392e-01, 2.7841470405691926e-01, 2.4901058712784352e-01, 2.2259684610025274e-01, 1.9911066238571343e-01, 1.7836869626462978e-01, 1.6012604235474073e-01, 1.4411576034945436e-01, 1.3007337958444765e-01, 1.1775073410121434e-01, 1.0692270852136421e-01, 9.7389548551727517e-02, 8.8976571976619706e-02, 8.1532484512507719e-02, 7.4927054427602918e-02, 6.9048595422691400e-02, 6.3801510013041379e-02, 5.9104022452155423e-02, 5.4886156119332841e-02, 5.1087967646298020e-02, 4.7658027013818209e-02, 4.4552121661498537e-02, 4.1732158397521382e-02, 3.9165236509655137e-02, 3.6822867106561567e-02, 3.4680316261132417e-02, 3.2716052358321902e-02, 3.0911280828591629e-02, 2.9249552005489250e-02, 2.7716430112046362e-02, 2.6299213340960925e-02, 2.4986696662356037e-02, 2.3768970398348299e-02, 2.2637248778637105e-02, 2.1583723668818808e-02, 2.0601439473761522e-02, 1.9684185889370136e-02, 1.8826405730974674e-02, 1.8023115525393936e-02, 1.7269836933243830e-02, 1.6562537382241456e-02, 1.5897578552651559e-02, 1.5271671572146013e-02, 1.4681837957018844e-02, 1.4125375486332256e-02, 1.3599828320422766e-02, 1.3102960779581179e-02, 1.2632734286171021e-02, 1.2187287046867289e-02, 1.1764916113465184e-02, 1.1364061512785639e-02, 1.0983292180206397e-02, 1.0621293468605932e-02, 1.0276856036123242e-02, 9.9488659430214364e-03, 9.6362958108527057e-03, 9.3381969166852260e-03, 9.0536921118920307e-03, 8.7819694693541655e-03, 8.5222765752608377e-03, 8.2739153923030301e-03, 8.0362376302109979e-03, 7.8086405674960340e-03}); + } + break; + case 2: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00}); + fxg = Vctr_cpu({2.0000e+00, 1.9891e+00, 1.9571e+00, 1.9056e+00, 1.8372e+00, 1.7550e+00, 1.6626e+00, 1.5633e+00, 1.4603e+00, 1.3565e+00, 1.2541e+00, 1.1548e+00, 1.0601e+00, 9.7070e-01, 8.8710e-01, 8.0960e-01, 7.3820e-01, 6.7270e-01, 6.1290e-01, 5.5830e-01, 5.0880e-01, 4.6380e-01, 4.2310e-01, 3.8620e-01, 3.5280e-01, 3.2260e-01, 2.9520e-01, 2.7040e-01, 2.4800e-01, 2.2760e-01, 2.0910e-01, 1.9240e-01, 1.7720e-01, 1.6330e-01, 1.5070e-01, 1.3930e-01, 1.2880e-01, 1.1920e-01, 1.1050e-01, 1.0250e-01, 9.5200e-02, 8.8500e-02, 8.2300e-02, 7.6700e-02, 7.1500e-02, 6.6700e-02, 6.2300e-02, 5.8300e-02, 5.4500e-02, 5.1100e-02, 4.7900e-02, 4.4900e-02, 4.2200e-02, 3.9600e-02, 3.7200e-02, 3.5100e-02, 3.3000e-02, 3.1100e-02, 2.9300e-02, 2.7700e-02, 2.6200e-02, 2.4700e-02, 2.3400e-02, 2.2100e-02, 2.1000e-02, 1.9900e-02, 1.8800e-02, 1.7900e-02, 1.7000e-02, 1.6100e-02, 1.5300e-02, 1.4600e-02, 1.3900e-02, 1.3200e-02, 1.2600e-02, 1.2000e-02, 1.1400e-02, 1.0900e-02, 1.0400e-02, 9.9000e-03}); + feg = Vctr_cpu({4.1800e-01, 4.1610e-01, 4.1060e-01, 4.0160e-01, 3.8960e-01, 3.7520e-01, 3.5890e-01, 3.4130e-01, 3.2290e-01, 3.0420e-01, 2.8570e-01, 2.6750e-01, 2.4990e-01, 2.3320e-01, 2.1740e-01, 2.0260e-01, 1.8870e-01, 1.7590e-01, 1.6390e-01, 1.5290e-01, 1.4280e-01, 1.3340e-01, 1.2480e-01, 1.1680e-01, 1.0950e-01, 1.0280e-01, 9.6600e-02, 9.0900e-02, 8.5600e-02, 8.0700e-02, 7.6200e-02, 7.2000e-02, 6.8200e-02, 6.4600e-02, 6.1300e-02, 5.8200e-02, 5.5300e-02, 5.2600e-02, 5.0100e-02, 4.7800e-02, 4.5600e-02, 4.3500e-02, 4.1600e-02, 3.9800e-02, 3.8100e-02, 3.6600e-02, 3.5100e-02, 3.3700e-02, 3.2300e-02, 3.1100e-02, 2.9900e-02, 2.8800e-02, 2.7700e-02, 2.6700e-02, 2.5800e-02, 2.4900e-02, 2.4000e-02, 2.3200e-02, 2.2400e-02, 2.1700e-02, 2.1000e-02, 2.0300e-02, 1.9700e-02, 1.9100e-02, 1.8500e-02, 1.7900e-02, 1.7400e-02, 1.6900e-02, 1.6400e-02, 1.6000e-02, 1.5500e-02, 1.5100e-02, 1.4700e-02, 1.4300e-02, 1.3900e-02, 1.3500e-02, 1.3200e-02, 1.2800e-02, 1.2500e-02, 1.2200e-02}); + } + break; + case 3: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00}); + fxg = Vctr_cpu({3.0000e+00, 2.9177e+00, 2.7075e+00, 2.4501e+00, 2.2151e+00, 2.0332e+00, 1.9037e+00, 1.8117e+00, 1.7416e+00, 1.6821e+00, 1.6261e+00, 1.5701e+00, 1.5127e+00, 1.4537e+00, 1.3932e+00, 1.3320e+00, 1.2705e+00, 1.2094e+00, 1.1491e+00, 1.0901e+00, 1.0327e+00, 9.7710e-01, 9.2370e-01, 8.7240e-01, 8.2340e-01, 7.7670e-01, 7.3230e-01, 6.9030e-01, 6.5050e-01, 6.1290e-01, 5.7740e-01, 5.4390e-01, 5.1240e-01, 4.8280e-01, 4.5500e-01, 4.2880e-01, 4.0430e-01, 3.8120e-01, 3.5960e-01, 3.3930e-01, 3.2030e-01, 3.0240e-01, 2.8560e-01, 2.6990e-01, 2.5510e-01, 2.4130e-01, 2.2830e-01, 2.1610e-01, 2.0460e-01, 1.9380e-01, 1.8370e-01, 1.7420e-01, 1.6520e-01, 1.5680e-01, 1.4890e-01, 1.4140e-01, 1.3430e-01, 1.2770e-01, 1.2150e-01, 1.1560e-01, 1.1000e-01, 1.0480e-01, 9.9800e-02, 9.5100e-02, 9.0700e-02, 8.6600e-02, 8.2600e-02, 7.8800e-02, 7.5300e-02, 7.2000e-02, 6.8800e-02, 6.5800e-02, 6.3000e-02, 6.0300e-02, 5.7700e-02, 5.5200e-02, 5.2900e-02, 5.0800e-02, 4.8700e-02, 4.6600e-02, 4.4700e-02, 4.3000e-02, 4.1300e-02, 3.9600e-02, 3.7900e-02, 3.6500e-02, 3.5200e-02, 3.4000e-02, 3.2600e-02, 3.1200e-02, 3.0000e-02, 2.9100e-02, 2.8100e-02, 2.7000e-02, 2.5800e-02, 2.4800e-02, 2.4100e-02, 2.3500e-02, 2.2700e-02, 2.1700e-02, 2.0700e-02, 2.0000e-02, 1.9500e-02, 1.9100e-02, 1.8500e-02, 1.7600e-02, 1.6700e-02, 1.6200e-02, 1.5900e-02, 1.5700e-02, 1.5300e-02, 1.4600e-02, 1.3700e-02, 1.3100e-02, 1.2900e-02, 1.2900e-02, 1.2800e-02, 1.2300e-02, 1.1600e-02, 1.0900e-02, 1.0400e-02, 1.0400e-02, 1.0500e-02, 1.0500e-02, 1.0100e-02, 9.4000e-03}); + feg = Vctr_cpu({3.2861e+00, 3.1524e+00, 2.8000e+00, 2.3396e+00, 1.8787e+00, 1.4809e+00, 1.1662e+00, 9.2870e-01, 7.5290e-01, 6.2310e-01, 5.2610e-01, 4.5250e-01, 3.9550e-01, 3.5040e-01, 3.1390e-01, 2.8390e-01, 2.5870e-01, 2.3730e-01, 2.1880e-01, 2.0260e-01, 1.8830e-01, 1.7570e-01, 1.6430e-01, 1.5400e-01, 1.4470e-01, 1.3620e-01, 1.2850e-01, 1.2130e-01, 1.1480e-01, 1.0870e-01, 1.0310e-01, 9.7900e-02, 9.3000e-02, 8.8500e-02, 8.4300e-02, 8.0400e-02, 7.6700e-02, 7.3300e-02, 7.0000e-02, 6.7000e-02, 6.4100e-02, 6.1500e-02, 5.8900e-02, 5.6500e-02, 5.4300e-02, 5.2200e-02, 5.0200e-02, 4.8300e-02, 4.6500e-02, 4.4800e-02, 4.3100e-02, 4.1600e-02, 4.0100e-02, 3.8800e-02, 3.7400e-02, 3.6200e-02, 3.5000e-02, 3.3900e-02, 3.2800e-02, 3.1700e-02, 3.0700e-02, 2.9800e-02, 2.8900e-02, 2.8000e-02, 2.7200e-02, 2.6400e-02, 2.5600e-02, 2.4900e-02, 2.4200e-02, 2.3600e-02, 2.2900e-02, 2.2300e-02, 2.1700e-02, 2.1100e-02, 2.0600e-02, 2.0000e-02, 1.9500e-02, 1.9000e-02, 1.8600e-02, 1.8100e-02, 1.7700e-02, 1.7300e-02, 1.6800e-02, 1.6500e-02, 1.6100e-02, 1.5700e-02, 1.5400e-02, 1.5000e-02, 1.4700e-02, 1.4400e-02, 1.4000e-02, 1.3700e-02, 1.3400e-02, 1.3200e-02, 1.2900e-02, 1.2600e-02, 1.2400e-02, 1.2100e-02, 1.1900e-02, 1.1600e-02, 1.1400e-02, 1.1200e-02, 1.1000e-02, 1.0800e-02, 1.0600e-02, 1.0400e-02, 1.0200e-02, 1.0000e-02, 9.8000e-03, 9.6000e-03, 9.4000e-03, 9.3000e-03, 9.1000e-03, 9.0000e-03, 8.8000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.4000e-03, 7.3000e-03}); + } + break; + case 4: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00}); + fxg = Vctr_cpu({4.0000e+00, 3.9219e+00, 3.7067e+00, 3.4022e+00, 3.0652e+00, 2.7426e+00, 2.4626e+00, 2.2356e+00, 2.0598e+00, 1.9272e+00, 1.8277e+00, 1.7520e+00, 1.6923e+00, 1.6429e+00, 1.5996e+00, 1.5594e+00, 1.5205e+00, 1.4818e+00, 1.4427e+00, 1.4029e+00, 1.3623e+00, 1.3211e+00, 1.2794e+00, 1.2374e+00, 1.1953e+00, 1.1534e+00, 1.1117e+00, 1.0705e+00, 1.0299e+00, 9.9010e-01, 9.5120e-01, 9.1330e-01, 8.7640e-01, 8.4050e-01, 8.0580e-01, 7.7230e-01, 7.3990e-01, 7.0870e-01, 6.7870e-01, 6.4990e-01, 6.2220e-01, 5.9560e-01, 5.7010e-01, 5.4570e-01, 5.2230e-01, 4.9990e-01, 4.7850e-01, 4.5810e-01, 4.3860e-01, 4.1990e-01, 4.0210e-01, 3.8510e-01, 3.6880e-01, 3.5330e-01, 3.3850e-01, 3.2440e-01, 3.1090e-01, 2.9810e-01, 2.8580e-01, 2.7410e-01, 2.6290e-01, 2.5220e-01, 2.4210e-01, 2.3240e-01, 2.2310e-01, 2.1420e-01, 2.0580e-01, 1.9770e-01, 1.9000e-01, 1.8260e-01, 1.7560e-01, 1.6880e-01, 1.6240e-01, 1.5620e-01, 1.5040e-01, 1.4470e-01, 1.3940e-01, 1.3420e-01, 1.2930e-01, 1.2460e-01, 1.2010e-01, 1.1570e-01, 1.1160e-01, 1.0760e-01, 1.0380e-01, 1.0020e-01, 9.6700e-02, 9.3300e-02, 9.0100e-02, 8.7000e-02, 8.4100e-02, 8.1200e-02, 7.8500e-02, 7.5800e-02, 7.3300e-02, 7.1000e-02, 6.8700e-02, 6.6400e-02, 6.4200e-02, 6.2100e-02, 6.0200e-02, 5.8400e-02, 5.6500e-02, 5.4700e-02, 5.2900e-02, 5.1300e-02, 4.9800e-02, 4.8400e-02, 4.6900e-02, 4.5300e-02, 4.3900e-02, 4.2600e-02, 4.1400e-02, 4.0400e-02, 3.9200e-02, 3.7900e-02, 3.6700e-02, 3.5600e-02, 3.4600e-02, 3.3800e-02, 3.3000e-02, 3.2100e-02, 3.1000e-02, 2.9900e-02, 2.9100e-02, 2.8400e-02, 2.7800e-02, 2.7300e-02, 2.6500e-02, 2.5600e-02, 2.4700e-02, 2.3900e-02, 2.3300e-02, 2.3000e-02, 2.2600e-02, 2.2200e-02, 2.1500e-02, 2.0600e-02, 1.9800e-02, 1.9200e-02, 1.8900e-02, 1.8800e-02, 1.8600e-02, 1.8200e-02, 1.7600e-02, 1.6800e-02, 1.6100e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5300e-02, 1.5200e-02, 1.4700e-02, 1.4100e-02, 1.3300e-02, 1.2700e-02, 1.2400e-02, 1.2400e-02, 1.2500e-02, 1.2600e-02, 1.2500e-02, 1.2100e-02, 1.1500e-02, 1.0700e-02, 1.0200e-02, 9.9000e-03}); + feg = Vctr_cpu({3.0539e+00, 2.9892e+00, 2.8078e+00, 2.5434e+00, 2.2372e+00, 1.9260e+00, 1.6354e+00, 1.3789e+00, 1.1609e+00, 9.8000e-01, 8.3190e-01, 7.1150e-01, 6.1370e-01, 5.3410e-01, 4.6900e-01, 4.1540e-01, 3.7090e-01, 3.3370e-01, 3.0230e-01, 2.7550e-01, 2.5250e-01, 2.3260e-01, 2.1520e-01, 2.0000e-01, 1.8650e-01, 1.7440e-01, 1.6360e-01, 1.5390e-01, 1.4510e-01, 1.3710e-01, 1.2970e-01, 1.2300e-01, 1.1680e-01, 1.1110e-01, 1.0580e-01, 1.0090e-01, 9.6300e-02, 9.2100e-02, 8.8100e-02, 8.4300e-02, 8.0800e-02, 7.7600e-02, 7.4500e-02, 7.1500e-02, 6.8800e-02, 6.6200e-02, 6.3700e-02, 6.1400e-02, 5.9200e-02, 5.7100e-02, 5.5100e-02, 5.3200e-02, 5.1400e-02, 4.9700e-02, 4.8100e-02, 4.6500e-02, 4.5000e-02, 4.3600e-02, 4.2300e-02, 4.1000e-02, 3.9800e-02, 3.8600e-02, 3.7400e-02, 3.6400e-02, 3.5300e-02, 3.4300e-02, 3.3400e-02, 3.2400e-02, 3.1600e-02, 3.0700e-02, 2.9900e-02, 2.9100e-02, 2.8300e-02, 2.7600e-02, 2.6900e-02, 2.6200e-02, 2.5600e-02, 2.5000e-02, 2.4400e-02, 2.3800e-02, 2.3200e-02, 2.2700e-02, 2.2100e-02, 2.1600e-02, 2.1100e-02, 2.0700e-02, 2.0200e-02, 1.9800e-02, 1.9300e-02, 1.8900e-02, 1.8500e-02, 1.8100e-02, 1.7700e-02, 1.7400e-02, 1.7000e-02, 1.6700e-02, 1.6300e-02, 1.6000e-02, 1.5700e-02, 1.5400e-02, 1.5100e-02, 1.4800e-02, 1.4500e-02, 1.4200e-02, 1.4000e-02, 1.3700e-02, 1.3500e-02, 1.3200e-02, 1.3000e-02, 1.2700e-02, 1.2500e-02, 1.2300e-02, 1.2100e-02, 1.1900e-02, 1.1700e-02, 1.1500e-02, 1.1300e-02, 1.1100e-02, 1.0900e-02, 1.0700e-02, 1.0500e-02, 1.0400e-02, 1.0200e-02, 1.0000e-02, 9.9000e-03, 9.7000e-03, 9.6000e-03, 9.4000e-03, 9.3000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.4000e-03, 6.4000e-03, 6.3000e-03, 6.2000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03}); + } + break; + case 5: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01}); + fxg = Vctr_cpu({5.0000e+00, 4.9281e+00, 4.7244e+00, 4.4211e+00, 4.0599e+00, 3.6809e+00, 3.3160e+00, 2.9853e+00, 2.6989e+00, 2.4589e+00, 2.2627e+00, 2.1048e+00, 1.9790e+00, 1.8789e+00, 1.7989e+00, 1.7342e+00, 1.6808e+00, 1.6354e+00, 1.5958e+00, 1.5599e+00, 1.5265e+00, 1.4946e+00, 1.4634e+00, 1.4325e+00, 1.4017e+00, 1.3706e+00, 1.3393e+00, 1.3077e+00, 1.2758e+00, 1.2438e+00, 1.2116e+00, 1.1793e+00, 1.1471e+00, 1.1151e+00, 1.0832e+00, 1.0517e+00, 1.0205e+00, 9.8970e-01, 9.5940e-01, 9.2960e-01, 9.0040e-01, 8.7170e-01, 8.4380e-01, 8.1650e-01, 7.8980e-01, 7.6390e-01, 7.3860e-01, 7.1410e-01, 6.9020e-01, 6.6710e-01, 6.4470e-01, 6.2290e-01, 6.0190e-01, 5.8150e-01, 5.6180e-01, 5.4270e-01, 5.2430e-01, 5.0650e-01, 4.8930e-01, 4.7270e-01, 4.5670e-01, 4.4120e-01, 4.2630e-01, 4.1200e-01, 3.9810e-01, 3.8470e-01, 3.7180e-01, 3.5940e-01, 3.4740e-01, 3.3580e-01, 3.2470e-01, 3.1400e-01, 3.0360e-01, 2.9370e-01, 2.8410e-01, 2.7480e-01, 2.6590e-01, 2.5730e-01, 2.4900e-01, 2.4100e-01, 2.3330e-01, 2.2590e-01, 2.1870e-01, 2.1180e-01, 2.0520e-01, 1.9880e-01, 1.9260e-01, 1.8660e-01, 1.8090e-01, 1.7530e-01, 1.7000e-01, 1.6480e-01, 1.5980e-01, 1.5500e-01, 1.5030e-01, 1.4590e-01, 1.4160e-01, 1.3740e-01, 1.3330e-01, 1.2940e-01, 1.2570e-01, 1.2210e-01, 1.1850e-01, 1.1510e-01, 1.1180e-01, 1.0860e-01, 1.0560e-01, 1.0270e-01, 9.9800e-02, 9.7000e-02, 9.4300e-02, 9.1700e-02, 8.9200e-02, 8.6800e-02, 8.4500e-02, 8.2200e-02, 7.9900e-02, 7.7700e-02, 7.5700e-02, 7.3800e-02, 7.1900e-02, 7.0000e-02, 6.8100e-02, 6.6300e-02, 6.4500e-02, 6.3000e-02, 6.1500e-02, 6.0000e-02, 5.8400e-02, 5.6900e-02, 5.5300e-02, 5.3900e-02, 5.2600e-02, 5.1500e-02, 5.0300e-02, 4.9100e-02, 4.7900e-02, 4.6600e-02, 4.5300e-02, 4.4200e-02, 4.3200e-02, 4.2400e-02, 4.1600e-02, 4.0600e-02, 3.9600e-02, 3.8500e-02, 3.7400e-02, 3.6500e-02, 3.5700e-02, 3.5100e-02, 3.4500e-02, 3.3900e-02, 3.3100e-02, 3.2100e-02, 3.1200e-02, 3.0300e-02, 2.9600e-02, 2.9100e-02, 2.8800e-02, 2.8400e-02, 2.7900e-02, 2.7200e-02, 2.6400e-02, 2.5500e-02, 2.4700e-02, 2.4200e-02, 2.3800e-02, 2.3600e-02, 2.3500e-02, 2.3200e-02, 2.2700e-02, 2.2000e-02, 2.1200e-02, 2.0500e-02, 1.9900e-02, 1.9500e-02, 1.9300e-02, 1.9300e-02, 1.9300e-02, 1.9100e-02, 1.8700e-02, 1.8100e-02, 1.7400e-02, 1.6600e-02, 1.6100e-02, 1.5700e-02, 1.5600e-02, 1.5700e-02, 1.5800e-02, 1.5900e-02, 1.5700e-02, 1.5300e-02, 1.4600e-02, 1.3900e-02, 1.3200e-02, 1.2700e-02, 1.2500e-02, 1.2600e-02, 1.2800e-02, 1.3000e-02, 1.3100e-02, 1.3100e-02, 1.2800e-02, 1.2200e-02, 1.1500e-02, 1.0700e-02, 1.0200e-02, 9.9000e-03}); + feg = Vctr_cpu({2.7950e+00, 2.7542e+00, 2.6382e+00, 2.4630e+00, 2.2501e+00, 2.0205e+00, 1.7913e+00, 1.5745e+00, 1.3769e+00, 1.2013e+00, 1.0482e+00, 9.1630e-01, 8.0340e-01, 7.0720e-01, 6.2540e-01, 5.5580e-01, 4.9650e-01, 4.4580e-01, 4.0230e-01, 3.6490e-01, 3.3250e-01, 3.0440e-01, 2.7980e-01, 2.5820e-01, 2.3920e-01, 2.2240e-01, 2.0740e-01, 1.9400e-01, 1.8190e-01, 1.7100e-01, 1.6120e-01, 1.5220e-01, 1.4410e-01, 1.3660e-01, 1.2970e-01, 1.2340e-01, 1.1760e-01, 1.1220e-01, 1.0720e-01, 1.0250e-01, 9.8100e-02, 9.4000e-02, 9.0200e-02, 8.6600e-02, 8.3300e-02, 8.0100e-02, 7.7100e-02, 7.4300e-02, 7.1600e-02, 6.9100e-02, 6.6700e-02, 6.4400e-02, 6.2300e-02, 6.0200e-02, 5.8300e-02, 5.6400e-02, 5.4700e-02, 5.3000e-02, 5.1300e-02, 4.9800e-02, 4.8300e-02, 4.6900e-02, 4.5600e-02, 4.4300e-02, 4.3000e-02, 4.1800e-02, 4.0700e-02, 3.9600e-02, 3.8500e-02, 3.7500e-02, 3.6500e-02, 3.5600e-02, 3.4700e-02, 3.3800e-02, 3.3000e-02, 3.2200e-02, 3.1400e-02, 3.0600e-02, 2.9900e-02, 2.9200e-02, 2.8500e-02, 2.7900e-02, 2.7200e-02, 2.6600e-02, 2.6000e-02, 2.5400e-02, 2.4900e-02, 2.4400e-02, 2.3800e-02, 2.3300e-02, 2.2800e-02, 2.2400e-02, 2.1900e-02, 2.1500e-02, 2.1000e-02, 2.0600e-02, 2.0200e-02, 1.9800e-02, 1.9400e-02, 1.9000e-02, 1.8700e-02, 1.8300e-02, 1.8000e-02, 1.7600e-02, 1.7300e-02, 1.7000e-02, 1.6700e-02, 1.6400e-02, 1.6100e-02, 1.5800e-02, 1.5500e-02, 1.5300e-02, 1.5000e-02, 1.4700e-02, 1.4500e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3500e-02, 1.3300e-02, 1.3100e-02, 1.2900e-02, 1.2700e-02, 1.2500e-02, 1.2300e-02, 1.2100e-02, 1.1900e-02, 1.1700e-02, 1.1500e-02, 1.1400e-02, 1.1200e-02, 1.1000e-02, 1.0900e-02, 1.0700e-02, 1.0600e-02, 1.0400e-02, 1.0300e-02, 1.0100e-02, 1.0000e-02, 9.8000e-03, 9.7000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.4000e-03, 6.4000e-03, 6.3000e-03, 6.2000e-03, 6.2000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.5000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03, 5.2000e-03, 5.2000e-03, 5.1000e-03, 5.1000e-03, 5.0000e-03, 5.0000e-03, 4.9000e-03, 4.9000e-03, 4.8000e-03, 4.8000e-03, 4.7000e-03, 4.7000e-03, 4.6000e-03, 4.6000e-03, 4.5000e-03, 4.5000e-03, 4.5000e-03}); + } + break; + case 6: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.0000e+00, 5.9352e+00, 5.7488e+00, 5.4626e+00, 5.1069e+00, 4.7136e+00, 4.3112e+00, 3.9217e+00, 3.5600e+00, 3.2345e+00, 2.9488e+00, 2.7026e+00, 2.4934e+00, 2.3177e+00, 2.1711e+00, 2.0494e+00, 1.9484e+00, 1.8645e+00, 1.7944e+00, 1.7353e+00, 1.6850e+00, 1.6414e+00, 1.6030e+00, 1.5685e+00, 1.5368e+00, 1.5073e+00, 1.4793e+00, 1.4522e+00, 1.4258e+00, 1.3998e+00, 1.3739e+00, 1.3482e+00, 1.3224e+00, 1.2965e+00, 1.2706e+00, 1.2446e+00, 1.2186e+00, 1.1925e+00, 1.1664e+00, 1.1403e+00, 1.1144e+00, 1.0885e+00, 1.0628e+00, 1.0373e+00, 1.0120e+00, 9.8700e-01, 9.6230e-01, 9.3790e-01, 9.1390e-01, 8.9020e-01, 8.6700e-01, 8.4410e-01, 8.2170e-01, 7.9970e-01, 7.7820e-01, 7.5710e-01, 7.3650e-01, 7.1630e-01, 6.9660e-01, 6.7740e-01, 6.5860e-01, 6.4030e-01, 6.2250e-01, 6.0510e-01, 5.8820e-01, 5.7170e-01, 5.5570e-01, 5.4010e-01, 5.2500e-01, 5.1020e-01, 4.9590e-01, 4.8200e-01, 4.6840e-01, 4.5530e-01, 4.4250e-01, 4.3010e-01, 4.1810e-01, 4.0640e-01, 3.9510e-01, 3.8410e-01, 3.7340e-01, 3.6310e-01, 3.5300e-01, 3.4330e-01, 3.3380e-01, 3.2460e-01, 3.1570e-01, 3.0710e-01, 2.9870e-01, 2.9060e-01, 2.8270e-01, 2.7510e-01, 2.6770e-01, 2.6050e-01, 2.5350e-01, 2.4670e-01, 2.4020e-01, 2.3380e-01, 2.2760e-01, 2.2160e-01, 2.1580e-01, 2.1020e-01, 2.0470e-01, 1.9940e-01, 1.9420e-01, 1.8920e-01, 1.8440e-01, 1.7970e-01, 1.7510e-01, 1.7060e-01, 1.6630e-01, 1.6210e-01, 1.5810e-01, 1.5410e-01, 1.5030e-01, 1.4660e-01, 1.4290e-01, 1.3940e-01, 1.3610e-01, 1.3270e-01, 1.2950e-01, 1.2640e-01, 1.2330e-01, 1.2030e-01, 1.1750e-01, 1.1470e-01, 1.1200e-01, 1.0940e-01, 1.0680e-01, 1.0420e-01, 1.0180e-01, 9.9500e-02, 9.7300e-02, 9.5000e-02, 9.2800e-02, 9.0700e-02, 8.8600e-02, 8.6500e-02, 8.4600e-02, 8.2800e-02, 8.1000e-02, 7.9200e-02, 7.7400e-02, 7.5600e-02, 7.3900e-02, 7.2300e-02, 7.0800e-02, 6.9400e-02, 6.7900e-02, 6.6500e-02, 6.5000e-02, 6.3500e-02, 6.2100e-02, 6.0700e-02, 5.9500e-02, 5.8400e-02, 5.7300e-02, 5.6100e-02, 5.4900e-02, 5.3700e-02, 5.2500e-02, 5.1300e-02, 5.0300e-02, 4.9300e-02, 4.8500e-02, 4.7600e-02, 4.6800e-02, 4.5800e-02, 4.4700e-02, 4.3700e-02, 4.2700e-02, 4.1800e-02, 4.1100e-02, 4.0500e-02, 3.9900e-02, 3.9200e-02, 3.8500e-02, 3.7600e-02, 3.6700e-02, 3.5800e-02, 3.5000e-02, 3.4400e-02, 3.3800e-02, 3.3400e-02, 3.3000e-02, 3.2600e-02, 3.2000e-02, 3.1200e-02, 3.0400e-02, 2.9600e-02, 2.8900e-02, 2.8400e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.6800e-02, 2.6300e-02, 2.5600e-02, 2.4900e-02, 2.4200e-02, 2.3600e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2700e-02, 2.2600e-02, 2.2300e-02, 2.1900e-02, 2.1300e-02, 2.0600e-02, 2.0000e-02, 1.9400e-02, 1.8900e-02, 1.8700e-02, 1.8600e-02, 1.8700e-02, 1.8700e-02, 1.8700e-02, 1.8500e-02, 1.8100e-02, 1.7600e-02, 1.6900e-02, 1.6300e-02, 1.5700e-02, 1.5300e-02, 1.5100e-02, 1.5100e-02, 1.5200e-02, 1.5400e-02, 1.5600e-02, 1.5600e-02, 1.5300e-02, 1.4900e-02, 1.4300e-02, 1.3600e-02, 1.3000e-02, 1.2500e-02, 1.2200e-02, 1.2100e-02, 1.2100e-02}); + feg = Vctr_cpu({2.5087e+00, 2.4821e+00, 2.4052e+00, 2.2865e+00, 2.1374e+00, 1.9704e+00, 1.7964e+00, 1.6242e+00, 1.4600e+00, 1.3074e+00, 1.1684e+00, 1.0436e+00, 9.3250e-01, 8.3440e-01, 7.4810e-01, 6.7240e-01, 6.0610e-01, 5.4800e-01, 4.9710e-01, 4.5240e-01, 4.1310e-01, 3.7850e-01, 3.4790e-01, 3.2080e-01, 2.9670e-01, 2.7530e-01, 2.5610e-01, 2.3890e-01, 2.2340e-01, 2.0950e-01, 1.9680e-01, 1.8540e-01, 1.7490e-01, 1.6540e-01, 1.5670e-01, 1.4870e-01, 1.4130e-01, 1.3450e-01, 1.2820e-01, 1.2240e-01, 1.1690e-01, 1.1190e-01, 1.0720e-01, 1.0280e-01, 9.8700e-02, 9.4800e-02, 9.1200e-02, 8.7800e-02, 8.4500e-02, 8.1500e-02, 7.8600e-02, 7.5900e-02, 7.3300e-02, 7.0900e-02, 6.8600e-02, 6.6400e-02, 6.4300e-02, 6.2300e-02, 6.0400e-02, 5.8600e-02, 5.6800e-02, 5.5200e-02, 5.3600e-02, 5.2100e-02, 5.0600e-02, 4.9200e-02, 4.7900e-02, 4.6600e-02, 4.5300e-02, 4.4200e-02, 4.3000e-02, 4.1900e-02, 4.0900e-02, 3.9800e-02, 3.8900e-02, 3.7900e-02, 3.7000e-02, 3.6100e-02, 3.5300e-02, 3.4500e-02, 3.3700e-02, 3.2900e-02, 3.2200e-02, 3.1400e-02, 3.0800e-02, 3.0100e-02, 2.9400e-02, 2.8800e-02, 2.8200e-02, 2.7600e-02, 2.7000e-02, 2.6500e-02, 2.5900e-02, 2.5400e-02, 2.4900e-02, 2.4400e-02, 2.3900e-02, 2.3500e-02, 2.3000e-02, 2.2600e-02, 2.2100e-02, 2.1700e-02, 2.1300e-02, 2.0900e-02, 2.0600e-02, 2.0200e-02, 1.9800e-02, 1.9500e-02, 1.9100e-02, 1.8800e-02, 1.8500e-02, 1.8100e-02, 1.7800e-02, 1.7500e-02, 1.7200e-02, 1.6900e-02, 1.6700e-02, 1.6400e-02, 1.6100e-02, 1.5900e-02, 1.5600e-02, 1.5400e-02, 1.5100e-02, 1.4900e-02, 1.4700e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3600e-02, 1.3400e-02, 1.3200e-02, 1.3000e-02, 1.2800e-02, 1.2600e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.1900e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1200e-02, 1.1100e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0500e-02, 1.0400e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.7000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.1000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.4000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03, 5.2000e-03, 5.2000e-03, 5.1000e-03, 5.1000e-03, 5.0000e-03, 5.0000e-03, 5.0000e-03, 4.9000e-03, 4.9000e-03, 4.8000e-03, 4.8000e-03, 4.7000e-03, 4.7000e-03, 4.6000e-03, 4.6000e-03, 4.6000e-03, 4.5000e-03, 4.5000e-03, 4.4000e-03, 4.4000e-03, 4.4000e-03, 4.3000e-03, 4.3000e-03, 4.3000e-03, 4.2000e-03, 4.2000e-03, 4.2000e-03, 4.1000e-03, 4.1000e-03, 4.0000e-03, 4.0000e-03, 4.0000e-03}); + } + break; + case 7: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.0000e+00, 6.9426e+00, 6.7755e+00, 6.5136e+00, 6.1781e+00, 5.7931e+00, 5.3822e+00, 4.9659e+00, 4.5602e+00, 4.1768e+00, 3.8229e+00, 3.5025e+00, 3.2168e+00, 2.9651e+00, 2.7455e+00, 2.5554e+00, 2.3917e+00, 2.2514e+00, 2.1315e+00, 2.0290e+00, 1.9414e+00, 1.8664e+00, 1.8018e+00, 1.7460e+00, 1.6973e+00, 1.6545e+00, 1.6164e+00, 1.5822e+00, 1.5509e+00, 1.5221e+00, 1.4951e+00, 1.4695e+00, 1.4450e+00, 1.4214e+00, 1.3983e+00, 1.3756e+00, 1.3532e+00, 1.3310e+00, 1.3089e+00, 1.2869e+00, 1.2649e+00, 1.2429e+00, 1.2209e+00, 1.1990e+00, 1.1770e+00, 1.1551e+00, 1.1333e+00, 1.1115e+00, 1.0897e+00, 1.0681e+00, 1.0466e+00, 1.0253e+00, 1.0041e+00, 9.8310e-01, 9.6240e-01, 9.4180e-01, 9.2150e-01, 9.0140e-01, 8.8160e-01, 8.6200e-01, 8.4280e-01, 8.2380e-01, 8.0520e-01, 7.8680e-01, 7.6880e-01, 7.5110e-01, 7.3370e-01, 7.1670e-01, 7.0000e-01, 6.8360e-01, 6.6750e-01, 6.5180e-01, 6.3640e-01, 6.2130e-01, 6.0660e-01, 5.9210e-01, 5.7800e-01, 5.6420e-01, 5.5080e-01, 5.3760e-01, 5.2480e-01, 5.1220e-01, 5.0000e-01, 4.8800e-01, 4.7630e-01, 4.6490e-01, 4.5380e-01, 4.4300e-01, 4.3240e-01, 4.2210e-01, 4.1200e-01, 4.0220e-01, 3.9260e-01, 3.8330e-01, 3.7420e-01, 3.6540e-01, 3.5670e-01, 3.4830e-01, 3.4010e-01, 3.3210e-01, 3.2430e-01, 3.1670e-01, 3.0930e-01, 3.0210e-01, 2.9510e-01, 2.8820e-01, 2.8160e-01, 2.7510e-01, 2.6870e-01, 2.6260e-01, 2.5660e-01, 2.5070e-01, 2.4500e-01, 2.3940e-01, 2.3400e-01, 2.2870e-01, 2.2360e-01, 2.1850e-01, 2.1370e-01, 2.0890e-01, 2.0420e-01, 1.9970e-01, 1.9530e-01, 1.9100e-01, 1.8680e-01, 1.8270e-01, 1.7870e-01, 1.7480e-01, 1.7100e-01, 1.6730e-01, 1.6370e-01, 1.6020e-01, 1.5680e-01, 1.5350e-01, 1.5020e-01, 1.4700e-01, 1.4390e-01, 1.4090e-01, 1.3790e-01, 1.3510e-01, 1.3230e-01, 1.2950e-01, 1.2680e-01, 1.2420e-01, 1.2160e-01, 1.1910e-01, 1.1670e-01, 1.1440e-01, 1.1210e-01, 1.0990e-01, 1.0760e-01, 1.0540e-01, 1.0330e-01, 1.0120e-01, 9.9200e-02, 9.7300e-02, 9.5500e-02, 9.3600e-02, 9.1800e-02, 8.9900e-02, 8.8100e-02, 8.6400e-02, 8.4700e-02, 8.3200e-02, 8.1700e-02, 8.0200e-02, 7.8700e-02, 7.7200e-02, 7.5600e-02, 7.4100e-02, 7.2700e-02, 7.1300e-02, 7.0000e-02, 6.8800e-02, 6.7700e-02, 6.6500e-02, 6.5300e-02, 6.4000e-02, 6.2700e-02, 6.1500e-02, 6.0300e-02, 5.9200e-02, 5.8300e-02, 5.7400e-02, 5.6500e-02, 5.5500e-02, 5.4600e-02, 5.3500e-02, 5.2400e-02, 5.1400e-02, 5.0400e-02, 4.9500e-02, 4.8700e-02, 4.8000e-02, 4.7400e-02, 4.6700e-02, 4.6000e-02, 4.5100e-02, 4.4200e-02, 4.3300e-02, 4.2400e-02, 4.1600e-02, 4.0900e-02, 4.0300e-02, 3.9800e-02, 3.9400e-02, 3.8900e-02, 3.8300e-02, 3.7700e-02, 3.6900e-02, 3.6100e-02, 3.5300e-02, 3.4600e-02, 3.3900e-02, 3.3500e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1800e-02, 3.1200e-02, 3.0500e-02, 2.9800e-02, 2.9100e-02, 2.8400e-02, 2.7900e-02, 2.7500e-02, 2.7200e-02, 2.7100e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6200e-02, 2.5600e-02, 2.5000e-02, 2.4300e-02, 2.3700e-02, 2.3100e-02, 2.2700e-02, 2.2400e-02, 2.2300e-02}); + feg = Vctr_cpu({2.2170e+00, 2.1997e+00, 2.1491e+00, 2.0696e+00, 1.9671e+00, 1.8486e+00, 1.7208e+00, 1.5897e+00, 1.4598e+00, 1.3347e+00, 1.2166e+00, 1.1069e+00, 1.0061e+00, 9.1430e-01, 8.3120e-01, 7.5650e-01, 6.8930e-01, 6.2920e-01, 5.7540e-01, 5.2730e-01, 4.8430e-01, 4.4580e-01, 4.1130e-01, 3.8030e-01, 3.5250e-01, 3.2750e-01, 3.0500e-01, 2.8460e-01, 2.6620e-01, 2.4940e-01, 2.3420e-01, 2.2040e-01, 2.0770e-01, 1.9620e-01, 1.8560e-01, 1.7580e-01, 1.6690e-01, 1.5860e-01, 1.5090e-01, 1.4380e-01, 1.3730e-01, 1.3110e-01, 1.2550e-01, 1.2010e-01, 1.1520e-01, 1.1050e-01, 1.0620e-01, 1.0210e-01, 9.8200e-02, 9.4600e-02, 9.1200e-02, 8.8000e-02, 8.4900e-02, 8.2000e-02, 7.9300e-02, 7.6700e-02, 7.4200e-02, 7.1900e-02, 6.9600e-02, 6.7500e-02, 6.5500e-02, 6.3600e-02, 6.1700e-02, 5.9900e-02, 5.8300e-02, 5.6600e-02, 5.5100e-02, 5.3600e-02, 5.2200e-02, 5.0800e-02, 4.9500e-02, 4.8200e-02, 4.7000e-02, 4.5800e-02, 4.4700e-02, 4.3600e-02, 4.2600e-02, 4.1600e-02, 4.0600e-02, 3.9700e-02, 3.8700e-02, 3.7900e-02, 3.7000e-02, 3.6200e-02, 3.5400e-02, 3.4600e-02, 3.3900e-02, 3.3200e-02, 3.2500e-02, 3.1800e-02, 3.1100e-02, 3.0500e-02, 2.9900e-02, 2.9300e-02, 2.8700e-02, 2.8200e-02, 2.7600e-02, 2.7100e-02, 2.6600e-02, 2.6100e-02, 2.5600e-02, 2.5100e-02, 2.4600e-02, 2.4200e-02, 2.3700e-02, 2.3300e-02, 2.2900e-02, 2.2500e-02, 2.2100e-02, 2.1700e-02, 2.1300e-02, 2.1000e-02, 2.0600e-02, 2.0300e-02, 1.9900e-02, 1.9600e-02, 1.9300e-02, 1.9000e-02, 1.8700e-02, 1.8400e-02, 1.8100e-02, 1.7800e-02, 1.7500e-02, 1.7200e-02, 1.7000e-02, 1.6700e-02, 1.6500e-02, 1.6200e-02, 1.6000e-02, 1.5700e-02, 1.5500e-02, 1.5300e-02, 1.5000e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3600e-02, 1.3400e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2000e-02, 1.1900e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1300e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.9000e-03, 6.8000e-03, 6.7000e-03, 6.7000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.2000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.5000e-03, 5.4000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03, 5.2000e-03, 5.2000e-03, 5.1000e-03, 5.1000e-03, 5.0000e-03, 5.0000e-03, 5.0000e-03, 4.9000e-03, 4.9000e-03, 4.8000e-03, 4.8000e-03, 4.8000e-03, 4.7000e-03, 4.7000e-03, 4.6000e-03}); + } + break; + case 8: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.0000e+00, 7.9484e+00, 7.7972e+00, 7.5570e+00, 7.2433e+00, 6.8745e+00, 6.4696e+00, 6.0464e+00, 5.6203e+00, 5.2036e+00, 4.8052e+00, 4.4316e+00, 4.0863e+00, 3.7712e+00, 3.4866e+00, 3.2317e+00, 3.0049e+00, 2.8043e+00, 2.6276e+00, 2.4726e+00, 2.3369e+00, 2.2184e+00, 2.1149e+00, 2.0245e+00, 1.9455e+00, 1.8763e+00, 1.8155e+00, 1.7619e+00, 1.7144e+00, 1.6721e+00, 1.6340e+00, 1.5996e+00, 1.5682e+00, 1.5393e+00, 1.5125e+00, 1.4873e+00, 1.4634e+00, 1.4407e+00, 1.4189e+00, 1.3977e+00, 1.3771e+00, 1.3569e+00, 1.3370e+00, 1.3173e+00, 1.2979e+00, 1.2786e+00, 1.2594e+00, 1.2402e+00, 1.2212e+00, 1.2021e+00, 1.1832e+00, 1.1642e+00, 1.1453e+00, 1.1265e+00, 1.1077e+00, 1.0890e+00, 1.0704e+00, 1.0519e+00, 1.0335e+00, 1.0152e+00, 9.9700e-01, 9.7900e-01, 9.6110e-01, 9.4330e-01, 9.2580e-01, 9.0840e-01, 8.9120e-01, 8.7420e-01, 8.5740e-01, 8.4080e-01, 8.2440e-01, 8.0830e-01, 7.9240e-01, 7.7670e-01, 7.6120e-01, 7.4600e-01, 7.3100e-01, 7.1630e-01, 7.0180e-01, 6.8750e-01, 6.7350e-01, 6.5970e-01, 6.4620e-01, 6.3300e-01, 6.1990e-01, 6.0710e-01, 5.9460e-01, 5.8230e-01, 5.7020e-01, 5.5840e-01, 5.4680e-01, 5.3540e-01, 5.2430e-01, 5.1340e-01, 5.0270e-01, 4.9220e-01, 4.8200e-01, 4.7190e-01, 4.6210e-01, 4.5250e-01, 4.4310e-01, 4.3390e-01, 4.2480e-01, 4.1600e-01, 4.0740e-01, 3.9890e-01, 3.9070e-01, 3.8260e-01, 3.7470e-01, 3.6700e-01, 3.5940e-01, 3.5200e-01, 3.4480e-01, 3.3770e-01, 3.3080e-01, 3.2400e-01, 3.1740e-01, 3.1090e-01, 3.0460e-01, 2.9840e-01, 2.9240e-01, 2.8650e-01, 2.8070e-01, 2.7500e-01, 2.6950e-01, 2.6410e-01, 2.5880e-01, 2.5370e-01, 2.4860e-01, 2.4370e-01, 2.3880e-01, 2.3410e-01, 2.2950e-01, 2.2500e-01, 2.2060e-01, 2.1630e-01, 2.1210e-01, 2.0790e-01, 2.0390e-01, 1.9990e-01, 1.9610e-01, 1.9230e-01, 1.8870e-01, 1.8500e-01, 1.8150e-01, 1.7800e-01, 1.7460e-01, 1.7130e-01, 1.6810e-01, 1.6500e-01, 1.6190e-01, 1.5890e-01, 1.5590e-01, 1.5300e-01, 1.5010e-01, 1.4730e-01, 1.4460e-01, 1.4200e-01, 1.3940e-01, 1.3690e-01, 1.3440e-01, 1.3200e-01, 1.2950e-01, 1.2710e-01, 1.2480e-01, 1.2260e-01, 1.2040e-01, 1.1830e-01, 1.1630e-01, 1.1430e-01, 1.1220e-01, 1.1020e-01, 1.0820e-01, 1.0630e-01, 1.0440e-01, 1.0260e-01, 1.0090e-01, 9.9200e-02, 9.7600e-02, 9.5900e-02, 9.4300e-02, 9.2600e-02, 9.0900e-02, 8.9300e-02, 8.7700e-02, 8.6300e-02, 8.4900e-02, 8.3600e-02, 8.2300e-02, 8.1000e-02, 7.9600e-02, 7.8300e-02, 7.6900e-02, 7.5500e-02, 7.4200e-02, 7.2900e-02, 7.1800e-02, 7.0700e-02, 6.9600e-02, 6.8700e-02, 6.7600e-02, 6.6600e-02, 6.5500e-02, 6.4300e-02, 6.3200e-02, 6.2000e-02, 6.1000e-02, 6.0000e-02, 5.9100e-02, 5.8300e-02, 5.7600e-02, 5.6800e-02, 5.6100e-02, 5.5200e-02, 5.4300e-02, 5.3300e-02, 5.2300e-02, 5.1400e-02, 5.0400e-02, 4.9600e-02, 4.9000e-02, 4.8400e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6200e-02, 4.5500e-02, 4.4700e-02, 4.3800e-02, 4.2900e-02, 4.2100e-02, 4.1300e-02, 4.0700e-02, 4.0200e-02, 3.9800e-02, 3.9500e-02, 3.9100e-02, 3.8800e-02, 3.8300e-02, 3.7800e-02, 3.7200e-02}); + feg = Vctr_cpu({1.9884e+00, 1.9764e+00, 1.9410e+00, 1.8848e+00, 1.8111e+00, 1.7240e+00, 1.6279e+00, 1.5267e+00, 1.4238e+00, 1.3220e+00, 1.2234e+00, 1.1293e+00, 1.0408e+00, 9.5820e-01, 8.8180e-01, 8.1150e-01, 7.4720e-01, 6.8850e-01, 6.3500e-01, 5.8630e-01, 5.4220e-01, 5.0200e-01, 4.6560e-01, 4.3260e-01, 4.0250e-01, 3.7520e-01, 3.5030e-01, 3.2770e-01, 3.0700e-01, 2.8810e-01, 2.7090e-01, 2.5500e-01, 2.4050e-01, 2.2720e-01, 2.1490e-01, 2.0360e-01, 1.9310e-01, 1.8350e-01, 1.7450e-01, 1.6620e-01, 1.5850e-01, 1.5130e-01, 1.4460e-01, 1.3840e-01, 1.3260e-01, 1.2710e-01, 1.2200e-01, 1.1720e-01, 1.1270e-01, 1.0840e-01, 1.0440e-01, 1.0060e-01, 9.7100e-02, 9.3700e-02, 9.0500e-02, 8.7500e-02, 8.4600e-02, 8.1900e-02, 7.9300e-02, 7.6800e-02, 7.4500e-02, 7.2300e-02, 7.0100e-02, 6.8100e-02, 6.6100e-02, 6.4300e-02, 6.2500e-02, 6.0800e-02, 5.9200e-02, 5.7600e-02, 5.6100e-02, 5.4600e-02, 5.3200e-02, 5.1900e-02, 5.0600e-02, 4.9400e-02, 4.8200e-02, 4.7000e-02, 4.5900e-02, 4.4900e-02, 4.3800e-02, 4.2800e-02, 4.1900e-02, 4.1000e-02, 4.0100e-02, 3.9200e-02, 3.8300e-02, 3.7500e-02, 3.6700e-02, 3.6000e-02, 3.5200e-02, 3.4500e-02, 3.3800e-02, 3.3100e-02, 3.2500e-02, 3.1900e-02, 3.1200e-02, 3.0600e-02, 3.0100e-02, 2.9500e-02, 2.8900e-02, 2.8400e-02, 2.7900e-02, 2.7400e-02, 2.6900e-02, 2.6400e-02, 2.5900e-02, 2.5500e-02, 2.5000e-02, 2.4600e-02, 2.4200e-02, 2.3800e-02, 2.3400e-02, 2.3000e-02, 2.2600e-02, 2.2200e-02, 2.1900e-02, 2.1500e-02, 2.1200e-02, 2.0800e-02, 2.0500e-02, 2.0200e-02, 1.9900e-02, 1.9600e-02, 1.9300e-02, 1.9000e-02, 1.8700e-02, 1.8400e-02, 1.8100e-02, 1.7800e-02, 1.7600e-02, 1.7300e-02, 1.7100e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6100e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5200e-02, 1.5000e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3700e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2800e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.1900e-02, 1.1800e-02, 1.1600e-02, 1.1500e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.2000e-03, 7.1000e-03, 7.0000e-03, 7.0000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.2000e-03, 6.1000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03, 5.9000e-03, 5.8000e-03, 5.8000e-03, 5.7000e-03, 5.7000e-03, 5.6000e-03, 5.6000e-03, 5.5000e-03, 5.5000e-03, 5.4000e-03, 5.4000e-03, 5.3000e-03, 5.3000e-03}); + } + break; + case 9: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.0000e+00, 8.9531e+00, 8.8152e+00, 8.5939e+00, 8.3009e+00, 7.9507e+00, 7.5585e+00, 7.1395e+00, 6.7075e+00, 6.2742e+00, 5.8494e+00, 5.4402e+00, 5.0521e+00, 4.6883e+00, 4.3509e+00, 4.0407e+00, 3.7575e+00, 3.5005e+00, 3.2685e+00, 3.0600e+00, 2.8733e+00, 2.7065e+00, 2.5579e+00, 2.4257e+00, 2.3083e+00, 2.2040e+00, 2.1115e+00, 2.0293e+00, 1.9562e+00, 1.8912e+00, 1.8331e+00, 1.7812e+00, 1.7345e+00, 1.6925e+00, 1.6544e+00, 1.6197e+00, 1.5879e+00, 1.5587e+00, 1.5315e+00, 1.5062e+00, 1.4823e+00, 1.4598e+00, 1.4383e+00, 1.4178e+00, 1.3979e+00, 1.3787e+00, 1.3600e+00, 1.3417e+00, 1.3237e+00, 1.3060e+00, 1.2886e+00, 1.2713e+00, 1.2541e+00, 1.2371e+00, 1.2202e+00, 1.2033e+00, 1.1866e+00, 1.1699e+00, 1.1532e+00, 1.1366e+00, 1.1201e+00, 1.1036e+00, 1.0872e+00, 1.0709e+00, 1.0546e+00, 1.0384e+00, 1.0223e+00, 1.0064e+00, 9.9050e-01, 9.7470e-01, 9.5900e-01, 9.4340e-01, 9.2800e-01, 9.1270e-01, 8.9760e-01, 8.8260e-01, 8.6770e-01, 8.5300e-01, 8.3850e-01, 8.2410e-01, 8.0990e-01, 7.9580e-01, 7.8200e-01, 7.6830e-01, 7.5480e-01, 7.4150e-01, 7.2830e-01, 7.1540e-01, 7.0260e-01, 6.9000e-01, 6.7760e-01, 6.6540e-01, 6.5340e-01, 6.4160e-01, 6.2990e-01, 6.1850e-01, 6.0720e-01, 5.9610e-01, 5.8520e-01, 5.7450e-01, 5.6400e-01, 5.5360e-01, 5.4350e-01, 5.3350e-01, 5.2370e-01, 5.1400e-01, 5.0460e-01, 4.9530e-01, 4.8620e-01, 4.7720e-01, 4.6840e-01, 4.5980e-01, 4.5130e-01, 4.4300e-01, 4.3480e-01, 4.2680e-01, 4.1900e-01, 4.1130e-01, 4.0370e-01, 3.9630e-01, 3.8910e-01, 3.8190e-01, 3.7500e-01, 3.6810e-01, 3.6140e-01, 3.5480e-01, 3.4830e-01, 3.4200e-01, 3.3580e-01, 3.2970e-01, 3.2370e-01, 3.1790e-01, 3.1210e-01, 3.0650e-01, 3.0100e-01, 2.9560e-01, 2.9030e-01, 2.8510e-01, 2.8000e-01, 2.7500e-01, 2.7010e-01, 2.6530e-01, 2.6060e-01, 2.5600e-01, 2.5140e-01, 2.4700e-01, 2.4270e-01, 2.3840e-01, 2.3430e-01, 2.3020e-01, 2.2610e-01, 2.2220e-01, 2.1830e-01, 2.1450e-01, 2.1090e-01, 2.0720e-01, 2.0370e-01, 2.0020e-01, 1.9670e-01, 1.9340e-01, 1.9010e-01, 1.8680e-01, 1.8370e-01, 1.8060e-01, 1.7760e-01, 1.7460e-01, 1.7170e-01, 1.6880e-01, 1.6590e-01, 1.6310e-01, 1.6040e-01, 1.5780e-01, 1.5520e-01, 1.5270e-01, 1.5020e-01, 1.4770e-01, 1.4530e-01, 1.4290e-01, 1.4050e-01, 1.3820e-01, 1.3600e-01, 1.3380e-01, 1.3170e-01, 1.2960e-01, 1.2760e-01, 1.2560e-01, 1.2350e-01, 1.2150e-01, 1.1960e-01, 1.1760e-01, 1.1580e-01, 1.1390e-01, 1.1220e-01, 1.1050e-01, 1.0880e-01, 1.0720e-01, 1.0550e-01, 1.0390e-01, 1.0220e-01, 1.0060e-01, 9.9000e-02, 9.7400e-02, 9.6000e-02, 9.4500e-02, 9.3200e-02, 9.1900e-02, 9.0500e-02, 8.9200e-02, 8.7900e-02, 8.6500e-02, 8.5100e-02, 8.3800e-02, 8.2400e-02, 8.1200e-02, 8.0000e-02, 7.8900e-02, 7.7900e-02, 7.6800e-02, 7.5800e-02, 7.4700e-02, 7.3600e-02, 7.2500e-02, 7.1400e-02, 7.0200e-02, 6.9100e-02, 6.8000e-02, 6.7100e-02, 6.6200e-02, 6.5400e-02, 6.4600e-02, 6.3800e-02, 6.3000e-02, 6.2100e-02, 6.1200e-02, 6.0300e-02, 5.9300e-02, 5.8300e-02, 5.7400e-02, 5.6500e-02, 5.5700e-02, 5.5000e-02}); + feg = Vctr_cpu({1.8040e+00, 1.7953e+00, 1.7695e+00, 1.7281e+00, 1.6731e+00, 1.6073e+00, 1.5333e+00, 1.4540e+00, 1.3717e+00, 1.2886e+00, 1.2065e+00, 1.1266e+00, 1.0499e+00, 9.7700e-01, 9.0830e-01, 8.4410e-01, 7.8420e-01, 7.2870e-01, 6.7740e-01, 6.3010e-01, 5.8650e-01, 5.4650e-01, 5.0970e-01, 4.7590e-01, 4.4490e-01, 4.1640e-01, 3.9020e-01, 3.6620e-01, 3.4400e-01, 3.2370e-01, 3.0490e-01, 2.8770e-01, 2.7170e-01, 2.5700e-01, 2.4330e-01, 2.3070e-01, 2.1900e-01, 2.0820e-01, 1.9810e-01, 1.8870e-01, 1.7990e-01, 1.7180e-01, 1.6420e-01, 1.5700e-01, 1.5040e-01, 1.4410e-01, 1.3830e-01, 1.3280e-01, 1.2760e-01, 1.2270e-01, 1.1810e-01, 1.1380e-01, 1.0970e-01, 1.0580e-01, 1.0220e-01, 9.8700e-02, 9.5400e-02, 9.2300e-02, 8.9300e-02, 8.6500e-02, 8.3800e-02, 8.1300e-02, 7.8800e-02, 7.6500e-02, 7.4300e-02, 7.2200e-02, 7.0100e-02, 6.8200e-02, 6.6300e-02, 6.4500e-02, 6.2800e-02, 6.1200e-02, 5.9600e-02, 5.8100e-02, 5.6700e-02, 5.5300e-02, 5.3900e-02, 5.2600e-02, 5.1400e-02, 5.0200e-02, 4.9000e-02, 4.7900e-02, 4.6800e-02, 4.5800e-02, 4.4700e-02, 4.3800e-02, 4.2800e-02, 4.1900e-02, 4.1000e-02, 4.0200e-02, 3.9300e-02, 3.8500e-02, 3.7800e-02, 3.7000e-02, 3.6300e-02, 3.5600e-02, 3.4900e-02, 3.4200e-02, 3.3600e-02, 3.2900e-02, 3.2300e-02, 3.1700e-02, 3.1100e-02, 3.0600e-02, 3.0000e-02, 2.9500e-02, 2.9000e-02, 2.8400e-02, 2.8000e-02, 2.7500e-02, 2.7000e-02, 2.6500e-02, 2.6100e-02, 2.5700e-02, 2.5200e-02, 2.4800e-02, 2.4400e-02, 2.4000e-02, 2.3600e-02, 2.3300e-02, 2.2900e-02, 2.2500e-02, 2.2200e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.0900e-02, 2.0600e-02, 2.0300e-02, 2.0000e-02, 1.9700e-02, 1.9400e-02, 1.9100e-02, 1.8800e-02, 1.8600e-02, 1.8300e-02, 1.8000e-02, 1.7800e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2700e-02, 1.2600e-02, 1.2400e-02, 1.2300e-02, 1.2100e-02, 1.2000e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.5000e-03, 7.4000e-03, 7.3000e-03, 7.3000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.6000e-03, 6.6000e-03, 6.5000e-03, 6.5000e-03, 6.4000e-03, 6.4000e-03, 6.3000e-03, 6.3000e-03, 6.2000e-03, 6.1000e-03, 6.1000e-03, 6.0000e-03, 6.0000e-03, 5.9000e-03}); + } + break; + case 10: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0000e+01, 9.9570e+00, 9.8302e+00, 9.6253e+00, 9.3514e+00, 9.0199e+00, 8.6433e+00, 8.2343e+00, 7.8049e+00, 7.3662e+00, 6.9275e+00, 6.4965e+00, 6.0792e+00, 5.6800e+00, 5.3021e+00, 4.9474e+00, 4.6169e+00, 4.3109e+00, 4.0291e+00, 3.7708e+00, 3.5350e+00, 3.3203e+00, 3.1255e+00, 2.9492e+00, 2.7899e+00, 2.6462e+00, 2.5168e+00, 2.4002e+00, 2.2954e+00, 2.2011e+00, 2.1163e+00, 2.0400e+00, 1.9713e+00, 1.9093e+00, 1.8533e+00, 1.8026e+00, 1.7566e+00, 1.7148e+00, 1.6766e+00, 1.6416e+00, 1.6094e+00, 1.5796e+00, 1.5520e+00, 1.5263e+00, 1.5021e+00, 1.4794e+00, 1.4578e+00, 1.4373e+00, 1.4177e+00, 1.3988e+00, 1.3806e+00, 1.3630e+00, 1.3458e+00, 1.3290e+00, 1.3126e+00, 1.2964e+00, 1.2805e+00, 1.2647e+00, 1.2492e+00, 1.2338e+00, 1.2185e+00, 1.2033e+00, 1.1882e+00, 1.1732e+00, 1.1583e+00, 1.1434e+00, 1.1287e+00, 1.1139e+00, 1.0993e+00, 1.0847e+00, 1.0701e+00, 1.0556e+00, 1.0412e+00, 1.0269e+00, 1.0126e+00, 9.9840e-01, 9.8430e-01, 9.7030e-01, 9.5640e-01, 9.4260e-01, 9.2890e-01, 9.1520e-01, 9.0170e-01, 8.8830e-01, 8.7500e-01, 8.6190e-01, 8.4880e-01, 8.3590e-01, 8.2310e-01, 8.1050e-01, 7.9790e-01, 7.8550e-01, 7.7330e-01, 7.6120e-01, 7.4920e-01, 7.3740e-01, 7.2570e-01, 7.1420e-01, 7.0280e-01, 6.9150e-01, 6.8040e-01, 6.6950e-01, 6.5870e-01, 6.4800e-01, 6.3750e-01, 6.2720e-01, 6.1700e-01, 6.0690e-01, 5.9700e-01, 5.8730e-01, 5.7760e-01, 5.6820e-01, 5.5890e-01, 5.4970e-01, 5.4060e-01, 5.3170e-01, 5.2300e-01, 5.1440e-01, 5.0590e-01, 4.9750e-01, 4.8930e-01, 4.8120e-01, 4.7330e-01, 4.6550e-01, 4.5780e-01, 4.5030e-01, 4.4280e-01, 4.3550e-01, 4.2830e-01, 4.2130e-01, 4.1430e-01, 4.0750e-01, 4.0080e-01, 3.9420e-01, 3.8770e-01, 3.8140e-01, 3.7510e-01, 3.6900e-01, 3.6290e-01, 3.5700e-01, 3.5110e-01, 3.4540e-01, 3.3980e-01, 3.3420e-01, 3.2880e-01, 3.2350e-01, 3.1820e-01, 3.1310e-01, 3.0800e-01, 3.0300e-01, 2.9810e-01, 2.9330e-01, 2.8860e-01, 2.8400e-01, 2.7940e-01, 2.7500e-01, 2.7060e-01, 2.6620e-01, 2.6200e-01, 2.5780e-01, 2.5370e-01, 2.4970e-01, 2.4580e-01, 2.4190e-01, 2.3810e-01, 2.3440e-01, 2.3070e-01, 2.2710e-01, 2.2350e-01, 2.2000e-01, 2.1660e-01, 2.1320e-01, 2.0990e-01, 2.0670e-01, 2.0350e-01, 2.0040e-01, 1.9730e-01, 1.9420e-01, 1.9130e-01, 1.8830e-01, 1.8550e-01, 1.8270e-01, 1.7990e-01, 1.7720e-01, 1.7450e-01, 1.7190e-01, 1.6930e-01, 1.6670e-01, 1.6420e-01, 1.6180e-01, 1.5940e-01, 1.5700e-01, 1.5470e-01, 1.5250e-01, 1.5020e-01, 1.4800e-01, 1.4580e-01, 1.4360e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3350e-01, 1.3160e-01, 1.2970e-01, 1.2790e-01, 1.2600e-01, 1.2420e-01, 1.2240e-01, 1.2060e-01, 1.1880e-01, 1.1720e-01, 1.1560e-01, 1.1400e-01, 1.1240e-01, 1.1090e-01, 1.0930e-01, 1.0780e-01, 1.0630e-01, 1.0470e-01, 1.0320e-01, 1.0170e-01, 1.0030e-01, 9.9000e-02, 9.7700e-02, 9.6400e-02, 9.5100e-02, 9.3900e-02, 9.2600e-02, 9.1400e-02, 9.0100e-02, 8.8800e-02, 8.7500e-02, 8.6300e-02, 8.5100e-02, 8.4000e-02, 8.2900e-02, 8.1900e-02, 8.0900e-02, 7.9900e-02, 7.8900e-02}); + feg = Vctr_cpu({1.6519e+00, 1.6453e+00, 1.6258e+00, 1.5944e+00, 1.5523e+00, 1.5012e+00, 1.4431e+00, 1.3799e+00, 1.3134e+00, 1.2452e+00, 1.1766e+00, 1.1088e+00, 1.0427e+00, 9.7890e-01, 9.1790e-01, 8.5990e-01, 8.0520e-01, 7.5380e-01, 7.0570e-01, 6.6080e-01, 6.1890e-01, 5.8000e-01, 5.4390e-01, 5.1040e-01, 4.7930e-01, 4.5060e-01, 4.2390e-01, 3.9920e-01, 3.7630e-01, 3.5510e-01, 3.3540e-01, 3.1720e-01, 3.0020e-01, 2.8450e-01, 2.6990e-01, 2.5630e-01, 2.4360e-01, 2.3180e-01, 2.2070e-01, 2.1040e-01, 2.0080e-01, 1.9180e-01, 1.8340e-01, 1.7550e-01, 1.6810e-01, 1.6110e-01, 1.5460e-01, 1.4840e-01, 1.4260e-01, 1.3720e-01, 1.3200e-01, 1.2720e-01, 1.2260e-01, 1.1820e-01, 1.1410e-01, 1.1020e-01, 1.0650e-01, 1.0300e-01, 9.9600e-02, 9.6400e-02, 9.3400e-02, 9.0500e-02, 8.7800e-02, 8.5200e-02, 8.2700e-02, 8.0300e-02, 7.8000e-02, 7.5800e-02, 7.3700e-02, 7.1700e-02, 6.9800e-02, 6.7900e-02, 6.6200e-02, 6.4500e-02, 6.2800e-02, 6.1300e-02, 5.9800e-02, 5.8300e-02, 5.6900e-02, 5.5600e-02, 5.4300e-02, 5.3000e-02, 5.1800e-02, 5.0600e-02, 4.9500e-02, 4.8400e-02, 4.7400e-02, 4.6400e-02, 4.5400e-02, 4.4400e-02, 4.3500e-02, 4.2600e-02, 4.1700e-02, 4.0900e-02, 4.0100e-02, 3.9300e-02, 3.8500e-02, 3.7800e-02, 3.7100e-02, 3.6400e-02, 3.5700e-02, 3.5000e-02, 3.4400e-02, 3.3800e-02, 3.3100e-02, 3.2600e-02, 3.2000e-02, 3.1400e-02, 3.0900e-02, 3.0300e-02, 2.9800e-02, 2.9300e-02, 2.8800e-02, 2.8300e-02, 2.7900e-02, 2.7400e-02, 2.7000e-02, 2.6500e-02, 2.6100e-02, 2.5700e-02, 2.5300e-02, 2.4900e-02, 2.4500e-02, 2.4100e-02, 2.3800e-02, 2.3400e-02, 2.3100e-02, 2.2700e-02, 2.2400e-02, 2.2000e-02, 2.1700e-02, 2.1400e-02, 2.1100e-02, 2.0800e-02, 2.0500e-02, 2.0200e-02, 1.9900e-02, 1.9600e-02, 1.9400e-02, 1.9100e-02, 1.8900e-02, 1.8600e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.6900e-02, 1.6700e-02, 1.6500e-02, 1.6300e-02, 1.6100e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3100e-02, 1.3000e-02, 1.2800e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.3000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 8.0000e-03, 7.9000e-03, 7.8000e-03, 7.8000e-03, 7.7000e-03, 7.6000e-03, 7.6000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03, 7.2000e-03, 7.1000e-03, 7.1000e-03, 7.0000e-03, 6.9000e-03, 6.9000e-03, 6.8000e-03, 6.8000e-03, 6.7000e-03, 6.7000e-03, 6.6000e-03}); + } + break; + case 11: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.1000e+01, 1.0880e+01, 1.0568e+01, 1.0167e+01, 9.7603e+00, 9.3812e+00, 9.0267e+00, 8.6821e+00, 8.3354e+00, 7.9809e+00, 7.6183e+00, 7.2503e+00, 6.8810e+00, 6.5147e+00, 6.1555e+00, 5.8068e+00, 5.4712e+00, 5.1509e+00, 4.8473e+00, 4.5612e+00, 4.2931e+00, 4.0430e+00, 3.8107e+00, 3.5957e+00, 3.3973e+00, 3.2148e+00, 3.0472e+00, 2.8937e+00, 2.7534e+00, 2.6252e+00, 2.5084e+00, 2.4019e+00, 2.3049e+00, 2.2167e+00, 2.1364e+00, 2.0633e+00, 1.9967e+00, 1.9361e+00, 1.8807e+00, 1.8302e+00, 1.7840e+00, 1.7417e+00, 1.7028e+00, 1.6670e+00, 1.6340e+00, 1.6034e+00, 1.5750e+00, 1.5485e+00, 1.5237e+00, 1.5004e+00, 1.4785e+00, 1.4577e+00, 1.4379e+00, 1.4191e+00, 1.4010e+00, 1.3836e+00, 1.3668e+00, 1.3505e+00, 1.3347e+00, 1.3192e+00, 1.3041e+00, 1.2893e+00, 1.2747e+00, 1.2604e+00, 1.2462e+00, 1.2322e+00, 1.2183e+00, 1.2046e+00, 1.1910e+00, 1.1774e+00, 1.1639e+00, 1.1505e+00, 1.1372e+00, 1.1239e+00, 1.1106e+00, 1.0976e+00, 1.0846e+00, 1.0715e+00, 1.0584e+00, 1.0455e+00, 1.0327e+00, 1.0200e+00, 1.0071e+00, 9.9430e-01, 9.8180e-01, 9.6940e-01, 9.5690e-01, 9.4430e-01, 9.3180e-01, 9.1970e-01, 9.0780e-01, 8.9570e-01, 8.8350e-01, 8.7140e-01, 8.5970e-01, 8.4830e-01, 8.3680e-01, 8.2510e-01, 8.1340e-01, 8.0200e-01, 7.9110e-01, 7.8030e-01, 7.6930e-01, 7.5810e-01, 7.4710e-01, 7.3650e-01, 7.2630e-01, 7.1620e-01, 7.0590e-01, 6.9530e-01, 6.8490e-01, 6.7500e-01, 6.6550e-01, 6.5620e-01, 6.4670e-01, 6.3700e-01, 6.2720e-01, 6.1780e-01, 6.0890e-01, 6.0030e-01, 5.9180e-01, 5.8310e-01, 5.7400e-01, 5.6500e-01, 5.5650e-01, 5.4850e-01, 5.4080e-01, 5.3310e-01, 5.2520e-01, 5.1700e-01, 5.0870e-01, 5.0090e-01, 4.9360e-01, 4.8660e-01, 4.7980e-01, 4.7290e-01, 4.6560e-01, 4.5810e-01, 4.5080e-01, 4.4400e-01, 4.3760e-01, 4.3150e-01, 4.2550e-01, 4.1940e-01, 4.1290e-01, 4.0620e-01, 3.9970e-01, 3.9360e-01, 3.8800e-01, 3.8250e-01, 3.7730e-01, 3.7200e-01, 3.6650e-01, 3.6060e-01, 3.5470e-01, 3.4910e-01, 3.4410e-01, 3.3920e-01, 3.3450e-01, 3.3000e-01, 3.2550e-01, 3.2070e-01, 3.1550e-01, 3.1030e-01, 3.0540e-01, 3.0100e-01, 2.9690e-01, 2.9280e-01, 2.8880e-01, 2.8500e-01, 2.8110e-01, 2.7670e-01, 2.7210e-01, 2.6760e-01, 2.6370e-01, 2.6010e-01, 2.5660e-01, 2.5310e-01, 2.4970e-01, 2.4650e-01, 2.4330e-01, 2.3950e-01, 2.3550e-01, 2.3160e-01, 2.2820e-01, 2.2520e-01, 2.2220e-01, 2.1920e-01, 2.1620e-01, 2.1350e-01, 2.1090e-01, 2.0810e-01, 2.0470e-01, 2.0120e-01, 1.9790e-01, 1.9520e-01, 1.9280e-01, 1.9030e-01, 1.8770e-01, 1.8520e-01, 1.8300e-01, 1.8090e-01, 1.7860e-01, 1.7590e-01, 1.7280e-01, 1.6980e-01, 1.6740e-01, 1.6550e-01, 1.6350e-01, 1.6140e-01, 1.5910e-01, 1.5710e-01, 1.5530e-01, 1.5370e-01, 1.5180e-01, 1.4940e-01, 1.4670e-01, 1.4420e-01, 1.4220e-01, 1.4070e-01, 1.3920e-01, 1.3740e-01, 1.3550e-01, 1.3360e-01, 1.3210e-01, 1.3090e-01, 1.2960e-01, 1.2780e-01, 1.2560e-01, 1.2330e-01, 1.2120e-01, 1.1980e-01, 1.1870e-01, 1.1750e-01, 1.1600e-01, 1.1430e-01, 1.1270e-01, 1.1150e-01, 1.1050e-01, 1.0960e-01, 1.0830e-01}); + feg = Vctr_cpu({4.7719e+00, 4.5955e+00, 4.1349e+00, 3.5444e+00, 2.9670e+00, 2.4796e+00, 2.0991e+00, 1.8115e+00, 1.5944e+00, 1.4273e+00, 1.2950e+00, 1.1867e+00, 1.0954e+00, 1.0163e+00, 9.4650e-01, 8.8390e-01, 8.2700e-01, 7.7500e-01, 7.2720e-01, 6.8300e-01, 6.4210e-01, 6.0410e-01, 5.6880e-01, 5.3600e-01, 5.0540e-01, 4.7700e-01, 4.5050e-01, 4.2580e-01, 4.0280e-01, 3.8130e-01, 3.6130e-01, 3.4260e-01, 3.2520e-01, 3.0890e-01, 2.9360e-01, 2.7940e-01, 2.6600e-01, 2.5350e-01, 2.4180e-01, 2.3090e-01, 2.2060e-01, 2.1090e-01, 2.0180e-01, 1.9330e-01, 1.8530e-01, 1.7770e-01, 1.7060e-01, 1.6380e-01, 1.5750e-01, 1.5150e-01, 1.4580e-01, 1.4050e-01, 1.3540e-01, 1.3060e-01, 1.2610e-01, 1.2170e-01, 1.1760e-01, 1.1370e-01, 1.1000e-01, 1.0650e-01, 1.0310e-01, 9.9900e-02, 9.6900e-02, 9.4000e-02, 9.1200e-02, 8.8500e-02, 8.6000e-02, 8.3600e-02, 8.1200e-02, 7.9000e-02, 7.6900e-02, 7.4800e-02, 7.2900e-02, 7.1000e-02, 6.9200e-02, 6.7400e-02, 6.5700e-02, 6.4100e-02, 6.2600e-02, 6.1100e-02, 5.9600e-02, 5.8200e-02, 5.6900e-02, 5.5600e-02, 5.4400e-02, 5.3200e-02, 5.2000e-02, 5.0900e-02, 4.9800e-02, 4.8700e-02, 4.7700e-02, 4.6700e-02, 4.5800e-02, 4.4800e-02, 4.3900e-02, 4.3100e-02, 4.2200e-02, 4.1400e-02, 4.0600e-02, 3.9800e-02, 3.9100e-02, 3.8400e-02, 3.7700e-02, 3.7000e-02, 3.6300e-02, 3.5600e-02, 3.5000e-02, 3.4400e-02, 3.3800e-02, 3.3200e-02, 3.2600e-02, 3.2100e-02, 3.1500e-02, 3.1000e-02, 3.0500e-02, 3.0000e-02, 2.9500e-02, 2.9000e-02, 2.8600e-02, 2.8100e-02, 2.7700e-02, 2.7200e-02, 2.6800e-02, 2.6400e-02, 2.6000e-02, 2.5600e-02, 2.5200e-02, 2.4900e-02, 2.4500e-02, 2.4100e-02, 2.3800e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2400e-02, 2.2100e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0100e-02, 1.9800e-02, 1.9600e-02, 1.9300e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8300e-02, 1.8100e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.7000e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6000e-02, 1.5800e-02, 1.5600e-02, 1.5400e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4500e-02, 1.4400e-02, 1.4200e-02, 1.4000e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3100e-02, 1.3000e-02, 1.2900e-02, 1.2700e-02, 1.2600e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.2000e-03, 8.1000e-03, 8.0000e-03, 7.9000e-03, 7.9000e-03, 7.8000e-03, 7.7000e-03, 7.7000e-03, 7.6000e-03, 7.5000e-03, 7.5000e-03, 7.4000e-03, 7.4000e-03, 7.3000e-03, 7.2000e-03}); + } + break; + case 12: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.2000e+01, 1.1868e+01, 1.1508e+01, 1.1011e+01, 1.0473e+01, 9.9603e+00, 9.5019e+00, 9.0978e+00, 8.7354e+00, 8.3995e+00, 8.0776e+00, 7.7614e+00, 7.4465e+00, 7.1315e+00, 6.8168e+00, 6.5038e+00, 6.1944e+00, 5.8909e+00, 5.5951e+00, 5.3089e+00, 5.0335e+00, 4.7702e+00, 4.5196e+00, 4.2823e+00, 4.0585e+00, 3.8482e+00, 3.6514e+00, 3.4676e+00, 3.2965e+00, 3.1376e+00, 2.9903e+00, 2.8541e+00, 2.7282e+00, 2.6122e+00, 2.5053e+00, 2.4069e+00, 2.3164e+00, 2.2332e+00, 2.1567e+00, 2.0865e+00, 2.0220e+00, 1.9627e+00, 1.9082e+00, 1.8580e+00, 1.8117e+00, 1.7691e+00, 1.7298e+00, 1.6933e+00, 1.6596e+00, 1.6283e+00, 1.5991e+00, 1.5719e+00, 1.5464e+00, 1.5226e+00, 1.5001e+00, 1.4788e+00, 1.4587e+00, 1.4396e+00, 1.4214e+00, 1.4040e+00, 1.3873e+00, 1.3711e+00, 1.3556e+00, 1.3405e+00, 1.3258e+00, 1.3115e+00, 1.2976e+00, 1.2839e+00, 1.2705e+00, 1.2572e+00, 1.2442e+00, 1.2314e+00, 1.2187e+00, 1.2061e+00, 1.1937e+00, 1.1813e+00, 1.1690e+00, 1.1568e+00, 1.1447e+00, 1.1327e+00, 1.1207e+00, 1.1087e+00, 1.0968e+00, 1.0850e+00, 1.0733e+00, 1.0615e+00, 1.0498e+00, 1.0381e+00, 1.0266e+00, 1.0151e+00, 1.0036e+00, 9.9200e-01, 9.8060e-01, 9.6930e-01, 9.5820e-01, 9.4690e-01, 9.3560e-01, 9.2440e-01, 9.1340e-01, 9.0260e-01, 8.9180e-01, 8.8080e-01, 8.6990e-01, 8.5910e-01, 8.4860e-01, 8.3830e-01, 8.2790e-01, 8.1740e-01, 8.0680e-01, 7.9660e-01, 7.8660e-01, 7.7690e-01, 7.6710e-01, 7.5700e-01, 7.4690e-01, 7.3710e-01, 7.2770e-01, 7.1850e-01, 7.0940e-01, 7.0000e-01, 6.9050e-01, 6.8110e-01, 6.7200e-01, 6.6340e-01, 6.5500e-01, 6.4650e-01, 6.3780e-01, 6.2880e-01, 6.2000e-01, 6.1160e-01, 6.0370e-01, 5.9600e-01, 5.8840e-01, 5.8040e-01, 5.7220e-01, 5.6390e-01, 5.5600e-01, 5.4860e-01, 5.4160e-01, 5.3480e-01, 5.2780e-01, 5.2040e-01, 5.1280e-01, 5.0530e-01, 4.9810e-01, 4.9150e-01, 4.8540e-01, 4.7940e-01, 4.7310e-01, 4.6650e-01, 4.5970e-01, 4.5280e-01, 4.4620e-01, 4.4010e-01, 4.3460e-01, 4.2940e-01, 4.2400e-01, 4.1830e-01, 4.1230e-01, 4.0610e-01, 3.9990e-01, 3.9410e-01, 3.8890e-01, 3.8420e-01, 3.7970e-01, 3.7500e-01, 3.7010e-01, 3.6480e-01, 3.5920e-01, 3.5370e-01, 3.4830e-01, 3.4360e-01, 3.3950e-01, 3.3570e-01, 3.3180e-01, 3.2760e-01, 3.2310e-01, 3.1840e-01, 3.1350e-01, 3.0860e-01, 3.0390e-01, 2.9990e-01, 2.9650e-01, 2.9330e-01, 2.9010e-01, 2.8650e-01, 2.8270e-01, 2.7860e-01, 2.7440e-01, 2.7000e-01, 2.6580e-01, 2.6200e-01, 2.5890e-01, 2.5630e-01, 2.5380e-01, 2.5090e-01, 2.4780e-01, 2.4440e-01, 2.4090e-01, 2.3720e-01, 2.3340e-01, 2.2970e-01, 2.2640e-01, 2.2380e-01, 2.2170e-01, 2.1970e-01, 2.1740e-01, 2.1480e-01, 2.1190e-01, 2.0900e-01, 2.0600e-01, 2.0270e-01, 1.9940e-01, 1.9620e-01, 1.9360e-01, 1.9170e-01, 1.9020e-01, 1.8860e-01, 1.8660e-01, 1.8430e-01, 1.8190e-01, 1.7940e-01, 1.7690e-01, 1.7420e-01, 1.7130e-01, 1.6840e-01, 1.6600e-01, 1.6430e-01, 1.6310e-01, 1.6200e-01, 1.6060e-01, 1.5880e-01, 1.5670e-01, 1.5460e-01, 1.5260e-01, 1.5060e-01, 1.4830e-01, 1.4570e-01, 1.4320e-01, 1.4110e-01, 1.3960e-01}); + feg = Vctr_cpu({5.2015e+00, 5.0711e+00, 4.7130e+00, 4.2097e+00, 3.6555e+00, 3.1243e+00, 2.6573e+00, 2.2681e+00, 1.9533e+00, 1.7022e+00, 1.5021e+00, 1.3414e+00, 1.2109e+00, 1.1032e+00, 1.0127e+00, 9.3540e-01, 8.6840e-01, 8.0950e-01, 7.5700e-01, 7.0980e-01, 6.6690e-01, 6.2780e-01, 5.9180e-01, 5.5870e-01, 5.2800e-01, 4.9950e-01, 4.7290e-01, 4.4820e-01, 4.2510e-01, 4.0350e-01, 3.8340e-01, 3.6440e-01, 3.4670e-01, 3.3010e-01, 3.1450e-01, 2.9990e-01, 2.8610e-01, 2.7320e-01, 2.6100e-01, 2.4960e-01, 2.3880e-01, 2.2870e-01, 2.1910e-01, 2.1000e-01, 2.0150e-01, 1.9350e-01, 1.8590e-01, 1.7870e-01, 1.7190e-01, 1.6540e-01, 1.5930e-01, 1.5350e-01, 1.4800e-01, 1.4280e-01, 1.3790e-01, 1.3320e-01, 1.2870e-01, 1.2450e-01, 1.2040e-01, 1.1660e-01, 1.1290e-01, 1.0940e-01, 1.0600e-01, 1.0280e-01, 9.9800e-02, 9.6900e-02, 9.4100e-02, 9.1400e-02, 8.8900e-02, 8.6400e-02, 8.4100e-02, 8.1800e-02, 7.9600e-02, 7.7600e-02, 7.5600e-02, 7.3700e-02, 7.1800e-02, 7.0000e-02, 6.8300e-02, 6.6700e-02, 6.5100e-02, 6.3600e-02, 6.2100e-02, 6.0700e-02, 5.9300e-02, 5.8000e-02, 5.6700e-02, 5.5500e-02, 5.4300e-02, 5.3100e-02, 5.2000e-02, 5.0900e-02, 4.9900e-02, 4.8800e-02, 4.7900e-02, 4.6900e-02, 4.6000e-02, 4.5100e-02, 4.4200e-02, 4.3400e-02, 4.2500e-02, 4.1700e-02, 4.1000e-02, 4.0200e-02, 3.9500e-02, 3.8800e-02, 3.8100e-02, 3.7400e-02, 3.6700e-02, 3.6100e-02, 3.5500e-02, 3.4900e-02, 3.4300e-02, 3.3700e-02, 3.3200e-02, 3.2600e-02, 3.2100e-02, 3.1600e-02, 3.1100e-02, 3.0600e-02, 3.0100e-02, 2.9600e-02, 2.9100e-02, 2.8700e-02, 2.8300e-02, 2.7800e-02, 2.7400e-02, 2.7000e-02, 2.6600e-02, 2.6200e-02, 2.5800e-02, 2.5400e-02, 2.5100e-02, 2.4700e-02, 2.4400e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3000e-02, 2.2700e-02, 2.2400e-02, 2.2100e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.1000e-02, 2.0700e-02, 2.0400e-02, 2.0200e-02, 1.9900e-02, 1.9600e-02, 1.9400e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6200e-02, 1.6000e-02, 1.5800e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3500e-02, 1.3400e-02, 1.3200e-02, 1.3100e-02, 1.3000e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 8.9000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.6000e-03, 8.6000e-03, 8.5000e-03, 8.4000e-03, 8.4000e-03, 8.3000e-03, 8.2000e-03, 8.1000e-03, 8.1000e-03, 8.0000e-03, 8.0000e-03, 7.9000e-03}); + } + break; + case 13: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.3000e+01, 1.2850e+01, 1.2439e+01, 1.1864e+01, 1.1230e+01, 1.0614e+01, 1.0059e+01, 9.5759e+00, 9.1582e+00, 8.7927e+00, 8.4648e+00, 8.1616e+00, 7.8731e+00, 7.5925e+00, 7.3157e+00, 7.0405e+00, 6.7663e+00, 6.4934e+00, 6.2226e+00, 5.9552e+00, 5.6924e+00, 5.4357e+00, 5.1861e+00, 4.9448e+00, 4.7124e+00, 4.4896e+00, 4.2770e+00, 4.0748e+00, 3.8831e+00, 3.7020e+00, 3.5314e+00, 3.3709e+00, 3.2205e+00, 3.0797e+00, 2.9482e+00, 2.8256e+00, 2.7114e+00, 2.6052e+00, 2.5066e+00, 2.4150e+00, 2.3301e+00, 2.2514e+00, 2.1785e+00, 2.1109e+00, 2.0484e+00, 1.9905e+00, 1.9368e+00, 1.8871e+00, 1.8411e+00, 1.7983e+00, 1.7586e+00, 1.7217e+00, 1.6873e+00, 1.6553e+00, 1.6254e+00, 1.5975e+00, 1.5713e+00, 1.5467e+00, 1.5236e+00, 1.5017e+00, 1.4811e+00, 1.4615e+00, 1.4429e+00, 1.4251e+00, 1.4082e+00, 1.3919e+00, 1.3763e+00, 1.3612e+00, 1.3466e+00, 1.3325e+00, 1.3188e+00, 1.3054e+00, 1.2924e+00, 1.2796e+00, 1.2671e+00, 1.2548e+00, 1.2427e+00, 1.2308e+00, 1.2190e+00, 1.2073e+00, 1.1958e+00, 1.1845e+00, 1.1732e+00, 1.1619e+00, 1.1507e+00, 1.1397e+00, 1.1288e+00, 1.1178e+00, 1.1068e+00, 1.0959e+00, 1.0852e+00, 1.0745e+00, 1.0638e+00, 1.0530e+00, 1.0423e+00, 1.0318e+00, 1.0214e+00, 1.0109e+00, 1.0003e+00, 9.8970e-01, 9.7930e-01, 9.6920e-01, 9.5900e-01, 9.4870e-01, 9.3830e-01, 9.2800e-01, 9.1800e-01, 9.0820e-01, 8.9840e-01, 8.8830e-01, 8.7820e-01, 8.6810e-01, 8.5840e-01, 8.4900e-01, 8.3970e-01, 8.3010e-01, 8.2030e-01, 8.1060e-01, 8.0110e-01, 7.9200e-01, 7.8320e-01, 7.7430e-01, 7.6510e-01, 7.5570e-01, 7.4640e-01, 7.3740e-01, 7.2900e-01, 7.2070e-01, 7.1240e-01, 7.0380e-01, 6.9490e-01, 6.8600e-01, 6.7750e-01, 6.6950e-01, 6.6190e-01, 6.5430e-01, 6.4640e-01, 6.3830e-01, 6.2990e-01, 6.2160e-01, 6.1390e-01, 6.0670e-01, 5.9980e-01, 5.9290e-01, 5.8570e-01, 5.7810e-01, 5.7030e-01, 5.6260e-01, 5.5540e-01, 5.4880e-01, 5.4260e-01, 5.3650e-01, 5.3010e-01, 5.2340e-01, 5.1620e-01, 5.0900e-01, 5.0210e-01, 4.9580e-01, 4.9010e-01, 4.8470e-01, 4.7930e-01, 4.7360e-01, 4.6750e-01, 4.6100e-01, 4.5430e-01, 4.4800e-01, 4.4230e-01, 4.3730e-01, 4.3250e-01, 4.2780e-01, 4.2290e-01, 4.1770e-01, 4.1200e-01, 4.0600e-01, 4.0000e-01, 3.9450e-01, 3.8980e-01, 3.8550e-01, 3.8150e-01, 3.7740e-01, 3.7320e-01, 3.6870e-01, 3.6360e-01, 3.5810e-01, 3.5270e-01, 3.4770e-01, 3.4340e-01, 3.3970e-01, 3.3630e-01, 3.3290e-01, 3.2940e-01, 3.2570e-01, 3.2150e-01, 3.1690e-01, 3.1190e-01, 3.0700e-01, 3.0280e-01, 2.9920e-01, 2.9620e-01, 2.9330e-01, 2.9050e-01, 2.8760e-01, 2.8450e-01, 2.8110e-01, 2.7710e-01, 2.7270e-01, 2.6820e-01, 2.6420e-01, 2.6090e-01, 2.5820e-01, 2.5590e-01, 2.5350e-01, 2.5110e-01, 2.4870e-01, 2.4610e-01, 2.4310e-01, 2.3960e-01, 2.3560e-01, 2.3160e-01, 2.2800e-01, 2.2520e-01, 2.2300e-01, 2.2110e-01, 2.1920e-01, 2.1720e-01, 2.1520e-01, 2.1320e-01, 2.1100e-01, 2.0830e-01, 2.0500e-01, 2.0140e-01, 1.9780e-01, 1.9480e-01, 1.9260e-01, 1.9100e-01, 1.8950e-01, 1.8800e-01, 1.8630e-01, 1.8470e-01, 1.8310e-01, 1.8140e-01}); + feg = Vctr_cpu({5.8861e+00, 5.7481e+00, 5.3687e+00, 4.8331e+00, 4.2367e+00, 3.6540e+00, 3.1280e+00, 2.6760e+00, 2.2987e+00, 1.9890e+00, 1.7367e+00, 1.5313e+00, 1.3634e+00, 1.2253e+00, 1.1106e+00, 1.0143e+00, 9.3250e-01, 8.6220e-01, 8.0100e-01, 7.4730e-01, 6.9960e-01, 6.5680e-01, 6.1820e-01, 5.8310e-01, 5.5100e-01, 5.2140e-01, 4.9410e-01, 4.6880e-01, 4.4530e-01, 4.2340e-01, 4.0290e-01, 3.8370e-01, 3.6570e-01, 3.4880e-01, 3.3300e-01, 3.1810e-01, 3.0400e-01, 2.9080e-01, 2.7830e-01, 2.6650e-01, 2.5540e-01, 2.4490e-01, 2.3490e-01, 2.2550e-01, 2.1660e-01, 2.0820e-01, 2.0020e-01, 1.9260e-01, 1.8550e-01, 1.7870e-01, 1.7220e-01, 1.6600e-01, 1.6020e-01, 1.5470e-01, 1.4940e-01, 1.4430e-01, 1.3960e-01, 1.3500e-01, 1.3060e-01, 1.2650e-01, 1.2250e-01, 1.1870e-01, 1.1510e-01, 1.1170e-01, 1.0840e-01, 1.0520e-01, 1.0220e-01, 9.9300e-02, 9.6500e-02, 9.3800e-02, 9.1300e-02, 8.8800e-02, 8.6500e-02, 8.4200e-02, 8.2000e-02, 8.0000e-02, 7.7900e-02, 7.6000e-02, 7.4200e-02, 7.2400e-02, 7.0600e-02, 6.9000e-02, 6.7400e-02, 6.5800e-02, 6.4300e-02, 6.2900e-02, 6.1500e-02, 6.0100e-02, 5.8800e-02, 5.7600e-02, 5.6300e-02, 5.5100e-02, 5.4000e-02, 5.2900e-02, 5.1800e-02, 5.0800e-02, 4.9800e-02, 4.8800e-02, 4.7800e-02, 4.6900e-02, 4.6000e-02, 4.5200e-02, 4.4300e-02, 4.3500e-02, 4.2700e-02, 4.1900e-02, 4.1200e-02, 4.0400e-02, 3.9700e-02, 3.9000e-02, 3.8400e-02, 3.7700e-02, 3.7100e-02, 3.6400e-02, 3.5800e-02, 3.5200e-02, 3.4700e-02, 3.4100e-02, 3.3500e-02, 3.3000e-02, 3.2500e-02, 3.2000e-02, 3.1500e-02, 3.1000e-02, 3.0500e-02, 3.0100e-02, 2.9600e-02, 2.9200e-02, 2.8700e-02, 2.8300e-02, 2.7900e-02, 2.7500e-02, 2.7100e-02, 2.6700e-02, 2.6300e-02, 2.5900e-02, 2.5600e-02, 2.5200e-02, 2.4900e-02, 2.4500e-02, 2.4200e-02, 2.3900e-02, 2.3500e-02, 2.3200e-02, 2.2900e-02, 2.2600e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.0900e-02, 2.0700e-02, 2.0400e-02, 2.0200e-02, 1.9900e-02, 1.9700e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6500e-02, 1.6300e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4000e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.3000e-03, 9.2000e-03, 9.1000e-03, 9.0000e-03, 9.0000e-03, 8.9000e-03, 8.8000e-03, 8.7000e-03, 8.7000e-03, 8.6000e-03, 8.5000e-03}); + } + break; + case 14: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.4000e+01, 1.3851e+01, 1.3435e+01, 1.2831e+01, 1.2135e+01, 1.1430e+01, 1.0770e+01, 1.0183e+01, 9.6736e+00, 9.2366e+00, 8.8595e+00, 8.5286e+00, 8.2313e+00, 7.9572e+00, 7.6980e+00, 7.4477e+00, 7.2025e+00, 6.9599e+00, 6.7187e+00, 6.4786e+00, 6.2398e+00, 6.0029e+00, 5.7687e+00, 5.5382e+00, 5.3123e+00, 5.0918e+00, 4.8774e+00, 4.6699e+00, 4.4699e+00, 4.2776e+00, 4.0934e+00, 3.9176e+00, 3.7502e+00, 3.5912e+00, 3.4405e+00, 3.2981e+00, 3.1637e+00, 3.0372e+00, 2.9182e+00, 2.8065e+00, 2.7017e+00, 2.6036e+00, 2.5118e+00, 2.4260e+00, 2.3459e+00, 2.2711e+00, 2.2014e+00, 2.1363e+00, 2.0757e+00, 2.0191e+00, 1.9664e+00, 1.9173e+00, 1.8714e+00, 1.8287e+00, 1.7888e+00, 1.7515e+00, 1.7166e+00, 1.6840e+00, 1.6535e+00, 1.6248e+00, 1.5979e+00, 1.5726e+00, 1.5487e+00, 1.5262e+00, 1.5049e+00, 1.4847e+00, 1.4656e+00, 1.4474e+00, 1.4300e+00, 1.4133e+00, 1.3974e+00, 1.3821e+00, 1.3674e+00, 1.3532e+00, 1.3394e+00, 1.3261e+00, 1.3132e+00, 1.3006e+00, 1.2883e+00, 1.2763e+00, 1.2645e+00, 1.2529e+00, 1.2416e+00, 1.2304e+00, 1.2194e+00, 1.2085e+00, 1.1978e+00, 1.1872e+00, 1.1766e+00, 1.1662e+00, 1.1559e+00, 1.1456e+00, 1.1354e+00, 1.1252e+00, 1.1152e+00, 1.1052e+00, 1.0951e+00, 1.0852e+00, 1.0752e+00, 1.0654e+00, 1.0557e+00, 1.0459e+00, 1.0361e+00, 1.0263e+00, 1.0166e+00, 1.0071e+00, 9.9750e-01, 9.8800e-01, 9.7830e-01, 9.6870e-01, 9.5930e-01, 9.5000e-01, 9.4070e-01, 9.3140e-01, 9.2200e-01, 9.1260e-01, 9.0330e-01, 8.9430e-01, 8.8530e-01, 8.7640e-01, 8.6730e-01, 8.5810e-01, 8.4900e-01, 8.4010e-01, 8.3150e-01, 8.2300e-01, 8.1440e-01, 8.0560e-01, 7.9670e-01, 7.8800e-01, 7.7950e-01, 7.7140e-01, 7.6340e-01, 7.5520e-01, 7.4690e-01, 7.3840e-01, 7.2990e-01, 7.2180e-01, 7.1410e-01, 7.0660e-01, 6.9910e-01, 6.9130e-01, 6.8340e-01, 6.7530e-01, 6.6740e-01, 6.5990e-01, 6.5270e-01, 6.4590e-01, 6.3900e-01, 6.3180e-01, 6.2430e-01, 6.1670e-01, 6.0930e-01, 6.0220e-01, 5.9560e-01, 5.8930e-01, 5.8310e-01, 5.7670e-01, 5.6990e-01, 5.6280e-01, 5.5580e-01, 5.4900e-01, 5.4260e-01, 5.3670e-01, 5.3120e-01, 5.2570e-01, 5.1990e-01, 5.1370e-01, 5.0720e-01, 5.0060e-01, 4.9430e-01, 4.8840e-01, 4.8310e-01, 4.7810e-01, 4.7340e-01, 4.6840e-01, 4.6300e-01, 4.5710e-01, 4.5110e-01, 4.4510e-01, 4.3950e-01, 4.3440e-01, 4.2980e-01, 4.2560e-01, 4.2150e-01, 4.1720e-01, 4.1230e-01, 4.0710e-01, 4.0150e-01, 3.9610e-01, 3.9100e-01, 3.8630e-01, 3.8210e-01, 3.7840e-01, 3.7490e-01, 3.7140e-01, 3.6750e-01, 3.6300e-01, 3.5810e-01, 3.5310e-01, 3.4830e-01, 3.4370e-01, 3.3960e-01, 3.3600e-01, 3.3300e-01, 3.3020e-01, 3.2730e-01, 3.2410e-01, 3.2020e-01, 3.1580e-01, 3.1130e-01, 3.0690e-01, 3.0270e-01, 2.9890e-01, 2.9560e-01, 2.9270e-01, 2.9030e-01, 2.8820e-01, 2.8580e-01, 2.8300e-01, 2.7940e-01, 2.7550e-01, 2.7140e-01, 2.6750e-01, 2.6380e-01, 2.6040e-01, 2.5750e-01, 2.5500e-01, 2.5300e-01, 2.5130e-01, 2.4970e-01, 2.4750e-01, 2.4480e-01, 2.4140e-01, 2.3770e-01, 2.3410e-01, 2.3070e-01, 2.2760e-01, 2.2470e-01, 2.2220e-01, 2.2020e-01}); + feg = Vctr_cpu({5.8107e+00, 5.7053e+00, 5.4089e+00, 4.9733e+00, 4.4630e+00, 3.9366e+00, 3.4356e+00, 2.9833e+00, 2.5886e+00, 2.2520e+00, 1.9685e+00, 1.7316e+00, 1.5341e+00, 1.3692e+00, 1.2313e+00, 1.1152e+00, 1.0168e+00, 9.3280e-01, 8.6060e-01, 7.9780e-01, 7.4290e-01, 6.9440e-01, 6.5130e-01, 6.1250e-01, 5.7760e-01, 5.4580e-01, 5.1680e-01, 4.9010e-01, 4.6550e-01, 4.4270e-01, 4.2150e-01, 4.0180e-01, 3.8330e-01, 3.6600e-01, 3.4980e-01, 3.3450e-01, 3.2020e-01, 3.0670e-01, 2.9390e-01, 2.8180e-01, 2.7040e-01, 2.5960e-01, 2.4940e-01, 2.3970e-01, 2.3050e-01, 2.2180e-01, 2.1350e-01, 2.0570e-01, 1.9820e-01, 1.9110e-01, 1.8430e-01, 1.7790e-01, 1.7180e-01, 1.6590e-01, 1.6040e-01, 1.5510e-01, 1.5000e-01, 1.4520e-01, 1.4050e-01, 1.3610e-01, 1.3190e-01, 1.2790e-01, 1.2400e-01, 1.2040e-01, 1.1680e-01, 1.1340e-01, 1.1020e-01, 1.0710e-01, 1.0410e-01, 1.0120e-01, 9.8500e-02, 9.5900e-02, 9.3300e-02, 9.0900e-02, 8.8500e-02, 8.6300e-02, 8.4100e-02, 8.2000e-02, 8.0000e-02, 7.8100e-02, 7.6200e-02, 7.4400e-02, 7.2700e-02, 7.1000e-02, 6.9400e-02, 6.7800e-02, 6.6300e-02, 6.4800e-02, 6.3400e-02, 6.2000e-02, 6.0700e-02, 5.9400e-02, 5.8200e-02, 5.7000e-02, 5.5800e-02, 5.4700e-02, 5.3600e-02, 5.2600e-02, 5.1500e-02, 5.0500e-02, 4.9600e-02, 4.8600e-02, 4.7700e-02, 4.6800e-02, 4.6000e-02, 4.5100e-02, 4.4300e-02, 4.3500e-02, 4.2800e-02, 4.2000e-02, 4.1300e-02, 4.0600e-02, 3.9900e-02, 3.9200e-02, 3.8500e-02, 3.7900e-02, 3.7300e-02, 3.6700e-02, 3.6100e-02, 3.5500e-02, 3.4900e-02, 3.4400e-02, 3.3800e-02, 3.3300e-02, 3.2800e-02, 3.2300e-02, 3.1800e-02, 3.1300e-02, 3.0900e-02, 3.0400e-02, 3.0000e-02, 2.9500e-02, 2.9100e-02, 2.8700e-02, 2.8300e-02, 2.7900e-02, 2.7500e-02, 2.7100e-02, 2.6700e-02, 2.6300e-02, 2.6000e-02, 2.5600e-02, 2.5300e-02, 2.5000e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2500e-02, 2.2200e-02, 2.1900e-02, 2.1600e-02, 2.1400e-02, 2.1100e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0100e-02, 1.9900e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5500e-02, 1.5400e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4100e-02, 1.4000e-02, 1.3900e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03, 9.7000e-03, 9.6000e-03, 9.5000e-03, 9.5000e-03, 9.4000e-03, 9.3000e-03, 9.2000e-03, 9.2000e-03}); + } + break; + case 15: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.5000e+01, 1.4858e+01, 1.4457e+01, 1.3856e+01, 1.3136e+01, 1.2373e+01, 1.1627e+01, 1.0939e+01, 1.0326e+01, 9.7930e+00, 9.3348e+00, 8.9412e+00, 8.6001e+00, 8.2998e+00, 8.0298e+00, 7.7813e+00, 7.5473e+00, 7.3228e+00, 7.1040e+00, 6.8884e+00, 6.6746e+00, 6.4618e+00, 6.2499e+00, 6.0390e+00, 5.8296e+00, 5.6222e+00, 5.4177e+00, 5.2165e+00, 5.0195e+00, 4.8272e+00, 4.6402e+00, 4.4588e+00, 4.2836e+00, 4.1148e+00, 3.9525e+00, 3.7971e+00, 3.6485e+00, 3.5067e+00, 3.3717e+00, 3.2435e+00, 3.1219e+00, 3.0067e+00, 2.8978e+00, 2.7950e+00, 2.6980e+00, 2.6066e+00, 2.5206e+00, 2.4398e+00, 2.3638e+00, 2.2924e+00, 2.2255e+00, 2.1626e+00, 2.1037e+00, 2.0485e+00, 1.9967e+00, 1.9482e+00, 1.9026e+00, 1.8600e+00, 1.8200e+00, 1.7824e+00, 1.7471e+00, 1.7140e+00, 1.6829e+00, 1.6536e+00, 1.6260e+00, 1.5999e+00, 1.5754e+00, 1.5522e+00, 1.5302e+00, 1.5094e+00, 1.4896e+00, 1.4708e+00, 1.4528e+00, 1.4357e+00, 1.4194e+00, 1.4037e+00, 1.3886e+00, 1.3742e+00, 1.3602e+00, 1.3467e+00, 1.3337e+00, 1.3210e+00, 1.3087e+00, 1.2968e+00, 1.2851e+00, 1.2737e+00, 1.2625e+00, 1.2516e+00, 1.2409e+00, 1.2303e+00, 1.2199e+00, 1.2097e+00, 1.1995e+00, 1.1896e+00, 1.1797e+00, 1.1699e+00, 1.1602e+00, 1.1506e+00, 1.1410e+00, 1.1316e+00, 1.1222e+00, 1.1128e+00, 1.1035e+00, 1.0942e+00, 1.0850e+00, 1.0759e+00, 1.0668e+00, 1.0577e+00, 1.0486e+00, 1.0395e+00, 1.0305e+00, 1.0216e+00, 1.0127e+00, 1.0038e+00, 9.9490e-01, 9.8600e-01, 9.7710e-01, 9.6840e-01, 9.5980e-01, 9.5120e-01, 9.4240e-01, 9.3370e-01, 9.2490e-01, 9.1640e-01, 9.0800e-01, 8.9970e-01, 8.9120e-01, 8.8270e-01, 8.7420e-01, 8.6570e-01, 8.5740e-01, 8.4940e-01, 8.4140e-01, 8.3330e-01, 8.2510e-01, 8.1680e-01, 8.0850e-01, 8.0050e-01, 7.9270e-01, 7.8510e-01, 7.7750e-01, 7.6980e-01, 7.6180e-01, 7.5390e-01, 7.4600e-01, 7.3840e-01, 7.3120e-01, 7.2410e-01, 7.1690e-01, 7.0960e-01, 7.0210e-01, 6.9450e-01, 6.8700e-01, 6.7980e-01, 6.7290e-01, 6.6630e-01, 6.5980e-01, 6.5310e-01, 6.4610e-01, 6.3890e-01, 6.3180e-01, 6.2480e-01, 6.1820e-01, 6.1200e-01, 6.0600e-01, 6.0010e-01, 5.9390e-01, 5.8750e-01, 5.8080e-01, 5.7400e-01, 5.6750e-01, 5.6140e-01, 5.5560e-01, 5.5020e-01, 5.4500e-01, 5.3950e-01, 5.3370e-01, 5.2760e-01, 5.2140e-01, 5.1510e-01, 5.0920e-01, 5.0380e-01, 4.9870e-01, 4.9400e-01, 4.8940e-01, 4.8460e-01, 4.7940e-01, 4.7380e-01, 4.6800e-01, 4.6220e-01, 4.5670e-01, 4.5170e-01, 4.4710e-01, 4.4290e-01, 4.3900e-01, 4.3490e-01, 4.3050e-01, 4.2570e-01, 4.2050e-01, 4.1510e-01, 4.0990e-01, 4.0500e-01, 4.0050e-01, 3.9660e-01, 3.9300e-01, 3.8970e-01, 3.8640e-01, 3.8260e-01, 3.7840e-01, 3.7370e-01, 3.6880e-01, 3.6400e-01, 3.5940e-01, 3.5520e-01, 3.5150e-01, 3.4830e-01, 3.4550e-01, 3.4290e-01, 3.4000e-01, 3.3670e-01, 3.3280e-01, 3.2860e-01, 3.2410e-01, 3.1970e-01, 3.1560e-01, 3.1190e-01, 3.0860e-01, 3.0580e-01, 3.0350e-01, 3.0140e-01, 2.9920e-01, 2.9660e-01, 2.9350e-01, 2.8990e-01, 2.8590e-01, 2.8180e-01, 2.7800e-01, 2.7440e-01, 2.7110e-01, 2.6840e-01, 2.6610e-01}); + feg = Vctr_cpu({5.4946e+00, 5.4177e+00, 5.1982e+00, 4.8661e+00, 4.4615e+00, 4.0243e+00, 3.5875e+00, 3.1739e+00, 2.7967e+00, 2.4617e+00, 2.1694e+00, 1.9175e+00, 1.7019e+00, 1.5182e+00, 1.3618e+00, 1.2286e+00, 1.1148e+00, 1.0173e+00, 9.3320e-01, 8.6050e-01, 7.9700e-01, 7.4140e-01, 6.9230e-01, 6.4870e-01, 6.0970e-01, 5.7460e-01, 5.4280e-01, 5.1390e-01, 4.8750e-01, 4.6320e-01, 4.4080e-01, 4.2000e-01, 4.0080e-01, 3.8280e-01, 3.6600e-01, 3.5020e-01, 3.3540e-01, 3.2150e-01, 3.0840e-01, 2.9600e-01, 2.8430e-01, 2.7320e-01, 2.6270e-01, 2.5280e-01, 2.4330e-01, 2.3440e-01, 2.2580e-01, 2.1770e-01, 2.1000e-01, 2.0270e-01, 1.9570e-01, 1.8900e-01, 1.8260e-01, 1.7660e-01, 1.7080e-01, 1.6520e-01, 1.5990e-01, 1.5490e-01, 1.5000e-01, 1.4540e-01, 1.4100e-01, 1.3670e-01, 1.3270e-01, 1.2880e-01, 1.2500e-01, 1.2150e-01, 1.1800e-01, 1.1470e-01, 1.1160e-01, 1.0850e-01, 1.0560e-01, 1.0280e-01, 1.0010e-01, 9.7500e-02, 9.5000e-02, 9.2600e-02, 9.0200e-02, 8.8000e-02, 8.5900e-02, 8.3800e-02, 8.1800e-02, 7.9800e-02, 7.8000e-02, 7.6200e-02, 7.4400e-02, 7.2800e-02, 7.1100e-02, 6.9600e-02, 6.8000e-02, 6.6600e-02, 6.5100e-02, 6.3800e-02, 6.2400e-02, 6.1100e-02, 5.9900e-02, 5.8700e-02, 5.7500e-02, 5.6400e-02, 5.5300e-02, 5.4200e-02, 5.3100e-02, 5.2100e-02, 5.1100e-02, 5.0200e-02, 4.9300e-02, 4.8400e-02, 4.7500e-02, 4.6600e-02, 4.5800e-02, 4.5000e-02, 4.4200e-02, 4.3400e-02, 4.2700e-02, 4.2000e-02, 4.1300e-02, 4.0600e-02, 3.9900e-02, 3.9300e-02, 3.8600e-02, 3.8000e-02, 3.7400e-02, 3.6800e-02, 3.6200e-02, 3.5600e-02, 3.5100e-02, 3.4600e-02, 3.4000e-02, 3.3500e-02, 3.3000e-02, 3.2500e-02, 3.2000e-02, 3.1600e-02, 3.1100e-02, 3.0700e-02, 3.0200e-02, 2.9800e-02, 2.9400e-02, 2.9000e-02, 2.8600e-02, 2.8200e-02, 2.7800e-02, 2.7400e-02, 2.7000e-02, 2.6700e-02, 2.6300e-02, 2.6000e-02, 2.5600e-02, 2.5300e-02, 2.5000e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2600e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1500e-02, 2.1200e-02, 2.1000e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.5000e-02, 1.4800e-02, 1.4700e-02, 1.4500e-02, 1.4400e-02, 1.4200e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02, 1.0300e-02, 1.0200e-02, 1.0100e-02, 1.0000e-02, 1.0000e-02, 9.9000e-03, 9.8000e-03}); + } + break; + case 16: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.6000e+01, 1.5867e+01, 1.5483e+01, 1.4898e+01, 1.4175e+01, 1.3383e+01, 1.2581e+01, 1.1813e+01, 1.1107e+01, 1.0477e+01, 9.9259e+00, 9.4495e+00, 9.0393e+00, 8.6850e+00, 8.3761e+00, 8.1029e+00, 7.8567e+00, 7.6303e+00, 7.4178e+00, 7.2148e+00, 7.0178e+00, 6.8246e+00, 6.6334e+00, 6.4434e+00, 6.2541e+00, 6.0654e+00, 5.8774e+00, 5.6905e+00, 5.5052e+00, 5.3219e+00, 5.1412e+00, 4.9636e+00, 4.7897e+00, 4.6197e+00, 4.4543e+00, 4.2936e+00, 4.1379e+00, 3.9876e+00, 3.8427e+00, 3.7034e+00, 3.5698e+00, 3.4418e+00, 3.3194e+00, 3.2027e+00, 3.0914e+00, 2.9856e+00, 2.8850e+00, 2.7895e+00, 2.6991e+00, 2.6134e+00, 2.5323e+00, 2.4557e+00, 2.3834e+00, 2.3150e+00, 2.2506e+00, 2.1898e+00, 2.1325e+00, 2.0785e+00, 2.0276e+00, 1.9797e+00, 1.9346e+00, 1.8921e+00, 1.8520e+00, 1.8143e+00, 1.7787e+00, 1.7451e+00, 1.7135e+00, 1.6836e+00, 1.6554e+00, 1.6287e+00, 1.6034e+00, 1.5795e+00, 1.5568e+00, 1.5353e+00, 1.5149e+00, 1.4954e+00, 1.4769e+00, 1.4592e+00, 1.4423e+00, 1.4262e+00, 1.4107e+00, 1.3958e+00, 1.3815e+00, 1.3677e+00, 1.3544e+00, 1.3416e+00, 1.3291e+00, 1.3170e+00, 1.3053e+00, 1.2938e+00, 1.2827e+00, 1.2718e+00, 1.2612e+00, 1.2507e+00, 1.2405e+00, 1.2305e+00, 1.2206e+00, 1.2109e+00, 1.2013e+00, 1.1918e+00, 1.1825e+00, 1.1732e+00, 1.1641e+00, 1.1550e+00, 1.1460e+00, 1.1371e+00, 1.1283e+00, 1.1195e+00, 1.1107e+00, 1.1020e+00, 1.0934e+00, 1.0848e+00, 1.0763e+00, 1.0678e+00, 1.0593e+00, 1.0508e+00, 1.0424e+00, 1.0340e+00, 1.0257e+00, 1.0174e+00, 1.0091e+00, 1.0008e+00, 9.9250e-01, 9.8430e-01, 9.7620e-01, 9.6810e-01, 9.6000e-01, 9.5190e-01, 9.4370e-01, 9.3560e-01, 9.2760e-01, 9.1980e-01, 9.1190e-01, 9.0410e-01, 8.9610e-01, 8.8810e-01, 8.8020e-01, 8.7240e-01, 8.6480e-01, 8.5720e-01, 8.4970e-01, 8.4200e-01, 8.3430e-01, 8.2660e-01, 8.1890e-01, 8.1140e-01, 8.0420e-01, 7.9700e-01, 7.8980e-01, 7.8250e-01, 7.7500e-01, 7.6760e-01, 7.6020e-01, 7.5300e-01, 7.4610e-01, 7.3930e-01, 7.3260e-01, 7.2570e-01, 7.1870e-01, 7.1160e-01, 7.0450e-01, 6.9750e-01, 6.9080e-01, 6.8440e-01, 6.7810e-01, 6.7190e-01, 6.6550e-01, 6.5890e-01, 6.5210e-01, 6.4540e-01, 6.3880e-01, 6.3250e-01, 6.2650e-01, 6.2070e-01, 6.1510e-01, 6.0930e-01, 6.0320e-01, 5.9700e-01, 5.9060e-01, 5.8430e-01, 5.7820e-01, 5.7250e-01, 5.6710e-01, 5.6200e-01, 5.5690e-01, 5.5170e-01, 5.4620e-01, 5.4040e-01, 5.3440e-01, 5.2850e-01, 5.2280e-01, 5.1750e-01, 5.1260e-01, 5.0800e-01, 5.0350e-01, 4.9900e-01, 4.9420e-01, 4.8910e-01, 4.8360e-01, 4.7810e-01, 4.7270e-01, 4.6750e-01, 4.6270e-01, 4.5840e-01, 4.5440e-01, 4.5060e-01, 4.4670e-01, 4.4250e-01, 4.3790e-01, 4.3300e-01, 4.2790e-01, 4.2280e-01, 4.1800e-01, 4.1350e-01, 4.0950e-01, 4.0590e-01, 4.0260e-01, 3.9940e-01, 3.9610e-01, 3.9240e-01, 3.8820e-01, 3.8370e-01, 3.7900e-01, 3.7430e-01, 3.6990e-01, 3.6590e-01, 3.6230e-01, 3.5910e-01, 3.5640e-01, 3.5380e-01, 3.5110e-01, 3.4810e-01, 3.4460e-01, 3.4070e-01, 3.3650e-01, 3.3220e-01, 3.2800e-01, 3.2410e-01, 3.2050e-01, 3.1750e-01, 3.1490e-01}); + feg = Vctr_cpu({5.1696e+00, 5.1119e+00, 4.9455e+00, 4.6888e+00, 4.3674e+00, 4.0087e+00, 3.6373e+00, 3.2726e+00, 2.9279e+00, 2.6112e+00, 2.3260e+00, 2.0731e+00, 1.8511e+00, 1.6575e+00, 1.4895e+00, 1.3440e+00, 1.2181e+00, 1.1090e+00, 1.0143e+00, 9.3190e-01, 8.5990e-01, 7.9670e-01, 7.4110e-01, 6.9180e-01, 6.4790e-01, 6.0870e-01, 5.7340e-01, 5.4150e-01, 5.1260e-01, 4.8620e-01, 4.6200e-01, 4.3980e-01, 4.1920e-01, 4.0020e-01, 3.8250e-01, 3.6590e-01, 3.5050e-01, 3.3600e-01, 3.2240e-01, 3.0960e-01, 2.9750e-01, 2.8610e-01, 2.7530e-01, 2.6500e-01, 2.5530e-01, 2.4610e-01, 2.3730e-01, 2.2900e-01, 2.2110e-01, 2.1350e-01, 2.0630e-01, 1.9940e-01, 1.9280e-01, 1.8660e-01, 1.8060e-01, 1.7480e-01, 1.6930e-01, 1.6410e-01, 1.5910e-01, 1.5420e-01, 1.4960e-01, 1.4520e-01, 1.4090e-01, 1.3690e-01, 1.3300e-01, 1.2920e-01, 1.2560e-01, 1.2210e-01, 1.1880e-01, 1.1560e-01, 1.1250e-01, 1.0950e-01, 1.0670e-01, 1.0390e-01, 1.0130e-01, 9.8700e-02, 9.6300e-02, 9.3900e-02, 9.1600e-02, 8.9400e-02, 8.7300e-02, 8.5200e-02, 8.3300e-02, 8.1300e-02, 7.9500e-02, 7.7700e-02, 7.6000e-02, 7.4300e-02, 7.2700e-02, 7.1100e-02, 6.9600e-02, 6.8100e-02, 6.6700e-02, 6.5300e-02, 6.4000e-02, 6.2700e-02, 6.1400e-02, 6.0200e-02, 5.9000e-02, 5.7900e-02, 5.6700e-02, 5.5700e-02, 5.4600e-02, 5.3600e-02, 5.2600e-02, 5.1600e-02, 5.0700e-02, 4.9800e-02, 4.8900e-02, 4.8000e-02, 4.7200e-02, 4.6400e-02, 4.5600e-02, 4.4800e-02, 4.4000e-02, 4.3300e-02, 4.2600e-02, 4.1900e-02, 4.1200e-02, 4.0500e-02, 3.9900e-02, 3.9200e-02, 3.8600e-02, 3.8000e-02, 3.7400e-02, 3.6800e-02, 3.6300e-02, 3.5700e-02, 3.5200e-02, 3.4700e-02, 3.4200e-02, 3.3700e-02, 3.3200e-02, 3.2700e-02, 3.2200e-02, 3.1800e-02, 3.1300e-02, 3.0900e-02, 3.0400e-02, 3.0000e-02, 2.9600e-02, 2.9200e-02, 2.8800e-02, 2.8400e-02, 2.8000e-02, 2.7700e-02, 2.7300e-02, 2.6900e-02, 2.6600e-02, 2.6200e-02, 2.5900e-02, 2.5600e-02, 2.5300e-02, 2.4900e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3200e-02, 2.2900e-02, 2.2600e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1300e-02, 2.1100e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7800e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4200e-02, 1.4000e-02, 1.3900e-02, 1.3800e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1000e-02, 1.1000e-02, 1.0900e-02, 1.0800e-02, 1.0700e-02, 1.0600e-02, 1.0500e-02, 1.0400e-02}); + } + break; + case 17: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.7000e+01, 1.6874e+01, 1.6510e+01, 1.5945e+01, 1.5233e+01, 1.4431e+01, 1.3595e+01, 1.2770e+01, 1.1990e+01, 1.1274e+01, 1.0632e+01, 1.0068e+01, 9.5760e+00, 9.1504e+00, 8.7821e+00, 8.4621e+00, 8.1814e+00, 7.9320e+00, 7.7066e+00, 7.4994e+00, 7.3053e+00, 7.1205e+00, 6.9420e+00, 6.7674e+00, 6.5953e+00, 6.4245e+00, 6.2543e+00, 6.0846e+00, 5.9152e+00, 5.7463e+00, 5.5782e+00, 5.4111e+00, 5.2456e+00, 5.0819e+00, 4.9207e+00, 4.7621e+00, 4.6068e+00, 4.4548e+00, 4.3067e+00, 4.1626e+00, 4.0227e+00, 3.8873e+00, 3.7564e+00, 3.6302e+00, 3.5087e+00, 3.3919e+00, 3.2799e+00, 3.1726e+00, 3.0699e+00, 2.9718e+00, 2.8782e+00, 2.7890e+00, 2.7041e+00, 2.6233e+00, 2.5465e+00, 2.4736e+00, 2.4044e+00, 2.3388e+00, 2.2766e+00, 2.2177e+00, 2.1619e+00, 2.1091e+00, 2.0591e+00, 2.0118e+00, 1.9671e+00, 1.9248e+00, 1.8847e+00, 1.8469e+00, 1.8111e+00, 1.7771e+00, 1.7451e+00, 1.7147e+00, 1.6859e+00, 1.6586e+00, 1.6327e+00, 1.6081e+00, 1.5848e+00, 1.5626e+00, 1.5415e+00, 1.5214e+00, 1.5022e+00, 1.4839e+00, 1.4665e+00, 1.4497e+00, 1.4337e+00, 1.4184e+00, 1.4036e+00, 1.3894e+00, 1.3757e+00, 1.3625e+00, 1.3498e+00, 1.3375e+00, 1.3255e+00, 1.3139e+00, 1.3026e+00, 1.2917e+00, 1.2810e+00, 1.2705e+00, 1.2603e+00, 1.2503e+00, 1.2405e+00, 1.2309e+00, 1.2215e+00, 1.2122e+00, 1.2030e+00, 1.1940e+00, 1.1851e+00, 1.1763e+00, 1.1676e+00, 1.1590e+00, 1.1504e+00, 1.1420e+00, 1.1336e+00, 1.1253e+00, 1.1170e+00, 1.1088e+00, 1.1007e+00, 1.0926e+00, 1.0846e+00, 1.0766e+00, 1.0686e+00, 1.0606e+00, 1.0527e+00, 1.0448e+00, 1.0370e+00, 1.0292e+00, 1.0214e+00, 1.0136e+00, 1.0058e+00, 9.9810e-01, 9.9040e-01, 9.8280e-01, 9.7530e-01, 9.6770e-01, 9.6010e-01, 9.5240e-01, 9.4480e-01, 9.3730e-01, 9.2990e-01, 9.2260e-01, 9.1520e-01, 9.0780e-01, 9.0030e-01, 8.9290e-01, 8.8550e-01, 8.7820e-01, 8.7110e-01, 8.6400e-01, 8.5690e-01, 8.4970e-01, 8.4250e-01, 8.3520e-01, 8.2800e-01, 8.2100e-01, 8.1410e-01, 8.0730e-01, 8.0050e-01, 7.9370e-01, 7.8670e-01, 7.7970e-01, 7.7280e-01, 7.6590e-01, 7.5920e-01, 7.5270e-01, 7.4630e-01, 7.3990e-01, 7.3350e-01, 7.2680e-01, 7.2010e-01, 7.1350e-01, 7.0690e-01, 7.0050e-01, 6.9440e-01, 6.8840e-01, 6.8250e-01, 6.7650e-01, 6.7030e-01, 6.6400e-01, 6.5770e-01, 6.5140e-01, 6.4520e-01, 6.3930e-01, 6.3370e-01, 6.2830e-01, 6.2290e-01, 6.1730e-01, 6.1160e-01, 6.0570e-01, 5.9970e-01, 5.9370e-01, 5.8800e-01, 5.8240e-01, 5.7720e-01, 5.7230e-01, 5.6740e-01, 5.6250e-01, 5.5740e-01, 5.5210e-01, 5.4650e-01, 5.4090e-01, 5.3530e-01, 5.3000e-01, 5.2500e-01, 5.2030e-01, 5.1600e-01, 5.1170e-01, 5.0740e-01, 5.0280e-01, 4.9800e-01, 4.9290e-01, 4.8760e-01, 4.8240e-01, 4.7740e-01, 4.7270e-01, 4.6840e-01, 4.6440e-01, 4.6070e-01, 4.5700e-01, 4.5320e-01, 4.4910e-01, 4.4470e-01, 4.4000e-01, 4.3510e-01, 4.3030e-01, 4.2570e-01, 4.2140e-01, 4.1750e-01, 4.1400e-01, 4.1080e-01, 4.0770e-01, 4.0460e-01, 4.0120e-01, 3.9740e-01, 3.9330e-01, 3.8880e-01, 3.8440e-01, 3.8000e-01, 3.7580e-01, 3.7200e-01, 3.6870e-01, 3.6570e-01}); + feg = Vctr_cpu({4.8630e+00, 4.8186e+00, 4.6895e+00, 4.4877e+00, 4.2299e+00, 3.9353e+00, 3.6220e+00, 3.3056e+00, 2.9979e+00, 2.7072e+00, 2.4384e+00, 2.1939e+00, 1.9743e+00, 1.7787e+00, 1.6056e+00, 1.4531e+00, 1.3191e+00, 1.2016e+00, 1.0984e+00, 1.0078e+00, 9.2810e-01, 8.5790e-01, 7.9580e-01, 7.4070e-01, 6.9170e-01, 6.4800e-01, 6.0870e-01, 5.7340e-01, 5.4140e-01, 5.1240e-01, 4.8600e-01, 4.6180e-01, 4.3960e-01, 4.1910e-01, 4.0010e-01, 3.8260e-01, 3.6620e-01, 3.5090e-01, 3.3660e-01, 3.2320e-01, 3.1060e-01, 2.9870e-01, 2.8750e-01, 2.7690e-01, 2.6690e-01, 2.5730e-01, 2.4830e-01, 2.3970e-01, 2.3150e-01, 2.2370e-01, 2.1630e-01, 2.0920e-01, 2.0250e-01, 1.9600e-01, 1.8980e-01, 1.8390e-01, 1.7820e-01, 1.7280e-01, 1.6760e-01, 1.6260e-01, 1.5780e-01, 1.5320e-01, 1.4880e-01, 1.4460e-01, 1.4050e-01, 1.3660e-01, 1.3290e-01, 1.2930e-01, 1.2580e-01, 1.2240e-01, 1.1920e-01, 1.1610e-01, 1.1310e-01, 1.1020e-01, 1.0750e-01, 1.0480e-01, 1.0220e-01, 9.9700e-02, 9.7300e-02, 9.5000e-02, 9.2700e-02, 9.0600e-02, 8.8500e-02, 8.6400e-02, 8.4500e-02, 8.2600e-02, 8.0800e-02, 7.9000e-02, 7.7300e-02, 7.5600e-02, 7.4000e-02, 7.2400e-02, 7.0900e-02, 6.9500e-02, 6.8000e-02, 6.6700e-02, 6.5300e-02, 6.4000e-02, 6.2800e-02, 6.1500e-02, 6.0300e-02, 5.9200e-02, 5.8100e-02, 5.7000e-02, 5.5900e-02, 5.4900e-02, 5.3900e-02, 5.2900e-02, 5.2000e-02, 5.1100e-02, 5.0200e-02, 4.9300e-02, 4.8400e-02, 4.7600e-02, 4.6800e-02, 4.6000e-02, 4.5200e-02, 4.4500e-02, 4.3800e-02, 4.3100e-02, 4.2400e-02, 4.1700e-02, 4.1000e-02, 4.0400e-02, 3.9800e-02, 3.9100e-02, 3.8500e-02, 3.8000e-02, 3.7400e-02, 3.6800e-02, 3.6300e-02, 3.5700e-02, 3.5200e-02, 3.4700e-02, 3.4200e-02, 3.3700e-02, 3.3200e-02, 3.2800e-02, 3.2300e-02, 3.1900e-02, 3.1400e-02, 3.1000e-02, 3.0600e-02, 3.0200e-02, 2.9800e-02, 2.9400e-02, 2.9000e-02, 2.8600e-02, 2.8200e-02, 2.7900e-02, 2.7500e-02, 2.7100e-02, 2.6800e-02, 2.6500e-02, 2.6100e-02, 2.5800e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3700e-02, 2.3400e-02, 2.3100e-02, 2.2900e-02, 2.2600e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9500e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.8000e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6600e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02, 1.1600e-02, 1.1500e-02, 1.1400e-02, 1.1300e-02, 1.1200e-02, 1.1100e-02, 1.1100e-02}); + } + break; + case 18: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.8000e+01, 1.7881e+01, 1.7536e+01, 1.6993e+01, 1.6298e+01, 1.5499e+01, 1.4647e+01, 1.3785e+01, 1.2949e+01, 1.2162e+01, 1.1440e+01, 1.0791e+01, 1.0216e+01, 9.7112e+00, 9.2716e+00, 8.8898e+00, 8.5575e+00, 8.2671e+00, 8.0109e+00, 7.7823e+00, 7.5753e+00, 7.3849e+00, 7.2068e+00, 7.0377e+00, 6.8749e+00, 6.7162e+00, 6.5601e+00, 6.4056e+00, 6.2519e+00, 6.0985e+00, 5.9452e+00, 5.7921e+00, 5.6393e+00, 5.4869e+00, 5.3352e+00, 5.1846e+00, 5.0355e+00, 4.8880e+00, 4.7427e+00, 4.5998e+00, 4.4596e+00, 4.3224e+00, 4.1884e+00, 4.0578e+00, 3.9309e+00, 3.8076e+00, 3.6882e+00, 3.5728e+00, 3.4613e+00, 3.3538e+00, 3.2504e+00, 3.1510e+00, 3.0556e+00, 2.9640e+00, 2.8764e+00, 2.7925e+00, 2.7123e+00, 2.6358e+00, 2.5627e+00, 2.4931e+00, 2.4267e+00, 2.3635e+00, 2.3034e+00, 2.2462e+00, 2.1918e+00, 2.1401e+00, 2.0910e+00, 2.0443e+00, 2.0000e+00, 1.9580e+00, 1.9180e+00, 1.8801e+00, 1.8441e+00, 1.8099e+00, 1.7775e+00, 1.7467e+00, 1.7174e+00, 1.6895e+00, 1.6630e+00, 1.6378e+00, 1.6139e+00, 1.5910e+00, 1.5693e+00, 1.5485e+00, 1.5287e+00, 1.5098e+00, 1.4917e+00, 1.4744e+00, 1.4578e+00, 1.4419e+00, 1.4266e+00, 1.4120e+00, 1.3978e+00, 1.3842e+00, 1.3711e+00, 1.3584e+00, 1.3462e+00, 1.3343e+00, 1.3228e+00, 1.3116e+00, 1.3007e+00, 1.2902e+00, 1.2798e+00, 1.2698e+00, 1.2599e+00, 1.2503e+00, 1.2409e+00, 1.2316e+00, 1.2225e+00, 1.2136e+00, 1.2048e+00, 1.1962e+00, 1.1876e+00, 1.1792e+00, 1.1709e+00, 1.1626e+00, 1.1545e+00, 1.1465e+00, 1.1385e+00, 1.1306e+00, 1.1227e+00, 1.1149e+00, 1.1072e+00, 1.0995e+00, 1.0919e+00, 1.0843e+00, 1.0768e+00, 1.0692e+00, 1.0617e+00, 1.0543e+00, 1.0469e+00, 1.0395e+00, 1.0322e+00, 1.0249e+00, 1.0175e+00, 1.0102e+00, 1.0030e+00, 9.9570e-01, 9.8860e-01, 9.8150e-01, 9.7430e-01, 9.6720e-01, 9.6000e-01, 9.5290e-01, 9.4580e-01, 9.3880e-01, 9.3180e-01, 9.2490e-01, 9.1800e-01, 9.1100e-01, 9.0400e-01, 8.9710e-01, 8.9010e-01, 8.8330e-01, 8.7650e-01, 8.6980e-01, 8.6310e-01, 8.5640e-01, 8.4970e-01, 8.4290e-01, 8.3610e-01, 8.2940e-01, 8.2280e-01, 8.1630e-01, 8.0990e-01, 8.0350e-01, 7.9710e-01, 7.9060e-01, 7.8400e-01, 7.7740e-01, 7.7100e-01, 7.6470e-01, 7.5850e-01, 7.5240e-01, 7.4640e-01, 7.4030e-01, 7.3420e-01, 7.2790e-01, 7.2160e-01, 7.1530e-01, 7.0920e-01, 7.0330e-01, 6.9750e-01, 6.9190e-01, 6.8630e-01, 6.8060e-01, 6.7480e-01, 6.6880e-01, 6.6280e-01, 6.5690e-01, 6.5100e-01, 6.4540e-01, 6.4000e-01, 6.3480e-01, 6.2970e-01, 6.2450e-01, 6.1920e-01, 6.1370e-01, 6.0810e-01, 6.0250e-01, 5.9690e-01, 5.9140e-01, 5.8630e-01, 5.8140e-01, 5.7670e-01, 5.7200e-01, 5.6740e-01, 5.6260e-01, 5.5750e-01, 5.5230e-01, 5.4700e-01, 5.4170e-01, 5.3660e-01, 5.3170e-01, 5.2720e-01, 5.2290e-01, 5.1880e-01, 5.1470e-01, 5.1050e-01, 5.0610e-01, 5.0150e-01, 4.9670e-01, 4.9170e-01, 4.8680e-01, 4.8200e-01, 4.7760e-01, 4.7340e-01, 4.6960e-01, 4.6600e-01, 4.6250e-01, 4.5890e-01, 4.5510e-01, 4.5110e-01, 4.4670e-01, 4.4220e-01, 4.3760e-01, 4.3310e-01, 4.2880e-01, 4.2480e-01, 4.2110e-01, 4.1780e-01}); + feg = Vctr_cpu({4.5818e+00, 4.5468e+00, 4.4447e+00, 4.2833e+00, 4.0743e+00, 3.8309e+00, 3.5667e+00, 3.2938e+00, 3.0224e+00, 2.7601e+00, 2.5120e+00, 2.2815e+00, 2.0701e+00, 1.8782e+00, 1.7053e+00, 1.5505e+00, 1.4125e+00, 1.2897e+00, 1.1806e+00, 1.0839e+00, 9.9800e-01, 9.2180e-01, 8.5400e-01, 7.9360e-01, 7.3960e-01, 6.9140e-01, 6.4800e-01, 6.0900e-01, 5.7380e-01, 5.4190e-01, 5.1290e-01, 4.8650e-01, 4.6220e-01, 4.4000e-01, 4.1950e-01, 4.0060e-01, 3.8310e-01, 3.6680e-01, 3.5160e-01, 3.3740e-01, 3.2410e-01, 3.1160e-01, 2.9980e-01, 2.8880e-01, 2.7830e-01, 2.6840e-01, 2.5900e-01, 2.5010e-01, 2.4160e-01, 2.3360e-01, 2.2590e-01, 2.1860e-01, 2.1160e-01, 2.0500e-01, 1.9860e-01, 1.9250e-01, 1.8670e-01, 1.8110e-01, 1.7570e-01, 1.7060e-01, 1.6570e-01, 1.6090e-01, 1.5640e-01, 1.5200e-01, 1.4780e-01, 1.4370e-01, 1.3990e-01, 1.3610e-01, 1.3250e-01, 1.2900e-01, 1.2570e-01, 1.2250e-01, 1.1930e-01, 1.1630e-01, 1.1340e-01, 1.1060e-01, 1.0800e-01, 1.0530e-01, 1.0280e-01, 1.0040e-01, 9.8000e-02, 9.5800e-02, 9.3600e-02, 9.1400e-02, 8.9400e-02, 8.7400e-02, 8.5500e-02, 8.3600e-02, 8.1800e-02, 8.0000e-02, 7.8400e-02, 7.6700e-02, 7.5100e-02, 7.3600e-02, 7.2100e-02, 7.0600e-02, 6.9200e-02, 6.7800e-02, 6.6500e-02, 6.5200e-02, 6.3900e-02, 6.2700e-02, 6.1500e-02, 6.0400e-02, 5.9300e-02, 5.8200e-02, 5.7100e-02, 5.6100e-02, 5.5100e-02, 5.4100e-02, 5.3200e-02, 5.2200e-02, 5.1300e-02, 5.0400e-02, 4.9600e-02, 4.8800e-02, 4.7900e-02, 4.7100e-02, 4.6400e-02, 4.5600e-02, 4.4900e-02, 4.4200e-02, 4.3500e-02, 4.2800e-02, 4.2100e-02, 4.1500e-02, 4.0800e-02, 4.0200e-02, 3.9600e-02, 3.9000e-02, 3.8400e-02, 3.7800e-02, 3.7300e-02, 3.6700e-02, 3.6200e-02, 3.5700e-02, 3.5200e-02, 3.4700e-02, 3.4200e-02, 3.3700e-02, 3.3300e-02, 3.2800e-02, 3.2400e-02, 3.1900e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9500e-02, 2.9100e-02, 2.8700e-02, 2.8400e-02, 2.8000e-02, 2.7600e-02, 2.7300e-02, 2.7000e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5400e-02, 2.5100e-02, 2.4800e-02, 2.4500e-02, 2.4200e-02, 2.3900e-02, 2.3600e-02, 2.3400e-02, 2.3100e-02, 2.2800e-02, 2.2600e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7900e-02, 1.7700e-02, 1.7500e-02, 1.7300e-02, 1.7200e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6300e-02, 1.6200e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5200e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3100e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02, 1.2200e-02, 1.2100e-02, 1.2000e-02, 1.1900e-02, 1.1800e-02, 1.1700e-02}); + } + break; + case 19: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.9000e+01, 1.8776e+01, 1.8206e+01, 1.7482e+01, 1.6733e+01, 1.5990e+01, 1.5243e+01, 1.4486e+01, 1.3728e+01, 1.2983e+01, 1.2268e+01, 1.1596e+01, 1.0976e+01, 1.0413e+01, 9.9076e+00, 9.4582e+00, 9.0611e+00, 8.7112e+00, 8.4030e+00, 8.1306e+00, 7.8885e+00, 7.6713e+00, 7.4744e+00, 7.2935e+00, 7.1251e+00, 6.9661e+00, 6.8140e+00, 6.6668e+00, 6.5229e+00, 6.3812e+00, 6.2408e+00, 6.1011e+00, 5.9617e+00, 5.8225e+00, 5.6833e+00, 5.5443e+00, 5.4056e+00, 5.2675e+00, 5.1300e+00, 4.9936e+00, 4.8585e+00, 4.7249e+00, 4.5932e+00, 4.4636e+00, 4.3363e+00, 4.2116e+00, 4.0895e+00, 3.9704e+00, 3.8543e+00, 3.7414e+00, 3.6318e+00, 3.5255e+00, 3.4225e+00, 3.3231e+00, 3.2270e+00, 3.1343e+00, 3.0451e+00, 2.9593e+00, 2.8768e+00, 2.7976e+00, 2.7217e+00, 2.6489e+00, 2.5791e+00, 2.5124e+00, 2.4487e+00, 2.3877e+00, 2.3294e+00, 2.2739e+00, 2.2209e+00, 2.1702e+00, 2.1218e+00, 2.0760e+00, 2.0323e+00, 1.9904e+00, 1.9505e+00, 1.9127e+00, 1.8769e+00, 1.8424e+00, 1.8094e+00, 1.7782e+00, 1.7489e+00, 1.7207e+00, 1.6934e+00, 1.6674e+00, 1.6431e+00, 1.6200e+00, 1.5977e+00, 1.5759e+00, 1.5553e+00, 1.5360e+00, 1.5178e+00, 1.5000e+00, 1.4823e+00, 1.4655e+00, 1.4500e+00, 1.4353e+00, 1.4210e+00, 1.4066e+00, 1.3925e+00, 1.3793e+00, 1.3672e+00, 1.3555e+00, 1.3437e+00, 1.3317e+00, 1.3201e+00, 1.3094e+00, 1.2994e+00, 1.2897e+00, 1.2798e+00, 1.2695e+00, 1.2594e+00, 1.2501e+00, 1.2415e+00, 1.2332e+00, 1.2246e+00, 1.2156e+00, 1.2064e+00, 1.1979e+00, 1.1900e+00, 1.1824e+00, 1.1749e+00, 1.1671e+00, 1.1587e+00, 1.1503e+00, 1.1426e+00, 1.1354e+00, 1.1284e+00, 1.1215e+00, 1.1142e+00, 1.1063e+00, 1.0983e+00, 1.0909e+00, 1.0840e+00, 1.0773e+00, 1.0707e+00, 1.0640e+00, 1.0568e+00, 1.0490e+00, 1.0415e+00, 1.0346e+00, 1.0280e+00, 1.0215e+00, 1.0151e+00, 1.0086e+00, 1.0016e+00, 9.9400e-01, 9.8670e-01, 9.8000e-01, 9.7360e-01, 9.6710e-01, 9.6080e-01, 9.5460e-01, 9.4810e-01, 9.4090e-01, 9.3350e-01, 9.2670e-01, 9.2040e-01, 9.1420e-01, 9.0780e-01, 9.0160e-01, 8.9570e-01, 8.8930e-01, 8.8220e-01, 8.7500e-01, 8.6840e-01, 8.6240e-01, 8.5630e-01, 8.5000e-01, 8.4390e-01, 8.3820e-01, 8.3240e-01, 8.2580e-01, 8.1870e-01, 8.1190e-01, 8.0590e-01, 8.0030e-01, 7.9440e-01, 7.8820e-01, 7.8240e-01, 7.7690e-01, 7.7140e-01, 7.6520e-01, 7.5830e-01, 7.5170e-01, 7.4590e-01, 7.4060e-01, 7.3520e-01, 7.2930e-01, 7.2350e-01, 7.1820e-01, 7.1320e-01, 7.0770e-01, 7.0150e-01, 6.9490e-01, 6.8880e-01, 6.8360e-01, 6.7870e-01, 6.7350e-01, 6.6800e-01, 6.6250e-01, 6.5750e-01, 6.5290e-01, 6.4800e-01, 6.4230e-01, 6.3600e-01, 6.3000e-01, 6.2480e-01, 6.2040e-01, 6.1580e-01, 6.1080e-01, 6.0560e-01, 6.0060e-01, 5.9620e-01, 5.9200e-01, 5.8740e-01, 5.8200e-01, 5.7610e-01, 5.7040e-01, 5.6560e-01, 5.6160e-01, 5.5750e-01, 5.5310e-01, 5.4830e-01, 5.4360e-01, 5.3950e-01, 5.3570e-01, 5.3180e-01, 5.2730e-01, 5.2200e-01, 5.1640e-01, 5.1130e-01, 5.0720e-01, 5.0370e-01, 5.0000e-01, 4.9600e-01, 4.9170e-01, 4.8750e-01, 4.8380e-01, 4.8050e-01, 4.7710e-01, 4.7310e-01}); + feg = Vctr_cpu({8.9440e+00, 8.5626e+00, 7.6043e+00, 6.4578e+00, 5.4248e+00, 4.6108e+00, 3.9968e+00, 3.5277e+00, 3.1545e+00, 2.8445e+00, 2.5779e+00, 2.3432e+00, 2.1338e+00, 1.9457e+00, 1.7764e+00, 1.6240e+00, 1.4867e+00, 1.3633e+00, 1.2525e+00, 1.1530e+00, 1.0638e+00, 9.8370e-01, 9.1190e-01, 8.4740e-01, 7.8950e-01, 7.3730e-01, 6.9030e-01, 6.4790e-01, 6.0940e-01, 5.7460e-01, 5.4290e-01, 5.1400e-01, 4.8760e-01, 4.6340e-01, 4.4110e-01, 4.2060e-01, 4.0170e-01, 3.8410e-01, 3.6780e-01, 3.5260e-01, 3.3850e-01, 3.2520e-01, 3.1270e-01, 3.0110e-01, 2.9000e-01, 2.7970e-01, 2.6980e-01, 2.6050e-01, 2.5170e-01, 2.4340e-01, 2.3540e-01, 2.2780e-01, 2.2060e-01, 2.1370e-01, 2.0710e-01, 2.0080e-01, 1.9480e-01, 1.8910e-01, 1.8350e-01, 1.7820e-01, 1.7320e-01, 1.6830e-01, 1.6360e-01, 1.5910e-01, 1.5470e-01, 1.5060e-01, 1.4660e-01, 1.4270e-01, 1.3900e-01, 1.3540e-01, 1.3190e-01, 1.2860e-01, 1.2530e-01, 1.2220e-01, 1.1920e-01, 1.1630e-01, 1.1350e-01, 1.1080e-01, 1.0820e-01, 1.0570e-01, 1.0320e-01, 1.0090e-01, 9.8600e-02, 9.6300e-02, 9.4200e-02, 9.2100e-02, 9.0100e-02, 8.8200e-02, 8.6300e-02, 8.4400e-02, 8.2600e-02, 8.0900e-02, 7.9300e-02, 7.7600e-02, 7.6100e-02, 7.4500e-02, 7.3000e-02, 7.1600e-02, 7.0200e-02, 6.8800e-02, 6.7500e-02, 6.6200e-02, 6.5000e-02, 6.3800e-02, 6.2600e-02, 6.1400e-02, 6.0300e-02, 5.9200e-02, 5.8200e-02, 5.7100e-02, 5.6100e-02, 5.5200e-02, 5.4200e-02, 5.3300e-02, 5.2400e-02, 5.1500e-02, 5.0600e-02, 4.9800e-02, 4.9000e-02, 4.8200e-02, 4.7400e-02, 4.6600e-02, 4.5900e-02, 4.5200e-02, 4.4500e-02, 4.3800e-02, 4.3100e-02, 4.2400e-02, 4.1800e-02, 4.1200e-02, 4.0600e-02, 4.0000e-02, 3.9400e-02, 3.8800e-02, 3.8200e-02, 3.7700e-02, 3.7100e-02, 3.6600e-02, 3.6100e-02, 3.5600e-02, 3.5100e-02, 3.4600e-02, 3.4200e-02, 3.3700e-02, 3.3200e-02, 3.2800e-02, 3.2400e-02, 3.1900e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9500e-02, 2.9200e-02, 2.8800e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6400e-02, 2.6100e-02, 2.5800e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3800e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2500e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6700e-02, 1.6600e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5800e-02, 1.5700e-02, 1.5500e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.5000e-02, 1.4900e-02, 1.4700e-02, 1.4600e-02, 1.4500e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.4000e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3000e-02, 1.2900e-02, 1.2800e-02, 1.2700e-02, 1.2600e-02, 1.2500e-02, 1.2400e-02, 1.2300e-02}); + } + break; + case 20: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.0000e+01, 1.9750e+01, 1.9091e+01, 1.8226e+01, 1.7331e+01, 1.6493e+01, 1.5723e+01, 1.5000e+01, 1.4304e+01, 1.3625e+01, 1.2961e+01, 1.2319e+01, 1.1705e+01, 1.1127e+01, 1.0590e+01, 1.0097e+01, 9.6494e+00, 9.2461e+00, 8.8848e+00, 8.5623e+00, 8.2747e+00, 8.0180e+00, 7.7878e+00, 7.5803e+00, 7.3916e+00, 7.2182e+00, 7.0572e+00, 6.9058e+00, 6.7619e+00, 6.6236e+00, 6.4893e+00, 6.3577e+00, 6.2281e+00, 6.0996e+00, 5.9718e+00, 5.8443e+00, 5.7170e+00, 5.5898e+00, 5.4626e+00, 5.3357e+00, 5.2091e+00, 5.0830e+00, 4.9576e+00, 4.8332e+00, 4.7099e+00, 4.5881e+00, 4.4678e+00, 4.3494e+00, 4.2329e+00, 4.1187e+00, 4.0068e+00, 3.8973e+00, 3.7905e+00, 3.6863e+00, 3.5850e+00, 3.4864e+00, 3.3908e+00, 3.2982e+00, 3.2084e+00, 3.1217e+00, 3.0379e+00, 2.9571e+00, 2.8791e+00, 2.8041e+00, 2.7319e+00, 2.6624e+00, 2.5957e+00, 2.5317e+00, 2.4703e+00, 2.4114e+00, 2.3549e+00, 2.3009e+00, 2.2492e+00, 2.1996e+00, 2.1521e+00, 2.1069e+00, 2.0638e+00, 2.0223e+00, 1.9826e+00, 1.9449e+00, 1.9090e+00, 1.8746e+00, 1.8415e+00, 1.8099e+00, 1.7800e+00, 1.7517e+00, 1.7242e+00, 1.6977e+00, 1.6724e+00, 1.6488e+00, 1.6263e+00, 1.6044e+00, 1.5830e+00, 1.5626e+00, 1.5436e+00, 1.5257e+00, 1.5082e+00, 1.4908e+00, 1.4740e+00, 1.4583e+00, 1.4437e+00, 1.4298e+00, 1.4158e+00, 1.4017e+00, 1.3881e+00, 1.3756e+00, 1.3641e+00, 1.3530e+00, 1.3415e+00, 1.3298e+00, 1.3183e+00, 1.3079e+00, 1.2984e+00, 1.2893e+00, 1.2799e+00, 1.2699e+00, 1.2598e+00, 1.2504e+00, 1.2420e+00, 1.2343e+00, 1.2266e+00, 1.2182e+00, 1.2092e+00, 1.2002e+00, 1.1921e+00, 1.1848e+00, 1.1780e+00, 1.1712e+00, 1.1638e+00, 1.1555e+00, 1.1472e+00, 1.1394e+00, 1.1326e+00, 1.1263e+00, 1.1202e+00, 1.1137e+00, 1.1064e+00, 1.0984e+00, 1.0906e+00, 1.0836e+00, 1.0773e+00, 1.0715e+00, 1.0658e+00, 1.0596e+00, 1.0525e+00, 1.0447e+00, 1.0371e+00, 1.0303e+00, 1.0243e+00, 1.0186e+00, 1.0131e+00, 1.0073e+00, 1.0009e+00, 9.9350e-01, 9.8590e-01, 9.7880e-01, 9.7260e-01, 9.6690e-01, 9.6140e-01, 9.5600e-01, 9.5040e-01, 9.4400e-01, 9.3680e-01, 9.2930e-01, 9.2240e-01, 9.1640e-01, 9.1070e-01, 9.0520e-01, 8.9990e-01, 8.9460e-01, 8.8890e-01, 8.8220e-01, 8.7480e-01, 8.6770e-01, 8.6150e-01, 8.5590e-01, 8.5040e-01, 8.4500e-01, 8.3980e-01, 8.3470e-01, 8.2930e-01, 8.2280e-01, 8.1560e-01, 8.0860e-01, 8.0260e-01, 7.9720e-01, 7.9200e-01, 7.8660e-01, 7.8140e-01, 7.7650e-01, 7.7170e-01, 7.6610e-01, 7.5960e-01, 7.5260e-01, 7.4610e-01, 7.4060e-01, 7.3570e-01, 7.3080e-01, 7.2550e-01, 7.2040e-01, 7.1570e-01, 7.1130e-01, 7.0630e-01, 7.0030e-01, 6.9360e-01, 6.8710e-01, 6.8170e-01, 6.7710e-01, 6.7260e-01, 6.6770e-01, 6.6260e-01, 6.5780e-01, 6.5360e-01, 6.4960e-01, 6.4480e-01, 6.3910e-01, 6.3260e-01, 6.2650e-01, 6.2150e-01, 6.1730e-01, 6.1330e-01, 6.0880e-01, 6.0390e-01, 5.9920e-01, 5.9520e-01, 5.9160e-01, 5.8770e-01, 5.8290e-01, 5.7720e-01, 5.7110e-01, 5.6560e-01, 5.6130e-01, 5.5780e-01, 5.5420e-01, 5.5000e-01, 5.4540e-01, 5.4090e-01, 5.3710e-01, 5.3390e-01, 5.3070e-01, 5.2660e-01}); + feg = Vctr_cpu({9.9065e+00, 9.5755e+00, 8.6998e+00, 7.5496e+00, 6.3881e+00, 5.3718e+00, 4.5497e+00, 3.9074e+00, 3.4080e+00, 3.0140e+00, 2.6955e+00, 2.4310e+00, 2.2059e+00, 2.0106e+00, 1.8385e+00, 1.6854e+00, 1.5483e+00, 1.4249e+00, 1.3137e+00, 1.2133e+00, 1.1225e+00, 1.0405e+00, 9.6620e-01, 8.9910e-01, 8.3820e-01, 7.8310e-01, 7.3320e-01, 6.8780e-01, 6.4660e-01, 6.0910e-01, 5.7490e-01, 5.4360e-01, 5.1500e-01, 4.8880e-01, 4.6470e-01, 4.4250e-01, 4.2200e-01, 4.0310e-01, 3.8550e-01, 3.6920e-01, 3.5400e-01, 3.3980e-01, 3.2650e-01, 3.1410e-01, 3.0240e-01, 2.9140e-01, 2.8110e-01, 2.7130e-01, 2.6210e-01, 2.5330e-01, 2.4500e-01, 2.3710e-01, 2.2960e-01, 2.2240e-01, 2.1560e-01, 2.0900e-01, 2.0280e-01, 1.9690e-01, 1.9110e-01, 1.8570e-01, 1.8040e-01, 1.7540e-01, 1.7060e-01, 1.6590e-01, 1.6140e-01, 1.5710e-01, 1.5300e-01, 1.4900e-01, 1.4520e-01, 1.4150e-01, 1.3790e-01, 1.3450e-01, 1.3110e-01, 1.2790e-01, 1.2480e-01, 1.2180e-01, 1.1890e-01, 1.1610e-01, 1.1340e-01, 1.1080e-01, 1.0820e-01, 1.0580e-01, 1.0340e-01, 1.0110e-01, 9.8900e-02, 9.6700e-02, 9.4600e-02, 9.2600e-02, 9.0600e-02, 8.8700e-02, 8.6900e-02, 8.5100e-02, 8.3300e-02, 8.1600e-02, 8.0000e-02, 7.8400e-02, 7.6800e-02, 7.5300e-02, 7.3900e-02, 7.2400e-02, 7.1100e-02, 6.9700e-02, 6.8400e-02, 6.7100e-02, 6.5900e-02, 6.4700e-02, 6.3500e-02, 6.2400e-02, 6.1300e-02, 6.0200e-02, 5.9100e-02, 5.8100e-02, 5.7100e-02, 5.6100e-02, 5.5200e-02, 5.4200e-02, 5.3300e-02, 5.2500e-02, 5.1600e-02, 5.0700e-02, 4.9900e-02, 4.9100e-02, 4.8300e-02, 4.7600e-02, 4.6800e-02, 4.6100e-02, 4.5400e-02, 4.4700e-02, 4.4000e-02, 4.3400e-02, 4.2700e-02, 4.2100e-02, 4.1500e-02, 4.0900e-02, 4.0300e-02, 3.9700e-02, 3.9100e-02, 3.8600e-02, 3.8000e-02, 3.7500e-02, 3.7000e-02, 3.6500e-02, 3.6000e-02, 3.5500e-02, 3.5000e-02, 3.4500e-02, 3.4100e-02, 3.3600e-02, 3.3200e-02, 3.2700e-02, 3.2300e-02, 3.1900e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9600e-02, 2.9200e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6800e-02, 2.6500e-02, 2.6200e-02, 2.5900e-02, 2.5600e-02, 2.5300e-02, 2.5000e-02, 2.4800e-02, 2.4500e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3400e-02, 2.3200e-02, 2.2900e-02, 2.2700e-02, 2.2400e-02, 2.2200e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7800e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6500e-02, 1.6300e-02, 1.6200e-02, 1.6000e-02, 1.5900e-02, 1.5800e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4200e-02, 1.4100e-02, 1.3900e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02, 1.3500e-02, 1.3400e-02, 1.3300e-02, 1.3200e-02, 1.3100e-02, 1.2900e-02}); + } + break; + case 21: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.1000e+01, 2.0765e+01, 2.0132e+01, 1.9274e+01, 1.8354e+01, 1.7467e+01, 1.6641e+01, 1.5867e+01, 1.5130e+01, 1.4419e+01, 1.3729e+01, 1.3061e+01, 1.2421e+01, 1.1813e+01, 1.1243e+01, 1.0713e+01, 1.0225e+01, 9.7804e+00, 9.3773e+00, 9.0138e+00, 8.6872e+00, 8.3944e+00, 8.1316e+00, 7.8955e+00, 7.6824e+00, 7.4889e+00, 7.3120e+00, 7.1487e+00, 6.9967e+00, 6.8535e+00, 6.7174e+00, 6.5867e+00, 6.4601e+00, 6.3364e+00, 6.2147e+00, 6.0945e+00, 5.9752e+00, 5.8564e+00, 5.7379e+00, 5.6195e+00, 5.5013e+00, 5.3832e+00, 5.2653e+00, 5.1477e+00, 5.0305e+00, 4.9140e+00, 4.7983e+00, 4.6836e+00, 4.5700e+00, 4.4577e+00, 4.3470e+00, 4.2379e+00, 4.1307e+00, 4.0254e+00, 3.9222e+00, 3.8212e+00, 3.7225e+00, 3.6261e+00, 3.5322e+00, 3.4408e+00, 3.3519e+00, 3.2656e+00, 3.1819e+00, 3.1008e+00, 3.0222e+00, 2.9462e+00, 2.8728e+00, 2.8020e+00, 2.7336e+00, 2.6677e+00, 2.6042e+00, 2.5431e+00, 2.4843e+00, 2.4277e+00, 2.3734e+00, 2.3213e+00, 2.2712e+00, 2.2230e+00, 2.1769e+00, 2.1328e+00, 2.0904e+00, 2.0496e+00, 2.0106e+00, 1.9734e+00, 1.9378e+00, 1.9036e+00, 1.8706e+00, 1.8392e+00, 1.8093e+00, 1.7807e+00, 1.7531e+00, 1.7264e+00, 1.7010e+00, 1.6770e+00, 1.6540e+00, 1.6318e+00, 1.6101e+00, 1.5894e+00, 1.5699e+00, 1.5514e+00, 1.5335e+00, 1.5159e+00, 1.4987e+00, 1.4825e+00, 1.4673e+00, 1.4529e+00, 1.4386e+00, 1.4244e+00, 1.4105e+00, 1.3974e+00, 1.3853e+00, 1.3738e+00, 1.3623e+00, 1.3506e+00, 1.3390e+00, 1.3279e+00, 1.3178e+00, 1.3084e+00, 1.2991e+00, 1.2894e+00, 1.2795e+00, 1.2697e+00, 1.2606e+00, 1.2524e+00, 1.2447e+00, 1.2368e+00, 1.2283e+00, 1.2196e+00, 1.2109e+00, 1.2029e+00, 1.1958e+00, 1.1892e+00, 1.1823e+00, 1.1749e+00, 1.1671e+00, 1.1590e+00, 1.1514e+00, 1.1447e+00, 1.1386e+00, 1.1326e+00, 1.1262e+00, 1.1192e+00, 1.1118e+00, 1.1043e+00, 1.0972e+00, 1.0910e+00, 1.0855e+00, 1.0800e+00, 1.0739e+00, 1.0674e+00, 1.0603e+00, 1.0530e+00, 1.0460e+00, 1.0398e+00, 1.0344e+00, 1.0293e+00, 1.0238e+00, 1.0177e+00, 1.0112e+00, 1.0043e+00, 9.9720e-01, 9.9050e-01, 9.8470e-01, 9.7960e-01, 9.7470e-01, 9.6930e-01, 9.6340e-01, 9.5710e-01, 9.5040e-01, 9.4350e-01, 9.3680e-01, 9.3080e-01, 9.2570e-01, 9.2100e-01, 9.1600e-01, 9.1040e-01, 9.0450e-01, 8.9830e-01, 8.9180e-01, 8.8500e-01, 8.7840e-01, 8.7270e-01, 8.6800e-01, 8.6350e-01, 8.5860e-01, 8.5320e-01, 8.4740e-01, 8.4150e-01, 8.3530e-01, 8.2880e-01, 8.2230e-01, 8.1630e-01, 8.1140e-01, 8.0710e-01, 8.0270e-01, 7.9780e-01, 7.9230e-01, 7.8660e-01, 7.8100e-01, 7.7520e-01, 7.6890e-01, 7.6250e-01, 7.5680e-01, 7.5200e-01, 7.4800e-01, 7.4400e-01, 7.3930e-01, 7.3400e-01, 7.2860e-01, 7.2340e-01, 7.1810e-01, 7.1240e-01, 7.0620e-01, 7.0020e-01, 6.9510e-01, 6.9090e-01, 6.8730e-01, 6.8350e-01, 6.7890e-01, 6.7380e-01, 6.6860e-01, 6.6370e-01, 6.5890e-01, 6.5370e-01, 6.4800e-01, 6.4210e-01, 6.3690e-01, 6.3270e-01, 6.2940e-01, 6.2620e-01, 6.2230e-01, 6.1760e-01, 6.1260e-01, 6.0790e-01, 6.0350e-01, 5.9910e-01, 5.9420e-01, 5.8880e-01, 5.8330e-01, 5.7830e-01, 5.7450e-01}); + feg = Vctr_cpu({9.2799e+00, 9.0161e+00, 8.3058e+00, 7.3430e+00, 6.3323e+00, 5.4114e+00, 4.6371e+00, 4.0114e+00, 3.5121e+00, 3.1113e+00, 2.7845e+00, 2.5125e+00, 2.2814e+00, 2.0816e+00, 1.9063e+00, 1.7508e+00, 1.6117e+00, 1.4866e+00, 1.3737e+00, 1.2715e+00, 1.1788e+00, 1.0946e+00, 1.0181e+00, 9.4860e-01, 8.8540e-01, 8.2780e-01, 7.7540e-01, 7.2760e-01, 6.8400e-01, 6.4410e-01, 6.0770e-01, 5.7430e-01, 5.4370e-01, 5.1560e-01, 4.8980e-01, 4.6590e-01, 4.4390e-01, 4.2360e-01, 4.0470e-01, 3.8720e-01, 3.7090e-01, 3.5580e-01, 3.4160e-01, 3.2830e-01, 3.1590e-01, 3.0420e-01, 2.9320e-01, 2.8290e-01, 2.7310e-01, 2.6380e-01, 2.5510e-01, 2.4680e-01, 2.3890e-01, 2.3140e-01, 2.2430e-01, 2.1750e-01, 2.1100e-01, 2.0480e-01, 1.9880e-01, 1.9320e-01, 1.8770e-01, 1.8250e-01, 1.7750e-01, 1.7270e-01, 1.6810e-01, 1.6360e-01, 1.5940e-01, 1.5520e-01, 1.5130e-01, 1.4750e-01, 1.4380e-01, 1.4020e-01, 1.3680e-01, 1.3350e-01, 1.3030e-01, 1.2720e-01, 1.2420e-01, 1.2130e-01, 1.1850e-01, 1.1580e-01, 1.1310e-01, 1.1060e-01, 1.0810e-01, 1.0580e-01, 1.0350e-01, 1.0120e-01, 9.9000e-02, 9.6900e-02, 9.4900e-02, 9.2900e-02, 9.1000e-02, 8.9100e-02, 8.7300e-02, 8.5600e-02, 8.3800e-02, 8.2200e-02, 8.0600e-02, 7.9000e-02, 7.7500e-02, 7.6000e-02, 7.4500e-02, 7.3100e-02, 7.1800e-02, 7.0400e-02, 6.9200e-02, 6.7900e-02, 6.6700e-02, 6.5500e-02, 6.4300e-02, 6.3200e-02, 6.2100e-02, 6.1000e-02, 5.9900e-02, 5.8900e-02, 5.7900e-02, 5.7000e-02, 5.6000e-02, 5.5100e-02, 5.4200e-02, 5.3300e-02, 5.2400e-02, 5.1600e-02, 5.0800e-02, 5.0000e-02, 4.9200e-02, 4.8400e-02, 4.7700e-02, 4.7000e-02, 4.6300e-02, 4.5600e-02, 4.4900e-02, 4.4200e-02, 4.3600e-02, 4.2900e-02, 4.2300e-02, 4.1700e-02, 4.1100e-02, 4.0500e-02, 3.9900e-02, 3.9400e-02, 3.8800e-02, 3.8300e-02, 3.7800e-02, 3.7300e-02, 3.6800e-02, 3.6300e-02, 3.5800e-02, 3.5300e-02, 3.4800e-02, 3.4400e-02, 3.3900e-02, 3.3500e-02, 3.3100e-02, 3.2700e-02, 3.2200e-02, 3.1800e-02, 3.1400e-02, 3.1000e-02, 3.0700e-02, 3.0300e-02, 2.9900e-02, 2.9600e-02, 2.9200e-02, 2.8900e-02, 2.8500e-02, 2.8200e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5400e-02, 2.5100e-02, 2.4800e-02, 2.4600e-02, 2.4300e-02, 2.4000e-02, 2.3800e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8500e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7800e-02, 1.7600e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02, 1.5900e-02, 1.5800e-02, 1.5700e-02, 1.5500e-02, 1.5400e-02, 1.5300e-02, 1.5100e-02, 1.5000e-02, 1.4900e-02, 1.4800e-02, 1.4600e-02, 1.4500e-02, 1.4400e-02, 1.4300e-02, 1.4100e-02, 1.4000e-02, 1.3900e-02, 1.3800e-02, 1.3700e-02, 1.3600e-02}); + } + break; + case 22: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.2000e+01, 2.1778e+01, 2.1173e+01, 2.0334e+01, 1.9409e+01, 1.8496e+01, 1.7631e+01, 1.6816e+01, 1.6039e+01, 1.5291e+01, 1.4568e+01, 1.3868e+01, 1.3195e+01, 1.2554e+01, 1.1947e+01, 1.1379e+01, 1.0851e+01, 1.0364e+01, 9.9193e+00, 9.5143e+00, 9.1474e+00, 8.8162e+00, 8.5178e+00, 8.2490e+00, 8.0066e+00, 7.7875e+00, 7.5887e+00, 7.4072e+00, 7.2405e+00, 7.0861e+00, 6.9419e+00, 6.8059e+00, 6.6765e+00, 6.5524e+00, 6.4323e+00, 6.3152e+00, 6.2003e+00, 6.0870e+00, 5.9748e+00, 5.8633e+00, 5.7523e+00, 5.6415e+00, 5.5309e+00, 5.4204e+00, 5.3101e+00, 5.1999e+00, 5.0902e+00, 4.9808e+00, 4.8719e+00, 4.7638e+00, 4.6565e+00, 4.5502e+00, 4.4450e+00, 4.3412e+00, 4.2387e+00, 4.1378e+00, 4.0385e+00, 3.9410e+00, 3.8454e+00, 3.7517e+00, 3.6602e+00, 3.5707e+00, 3.4833e+00, 3.3981e+00, 3.3152e+00, 3.2346e+00, 3.1562e+00, 3.0801e+00, 3.0063e+00, 2.9348e+00, 2.8655e+00, 2.7985e+00, 2.7337e+00, 2.6711e+00, 2.6106e+00, 2.5522e+00, 2.4960e+00, 2.4417e+00, 2.3895e+00, 2.3391e+00, 2.2907e+00, 2.2441e+00, 2.1993e+00, 2.1562e+00, 2.1147e+00, 2.0749e+00, 2.0368e+00, 2.0001e+00, 1.9647e+00, 1.9308e+00, 1.8983e+00, 1.8673e+00, 1.8374e+00, 1.8085e+00, 1.7807e+00, 1.7542e+00, 1.7290e+00, 1.7048e+00, 1.6812e+00, 1.6584e+00, 1.6367e+00, 1.6161e+00, 1.5964e+00, 1.5773e+00, 1.5586e+00, 1.5405e+00, 1.5233e+00, 1.5071e+00, 1.4917e+00, 1.4765e+00, 1.4614e+00, 1.4467e+00, 1.4329e+00, 1.4199e+00, 1.4076e+00, 1.3954e+00, 1.3831e+00, 1.3709e+00, 1.3593e+00, 1.3485e+00, 1.3384e+00, 1.3286e+00, 1.3186e+00, 1.3083e+00, 1.2982e+00, 1.2886e+00, 1.2798e+00, 1.2717e+00, 1.2635e+00, 1.2551e+00, 1.2463e+00, 1.2375e+00, 1.2291e+00, 1.2215e+00, 1.2145e+00, 1.2077e+00, 1.2005e+00, 1.1928e+00, 1.1849e+00, 1.1771e+00, 1.1699e+00, 1.1634e+00, 1.1575e+00, 1.1514e+00, 1.1448e+00, 1.1377e+00, 1.1304e+00, 1.1232e+00, 1.1165e+00, 1.1106e+00, 1.1052e+00, 1.0997e+00, 1.0937e+00, 1.0871e+00, 1.0802e+00, 1.0733e+00, 1.0667e+00, 1.0607e+00, 1.0555e+00, 1.0505e+00, 1.0452e+00, 1.0393e+00, 1.0329e+00, 1.0262e+00, 1.0195e+00, 1.0131e+00, 1.0074e+00, 1.0023e+00, 9.9770e-01, 9.9270e-01, 9.8710e-01, 9.8090e-01, 9.7440e-01, 9.6800e-01, 9.6160e-01, 9.5560e-01, 9.5030e-01, 9.4580e-01, 9.4130e-01, 9.3620e-01, 9.3050e-01, 9.2440e-01, 9.1810e-01, 9.1190e-01, 9.0570e-01, 8.9980e-01, 8.9460e-01, 8.9010e-01, 8.8590e-01, 8.8110e-01, 8.7570e-01, 8.6980e-01, 8.6370e-01, 8.5770e-01, 8.5170e-01, 8.4570e-01, 8.4010e-01, 8.3540e-01, 8.3130e-01, 8.2720e-01, 8.2250e-01, 8.1710e-01, 8.1130e-01, 8.0550e-01, 7.9980e-01, 7.9400e-01, 7.8810e-01, 7.8260e-01, 7.7780e-01, 7.7380e-01, 7.7000e-01, 7.6590e-01, 7.6090e-01, 7.5540e-01, 7.4970e-01, 7.4430e-01, 7.3900e-01, 7.3350e-01, 7.2780e-01, 7.2250e-01, 7.1800e-01, 7.1430e-01, 7.1090e-01, 7.0700e-01, 7.0230e-01, 6.9700e-01, 6.9160e-01, 6.8650e-01, 6.8160e-01, 6.7650e-01, 6.7120e-01, 6.6580e-01, 6.6110e-01, 6.5720e-01, 6.5400e-01, 6.5080e-01, 6.4710e-01, 6.4250e-01, 6.3730e-01, 6.3220e-01, 6.2750e-01}); + feg = Vctr_cpu({8.7360e+00, 8.5162e+00, 7.9179e+00, 7.0909e+00, 6.2005e+00, 5.3669e+00, 4.6472e+00, 4.0516e+00, 3.5667e+00, 3.1716e+00, 2.8461e+00, 2.5735e+00, 2.3414e+00, 2.1404e+00, 1.9641e+00, 1.8077e+00, 1.6678e+00, 1.5418e+00, 1.4278e+00, 1.3245e+00, 1.2304e+00, 1.1448e+00, 1.0667e+00, 9.9540e-01, 9.3030e-01, 8.7080e-01, 8.1640e-01, 7.6650e-01, 7.2090e-01, 6.7910e-01, 6.4070e-01, 6.0550e-01, 5.7300e-01, 5.4320e-01, 5.1570e-01, 4.9030e-01, 4.6680e-01, 4.4510e-01, 4.2500e-01, 4.0630e-01, 3.8890e-01, 3.7270e-01, 3.5750e-01, 3.4340e-01, 3.3010e-01, 3.1770e-01, 3.0600e-01, 2.9500e-01, 2.8470e-01, 2.7490e-01, 2.6570e-01, 2.5690e-01, 2.4860e-01, 2.4070e-01, 2.3320e-01, 2.2610e-01, 2.1930e-01, 2.1280e-01, 2.0670e-01, 2.0070e-01, 1.9510e-01, 1.8970e-01, 1.8450e-01, 1.7950e-01, 1.7470e-01, 1.7010e-01, 1.6570e-01, 1.6140e-01, 1.5730e-01, 1.5330e-01, 1.4950e-01, 1.4590e-01, 1.4230e-01, 1.3890e-01, 1.3560e-01, 1.3240e-01, 1.2930e-01, 1.2630e-01, 1.2340e-01, 1.2060e-01, 1.1790e-01, 1.1530e-01, 1.1280e-01, 1.1030e-01, 1.0790e-01, 1.0560e-01, 1.0340e-01, 1.0120e-01, 9.9100e-02, 9.7000e-02, 9.5000e-02, 9.3100e-02, 9.1200e-02, 8.9400e-02, 8.7600e-02, 8.5900e-02, 8.4200e-02, 8.2600e-02, 8.1000e-02, 7.9500e-02, 7.8000e-02, 7.6500e-02, 7.5100e-02, 7.3700e-02, 7.2400e-02, 7.1100e-02, 6.9800e-02, 6.8500e-02, 6.7300e-02, 6.6100e-02, 6.5000e-02, 6.3900e-02, 6.2800e-02, 6.1700e-02, 6.0700e-02, 5.9700e-02, 5.8700e-02, 5.7700e-02, 5.6800e-02, 5.5800e-02, 5.4900e-02, 5.4100e-02, 5.3200e-02, 5.2400e-02, 5.1600e-02, 5.0800e-02, 5.0000e-02, 4.9200e-02, 4.8500e-02, 4.7700e-02, 4.7000e-02, 4.6300e-02, 4.5600e-02, 4.5000e-02, 4.4300e-02, 4.3700e-02, 4.3100e-02, 4.2500e-02, 4.1900e-02, 4.1300e-02, 4.0700e-02, 4.0100e-02, 3.9600e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7500e-02, 3.7000e-02, 3.6500e-02, 3.6000e-02, 3.5600e-02, 3.5100e-02, 3.4700e-02, 3.4200e-02, 3.3800e-02, 3.3400e-02, 3.2900e-02, 3.2500e-02, 3.2100e-02, 3.1700e-02, 3.1300e-02, 3.1000e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9500e-02, 2.9200e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3900e-02, 2.3600e-02, 2.3400e-02, 2.3100e-02, 2.2900e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9300e-02, 1.9100e-02, 1.9000e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.7900e-02, 1.7800e-02, 1.7600e-02, 1.7500e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5800e-02, 1.5700e-02, 1.5600e-02, 1.5400e-02, 1.5300e-02, 1.5200e-02, 1.5100e-02, 1.4900e-02, 1.4800e-02, 1.4700e-02, 1.4600e-02, 1.4400e-02, 1.4300e-02, 1.4200e-02}); + } + break; + case 23: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.3000e+01, 2.2790e+01, 2.2211e+01, 2.1394e+01, 2.0474e+01, 1.9547e+01, 1.8654e+01, 1.7805e+01, 1.6994e+01, 1.6213e+01, 1.5457e+01, 1.4725e+01, 1.4019e+01, 1.3344e+01, 1.2701e+01, 1.2095e+01, 1.1527e+01, 1.1000e+01, 1.0514e+01, 1.0067e+01, 9.6591e+00, 9.2883e+00, 8.9519e+00, 8.6475e+00, 8.3724e+00, 8.1234e+00, 7.8979e+00, 7.6930e+00, 7.5062e+00, 7.3349e+00, 7.1768e+00, 7.0300e+00, 6.8925e+00, 6.7627e+00, 6.6392e+00, 6.5207e+00, 6.4062e+00, 6.2948e+00, 6.1856e+00, 6.0783e+00, 5.9722e+00, 5.8669e+00, 5.7622e+00, 5.6580e+00, 5.5539e+00, 5.4501e+00, 5.3464e+00, 5.2430e+00, 5.1397e+00, 5.0368e+00, 4.9342e+00, 4.8322e+00, 4.7308e+00, 4.6300e+00, 4.5302e+00, 4.4314e+00, 4.3336e+00, 4.2371e+00, 4.1419e+00, 4.0481e+00, 3.9558e+00, 3.8652e+00, 3.7763e+00, 3.6891e+00, 3.6037e+00, 3.5202e+00, 3.4387e+00, 3.3591e+00, 3.2814e+00, 3.2058e+00, 3.1322e+00, 3.0607e+00, 2.9911e+00, 2.9235e+00, 2.8581e+00, 2.7946e+00, 2.7330e+00, 2.6734e+00, 2.6158e+00, 2.5601e+00, 2.5062e+00, 2.4541e+00, 2.4038e+00, 2.3553e+00, 2.3085e+00, 2.2634e+00, 2.2198e+00, 2.1779e+00, 2.1375e+00, 2.0986e+00, 2.0612e+00, 2.0250e+00, 1.9902e+00, 1.9568e+00, 1.9248e+00, 1.8939e+00, 1.8641e+00, 1.8353e+00, 1.8077e+00, 1.7813e+00, 1.7560e+00, 1.7316e+00, 1.7079e+00, 1.6850e+00, 1.6631e+00, 1.6423e+00, 1.6223e+00, 1.6028e+00, 1.5838e+00, 1.5655e+00, 1.5480e+00, 1.5315e+00, 1.5156e+00, 1.5000e+00, 1.4847e+00, 1.4698e+00, 1.4556e+00, 1.4422e+00, 1.4295e+00, 1.4170e+00, 1.4045e+00, 1.3921e+00, 1.3802e+00, 1.3690e+00, 1.3585e+00, 1.3484e+00, 1.3383e+00, 1.3280e+00, 1.3178e+00, 1.3079e+00, 1.2986e+00, 1.2901e+00, 1.2819e+00, 1.2736e+00, 1.2649e+00, 1.2561e+00, 1.2475e+00, 1.2394e+00, 1.2320e+00, 1.2251e+00, 1.2182e+00, 1.2109e+00, 1.2033e+00, 1.1955e+00, 1.1879e+00, 1.1810e+00, 1.1746e+00, 1.1686e+00, 1.1626e+00, 1.1562e+00, 1.1492e+00, 1.1421e+00, 1.1351e+00, 1.1286e+00, 1.1227e+00, 1.1173e+00, 1.1120e+00, 1.1063e+00, 1.1001e+00, 1.0934e+00, 1.0867e+00, 1.0803e+00, 1.0743e+00, 1.0689e+00, 1.0640e+00, 1.0591e+00, 1.0537e+00, 1.0477e+00, 1.0413e+00, 1.0349e+00, 1.0287e+00, 1.0228e+00, 1.0175e+00, 1.0127e+00, 1.0082e+00, 1.0033e+00, 9.9780e-01, 9.9170e-01, 9.8540e-01, 9.7920e-01, 9.7330e-01, 9.6780e-01, 9.6270e-01, 9.5820e-01, 9.5380e-01, 9.4910e-01, 9.4380e-01, 9.3780e-01, 9.3160e-01, 9.2560e-01, 9.1980e-01, 9.1430e-01, 9.0920e-01, 9.0450e-01, 9.0040e-01, 8.9610e-01, 8.9130e-01, 8.8570e-01, 8.7970e-01, 8.7370e-01, 8.6800e-01, 8.6250e-01, 8.5710e-01, 8.5210e-01, 8.4760e-01, 8.4360e-01, 8.3970e-01, 8.3510e-01, 8.2970e-01, 8.2390e-01, 8.1800e-01, 8.1240e-01, 8.0710e-01, 8.0190e-01, 7.9680e-01, 7.9210e-01, 7.8800e-01, 7.8440e-01, 7.8050e-01, 7.7600e-01, 7.7060e-01, 7.6490e-01, 7.5920e-01, 7.5400e-01, 7.4900e-01, 7.4400e-01, 7.3900e-01, 7.3440e-01, 7.3030e-01, 7.2680e-01, 7.2340e-01, 7.1940e-01, 7.1460e-01, 7.0920e-01, 7.0360e-01, 6.9840e-01, 6.9360e-01, 6.8900e-01, 6.8430e-01, 6.7950e-01, 6.7510e-01}); + feg = Vctr_cpu({8.2468e+00, 8.0613e+00, 7.5516e+00, 6.8348e+00, 6.0460e+00, 5.2899e+00, 4.6228e+00, 4.0598e+00, 3.5937e+00, 3.2088e+00, 2.8887e+00, 2.6190e+00, 2.3883e+00, 2.1881e+00, 2.0122e+00, 1.8560e+00, 1.7161e+00, 1.5900e+00, 1.4758e+00, 1.3719e+00, 1.2772e+00, 1.1906e+00, 1.1115e+00, 1.0390e+00, 9.7250e-01, 9.1150e-01, 8.5550e-01, 8.0410e-01, 7.5680e-01, 7.1330e-01, 6.7330e-01, 6.3640e-01, 6.0240e-01, 5.7100e-01, 5.4200e-01, 5.1510e-01, 4.9030e-01, 4.6730e-01, 4.4590e-01, 4.2600e-01, 4.0750e-01, 3.9030e-01, 3.7420e-01, 3.5920e-01, 3.4510e-01, 3.3190e-01, 3.1950e-01, 3.0780e-01, 2.9680e-01, 2.8650e-01, 2.7670e-01, 2.6750e-01, 2.5870e-01, 2.5040e-01, 2.4260e-01, 2.3510e-01, 2.2790e-01, 2.2110e-01, 2.1470e-01, 2.0850e-01, 2.0260e-01, 1.9690e-01, 1.9150e-01, 1.8630e-01, 1.8130e-01, 1.7660e-01, 1.7200e-01, 1.6750e-01, 1.6330e-01, 1.5920e-01, 1.5530e-01, 1.5150e-01, 1.4780e-01, 1.4430e-01, 1.4090e-01, 1.3760e-01, 1.3440e-01, 1.3130e-01, 1.2830e-01, 1.2540e-01, 1.2260e-01, 1.1990e-01, 1.1730e-01, 1.1480e-01, 1.1230e-01, 1.0990e-01, 1.0760e-01, 1.0530e-01, 1.0320e-01, 1.0100e-01, 9.9000e-02, 9.7000e-02, 9.5100e-02, 9.3200e-02, 9.1300e-02, 8.9600e-02, 8.7800e-02, 8.6100e-02, 8.4500e-02, 8.2900e-02, 8.1400e-02, 7.9800e-02, 7.8400e-02, 7.6900e-02, 7.5500e-02, 7.4200e-02, 7.2900e-02, 7.1600e-02, 7.0300e-02, 6.9100e-02, 6.7900e-02, 6.6700e-02, 6.5600e-02, 6.4500e-02, 6.3400e-02, 6.2300e-02, 6.1300e-02, 6.0300e-02, 5.9300e-02, 5.8400e-02, 5.7400e-02, 5.6500e-02, 5.5600e-02, 5.4800e-02, 5.3900e-02, 5.3100e-02, 5.2200e-02, 5.1500e-02, 5.0700e-02, 4.9900e-02, 4.9200e-02, 4.8400e-02, 4.7700e-02, 4.7000e-02, 4.6400e-02, 4.5700e-02, 4.5000e-02, 4.4400e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2000e-02, 4.1400e-02, 4.0800e-02, 4.0300e-02, 3.9700e-02, 3.9200e-02, 3.8700e-02, 3.8200e-02, 3.7700e-02, 3.7200e-02, 3.6700e-02, 3.6200e-02, 3.5800e-02, 3.5300e-02, 3.4900e-02, 3.4400e-02, 3.4000e-02, 3.3600e-02, 3.3200e-02, 3.2800e-02, 3.2400e-02, 3.2000e-02, 3.1600e-02, 3.1200e-02, 3.0900e-02, 3.0500e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9100e-02, 2.8800e-02, 2.8500e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3400e-02, 2.3200e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8600e-02, 1.8400e-02, 1.8200e-02, 1.8100e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5500e-02, 1.5300e-02, 1.5200e-02, 1.5100e-02, 1.5000e-02, 1.4800e-02}); + } + break; + case 24: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.4000e+01, 2.3822e+01, 2.3328e+01, 2.2615e+01, 2.1784e+01, 2.0903e+01, 2.0011e+01, 1.9124e+01, 1.8248e+01, 1.7388e+01, 1.6550e+01, 1.5738e+01, 1.4957e+01, 1.4212e+01, 1.3507e+01, 1.2844e+01, 1.2224e+01, 1.1648e+01, 1.1116e+01, 1.0627e+01, 1.0179e+01, 9.7705e+00, 9.3988e+00, 9.0614e+00, 8.7555e+00, 8.4782e+00, 8.2268e+00, 7.9985e+00, 7.7908e+00, 7.6011e+00, 7.4271e+00, 7.2666e+00, 7.1178e+00, 6.9789e+00, 6.8483e+00, 6.7246e+00, 6.6066e+00, 6.4932e+00, 6.3836e+00, 6.2768e+00, 6.1723e+00, 6.0696e+00, 5.9682e+00, 5.8678e+00, 5.7681e+00, 5.6688e+00, 5.5700e+00, 5.4714e+00, 5.3730e+00, 5.2748e+00, 5.1769e+00, 5.0793e+00, 4.9820e+00, 4.8851e+00, 4.7888e+00, 4.6930e+00, 4.5980e+00, 4.5037e+00, 4.4103e+00, 4.3180e+00, 4.2267e+00, 4.1366e+00, 4.0478e+00, 3.9603e+00, 3.8743e+00, 3.7898e+00, 3.7068e+00, 3.6254e+00, 3.5457e+00, 3.4677e+00, 3.3914e+00, 3.3169e+00, 3.2442e+00, 3.1732e+00, 3.1041e+00, 3.0368e+00, 2.9713e+00, 2.9076e+00, 2.8457e+00, 2.7857e+00, 2.7274e+00, 2.6707e+00, 2.6159e+00, 2.5628e+00, 2.5114e+00, 2.4616e+00, 2.4133e+00, 2.3666e+00, 2.3217e+00, 2.2782e+00, 2.2361e+00, 2.1954e+00, 2.1561e+00, 2.1183e+00, 2.0819e+00, 2.0467e+00, 2.0125e+00, 1.9796e+00, 1.9481e+00, 1.9178e+00, 1.8885e+00, 1.8601e+00, 1.8326e+00, 1.8062e+00, 1.7810e+00, 1.7568e+00, 1.7333e+00, 1.7104e+00, 1.6882e+00, 1.6670e+00, 1.6469e+00, 1.6275e+00, 1.6087e+00, 1.5902e+00, 1.5723e+00, 1.5551e+00, 1.5388e+00, 1.5233e+00, 1.5082e+00, 1.4933e+00, 1.4786e+00, 1.4644e+00, 1.4509e+00, 1.4382e+00, 1.4260e+00, 1.4140e+00, 1.4021e+00, 1.3902e+00, 1.3787e+00, 1.3678e+00, 1.3575e+00, 1.3478e+00, 1.3381e+00, 1.3284e+00, 1.3186e+00, 1.3089e+00, 1.2997e+00, 1.2910e+00, 1.2829e+00, 1.2750e+00, 1.2670e+00, 1.2588e+00, 1.2506e+00, 1.2424e+00, 1.2346e+00, 1.2273e+00, 1.2206e+00, 1.2139e+00, 1.2071e+00, 1.2000e+00, 1.1928e+00, 1.1856e+00, 1.1785e+00, 1.1720e+00, 1.1661e+00, 1.1603e+00, 1.1544e+00, 1.1482e+00, 1.1418e+00, 1.1352e+00, 1.1286e+00, 1.1222e+00, 1.1164e+00, 1.1111e+00, 1.1059e+00, 1.1005e+00, 1.0948e+00, 1.0889e+00, 1.0827e+00, 1.0765e+00, 1.0704e+00, 1.0648e+00, 1.0598e+00, 1.0550e+00, 1.0500e+00, 1.0448e+00, 1.0392e+00, 1.0335e+00, 1.0276e+00, 1.0216e+00, 1.0158e+00, 1.0106e+00, 1.0058e+00, 1.0013e+00, 9.9660e-01, 9.9150e-01, 9.8620e-01, 9.8070e-01, 9.7500e-01, 9.6920e-01, 9.6350e-01, 9.5810e-01, 9.5330e-01, 9.4890e-01, 9.4460e-01, 9.3990e-01, 9.3480e-01, 9.2960e-01, 9.2420e-01, 9.1870e-01, 9.1300e-01, 9.0740e-01, 9.0210e-01, 8.9750e-01, 8.9330e-01, 8.8910e-01, 8.8460e-01, 8.7980e-01, 8.7470e-01, 8.6960e-01, 8.6430e-01, 8.5890e-01, 8.5330e-01, 8.4780e-01, 8.4290e-01, 8.3870e-01, 8.3470e-01, 8.3070e-01, 8.2630e-01, 8.2150e-01, 8.1660e-01, 8.1170e-01, 8.0670e-01, 8.0150e-01, 7.9600e-01, 7.9060e-01, 7.8570e-01, 7.8140e-01, 7.7760e-01, 7.7400e-01, 7.7000e-01, 7.6550e-01, 7.6080e-01, 7.5610e-01, 7.5140e-01, 7.4660e-01, 7.4160e-01, 7.3630e-01, 7.3110e-01, 7.2630e-01, 7.2220e-01}); + feg = Vctr_cpu({6.9630e+00, 6.8202e+00, 6.4312e+00, 5.8918e+00, 5.3049e+00, 4.7437e+00, 4.2430e+00, 3.8110e+00, 3.4419e+00, 3.1259e+00, 2.8530e+00, 2.6148e+00, 2.4047e+00, 2.2178e+00, 2.0501e+00, 1.8988e+00, 1.7616e+00, 1.6367e+00, 1.5228e+00, 1.4186e+00, 1.3231e+00, 1.2356e+00, 1.1552e+00, 1.0814e+00, 1.0135e+00, 9.5100e-01, 8.9350e-01, 8.4050e-01, 7.9170e-01, 7.4670e-01, 7.0520e-01, 6.6680e-01, 6.3130e-01, 5.9850e-01, 5.6820e-01, 5.4000e-01, 5.1390e-01, 4.8970e-01, 4.6720e-01, 4.4620e-01, 4.2670e-01, 4.0850e-01, 3.9140e-01, 3.7550e-01, 3.6060e-01, 3.4670e-01, 3.3350e-01, 3.2120e-01, 3.0960e-01, 2.9870e-01, 2.8830e-01, 2.7860e-01, 2.6930e-01, 2.6060e-01, 2.5230e-01, 2.4440e-01, 2.3690e-01, 2.2980e-01, 2.2300e-01, 2.1650e-01, 2.1030e-01, 2.0440e-01, 1.9880e-01, 1.9330e-01, 1.8820e-01, 1.8320e-01, 1.7840e-01, 1.7380e-01, 1.6940e-01, 1.6510e-01, 1.6110e-01, 1.5710e-01, 1.5330e-01, 1.4970e-01, 1.4610e-01, 1.4270e-01, 1.3940e-01, 1.3620e-01, 1.3310e-01, 1.3020e-01, 1.2730e-01, 1.2450e-01, 1.2180e-01, 1.1920e-01, 1.1660e-01, 1.1420e-01, 1.1180e-01, 1.0940e-01, 1.0720e-01, 1.0500e-01, 1.0290e-01, 1.0080e-01, 9.8800e-02, 9.6900e-02, 9.5000e-02, 9.3100e-02, 9.1400e-02, 8.9600e-02, 8.7900e-02, 8.6300e-02, 8.4700e-02, 8.3100e-02, 8.1600e-02, 8.0100e-02, 7.8700e-02, 7.7300e-02, 7.5900e-02, 7.4600e-02, 7.3300e-02, 7.2000e-02, 7.0700e-02, 6.9500e-02, 6.8400e-02, 6.7200e-02, 6.6100e-02, 6.5000e-02, 6.3900e-02, 6.2900e-02, 6.1900e-02, 6.0900e-02, 5.9900e-02, 5.8900e-02, 5.8000e-02, 5.7100e-02, 5.6200e-02, 5.5400e-02, 5.4500e-02, 5.3700e-02, 5.2900e-02, 5.2100e-02, 5.1300e-02, 5.0500e-02, 4.9800e-02, 4.9100e-02, 4.8400e-02, 4.7700e-02, 4.7000e-02, 4.6300e-02, 4.5700e-02, 4.5000e-02, 4.4400e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2000e-02, 4.1500e-02, 4.0900e-02, 4.0400e-02, 3.9800e-02, 3.9300e-02, 3.8800e-02, 3.8300e-02, 3.7800e-02, 3.7300e-02, 3.6900e-02, 3.6400e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4600e-02, 3.4200e-02, 3.3800e-02, 3.3400e-02, 3.3000e-02, 3.2600e-02, 3.2200e-02, 3.1800e-02, 3.1500e-02, 3.1100e-02, 3.0700e-02, 3.0400e-02, 3.0000e-02, 2.9700e-02, 2.9400e-02, 2.9000e-02, 2.8700e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9400e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8700e-02, 1.8500e-02, 1.8300e-02, 1.8200e-02, 1.8000e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7100e-02, 1.7000e-02, 1.6800e-02, 1.6700e-02, 1.6500e-02, 1.6400e-02, 1.6300e-02, 1.6100e-02, 1.6000e-02, 1.5900e-02, 1.5700e-02, 1.5600e-02, 1.5500e-02}); + } + break; + case 25: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.5000e+01, 2.4809e+01, 2.4276e+01, 2.3505e+01, 2.2610e+01, 2.1679e+01, 2.0758e+01, 1.9866e+01, 1.9003e+01, 1.8166e+01, 1.7354e+01, 1.6563e+01, 1.5796e+01, 1.5056e+01, 1.4346e+01, 1.3668e+01, 1.3025e+01, 1.2420e+01, 1.1854e+01, 1.1326e+01, 1.0837e+01, 1.0386e+01, 9.9707e+00, 9.5907e+00, 9.2435e+00, 8.9268e+00, 8.6383e+00, 8.3757e+00, 8.1364e+00, 7.9183e+00, 7.7189e+00, 7.5362e+00, 7.3682e+00, 7.2130e+00, 7.0689e+00, 6.9342e+00, 6.8077e+00, 6.6880e+00, 6.5739e+00, 6.4646e+00, 6.3592e+00, 6.2568e+00, 6.1569e+00, 6.0591e+00, 5.9627e+00, 5.8674e+00, 5.7731e+00, 5.6793e+00, 5.5861e+00, 5.4932e+00, 5.4005e+00, 5.3081e+00, 5.2159e+00, 5.1240e+00, 5.0322e+00, 4.9408e+00, 4.8498e+00, 4.7591e+00, 4.6690e+00, 4.5795e+00, 4.4907e+00, 4.4026e+00, 4.3153e+00, 4.2290e+00, 4.1437e+00, 4.0595e+00, 3.9764e+00, 3.8946e+00, 3.8140e+00, 3.7348e+00, 3.6570e+00, 3.5806e+00, 3.5057e+00, 3.4323e+00, 3.3605e+00, 3.2903e+00, 3.2216e+00, 3.1545e+00, 3.0891e+00, 3.0253e+00, 2.9631e+00, 2.9025e+00, 2.8435e+00, 2.7862e+00, 2.7304e+00, 2.6763e+00, 2.6236e+00, 2.5725e+00, 2.5230e+00, 2.4750e+00, 2.4284e+00, 2.3833e+00, 2.3395e+00, 2.2972e+00, 2.2563e+00, 2.2167e+00, 2.1783e+00, 2.1412e+00, 2.1052e+00, 2.0707e+00, 2.0373e+00, 2.0050e+00, 1.9736e+00, 1.9433e+00, 1.9141e+00, 1.8861e+00, 1.8590e+00, 1.8328e+00, 1.8072e+00, 1.7826e+00, 1.7589e+00, 1.7363e+00, 1.7145e+00, 1.6933e+00, 1.6725e+00, 1.6524e+00, 1.6331e+00, 1.6148e+00, 1.5972e+00, 1.5801e+00, 1.5632e+00, 1.5467e+00, 1.5308e+00, 1.5157e+00, 1.5014e+00, 1.4876e+00, 1.4740e+00, 1.4605e+00, 1.4472e+00, 1.4344e+00, 1.4223e+00, 1.4109e+00, 1.4000e+00, 1.3891e+00, 1.3782e+00, 1.3672e+00, 1.3566e+00, 1.3465e+00, 1.3372e+00, 1.3283e+00, 1.3196e+00, 1.3107e+00, 1.3016e+00, 1.2925e+00, 1.2837e+00, 1.2755e+00, 1.2679e+00, 1.2607e+00, 1.2536e+00, 1.2461e+00, 1.2384e+00, 1.2305e+00, 1.2229e+00, 1.2157e+00, 1.2091e+00, 1.2030e+00, 1.1971e+00, 1.1908e+00, 1.1842e+00, 1.1772e+00, 1.1703e+00, 1.1636e+00, 1.1574e+00, 1.1517e+00, 1.1465e+00, 1.1413e+00, 1.1357e+00, 1.1297e+00, 1.1233e+00, 1.1169e+00, 1.1107e+00, 1.1049e+00, 1.0996e+00, 1.0948e+00, 1.0901e+00, 1.0853e+00, 1.0799e+00, 1.0739e+00, 1.0678e+00, 1.0619e+00, 1.0561e+00, 1.0508e+00, 1.0459e+00, 1.0415e+00, 1.0372e+00, 1.0326e+00, 1.0275e+00, 1.0218e+00, 1.0159e+00, 1.0101e+00, 1.0046e+00, 9.9930e-01, 9.9450e-01, 9.9010e-01, 9.8600e-01, 9.8190e-01, 9.7730e-01, 9.7200e-01, 9.6630e-01, 9.6060e-01, 9.5500e-01, 9.4970e-01, 9.4470e-01, 9.4000e-01, 9.3570e-01, 9.3190e-01, 9.2800e-01, 9.2360e-01, 9.1850e-01, 9.1300e-01, 9.0730e-01, 9.0190e-01, 8.9670e-01, 8.9170e-01, 8.8690e-01, 8.8250e-01, 8.7850e-01, 8.7490e-01, 8.7110e-01, 8.6670e-01, 8.6160e-01, 8.5610e-01, 8.5060e-01, 8.4540e-01, 8.4040e-01, 8.3560e-01, 8.3080e-01, 8.2640e-01, 8.2240e-01, 8.1890e-01, 8.1550e-01, 8.1160e-01, 8.0690e-01, 8.0170e-01, 7.9630e-01, 7.9110e-01, 7.8620e-01, 7.8150e-01, 7.7680e-01, 7.7220e-01, 7.6790e-01}); + feg = Vctr_cpu({7.4716e+00, 7.3280e+00, 6.9301e+00, 6.3611e+00, 5.7199e+00, 5.0875e+00, 4.5123e+00, 4.0126e+00, 3.5884e+00, 3.2306e+00, 2.9282e+00, 2.6702e+00, 2.4475e+00, 2.2532e+00, 2.0816e+00, 1.9287e+00, 1.7912e+00, 1.6669e+00, 1.5538e+00, 1.4505e+00, 1.3559e+00, 1.2690e+00, 1.1891e+00, 1.1155e+00, 1.0475e+00, 9.8480e-01, 9.2690e-01, 8.7330e-01, 8.2370e-01, 7.7780e-01, 7.3530e-01, 6.9590e-01, 6.5940e-01, 6.2550e-01, 5.9400e-01, 5.6470e-01, 5.3750e-01, 5.1220e-01, 4.8860e-01, 4.6670e-01, 4.4610e-01, 4.2700e-01, 4.0910e-01, 3.9230e-01, 3.7660e-01, 3.6180e-01, 3.4800e-01, 3.3490e-01, 3.2270e-01, 3.1110e-01, 3.0020e-01, 2.8990e-01, 2.8020e-01, 2.7100e-01, 2.6220e-01, 2.5390e-01, 2.4610e-01, 2.3860e-01, 2.3140e-01, 2.2460e-01, 2.1820e-01, 2.1200e-01, 2.0610e-01, 2.0040e-01, 1.9500e-01, 1.8980e-01, 1.8480e-01, 1.8000e-01, 1.7550e-01, 1.7100e-01, 1.6680e-01, 1.6270e-01, 1.5880e-01, 1.5500e-01, 1.5130e-01, 1.4780e-01, 1.4440e-01, 1.4110e-01, 1.3790e-01, 1.3480e-01, 1.3190e-01, 1.2900e-01, 1.2620e-01, 1.2350e-01, 1.2090e-01, 1.1830e-01, 1.1590e-01, 1.1350e-01, 1.1110e-01, 1.0890e-01, 1.0670e-01, 1.0460e-01, 1.0250e-01, 1.0050e-01, 9.8600e-02, 9.6700e-02, 9.4800e-02, 9.3000e-02, 9.1300e-02, 8.9600e-02, 8.7900e-02, 8.6300e-02, 8.4800e-02, 8.3200e-02, 8.1700e-02, 8.0300e-02, 7.8900e-02, 7.7500e-02, 7.6100e-02, 7.4800e-02, 7.3600e-02, 7.2300e-02, 7.1100e-02, 6.9900e-02, 6.8700e-02, 6.7600e-02, 6.6500e-02, 6.5400e-02, 6.4400e-02, 6.3300e-02, 6.2300e-02, 6.1300e-02, 6.0400e-02, 5.9400e-02, 5.8500e-02, 5.7600e-02, 5.6700e-02, 5.5900e-02, 5.5000e-02, 5.4200e-02, 5.3400e-02, 5.2600e-02, 5.1900e-02, 5.1100e-02, 5.0400e-02, 4.9700e-02, 4.9000e-02, 4.8300e-02, 4.7600e-02, 4.6900e-02, 4.6300e-02, 4.5600e-02, 4.5000e-02, 4.4400e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2100e-02, 4.1500e-02, 4.1000e-02, 4.0400e-02, 3.9900e-02, 3.9400e-02, 3.8900e-02, 3.8400e-02, 3.7900e-02, 3.7500e-02, 3.7000e-02, 3.6500e-02, 3.6100e-02, 3.5600e-02, 3.5200e-02, 3.4800e-02, 3.4400e-02, 3.4000e-02, 3.3600e-02, 3.3200e-02, 3.2800e-02, 3.2400e-02, 3.2000e-02, 3.1700e-02, 3.1300e-02, 3.0900e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9600e-02, 2.9200e-02, 2.8900e-02, 2.8600e-02, 2.8300e-02, 2.8000e-02, 2.7700e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6500e-02, 2.6300e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0700e-02, 2.0500e-02, 2.0300e-02, 2.0200e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8800e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.8000e-02, 1.7800e-02, 1.7700e-02, 1.7500e-02, 1.7400e-02, 1.7200e-02, 1.7100e-02, 1.6900e-02, 1.6800e-02, 1.6600e-02, 1.6500e-02, 1.6400e-02, 1.6200e-02, 1.6100e-02}); + } + break; + case 26: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.6000e+01, 2.5816e+01, 2.5304e+01, 2.4555e+01, 2.3677e+01, 2.2751e+01, 2.1825e+01, 2.0920e+01, 2.0040e+01, 1.9183e+01, 1.8347e+01, 1.7531e+01, 1.6738e+01, 1.5969e+01, 1.5228e+01, 1.4517e+01, 1.3840e+01, 1.3199e+01, 1.2594e+01, 1.2028e+01, 1.1500e+01, 1.1009e+01, 1.0555e+01, 1.0136e+01, 9.7519e+00, 9.3991e+00, 9.0762e+00, 8.7811e+00, 8.5115e+00, 8.2651e+00, 8.0400e+00, 7.8339e+00, 7.6448e+00, 7.4710e+00, 7.3105e+00, 7.1617e+00, 7.0232e+00, 6.8935e+00, 6.7714e+00, 6.6558e+00, 6.5456e+00, 6.4400e+00, 6.3382e+00, 6.2395e+00, 6.1434e+00, 6.0493e+00, 5.9569e+00, 5.8657e+00, 5.7755e+00, 5.6860e+00, 5.5972e+00, 5.5087e+00, 5.4207e+00, 5.3329e+00, 5.2453e+00, 5.1580e+00, 5.0709e+00, 4.9841e+00, 4.8976e+00, 4.8114e+00, 4.7256e+00, 4.6403e+00, 4.5556e+00, 4.4714e+00, 4.3879e+00, 4.3052e+00, 4.2233e+00, 4.1423e+00, 4.0623e+00, 3.9832e+00, 3.9053e+00, 3.8285e+00, 3.7528e+00, 3.6784e+00, 3.6053e+00, 3.5335e+00, 3.4630e+00, 3.3939e+00, 3.3262e+00, 3.2599e+00, 3.1951e+00, 3.1316e+00, 3.0697e+00, 3.0092e+00, 2.9502e+00, 2.8927e+00, 2.8365e+00, 2.7819e+00, 2.7287e+00, 2.6770e+00, 2.6266e+00, 2.5776e+00, 2.5300e+00, 2.4839e+00, 2.4391e+00, 2.3955e+00, 2.3532e+00, 2.3121e+00, 2.2724e+00, 2.2340e+00, 2.1968e+00, 2.1605e+00, 2.1253e+00, 2.0914e+00, 2.0587e+00, 2.0271e+00, 1.9964e+00, 1.9665e+00, 1.9374e+00, 1.9095e+00, 1.8828e+00, 1.8570e+00, 1.8319e+00, 1.8073e+00, 1.7834e+00, 1.7605e+00, 1.7386e+00, 1.7176e+00, 1.6972e+00, 1.6772e+00, 1.6576e+00, 1.6386e+00, 1.6205e+00, 1.6033e+00, 1.5868e+00, 1.5706e+00, 1.5546e+00, 1.5389e+00, 1.5236e+00, 1.5091e+00, 1.4954e+00, 1.4824e+00, 1.4696e+00, 1.4568e+00, 1.4441e+00, 1.4315e+00, 1.4196e+00, 1.4084e+00, 1.3979e+00, 1.3877e+00, 1.3776e+00, 1.3672e+00, 1.3569e+00, 1.3467e+00, 1.3371e+00, 1.3281e+00, 1.3198e+00, 1.3117e+00, 1.3034e+00, 1.2950e+00, 1.2863e+00, 1.2777e+00, 1.2695e+00, 1.2620e+00, 1.2550e+00, 1.2484e+00, 1.2417e+00, 1.2347e+00, 1.2274e+00, 1.2200e+00, 1.2126e+00, 1.2056e+00, 1.1993e+00, 1.1936e+00, 1.1880e+00, 1.1823e+00, 1.1763e+00, 1.1699e+00, 1.1633e+00, 1.1566e+00, 1.1503e+00, 1.1445e+00, 1.1393e+00, 1.1344e+00, 1.1295e+00, 1.1243e+00, 1.1187e+00, 1.1128e+00, 1.1067e+00, 1.1005e+00, 1.0947e+00, 1.0895e+00, 1.0849e+00, 1.0805e+00, 1.0761e+00, 1.0712e+00, 1.0660e+00, 1.0605e+00, 1.0548e+00, 1.0490e+00, 1.0433e+00, 1.0381e+00, 1.0335e+00, 1.0294e+00, 1.0254e+00, 1.0210e+00, 1.0163e+00, 1.0112e+00, 1.0060e+00, 1.0004e+00, 9.9480e-01, 9.8930e-01, 9.8420e-01, 9.7980e-01, 9.7600e-01, 9.7220e-01, 9.6810e-01, 9.6350e-01, 9.5870e-01, 9.5370e-01, 9.4850e-01, 9.4310e-01, 9.3750e-01, 9.3230e-01, 9.2760e-01, 9.2360e-01, 9.2000e-01, 9.1630e-01, 9.1220e-01, 9.0780e-01, 9.0300e-01, 8.9820e-01, 8.9320e-01, 8.8800e-01, 8.8250e-01, 8.7720e-01, 8.7250e-01, 8.6840e-01, 8.6490e-01, 8.6150e-01, 8.5780e-01, 8.5360e-01, 8.4910e-01, 8.4440e-01, 8.3980e-01, 8.3500e-01, 8.2990e-01, 8.2460e-01, 8.1940e-01, 8.1470e-01, 8.1070e-01}); + feg = Vctr_cpu({7.1598e+00, 7.0290e+00, 6.6666e+00, 6.1478e+00, 5.5606e+00, 4.9769e+00, 4.4406e+00, 3.9698e+00, 3.5661e+00, 3.2230e+00, 2.9308e+00, 2.6802e+00, 2.4631e+00, 2.2729e+00, 2.1046e+00, 1.9543e+00, 1.8189e+00, 1.6962e+00, 1.5844e+00, 1.4821e+00, 1.3882e+00, 1.3017e+00, 1.2220e+00, 1.1483e+00, 1.0802e+00, 1.0171e+00, 9.5870e-01, 9.0450e-01, 8.5420e-01, 8.0750e-01, 7.6420e-01, 7.2390e-01, 6.8640e-01, 6.5160e-01, 6.1910e-01, 5.8890e-01, 5.6070e-01, 5.3450e-01, 5.0990e-01, 4.8700e-01, 4.6560e-01, 4.4560e-01, 4.2680e-01, 4.0930e-01, 3.9280e-01, 3.7730e-01, 3.6270e-01, 3.4900e-01, 3.3610e-01, 3.2400e-01, 3.1250e-01, 3.0170e-01, 2.9140e-01, 2.8170e-01, 2.7260e-01, 2.6380e-01, 2.5560e-01, 2.4770e-01, 2.4020e-01, 2.3310e-01, 2.2630e-01, 2.1980e-01, 2.1360e-01, 2.0770e-01, 2.0210e-01, 1.9660e-01, 1.9140e-01, 1.8650e-01, 1.8170e-01, 1.7710e-01, 1.7270e-01, 1.6840e-01, 1.6430e-01, 1.6040e-01, 1.5660e-01, 1.5290e-01, 1.4940e-01, 1.4600e-01, 1.4270e-01, 1.3950e-01, 1.3650e-01, 1.3350e-01, 1.3060e-01, 1.2780e-01, 1.2510e-01, 1.2250e-01, 1.1990e-01, 1.1750e-01, 1.1510e-01, 1.1280e-01, 1.1050e-01, 1.0830e-01, 1.0620e-01, 1.0410e-01, 1.0210e-01, 1.0020e-01, 9.8300e-02, 9.6400e-02, 9.4600e-02, 9.2900e-02, 9.1200e-02, 8.9500e-02, 8.7900e-02, 8.6300e-02, 8.4800e-02, 8.3300e-02, 8.1800e-02, 8.0400e-02, 7.9000e-02, 7.7600e-02, 7.6300e-02, 7.5000e-02, 7.3800e-02, 7.2600e-02, 7.1400e-02, 7.0200e-02, 6.9000e-02, 6.7900e-02, 6.6800e-02, 6.5800e-02, 6.4700e-02, 6.3700e-02, 6.2700e-02, 6.1800e-02, 6.0800e-02, 5.9900e-02, 5.9000e-02, 5.8100e-02, 5.7200e-02, 5.6400e-02, 5.5500e-02, 5.4700e-02, 5.3900e-02, 5.3100e-02, 5.2400e-02, 5.1600e-02, 5.0900e-02, 5.0200e-02, 4.9500e-02, 4.8800e-02, 4.8100e-02, 4.7400e-02, 4.6800e-02, 4.6200e-02, 4.5500e-02, 4.4900e-02, 4.4300e-02, 4.3800e-02, 4.3200e-02, 4.2600e-02, 4.2100e-02, 4.1500e-02, 4.1000e-02, 4.0500e-02, 4.0000e-02, 3.9500e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7500e-02, 3.7100e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5300e-02, 3.4900e-02, 3.4500e-02, 3.4100e-02, 3.3700e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2200e-02, 3.1800e-02, 3.1500e-02, 3.1100e-02, 3.0800e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9400e-02, 2.9100e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7600e-02, 2.7300e-02, 2.7000e-02, 2.6700e-02, 2.6500e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5400e-02, 2.5200e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0200e-02, 2.0000e-02, 1.9900e-02, 1.9700e-02, 1.9500e-02, 1.9300e-02, 1.9200e-02, 1.9000e-02, 1.8800e-02, 1.8700e-02, 1.8500e-02, 1.8400e-02, 1.8200e-02, 1.8000e-02, 1.7900e-02, 1.7700e-02, 1.7600e-02, 1.7400e-02, 1.7300e-02, 1.7200e-02, 1.7000e-02, 1.6900e-02, 1.6700e-02}); + } + break; + case 27: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.7000e+01, 2.6824e+01, 2.6331e+01, 2.5605e+01, 2.4743e+01, 2.3825e+01, 2.2898e+01, 2.1985e+01, 2.1090e+01, 2.0216e+01, 1.9361e+01, 1.8523e+01, 1.7706e+01, 1.6912e+01, 1.6142e+01, 1.5402e+01, 1.4692e+01, 1.4017e+01, 1.3377e+01, 1.2774e+01, 1.2208e+01, 1.1679e+01, 1.1187e+01, 1.0730e+01, 1.0308e+01, 9.9185e+00, 9.5604e+00, 9.2314e+00, 8.9297e+00, 8.6532e+00, 8.3998e+00, 8.1676e+00, 7.9546e+00, 7.7589e+00, 7.5788e+00, 7.4126e+00, 7.2586e+00, 7.1155e+00, 6.9819e+00, 6.8566e+00, 6.7384e+00, 6.6264e+00, 6.5197e+00, 6.4174e+00, 6.3188e+00, 6.2234e+00, 6.1305e+00, 6.0398e+00, 5.9508e+00, 5.8631e+00, 5.7766e+00, 5.6909e+00, 5.6059e+00, 5.5214e+00, 5.4374e+00, 5.3537e+00, 5.2703e+00, 5.1871e+00, 5.1042e+00, 5.0216e+00, 4.9392e+00, 4.8571e+00, 4.7753e+00, 4.6940e+00, 4.6130e+00, 4.5326e+00, 4.4527e+00, 4.3735e+00, 4.2949e+00, 4.2170e+00, 4.1399e+00, 4.0637e+00, 3.9884e+00, 3.9140e+00, 3.8407e+00, 3.7684e+00, 3.6972e+00, 3.6270e+00, 3.5581e+00, 3.4904e+00, 3.4239e+00, 3.3587e+00, 3.2946e+00, 3.2320e+00, 3.1706e+00, 3.1105e+00, 3.0517e+00, 2.9943e+00, 2.9382e+00, 2.8835e+00, 2.8300e+00, 2.7777e+00, 2.7269e+00, 2.6774e+00, 2.6292e+00, 2.5822e+00, 2.5364e+00, 2.4919e+00, 2.4487e+00, 2.4067e+00, 2.3660e+00, 2.3262e+00, 2.2875e+00, 2.2500e+00, 2.2138e+00, 2.1787e+00, 2.1446e+00, 2.1113e+00, 2.0789e+00, 2.0477e+00, 2.0176e+00, 1.9886e+00, 1.9602e+00, 1.9326e+00, 1.9057e+00, 1.8797e+00, 1.8548e+00, 1.8309e+00, 1.8077e+00, 1.7849e+00, 1.7626e+00, 1.7410e+00, 1.7203e+00, 1.7005e+00, 1.6815e+00, 1.6630e+00, 1.6447e+00, 1.6267e+00, 1.6093e+00, 1.5927e+00, 1.5769e+00, 1.5618e+00, 1.5470e+00, 1.5324e+00, 1.5178e+00, 1.5036e+00, 1.4900e+00, 1.4772e+00, 1.4651e+00, 1.4533e+00, 1.4416e+00, 1.4299e+00, 1.4182e+00, 1.4068e+00, 1.3959e+00, 1.3858e+00, 1.3762e+00, 1.3669e+00, 1.3576e+00, 1.3481e+00, 1.3386e+00, 1.3291e+00, 1.3201e+00, 1.3116e+00, 1.3038e+00, 1.2964e+00, 1.2889e+00, 1.2812e+00, 1.2733e+00, 1.2653e+00, 1.2573e+00, 1.2499e+00, 1.2430e+00, 1.2367e+00, 1.2306e+00, 1.2244e+00, 1.2179e+00, 1.2112e+00, 1.2042e+00, 1.1973e+00, 1.1906e+00, 1.1845e+00, 1.1790e+00, 1.1739e+00, 1.1687e+00, 1.1632e+00, 1.1574e+00, 1.1513e+00, 1.1451e+00, 1.1389e+00, 1.1329e+00, 1.1276e+00, 1.1228e+00, 1.1183e+00, 1.1137e+00, 1.1088e+00, 1.1036e+00, 1.0981e+00, 1.0923e+00, 1.0865e+00, 1.0808e+00, 1.0756e+00, 1.0710e+00, 1.0669e+00, 1.0628e+00, 1.0585e+00, 1.0538e+00, 1.0487e+00, 1.0435e+00, 1.0380e+00, 1.0325e+00, 1.0270e+00, 1.0221e+00, 1.0178e+00, 1.0139e+00, 1.0101e+00, 1.0061e+00, 1.0016e+00, 9.9690e-01, 9.9200e-01, 9.8680e-01, 9.8150e-01, 9.7610e-01, 9.7100e-01, 9.6640e-01, 9.6240e-01, 9.5880e-01, 9.5520e-01, 9.5130e-01, 9.4690e-01, 9.4230e-01, 9.3750e-01, 9.3260e-01, 9.2750e-01, 9.2220e-01, 9.1700e-01, 9.1240e-01, 9.0830e-01, 9.0490e-01, 9.0150e-01, 8.9790e-01, 8.9380e-01, 8.8940e-01, 8.8490e-01, 8.8020e-01, 8.7550e-01, 8.7050e-01, 8.6530e-01, 8.6020e-01, 8.5560e-01, 8.5170e-01}); + feg = Vctr_cpu({6.8497e+00, 6.7326e+00, 6.4069e+00, 5.9375e+00, 5.4015e+00, 4.8632e+00, 4.3631e+00, 3.9196e+00, 3.5359e+00, 3.2071e+00, 2.9254e+00, 2.6826e+00, 2.4715e+00, 2.2859e+00, 2.1213e+00, 1.9740e+00, 1.8410e+00, 1.7203e+00, 1.6101e+00, 1.5091e+00, 1.4161e+00, 1.3304e+00, 1.2512e+00, 1.1778e+00, 1.1097e+00, 1.0466e+00, 9.8790e-01, 9.3340e-01, 8.8260e-01, 8.3540e-01, 7.9140e-01, 7.5040e-01, 7.1220e-01, 6.7660e-01, 6.4330e-01, 6.1230e-01, 5.8330e-01, 5.5620e-01, 5.3090e-01, 5.0710e-01, 4.8490e-01, 4.6410e-01, 4.4460e-01, 4.2630e-01, 4.0910e-01, 3.9290e-01, 3.7770e-01, 3.6340e-01, 3.4990e-01, 3.3710e-01, 3.2510e-01, 3.1370e-01, 3.0300e-01, 2.9280e-01, 2.8320e-01, 2.7400e-01, 2.6530e-01, 2.5710e-01, 2.4920e-01, 2.4180e-01, 2.3470e-01, 2.2790e-01, 2.2140e-01, 2.1520e-01, 2.0930e-01, 2.0360e-01, 1.9820e-01, 1.9300e-01, 1.8800e-01, 1.8320e-01, 1.7870e-01, 1.7420e-01, 1.7000e-01, 1.6590e-01, 1.6200e-01, 1.5820e-01, 1.5450e-01, 1.5100e-01, 1.4750e-01, 1.4430e-01, 1.4110e-01, 1.3800e-01, 1.3500e-01, 1.3210e-01, 1.2930e-01, 1.2660e-01, 1.2400e-01, 1.2150e-01, 1.1900e-01, 1.1660e-01, 1.1430e-01, 1.1200e-01, 1.0980e-01, 1.0770e-01, 1.0560e-01, 1.0360e-01, 1.0160e-01, 9.9700e-02, 9.7900e-02, 9.6100e-02, 9.4300e-02, 9.2600e-02, 9.1000e-02, 8.9300e-02, 8.7800e-02, 8.6200e-02, 8.4700e-02, 8.3200e-02, 8.1800e-02, 8.0400e-02, 7.9100e-02, 7.7700e-02, 7.6400e-02, 7.5200e-02, 7.3900e-02, 7.2700e-02, 7.1600e-02, 7.0400e-02, 6.9300e-02, 6.8200e-02, 6.7100e-02, 6.6100e-02, 6.5000e-02, 6.4000e-02, 6.3100e-02, 6.2100e-02, 6.1200e-02, 6.0200e-02, 5.9300e-02, 5.8500e-02, 5.7600e-02, 5.6800e-02, 5.5900e-02, 5.5100e-02, 5.4300e-02, 5.3600e-02, 5.2800e-02, 5.2100e-02, 5.1300e-02, 5.0600e-02, 4.9900e-02, 4.9300e-02, 4.8600e-02, 4.7900e-02, 4.7300e-02, 4.6700e-02, 4.6000e-02, 4.5400e-02, 4.4800e-02, 4.4200e-02, 4.3700e-02, 4.3100e-02, 4.2600e-02, 4.2000e-02, 4.1500e-02, 4.1000e-02, 4.0500e-02, 4.0000e-02, 3.9500e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7600e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.5800e-02, 3.5400e-02, 3.5000e-02, 3.4600e-02, 3.4200e-02, 3.3800e-02, 3.3400e-02, 3.3000e-02, 3.2700e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6700e-02, 2.6400e-02, 2.6100e-02, 2.5900e-02, 2.5600e-02, 2.5400e-02, 2.5100e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9700e-02, 1.9600e-02, 1.9400e-02, 1.9200e-02, 1.9100e-02, 1.8900e-02, 1.8700e-02, 1.8600e-02, 1.8400e-02, 1.8300e-02, 1.8100e-02, 1.8000e-02, 1.7800e-02, 1.7700e-02, 1.7500e-02, 1.7400e-02}); + } + break; + case 28: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.8000e+01, 2.7832e+01, 2.7357e+01, 2.6652e+01, 2.5807e+01, 2.4898e+01, 2.3972e+01, 2.3052e+01, 2.2147e+01, 2.1259e+01, 2.0387e+01, 1.9531e+01, 1.8693e+01, 1.7875e+01, 1.7081e+01, 1.6313e+01, 1.5574e+01, 1.4867e+01, 1.4194e+01, 1.3556e+01, 1.2955e+01, 1.2389e+01, 1.1860e+01, 1.1367e+01, 1.0908e+01, 1.0482e+01, 1.0089e+01, 9.7256e+00, 9.3909e+00, 9.0829e+00, 8.7997e+00, 8.5395e+00, 8.3003e+00, 8.0804e+00, 7.8780e+00, 7.6915e+00, 7.5192e+00, 7.3597e+00, 7.2116e+00, 7.0735e+00, 6.9443e+00, 6.8229e+00, 6.7083e+00, 6.5996e+00, 6.4959e+00, 6.3965e+00, 6.3008e+00, 6.2083e+00, 6.1184e+00, 6.0306e+00, 5.9446e+00, 5.8601e+00, 5.7768e+00, 5.6944e+00, 5.6129e+00, 5.5319e+00, 5.4515e+00, 5.3714e+00, 5.2918e+00, 5.2124e+00, 5.1332e+00, 5.0543e+00, 4.9757e+00, 4.8974e+00, 4.8193e+00, 4.7416e+00, 4.6643e+00, 4.5873e+00, 4.5108e+00, 4.4349e+00, 4.3595e+00, 4.2846e+00, 4.2105e+00, 4.1370e+00, 4.0643e+00, 3.9925e+00, 3.9214e+00, 3.8512e+00, 3.7820e+00, 3.7138e+00, 3.6466e+00, 3.5804e+00, 3.5153e+00, 3.4512e+00, 3.3883e+00, 3.3266e+00, 3.2659e+00, 3.2065e+00, 3.1482e+00, 3.0912e+00, 3.0353e+00, 2.9806e+00, 2.9271e+00, 2.8749e+00, 2.8239e+00, 2.7741e+00, 2.7254e+00, 2.6778e+00, 2.6315e+00, 2.5864e+00, 2.5425e+00, 2.4997e+00, 2.4579e+00, 2.4171e+00, 2.3776e+00, 2.3392e+00, 2.3019e+00, 2.2656e+00, 2.2301e+00, 2.1956e+00, 2.1622e+00, 2.1300e+00, 2.0986e+00, 2.0681e+00, 2.0383e+00, 2.0093e+00, 1.9812e+00, 1.9542e+00, 1.9281e+00, 1.9027e+00, 1.8778e+00, 1.8536e+00, 1.8301e+00, 1.8075e+00, 1.7858e+00, 1.7648e+00, 1.7443e+00, 1.7241e+00, 1.7044e+00, 1.6853e+00, 1.6671e+00, 1.6497e+00, 1.6328e+00, 1.6163e+00, 1.6000e+00, 1.5840e+00, 1.5684e+00, 1.5535e+00, 1.5394e+00, 1.5258e+00, 1.5126e+00, 1.4995e+00, 1.4864e+00, 1.4736e+00, 1.4612e+00, 1.4494e+00, 1.4382e+00, 1.4276e+00, 1.4171e+00, 1.4066e+00, 1.3961e+00, 1.3856e+00, 1.3754e+00, 1.3657e+00, 1.3567e+00, 1.3481e+00, 1.3398e+00, 1.3314e+00, 1.3228e+00, 1.3141e+00, 1.3054e+00, 1.2972e+00, 1.2894e+00, 1.2821e+00, 1.2753e+00, 1.2686e+00, 1.2617e+00, 1.2545e+00, 1.2471e+00, 1.2398e+00, 1.2327e+00, 1.2261e+00, 1.2199e+00, 1.2142e+00, 1.2086e+00, 1.2029e+00, 1.1969e+00, 1.1905e+00, 1.1840e+00, 1.1777e+00, 1.1716e+00, 1.1659e+00, 1.1607e+00, 1.1558e+00, 1.1511e+00, 1.1461e+00, 1.1408e+00, 1.1351e+00, 1.1292e+00, 1.1234e+00, 1.1178e+00, 1.1125e+00, 1.1077e+00, 1.1032e+00, 1.0990e+00, 1.0948e+00, 1.0901e+00, 1.0850e+00, 1.0796e+00, 1.0741e+00, 1.0687e+00, 1.0636e+00, 1.0587e+00, 1.0542e+00, 1.0501e+00, 1.0463e+00, 1.0424e+00, 1.0382e+00, 1.0334e+00, 1.0282e+00, 1.0229e+00, 1.0178e+00, 1.0128e+00, 1.0080e+00, 1.0035e+00, 9.9940e-01, 9.9570e-01, 9.9210e-01, 9.8840e-01, 9.8420e-01, 9.7950e-01, 9.7440e-01, 9.6930e-01, 9.6440e-01, 9.5960e-01, 9.5500e-01, 9.5060e-01, 9.4650e-01, 9.4280e-01, 9.3940e-01, 9.3600e-01, 9.3220e-01, 9.2780e-01, 9.2300e-01, 9.1790e-01, 9.1300e-01, 9.0830e-01, 9.0370e-01, 8.9930e-01, 8.9500e-01, 8.9100e-01}); + feg = Vctr_cpu({6.5539e+00, 6.4501e+00, 6.1597e+00, 5.7370e+00, 5.2484e+00, 4.7516e+00, 4.2849e+00, 3.8669e+00, 3.5019e+00, 3.1869e+00, 2.9154e+00, 2.6803e+00, 2.4750e+00, 2.2942e+00, 2.1334e+00, 1.9891e+00, 1.8587e+00, 1.7402e+00, 1.6317e+00, 1.5321e+00, 1.4404e+00, 1.3555e+00, 1.2770e+00, 1.2041e+00, 1.1363e+00, 1.0733e+00, 1.0146e+00, 9.5990e-01, 9.0890e-01, 8.6140e-01, 8.1690e-01, 7.7550e-01, 7.3670e-01, 7.0050e-01, 6.6660e-01, 6.3480e-01, 6.0520e-01, 5.7740e-01, 5.5130e-01, 5.2690e-01, 5.0390e-01, 4.8240e-01, 4.6220e-01, 4.4320e-01, 4.2530e-01, 4.0850e-01, 3.9270e-01, 3.7780e-01, 3.6370e-01, 3.5040e-01, 3.3780e-01, 3.2600e-01, 3.1470e-01, 3.0410e-01, 2.9400e-01, 2.8440e-01, 2.7530e-01, 2.6670e-01, 2.5850e-01, 2.5070e-01, 2.4320e-01, 2.3610e-01, 2.2940e-01, 2.2290e-01, 2.1670e-01, 2.1080e-01, 2.0510e-01, 1.9970e-01, 1.9450e-01, 1.8950e-01, 1.8480e-01, 1.8020e-01, 1.7570e-01, 1.7150e-01, 1.6740e-01, 1.6340e-01, 1.5960e-01, 1.5600e-01, 1.5240e-01, 1.4900e-01, 1.4570e-01, 1.4250e-01, 1.3940e-01, 1.3650e-01, 1.3360e-01, 1.3080e-01, 1.2810e-01, 1.2540e-01, 1.2290e-01, 1.2040e-01, 1.1800e-01, 1.1570e-01, 1.1340e-01, 1.1120e-01, 1.0910e-01, 1.0700e-01, 1.0500e-01, 1.0310e-01, 1.0120e-01, 9.9300e-02, 9.7500e-02, 9.5700e-02, 9.4000e-02, 9.2300e-02, 9.0700e-02, 8.9100e-02, 8.7600e-02, 8.6100e-02, 8.4600e-02, 8.3200e-02, 8.1800e-02, 8.0400e-02, 7.9100e-02, 7.7800e-02, 7.6500e-02, 7.5300e-02, 7.4000e-02, 7.2900e-02, 7.1700e-02, 7.0600e-02, 6.9500e-02, 6.8400e-02, 6.7300e-02, 6.6300e-02, 6.5300e-02, 6.4300e-02, 6.3300e-02, 6.2400e-02, 6.1500e-02, 6.0600e-02, 5.9700e-02, 5.8800e-02, 5.7900e-02, 5.7100e-02, 5.6300e-02, 5.5500e-02, 5.4700e-02, 5.4000e-02, 5.3200e-02, 5.2500e-02, 5.1800e-02, 5.1000e-02, 5.0400e-02, 4.9700e-02, 4.9000e-02, 4.8400e-02, 4.7700e-02, 4.7100e-02, 4.6500e-02, 4.5900e-02, 4.5300e-02, 4.4700e-02, 4.4100e-02, 4.3600e-02, 4.3000e-02, 4.2500e-02, 4.2000e-02, 4.1400e-02, 4.0900e-02, 4.0400e-02, 3.9900e-02, 3.9400e-02, 3.9000e-02, 3.8500e-02, 3.8000e-02, 3.7600e-02, 3.7200e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.3900e-02, 3.3500e-02, 3.3100e-02, 3.2800e-02, 3.2400e-02, 3.2100e-02, 3.1700e-02, 3.1400e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0000e-02, 2.9700e-02, 2.9400e-02, 2.9100e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7700e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6600e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5500e-02, 2.5300e-02, 2.5000e-02, 2.4800e-02, 2.4600e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9800e-02, 1.9600e-02, 1.9400e-02, 1.9300e-02, 1.9100e-02, 1.8900e-02, 1.8800e-02, 1.8600e-02, 1.8500e-02, 1.8300e-02, 1.8200e-02, 1.8000e-02}); + } + break; + case 29: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({2.9000e+01, 2.8857e+01, 2.8449e+01, 2.7837e+01, 2.7086e+01, 2.6251e+01, 2.5370e+01, 2.4462e+01, 2.3539e+01, 2.2612e+01, 2.1687e+01, 2.0770e+01, 1.9868e+01, 1.8987e+01, 1.8132e+01, 1.7306e+01, 1.6513e+01, 1.5755e+01, 1.5034e+01, 1.4351e+01, 1.3706e+01, 1.3100e+01, 1.2532e+01, 1.2001e+01, 1.1507e+01, 1.1047e+01, 1.0620e+01, 1.0225e+01, 9.8602e+00, 9.5233e+00, 9.2127e+00, 8.9264e+00, 8.6627e+00, 8.4199e+00, 8.1960e+00, 7.9896e+00, 7.7990e+00, 7.6226e+00, 7.4592e+00, 7.3073e+00, 7.1657e+00, 7.0333e+00, 6.9090e+00, 6.7919e+00, 6.6810e+00, 6.5757e+00, 6.4750e+00, 6.3785e+00, 6.2855e+00, 6.1954e+00, 6.1080e+00, 6.0227e+00, 5.9392e+00, 5.8572e+00, 5.7764e+00, 5.6967e+00, 5.6178e+00, 5.5397e+00, 5.4621e+00, 5.3850e+00, 5.3082e+00, 5.2319e+00, 5.1558e+00, 5.0801e+00, 5.0046e+00, 4.9294e+00, 4.8545e+00, 4.7799e+00, 4.7056e+00, 4.6317e+00, 4.5583e+00, 4.4852e+00, 4.4127e+00, 4.3407e+00, 4.2692e+00, 4.1984e+00, 4.1282e+00, 4.0587e+00, 3.9900e+00, 3.9220e+00, 3.8549e+00, 3.7886e+00, 3.7231e+00, 3.6586e+00, 3.5951e+00, 3.5325e+00, 3.4709e+00, 3.4103e+00, 3.3507e+00, 3.2922e+00, 3.2348e+00, 3.1784e+00, 3.1230e+00, 3.0688e+00, 3.0158e+00, 2.9638e+00, 2.9129e+00, 2.8630e+00, 2.8143e+00, 2.7667e+00, 2.7202e+00, 2.6748e+00, 2.6304e+00, 2.5870e+00, 2.5448e+00, 2.5036e+00, 2.4635e+00, 2.4244e+00, 2.3861e+00, 2.3489e+00, 2.3127e+00, 2.2775e+00, 2.2434e+00, 2.2100e+00, 2.1774e+00, 2.1457e+00, 2.1149e+00, 2.0852e+00, 2.0563e+00, 2.0281e+00, 2.0006e+00, 1.9738e+00, 1.9478e+00, 1.9226e+00, 1.8983e+00, 1.8748e+00, 1.8518e+00, 1.8293e+00, 1.8073e+00, 1.7860e+00, 1.7655e+00, 1.7458e+00, 1.7267e+00, 1.7080e+00, 1.6897e+00, 1.6717e+00, 1.6543e+00, 1.6375e+00, 1.6214e+00, 1.6059e+00, 1.5908e+00, 1.5759e+00, 1.5612e+00, 1.5469e+00, 1.5330e+00, 1.5196e+00, 1.5069e+00, 1.4946e+00, 1.4826e+00, 1.4707e+00, 1.4589e+00, 1.4473e+00, 1.4360e+00, 1.4252e+00, 1.4149e+00, 1.4050e+00, 1.3954e+00, 1.3859e+00, 1.3764e+00, 1.3668e+00, 1.3575e+00, 1.3484e+00, 1.3398e+00, 1.3316e+00, 1.3237e+00, 1.3161e+00, 1.3084e+00, 1.3005e+00, 1.2926e+00, 1.2849e+00, 1.2773e+00, 1.2701e+00, 1.2633e+00, 1.2568e+00, 1.2505e+00, 1.2442e+00, 1.2377e+00, 1.2310e+00, 1.2243e+00, 1.2178e+00, 1.2115e+00, 1.2055e+00, 1.1997e+00, 1.1943e+00, 1.1890e+00, 1.1837e+00, 1.1781e+00, 1.1722e+00, 1.1663e+00, 1.1605e+00, 1.1549e+00, 1.1496e+00, 1.1444e+00, 1.1396e+00, 1.1350e+00, 1.1304e+00, 1.1255e+00, 1.1204e+00, 1.1150e+00, 1.1097e+00, 1.1044e+00, 1.0994e+00, 1.0945e+00, 1.0899e+00, 1.0855e+00, 1.0814e+00, 1.0772e+00, 1.0728e+00, 1.0680e+00, 1.0630e+00, 1.0580e+00, 1.0531e+00, 1.0483e+00, 1.0436e+00, 1.0392e+00, 1.0349e+00, 1.0309e+00, 1.0271e+00, 1.0233e+00, 1.0190e+00, 1.0144e+00, 1.0096e+00, 1.0047e+00, 1.0001e+00, 9.9550e-01, 9.9100e-01, 9.8670e-01, 9.8260e-01, 9.7870e-01, 9.7510e-01, 9.7150e-01, 9.6770e-01, 9.6340e-01, 9.5870e-01, 9.5400e-01, 9.4930e-01, 9.4490e-01, 9.4050e-01, 9.3620e-01, 9.3200e-01, 9.2800e-01}); + feg = Vctr_cpu({5.5767e+00, 5.4964e+00, 5.2729e+00, 4.9505e+00, 4.5819e+00, 4.2102e+00, 3.8616e+00, 3.5468e+00, 3.2673e+00, 3.0200e+00, 2.8006e+00, 2.6046e+00, 2.4284e+00, 2.2688e+00, 2.1234e+00, 1.9903e+00, 1.8679e+00, 1.7551e+00, 1.6507e+00, 1.5540e+00, 1.4642e+00, 1.3807e+00, 1.3029e+00, 1.2305e+00, 1.1630e+00, 1.1000e+00, 1.0412e+00, 9.8620e-01, 9.3490e-01, 8.8680e-01, 8.4190e-01, 7.9990e-01, 7.6050e-01, 7.2370e-01, 6.8920e-01, 6.5680e-01, 6.2640e-01, 5.9800e-01, 5.7120e-01, 5.4620e-01, 5.2260e-01, 5.0040e-01, 4.7960e-01, 4.5990e-01, 4.4150e-01, 4.2410e-01, 4.0760e-01, 3.9220e-01, 3.7750e-01, 3.6370e-01, 3.5060e-01, 3.3830e-01, 3.2660e-01, 3.1550e-01, 3.0500e-01, 2.9500e-01, 2.8550e-01, 2.7650e-01, 2.6790e-01, 2.5980e-01, 2.5200e-01, 2.4460e-01, 2.3750e-01, 2.3080e-01, 2.2430e-01, 2.1820e-01, 2.1230e-01, 2.0660e-01, 2.0120e-01, 1.9600e-01, 1.9100e-01, 1.8620e-01, 1.8160e-01, 1.7720e-01, 1.7290e-01, 1.6880e-01, 1.6490e-01, 1.6110e-01, 1.5740e-01, 1.5390e-01, 1.5050e-01, 1.4710e-01, 1.4400e-01, 1.4090e-01, 1.3790e-01, 1.3500e-01, 1.3220e-01, 1.2950e-01, 1.2680e-01, 1.2430e-01, 1.2180e-01, 1.1940e-01, 1.1710e-01, 1.1480e-01, 1.1260e-01, 1.1050e-01, 1.0840e-01, 1.0640e-01, 1.0440e-01, 1.0250e-01, 1.0060e-01, 9.8800e-02, 9.7100e-02, 9.5300e-02, 9.3700e-02, 9.2000e-02, 9.0400e-02, 8.8900e-02, 8.7400e-02, 8.5900e-02, 8.4500e-02, 8.3100e-02, 8.1700e-02, 8.0300e-02, 7.9000e-02, 7.7800e-02, 7.6500e-02, 7.5300e-02, 7.4100e-02, 7.2900e-02, 7.1800e-02, 7.0700e-02, 6.9600e-02, 6.8500e-02, 6.7500e-02, 6.6500e-02, 6.5500e-02, 6.4500e-02, 6.3600e-02, 6.2600e-02, 6.1700e-02, 6.0800e-02, 5.9900e-02, 5.9100e-02, 5.8200e-02, 5.7400e-02, 5.6600e-02, 5.5800e-02, 5.5100e-02, 5.4300e-02, 5.3600e-02, 5.2800e-02, 5.2100e-02, 5.1400e-02, 5.0700e-02, 5.0100e-02, 4.9400e-02, 4.8700e-02, 4.8100e-02, 4.7500e-02, 4.6900e-02, 4.6300e-02, 4.5700e-02, 4.5100e-02, 4.4500e-02, 4.4000e-02, 4.3400e-02, 4.2900e-02, 4.2400e-02, 4.1900e-02, 4.1300e-02, 4.0900e-02, 4.0400e-02, 3.9900e-02, 3.9400e-02, 3.8900e-02, 3.8500e-02, 3.8000e-02, 3.7600e-02, 3.7200e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.3900e-02, 3.3600e-02, 3.3200e-02, 3.2800e-02, 3.2500e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1100e-02, 3.0800e-02, 3.0500e-02, 3.0200e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.8900e-02, 2.8600e-02, 2.8400e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02, 2.6700e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5400e-02, 2.5200e-02, 2.5000e-02, 2.4700e-02, 2.4500e-02, 2.4300e-02, 2.4000e-02, 2.3800e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02, 1.9800e-02, 1.9600e-02, 1.9500e-02, 1.9300e-02, 1.9100e-02, 1.9000e-02, 1.8800e-02, 1.8700e-02}); + } + break; + case 30: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.0000e+01, 2.9844e+01, 2.9401e+01, 2.8736e+01, 2.7926e+01, 2.7040e+01, 2.6123e+01, 2.5200e+01, 2.4283e+01, 2.3375e+01, 2.2478e+01, 2.1592e+01, 2.0720e+01, 1.9864e+01, 1.9026e+01, 1.8211e+01, 1.7421e+01, 1.6658e+01, 1.5926e+01, 1.5225e+01, 1.4558e+01, 1.3925e+01, 1.3327e+01, 1.2764e+01, 1.2234e+01, 1.1738e+01, 1.1275e+01, 1.0843e+01, 1.0441e+01, 1.0069e+01, 9.7231e+00, 9.4031e+00, 9.1071e+00, 8.8336e+00, 8.5809e+00, 8.3474e+00, 8.1315e+00, 7.9319e+00, 7.7471e+00, 7.5757e+00, 7.4165e+00, 7.2683e+00, 7.1300e+00, 7.0004e+00, 6.8787e+00, 6.7640e+00, 6.6554e+00, 6.5522e+00, 6.4537e+00, 6.3594e+00, 6.2687e+00, 6.1810e+00, 6.0959e+00, 6.0132e+00, 5.9323e+00, 5.8531e+00, 5.7752e+00, 5.6984e+00, 5.6226e+00, 5.5476e+00, 5.4732e+00, 5.3994e+00, 5.3261e+00, 5.2531e+00, 5.1804e+00, 5.1081e+00, 5.0361e+00, 4.9643e+00, 4.8928e+00, 4.8215e+00, 4.7506e+00, 4.6799e+00, 4.6096e+00, 4.5397e+00, 4.4701e+00, 4.4010e+00, 4.3324e+00, 4.2642e+00, 4.1966e+00, 4.1296e+00, 4.0632e+00, 3.9974e+00, 3.9323e+00, 3.8679e+00, 3.8043e+00, 3.7415e+00, 3.6795e+00, 3.6182e+00, 3.5579e+00, 3.4985e+00, 3.4400e+00, 3.3824e+00, 3.3256e+00, 3.2699e+00, 3.2152e+00, 3.1615e+00, 3.1087e+00, 3.0568e+00, 3.0060e+00, 2.9562e+00, 2.9075e+00, 2.8598e+00, 2.8130e+00, 2.7671e+00, 2.7223e+00, 2.6785e+00, 2.6359e+00, 2.5942e+00, 2.5533e+00, 2.5132e+00, 2.4742e+00, 2.4362e+00, 2.3993e+00, 2.3633e+00, 2.3281e+00, 2.2936e+00, 2.2599e+00, 2.2272e+00, 2.1955e+00, 2.1648e+00, 2.1348e+00, 2.1054e+00, 2.0766e+00, 2.0485e+00, 2.0214e+00, 1.9952e+00, 1.9699e+00, 1.9452e+00, 1.9210e+00, 1.8971e+00, 1.8739e+00, 1.8514e+00, 1.8299e+00, 1.8091e+00, 1.7890e+00, 1.7692e+00, 1.7496e+00, 1.7304e+00, 1.7118e+00, 1.6939e+00, 1.6768e+00, 1.6604e+00, 1.6444e+00, 1.6286e+00, 1.6129e+00, 1.5974e+00, 1.5824e+00, 1.5680e+00, 1.5543e+00, 1.5412e+00, 1.5286e+00, 1.5160e+00, 1.5035e+00, 1.4910e+00, 1.4786e+00, 1.4668e+00, 1.4556e+00, 1.4450e+00, 1.4349e+00, 1.4250e+00, 1.4151e+00, 1.4050e+00, 1.3949e+00, 1.3849e+00, 1.3753e+00, 1.3663e+00, 1.3578e+00, 1.3498e+00, 1.3420e+00, 1.3341e+00, 1.3261e+00, 1.3179e+00, 1.3096e+00, 1.3015e+00, 1.2938e+00, 1.2866e+00, 1.2799e+00, 1.2735e+00, 1.2673e+00, 1.2610e+00, 1.2544e+00, 1.2475e+00, 1.2404e+00, 1.2335e+00, 1.2270e+00, 1.2209e+00, 1.2153e+00, 1.2100e+00, 1.2048e+00, 1.1996e+00, 1.1942e+00, 1.1885e+00, 1.1824e+00, 1.1762e+00, 1.1702e+00, 1.1646e+00, 1.1595e+00, 1.1547e+00, 1.1501e+00, 1.1457e+00, 1.1412e+00, 1.1366e+00, 1.1316e+00, 1.1262e+00, 1.1205e+00, 1.1150e+00, 1.1098e+00, 1.1050e+00, 1.1006e+00, 1.0965e+00, 1.0924e+00, 1.0885e+00, 1.0845e+00, 1.0803e+00, 1.0756e+00, 1.0705e+00, 1.0652e+00, 1.0600e+00, 1.0551e+00, 1.0507e+00, 1.0466e+00, 1.0427e+00, 1.0389e+00, 1.0352e+00, 1.0316e+00, 1.0278e+00, 1.0237e+00, 1.0191e+00, 1.0141e+00, 1.0089e+00, 1.0040e+00, 9.9950e-01, 9.9540e-01, 9.9160e-01, 9.8790e-01, 9.8430e-01, 9.8080e-01, 9.7730e-01, 9.7380e-01, 9.7000e-01, 9.6570e-01}); + feg = Vctr_cpu({6.0665e+00, 5.9796e+00, 5.7360e+00, 5.3793e+00, 4.9628e+00, 4.5336e+00, 4.1239e+00, 3.7510e+00, 3.4208e+00, 3.1321e+00, 2.8806e+00, 2.6609e+00, 2.4678e+00, 2.2968e+00, 2.1440e+00, 2.0064e+00, 1.8817e+00, 1.7679e+00, 1.6634e+00, 1.5672e+00, 1.4783e+00, 1.3958e+00, 1.3191e+00, 1.2477e+00, 1.1811e+00, 1.1189e+00, 1.0607e+00, 1.0063e+00, 9.5530e-01, 9.0750e-01, 8.6280e-01, 8.2070e-01, 7.8130e-01, 7.4430e-01, 7.0950e-01, 6.7690e-01, 6.4620e-01, 6.1730e-01, 5.9010e-01, 5.6460e-01, 5.4050e-01, 5.1780e-01, 4.9650e-01, 4.7630e-01, 4.5730e-01, 4.3940e-01, 4.2250e-01, 4.0650e-01, 3.9140e-01, 3.7700e-01, 3.6350e-01, 3.5070e-01, 3.3850e-01, 3.2700e-01, 3.1610e-01, 3.0570e-01, 2.9580e-01, 2.8640e-01, 2.7750e-01, 2.6900e-01, 2.6090e-01, 2.5320e-01, 2.4580e-01, 2.3880e-01, 2.3200e-01, 2.2560e-01, 2.1950e-01, 2.1360e-01, 2.0790e-01, 2.0250e-01, 1.9730e-01, 1.9230e-01, 1.8760e-01, 1.8300e-01, 1.7850e-01, 1.7430e-01, 1.7020e-01, 1.6620e-01, 1.6240e-01, 1.5870e-01, 1.5520e-01, 1.5180e-01, 1.4850e-01, 1.4530e-01, 1.4220e-01, 1.3920e-01, 1.3630e-01, 1.3350e-01, 1.3080e-01, 1.2810e-01, 1.2560e-01, 1.2310e-01, 1.2070e-01, 1.1830e-01, 1.1610e-01, 1.1390e-01, 1.1170e-01, 1.0970e-01, 1.0760e-01, 1.0570e-01, 1.0370e-01, 1.0190e-01, 1.0010e-01, 9.8300e-02, 9.6600e-02, 9.4900e-02, 9.3300e-02, 9.1700e-02, 9.0100e-02, 8.8600e-02, 8.7100e-02, 8.5700e-02, 8.4300e-02, 8.2900e-02, 8.1500e-02, 8.0200e-02, 7.8900e-02, 7.7700e-02, 7.6500e-02, 7.5300e-02, 7.4100e-02, 7.3000e-02, 7.1800e-02, 7.0700e-02, 6.9700e-02, 6.8600e-02, 6.7600e-02, 6.6600e-02, 6.5600e-02, 6.4700e-02, 6.3700e-02, 6.2800e-02, 6.1900e-02, 6.1000e-02, 6.0200e-02, 5.9300e-02, 5.8500e-02, 5.7700e-02, 5.6900e-02, 5.6100e-02, 5.5300e-02, 5.4600e-02, 5.3900e-02, 5.3100e-02, 5.2400e-02, 5.1700e-02, 5.1100e-02, 5.0400e-02, 4.9700e-02, 4.9100e-02, 4.8500e-02, 4.7800e-02, 4.7200e-02, 4.6600e-02, 4.6100e-02, 4.5500e-02, 4.4900e-02, 4.4400e-02, 4.3800e-02, 4.3300e-02, 4.2800e-02, 4.2200e-02, 4.1700e-02, 4.1200e-02, 4.0800e-02, 4.0300e-02, 3.9800e-02, 3.9300e-02, 3.8900e-02, 3.8400e-02, 3.8000e-02, 3.7600e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3200e-02, 3.2900e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1500e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0200e-02, 2.9900e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7600e-02, 2.7400e-02, 2.7100e-02, 2.6800e-02, 2.6600e-02, 2.6300e-02, 2.6100e-02, 2.5800e-02, 2.5600e-02, 2.5300e-02, 2.5100e-02, 2.4900e-02, 2.4600e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1400e-02, 2.1200e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0500e-02, 2.0300e-02, 2.0100e-02, 2.0000e-02, 1.9800e-02, 1.9600e-02, 1.9500e-02, 1.9300e-02}); + } + break; + case 31: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.1000e+01, 3.0818e+01, 3.0308e+01, 2.9560e+01, 2.8675e+01, 2.7733e+01, 2.6782e+01, 2.5847e+01, 2.4934e+01, 2.4044e+01, 2.3173e+01, 2.2320e+01, 2.1481e+01, 2.0656e+01, 1.9846e+01, 1.9053e+01, 1.8278e+01, 1.7524e+01, 1.6793e+01, 1.6088e+01, 1.5410e+01, 1.4761e+01, 1.4141e+01, 1.3553e+01, 1.2995e+01, 1.2469e+01, 1.1973e+01, 1.1508e+01, 1.1073e+01, 1.0665e+01, 1.0286e+01, 9.9321e+00, 9.6034e+00, 9.2982e+00, 9.0151e+00, 8.7527e+00, 8.5095e+00, 8.2841e+00, 8.0753e+00, 7.8816e+00, 7.7019e+00, 7.5349e+00, 7.3794e+00, 7.2343e+00, 7.0988e+00, 6.9717e+00, 6.8523e+00, 6.7396e+00, 6.6330e+00, 6.5317e+00, 6.4352e+00, 6.3428e+00, 6.2540e+00, 6.1684e+00, 6.0855e+00, 6.0050e+00, 5.9265e+00, 5.8497e+00, 5.7743e+00, 5.7002e+00, 5.6272e+00, 5.5550e+00, 5.4836e+00, 5.4127e+00, 5.3424e+00, 5.2725e+00, 5.2031e+00, 5.1339e+00, 5.0650e+00, 4.9964e+00, 4.9280e+00, 4.8599e+00, 4.7921e+00, 4.7245e+00, 4.6572e+00, 4.5902e+00, 4.5235e+00, 4.4572e+00, 4.3913e+00, 4.3258e+00, 4.2607e+00, 4.1960e+00, 4.1319e+00, 4.0684e+00, 4.0054e+00, 3.9430e+00, 3.8812e+00, 3.8201e+00, 3.7597e+00, 3.7001e+00, 3.6411e+00, 3.5829e+00, 3.5255e+00, 3.4689e+00, 3.4133e+00, 3.3584e+00, 3.3042e+00, 3.2510e+00, 3.1987e+00, 3.1474e+00, 3.0970e+00, 3.0473e+00, 2.9985e+00, 2.9507e+00, 2.9040e+00, 2.8583e+00, 2.8133e+00, 2.7691e+00, 2.7258e+00, 2.6835e+00, 2.6423e+00, 2.6020e+00, 2.5626e+00, 2.5238e+00, 2.4858e+00, 2.4487e+00, 2.4128e+00, 2.3779e+00, 2.3437e+00, 2.3101e+00, 2.2771e+00, 2.2449e+00, 2.2137e+00, 2.1836e+00, 2.1543e+00, 2.1257e+00, 2.0974e+00, 2.0697e+00, 2.0427e+00, 2.0166e+00, 1.9915e+00, 1.9672e+00, 1.9435e+00, 1.9200e+00, 1.8969e+00, 1.8744e+00, 1.8525e+00, 1.8316e+00, 1.8116e+00, 1.7921e+00, 1.7729e+00, 1.7539e+00, 1.7351e+00, 1.7168e+00, 1.6992e+00, 1.6825e+00, 1.6665e+00, 1.6510e+00, 1.6356e+00, 1.6202e+00, 1.6050e+00, 1.5900e+00, 1.5757e+00, 1.5621e+00, 1.5492e+00, 1.5369e+00, 1.5247e+00, 1.5124e+00, 1.5001e+00, 1.4879e+00, 1.4759e+00, 1.4644e+00, 1.4538e+00, 1.4438e+00, 1.4341e+00, 1.4245e+00, 1.4148e+00, 1.4049e+00, 1.3949e+00, 1.3851e+00, 1.3757e+00, 1.3669e+00, 1.3589e+00, 1.3513e+00, 1.3437e+00, 1.3360e+00, 1.3280e+00, 1.3199e+00, 1.3117e+00, 1.3036e+00, 1.2960e+00, 1.2889e+00, 1.2826e+00, 1.2766e+00, 1.2706e+00, 1.2643e+00, 1.2578e+00, 1.2510e+00, 1.2441e+00, 1.2372e+00, 1.2305e+00, 1.2243e+00, 1.2189e+00, 1.2140e+00, 1.2091e+00, 1.2041e+00, 1.1987e+00, 1.1931e+00, 1.1872e+00, 1.1812e+00, 1.1751e+00, 1.1692e+00, 1.1639e+00, 1.1592e+00, 1.1551e+00, 1.1511e+00, 1.1468e+00, 1.1422e+00, 1.1372e+00, 1.1321e+00, 1.1268e+00, 1.1213e+00, 1.1158e+00, 1.1106e+00, 1.1060e+00, 1.1021e+00, 1.0986e+00, 1.0951e+00, 1.0912e+00, 1.0870e+00, 1.0824e+00, 1.0778e+00, 1.0729e+00, 1.0678e+00, 1.0626e+00, 1.0576e+00, 1.0531e+00, 1.0493e+00, 1.0460e+00, 1.0430e+00, 1.0396e+00, 1.0358e+00, 1.0317e+00, 1.0274e+00, 1.0230e+00, 1.0184e+00, 1.0135e+00, 1.0085e+00, 1.0037e+00, 9.9930e-01, 9.9570e-01}); + feg = Vctr_cpu({7.1003e+00, 6.9737e+00, 6.6241e+00, 6.1259e+00, 5.5638e+00, 5.0042e+00, 4.4865e+00, 4.0274e+00, 3.6296e+00, 3.2887e+00, 2.9971e+00, 2.7471e+00, 2.5314e+00, 2.3438e+00, 2.1792e+00, 2.0333e+00, 1.9030e+00, 1.7856e+00, 1.6791e+00, 1.5818e+00, 1.4925e+00, 1.4101e+00, 1.3339e+00, 1.2630e+00, 1.1970e+00, 1.1354e+00, 1.0778e+00, 1.0239e+00, 9.7330e-01, 9.2590e-01, 8.8140e-01, 8.3950e-01, 8.0020e-01, 7.6310e-01, 7.2830e-01, 6.9550e-01, 6.6450e-01, 6.3540e-01, 6.0790e-01, 5.8200e-01, 5.5760e-01, 5.3450e-01, 5.1280e-01, 4.9220e-01, 4.7280e-01, 4.5440e-01, 4.3700e-01, 4.2060e-01, 4.0500e-01, 3.9020e-01, 3.7630e-01, 3.6300e-01, 3.5050e-01, 3.3850e-01, 3.2720e-01, 3.1640e-01, 3.0620e-01, 2.9640e-01, 2.8720e-01, 2.7830e-01, 2.6990e-01, 2.6190e-01, 2.5420e-01, 2.4690e-01, 2.3990e-01, 2.3320e-01, 2.2680e-01, 2.2070e-01, 2.1480e-01, 2.0920e-01, 2.0380e-01, 1.9860e-01, 1.9360e-01, 1.8880e-01, 1.8420e-01, 1.7980e-01, 1.7550e-01, 1.7140e-01, 1.6750e-01, 1.6370e-01, 1.6000e-01, 1.5640e-01, 1.5300e-01, 1.4970e-01, 1.4650e-01, 1.4340e-01, 1.4040e-01, 1.3750e-01, 1.3470e-01, 1.3200e-01, 1.2930e-01, 1.2680e-01, 1.2430e-01, 1.2190e-01, 1.1960e-01, 1.1730e-01, 1.1510e-01, 1.1290e-01, 1.1090e-01, 1.0880e-01, 1.0690e-01, 1.0490e-01, 1.0310e-01, 1.0120e-01, 9.9500e-02, 9.7700e-02, 9.6100e-02, 9.4400e-02, 9.2800e-02, 9.1300e-02, 8.9700e-02, 8.8300e-02, 8.6800e-02, 8.5400e-02, 8.4000e-02, 8.2700e-02, 8.1400e-02, 8.0100e-02, 7.8800e-02, 7.7600e-02, 7.6400e-02, 7.5200e-02, 7.4100e-02, 7.2900e-02, 7.1800e-02, 7.0800e-02, 6.9700e-02, 6.8700e-02, 6.7700e-02, 6.6700e-02, 6.5700e-02, 6.4800e-02, 6.3900e-02, 6.3000e-02, 6.2100e-02, 6.1200e-02, 6.0300e-02, 5.9500e-02, 5.8700e-02, 5.7900e-02, 5.7100e-02, 5.6300e-02, 5.5600e-02, 5.4800e-02, 5.4100e-02, 5.3400e-02, 5.2700e-02, 5.2000e-02, 5.1300e-02, 5.0700e-02, 5.0000e-02, 4.9400e-02, 4.8800e-02, 4.8200e-02, 4.7600e-02, 4.7000e-02, 4.6400e-02, 4.5800e-02, 4.5300e-02, 4.4700e-02, 4.4200e-02, 4.3600e-02, 4.3100e-02, 4.2600e-02, 4.2100e-02, 4.1600e-02, 4.1100e-02, 4.0600e-02, 4.0200e-02, 3.9700e-02, 3.9300e-02, 3.8800e-02, 3.8400e-02, 3.7900e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4400e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.0900e-02, 3.0600e-02, 3.0300e-02, 3.0000e-02, 2.9700e-02, 2.9400e-02, 2.9100e-02, 2.8800e-02, 2.8600e-02, 2.8300e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.6900e-02, 2.6700e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4500e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1700e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.1000e-02, 2.0800e-02, 2.0600e-02, 2.0400e-02, 2.0300e-02, 2.0100e-02, 1.9900e-02}); + } + break; + case 32: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.2000e+01, 3.1810e+01, 3.1276e+01, 3.0482e+01, 2.9534e+01, 2.8520e+01, 2.7503e+01, 2.6514e+01, 2.5567e+01, 2.4660e+01, 2.3791e+01, 2.2951e+01, 2.2136e+01, 2.1340e+01, 2.0560e+01, 1.9796e+01, 1.9046e+01, 1.8313e+01, 1.7598e+01, 1.6902e+01, 1.6227e+01, 1.5575e+01, 1.4947e+01, 1.4345e+01, 1.3770e+01, 1.3222e+01, 1.2701e+01, 1.2209e+01, 1.1744e+01, 1.1307e+01, 1.0896e+01, 1.0511e+01, 1.0150e+01, 9.8139e+00, 9.5001e+00, 9.2080e+00, 8.9361e+00, 8.6834e+00, 8.4485e+00, 8.2302e+00, 8.0274e+00, 7.8389e+00, 7.6635e+00, 7.5001e+00, 7.3477e+00, 7.2054e+00, 7.0722e+00, 6.9472e+00, 6.8297e+00, 6.7188e+00, 6.6138e+00, 6.5142e+00, 6.4193e+00, 6.3286e+00, 6.2415e+00, 6.1577e+00, 6.0766e+00, 5.9981e+00, 5.9216e+00, 5.8470e+00, 5.7740e+00, 5.7023e+00, 5.6317e+00, 5.5621e+00, 5.4933e+00, 5.4252e+00, 5.3577e+00, 5.2907e+00, 5.2241e+00, 5.1579e+00, 5.0920e+00, 5.0263e+00, 4.9609e+00, 4.8958e+00, 4.8309e+00, 4.7662e+00, 4.7018e+00, 4.6376e+00, 4.5737e+00, 4.5101e+00, 4.4467e+00, 4.3838e+00, 4.3212e+00, 4.2590e+00, 4.1971e+00, 4.1357e+00, 4.0749e+00, 4.0145e+00, 3.9546e+00, 3.8953e+00, 3.8365e+00, 3.7784e+00, 3.7210e+00, 3.6642e+00, 3.6080e+00, 3.5525e+00, 3.4978e+00, 3.4440e+00, 3.3908e+00, 3.3383e+00, 3.2865e+00, 3.2356e+00, 3.1856e+00, 3.1365e+00, 3.0881e+00, 3.0404e+00, 2.9935e+00, 2.9476e+00, 2.9027e+00, 2.8587e+00, 2.8153e+00, 2.7727e+00, 2.7308e+00, 2.6899e+00, 2.6500e+00, 2.6111e+00, 2.5729e+00, 2.5352e+00, 2.4983e+00, 2.4622e+00, 2.4271e+00, 2.3930e+00, 2.3598e+00, 2.3271e+00, 2.2949e+00, 2.2633e+00, 2.2325e+00, 2.2028e+00, 2.1740e+00, 2.1460e+00, 2.1184e+00, 2.0912e+00, 2.0645e+00, 2.0384e+00, 2.0133e+00, 1.9892e+00, 1.9658e+00, 1.9429e+00, 1.9203e+00, 1.8978e+00, 1.8758e+00, 1.8546e+00, 1.8342e+00, 1.8147e+00, 1.7959e+00, 1.7773e+00, 1.7589e+00, 1.7406e+00, 1.7226e+00, 1.7051e+00, 1.6885e+00, 1.6727e+00, 1.6576e+00, 1.6428e+00, 1.6281e+00, 1.6132e+00, 1.5985e+00, 1.5840e+00, 1.5701e+00, 1.5571e+00, 1.5448e+00, 1.5330e+00, 1.5214e+00, 1.5097e+00, 1.4978e+00, 1.4859e+00, 1.4741e+00, 1.4628e+00, 1.4523e+00, 1.4426e+00, 1.4333e+00, 1.4242e+00, 1.4151e+00, 1.4057e+00, 1.3960e+00, 1.3862e+00, 1.3767e+00, 1.3677e+00, 1.3596e+00, 1.3521e+00, 1.3449e+00, 1.3378e+00, 1.3305e+00, 1.3230e+00, 1.3151e+00, 1.3070e+00, 1.2989e+00, 1.2913e+00, 1.2845e+00, 1.2784e+00, 1.2727e+00, 1.2671e+00, 1.2614e+00, 1.2554e+00, 1.2490e+00, 1.2423e+00, 1.2353e+00, 1.2285e+00, 1.2221e+00, 1.2165e+00, 1.2116e+00, 1.2070e+00, 1.2025e+00, 1.1978e+00, 1.1928e+00, 1.1875e+00, 1.1818e+00, 1.1757e+00, 1.1695e+00, 1.1636e+00, 1.1584e+00, 1.1539e+00, 1.1500e+00, 1.1463e+00, 1.1424e+00, 1.1383e+00, 1.1339e+00, 1.1292e+00, 1.1241e+00, 1.1185e+00, 1.1128e+00, 1.1073e+00, 1.1025e+00, 1.0984e+00, 1.0949e+00, 1.0917e+00, 1.0884e+00, 1.0848e+00, 1.0810e+00, 1.0769e+00, 1.0725e+00, 1.0676e+00, 1.0623e+00, 1.0568e+00, 1.0517e+00, 1.0473e+00, 1.0436e+00, 1.0406e+00, 1.0377e+00, 1.0347e+00, 1.0314e+00}); + feg = Vctr_cpu({7.3784e+00, 7.2619e+00, 6.9356e+00, 6.4585e+00, 5.9023e+00, 5.3297e+00, 4.7835e+00, 4.2872e+00, 3.8494e+00, 3.4699e+00, 3.1435e+00, 2.8636e+00, 2.6231e+00, 2.4155e+00, 2.2351e+00, 2.0771e+00, 1.9377e+00, 1.8136e+00, 1.7022e+00, 1.6016e+00, 1.5101e+00, 1.4263e+00, 1.3492e+00, 1.2780e+00, 1.2120e+00, 1.1506e+00, 1.0932e+00, 1.0396e+00, 9.8940e-01, 9.4220e-01, 8.9800e-01, 8.5630e-01, 8.1710e-01, 7.8020e-01, 7.4530e-01, 7.1250e-01, 6.8150e-01, 6.5220e-01, 6.2460e-01, 5.9840e-01, 5.7380e-01, 5.5040e-01, 5.2830e-01, 5.0740e-01, 4.8760e-01, 4.6890e-01, 4.5110e-01, 4.3430e-01, 4.1830e-01, 4.0320e-01, 3.8890e-01, 3.7520e-01, 3.6230e-01, 3.5000e-01, 3.3830e-01, 3.2710e-01, 3.1660e-01, 3.0650e-01, 2.9690e-01, 2.8770e-01, 2.7900e-01, 2.7060e-01, 2.6270e-01, 2.5510e-01, 2.4780e-01, 2.4090e-01, 2.3420e-01, 2.2780e-01, 2.2170e-01, 2.1590e-01, 2.1030e-01, 2.0490e-01, 1.9970e-01, 1.9480e-01, 1.9000e-01, 1.8540e-01, 1.8100e-01, 1.7670e-01, 1.7260e-01, 1.6870e-01, 1.6490e-01, 1.6120e-01, 1.5760e-01, 1.5420e-01, 1.5090e-01, 1.4770e-01, 1.4460e-01, 1.4160e-01, 1.3870e-01, 1.3590e-01, 1.3310e-01, 1.3050e-01, 1.2790e-01, 1.2550e-01, 1.2300e-01, 1.2070e-01, 1.1840e-01, 1.1620e-01, 1.1410e-01, 1.1200e-01, 1.1000e-01, 1.0800e-01, 1.0610e-01, 1.0420e-01, 1.0240e-01, 1.0060e-01, 9.8900e-02, 9.7200e-02, 9.5500e-02, 9.3900e-02, 9.2400e-02, 9.0800e-02, 8.9400e-02, 8.7900e-02, 8.6500e-02, 8.5100e-02, 8.3700e-02, 8.2400e-02, 8.1100e-02, 7.9900e-02, 7.8600e-02, 7.7400e-02, 7.6300e-02, 7.5100e-02, 7.4000e-02, 7.2900e-02, 7.1800e-02, 7.0700e-02, 6.9700e-02, 6.8700e-02, 6.7700e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3100e-02, 6.2200e-02, 6.1300e-02, 6.0500e-02, 5.9700e-02, 5.8900e-02, 5.8100e-02, 5.7300e-02, 5.6500e-02, 5.5800e-02, 5.5000e-02, 5.4300e-02, 5.3600e-02, 5.2900e-02, 5.2300e-02, 5.1600e-02, 5.0900e-02, 5.0300e-02, 4.9700e-02, 4.9000e-02, 4.8400e-02, 4.7800e-02, 4.7300e-02, 4.6700e-02, 4.6100e-02, 4.5600e-02, 4.5000e-02, 4.4500e-02, 4.3900e-02, 4.3400e-02, 4.2900e-02, 4.2400e-02, 4.1900e-02, 4.1400e-02, 4.1000e-02, 4.0500e-02, 4.0000e-02, 3.9600e-02, 3.9100e-02, 3.8700e-02, 3.8300e-02, 3.7900e-02, 3.7400e-02, 3.7000e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5500e-02, 3.5100e-02, 3.4700e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.8900e-02, 2.8600e-02, 2.8300e-02, 2.8100e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6500e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5600e-02, 2.5300e-02, 2.5100e-02, 2.4900e-02, 2.4700e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3800e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2000e-02, 2.1800e-02, 2.1600e-02, 2.1500e-02, 2.1300e-02, 2.1100e-02, 2.0900e-02, 2.0800e-02, 2.0600e-02}); + } + break; + case 33: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.3000e+01, 3.2811e+01, 3.2273e+01, 3.1460e+01, 3.0471e+01, 2.9395e+01, 2.8305e+01, 2.7244e+01, 2.6234e+01, 2.5283e+01, 2.4386e+01, 2.3536e+01, 2.2724e+01, 2.1943e+01, 2.1186e+01, 2.0448e+01, 1.9726e+01, 1.9019e+01, 1.8326e+01, 1.7649e+01, 1.6988e+01, 1.6345e+01, 1.5721e+01, 1.5117e+01, 1.4534e+01, 1.3975e+01, 1.3439e+01, 1.2928e+01, 1.2441e+01, 1.1979e+01, 1.1541e+01, 1.1129e+01, 1.0740e+01, 1.0374e+01, 1.0031e+01, 9.7103e+00, 9.4099e+00, 9.1293e+00, 8.8675e+00, 8.6233e+00, 8.3958e+00, 8.1838e+00, 7.9863e+00, 7.8023e+00, 7.6306e+00, 7.4705e+00, 7.3209e+00, 7.1809e+00, 7.0497e+00, 6.9265e+00, 6.8105e+00, 6.7011e+00, 6.5976e+00, 6.4994e+00, 6.4059e+00, 6.3166e+00, 6.2310e+00, 6.1487e+00, 6.0693e+00, 5.9925e+00, 5.9179e+00, 5.8452e+00, 5.7742e+00, 5.7046e+00, 5.6363e+00, 5.5690e+00, 5.5027e+00, 5.4371e+00, 5.3721e+00, 5.3077e+00, 5.2438e+00, 5.1803e+00, 5.1171e+00, 5.0542e+00, 4.9916e+00, 4.9293e+00, 4.8671e+00, 4.8052e+00, 4.7435e+00, 4.6820e+00, 4.6208e+00, 4.5597e+00, 4.4990e+00, 4.4385e+00, 4.3783e+00, 4.3184e+00, 4.2588e+00, 4.1996e+00, 4.1408e+00, 4.0824e+00, 4.0245e+00, 3.9670e+00, 3.9099e+00, 3.8535e+00, 3.7976e+00, 3.7422e+00, 3.6873e+00, 3.6331e+00, 3.5795e+00, 3.5266e+00, 3.4744e+00, 3.4227e+00, 3.3718e+00, 3.3215e+00, 3.2721e+00, 3.2234e+00, 3.1754e+00, 3.1281e+00, 3.0815e+00, 3.0357e+00, 2.9908e+00, 2.9468e+00, 2.9034e+00, 2.8606e+00, 2.8186e+00, 2.7774e+00, 2.7372e+00, 2.6978e+00, 2.6592e+00, 2.6211e+00, 2.5837e+00, 2.5471e+00, 2.5113e+00, 2.4765e+00, 2.4425e+00, 2.4091e+00, 2.3762e+00, 2.3440e+00, 2.3124e+00, 2.2817e+00, 2.2519e+00, 2.2230e+00, 2.1946e+00, 2.1666e+00, 2.1390e+00, 2.1120e+00, 2.0858e+00, 2.0605e+00, 2.0361e+00, 2.0122e+00, 1.9887e+00, 1.9655e+00, 1.9426e+00, 1.9203e+00, 1.8987e+00, 1.8780e+00, 1.8581e+00, 1.8387e+00, 1.8195e+00, 1.8004e+00, 1.7816e+00, 1.7631e+00, 1.7453e+00, 1.7283e+00, 1.7120e+00, 1.6963e+00, 1.6809e+00, 1.6655e+00, 1.6501e+00, 1.6348e+00, 1.6199e+00, 1.6056e+00, 1.5922e+00, 1.5794e+00, 1.5671e+00, 1.5549e+00, 1.5427e+00, 1.5302e+00, 1.5178e+00, 1.5056e+00, 1.4940e+00, 1.4831e+00, 1.4729e+00, 1.4632e+00, 1.4537e+00, 1.4441e+00, 1.4342e+00, 1.4241e+00, 1.4140e+00, 1.4041e+00, 1.3948e+00, 1.3862e+00, 1.3783e+00, 1.3709e+00, 1.3635e+00, 1.3559e+00, 1.3480e+00, 1.3398e+00, 1.3314e+00, 1.3231e+00, 1.3152e+00, 1.3080e+00, 1.3015e+00, 1.2956e+00, 1.2899e+00, 1.2840e+00, 1.2779e+00, 1.2713e+00, 1.2644e+00, 1.2573e+00, 1.2502e+00, 1.2435e+00, 1.2375e+00, 1.2322e+00, 1.2275e+00, 1.2231e+00, 1.2184e+00, 1.2135e+00, 1.2080e+00, 1.2022e+00, 1.1961e+00, 1.1898e+00, 1.1837e+00, 1.1781e+00, 1.1732e+00, 1.1690e+00, 1.1653e+00, 1.1617e+00, 1.1578e+00, 1.1535e+00, 1.1488e+00, 1.1437e+00, 1.1382e+00, 1.1325e+00, 1.1269e+00, 1.1216e+00, 1.1170e+00, 1.1132e+00, 1.1100e+00, 1.1070e+00, 1.1039e+00, 1.1003e+00, 1.0963e+00, 1.0919e+00, 1.0871e+00, 1.0820e+00, 1.0767e+00, 1.0714e+00, 1.0665e+00, 1.0622e+00, 1.0587e+00}); + feg = Vctr_cpu({7.3340e+00, 7.2375e+00, 6.9633e+00, 6.5514e+00, 6.0541e+00, 5.5219e+00, 4.9946e+00, 4.4986e+00, 4.0482e+00, 3.6484e+00, 3.2987e+00, 2.9952e+00, 2.7326e+00, 2.5054e+00, 2.3083e+00, 2.1364e+00, 1.9856e+00, 1.8526e+00, 1.7343e+00, 1.6284e+00, 1.5329e+00, 1.4462e+00, 1.3671e+00, 1.2946e+00, 1.2276e+00, 1.1657e+00, 1.1081e+00, 1.0544e+00, 1.0042e+00, 9.5720e-01, 9.1300e-01, 8.7150e-01, 8.3240e-01, 7.9560e-01, 7.6090e-01, 7.2800e-01, 6.9700e-01, 6.6770e-01, 6.4000e-01, 6.1370e-01, 5.8890e-01, 5.6530e-01, 5.4300e-01, 5.2190e-01, 5.0180e-01, 4.8280e-01, 4.6470e-01, 4.4760e-01, 4.3130e-01, 4.1590e-01, 4.0120e-01, 3.8720e-01, 3.7390e-01, 3.6130e-01, 3.4920e-01, 3.3780e-01, 3.2690e-01, 3.1650e-01, 3.0660e-01, 2.9710e-01, 2.8810e-01, 2.7950e-01, 2.7120e-01, 2.6340e-01, 2.5580e-01, 2.4860e-01, 2.4170e-01, 2.3510e-01, 2.2880e-01, 2.2270e-01, 2.1690e-01, 2.1130e-01, 2.0600e-01, 2.0080e-01, 1.9590e-01, 1.9110e-01, 1.8650e-01, 1.8210e-01, 1.7790e-01, 1.7380e-01, 1.6980e-01, 1.6600e-01, 1.6230e-01, 1.5880e-01, 1.5530e-01, 1.5200e-01, 1.4880e-01, 1.4570e-01, 1.4270e-01, 1.3980e-01, 1.3700e-01, 1.3430e-01, 1.3160e-01, 1.2900e-01, 1.2660e-01, 1.2410e-01, 1.2180e-01, 1.1950e-01, 1.1730e-01, 1.1520e-01, 1.1310e-01, 1.1100e-01, 1.0910e-01, 1.0710e-01, 1.0530e-01, 1.0340e-01, 1.0160e-01, 9.9900e-02, 9.8200e-02, 9.6600e-02, 9.5000e-02, 9.3400e-02, 9.1900e-02, 9.0400e-02, 8.8900e-02, 8.7500e-02, 8.6100e-02, 8.4800e-02, 8.3400e-02, 8.2100e-02, 8.0900e-02, 7.9700e-02, 7.8400e-02, 7.7300e-02, 7.6100e-02, 7.5000e-02, 7.3900e-02, 7.2800e-02, 7.1700e-02, 7.0700e-02, 6.9700e-02, 6.8700e-02, 6.7700e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3100e-02, 6.2300e-02, 6.1400e-02, 6.0600e-02, 5.9800e-02, 5.9000e-02, 5.8200e-02, 5.7400e-02, 5.6700e-02, 5.5900e-02, 5.5200e-02, 5.4500e-02, 5.3800e-02, 5.3100e-02, 5.2500e-02, 5.1800e-02, 5.1200e-02, 5.0500e-02, 4.9900e-02, 4.9300e-02, 4.8700e-02, 4.8100e-02, 4.7500e-02, 4.6900e-02, 4.6400e-02, 4.5800e-02, 4.5300e-02, 4.4800e-02, 4.4200e-02, 4.3700e-02, 4.3200e-02, 4.2700e-02, 4.2200e-02, 4.1700e-02, 4.1300e-02, 4.0800e-02, 4.0400e-02, 3.9900e-02, 3.9500e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7400e-02, 3.7000e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5400e-02, 3.5000e-02, 3.4700e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8400e-02, 2.8100e-02, 2.7900e-02, 2.7600e-02, 2.7400e-02, 2.7100e-02, 2.6900e-02, 2.6600e-02, 2.6400e-02, 2.6100e-02, 2.5900e-02, 2.5700e-02, 2.5400e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4500e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02, 2.2300e-02, 2.2100e-02, 2.1900e-02, 2.1800e-02, 2.1600e-02, 2.1400e-02, 2.1200e-02}); + } + break; + case 34: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.4000e+01, 3.3814e+01, 3.3279e+01, 3.2461e+01, 3.1447e+01, 3.0326e+01, 2.9173e+01, 2.8041e+01, 2.6960e+01, 2.5947e+01, 2.5001e+01, 2.4117e+01, 2.3288e+01, 2.2502e+01, 2.1752e+01, 2.1029e+01, 2.0328e+01, 1.9645e+01, 1.8977e+01, 1.8323e+01, 1.7682e+01, 1.7056e+01, 1.6444e+01, 1.5848e+01, 1.5268e+01, 1.4707e+01, 1.4166e+01, 1.3644e+01, 1.3144e+01, 1.2665e+01, 1.2208e+01, 1.1774e+01, 1.1361e+01, 1.0971e+01, 1.0602e+01, 1.0254e+01, 9.9266e+00, 9.6192e+00, 9.3308e+00, 9.0606e+00, 8.8078e+00, 8.5714e+00, 8.3505e+00, 8.1441e+00, 7.9513e+00, 7.7713e+00, 7.6030e+00, 7.4457e+00, 7.2984e+00, 7.1605e+00, 7.0310e+00, 6.9094e+00, 6.7948e+00, 6.6866e+00, 6.5843e+00, 6.4873e+00, 6.3949e+00, 6.3068e+00, 6.2225e+00, 6.1415e+00, 6.0635e+00, 5.9882e+00, 5.9152e+00, 5.8442e+00, 5.7750e+00, 5.7073e+00, 5.6410e+00, 5.5758e+00, 5.5116e+00, 5.4483e+00, 5.3857e+00, 5.3237e+00, 5.2622e+00, 5.2012e+00, 5.1405e+00, 5.0802e+00, 5.0202e+00, 4.9604e+00, 4.9009e+00, 4.8416e+00, 4.7824e+00, 4.7235e+00, 4.6648e+00, 4.6063e+00, 4.5479e+00, 4.4898e+00, 4.4320e+00, 4.3743e+00, 4.3170e+00, 4.2600e+00, 4.2032e+00, 4.1468e+00, 4.0908e+00, 4.0351e+00, 3.9799e+00, 3.9250e+00, 3.8706e+00, 3.8167e+00, 3.7633e+00, 3.7104e+00, 3.6581e+00, 3.6062e+00, 3.5550e+00, 3.5043e+00, 3.4543e+00, 3.4049e+00, 3.3561e+00, 3.3079e+00, 3.2604e+00, 3.2136e+00, 3.1675e+00, 3.1221e+00, 3.0773e+00, 3.0332e+00, 2.9898e+00, 2.9471e+00, 2.9052e+00, 2.8641e+00, 2.8237e+00, 2.7839e+00, 2.7447e+00, 2.7062e+00, 2.6686e+00, 2.6318e+00, 2.5957e+00, 2.5603e+00, 2.5254e+00, 2.4912e+00, 2.4576e+00, 2.4249e+00, 2.3930e+00, 2.3618e+00, 2.3312e+00, 2.3011e+00, 2.2715e+00, 2.2425e+00, 2.2142e+00, 2.1868e+00, 2.1601e+00, 2.1341e+00, 2.1085e+00, 2.0832e+00, 2.0584e+00, 2.0341e+00, 2.0106e+00, 1.9878e+00, 1.9658e+00, 1.9443e+00, 1.9231e+00, 1.9022e+00, 1.8815e+00, 1.8613e+00, 1.8417e+00, 1.8228e+00, 1.8047e+00, 1.7872e+00, 1.7699e+00, 1.7528e+00, 1.7357e+00, 1.7189e+00, 1.7025e+00, 1.6867e+00, 1.6717e+00, 1.6573e+00, 1.6434e+00, 1.6296e+00, 1.6159e+00, 1.6021e+00, 1.5884e+00, 1.5750e+00, 1.5621e+00, 1.5499e+00, 1.5384e+00, 1.5274e+00, 1.5166e+00, 1.5057e+00, 1.4947e+00, 1.4836e+00, 1.4725e+00, 1.4616e+00, 1.4513e+00, 1.4418e+00, 1.4328e+00, 1.4243e+00, 1.4159e+00, 1.4074e+00, 1.3987e+00, 1.3896e+00, 1.3805e+00, 1.3715e+00, 1.3629e+00, 1.3550e+00, 1.3477e+00, 1.3410e+00, 1.3346e+00, 1.3280e+00, 1.3212e+00, 1.3140e+00, 1.3065e+00, 1.2988e+00, 1.2913e+00, 1.2842e+00, 1.2777e+00, 1.2719e+00, 1.2666e+00, 1.2616e+00, 1.2566e+00, 1.2512e+00, 1.2453e+00, 1.2391e+00, 1.2326e+00, 1.2259e+00, 1.2196e+00, 1.2137e+00, 1.2085e+00, 1.2039e+00, 1.1999e+00, 1.1960e+00, 1.1919e+00, 1.1874e+00, 1.1824e+00, 1.1770e+00, 1.1712e+00, 1.1653e+00, 1.1595e+00, 1.1541e+00, 1.1494e+00, 1.1454e+00, 1.1420e+00, 1.1388e+00, 1.1356e+00, 1.1320e+00, 1.1280e+00, 1.1234e+00, 1.1184e+00, 1.1131e+00, 1.1076e+00, 1.1023e+00, 1.0973e+00, 1.0930e+00, 1.0894e+00}); + feg = Vctr_cpu({7.2181e+00, 7.1373e+00, 6.9052e+00, 6.5505e+00, 6.1115e+00, 5.6281e+00, 5.1349e+00, 4.6574e+00, 4.2120e+00, 3.8073e+00, 3.4461e+00, 3.1276e+00, 2.8487e+00, 2.6053e+00, 2.3930e+00, 2.2076e+00, 2.0451e+00, 1.9021e+00, 1.7756e+00, 1.6630e+00, 1.5622e+00, 1.4713e+00, 1.3890e+00, 1.3140e+00, 1.2453e+00, 1.1821e+00, 1.1236e+00, 1.0693e+00, 1.0187e+00, 9.7150e-01, 9.2720e-01, 8.8570e-01, 8.4660e-01, 8.0980e-01, 7.7510e-01, 7.4230e-01, 7.1130e-01, 6.8200e-01, 6.5420e-01, 6.2790e-01, 6.0290e-01, 5.7930e-01, 5.5680e-01, 5.3550e-01, 5.1520e-01, 4.9600e-01, 4.7770e-01, 4.6030e-01, 4.4380e-01, 4.2810e-01, 4.1310e-01, 3.9880e-01, 3.8530e-01, 3.7240e-01, 3.6000e-01, 3.4830e-01, 3.3710e-01, 3.2640e-01, 3.1620e-01, 3.0650e-01, 2.9720e-01, 2.8830e-01, 2.7980e-01, 2.7170e-01, 2.6390e-01, 2.5640e-01, 2.4930e-01, 2.4250e-01, 2.3590e-01, 2.2960e-01, 2.2360e-01, 2.1780e-01, 2.1230e-01, 2.0690e-01, 2.0180e-01, 1.9690e-01, 1.9210e-01, 1.8760e-01, 1.8320e-01, 1.7890e-01, 1.7480e-01, 1.7090e-01, 1.6710e-01, 1.6340e-01, 1.5980e-01, 1.5640e-01, 1.5310e-01, 1.4990e-01, 1.4680e-01, 1.4380e-01, 1.4090e-01, 1.3810e-01, 1.3530e-01, 1.3270e-01, 1.3010e-01, 1.2760e-01, 1.2520e-01, 1.2280e-01, 1.2060e-01, 1.1830e-01, 1.1620e-01, 1.1410e-01, 1.1210e-01, 1.1010e-01, 1.0810e-01, 1.0630e-01, 1.0440e-01, 1.0270e-01, 1.0090e-01, 9.9200e-02, 9.7600e-02, 9.6000e-02, 9.4400e-02, 9.2900e-02, 9.1400e-02, 8.9900e-02, 8.8500e-02, 8.7100e-02, 8.5700e-02, 8.4400e-02, 8.3100e-02, 8.1800e-02, 8.0600e-02, 7.9400e-02, 7.8200e-02, 7.7100e-02, 7.5900e-02, 7.4800e-02, 7.3700e-02, 7.2700e-02, 7.1600e-02, 7.0600e-02, 6.9600e-02, 6.8600e-02, 6.7700e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3200e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9100e-02, 5.8300e-02, 5.7500e-02, 5.6800e-02, 5.6100e-02, 5.5400e-02, 5.4700e-02, 5.4000e-02, 5.3300e-02, 5.2600e-02, 5.2000e-02, 5.1300e-02, 5.0700e-02, 5.0100e-02, 4.9500e-02, 4.8900e-02, 4.8300e-02, 4.7700e-02, 4.7200e-02, 4.6600e-02, 4.6100e-02, 4.5500e-02, 4.5000e-02, 4.4500e-02, 4.4000e-02, 4.3500e-02, 4.3000e-02, 4.2500e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0600e-02, 4.0200e-02, 3.9700e-02, 3.9300e-02, 3.8900e-02, 3.8500e-02, 3.8100e-02, 3.7700e-02, 3.7200e-02, 3.6900e-02, 3.6500e-02, 3.6100e-02, 3.5700e-02, 3.5300e-02, 3.5000e-02, 3.4600e-02, 3.4300e-02, 3.3900e-02, 3.3600e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.7900e-02, 2.7700e-02, 2.7400e-02, 2.7200e-02, 2.6900e-02, 2.6700e-02, 2.6400e-02, 2.6200e-02, 2.6000e-02, 2.5700e-02, 2.5500e-02, 2.5300e-02, 2.5100e-02, 2.4800e-02, 2.4600e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3800e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02, 2.3000e-02, 2.2800e-02, 2.2600e-02, 2.2400e-02, 2.2200e-02, 2.2100e-02, 2.1900e-02}); + } + break; + case 35: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.5000e+01, 3.4817e+01, 3.4290e+01, 3.3474e+01, 3.2448e+01, 3.1296e+01, 3.0093e+01, 2.8897e+01, 2.7747e+01, 2.6664e+01, 2.5657e+01, 2.4724e+01, 2.3857e+01, 2.3049e+01, 2.2288e+01, 2.1566e+01, 2.0875e+01, 2.0207e+01, 1.9559e+01, 1.8926e+01, 1.8307e+01, 1.7701e+01, 1.7107e+01, 1.6526e+01, 1.5958e+01, 1.5404e+01, 1.4865e+01, 1.4342e+01, 1.3836e+01, 1.3349e+01, 1.2880e+01, 1.2430e+01, 1.2000e+01, 1.1590e+01, 1.1200e+01, 1.0829e+01, 1.0479e+01, 1.0147e+01, 9.8336e+00, 9.5386e+00, 9.2611e+00, 9.0004e+00, 8.7558e+00, 8.5264e+00, 8.3115e+00, 8.1102e+00, 7.9217e+00, 7.7453e+00, 7.5800e+00, 7.4253e+00, 7.2801e+00, 7.1440e+00, 7.0160e+00, 6.8957e+00, 6.7823e+00, 6.6752e+00, 6.5738e+00, 6.4777e+00, 6.3864e+00, 6.2992e+00, 6.2160e+00, 6.1361e+00, 6.0593e+00, 5.9852e+00, 5.9136e+00, 5.8441e+00, 5.7764e+00, 5.7104e+00, 5.6458e+00, 5.5825e+00, 5.5202e+00, 5.4589e+00, 5.3984e+00, 5.3386e+00, 5.2793e+00, 5.2206e+00, 5.1623e+00, 5.1044e+00, 5.0467e+00, 4.9894e+00, 4.9323e+00, 4.8754e+00, 4.8187e+00, 4.7622e+00, 4.7059e+00, 4.6497e+00, 4.5937e+00, 4.5379e+00, 4.4823e+00, 4.4269e+00, 4.3718e+00, 4.3168e+00, 4.2621e+00, 4.2077e+00, 4.1536e+00, 4.0998e+00, 4.0463e+00, 3.9931e+00, 3.9403e+00, 3.8880e+00, 3.8360e+00, 3.7845e+00, 3.7334e+00, 3.6827e+00, 3.6326e+00, 3.5830e+00, 3.5340e+00, 3.4854e+00, 3.4374e+00, 3.3899e+00, 3.3431e+00, 3.2968e+00, 3.2512e+00, 3.2062e+00, 3.1617e+00, 3.1179e+00, 3.0747e+00, 3.0323e+00, 2.9905e+00, 2.9493e+00, 2.9087e+00, 2.8688e+00, 2.8295e+00, 2.7910e+00, 2.7531e+00, 2.7160e+00, 2.6794e+00, 2.6435e+00, 2.6081e+00, 2.5735e+00, 2.5396e+00, 2.5064e+00, 2.4739e+00, 2.4419e+00, 2.4104e+00, 2.3796e+00, 2.3493e+00, 2.3198e+00, 2.2910e+00, 2.2629e+00, 2.2353e+00, 2.2082e+00, 2.1815e+00, 2.1553e+00, 2.1298e+00, 2.1049e+00, 2.0808e+00, 2.0573e+00, 2.0342e+00, 2.0115e+00, 1.9891e+00, 1.9671e+00, 1.9456e+00, 1.9248e+00, 1.9047e+00, 1.8852e+00, 1.8662e+00, 1.8474e+00, 1.8288e+00, 1.8104e+00, 1.7924e+00, 1.7750e+00, 1.7582e+00, 1.7420e+00, 1.7263e+00, 1.7110e+00, 1.6958e+00, 1.6807e+00, 1.6657e+00, 1.6510e+00, 1.6367e+00, 1.6230e+00, 1.6100e+00, 1.5974e+00, 1.5852e+00, 1.5731e+00, 1.5610e+00, 1.5488e+00, 1.5366e+00, 1.5248e+00, 1.5134e+00, 1.5026e+00, 1.4924e+00, 1.4826e+00, 1.4731e+00, 1.4636e+00, 1.4539e+00, 1.4440e+00, 1.4341e+00, 1.4243e+00, 1.4150e+00, 1.4062e+00, 1.3980e+00, 1.3903e+00, 1.3829e+00, 1.3755e+00, 1.3679e+00, 1.3600e+00, 1.3518e+00, 1.3436e+00, 1.3356e+00, 1.3280e+00, 1.3210e+00, 1.3145e+00, 1.3086e+00, 1.3029e+00, 1.2971e+00, 1.2911e+00, 1.2847e+00, 1.2779e+00, 1.2709e+00, 1.2640e+00, 1.2574e+00, 1.2513e+00, 1.2459e+00, 1.2409e+00, 1.2364e+00, 1.2320e+00, 1.2274e+00, 1.2224e+00, 1.2169e+00, 1.2110e+00, 1.2049e+00, 1.1988e+00, 1.1930e+00, 1.1878e+00, 1.1830e+00, 1.1789e+00, 1.1752e+00, 1.1718e+00, 1.1682e+00, 1.1642e+00, 1.1597e+00, 1.1546e+00, 1.1492e+00, 1.1436e+00, 1.1382e+00, 1.1331e+00, 1.1285e+00, 1.1244e+00, 1.1210e+00}); + feg = Vctr_cpu({7.0661e+00, 6.9977e+00, 6.8001e+00, 6.4938e+00, 6.1077e+00, 5.6733e+00, 5.2194e+00, 4.7693e+00, 4.3397e+00, 3.9408e+00, 3.5778e+00, 3.2523e+00, 2.9632e+00, 2.7080e+00, 2.4836e+00, 2.2864e+00, 2.1129e+00, 1.9601e+00, 1.8250e+00, 1.7051e+00, 1.5981e+00, 1.5021e+00, 1.4157e+00, 1.3373e+00, 1.2660e+00, 1.2007e+00, 1.1406e+00, 1.0851e+00, 1.0337e+00, 9.8590e-01, 9.4120e-01, 8.9940e-01, 8.6010e-01, 8.2320e-01, 7.8840e-01, 7.5560e-01, 7.2460e-01, 6.9520e-01, 6.6740e-01, 6.4100e-01, 6.1600e-01, 5.9230e-01, 5.6970e-01, 5.4830e-01, 5.2790e-01, 5.0850e-01, 4.9000e-01, 4.7250e-01, 4.5570e-01, 4.3980e-01, 4.2460e-01, 4.1010e-01, 3.9630e-01, 3.8310e-01, 3.7060e-01, 3.5860e-01, 3.4710e-01, 3.3620e-01, 3.2570e-01, 3.1570e-01, 3.0620e-01, 2.9700e-01, 2.8830e-01, 2.7990e-01, 2.7190e-01, 2.6430e-01, 2.5690e-01, 2.4990e-01, 2.4310e-01, 2.3660e-01, 2.3040e-01, 2.2440e-01, 2.1870e-01, 2.1310e-01, 2.0780e-01, 2.0270e-01, 1.9780e-01, 1.9310e-01, 1.8850e-01, 1.8410e-01, 1.7990e-01, 1.7580e-01, 1.7190e-01, 1.6810e-01, 1.6440e-01, 1.6090e-01, 1.5740e-01, 1.5410e-01, 1.5090e-01, 1.4780e-01, 1.4480e-01, 1.4190e-01, 1.3910e-01, 1.3630e-01, 1.3370e-01, 1.3110e-01, 1.2860e-01, 1.2620e-01, 1.2380e-01, 1.2160e-01, 1.1930e-01, 1.1720e-01, 1.1510e-01, 1.1300e-01, 1.1110e-01, 1.0910e-01, 1.0720e-01, 1.0540e-01, 1.0360e-01, 1.0190e-01, 1.0020e-01, 9.8500e-02, 9.6900e-02, 9.5300e-02, 9.3800e-02, 9.2300e-02, 9.0900e-02, 8.9400e-02, 8.8000e-02, 8.6700e-02, 8.5300e-02, 8.4000e-02, 8.2800e-02, 8.1500e-02, 8.0300e-02, 7.9100e-02, 7.8000e-02, 7.6800e-02, 7.5700e-02, 7.4600e-02, 7.3600e-02, 7.2500e-02, 7.1500e-02, 7.0500e-02, 6.9500e-02, 6.8500e-02, 6.7600e-02, 6.6700e-02, 6.5800e-02, 6.4900e-02, 6.4000e-02, 6.3200e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9100e-02, 5.8400e-02, 5.7600e-02, 5.6900e-02, 5.6200e-02, 5.5500e-02, 5.4800e-02, 5.4100e-02, 5.3400e-02, 5.2800e-02, 5.2100e-02, 5.1500e-02, 5.0900e-02, 5.0300e-02, 4.9700e-02, 4.9100e-02, 4.8500e-02, 4.7900e-02, 4.7400e-02, 4.6800e-02, 4.6300e-02, 4.5800e-02, 4.5200e-02, 4.4700e-02, 4.4200e-02, 4.3700e-02, 4.3200e-02, 4.2700e-02, 4.2300e-02, 4.1800e-02, 4.1300e-02, 4.0900e-02, 4.0400e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8700e-02, 3.8300e-02, 3.7900e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6400e-02, 3.6000e-02, 3.5600e-02, 3.5300e-02, 3.4900e-02, 3.4600e-02, 3.4200e-02, 3.3900e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02, 2.6700e-02, 2.6500e-02, 2.6300e-02, 2.6000e-02, 2.5800e-02, 2.5600e-02, 2.5400e-02, 2.5100e-02, 2.4900e-02, 2.4700e-02, 2.4500e-02, 2.4300e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3500e-02, 2.3300e-02, 2.3100e-02, 2.2900e-02, 2.2700e-02, 2.2500e-02}); + } + break; + case 36: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.6000e+01, 3.5821e+01, 3.5303e+01, 3.4495e+01, 3.3466e+01, 3.2295e+01, 3.1054e+01, 2.9804e+01, 2.8590e+01, 2.7438e+01, 2.6363e+01, 2.5369e+01, 2.4453e+01, 2.3606e+01, 2.2820e+01, 2.2083e+01, 2.1387e+01, 2.0724e+01, 2.0087e+01, 1.9470e+01, 1.8870e+01, 1.8284e+01, 1.7709e+01, 1.7146e+01, 1.6594e+01, 1.6053e+01, 1.5523e+01, 1.5007e+01, 1.4504e+01, 1.4015e+01, 1.3542e+01, 1.3084e+01, 1.2644e+01, 1.2220e+01, 1.1814e+01, 1.1426e+01, 1.1056e+01, 1.0703e+01, 1.0368e+01, 1.0051e+01, 9.7509e+00, 9.4672e+00, 9.1997e+00, 8.9477e+00, 8.7105e+00, 8.4875e+00, 8.2781e+00, 8.0815e+00, 7.8969e+00, 7.7238e+00, 7.5613e+00, 7.4088e+00, 7.2656e+00, 7.1310e+00, 7.0044e+00, 6.8852e+00, 6.7728e+00, 6.6665e+00, 6.5660e+00, 6.4707e+00, 6.3801e+00, 6.2938e+00, 6.2114e+00, 6.1324e+00, 6.0566e+00, 5.9836e+00, 5.9131e+00, 5.8448e+00, 5.7785e+00, 5.7139e+00, 5.6509e+00, 5.5892e+00, 5.5287e+00, 5.4692e+00, 5.4105e+00, 5.3527e+00, 5.2954e+00, 5.2388e+00, 5.1826e+00, 5.1268e+00, 5.0714e+00, 5.0163e+00, 4.9615e+00, 4.9069e+00, 4.8525e+00, 4.7982e+00, 4.7442e+00, 4.6903e+00, 4.6366e+00, 4.5830e+00, 4.5296e+00, 4.4763e+00, 4.4232e+00, 4.3703e+00, 4.3177e+00, 4.2652e+00, 4.2129e+00, 4.1609e+00, 4.1092e+00, 4.0578e+00, 4.0066e+00, 3.9558e+00, 3.9053e+00, 3.8552e+00, 3.8054e+00, 3.7561e+00, 3.7072e+00, 3.6587e+00, 3.6106e+00, 3.5630e+00, 3.5159e+00, 3.4693e+00, 3.4232e+00, 3.3776e+00, 3.3325e+00, 3.2880e+00, 3.2440e+00, 3.2007e+00, 3.1579e+00, 3.1157e+00, 3.0740e+00, 3.0329e+00, 2.9924e+00, 2.9525e+00, 2.9133e+00, 2.8747e+00, 2.8367e+00, 2.7992e+00, 2.7624e+00, 2.7261e+00, 2.6906e+00, 2.6557e+00, 2.6214e+00, 2.5877e+00, 2.5546e+00, 2.5219e+00, 2.4899e+00, 2.4586e+00, 2.4280e+00, 2.3979e+00, 2.3685e+00, 2.3395e+00, 2.3110e+00, 2.2830e+00, 2.2556e+00, 2.2289e+00, 2.2028e+00, 2.1774e+00, 2.1524e+00, 2.1278e+00, 2.1036e+00, 2.0798e+00, 2.0566e+00, 2.0340e+00, 2.0121e+00, 1.9907e+00, 1.9698e+00, 1.9492e+00, 1.9289e+00, 1.9088e+00, 1.8892e+00, 1.8702e+00, 1.8517e+00, 1.8338e+00, 1.8165e+00, 1.7994e+00, 1.7826e+00, 1.7660e+00, 1.7495e+00, 1.7334e+00, 1.7177e+00, 1.7026e+00, 1.6881e+00, 1.6741e+00, 1.6604e+00, 1.6468e+00, 1.6333e+00, 1.6199e+00, 1.6066e+00, 1.5935e+00, 1.5810e+00, 1.5690e+00, 1.5576e+00, 1.5466e+00, 1.5358e+00, 1.5251e+00, 1.5143e+00, 1.5034e+00, 1.4925e+00, 1.4819e+00, 1.4717e+00, 1.4619e+00, 1.4528e+00, 1.4441e+00, 1.4356e+00, 1.4273e+00, 1.4187e+00, 1.4100e+00, 1.4012e+00, 1.3923e+00, 1.3836e+00, 1.3754e+00, 1.3676e+00, 1.3605e+00, 1.3537e+00, 1.3472e+00, 1.3407e+00, 1.3340e+00, 1.3270e+00, 1.3197e+00, 1.3122e+00, 1.3049e+00, 1.2979e+00, 1.2913e+00, 1.2853e+00, 1.2799e+00, 1.2748e+00, 1.2698e+00, 1.2646e+00, 1.2592e+00, 1.2533e+00, 1.2471e+00, 1.2407e+00, 1.2344e+00, 1.2283e+00, 1.2227e+00, 1.2177e+00, 1.2133e+00, 1.2092e+00, 1.2053e+00, 1.2013e+00, 1.1970e+00, 1.1923e+00, 1.1870e+00, 1.1814e+00, 1.1757e+00, 1.1701e+00, 1.1648e+00, 1.1601e+00, 1.1559e+00, 1.1522e+00}); + feg = Vctr_cpu({6.8983e+00, 6.8398e+00, 6.6699e+00, 6.4040e+00, 6.0641e+00, 5.6751e+00, 5.2608e+00, 4.8419e+00, 4.4339e+00, 4.0479e+00, 3.6903e+00, 3.3644e+00, 3.0707e+00, 2.8083e+00, 2.5752e+00, 2.3686e+00, 2.1858e+00, 2.0241e+00, 1.8807e+00, 1.7534e+00, 1.6399e+00, 1.5384e+00, 1.4472e+00, 1.3648e+00, 1.2902e+00, 1.2222e+00, 1.1600e+00, 1.1028e+00, 1.0500e+00, 1.0011e+00, 9.5560e-01, 9.1310e-01, 8.7340e-01, 8.3620e-01, 8.0120e-01, 7.6820e-01, 7.3710e-01, 7.0760e-01, 6.7970e-01, 6.5330e-01, 6.2820e-01, 6.0440e-01, 5.8180e-01, 5.6030e-01, 5.3980e-01, 5.2030e-01, 5.0170e-01, 4.8400e-01, 4.6710e-01, 4.5100e-01, 4.3560e-01, 4.2090e-01, 4.0690e-01, 3.9360e-01, 3.8080e-01, 3.6860e-01, 3.5690e-01, 3.4570e-01, 3.3510e-01, 3.2480e-01, 3.1510e-01, 3.0570e-01, 2.9680e-01, 2.8820e-01, 2.7990e-01, 2.7210e-01, 2.6450e-01, 2.5720e-01, 2.5030e-01, 2.4360e-01, 2.3720e-01, 2.3100e-01, 2.2510e-01, 2.1940e-01, 2.1390e-01, 2.0860e-01, 2.0360e-01, 1.9870e-01, 1.9400e-01, 1.8940e-01, 1.8510e-01, 1.8080e-01, 1.7680e-01, 1.7280e-01, 1.6900e-01, 1.6540e-01, 1.6180e-01, 1.5840e-01, 1.5510e-01, 1.5190e-01, 1.4880e-01, 1.4580e-01, 1.4290e-01, 1.4000e-01, 1.3730e-01, 1.3470e-01, 1.3210e-01, 1.2960e-01, 1.2720e-01, 1.2480e-01, 1.2250e-01, 1.2030e-01, 1.1810e-01, 1.1600e-01, 1.1400e-01, 1.1200e-01, 1.1010e-01, 1.0820e-01, 1.0630e-01, 1.0450e-01, 1.0280e-01, 1.0110e-01, 9.9400e-02, 9.7800e-02, 9.6300e-02, 9.4700e-02, 9.3200e-02, 9.1800e-02, 9.0300e-02, 8.8900e-02, 8.7600e-02, 8.6200e-02, 8.4900e-02, 8.3600e-02, 8.2400e-02, 8.1200e-02, 8.0000e-02, 7.8800e-02, 7.7700e-02, 7.6600e-02, 7.5500e-02, 7.4400e-02, 7.3400e-02, 7.2300e-02, 7.1300e-02, 7.0300e-02, 6.9400e-02, 6.8400e-02, 6.7500e-02, 6.6600e-02, 6.5700e-02, 6.4800e-02, 6.4000e-02, 6.3100e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9200e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5600e-02, 5.4900e-02, 5.4200e-02, 5.3500e-02, 5.2900e-02, 5.2300e-02, 5.1600e-02, 5.1000e-02, 5.0400e-02, 4.9800e-02, 4.9200e-02, 4.8700e-02, 4.8100e-02, 4.7600e-02, 4.7000e-02, 4.6500e-02, 4.5900e-02, 4.5400e-02, 4.4900e-02, 4.4400e-02, 4.3900e-02, 4.3400e-02, 4.3000e-02, 4.2500e-02, 4.2000e-02, 4.1600e-02, 4.1100e-02, 4.0700e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7400e-02, 3.7000e-02, 3.6600e-02, 3.6300e-02, 3.5900e-02, 3.5500e-02, 3.5200e-02, 3.4800e-02, 3.4500e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02, 2.6800e-02, 2.6500e-02, 2.6300e-02, 2.6100e-02, 2.5900e-02, 2.5600e-02, 2.5400e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4600e-02, 2.4400e-02, 2.4100e-02, 2.3900e-02, 2.3700e-02, 2.3600e-02, 2.3400e-02, 2.3200e-02}); + } + break; + case 37: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.7000e+01, 3.6706e+01, 3.5950e+01, 3.4967e+01, 3.3907e+01, 3.2811e+01, 3.1680e+01, 3.0525e+01, 2.9368e+01, 2.8235e+01, 2.7147e+01, 2.6119e+01, 2.5158e+01, 2.4263e+01, 2.3432e+01, 2.2658e+01, 2.1934e+01, 2.1252e+01, 2.0605e+01, 1.9986e+01, 1.9391e+01, 1.8814e+01, 1.8252e+01, 1.7704e+01, 1.7167e+01, 1.6641e+01, 1.6125e+01, 1.5620e+01, 1.5126e+01, 1.4643e+01, 1.4173e+01, 1.3715e+01, 1.3271e+01, 1.2842e+01, 1.2427e+01, 1.2027e+01, 1.1644e+01, 1.1276e+01, 1.0924e+01, 1.0589e+01, 1.0269e+01, 9.9654e+00, 9.6772e+00, 9.4042e+00, 9.1460e+00, 8.9021e+00, 8.6719e+00, 8.4550e+00, 8.2507e+00, 8.0584e+00, 7.8775e+00, 7.7074e+00, 7.5474e+00, 7.3970e+00, 7.2554e+00, 7.1222e+00, 6.9967e+00, 6.8785e+00, 6.7668e+00, 6.6612e+00, 6.5613e+00, 6.4666e+00, 6.3765e+00, 6.2908e+00, 6.2091e+00, 6.1307e+00, 6.0555e+00, 5.9834e+00, 5.9139e+00, 5.8465e+00, 5.7811e+00, 5.7179e+00, 5.6563e+00, 5.5958e+00, 5.5365e+00, 5.4787e+00, 5.4220e+00, 5.3658e+00, 5.3100e+00, 5.2552e+00, 5.2013e+00, 5.1477e+00, 5.0939e+00, 5.0406e+00, 4.9880e+00, 4.9360e+00, 4.8837e+00, 4.8312e+00, 4.7789e+00, 4.7275e+00, 4.6764e+00, 4.6250e+00, 4.5731e+00, 4.5215e+00, 4.4707e+00, 4.4204e+00, 4.3699e+00, 4.3189e+00, 4.2679e+00, 4.2177e+00, 4.1682e+00, 4.1190e+00, 4.0696e+00, 4.0197e+00, 3.9702e+00, 3.9216e+00, 3.8738e+00, 3.8263e+00, 3.7787e+00, 3.7307e+00, 3.6832e+00, 3.6367e+00, 3.5910e+00, 3.5459e+00, 3.5009e+00, 3.4556e+00, 3.4105e+00, 3.3663e+00, 3.3233e+00, 3.2809e+00, 3.2390e+00, 3.1973e+00, 3.1553e+00, 3.1137e+00, 3.0734e+00, 3.0340e+00, 2.9953e+00, 2.9573e+00, 2.9194e+00, 2.8813e+00, 2.8436e+00, 2.8071e+00, 2.7716e+00, 2.7367e+00, 2.7026e+00, 2.6690e+00, 2.6353e+00, 2.6015e+00, 2.5686e+00, 2.5369e+00, 2.5060e+00, 2.4756e+00, 2.4459e+00, 2.4169e+00, 2.3877e+00, 2.3583e+00, 2.3298e+00, 2.3025e+00, 2.2760e+00, 2.2498e+00, 2.2243e+00, 2.1996e+00, 2.1749e+00, 2.1499e+00, 2.1252e+00, 2.1016e+00, 2.0792e+00, 2.0571e+00, 2.0352e+00, 2.0140e+00, 1.9936e+00, 1.9732e+00, 1.9523e+00, 1.9316e+00, 1.9120e+00, 1.8936e+00, 1.8755e+00, 1.8574e+00, 1.8398e+00, 1.8231e+00, 1.8067e+00, 1.7897e+00, 1.7724e+00, 1.7558e+00, 1.7404e+00, 1.7259e+00, 1.7113e+00, 1.6966e+00, 1.6826e+00, 1.6693e+00, 1.6563e+00, 1.6426e+00, 1.6284e+00, 1.6147e+00, 1.6023e+00, 1.5908e+00, 1.5793e+00, 1.5676e+00, 1.5561e+00, 1.5455e+00, 1.5353e+00, 1.5248e+00, 1.5135e+00, 1.5019e+00, 1.4911e+00, 1.4816e+00, 1.4727e+00, 1.4636e+00, 1.4543e+00, 1.4453e+00, 1.4369e+00, 1.4291e+00, 1.4209e+00, 1.4119e+00, 1.4023e+00, 1.3932e+00, 1.3852e+00, 1.3782e+00, 1.3713e+00, 1.3640e+00, 1.3567e+00, 1.3497e+00, 1.3434e+00, 1.3373e+00, 1.3307e+00, 1.3233e+00, 1.3152e+00, 1.3076e+00, 1.3010e+00, 1.2955e+00, 1.2901e+00, 1.2844e+00, 1.2786e+00, 1.2730e+00, 1.2679e+00, 1.2631e+00, 1.2581e+00, 1.2523e+00, 1.2457e+00, 1.2387e+00, 1.2324e+00, 1.2272e+00, 1.2228e+00, 1.2185e+00, 1.2139e+00, 1.2092e+00, 1.2047e+00, 1.2006e+00, 1.1968e+00, 1.1928e+00, 1.1881e+00}); + feg = Vctr_cpu({1.1723e+01, 1.1245e+01, 1.0055e+01, 8.6511e+00, 7.4017e+00, 6.4165e+00, 5.6588e+00, 5.0604e+00, 4.5667e+00, 4.1439e+00, 3.7730e+00, 3.4435e+00, 3.1492e+00, 2.8861e+00, 2.6509e+00, 2.4409e+00, 2.2537e+00, 2.0867e+00, 1.9377e+00, 1.8048e+00, 1.6858e+00, 1.5792e+00, 1.4833e+00, 1.3968e+00, 1.3185e+00, 1.2474e+00, 1.1825e+00, 1.1231e+00, 1.0684e+00, 1.0180e+00, 9.7130e-01, 9.2790e-01, 8.8740e-01, 8.4950e-01, 8.1400e-01, 7.8070e-01, 7.4920e-01, 7.1960e-01, 6.9150e-01, 6.6500e-01, 6.3980e-01, 6.1590e-01, 5.9310e-01, 5.7150e-01, 5.5090e-01, 5.3130e-01, 5.1270e-01, 4.9480e-01, 4.7780e-01, 4.6160e-01, 4.4610e-01, 4.3130e-01, 4.1710e-01, 4.0360e-01, 3.9060e-01, 3.7820e-01, 3.6640e-01, 3.5500e-01, 3.4420e-01, 3.3380e-01, 3.2380e-01, 3.1420e-01, 3.0510e-01, 2.9630e-01, 2.8790e-01, 2.7980e-01, 2.7200e-01, 2.6460e-01, 2.5740e-01, 2.5060e-01, 2.4400e-01, 2.3760e-01, 2.3150e-01, 2.2570e-01, 2.2000e-01, 2.1460e-01, 2.0940e-01, 2.0430e-01, 1.9950e-01, 1.9480e-01, 1.9030e-01, 1.8590e-01, 1.8170e-01, 1.7770e-01, 1.7370e-01, 1.6990e-01, 1.6630e-01, 1.6280e-01, 1.5930e-01, 1.5600e-01, 1.5280e-01, 1.4970e-01, 1.4670e-01, 1.4380e-01, 1.4100e-01, 1.3820e-01, 1.3560e-01, 1.3300e-01, 1.3050e-01, 1.2810e-01, 1.2570e-01, 1.2340e-01, 1.2120e-01, 1.1900e-01, 1.1690e-01, 1.1490e-01, 1.1290e-01, 1.1100e-01, 1.0910e-01, 1.0720e-01, 1.0540e-01, 1.0370e-01, 1.0200e-01, 1.0030e-01, 9.8700e-02, 9.7100e-02, 9.5600e-02, 9.4100e-02, 9.2600e-02, 9.1200e-02, 8.9800e-02, 8.8400e-02, 8.7100e-02, 8.5800e-02, 8.4500e-02, 8.3200e-02, 8.2000e-02, 8.0800e-02, 7.9700e-02, 7.8500e-02, 7.7400e-02, 7.6300e-02, 7.5200e-02, 7.4200e-02, 7.3100e-02, 7.2100e-02, 7.1100e-02, 7.0200e-02, 6.9200e-02, 6.8300e-02, 6.7400e-02, 6.6500e-02, 6.5600e-02, 6.4800e-02, 6.3900e-02, 6.3100e-02, 6.2300e-02, 6.1500e-02, 6.0700e-02, 5.9900e-02, 5.9200e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5600e-02, 5.4900e-02, 5.4300e-02, 5.3600e-02, 5.3000e-02, 5.2400e-02, 5.1700e-02, 5.1100e-02, 5.0500e-02, 5.0000e-02, 4.9400e-02, 4.8800e-02, 4.8300e-02, 4.7700e-02, 4.7200e-02, 4.6600e-02, 4.6100e-02, 4.5600e-02, 4.5100e-02, 4.4600e-02, 4.4100e-02, 4.3600e-02, 4.3200e-02, 4.2700e-02, 4.2200e-02, 4.1800e-02, 4.1300e-02, 4.0900e-02, 4.0500e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8800e-02, 3.8400e-02, 3.8000e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6500e-02, 3.6100e-02, 3.5800e-02, 3.5400e-02, 3.5100e-02, 3.4700e-02, 3.4400e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1200e-02, 3.1000e-02, 3.0700e-02, 3.0400e-02, 3.0100e-02, 2.9800e-02, 2.9600e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8500e-02, 2.8300e-02, 2.8000e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6300e-02, 2.6100e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5200e-02, 2.5000e-02, 2.4800e-02, 2.4600e-02, 2.4400e-02, 2.4200e-02, 2.4000e-02, 2.3800e-02}); + } + break; + case 38: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.8000e+01, 3.7671e+01, 3.6803e+01, 3.5659e+01, 3.4457e+01, 3.3292e+01, 3.2170e+01, 3.1073e+01, 2.9987e+01, 2.8914e+01, 2.7863e+01, 2.6846e+01, 2.5874e+01, 2.4954e+01, 2.4090e+01, 2.3280e+01, 2.2522e+01, 2.1811e+01, 2.1141e+01, 2.0506e+01, 1.9902e+01, 1.9323e+01, 1.8764e+01, 1.8223e+01, 1.7696e+01, 1.7181e+01, 1.6678e+01, 1.6185e+01, 1.5702e+01, 1.5229e+01, 1.4766e+01, 1.4313e+01, 1.3872e+01, 1.3442e+01, 1.3025e+01, 1.2620e+01, 1.2229e+01, 1.1852e+01, 1.1488e+01, 1.1139e+01, 1.0805e+01, 1.0485e+01, 1.0179e+01, 9.8880e+00, 9.6110e+00, 9.3479e+00, 9.0985e+00, 8.8621e+00, 8.6386e+00, 8.4274e+00, 8.2279e+00, 8.0396e+00, 7.8622e+00, 7.6950e+00, 7.5373e+00, 7.3888e+00, 7.2488e+00, 7.1168e+00, 6.9924e+00, 6.8749e+00, 6.7638e+00, 6.6588e+00, 6.5594e+00, 6.4651e+00, 6.3754e+00, 6.2901e+00, 6.2088e+00, 6.1309e+00, 6.0563e+00, 5.9848e+00, 5.9159e+00, 5.8494e+00, 5.7850e+00, 5.7225e+00, 5.6618e+00, 5.6028e+00, 5.5449e+00, 5.4881e+00, 5.4326e+00, 5.3781e+00, 5.3243e+00, 5.2710e+00, 5.2183e+00, 5.1664e+00, 5.1151e+00, 5.0639e+00, 5.0127e+00, 4.9620e+00, 4.9120e+00, 4.8622e+00, 4.8122e+00, 4.7620e+00, 4.7122e+00, 4.6630e+00, 4.6141e+00, 4.5649e+00, 4.5153e+00, 4.4660e+00, 4.4173e+00, 4.3692e+00, 4.3210e+00, 4.2722e+00, 4.2233e+00, 4.1750e+00, 4.1276e+00, 4.0806e+00, 4.0334e+00, 3.9857e+00, 3.9380e+00, 3.8911e+00, 3.8452e+00, 3.7999e+00, 3.7545e+00, 3.7086e+00, 3.6626e+00, 3.6174e+00, 3.5733e+00, 3.5303e+00, 3.4874e+00, 3.4441e+00, 3.4006e+00, 3.3574e+00, 3.3153e+00, 3.2745e+00, 3.2346e+00, 3.1947e+00, 3.1545e+00, 3.1143e+00, 3.0743e+00, 3.0355e+00, 2.9982e+00, 2.9619e+00, 2.9256e+00, 2.8891e+00, 2.8526e+00, 2.8162e+00, 2.7807e+00, 2.7466e+00, 2.7139e+00, 2.6817e+00, 2.6493e+00, 2.6169e+00, 2.5845e+00, 2.5524e+00, 2.5211e+00, 2.4915e+00, 2.4631e+00, 2.4350e+00, 2.4068e+00, 2.3786e+00, 2.3506e+00, 2.3226e+00, 2.2952e+00, 2.2692e+00, 2.2447e+00, 2.2209e+00, 2.1969e+00, 2.1728e+00, 2.1489e+00, 2.1251e+00, 2.1014e+00, 2.0783e+00, 2.0567e+00, 2.0365e+00, 2.0168e+00, 1.9967e+00, 1.9765e+00, 1.9565e+00, 1.9368e+00, 1.9170e+00, 1.8975e+00, 1.8792e+00, 1.8624e+00, 1.8464e+00, 1.8301e+00, 1.8134e+00, 1.7968e+00, 1.7807e+00, 1.7647e+00, 1.7484e+00, 1.7324e+00, 1.7177e+00, 1.7045e+00, 1.6918e+00, 1.6787e+00, 1.6650e+00, 1.6516e+00, 1.6386e+00, 1.6258e+00, 1.6127e+00, 1.5994e+00, 1.5869e+00, 1.5760e+00, 1.5661e+00, 1.5561e+00, 1.5454e+00, 1.5343e+00, 1.5235e+00, 1.5134e+00, 1.5033e+00, 1.4927e+00, 1.4818e+00, 1.4716e+00, 1.4630e+00, 1.4555e+00, 1.4480e+00, 1.4396e+00, 1.4305e+00, 1.4216e+00, 1.4135e+00, 1.4057e+00, 1.3975e+00, 1.3885e+00, 1.3797e+00, 1.3719e+00, 1.3657e+00, 1.3602e+00, 1.3543e+00, 1.3474e+00, 1.3399e+00, 1.3327e+00, 1.3262e+00, 1.3201e+00, 1.3136e+00, 1.3063e+00, 1.2987e+00, 1.2919e+00, 1.2866e+00, 1.2824e+00, 1.2783e+00, 1.2733e+00, 1.2673e+00, 1.2609e+00, 1.2552e+00, 1.2501e+00, 1.2452e+00, 1.2397e+00, 1.2334e+00, 1.2269e+00, 1.2211e+00, 1.2167e+00}); + feg = Vctr_cpu({1.3049e+01, 1.2610e+01, 1.1456e+01, 9.9599e+00, 8.4789e+00, 7.2114e+00, 6.2013e+00, 5.4136e+00, 4.7944e+00, 4.2956e+00, 3.8820e+00, 3.5300e+00, 3.2247e+00, 2.9560e+00, 2.7177e+00, 2.5053e+00, 2.3153e+00, 2.1452e+00, 1.9926e+00, 1.8557e+00, 1.7326e+00, 1.6218e+00, 1.5219e+00, 1.4316e+00, 1.3499e+00, 1.2756e+00, 1.2078e+00, 1.1459e+00, 1.0891e+00, 1.0369e+00, 9.8860e-01, 9.4390e-01, 9.0230e-01, 8.6360e-01, 8.2730e-01, 7.9340e-01, 7.6150e-01, 7.3140e-01, 7.0310e-01, 6.7630e-01, 6.5090e-01, 6.2680e-01, 6.0400e-01, 5.8220e-01, 5.6150e-01, 5.4180e-01, 5.2300e-01, 5.0510e-01, 4.8800e-01, 4.7170e-01, 4.5600e-01, 4.4110e-01, 4.2680e-01, 4.1310e-01, 4.0000e-01, 3.8750e-01, 3.7550e-01, 3.6400e-01, 3.5300e-01, 3.4240e-01, 3.3230e-01, 3.2250e-01, 3.1320e-01, 3.0430e-01, 2.9570e-01, 2.8740e-01, 2.7950e-01, 2.7190e-01, 2.6450e-01, 2.5750e-01, 2.5070e-01, 2.4420e-01, 2.3800e-01, 2.3190e-01, 2.2610e-01, 2.2060e-01, 2.1520e-01, 2.1000e-01, 2.0500e-01, 2.0020e-01, 1.9550e-01, 1.9100e-01, 1.8670e-01, 1.8250e-01, 1.7850e-01, 1.7460e-01, 1.7080e-01, 1.6710e-01, 1.6360e-01, 1.6020e-01, 1.5690e-01, 1.5370e-01, 1.5060e-01, 1.4760e-01, 1.4470e-01, 1.4190e-01, 1.3910e-01, 1.3650e-01, 1.3390e-01, 1.3140e-01, 1.2900e-01, 1.2660e-01, 1.2430e-01, 1.2210e-01, 1.1990e-01, 1.1780e-01, 1.1580e-01, 1.1380e-01, 1.1180e-01, 1.0990e-01, 1.0810e-01, 1.0630e-01, 1.0450e-01, 1.0280e-01, 1.0120e-01, 9.9600e-02, 9.8000e-02, 9.6400e-02, 9.4900e-02, 9.3400e-02, 9.2000e-02, 9.0600e-02, 8.9200e-02, 8.7900e-02, 8.6600e-02, 8.5300e-02, 8.4000e-02, 8.2800e-02, 8.1600e-02, 8.0500e-02, 7.9300e-02, 7.8200e-02, 7.7100e-02, 7.6000e-02, 7.5000e-02, 7.3900e-02, 7.2900e-02, 7.1900e-02, 7.1000e-02, 7.0000e-02, 6.9100e-02, 6.8200e-02, 6.7300e-02, 6.6400e-02, 6.5500e-02, 6.4700e-02, 6.3800e-02, 6.3000e-02, 6.2200e-02, 6.1400e-02, 6.0700e-02, 5.9900e-02, 5.9200e-02, 5.8500e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4300e-02, 5.3700e-02, 5.3100e-02, 5.2400e-02, 5.1800e-02, 5.1200e-02, 5.0600e-02, 5.0100e-02, 4.9500e-02, 4.8900e-02, 4.8400e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5700e-02, 4.5200e-02, 4.4800e-02, 4.4300e-02, 4.3800e-02, 4.3300e-02, 4.2900e-02, 4.2400e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4600e-02, 3.4300e-02, 3.4000e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2700e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0300e-02, 3.0100e-02, 2.9800e-02, 2.9500e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8500e-02, 2.8300e-02, 2.8000e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02, 2.6100e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5300e-02, 2.5100e-02, 2.4900e-02, 2.4700e-02, 2.4500e-02}); + } + break; + case 39: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({3.9000e+01, 3.8679e+01, 3.7817e+01, 3.6641e+01, 3.5365e+01, 3.4108e+01, 3.2905e+01, 3.1752e+01, 3.0635e+01, 2.9547e+01, 2.8490e+01, 2.7468e+01, 2.6489e+01, 2.5558e+01, 2.4679e+01, 2.3853e+01, 2.3077e+01, 2.2350e+01, 2.1666e+01, 2.1021e+01, 2.0410e+01, 1.9828e+01, 1.9270e+01, 1.8732e+01, 1.8211e+01, 1.7704e+01, 1.7210e+01, 1.6727e+01, 1.6253e+01, 1.5789e+01, 1.5334e+01, 1.4888e+01, 1.4451e+01, 1.4024e+01, 1.3607e+01, 1.3201e+01, 1.2806e+01, 1.2423e+01, 1.2052e+01, 1.1693e+01, 1.1348e+01, 1.1015e+01, 1.0695e+01, 1.0389e+01, 1.0096e+01, 9.8165e+00, 9.5498e+00, 9.2959e+00, 9.0545e+00, 8.8254e+00, 8.6082e+00, 8.4024e+00, 8.2077e+00, 8.0235e+00, 7.8495e+00, 7.6851e+00, 7.5299e+00, 7.3833e+00, 7.2450e+00, 7.1143e+00, 6.9909e+00, 6.8742e+00, 6.7639e+00, 6.6594e+00, 6.5603e+00, 6.4664e+00, 6.3771e+00, 6.2920e+00, 6.2109e+00, 6.1335e+00, 6.0593e+00, 5.9882e+00, 5.9197e+00, 5.8537e+00, 5.7900e+00, 5.7284e+00, 5.6684e+00, 5.6100e+00, 5.5532e+00, 5.4977e+00, 5.4433e+00, 5.3898e+00, 5.3371e+00, 5.2854e+00, 5.2345e+00, 5.1839e+00, 5.1337e+00, 5.0840e+00, 5.0350e+00, 4.9864e+00, 4.9377e+00, 4.8890e+00, 4.8407e+00, 4.7930e+00, 4.7456e+00, 4.6979e+00, 4.6500e+00, 4.6022e+00, 4.5551e+00, 4.5084e+00, 4.4616e+00, 4.4144e+00, 4.3670e+00, 4.3201e+00, 4.2739e+00, 4.2281e+00, 4.1820e+00, 4.1354e+00, 4.0888e+00, 4.0428e+00, 3.9978e+00, 3.9532e+00, 3.9084e+00, 3.8632e+00, 3.8178e+00, 3.7730e+00, 3.7294e+00, 3.6865e+00, 3.6438e+00, 3.6006e+00, 3.5571e+00, 3.5139e+00, 3.4717e+00, 3.4308e+00, 3.3905e+00, 3.3503e+00, 3.3097e+00, 3.2688e+00, 3.2284e+00, 3.1890e+00, 3.1510e+00, 3.1139e+00, 3.0769e+00, 3.0395e+00, 3.0020e+00, 2.9646e+00, 2.9281e+00, 2.8930e+00, 2.8592e+00, 2.8259e+00, 2.7924e+00, 2.7587e+00, 2.7249e+00, 2.6914e+00, 2.6589e+00, 2.6279e+00, 2.5982e+00, 2.5688e+00, 2.5394e+00, 2.5097e+00, 2.4799e+00, 2.4503e+00, 2.4215e+00, 2.3940e+00, 2.3681e+00, 2.3428e+00, 2.3175e+00, 2.2920e+00, 2.2664e+00, 2.2408e+00, 2.2154e+00, 2.1908e+00, 2.1677e+00, 2.1460e+00, 2.1248e+00, 2.1035e+00, 2.0819e+00, 2.0603e+00, 2.0387e+00, 2.0172e+00, 1.9962e+00, 1.9764e+00, 1.9582e+00, 1.9408e+00, 1.9233e+00, 1.9055e+00, 1.8876e+00, 1.8698e+00, 1.8520e+00, 1.8341e+00, 1.8167e+00, 1.8007e+00, 1.7862e+00, 1.7723e+00, 1.7582e+00, 1.7436e+00, 1.7290e+00, 1.7145e+00, 1.7001e+00, 1.6855e+00, 1.6709e+00, 1.6574e+00, 1.6453e+00, 1.6344e+00, 1.6235e+00, 1.6120e+00, 1.6001e+00, 1.5883e+00, 1.5768e+00, 1.5653e+00, 1.5533e+00, 1.5414e+00, 1.5304e+00, 1.5209e+00, 1.5125e+00, 1.5042e+00, 1.4952e+00, 1.4856e+00, 1.4760e+00, 1.4669e+00, 1.4578e+00, 1.4484e+00, 1.4386e+00, 1.4290e+00, 1.4206e+00, 1.4136e+00, 1.4075e+00, 1.4011e+00, 1.3939e+00, 1.3860e+00, 1.3782e+00, 1.3709e+00, 1.3639e+00, 1.3564e+00, 1.3483e+00, 1.3402e+00, 1.3329e+00, 1.3271e+00, 1.3225e+00, 1.3179e+00, 1.3127e+00, 1.3064e+00, 1.2998e+00, 1.2936e+00, 1.2879e+00, 1.2823e+00, 1.2761e+00, 1.2693e+00, 1.2623e+00, 1.2562e+00, 1.2515e+00}); + feg = Vctr_cpu({1.2636e+01, 1.2279e+01, 1.1322e+01, 1.0036e+01, 8.7004e+00, 7.4937e+00, 6.4830e+00, 5.6642e+00, 5.0051e+00, 4.4689e+00, 4.0248e+00, 3.6496e+00, 3.3271e+00, 3.0458e+00, 2.7980e+00, 2.5780e+00, 2.3818e+00, 2.2062e+00, 2.0487e+00, 1.9071e+00, 1.7797e+00, 1.6648e+00, 1.5611e+00, 1.4672e+00, 1.3821e+00, 1.3048e+00, 1.2343e+00, 1.1700e+00, 1.1110e+00, 1.0569e+00, 1.0070e+00, 9.6080e-01, 9.1800e-01, 8.7830e-01, 8.4120e-01, 8.0650e-01, 7.7400e-01, 7.4340e-01, 7.1460e-01, 6.8750e-01, 6.6180e-01, 6.3750e-01, 6.1450e-01, 5.9250e-01, 5.7170e-01, 5.5190e-01, 5.3300e-01, 5.1490e-01, 4.9770e-01, 4.8130e-01, 4.6550e-01, 4.5050e-01, 4.3610e-01, 4.2230e-01, 4.0910e-01, 3.9640e-01, 3.8430e-01, 3.7260e-01, 3.6150e-01, 3.5080e-01, 3.4050e-01, 3.3060e-01, 3.2110e-01, 3.1200e-01, 3.0330e-01, 2.9490e-01, 2.8680e-01, 2.7900e-01, 2.7150e-01, 2.6440e-01, 2.5740e-01, 2.5080e-01, 2.4440e-01, 2.3820e-01, 2.3220e-01, 2.2650e-01, 2.2100e-01, 2.1570e-01, 2.1050e-01, 2.0560e-01, 2.0080e-01, 1.9620e-01, 1.9170e-01, 1.8740e-01, 1.8330e-01, 1.7920e-01, 1.7530e-01, 1.7160e-01, 1.6800e-01, 1.6440e-01, 1.6100e-01, 1.5770e-01, 1.5450e-01, 1.5150e-01, 1.4850e-01, 1.4550e-01, 1.4270e-01, 1.4000e-01, 1.3730e-01, 1.3480e-01, 1.3230e-01, 1.2980e-01, 1.2750e-01, 1.2520e-01, 1.2290e-01, 1.2080e-01, 1.1870e-01, 1.1660e-01, 1.1460e-01, 1.1270e-01, 1.1080e-01, 1.0890e-01, 1.0710e-01, 1.0540e-01, 1.0370e-01, 1.0200e-01, 1.0040e-01, 9.8800e-02, 9.7200e-02, 9.5700e-02, 9.4300e-02, 9.2800e-02, 9.1400e-02, 9.0000e-02, 8.8700e-02, 8.7400e-02, 8.6100e-02, 8.4800e-02, 8.3600e-02, 8.2400e-02, 8.1200e-02, 8.0100e-02, 7.9000e-02, 7.7800e-02, 7.6800e-02, 7.5700e-02, 7.4700e-02, 7.3700e-02, 7.2700e-02, 7.1700e-02, 7.0700e-02, 6.9800e-02, 6.8900e-02, 6.8000e-02, 6.7100e-02, 6.6200e-02, 6.5400e-02, 6.4600e-02, 6.3700e-02, 6.2900e-02, 6.2200e-02, 6.1400e-02, 6.0600e-02, 5.9900e-02, 5.9100e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4400e-02, 5.3700e-02, 5.3100e-02, 5.2500e-02, 5.1900e-02, 5.1300e-02, 5.0700e-02, 5.0100e-02, 4.9600e-02, 4.9000e-02, 4.8500e-02, 4.7900e-02, 4.7400e-02, 4.6900e-02, 4.6400e-02, 4.5900e-02, 4.5400e-02, 4.4900e-02, 4.4400e-02, 4.3900e-02, 4.3500e-02, 4.3000e-02, 4.2600e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.0800e-02, 4.0400e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8800e-02, 3.8400e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.6900e-02, 3.6600e-02, 3.6200e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4800e-02, 3.4500e-02, 3.4200e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2000e-02, 3.1700e-02, 3.1400e-02, 3.1100e-02, 3.0900e-02, 3.0600e-02, 3.0300e-02, 3.0000e-02, 2.9800e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7800e-02, 2.7500e-02, 2.7300e-02, 2.7100e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02, 2.5500e-02, 2.5300e-02, 2.5100e-02}); + } + break; + case 40: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.0000e+01, 3.9690e+01, 3.8846e+01, 3.7667e+01, 3.6353e+01, 3.5031e+01, 3.3754e+01, 3.2533e+01, 3.1361e+01, 3.0231e+01, 2.9143e+01, 2.8097e+01, 2.7097e+01, 2.6147e+01, 2.5250e+01, 2.4406e+01, 2.3614e+01, 2.2871e+01, 2.2174e+01, 2.1518e+01, 2.0900e+01, 2.0313e+01, 1.9753e+01, 1.9217e+01, 1.8700e+01, 1.8200e+01, 1.7713e+01, 1.7239e+01, 1.6775e+01, 1.6320e+01, 1.5873e+01, 1.5435e+01, 1.5005e+01, 1.4583e+01, 1.4169e+01, 1.3765e+01, 1.3370e+01, 1.2985e+01, 1.2610e+01, 1.2245e+01, 1.1892e+01, 1.1550e+01, 1.1221e+01, 1.0903e+01, 1.0597e+01, 1.0303e+01, 1.0021e+01, 9.7522e+00, 9.4949e+00, 9.2495e+00, 9.0157e+00, 8.7933e+00, 8.5819e+00, 8.3813e+00, 8.1910e+00, 8.0107e+00, 7.8400e+00, 7.6783e+00, 7.5254e+00, 7.3808e+00, 7.2440e+00, 7.1146e+00, 6.9921e+00, 6.8763e+00, 6.7665e+00, 6.6625e+00, 6.5638e+00, 6.4701e+00, 6.3811e+00, 6.2962e+00, 6.2153e+00, 6.1381e+00, 6.0642e+00, 5.9932e+00, 5.9251e+00, 5.8596e+00, 5.7964e+00, 5.7351e+00, 5.6757e+00, 5.6181e+00, 5.5621e+00, 5.5074e+00, 5.4537e+00, 5.4011e+00, 5.3498e+00, 5.2994e+00, 5.2495e+00, 5.1999e+00, 5.1511e+00, 5.1031e+00, 5.0557e+00, 5.0083e+00, 4.9609e+00, 4.9138e+00, 4.8675e+00, 4.8216e+00, 4.7756e+00, 4.7292e+00, 4.6829e+00, 4.6372e+00, 4.5920e+00, 4.5470e+00, 4.5015e+00, 4.4557e+00, 4.4100e+00, 4.3650e+00, 4.3207e+00, 4.2763e+00, 4.2315e+00, 4.1863e+00, 4.1412e+00, 4.0969e+00, 4.0534e+00, 4.0102e+00, 3.9666e+00, 3.9224e+00, 3.8782e+00, 3.8348e+00, 3.7923e+00, 3.7505e+00, 3.7088e+00, 3.6667e+00, 3.6241e+00, 3.5817e+00, 3.5403e+00, 3.5000e+00, 3.4605e+00, 3.4211e+00, 3.3813e+00, 3.3411e+00, 3.3010e+00, 3.2619e+00, 3.2240e+00, 3.1872e+00, 3.1508e+00, 3.1142e+00, 3.0772e+00, 3.0399e+00, 3.0032e+00, 2.9678e+00, 2.9336e+00, 2.9003e+00, 2.8674e+00, 2.8344e+00, 2.8008e+00, 2.7671e+00, 2.7339e+00, 2.7020e+00, 2.6714e+00, 2.6417e+00, 2.6127e+00, 2.5837e+00, 2.5543e+00, 2.5244e+00, 2.4946e+00, 2.4659e+00, 2.4385e+00, 2.4123e+00, 2.3868e+00, 2.3618e+00, 2.3369e+00, 2.3115e+00, 2.2855e+00, 2.2597e+00, 2.2349e+00, 2.2115e+00, 2.1891e+00, 2.1674e+00, 2.1463e+00, 2.1254e+00, 2.1042e+00, 2.0824e+00, 2.0602e+00, 2.0386e+00, 2.0183e+00, 1.9992e+00, 1.9808e+00, 1.9630e+00, 1.9456e+00, 1.9286e+00, 1.9112e+00, 1.8930e+00, 1.8744e+00, 1.8563e+00, 1.8393e+00, 1.8236e+00, 1.8086e+00, 1.7940e+00, 1.7798e+00, 1.7661e+00, 1.7524e+00, 1.7380e+00, 1.7228e+00, 1.7074e+00, 1.6928e+00, 1.6794e+00, 1.6670e+00, 1.6551e+00, 1.6434e+00, 1.6321e+00, 1.6213e+00, 1.6106e+00, 1.5994e+00, 1.5872e+00, 1.5744e+00, 1.5621e+00, 1.5510e+00, 1.5410e+00, 1.5316e+00, 1.5223e+00, 1.5131e+00, 1.5044e+00, 1.4961e+00, 1.4879e+00, 1.4789e+00, 1.4689e+00, 1.4583e+00, 1.4481e+00, 1.4392e+00, 1.4314e+00, 1.4242e+00, 1.4169e+00, 1.4096e+00, 1.4026e+00, 1.3961e+00, 1.3899e+00, 1.3834e+00, 1.3758e+00, 1.3672e+00, 1.3583e+00, 1.3501e+00, 1.3433e+00, 1.3375e+00, 1.3320e+00, 1.3263e+00, 1.3204e+00, 1.3148e+00, 1.3097e+00, 1.3051e+00, 1.3002e+00, 1.2944e+00}); + feg = Vctr_cpu({1.2165e+01, 1.1863e+01, 1.1044e+01, 9.9245e+00, 8.7288e+00, 7.6117e+00, 6.6437e+00, 5.8355e+00, 5.1692e+00, 4.6183e+00, 4.1577e+00, 3.7671e+00, 3.4313e+00, 3.1389e+00, 2.8818e+00, 2.6540e+00, 2.4512e+00, 2.2697e+00, 2.1069e+00, 1.9605e+00, 1.8286e+00, 1.7095e+00, 1.6019e+00, 1.5045e+00, 1.4161e+00, 1.3357e+00, 1.2625e+00, 1.1956e+00, 1.1344e+00, 1.0783e+00, 1.0266e+00, 9.7890e-01, 9.3470e-01, 8.9380e-01, 8.5570e-01, 8.2010e-01, 7.8690e-01, 7.5570e-01, 7.2640e-01, 6.9880e-01, 6.7270e-01, 6.4810e-01, 6.2480e-01, 6.0260e-01, 5.8160e-01, 5.6160e-01, 5.4250e-01, 5.2440e-01, 5.0700e-01, 4.9040e-01, 4.7460e-01, 4.5940e-01, 4.4490e-01, 4.3100e-01, 4.1770e-01, 4.0500e-01, 3.9270e-01, 3.8100e-01, 3.6970e-01, 3.5880e-01, 3.4840e-01, 3.3840e-01, 3.2880e-01, 3.1960e-01, 3.1070e-01, 3.0220e-01, 2.9390e-01, 2.8600e-01, 2.7840e-01, 2.7110e-01, 2.6400e-01, 2.5720e-01, 2.5070e-01, 2.4440e-01, 2.3830e-01, 2.3240e-01, 2.2680e-01, 2.2130e-01, 2.1600e-01, 2.1100e-01, 2.0610e-01, 2.0130e-01, 1.9670e-01, 1.9230e-01, 1.8810e-01, 1.8390e-01, 1.7990e-01, 1.7610e-01, 1.7230e-01, 1.6870e-01, 1.6520e-01, 1.6180e-01, 1.5850e-01, 1.5530e-01, 1.5230e-01, 1.4930e-01, 1.4640e-01, 1.4350e-01, 1.4080e-01, 1.3820e-01, 1.3560e-01, 1.3310e-01, 1.3070e-01, 1.2830e-01, 1.2600e-01, 1.2380e-01, 1.2160e-01, 1.1950e-01, 1.1740e-01, 1.1540e-01, 1.1350e-01, 1.1160e-01, 1.0970e-01, 1.0790e-01, 1.0620e-01, 1.0450e-01, 1.0280e-01, 1.0120e-01, 9.9600e-02, 9.8000e-02, 9.6500e-02, 9.5000e-02, 9.3600e-02, 9.2200e-02, 9.0800e-02, 8.9500e-02, 8.8100e-02, 8.6800e-02, 8.5600e-02, 8.4400e-02, 8.3200e-02, 8.2000e-02, 8.0800e-02, 7.9700e-02, 7.8600e-02, 7.7500e-02, 7.6400e-02, 7.5400e-02, 7.4400e-02, 7.3400e-02, 7.2400e-02, 7.1500e-02, 7.0500e-02, 6.9600e-02, 6.8700e-02, 6.7800e-02, 6.6900e-02, 6.6100e-02, 6.5300e-02, 6.4400e-02, 6.3600e-02, 6.2800e-02, 6.2100e-02, 6.1300e-02, 6.0600e-02, 5.9800e-02, 5.9100e-02, 5.8400e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3200e-02, 5.2500e-02, 5.1900e-02, 5.1400e-02, 5.0800e-02, 5.0200e-02, 4.9700e-02, 4.9100e-02, 4.8600e-02, 4.8000e-02, 4.7500e-02, 4.7000e-02, 4.6500e-02, 4.6000e-02, 4.5500e-02, 4.5000e-02, 4.4500e-02, 4.4100e-02, 4.3600e-02, 4.3200e-02, 4.2700e-02, 4.2300e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0600e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8600e-02, 3.8200e-02, 3.7800e-02, 3.7500e-02, 3.7100e-02, 3.6700e-02, 3.6400e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1400e-02, 3.1100e-02, 3.0800e-02, 3.0500e-02, 3.0300e-02, 3.0000e-02, 2.9700e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02, 2.6200e-02, 2.5900e-02, 2.5700e-02}); + } + break; + case 41: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.1000e+01, 4.0726e+01, 3.9967e+01, 3.8871e+01, 3.7595e+01, 3.6251e+01, 3.4902e+01, 3.3579e+01, 3.2295e+01, 3.1060e+01, 2.9879e+01, 2.8757e+01, 2.7696e+01, 2.6700e+01, 2.5767e+01, 2.4897e+01, 2.4086e+01, 2.3331e+01, 2.2626e+01, 2.1966e+01, 2.1346e+01, 2.0760e+01, 2.0204e+01, 1.9674e+01, 1.9165e+01, 1.8673e+01, 1.8196e+01, 1.7731e+01, 1.7277e+01, 1.6831e+01, 1.6394e+01, 1.5964e+01, 1.5542e+01, 1.5126e+01, 1.4718e+01, 1.4317e+01, 1.3923e+01, 1.3538e+01, 1.3162e+01, 1.2794e+01, 1.2436e+01, 1.2088e+01, 1.1750e+01, 1.1423e+01, 1.1107e+01, 1.0802e+01, 1.0508e+01, 1.0225e+01, 9.9538e+00, 9.6939e+00, 9.4451e+00, 9.2074e+00, 8.9806e+00, 8.7644e+00, 8.5586e+00, 8.3629e+00, 8.1769e+00, 8.0003e+00, 7.8327e+00, 7.6739e+00, 7.5233e+00, 7.3806e+00, 7.2454e+00, 7.1173e+00, 6.9959e+00, 6.8808e+00, 6.7717e+00, 6.6682e+00, 6.5699e+00, 6.4765e+00, 6.3876e+00, 6.3030e+00, 6.2222e+00, 6.1450e+00, 6.0712e+00, 6.0005e+00, 5.9326e+00, 5.8672e+00, 5.8041e+00, 5.7432e+00, 5.6844e+00, 5.6273e+00, 5.5716e+00, 5.5174e+00, 5.4646e+00, 5.4131e+00, 5.3624e+00, 5.3124e+00, 5.2634e+00, 5.2153e+00, 5.1679e+00, 5.1208e+00, 5.0740e+00, 5.0277e+00, 4.9821e+00, 4.9369e+00, 4.8918e+00, 4.8467e+00, 4.8017e+00, 4.7571e+00, 4.7131e+00, 4.6691e+00, 4.6250e+00, 4.5806e+00, 4.5365e+00, 4.4928e+00, 4.4495e+00, 4.4062e+00, 4.3627e+00, 4.3189e+00, 4.2752e+00, 4.2321e+00, 4.1894e+00, 4.1470e+00, 4.1043e+00, 4.0613e+00, 4.0183e+00, 3.9757e+00, 3.9339e+00, 3.8925e+00, 3.8512e+00, 3.8096e+00, 3.7678e+00, 3.7261e+00, 3.6851e+00, 3.6450e+00, 3.6053e+00, 3.5659e+00, 3.5261e+00, 3.4862e+00, 3.4464e+00, 3.4074e+00, 3.3692e+00, 3.3318e+00, 3.2948e+00, 3.2577e+00, 3.2204e+00, 3.1830e+00, 3.1461e+00, 3.1102e+00, 3.0752e+00, 3.0409e+00, 3.0070e+00, 2.9731e+00, 2.9389e+00, 2.9046e+00, 2.8709e+00, 2.8382e+00, 2.8065e+00, 2.7755e+00, 2.7451e+00, 2.7148e+00, 2.6844e+00, 2.6536e+00, 2.6232e+00, 2.5935e+00, 2.5649e+00, 2.5373e+00, 2.5103e+00, 2.4838e+00, 2.4574e+00, 2.4307e+00, 2.4038e+00, 2.3771e+00, 2.3512e+00, 2.3264e+00, 2.3026e+00, 2.2794e+00, 2.2567e+00, 2.2342e+00, 2.2116e+00, 2.1886e+00, 2.1655e+00, 2.1428e+00, 2.1212e+00, 2.1007e+00, 2.0808e+00, 2.0616e+00, 2.0427e+00, 2.0241e+00, 2.0052e+00, 1.9859e+00, 1.9664e+00, 1.9472e+00, 1.9291e+00, 1.9120e+00, 1.8956e+00, 1.8797e+00, 1.8642e+00, 1.8490e+00, 1.8339e+00, 1.8183e+00, 1.8021e+00, 1.7859e+00, 1.7702e+00, 1.7557e+00, 1.7420e+00, 1.7289e+00, 1.7162e+00, 1.7038e+00, 1.6918e+00, 1.6798e+00, 1.6673e+00, 1.6542e+00, 1.6407e+00, 1.6276e+00, 1.6155e+00, 1.6044e+00, 1.5939e+00, 1.5837e+00, 1.5738e+00, 1.5641e+00, 1.5548e+00, 1.5454e+00, 1.5354e+00, 1.5247e+00, 1.5136e+00, 1.5028e+00, 1.4931e+00, 1.4843e+00, 1.4761e+00, 1.4681e+00, 1.4603e+00, 1.4527e+00, 1.4455e+00, 1.4384e+00, 1.4309e+00, 1.4226e+00, 1.4135e+00, 1.4043e+00, 1.3956e+00, 1.3880e+00, 1.3813e+00, 1.3751e+00, 1.3689e+00, 1.3627e+00, 1.3568e+00, 1.3513e+00, 1.3459e+00, 1.3402e+00, 1.3338e+00}); + feg = Vctr_cpu({1.0711e+01, 1.0491e+01, 9.8905e+00, 9.0584e+00, 8.1501e+00, 7.2749e+00, 6.4866e+00, 5.7997e+00, 5.2083e+00, 4.6992e+00, 4.2586e+00, 3.8748e+00, 3.5379e+00, 3.2403e+00, 2.9761e+00, 2.7406e+00, 2.5300e+00, 2.3413e+00, 2.1717e+00, 2.0191e+00, 1.8816e+00, 1.7575e+00, 1.6453e+00, 1.5438e+00, 1.4517e+00, 1.3680e+00, 1.2918e+00, 1.2223e+00, 1.1588e+00, 1.1005e+00, 1.0469e+00, 9.9760e-01, 9.5200e-01, 9.0980e-01, 8.7060e-01, 8.3410e-01, 8.0010e-01, 7.6820e-01, 7.3830e-01, 7.1010e-01, 6.8360e-01, 6.5860e-01, 6.3500e-01, 6.1260e-01, 5.9130e-01, 5.7110e-01, 5.5180e-01, 5.3350e-01, 5.1600e-01, 4.9930e-01, 4.8330e-01, 4.6810e-01, 4.5350e-01, 4.3950e-01, 4.2600e-01, 4.1320e-01, 4.0080e-01, 3.8890e-01, 3.7760e-01, 3.6660e-01, 3.5610e-01, 3.4600e-01, 3.3630e-01, 3.2690e-01, 3.1790e-01, 3.0920e-01, 3.0090e-01, 2.9290e-01, 2.8510e-01, 2.7770e-01, 2.7050e-01, 2.6360e-01, 2.5690e-01, 2.5050e-01, 2.4430e-01, 2.3830e-01, 2.3250e-01, 2.2690e-01, 2.2150e-01, 2.1630e-01, 2.1130e-01, 2.0650e-01, 2.0180e-01, 1.9720e-01, 1.9290e-01, 1.8860e-01, 1.8450e-01, 1.8060e-01, 1.7670e-01, 1.7300e-01, 1.6940e-01, 1.6590e-01, 1.6250e-01, 1.5930e-01, 1.5610e-01, 1.5300e-01, 1.5000e-01, 1.4710e-01, 1.4430e-01, 1.4160e-01, 1.3900e-01, 1.3640e-01, 1.3390e-01, 1.3150e-01, 1.2910e-01, 1.2680e-01, 1.2460e-01, 1.2240e-01, 1.2030e-01, 1.1820e-01, 1.1620e-01, 1.1430e-01, 1.1240e-01, 1.1050e-01, 1.0870e-01, 1.0700e-01, 1.0520e-01, 1.0360e-01, 1.0190e-01, 1.0030e-01, 9.8800e-02, 9.7300e-02, 9.5800e-02, 9.4300e-02, 9.2900e-02, 9.1600e-02, 9.0200e-02, 8.8900e-02, 8.7600e-02, 8.6300e-02, 8.5100e-02, 8.3900e-02, 8.2700e-02, 8.1500e-02, 8.0400e-02, 7.9300e-02, 7.8200e-02, 7.7200e-02, 7.6100e-02, 7.5100e-02, 7.4100e-02, 7.3100e-02, 7.2200e-02, 7.1200e-02, 7.0300e-02, 6.9400e-02, 6.8500e-02, 6.7600e-02, 6.6800e-02, 6.5900e-02, 6.5100e-02, 6.4300e-02, 6.3500e-02, 6.2700e-02, 6.2000e-02, 6.1200e-02, 6.0500e-02, 5.9800e-02, 5.9000e-02, 5.8300e-02, 5.7700e-02, 5.7000e-02, 5.6300e-02, 5.5700e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3200e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0800e-02, 5.0300e-02, 4.9700e-02, 4.9200e-02, 4.8600e-02, 4.8100e-02, 4.7600e-02, 4.7100e-02, 4.6600e-02, 4.6100e-02, 4.5600e-02, 4.5100e-02, 4.4700e-02, 4.4200e-02, 4.3700e-02, 4.3300e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0300e-02, 3.9900e-02, 3.9500e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8000e-02, 3.7600e-02, 3.7300e-02, 3.6900e-02, 3.6600e-02, 3.6200e-02, 3.5900e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2700e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0500e-02, 3.0200e-02, 2.9900e-02, 2.9700e-02, 2.9400e-02, 2.9200e-02, 2.8900e-02, 2.8700e-02, 2.8400e-02, 2.8200e-02, 2.8000e-02, 2.7700e-02, 2.7500e-02, 2.7300e-02, 2.7000e-02, 2.6800e-02, 2.6600e-02, 2.6400e-02}); + } + break; + case 42: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.2000e+01, 4.1736e+01, 4.1000e+01, 3.9922e+01, 3.8646e+01, 3.7280e+01, 3.5892e+01, 3.4519e+01, 3.3181e+01, 3.1890e+01, 3.0656e+01, 2.9483e+01, 2.8377e+01, 2.7338e+01, 2.6367e+01, 2.5462e+01, 2.4621e+01, 2.3838e+01, 2.3111e+01, 2.2433e+01, 2.1798e+01, 2.1203e+01, 2.0640e+01, 2.0107e+01, 1.9598e+01, 1.9109e+01, 1.8637e+01, 1.8179e+01, 1.7733e+01, 1.7297e+01, 1.6870e+01, 1.6450e+01, 1.6037e+01, 1.5630e+01, 1.5230e+01, 1.4836e+01, 1.4448e+01, 1.4067e+01, 1.3693e+01, 1.3326e+01, 1.2967e+01, 1.2617e+01, 1.2275e+01, 1.1943e+01, 1.1620e+01, 1.1307e+01, 1.1004e+01, 1.0711e+01, 1.0428e+01, 1.0156e+01, 9.8943e+00, 9.6432e+00, 9.4024e+00, 9.1719e+00, 8.9516e+00, 8.7412e+00, 8.5405e+00, 8.3493e+00, 8.1673e+00, 7.9941e+00, 7.8295e+00, 7.6731e+00, 7.5245e+00, 7.3836e+00, 7.2498e+00, 7.1228e+00, 7.0023e+00, 6.8880e+00, 6.7794e+00, 6.6762e+00, 6.5781e+00, 6.4849e+00, 6.3961e+00, 6.3115e+00, 6.2307e+00, 6.1536e+00, 6.0799e+00, 6.0091e+00, 5.9412e+00, 5.8760e+00, 5.8132e+00, 5.7526e+00, 5.6938e+00, 5.6369e+00, 5.5818e+00, 5.5283e+00, 5.4760e+00, 5.4248e+00, 5.3747e+00, 5.3258e+00, 5.2779e+00, 5.2305e+00, 5.1837e+00, 5.1376e+00, 5.0922e+00, 5.0474e+00, 5.0029e+00, 4.9585e+00, 4.9144e+00, 4.8708e+00, 4.8276e+00, 4.7847e+00, 4.7417e+00, 4.6986e+00, 4.6557e+00, 4.6132e+00, 4.5711e+00, 4.5290e+00, 4.4868e+00, 4.4443e+00, 4.4019e+00, 4.3600e+00, 4.3185e+00, 4.2771e+00, 4.2355e+00, 4.1936e+00, 4.1517e+00, 4.1102e+00, 4.0693e+00, 4.0287e+00, 3.9881e+00, 3.9473e+00, 3.9063e+00, 3.8654e+00, 3.8250e+00, 3.7853e+00, 3.7460e+00, 3.7069e+00, 3.6675e+00, 3.6279e+00, 3.5884e+00, 3.5495e+00, 3.5114e+00, 3.4740e+00, 3.4368e+00, 3.3996e+00, 3.3622e+00, 3.3247e+00, 3.2876e+00, 3.2513e+00, 3.2159e+00, 3.1811e+00, 3.1466e+00, 3.1121e+00, 3.0774e+00, 3.0426e+00, 3.0084e+00, 2.9749e+00, 2.9424e+00, 2.9106e+00, 2.8793e+00, 2.8481e+00, 2.8167e+00, 2.7851e+00, 2.7538e+00, 2.7232e+00, 2.6936e+00, 2.6649e+00, 2.6368e+00, 2.6091e+00, 2.5815e+00, 2.5537e+00, 2.5257e+00, 2.4979e+00, 2.4709e+00, 2.4449e+00, 2.4198e+00, 2.3954e+00, 2.3714e+00, 2.3476e+00, 2.3237e+00, 2.2995e+00, 2.2752e+00, 2.2513e+00, 2.2285e+00, 2.2066e+00, 2.1855e+00, 2.1649e+00, 2.1447e+00, 2.1247e+00, 2.1046e+00, 2.0840e+00, 2.0633e+00, 2.0430e+00, 2.0236e+00, 2.0052e+00, 1.9875e+00, 1.9704e+00, 1.9536e+00, 1.9372e+00, 1.9207e+00, 1.9039e+00, 1.8866e+00, 1.8693e+00, 1.8525e+00, 1.8368e+00, 1.8219e+00, 1.8077e+00, 1.7938e+00, 1.7803e+00, 1.7671e+00, 1.7539e+00, 1.7404e+00, 1.7262e+00, 1.7118e+00, 1.6977e+00, 1.6846e+00, 1.6724e+00, 1.6608e+00, 1.6497e+00, 1.6388e+00, 1.6282e+00, 1.6179e+00, 1.6075e+00, 1.5966e+00, 1.5850e+00, 1.5731e+00, 1.5615e+00, 1.5509e+00, 1.5412e+00, 1.5321e+00, 1.5233e+00, 1.5147e+00, 1.5064e+00, 1.4984e+00, 1.4905e+00, 1.4821e+00, 1.4731e+00, 1.4634e+00, 1.4535e+00, 1.4442e+00, 1.4359e+00, 1.4285e+00, 1.4215e+00, 1.4147e+00, 1.4081e+00, 1.4016e+00, 1.3955e+00, 1.3895e+00, 1.3832e+00, 1.3761e+00}); + feg = Vctr_cpu({1.0286e+01, 1.0095e+01, 9.5730e+00, 8.8405e+00, 8.0278e+00, 7.2300e+00, 6.4973e+00, 5.8467e+00, 5.2770e+00, 4.7796e+00, 4.3442e+00, 3.9613e+00, 3.6229e+00, 3.3223e+00, 3.0544e+00, 2.8147e+00, 2.5997e+00, 2.4065e+00, 2.2325e+00, 2.0757e+00, 1.9340e+00, 1.8059e+00, 1.6900e+00, 1.5848e+00, 1.4894e+00, 1.4026e+00, 1.3235e+00, 1.2513e+00, 1.1853e+00, 1.1248e+00, 1.0693e+00, 1.0181e+00, 9.7090e-01, 9.2730e-01, 8.8680e-01, 8.4920e-01, 8.1410e-01, 7.8140e-01, 7.5070e-01, 7.2190e-01, 6.9490e-01, 6.6940e-01, 6.4530e-01, 6.2250e-01, 6.0090e-01, 5.8040e-01, 5.6100e-01, 5.4240e-01, 5.2470e-01, 5.0790e-01, 4.9180e-01, 4.7640e-01, 4.6160e-01, 4.4750e-01, 4.3400e-01, 4.2100e-01, 4.0860e-01, 3.9660e-01, 3.8510e-01, 3.7410e-01, 3.6350e-01, 3.5330e-01, 3.4340e-01, 3.3400e-01, 3.2490e-01, 3.1610e-01, 3.0770e-01, 2.9950e-01, 2.9170e-01, 2.8410e-01, 2.7680e-01, 2.6980e-01, 2.6300e-01, 2.5650e-01, 2.5010e-01, 2.4400e-01, 2.3810e-01, 2.3250e-01, 2.2700e-01, 2.2170e-01, 2.1650e-01, 2.1160e-01, 2.0680e-01, 2.0210e-01, 1.9760e-01, 1.9330e-01, 1.8910e-01, 1.8500e-01, 1.8110e-01, 1.7730e-01, 1.7360e-01, 1.7000e-01, 1.6660e-01, 1.6320e-01, 1.6000e-01, 1.5680e-01, 1.5370e-01, 1.5080e-01, 1.4790e-01, 1.4510e-01, 1.4230e-01, 1.3970e-01, 1.3710e-01, 1.3460e-01, 1.3220e-01, 1.2990e-01, 1.2760e-01, 1.2530e-01, 1.2320e-01, 1.2100e-01, 1.1900e-01, 1.1700e-01, 1.1500e-01, 1.1310e-01, 1.1130e-01, 1.0950e-01, 1.0770e-01, 1.0600e-01, 1.0430e-01, 1.0270e-01, 1.0110e-01, 9.9500e-02, 9.8000e-02, 9.6500e-02, 9.5100e-02, 9.3700e-02, 9.2300e-02, 9.0900e-02, 8.9600e-02, 8.8300e-02, 8.7000e-02, 8.5800e-02, 8.4600e-02, 8.3400e-02, 8.2200e-02, 8.1100e-02, 8.0000e-02, 7.8900e-02, 7.7800e-02, 7.6800e-02, 7.5800e-02, 7.4800e-02, 7.3800e-02, 7.2800e-02, 7.1900e-02, 7.1000e-02, 7.0000e-02, 6.9200e-02, 6.8300e-02, 6.7400e-02, 6.6600e-02, 6.5800e-02, 6.4900e-02, 6.4200e-02, 6.3400e-02, 6.2600e-02, 6.1900e-02, 6.1100e-02, 6.0400e-02, 5.9700e-02, 5.9000e-02, 5.8300e-02, 5.7600e-02, 5.6900e-02, 5.6300e-02, 5.5600e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3200e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9200e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7200e-02, 4.6700e-02, 4.6200e-02, 4.5700e-02, 4.5200e-02, 4.4700e-02, 4.4300e-02, 4.3800e-02, 4.3400e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.0800e-02, 4.0400e-02, 4.0100e-02, 3.9700e-02, 3.9300e-02, 3.8900e-02, 3.8500e-02, 3.8100e-02, 3.7800e-02, 3.7400e-02, 3.7100e-02, 3.6700e-02, 3.6400e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2000e-02, 3.1700e-02, 3.1500e-02, 3.1200e-02, 3.0900e-02, 3.0600e-02, 3.0400e-02, 3.0100e-02, 2.9900e-02, 2.9600e-02, 2.9400e-02, 2.9100e-02, 2.8900e-02, 2.8600e-02, 2.8400e-02, 2.8100e-02, 2.7900e-02, 2.7700e-02, 2.7500e-02, 2.7200e-02, 2.7000e-02}); + } + break; + case 43: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.3000e+01, 4.2722e+01, 4.1947e+01, 4.0813e+01, 3.9481e+01, 3.8072e+01, 3.6659e+01, 3.5276e+01, 3.3938e+01, 3.2650e+01, 3.1414e+01, 3.0233e+01, 2.9111e+01, 2.8049e+01, 2.7050e+01, 2.6113e+01, 2.5237e+01, 2.4420e+01, 2.3659e+01, 2.2950e+01, 2.2288e+01, 2.1669e+01, 2.1088e+01, 2.0540e+01, 2.0020e+01, 1.9525e+01, 1.9050e+01, 1.8593e+01, 1.8151e+01, 1.7721e+01, 1.7301e+01, 1.6890e+01, 1.6486e+01, 1.6089e+01, 1.5698e+01, 1.5313e+01, 1.4934e+01, 1.4560e+01, 1.4193e+01, 1.3831e+01, 1.3476e+01, 1.3127e+01, 1.2786e+01, 1.2452e+01, 1.2127e+01, 1.1809e+01, 1.1501e+01, 1.1201e+01, 1.0910e+01, 1.0629e+01, 1.0357e+01, 1.0095e+01, 9.8426e+00, 9.5998e+00, 9.3667e+00, 9.1430e+00, 8.9288e+00, 8.7238e+00, 8.5280e+00, 8.3410e+00, 8.1625e+00, 7.9925e+00, 7.8306e+00, 7.6765e+00, 7.5298e+00, 7.3903e+00, 7.2578e+00, 7.1318e+00, 7.0120e+00, 6.8982e+00, 6.7900e+00, 6.6871e+00, 6.5891e+00, 6.4958e+00, 6.4071e+00, 6.3224e+00, 6.2415e+00, 6.1643e+00, 6.0904e+00, 6.0197e+00, 5.9517e+00, 5.8864e+00, 5.8236e+00, 5.7631e+00, 5.7046e+00, 5.6480e+00, 5.5931e+00, 5.5398e+00, 5.4880e+00, 5.4374e+00, 5.3881e+00, 5.3397e+00, 5.2922e+00, 5.2457e+00, 5.2000e+00, 5.1549e+00, 5.1104e+00, 5.0663e+00, 5.0228e+00, 4.9798e+00, 4.9372e+00, 4.8948e+00, 4.8526e+00, 4.8105e+00, 4.7688e+00, 4.7275e+00, 4.6864e+00, 4.6452e+00, 4.6039e+00, 4.5628e+00, 4.5219e+00, 4.4814e+00, 4.4410e+00, 4.4005e+00, 4.3598e+00, 4.3191e+00, 4.2787e+00, 4.2387e+00, 4.1989e+00, 4.1591e+00, 4.1190e+00, 4.0788e+00, 4.0387e+00, 3.9992e+00, 3.9601e+00, 3.9213e+00, 3.8823e+00, 3.8431e+00, 3.8038e+00, 3.7648e+00, 3.7264e+00, 3.6886e+00, 3.6512e+00, 3.6137e+00, 3.5759e+00, 3.5381e+00, 3.5005e+00, 3.4636e+00, 3.4274e+00, 3.3918e+00, 3.3564e+00, 3.3208e+00, 3.2851e+00, 3.2494e+00, 3.2141e+00, 3.1797e+00, 3.1460e+00, 3.1131e+00, 3.0803e+00, 3.0474e+00, 3.0142e+00, 2.9811e+00, 2.9486e+00, 2.9168e+00, 2.8858e+00, 2.8557e+00, 2.8261e+00, 2.7964e+00, 2.7664e+00, 2.7363e+00, 2.7065e+00, 2.6774e+00, 2.6491e+00, 2.6217e+00, 2.5951e+00, 2.5689e+00, 2.5426e+00, 2.5160e+00, 2.4893e+00, 2.4629e+00, 2.4371e+00, 2.4121e+00, 2.3880e+00, 2.3648e+00, 2.3422e+00, 2.3196e+00, 2.2966e+00, 2.2734e+00, 2.2502e+00, 2.2276e+00, 2.2056e+00, 2.1843e+00, 2.1640e+00, 2.1445e+00, 2.1255e+00, 2.1064e+00, 2.0869e+00, 2.0671e+00, 2.0473e+00, 2.0280e+00, 2.0093e+00, 1.9913e+00, 1.9739e+00, 1.9575e+00, 1.9418e+00, 1.9263e+00, 1.9104e+00, 1.8939e+00, 1.8772e+00, 1.8607e+00, 1.8448e+00, 1.8294e+00, 1.8146e+00, 1.8004e+00, 1.7871e+00, 1.7745e+00, 1.7621e+00, 1.7493e+00, 1.7358e+00, 1.7220e+00, 1.7082e+00, 1.6950e+00, 1.6823e+00, 1.6700e+00, 1.6582e+00, 1.6471e+00, 1.6368e+00, 1.6271e+00, 1.6173e+00, 1.6070e+00, 1.5959e+00, 1.5844e+00, 1.5732e+00, 1.5625e+00, 1.5522e+00, 1.5423e+00, 1.5327e+00, 1.5236e+00, 1.5154e+00, 1.5079e+00, 1.5006e+00, 1.4928e+00, 1.4841e+00, 1.4748e+00, 1.4654e+00, 1.4563e+00, 1.4478e+00, 1.4397e+00, 1.4318e+00, 1.4241e+00, 1.4169e+00}); + feg = Vctr_cpu({1.0824e+01, 1.0628e+01, 1.0083e+01, 9.3033e+00, 8.4226e+00, 7.5488e+00, 6.7451e+00, 6.0360e+00, 5.4219e+00, 4.8931e+00, 4.4368e+00, 4.0405e+00, 3.6936e+00, 3.3877e+00, 3.1163e+00, 2.8741e+00, 2.6571e+00, 2.4619e+00, 2.2859e+00, 2.1268e+00, 1.9828e+00, 1.8522e+00, 1.7337e+00, 1.6259e+00, 1.5278e+00, 1.4383e+00, 1.3567e+00, 1.2821e+00, 1.2137e+00, 1.1511e+00, 1.0935e+00, 1.0404e+00, 9.9150e-01, 9.4630e-01, 9.0440e-01, 8.6550e-01, 8.2930e-01, 7.9550e-01, 7.6400e-01, 7.3440e-01, 7.0660e-01, 6.8050e-01, 6.5590e-01, 6.3270e-01, 6.1070e-01, 5.8980e-01, 5.7010e-01, 5.5130e-01, 5.3340e-01, 5.1630e-01, 5.0000e-01, 4.8450e-01, 4.6960e-01, 4.5530e-01, 4.4170e-01, 4.2860e-01, 4.1600e-01, 4.0400e-01, 3.9240e-01, 3.8130e-01, 3.7060e-01, 3.6030e-01, 3.5040e-01, 3.4080e-01, 3.3160e-01, 3.2280e-01, 3.1420e-01, 3.0600e-01, 2.9800e-01, 2.9040e-01, 2.8300e-01, 2.7590e-01, 2.6900e-01, 2.6230e-01, 2.5590e-01, 2.4970e-01, 2.4370e-01, 2.3790e-01, 2.3230e-01, 2.2690e-01, 2.2170e-01, 2.1660e-01, 2.1170e-01, 2.0700e-01, 2.0240e-01, 1.9800e-01, 1.9370e-01, 1.8950e-01, 1.8550e-01, 1.8160e-01, 1.7780e-01, 1.7420e-01, 1.7060e-01, 1.6720e-01, 1.6380e-01, 1.6060e-01, 1.5740e-01, 1.5440e-01, 1.5140e-01, 1.4860e-01, 1.4580e-01, 1.4300e-01, 1.4040e-01, 1.3780e-01, 1.3540e-01, 1.3290e-01, 1.3060e-01, 1.2830e-01, 1.2610e-01, 1.2390e-01, 1.2180e-01, 1.1970e-01, 1.1770e-01, 1.1580e-01, 1.1390e-01, 1.1200e-01, 1.1020e-01, 1.0840e-01, 1.0670e-01, 1.0500e-01, 1.0340e-01, 1.0180e-01, 1.0020e-01, 9.8700e-02, 9.7200e-02, 9.5800e-02, 9.4400e-02, 9.3000e-02, 9.1600e-02, 9.0300e-02, 8.9000e-02, 8.7700e-02, 8.6500e-02, 8.5300e-02, 8.4100e-02, 8.2900e-02, 8.1800e-02, 8.0700e-02, 7.9600e-02, 7.8500e-02, 7.7500e-02, 7.6400e-02, 7.5400e-02, 7.4400e-02, 7.3500e-02, 7.2500e-02, 7.1600e-02, 7.0700e-02, 6.9800e-02, 6.8900e-02, 6.8100e-02, 6.7200e-02, 6.6400e-02, 6.5600e-02, 6.4800e-02, 6.4000e-02, 6.3200e-02, 6.2500e-02, 6.1700e-02, 6.1000e-02, 6.0300e-02, 5.9600e-02, 5.8900e-02, 5.8200e-02, 5.7500e-02, 5.6900e-02, 5.6200e-02, 5.5600e-02, 5.5000e-02, 5.4400e-02, 5.3700e-02, 5.3200e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7200e-02, 4.6700e-02, 4.6200e-02, 4.5800e-02, 4.5300e-02, 4.4800e-02, 4.4400e-02, 4.3900e-02, 4.3500e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0600e-02, 4.0200e-02, 3.9800e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8300e-02, 3.7900e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4300e-02, 3.3900e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1600e-02, 3.1400e-02, 3.1100e-02, 3.0800e-02, 3.0600e-02, 3.0300e-02, 3.0000e-02, 2.9800e-02, 2.9500e-02, 2.9300e-02, 2.9000e-02, 2.8800e-02, 2.8600e-02, 2.8300e-02, 2.8100e-02, 2.7900e-02, 2.7600e-02}); + } + break; + case 44: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.4000e+01, 4.3755e+01, 4.3061e+01, 4.2027e+01, 4.0771e+01, 3.9394e+01, 3.7961e+01, 3.6518e+01, 3.5091e+01, 3.3701e+01, 3.2361e+01, 3.1083e+01, 2.9873e+01, 2.8734e+01, 2.7670e+01, 2.6678e+01, 2.5758e+01, 2.4905e+01, 2.4115e+01, 2.3384e+01, 2.2705e+01, 2.2074e+01, 2.1485e+01, 2.0932e+01, 2.0412e+01, 1.9918e+01, 1.9447e+01, 1.8995e+01, 1.8560e+01, 1.8138e+01, 1.7727e+01, 1.7326e+01, 1.6932e+01, 1.6544e+01, 1.6163e+01, 1.5786e+01, 1.5415e+01, 1.5048e+01, 1.4687e+01, 1.4330e+01, 1.3978e+01, 1.3632e+01, 1.3292e+01, 1.2958e+01, 1.2631e+01, 1.2310e+01, 1.1998e+01, 1.1693e+01, 1.1396e+01, 1.1107e+01, 1.0827e+01, 1.0555e+01, 1.0293e+01, 1.0039e+01, 9.7949e+00, 9.5595e+00, 9.3331e+00, 9.1157e+00, 8.9070e+00, 8.7071e+00, 8.5158e+00, 8.3328e+00, 8.1580e+00, 7.9911e+00, 7.8319e+00, 7.6801e+00, 7.5354e+00, 7.3977e+00, 7.2665e+00, 7.1416e+00, 7.0227e+00, 6.9096e+00, 6.8019e+00, 6.6993e+00, 6.6016e+00, 6.5085e+00, 6.4198e+00, 6.3351e+00, 6.2541e+00, 6.1768e+00, 6.1029e+00, 6.0320e+00, 5.9639e+00, 5.8985e+00, 5.8357e+00, 5.7752e+00, 5.7167e+00, 5.6601e+00, 5.6053e+00, 5.5522e+00, 5.5007e+00, 5.4504e+00, 5.4012e+00, 5.3532e+00, 5.3063e+00, 5.2605e+00, 5.2154e+00, 5.1708e+00, 5.1268e+00, 5.0836e+00, 5.0411e+00, 4.9991e+00, 4.9572e+00, 4.9156e+00, 4.8743e+00, 4.8335e+00, 4.7931e+00, 4.7530e+00, 4.7127e+00, 4.6725e+00, 4.6323e+00, 4.5926e+00, 4.5533e+00, 4.5140e+00, 4.4747e+00, 4.4351e+00, 4.3955e+00, 4.3562e+00, 4.3173e+00, 4.2786e+00, 4.2400e+00, 4.2011e+00, 4.1620e+00, 4.1230e+00, 4.0843e+00, 4.0461e+00, 4.0082e+00, 3.9704e+00, 3.9323e+00, 3.8939e+00, 3.8557e+00, 3.8178e+00, 3.7805e+00, 3.7437e+00, 3.7070e+00, 3.6703e+00, 3.6333e+00, 3.5963e+00, 3.5596e+00, 3.5234e+00, 3.4879e+00, 3.4528e+00, 3.4180e+00, 3.3831e+00, 3.3480e+00, 3.3129e+00, 3.2781e+00, 3.2440e+00, 3.2106e+00, 3.1778e+00, 3.1453e+00, 3.1129e+00, 3.0804e+00, 3.0478e+00, 3.0153e+00, 2.9835e+00, 2.9524e+00, 2.9221e+00, 2.8923e+00, 2.8628e+00, 2.8335e+00, 2.8039e+00, 2.7743e+00, 2.7449e+00, 2.7161e+00, 2.6882e+00, 2.6610e+00, 2.6344e+00, 2.6082e+00, 2.5822e+00, 2.5561e+00, 2.5298e+00, 2.5036e+00, 2.4777e+00, 2.4527e+00, 2.4285e+00, 2.4050e+00, 2.3821e+00, 2.3595e+00, 2.3371e+00, 2.3145e+00, 2.2917e+00, 2.2689e+00, 2.2464e+00, 2.2248e+00, 2.2040e+00, 2.1839e+00, 2.1643e+00, 2.1451e+00, 2.1262e+00, 2.1073e+00, 2.0882e+00, 2.0687e+00, 2.0493e+00, 2.0304e+00, 2.0124e+00, 1.9952e+00, 1.9786e+00, 1.9624e+00, 1.9466e+00, 1.9311e+00, 1.9156e+00, 1.8998e+00, 1.8836e+00, 1.8673e+00, 1.8513e+00, 1.8361e+00, 1.8218e+00, 1.8081e+00, 1.7948e+00, 1.7819e+00, 1.7693e+00, 1.7569e+00, 1.7444e+00, 1.7315e+00, 1.7181e+00, 1.7046e+00, 1.6914e+00, 1.6789e+00, 1.6674e+00, 1.6564e+00, 1.6459e+00, 1.6356e+00, 1.6255e+00, 1.6158e+00, 1.6060e+00, 1.5960e+00, 1.5854e+00, 1.5743e+00, 1.5631e+00, 1.5524e+00, 1.5426e+00, 1.5336e+00, 1.5251e+00, 1.5169e+00, 1.5088e+00, 1.5011e+00, 1.4935e+00, 1.4860e+00, 1.4783e+00, 1.4699e+00}); + feg = Vctr_cpu({9.5520e+00, 9.4015e+00, 8.9865e+00, 8.3958e+00, 7.7274e+00, 7.0558e+00, 6.4235e+00, 5.8475e+00, 5.3307e+00, 4.8691e+00, 4.4569e+00, 4.0879e+00, 3.7569e+00, 3.4591e+00, 3.1906e+00, 2.9481e+00, 2.7288e+00, 2.5302e+00, 2.3502e+00, 2.1869e+00, 2.0386e+00, 1.9039e+00, 1.7814e+00, 1.6698e+00, 1.5682e+00, 1.4755e+00, 1.3909e+00, 1.3135e+00, 1.2426e+00, 1.1776e+00, 1.1179e+00, 1.0629e+00, 1.0123e+00, 9.6550e-01, 9.2210e-01, 8.8200e-01, 8.4460e-01, 8.0980e-01, 7.7740e-01, 7.4700e-01, 7.1850e-01, 6.9180e-01, 6.6660e-01, 6.4290e-01, 6.2050e-01, 5.9930e-01, 5.7920e-01, 5.6010e-01, 5.4190e-01, 5.2460e-01, 5.0810e-01, 4.9240e-01, 4.7740e-01, 4.6300e-01, 4.4920e-01, 4.3600e-01, 4.2330e-01, 4.1120e-01, 3.9950e-01, 3.8830e-01, 3.7750e-01, 3.6710e-01, 3.5710e-01, 3.4740e-01, 3.3810e-01, 3.2920e-01, 3.2060e-01, 3.1220e-01, 3.0420e-01, 2.9650e-01, 2.8900e-01, 2.8180e-01, 2.7480e-01, 2.6800e-01, 2.6150e-01, 2.5520e-01, 2.4920e-01, 2.4330e-01, 2.3760e-01, 2.3210e-01, 2.2680e-01, 2.2160e-01, 2.1660e-01, 2.1180e-01, 2.0710e-01, 2.0260e-01, 1.9820e-01, 1.9400e-01, 1.8990e-01, 1.8590e-01, 1.8200e-01, 1.7830e-01, 1.7460e-01, 1.7110e-01, 1.6770e-01, 1.6440e-01, 1.6120e-01, 1.5800e-01, 1.5500e-01, 1.5210e-01, 1.4920e-01, 1.4640e-01, 1.4370e-01, 1.4110e-01, 1.3850e-01, 1.3600e-01, 1.3360e-01, 1.3130e-01, 1.2900e-01, 1.2680e-01, 1.2460e-01, 1.2250e-01, 1.2040e-01, 1.1840e-01, 1.1650e-01, 1.1460e-01, 1.1270e-01, 1.1090e-01, 1.0910e-01, 1.0740e-01, 1.0570e-01, 1.0410e-01, 1.0250e-01, 1.0090e-01, 9.9400e-02, 9.7900e-02, 9.6500e-02, 9.5000e-02, 9.3600e-02, 9.2300e-02, 9.1000e-02, 8.9700e-02, 8.8400e-02, 8.7100e-02, 8.5900e-02, 8.4700e-02, 8.3600e-02, 8.2400e-02, 8.1300e-02, 8.0200e-02, 7.9200e-02, 7.8100e-02, 7.7100e-02, 7.6100e-02, 7.5100e-02, 7.4100e-02, 7.3200e-02, 7.2200e-02, 7.1300e-02, 7.0400e-02, 6.9500e-02, 6.8700e-02, 6.7800e-02, 6.7000e-02, 6.6200e-02, 6.5400e-02, 6.4600e-02, 6.3800e-02, 6.3100e-02, 6.2300e-02, 6.1600e-02, 6.0900e-02, 6.0200e-02, 5.9500e-02, 5.8800e-02, 5.8100e-02, 5.7400e-02, 5.6800e-02, 5.6200e-02, 5.5500e-02, 5.4900e-02, 5.4300e-02, 5.3700e-02, 5.3100e-02, 5.2600e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5800e-02, 4.5300e-02, 4.4900e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3100e-02, 4.2700e-02, 4.2300e-02, 4.1900e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0300e-02, 3.9900e-02, 3.9500e-02, 3.9100e-02, 3.8800e-02, 3.8400e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1300e-02, 3.1000e-02, 3.0700e-02, 3.0500e-02, 3.0200e-02, 3.0000e-02, 2.9700e-02, 2.9500e-02, 2.9200e-02, 2.9000e-02, 2.8700e-02, 2.8500e-02, 2.8300e-02}); + } + break; + case 45: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.5000e+01, 4.4762e+01, 4.4089e+01, 4.3076e+01, 4.1835e+01, 4.0460e+01, 3.9017e+01, 3.7550e+01, 3.6089e+01, 3.4658e+01, 3.3272e+01, 3.1944e+01, 3.0682e+01, 2.9492e+01, 2.8377e+01, 2.7338e+01, 2.6372e+01, 2.5477e+01, 2.4649e+01, 2.3884e+01, 2.3176e+01, 2.2520e+01, 2.1910e+01, 2.1341e+01, 2.0807e+01, 2.0305e+01, 1.9829e+01, 1.9375e+01, 1.8941e+01, 1.8522e+01, 1.8116e+01, 1.7721e+01, 1.7335e+01, 1.6956e+01, 1.6584e+01, 1.6217e+01, 1.5855e+01, 1.5498e+01, 1.5144e+01, 1.4795e+01, 1.4450e+01, 1.4110e+01, 1.3774e+01, 1.3443e+01, 1.3118e+01, 1.2798e+01, 1.2485e+01, 1.2178e+01, 1.1877e+01, 1.1584e+01, 1.1299e+01, 1.1021e+01, 1.0751e+01, 1.0489e+01, 1.0236e+01, 9.9905e+00, 9.7537e+00, 9.5253e+00, 9.3053e+00, 9.0937e+00, 8.8904e+00, 8.6953e+00, 8.5082e+00, 8.3290e+00, 8.1575e+00, 7.9935e+00, 7.8367e+00, 7.6871e+00, 7.5442e+00, 7.4080e+00, 7.2780e+00, 7.1541e+00, 7.0360e+00, 6.9234e+00, 6.8161e+00, 6.7138e+00, 6.6163e+00, 6.5232e+00, 6.4344e+00, 6.3496e+00, 6.2686e+00, 6.1911e+00, 6.1168e+00, 6.0457e+00, 5.9776e+00, 5.9121e+00, 5.8491e+00, 5.7883e+00, 5.7297e+00, 5.6733e+00, 5.6186e+00, 5.5656e+00, 5.5140e+00, 5.4638e+00, 5.4151e+00, 5.3676e+00, 5.3212e+00, 5.2755e+00, 5.2307e+00, 5.1868e+00, 5.1438e+00, 5.1014e+00, 5.0595e+00, 5.0179e+00, 4.9767e+00, 4.9362e+00, 4.8962e+00, 4.8566e+00, 4.8169e+00, 4.7774e+00, 4.7380e+00, 4.6991e+00, 4.6606e+00, 4.6222e+00, 4.5838e+00, 4.5452e+00, 4.5067e+00, 4.4684e+00, 4.4305e+00, 4.3929e+00, 4.3552e+00, 4.3174e+00, 4.2793e+00, 4.2413e+00, 4.2036e+00, 4.1664e+00, 4.1293e+00, 4.0923e+00, 4.0550e+00, 4.0176e+00, 3.9802e+00, 3.9431e+00, 3.9064e+00, 3.8702e+00, 3.8341e+00, 3.7979e+00, 3.7614e+00, 3.7249e+00, 3.6886e+00, 3.6528e+00, 3.6176e+00, 3.5827e+00, 3.5481e+00, 3.5133e+00, 3.4784e+00, 3.4434e+00, 3.4087e+00, 3.3746e+00, 3.3411e+00, 3.3081e+00, 3.2754e+00, 3.2428e+00, 3.2100e+00, 3.1771e+00, 3.1444e+00, 3.1122e+00, 3.0808e+00, 3.0499e+00, 3.0196e+00, 2.9896e+00, 2.9596e+00, 2.9295e+00, 2.8993e+00, 2.8693e+00, 2.8399e+00, 2.8112e+00, 2.7832e+00, 2.7558e+00, 2.7288e+00, 2.7019e+00, 2.6750e+00, 2.6479e+00, 2.6208e+00, 2.5942e+00, 2.5683e+00, 2.5431e+00, 2.5186e+00, 2.4946e+00, 2.4710e+00, 2.4475e+00, 2.4240e+00, 2.4002e+00, 2.3764e+00, 2.3530e+00, 2.3304e+00, 2.3085e+00, 2.2873e+00, 2.2666e+00, 2.2463e+00, 2.2263e+00, 2.2063e+00, 2.1860e+00, 2.1656e+00, 2.1452e+00, 2.1253e+00, 2.1062e+00, 2.0879e+00, 2.0702e+00, 2.0529e+00, 2.0360e+00, 2.0193e+00, 2.0027e+00, 1.9859e+00, 1.9687e+00, 1.9514e+00, 1.9344e+00, 1.9182e+00, 1.9029e+00, 1.8881e+00, 1.8738e+00, 1.8598e+00, 1.8461e+00, 1.8327e+00, 1.8192e+00, 1.8053e+00, 1.7910e+00, 1.7766e+00, 1.7625e+00, 1.7492e+00, 1.7367e+00, 1.7248e+00, 1.7133e+00, 1.7020e+00, 1.6911e+00, 1.6804e+00, 1.6697e+00, 1.6588e+00, 1.6473e+00, 1.6355e+00, 1.6236e+00, 1.6122e+00, 1.6016e+00, 1.5917e+00, 1.5824e+00, 1.5734e+00, 1.5646e+00, 1.5560e+00, 1.5477e+00, 1.5395e+00, 1.5309e+00, 1.5219e+00}); + feg = Vctr_cpu({9.2363e+00, 9.1005e+00, 8.7249e+00, 8.1875e+00, 7.5750e+00, 6.9544e+00, 6.3646e+00, 5.8225e+00, 5.3316e+00, 4.8893e+00, 4.4911e+00, 4.1320e+00, 3.8076e+00, 3.5139e+00, 3.2477e+00, 3.0060e+00, 2.7865e+00, 2.5869e+00, 2.4052e+00, 2.2399e+00, 2.0893e+00, 1.9520e+00, 1.8269e+00, 1.7127e+00, 1.6084e+00, 1.5131e+00, 1.4259e+00, 1.3460e+00, 1.2728e+00, 1.2056e+00, 1.1439e+00, 1.0870e+00, 1.0346e+00, 9.8610e-01, 9.4130e-01, 8.9980e-01, 8.6120e-01, 8.2520e-01, 7.9180e-01, 7.6050e-01, 7.3120e-01, 7.0370e-01, 6.7790e-01, 6.5360e-01, 6.3060e-01, 6.0900e-01, 5.8840e-01, 5.6900e-01, 5.5050e-01, 5.3300e-01, 5.1620e-01, 5.0030e-01, 4.8500e-01, 4.7050e-01, 4.5650e-01, 4.4320e-01, 4.3040e-01, 4.1810e-01, 4.0630e-01, 3.9500e-01, 3.8410e-01, 3.7360e-01, 3.6350e-01, 3.5380e-01, 3.4440e-01, 3.3540e-01, 3.2670e-01, 3.1830e-01, 3.1020e-01, 3.0240e-01, 2.9480e-01, 2.8750e-01, 2.8040e-01, 2.7360e-01, 2.6700e-01, 2.6060e-01, 2.5450e-01, 2.4850e-01, 2.4270e-01, 2.3720e-01, 2.3170e-01, 2.2650e-01, 2.2140e-01, 2.1650e-01, 2.1180e-01, 2.0720e-01, 2.0270e-01, 1.9840e-01, 1.9420e-01, 1.9010e-01, 1.8620e-01, 1.8240e-01, 1.7860e-01, 1.7500e-01, 1.7160e-01, 1.6820e-01, 1.6490e-01, 1.6170e-01, 1.5860e-01, 1.5560e-01, 1.5260e-01, 1.4980e-01, 1.4700e-01, 1.4430e-01, 1.4170e-01, 1.3920e-01, 1.3670e-01, 1.3430e-01, 1.3190e-01, 1.2960e-01, 1.2740e-01, 1.2530e-01, 1.2310e-01, 1.2110e-01, 1.1910e-01, 1.1710e-01, 1.1520e-01, 1.1340e-01, 1.1160e-01, 1.0980e-01, 1.0810e-01, 1.0640e-01, 1.0480e-01, 1.0320e-01, 1.0160e-01, 1.0010e-01, 9.8600e-02, 9.7100e-02, 9.5700e-02, 9.4300e-02, 9.2900e-02, 9.1600e-02, 9.0300e-02, 8.9000e-02, 8.7800e-02, 8.6600e-02, 8.5400e-02, 8.4200e-02, 8.3100e-02, 8.1900e-02, 8.0900e-02, 7.9800e-02, 7.8700e-02, 7.7700e-02, 7.6700e-02, 7.5700e-02, 7.4700e-02, 7.3800e-02, 7.2800e-02, 7.1900e-02, 7.1000e-02, 7.0100e-02, 6.9300e-02, 6.8400e-02, 6.7600e-02, 6.6800e-02, 6.6000e-02, 6.5200e-02, 6.4400e-02, 6.3600e-02, 6.2900e-02, 6.2200e-02, 6.1400e-02, 6.0700e-02, 6.0000e-02, 5.9300e-02, 5.8700e-02, 5.8000e-02, 5.7400e-02, 5.6700e-02, 5.6100e-02, 5.5500e-02, 5.4900e-02, 5.4300e-02, 5.3700e-02, 5.3100e-02, 5.2500e-02, 5.2000e-02, 5.1400e-02, 5.0900e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5400e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3600e-02, 4.3200e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1500e-02, 4.1100e-02, 4.0800e-02, 4.0400e-02, 4.0000e-02, 3.9600e-02, 3.9200e-02, 3.8900e-02, 3.8500e-02, 3.8200e-02, 3.7800e-02, 3.7500e-02, 3.7100e-02, 3.6800e-02, 3.6400e-02, 3.6100e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4500e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1700e-02, 3.1400e-02, 3.1100e-02, 3.0900e-02, 3.0600e-02, 3.0400e-02, 3.0100e-02, 2.9900e-02, 2.9600e-02, 2.9400e-02, 2.9100e-02, 2.8900e-02}); + } + break; + case 46: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.6000e+01, 4.5803e+01, 4.5231e+01, 4.4332e+01, 4.3172e+01, 4.1825e+01, 4.0359e+01, 3.8831e+01, 3.7289e+01, 3.5766e+01, 3.4288e+01, 3.2872e+01, 3.1529e+01, 3.0266e+01, 2.9085e+01, 2.7987e+01, 2.6969e+01, 2.6029e+01, 2.5162e+01, 2.4363e+01, 2.3626e+01, 2.2946e+01, 2.2316e+01, 2.1732e+01, 2.1187e+01, 2.0676e+01, 2.0195e+01, 1.9740e+01, 1.9305e+01, 1.8889e+01, 1.8488e+01, 1.8099e+01, 1.7721e+01, 1.7350e+01, 1.6987e+01, 1.6629e+01, 1.6276e+01, 1.5927e+01, 1.5582e+01, 1.5241e+01, 1.4904e+01, 1.4570e+01, 1.4239e+01, 1.3913e+01, 1.3591e+01, 1.3274e+01, 1.2962e+01, 1.2655e+01, 1.2353e+01, 1.2058e+01, 1.1769e+01, 1.1487e+01, 1.1211e+01, 1.0943e+01, 1.0682e+01, 1.0429e+01, 1.0184e+01, 9.9462e+00, 9.7164e+00, 9.4945e+00, 9.2805e+00, 9.0744e+00, 8.8761e+00, 8.6854e+00, 8.5024e+00, 8.3268e+00, 8.1585e+00, 7.9973e+00, 7.8430e+00, 7.6954e+00, 7.5544e+00, 7.4196e+00, 7.2909e+00, 7.1681e+00, 7.0508e+00, 6.9388e+00, 6.8320e+00, 6.7300e+00, 6.6326e+00, 6.5396e+00, 6.4508e+00, 6.3659e+00, 6.2847e+00, 6.2070e+00, 6.1326e+00, 6.0613e+00, 5.9929e+00, 5.9272e+00, 5.8640e+00, 5.8031e+00, 5.7444e+00, 5.6877e+00, 5.6329e+00, 5.5799e+00, 5.5284e+00, 5.4784e+00, 5.4298e+00, 5.3823e+00, 5.3360e+00, 5.2908e+00, 5.2465e+00, 5.2031e+00, 5.1604e+00, 5.1183e+00, 5.0770e+00, 5.0362e+00, 4.9959e+00, 4.9561e+00, 4.9167e+00, 4.8776e+00, 4.8388e+00, 4.8004e+00, 4.7622e+00, 4.7243e+00, 4.6865e+00, 4.6488e+00, 4.6113e+00, 4.5740e+00, 4.5368e+00, 4.4998e+00, 4.4629e+00, 4.4260e+00, 4.3891e+00, 4.3523e+00, 4.3157e+00, 4.2792e+00, 4.2428e+00, 4.2064e+00, 4.1701e+00, 4.1337e+00, 4.0974e+00, 4.0613e+00, 4.0254e+00, 3.9896e+00, 3.9539e+00, 3.9183e+00, 3.8826e+00, 3.8470e+00, 3.8116e+00, 3.7764e+00, 3.7415e+00, 3.7068e+00, 3.6722e+00, 3.6377e+00, 3.6032e+00, 3.5688e+00, 3.5346e+00, 3.5008e+00, 3.4673e+00, 3.4341e+00, 3.4012e+00, 3.3683e+00, 3.3356e+00, 3.3029e+00, 3.2704e+00, 3.2383e+00, 3.2066e+00, 3.1753e+00, 3.1444e+00, 3.1138e+00, 3.0833e+00, 3.0528e+00, 3.0225e+00, 2.9924e+00, 2.9627e+00, 2.9335e+00, 2.9049e+00, 2.8766e+00, 2.8487e+00, 2.8210e+00, 2.7933e+00, 2.7657e+00, 2.7383e+00, 2.7112e+00, 2.6846e+00, 2.6586e+00, 2.6332e+00, 2.6082e+00, 2.5835e+00, 2.5589e+00, 2.5344e+00, 2.5099e+00, 2.4856e+00, 2.4616e+00, 2.4381e+00, 2.4153e+00, 2.3930e+00, 2.3712e+00, 2.3498e+00, 2.3285e+00, 2.3073e+00, 2.2861e+00, 2.2649e+00, 2.2439e+00, 2.2233e+00, 2.2032e+00, 2.1838e+00, 2.1649e+00, 2.1466e+00, 2.1285e+00, 2.1106e+00, 2.0928e+00, 2.0748e+00, 2.0568e+00, 2.0389e+00, 2.0213e+00, 2.0042e+00, 1.9877e+00, 1.9718e+00, 1.9564e+00, 1.9414e+00, 1.9267e+00, 1.9120e+00, 1.8973e+00, 1.8824e+00, 1.8674e+00, 1.8524e+00, 1.8377e+00, 1.8235e+00, 1.8099e+00, 1.7969e+00, 1.7844e+00, 1.7723e+00, 1.7605e+00, 1.7487e+00, 1.7369e+00, 1.7249e+00, 1.7126e+00, 1.7002e+00, 1.6879e+00, 1.6759e+00, 1.6644e+00, 1.6535e+00, 1.6432e+00, 1.6334e+00, 1.6240e+00, 1.6147e+00, 1.6056e+00, 1.5963e+00, 1.5868e+00, 1.5769e+00}); + feg = Vctr_cpu({7.5832e+00, 7.5250e+00, 7.3569e+00, 7.0965e+00, 6.7675e+00, 6.3949e+00, 6.0008e+00, 5.6026e+00, 5.2124e+00, 4.8383e+00, 4.4850e+00, 4.1547e+00, 3.8482e+00, 3.5652e+00, 3.3048e+00, 3.0657e+00, 2.8467e+00, 2.6462e+00, 2.4628e+00, 2.2952e+00, 2.1420e+00, 2.0019e+00, 1.8739e+00, 1.7568e+00, 1.6497e+00, 1.5516e+00, 1.4618e+00, 1.3794e+00, 1.3039e+00, 1.2344e+00, 1.1706e+00, 1.1118e+00, 1.0576e+00, 1.0075e+00, 9.6110e-01, 9.1820e-01, 8.7830e-01, 8.4120e-01, 8.0670e-01, 7.7440e-01, 7.4420e-01, 7.1600e-01, 6.8950e-01, 6.6450e-01, 6.4100e-01, 6.1890e-01, 5.9790e-01, 5.7810e-01, 5.5920e-01, 5.4130e-01, 5.2430e-01, 5.0810e-01, 4.9270e-01, 4.7790e-01, 4.6380e-01, 4.5030e-01, 4.3740e-01, 4.2490e-01, 4.1300e-01, 4.0160e-01, 3.9060e-01, 3.8000e-01, 3.6980e-01, 3.6000e-01, 3.5060e-01, 3.4150e-01, 3.3270e-01, 3.2420e-01, 3.1600e-01, 3.0810e-01, 3.0050e-01, 2.9310e-01, 2.8590e-01, 2.7900e-01, 2.7240e-01, 2.6590e-01, 2.5970e-01, 2.5360e-01, 2.4780e-01, 2.4210e-01, 2.3660e-01, 2.3130e-01, 2.2620e-01, 2.2120e-01, 2.1640e-01, 2.1170e-01, 2.0710e-01, 2.0270e-01, 1.9850e-01, 1.9430e-01, 1.9030e-01, 1.8640e-01, 1.8260e-01, 1.7900e-01, 1.7540e-01, 1.7190e-01, 1.6860e-01, 1.6530e-01, 1.6210e-01, 1.5910e-01, 1.5610e-01, 1.5310e-01, 1.5030e-01, 1.4760e-01, 1.4490e-01, 1.4230e-01, 1.3970e-01, 1.3730e-01, 1.3490e-01, 1.3250e-01, 1.3030e-01, 1.2800e-01, 1.2590e-01, 1.2380e-01, 1.2170e-01, 1.1970e-01, 1.1780e-01, 1.1590e-01, 1.1400e-01, 1.1220e-01, 1.1050e-01, 1.0870e-01, 1.0710e-01, 1.0540e-01, 1.0380e-01, 1.0220e-01, 1.0070e-01, 9.9200e-02, 9.7800e-02, 9.6300e-02, 9.4900e-02, 9.3600e-02, 9.2300e-02, 9.0900e-02, 8.9700e-02, 8.8400e-02, 8.7200e-02, 8.6000e-02, 8.4800e-02, 8.3700e-02, 8.2600e-02, 8.1500e-02, 8.0400e-02, 7.9300e-02, 7.8300e-02, 7.7300e-02, 7.6300e-02, 7.5300e-02, 7.4400e-02, 7.3400e-02, 7.2500e-02, 7.1600e-02, 7.0700e-02, 6.9800e-02, 6.9000e-02, 6.8200e-02, 6.7300e-02, 6.6500e-02, 6.5700e-02, 6.5000e-02, 6.4200e-02, 6.3400e-02, 6.2700e-02, 6.2000e-02, 6.1300e-02, 6.0600e-02, 5.9900e-02, 5.9200e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6600e-02, 5.6000e-02, 5.5400e-02, 5.4800e-02, 5.4200e-02, 5.3600e-02, 5.3000e-02, 5.2500e-02, 5.1900e-02, 5.1400e-02, 5.0800e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5400e-02, 4.5000e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1600e-02, 4.1200e-02, 4.0800e-02, 4.0500e-02, 4.0100e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8600e-02, 3.8300e-02, 3.7900e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2400e-02, 3.2100e-02, 3.1800e-02, 3.1600e-02, 3.1300e-02, 3.1000e-02, 3.0800e-02, 3.0500e-02, 3.0300e-02, 3.0000e-02, 2.9800e-02, 2.9500e-02}); + } + break; + case 47: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.7000e+01, 4.6776e+01, 4.6139e+01, 4.5169e+01, 4.3963e+01, 4.2605e+01, 4.1157e+01, 3.9662e+01, 3.8154e+01, 3.6657e+01, 3.5192e+01, 3.3774e+01, 3.2415e+01, 3.1125e+01, 2.9909e+01, 2.8769e+01, 2.7706e+01, 2.6719e+01, 2.5805e+01, 2.4960e+01, 2.4180e+01, 2.3460e+01, 2.2794e+01, 2.2178e+01, 2.1607e+01, 2.1073e+01, 2.0575e+01, 2.0105e+01, 1.9661e+01, 1.9239e+01, 1.8834e+01, 1.8445e+01, 1.8069e+01, 1.7703e+01, 1.7346e+01, 1.6996e+01, 1.6651e+01, 1.6312e+01, 1.5976e+01, 1.5645e+01, 1.5316e+01, 1.4991e+01, 1.4669e+01, 1.4351e+01, 1.4035e+01, 1.3723e+01, 1.3416e+01, 1.3112e+01, 1.2813e+01, 1.2519e+01, 1.2230e+01, 1.1946e+01, 1.1668e+01, 1.1397e+01, 1.1132e+01, 1.0873e+01, 1.0622e+01, 1.0377e+01, 1.0139e+01, 9.9090e+00, 9.6860e+00, 9.4704e+00, 9.2621e+00, 9.0612e+00, 8.8675e+00, 8.6811e+00, 8.5018e+00, 8.3295e+00, 8.1641e+00, 8.0055e+00, 7.8534e+00, 7.7077e+00, 7.5683e+00, 7.4348e+00, 7.3071e+00, 7.1851e+00, 7.0684e+00, 6.9569e+00, 6.8503e+00, 6.7485e+00, 6.6512e+00, 6.5582e+00, 6.4692e+00, 6.3840e+00, 6.3027e+00, 6.2248e+00, 6.1500e+00, 6.0783e+00, 6.0096e+00, 5.9436e+00, 5.8802e+00, 5.8191e+00, 5.7601e+00, 5.7031e+00, 5.6483e+00, 5.5952e+00, 5.5438e+00, 5.4937e+00, 5.4450e+00, 5.3977e+00, 5.3517e+00, 5.3068e+00, 5.2628e+00, 5.2196e+00, 5.1772e+00, 5.1357e+00, 5.0950e+00, 5.0549e+00, 5.0152e+00, 4.9759e+00, 4.9370e+00, 4.8987e+00, 4.8610e+00, 4.8236e+00, 4.7863e+00, 4.7490e+00, 4.7119e+00, 4.6752e+00, 4.6389e+00, 4.6028e+00, 4.5669e+00, 4.5308e+00, 4.4946e+00, 4.4585e+00, 4.4227e+00, 4.3872e+00, 4.3520e+00, 4.3167e+00, 4.2813e+00, 4.2456e+00, 4.2100e+00, 4.1747e+00, 4.1396e+00, 4.1049e+00, 4.0703e+00, 4.0355e+00, 4.0005e+00, 3.9654e+00, 3.9305e+00, 3.8959e+00, 3.8617e+00, 3.8278e+00, 3.7940e+00, 3.7600e+00, 3.7259e+00, 3.6917e+00, 3.6577e+00, 3.6241e+00, 3.5910e+00, 3.5583e+00, 3.5257e+00, 3.4932e+00, 3.4606e+00, 3.4278e+00, 3.3951e+00, 3.3628e+00, 3.3311e+00, 3.2999e+00, 3.2690e+00, 3.2384e+00, 3.2078e+00, 3.1771e+00, 3.1463e+00, 3.1157e+00, 3.0855e+00, 3.0559e+00, 3.0270e+00, 2.9984e+00, 2.9702e+00, 2.9421e+00, 2.9140e+00, 2.8857e+00, 2.8575e+00, 2.8296e+00, 2.8023e+00, 2.7757e+00, 2.7497e+00, 2.7240e+00, 2.6987e+00, 2.6736e+00, 2.6484e+00, 2.6230e+00, 2.5977e+00, 2.5727e+00, 2.5483e+00, 2.5246e+00, 2.5016e+00, 2.4789e+00, 2.4567e+00, 2.4347e+00, 2.4127e+00, 2.3906e+00, 2.3683e+00, 2.3462e+00, 2.3245e+00, 2.3035e+00, 2.2832e+00, 2.2634e+00, 2.2440e+00, 2.2250e+00, 2.2063e+00, 2.1876e+00, 2.1687e+00, 2.1497e+00, 2.1305e+00, 2.1118e+00, 2.0937e+00, 2.0763e+00, 2.0595e+00, 2.0432e+00, 2.0271e+00, 2.0114e+00, 1.9959e+00, 1.9803e+00, 1.9646e+00, 1.9485e+00, 1.9324e+00, 1.9166e+00, 1.9014e+00, 1.8871e+00, 1.8732e+00, 1.8598e+00, 1.8467e+00, 1.8338e+00, 1.8212e+00, 1.8086e+00, 1.7959e+00, 1.7828e+00, 1.7694e+00, 1.7560e+00, 1.7431e+00, 1.7308e+00, 1.7193e+00, 1.7083e+00, 1.6976e+00, 1.6871e+00, 1.6769e+00, 1.6669e+00, 1.6570e+00, 1.6469e+00, 1.6364e+00}); + feg = Vctr_cpu({8.6712e+00, 8.5580e+00, 8.2436e+00, 7.7901e+00, 7.2676e+00, 6.7316e+00, 6.2154e+00, 5.7345e+00, 5.2930e+00, 4.8898e+00, 4.5219e+00, 4.1858e+00, 3.8785e+00, 3.5971e+00, 3.3392e+00, 3.1029e+00, 2.8861e+00, 2.6874e+00, 2.5051e+00, 2.3380e+00, 2.1847e+00, 2.0441e+00, 1.9151e+00, 1.7968e+00, 1.6882e+00, 1.5885e+00, 1.4969e+00, 1.4128e+00, 1.3353e+00, 1.2641e+00, 1.1984e+00, 1.1378e+00, 1.0819e+00, 1.0302e+00, 9.8230e-01, 9.3790e-01, 8.9670e-01, 8.5840e-01, 8.2270e-01, 7.8940e-01, 7.5830e-01, 7.2920e-01, 7.0190e-01, 6.7620e-01, 6.5200e-01, 6.2930e-01, 6.0780e-01, 5.8750e-01, 5.6820e-01, 5.4990e-01, 5.3260e-01, 5.1610e-01, 5.0040e-01, 4.8540e-01, 4.7100e-01, 4.5730e-01, 4.4420e-01, 4.3170e-01, 4.1960e-01, 4.0800e-01, 3.9690e-01, 3.8620e-01, 3.7590e-01, 3.6600e-01, 3.5650e-01, 3.4730e-01, 3.3840e-01, 3.2990e-01, 3.2160e-01, 3.1360e-01, 3.0590e-01, 2.9850e-01, 2.9130e-01, 2.8430e-01, 2.7760e-01, 2.7110e-01, 2.6470e-01, 2.5860e-01, 2.5270e-01, 2.4700e-01, 2.4140e-01, 2.3600e-01, 2.3080e-01, 2.2580e-01, 2.2090e-01, 2.1610e-01, 2.1150e-01, 2.0700e-01, 2.0270e-01, 1.9850e-01, 1.9440e-01, 1.9040e-01, 1.8660e-01, 1.8280e-01, 1.7920e-01, 1.7570e-01, 1.7230e-01, 1.6890e-01, 1.6570e-01, 1.6250e-01, 1.5950e-01, 1.5650e-01, 1.5360e-01, 1.5080e-01, 1.4810e-01, 1.4540e-01, 1.4280e-01, 1.4030e-01, 1.3780e-01, 1.3540e-01, 1.3310e-01, 1.3090e-01, 1.2860e-01, 1.2650e-01, 1.2440e-01, 1.2230e-01, 1.2030e-01, 1.1840e-01, 1.1650e-01, 1.1460e-01, 1.1280e-01, 1.1110e-01, 1.0940e-01, 1.0770e-01, 1.0600e-01, 1.0440e-01, 1.0290e-01, 1.0130e-01, 9.9800e-02, 9.8400e-02, 9.7000e-02, 9.5600e-02, 9.4200e-02, 9.2900e-02, 9.1600e-02, 9.0300e-02, 8.9000e-02, 8.7800e-02, 8.6600e-02, 8.5400e-02, 8.4300e-02, 8.3200e-02, 8.2100e-02, 8.1000e-02, 7.9900e-02, 7.8900e-02, 7.7900e-02, 7.6900e-02, 7.5900e-02, 7.4900e-02, 7.4000e-02, 7.3100e-02, 7.2200e-02, 7.1300e-02, 7.0400e-02, 6.9600e-02, 6.8700e-02, 6.7900e-02, 6.7100e-02, 6.6300e-02, 6.5500e-02, 6.4700e-02, 6.4000e-02, 6.3300e-02, 6.2500e-02, 6.1800e-02, 6.1100e-02, 6.0400e-02, 5.9700e-02, 5.9100e-02, 5.8400e-02, 5.7800e-02, 5.7100e-02, 5.6500e-02, 5.5900e-02, 5.5300e-02, 5.4700e-02, 5.4100e-02, 5.3500e-02, 5.3000e-02, 5.2400e-02, 5.1900e-02, 5.1300e-02, 5.0800e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6400e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.0900e-02, 4.0500e-02, 4.0100e-02, 3.9800e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8300e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5100e-02, 3.4800e-02, 3.4500e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3300e-02, 3.3000e-02, 3.2800e-02, 3.2500e-02, 3.2200e-02, 3.1900e-02, 3.1700e-02, 3.1400e-02, 3.1200e-02, 3.0900e-02, 3.0700e-02, 3.0400e-02, 3.0200e-02}); + } + break; + case 48: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.8000e+01, 4.7762e+01, 4.7084e+01, 4.6059e+01, 4.4797e+01, 4.3394e+01, 4.1922e+01, 4.0425e+01, 3.8929e+01, 3.7452e+01, 3.6007e+01, 3.4603e+01, 3.3250e+01, 3.1956e+01, 3.0724e+01, 2.9561e+01, 2.8467e+01, 2.7444e+01, 2.6491e+01, 2.5605e+01, 2.4783e+01, 2.4023e+01, 2.3319e+01, 2.2667e+01, 2.2063e+01, 2.1501e+01, 2.0978e+01, 2.0488e+01, 2.0027e+01, 1.9592e+01, 1.9179e+01, 1.8784e+01, 1.8405e+01, 1.8040e+01, 1.7685e+01, 1.7339e+01, 1.7000e+01, 1.6668e+01, 1.6340e+01, 1.6017e+01, 1.5698e+01, 1.5382e+01, 1.5069e+01, 1.4758e+01, 1.4451e+01, 1.4146e+01, 1.3845e+01, 1.3547e+01, 1.3252e+01, 1.2961e+01, 1.2675e+01, 1.2393e+01, 1.2115e+01, 1.1843e+01, 1.1576e+01, 1.1314e+01, 1.1059e+01, 1.0809e+01, 1.0566e+01, 1.0330e+01, 1.0100e+01, 9.8762e+00, 9.6597e+00, 9.4499e+00, 9.2471e+00, 9.0511e+00, 8.8619e+00, 8.6795e+00, 8.5038e+00, 8.3347e+00, 8.1721e+00, 8.0159e+00, 7.8660e+00, 7.7221e+00, 7.5841e+00, 7.4519e+00, 7.3253e+00, 7.2040e+00, 7.0879e+00, 6.9768e+00, 6.8706e+00, 6.7688e+00, 6.6715e+00, 6.5784e+00, 6.4893e+00, 6.4040e+00, 6.3223e+00, 6.2440e+00, 6.1690e+00, 6.0970e+00, 6.0279e+00, 5.9615e+00, 5.8976e+00, 5.8363e+00, 5.7772e+00, 5.7201e+00, 5.6648e+00, 5.6114e+00, 5.5599e+00, 5.5099e+00, 5.4614e+00, 5.4141e+00, 5.3679e+00, 5.3230e+00, 5.2793e+00, 5.2367e+00, 5.1947e+00, 5.1535e+00, 5.1129e+00, 5.0731e+00, 5.0341e+00, 4.9957e+00, 4.9577e+00, 4.9199e+00, 4.8825e+00, 4.8455e+00, 4.8091e+00, 4.7731e+00, 4.7373e+00, 4.7014e+00, 4.6656e+00, 4.6300e+00, 4.5947e+00, 4.5599e+00, 4.5252e+00, 4.4906e+00, 4.4558e+00, 4.4208e+00, 4.3859e+00, 4.3514e+00, 4.3173e+00, 4.2833e+00, 4.2494e+00, 4.2151e+00, 4.1807e+00, 4.1462e+00, 4.1120e+00, 4.0782e+00, 4.0448e+00, 4.0115e+00, 3.9780e+00, 3.9442e+00, 3.9102e+00, 3.8763e+00, 3.8428e+00, 3.8098e+00, 3.7772e+00, 3.7447e+00, 3.7121e+00, 3.6793e+00, 3.6462e+00, 3.6132e+00, 3.5805e+00, 3.5485e+00, 3.5170e+00, 3.4859e+00, 3.4547e+00, 3.4233e+00, 3.3918e+00, 3.3601e+00, 3.3287e+00, 3.2977e+00, 3.2675e+00, 3.2378e+00, 3.2086e+00, 3.1793e+00, 3.1499e+00, 3.1203e+00, 3.0906e+00, 3.0611e+00, 3.0321e+00, 3.0038e+00, 2.9763e+00, 2.9493e+00, 2.9224e+00, 2.8955e+00, 2.8684e+00, 2.8413e+00, 2.8141e+00, 2.7872e+00, 2.7609e+00, 2.7354e+00, 2.7107e+00, 2.6865e+00, 2.6624e+00, 2.6383e+00, 2.6141e+00, 2.5897e+00, 2.5654e+00, 2.5412e+00, 2.5175e+00, 2.4946e+00, 2.4726e+00, 2.4512e+00, 2.4302e+00, 2.4092e+00, 2.3880e+00, 2.3668e+00, 2.3455e+00, 2.3242e+00, 2.3031e+00, 2.2824e+00, 2.2625e+00, 2.2436e+00, 2.2253e+00, 2.2075e+00, 2.1896e+00, 2.1715e+00, 2.1533e+00, 2.1351e+00, 2.1169e+00, 2.0987e+00, 2.0808e+00, 2.0634e+00, 2.0468e+00, 2.0312e+00, 2.0162e+00, 2.0014e+00, 1.9865e+00, 1.9714e+00, 1.9561e+00, 1.9409e+00, 1.9256e+00, 1.9104e+00, 1.8952e+00, 1.8804e+00, 1.8665e+00, 1.8534e+00, 1.8411e+00, 1.8292e+00, 1.8172e+00, 1.8049e+00, 1.7924e+00, 1.7799e+00, 1.7673e+00, 1.7548e+00, 1.7421e+00, 1.7296e+00, 1.7174e+00, 1.7059e+00, 1.6954e+00}); + feg = Vctr_cpu({9.2326e+00, 9.1094e+00, 8.7641e+00, 8.2584e+00, 7.6670e+00, 7.0547e+00, 6.4648e+00, 5.9198e+00, 5.4274e+00, 4.9866e+00, 4.5927e+00, 4.2398e+00, 3.9224e+00, 3.6355e+00, 3.3752e+00, 3.1382e+00, 2.9218e+00, 2.7237e+00, 2.5422e+00, 2.3756e+00, 2.2227e+00, 2.0821e+00, 1.9528e+00, 1.8338e+00, 1.7244e+00, 1.6236e+00, 1.5308e+00, 1.4452e+00, 1.3663e+00, 1.2935e+00, 1.2263e+00, 1.1642e+00, 1.1067e+00, 1.0535e+00, 1.0042e+00, 9.5850e-01, 9.1600e-01, 8.7640e-01, 8.3960e-01, 8.0520e-01, 7.7310e-01, 7.4310e-01, 7.1490e-01, 6.8850e-01, 6.6360e-01, 6.4020e-01, 6.1810e-01, 5.9730e-01, 5.7750e-01, 5.5880e-01, 5.4110e-01, 5.2420e-01, 5.0820e-01, 4.9290e-01, 4.7830e-01, 4.6440e-01, 4.5110e-01, 4.3830e-01, 4.2610e-01, 4.1440e-01, 4.0320e-01, 3.9230e-01, 3.8190e-01, 3.7190e-01, 3.6230e-01, 3.5300e-01, 3.4410e-01, 3.3540e-01, 3.2710e-01, 3.1900e-01, 3.1130e-01, 3.0370e-01, 2.9650e-01, 2.8940e-01, 2.8260e-01, 2.7600e-01, 2.6970e-01, 2.6350e-01, 2.5750e-01, 2.5170e-01, 2.4610e-01, 2.4060e-01, 2.3540e-01, 2.3030e-01, 2.2530e-01, 2.2050e-01, 2.1580e-01, 2.1130e-01, 2.0690e-01, 2.0260e-01, 1.9840e-01, 1.9440e-01, 1.9050e-01, 1.8670e-01, 1.8300e-01, 1.7940e-01, 1.7590e-01, 1.7250e-01, 1.6920e-01, 1.6600e-01, 1.6290e-01, 1.5990e-01, 1.5690e-01, 1.5400e-01, 1.5130e-01, 1.4850e-01, 1.4590e-01, 1.4330e-01, 1.4080e-01, 1.3840e-01, 1.3600e-01, 1.3370e-01, 1.3140e-01, 1.2920e-01, 1.2700e-01, 1.2500e-01, 1.2290e-01, 1.2090e-01, 1.1900e-01, 1.1710e-01, 1.1520e-01, 1.1340e-01, 1.1170e-01, 1.1000e-01, 1.0830e-01, 1.0660e-01, 1.0500e-01, 1.0350e-01, 1.0190e-01, 1.0040e-01, 9.9000e-02, 9.7600e-02, 9.6200e-02, 9.4800e-02, 9.3500e-02, 9.2100e-02, 9.0900e-02, 8.9600e-02, 8.8400e-02, 8.7200e-02, 8.6000e-02, 8.4900e-02, 8.3700e-02, 8.2600e-02, 8.1500e-02, 8.0500e-02, 7.9400e-02, 7.8400e-02, 7.7400e-02, 7.6400e-02, 7.5500e-02, 7.4500e-02, 7.3600e-02, 7.2700e-02, 7.1800e-02, 7.1000e-02, 7.0100e-02, 6.9300e-02, 6.8400e-02, 6.7600e-02, 6.6800e-02, 6.6000e-02, 6.5300e-02, 6.4500e-02, 6.3800e-02, 6.3000e-02, 6.2300e-02, 6.1600e-02, 6.0900e-02, 6.0300e-02, 5.9600e-02, 5.8900e-02, 5.8300e-02, 5.7600e-02, 5.7000e-02, 5.6400e-02, 5.5800e-02, 5.5200e-02, 5.4600e-02, 5.4000e-02, 5.3500e-02, 5.2900e-02, 5.2400e-02, 5.1800e-02, 5.1300e-02, 5.0800e-02, 5.0200e-02, 4.9700e-02, 4.9200e-02, 4.8700e-02, 4.8200e-02, 4.7800e-02, 4.7300e-02, 4.6800e-02, 4.6400e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1700e-02, 4.1300e-02, 4.1000e-02, 4.0600e-02, 4.0200e-02, 3.9800e-02, 3.9500e-02, 3.9100e-02, 3.8800e-02, 3.8400e-02, 3.8100e-02, 3.7700e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6400e-02, 3.6100e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4300e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02, 3.2300e-02, 3.2100e-02, 3.1800e-02, 3.1500e-02, 3.1300e-02, 3.1000e-02, 3.0800e-02}); + } + break; + case 49: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({4.9000e+01, 4.8732e+01, 4.7980e+01, 4.6867e+01, 4.5533e+01, 4.4088e+01, 4.2602e+01, 4.1112e+01, 3.9638e+01, 3.8190e+01, 3.6774e+01, 3.5395e+01, 3.4059e+01, 3.2771e+01, 3.1537e+01, 3.0361e+01, 2.9246e+01, 2.8195e+01, 2.7207e+01, 2.6284e+01, 2.5424e+01, 2.4623e+01, 2.3880e+01, 2.3190e+01, 2.2551e+01, 2.1957e+01, 2.1404e+01, 2.0889e+01, 2.0407e+01, 1.9955e+01, 1.9528e+01, 1.9122e+01, 1.8736e+01, 1.8366e+01, 1.8010e+01, 1.7665e+01, 1.7330e+01, 1.7002e+01, 1.6681e+01, 1.6365e+01, 1.6053e+01, 1.5745e+01, 1.5441e+01, 1.5139e+01, 1.4840e+01, 1.4543e+01, 1.4250e+01, 1.3958e+01, 1.3670e+01, 1.3384e+01, 1.3102e+01, 1.2823e+01, 1.2548e+01, 1.2277e+01, 1.2010e+01, 1.1748e+01, 1.1491e+01, 1.1239e+01, 1.0992e+01, 1.0752e+01, 1.0516e+01, 1.0287e+01, 1.0064e+01, 9.8474e+00, 9.6368e+00, 9.4327e+00, 9.2350e+00, 9.0437e+00, 8.8587e+00, 8.6802e+00, 8.5079e+00, 8.3419e+00, 8.1820e+00, 8.0282e+00, 7.8803e+00, 7.7382e+00, 7.6017e+00, 7.4707e+00, 7.3450e+00, 7.2246e+00, 7.1091e+00, 6.9984e+00, 6.8924e+00, 6.7908e+00, 6.6936e+00, 6.6004e+00, 6.5111e+00, 6.4255e+00, 6.3436e+00, 6.2651e+00, 6.1897e+00, 6.1172e+00, 6.0477e+00, 5.9810e+00, 5.9170e+00, 5.8552e+00, 5.7955e+00, 5.7380e+00, 5.6826e+00, 5.6293e+00, 5.5776e+00, 5.5272e+00, 5.4783e+00, 5.4310e+00, 5.3852e+00, 5.3406e+00, 5.2970e+00, 5.2541e+00, 5.2121e+00, 5.1711e+00, 5.1312e+00, 5.0922e+00, 5.0536e+00, 5.0153e+00, 4.9773e+00, 4.9401e+00, 4.9036e+00, 4.8678e+00, 4.8322e+00, 4.7966e+00, 4.7610e+00, 4.7256e+00, 4.6908e+00, 4.6565e+00, 4.6227e+00, 4.5887e+00, 4.5545e+00, 4.5202e+00, 4.4859e+00, 4.4521e+00, 4.4189e+00, 4.3859e+00, 4.3529e+00, 4.3195e+00, 4.2857e+00, 4.2519e+00, 4.2184e+00, 4.1855e+00, 4.1531e+00, 4.1207e+00, 4.0881e+00, 4.0550e+00, 4.0216e+00, 3.9883e+00, 3.9554e+00, 3.9231e+00, 3.8913e+00, 3.8596e+00, 3.8277e+00, 3.7953e+00, 3.7626e+00, 3.7299e+00, 3.6976e+00, 3.6659e+00, 3.6350e+00, 3.6043e+00, 3.5736e+00, 3.5425e+00, 3.5111e+00, 3.4795e+00, 3.4480e+00, 3.4170e+00, 3.3868e+00, 3.3575e+00, 3.3284e+00, 3.2992e+00, 3.2697e+00, 3.2399e+00, 3.2100e+00, 3.1801e+00, 3.1507e+00, 3.1222e+00, 3.0946e+00, 3.0675e+00, 3.0405e+00, 3.0133e+00, 2.9858e+00, 2.9581e+00, 2.9304e+00, 2.9028e+00, 2.8758e+00, 2.8498e+00, 2.8247e+00, 2.8002e+00, 2.7758e+00, 2.7511e+00, 2.7262e+00, 2.7011e+00, 2.6760e+00, 2.6510e+00, 2.6264e+00, 2.6026e+00, 2.5800e+00, 2.5581e+00, 2.5366e+00, 2.5149e+00, 2.4929e+00, 2.4708e+00, 2.4487e+00, 2.4265e+00, 2.4044e+00, 2.3826e+00, 2.3618e+00, 2.3421e+00, 2.3232e+00, 2.3047e+00, 2.2861e+00, 2.2672e+00, 2.2481e+00, 2.2289e+00, 2.2098e+00, 2.1906e+00, 2.1715e+00, 2.1530e+00, 2.1356e+00, 2.1192e+00, 2.1036e+00, 2.0881e+00, 2.0724e+00, 2.0563e+00, 2.0401e+00, 2.0240e+00, 2.0078e+00, 1.9916e+00, 1.9753e+00, 1.9594e+00, 1.9445e+00, 1.9306e+00, 1.9177e+00, 1.9052e+00, 1.8925e+00, 1.8793e+00, 1.8659e+00, 1.8525e+00, 1.8391e+00, 1.8257e+00, 1.8122e+00, 1.7986e+00, 1.7854e+00, 1.7730e+00, 1.7617e+00}); + feg = Vctr_cpu({1.0424e+01, 1.0248e+01, 9.7632e+00, 9.0737e+00, 8.2971e+00, 7.5239e+00, 6.8061e+00, 6.1644e+00, 5.6014e+00, 5.1105e+00, 4.6819e+00, 4.3058e+00, 3.9733e+00, 3.6773e+00, 3.4119e+00, 3.1723e+00, 2.9549e+00, 2.7568e+00, 2.5757e+00, 2.4096e+00, 2.2571e+00, 2.1168e+00, 1.9875e+00, 1.8683e+00, 1.7584e+00, 1.6569e+00, 1.5632e+00, 1.4766e+00, 1.3966e+00, 1.3225e+00, 1.2540e+00, 1.1906e+00, 1.1317e+00, 1.0772e+00, 1.0266e+00, 9.7950e-01, 9.3580e-01, 8.9510e-01, 8.5710e-01, 8.2160e-01, 7.8850e-01, 7.5760e-01, 7.2850e-01, 7.0130e-01, 6.7570e-01, 6.5160e-01, 6.2890e-01, 6.0750e-01, 5.8720e-01, 5.6800e-01, 5.4990e-01, 5.3260e-01, 5.1620e-01, 5.0060e-01, 4.8580e-01, 4.7160e-01, 4.5800e-01, 4.4510e-01, 4.3270e-01, 4.2080e-01, 4.0940e-01, 3.9840e-01, 3.8790e-01, 3.7780e-01, 3.6800e-01, 3.5860e-01, 3.4960e-01, 3.4090e-01, 3.3240e-01, 3.2430e-01, 3.1640e-01, 3.0890e-01, 3.0150e-01, 2.9440e-01, 2.8760e-01, 2.8090e-01, 2.7450e-01, 2.6820e-01, 2.6220e-01, 2.5630e-01, 2.5070e-01, 2.4510e-01, 2.3980e-01, 2.3460e-01, 2.2960e-01, 2.2470e-01, 2.2000e-01, 2.1540e-01, 2.1090e-01, 2.0660e-01, 2.0240e-01, 1.9830e-01, 1.9430e-01, 1.9050e-01, 1.8670e-01, 1.8310e-01, 1.7950e-01, 1.7610e-01, 1.7270e-01, 1.6950e-01, 1.6630e-01, 1.6320e-01, 1.6020e-01, 1.5730e-01, 1.5440e-01, 1.5160e-01, 1.4890e-01, 1.4630e-01, 1.4380e-01, 1.4130e-01, 1.3880e-01, 1.3650e-01, 1.3420e-01, 1.3190e-01, 1.2970e-01, 1.2760e-01, 1.2550e-01, 1.2350e-01, 1.2150e-01, 1.1950e-01, 1.1760e-01, 1.1580e-01, 1.1400e-01, 1.1220e-01, 1.1050e-01, 1.0880e-01, 1.0720e-01, 1.0560e-01, 1.0400e-01, 1.0250e-01, 1.0100e-01, 9.9600e-02, 9.8100e-02, 9.6700e-02, 9.5400e-02, 9.4000e-02, 9.2700e-02, 9.1400e-02, 9.0200e-02, 8.8900e-02, 8.7700e-02, 8.6600e-02, 8.5400e-02, 8.4300e-02, 8.3200e-02, 8.2100e-02, 8.1000e-02, 8.0000e-02, 7.9000e-02, 7.8000e-02, 7.7000e-02, 7.6000e-02, 7.5100e-02, 7.4200e-02, 7.3300e-02, 7.2400e-02, 7.1500e-02, 7.0600e-02, 6.9800e-02, 6.9000e-02, 6.8100e-02, 6.7300e-02, 6.6600e-02, 6.5800e-02, 6.5000e-02, 6.4300e-02, 6.3600e-02, 6.2800e-02, 6.2100e-02, 6.1400e-02, 6.0800e-02, 6.0100e-02, 5.9400e-02, 5.8800e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6300e-02, 5.5700e-02, 5.5100e-02, 5.4500e-02, 5.3900e-02, 5.3400e-02, 5.2800e-02, 5.2300e-02, 5.1700e-02, 5.1200e-02, 5.0700e-02, 5.0200e-02, 4.9700e-02, 4.9200e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6800e-02, 4.6400e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2500e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0600e-02, 4.0300e-02, 3.9900e-02, 3.9500e-02, 3.9200e-02, 3.8800e-02, 3.8500e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3300e-02, 3.3000e-02, 3.2700e-02, 3.2400e-02, 3.2200e-02, 3.1900e-02, 3.1700e-02, 3.1400e-02}); + } + break; + case 50: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.0000e+01, 4.9721e+01, 4.8934e+01, 4.7765e+01, 4.6361e+01, 4.4848e+01, 4.3308e+01, 4.1786e+01, 4.0302e+01, 3.8860e+01, 3.7462e+01, 3.6106e+01, 3.4793e+01, 3.3525e+01, 3.2302e+01, 3.1130e+01, 3.0010e+01, 2.8945e+01, 2.7937e+01, 2.6987e+01, 2.6095e+01, 2.5260e+01, 2.4481e+01, 2.3755e+01, 2.3080e+01, 2.2452e+01, 2.1867e+01, 2.1323e+01, 2.0815e+01, 2.0339e+01, 1.9893e+01, 1.9472e+01, 1.9073e+01, 1.8694e+01, 1.8331e+01, 1.7983e+01, 1.7646e+01, 1.7320e+01, 1.7002e+01, 1.6690e+01, 1.6384e+01, 1.6083e+01, 1.5786e+01, 1.5492e+01, 1.5201e+01, 1.4913e+01, 1.4627e+01, 1.4343e+01, 1.4062e+01, 1.3783e+01, 1.3506e+01, 1.3232e+01, 1.2962e+01, 1.2694e+01, 1.2430e+01, 1.2169e+01, 1.1913e+01, 1.1660e+01, 1.1412e+01, 1.1169e+01, 1.0931e+01, 1.0698e+01, 1.0471e+01, 1.0249e+01, 1.0033e+01, 9.8219e+00, 9.6172e+00, 9.4184e+00, 9.2255e+00, 9.0387e+00, 8.8579e+00, 8.6830e+00, 8.5140e+00, 8.3510e+00, 8.1937e+00, 8.0422e+00, 7.8962e+00, 7.7559e+00, 7.6209e+00, 7.4911e+00, 7.3664e+00, 7.2467e+00, 7.1319e+00, 7.0216e+00, 6.9158e+00, 6.8144e+00, 6.7172e+00, 6.6240e+00, 6.5346e+00, 6.4487e+00, 6.3664e+00, 6.2876e+00, 6.2119e+00, 6.1392e+00, 6.0692e+00, 6.0019e+00, 5.9374e+00, 5.8754e+00, 5.8155e+00, 5.7577e+00, 5.7018e+00, 5.6479e+00, 5.5960e+00, 5.5458e+00, 5.4969e+00, 5.4493e+00, 5.4030e+00, 5.3582e+00, 5.3147e+00, 5.2724e+00, 5.2308e+00, 5.1899e+00, 5.1497e+00, 5.1105e+00, 5.0724e+00, 5.0350e+00, 4.9980e+00, 4.9612e+00, 4.9247e+00, 4.8887e+00, 4.8535e+00, 4.8190e+00, 4.7849e+00, 4.7507e+00, 4.7164e+00, 4.6821e+00, 4.6481e+00, 4.6149e+00, 4.5821e+00, 4.5496e+00, 4.5169e+00, 4.4838e+00, 4.4505e+00, 4.4174e+00, 4.3848e+00, 4.3528e+00, 4.3211e+00, 4.2893e+00, 4.2571e+00, 4.2244e+00, 4.1915e+00, 4.1590e+00, 4.1271e+00, 4.0957e+00, 4.0646e+00, 4.0333e+00, 4.0016e+00, 3.9693e+00, 3.9369e+00, 3.9047e+00, 3.8732e+00, 3.8423e+00, 3.8119e+00, 3.7815e+00, 3.7506e+00, 3.7193e+00, 3.6876e+00, 3.6559e+00, 3.6246e+00, 3.5943e+00, 3.5646e+00, 3.5353e+00, 3.5060e+00, 3.4763e+00, 3.4461e+00, 3.4155e+00, 3.3849e+00, 3.3548e+00, 3.3257e+00, 3.2974e+00, 3.2697e+00, 3.2420e+00, 3.2142e+00, 3.1859e+00, 3.1572e+00, 3.1282e+00, 3.0995e+00, 3.0715e+00, 3.0446e+00, 3.0186e+00, 2.9930e+00, 2.9675e+00, 2.9418e+00, 2.9157e+00, 2.8892e+00, 2.8625e+00, 2.8359e+00, 2.8100e+00, 2.7851e+00, 2.7614e+00, 2.7383e+00, 2.7153e+00, 2.6923e+00, 2.6690e+00, 2.6455e+00, 2.6215e+00, 2.5974e+00, 2.5734e+00, 2.5503e+00, 2.5284e+00, 2.5075e+00, 2.4872e+00, 2.4672e+00, 2.4470e+00, 2.4266e+00, 2.4060e+00, 2.3850e+00, 2.3637e+00, 2.3424e+00, 2.3217e+00, 2.3020e+00, 2.2836e+00, 2.2660e+00, 2.2489e+00, 2.2317e+00, 2.2143e+00, 2.1969e+00, 2.1792e+00, 2.1612e+00, 2.1428e+00, 2.1243e+00, 2.1063e+00, 2.0894e+00, 2.0736e+00, 2.0589e+00, 2.0447e+00, 2.0304e+00, 2.0159e+00, 2.0014e+00, 1.9867e+00, 1.9718e+00, 1.9566e+00, 1.9409e+00, 1.9252e+00, 1.9101e+00, 1.8960e+00, 1.8832e+00, 1.8714e+00, 1.8599e+00, 1.8483e+00, 1.8365e+00}); + feg = Vctr_cpu({1.0858e+01, 1.0686e+01, 1.0206e+01, 9.5111e+00, 8.7089e+00, 7.8914e+00, 7.1182e+00, 6.4191e+00, 5.8029e+00, 5.2666e+00, 4.8014e+00, 4.3971e+00, 4.0439e+00, 3.7332e+00, 3.4577e+00, 3.2116e+00, 2.9902e+00, 2.7899e+00, 2.6076e+00, 2.4411e+00, 2.2885e+00, 2.1482e+00, 2.0190e+00, 1.8998e+00, 1.7897e+00, 1.6879e+00, 1.5937e+00, 1.5064e+00, 1.4255e+00, 1.3506e+00, 1.2810e+00, 1.2165e+00, 1.1565e+00, 1.1008e+00, 1.0491e+00, 1.0009e+00, 9.5600e-01, 9.1410e-01, 8.7510e-01, 8.3860e-01, 8.0450e-01, 7.7260e-01, 7.4270e-01, 7.1470e-01, 6.8830e-01, 6.6350e-01, 6.4020e-01, 6.1810e-01, 5.9730e-01, 5.7760e-01, 5.5900e-01, 5.4130e-01, 5.2450e-01, 5.0860e-01, 4.9340e-01, 4.7890e-01, 4.6510e-01, 4.5190e-01, 4.3930e-01, 4.2720e-01, 4.1560e-01, 4.0450e-01, 3.9380e-01, 3.8350e-01, 3.7370e-01, 3.6420e-01, 3.5500e-01, 3.4620e-01, 3.3770e-01, 3.2950e-01, 3.2150e-01, 3.1390e-01, 3.0650e-01, 2.9930e-01, 2.9240e-01, 2.8560e-01, 2.7910e-01, 2.7280e-01, 2.6670e-01, 2.6080e-01, 2.5510e-01, 2.4950e-01, 2.4410e-01, 2.3890e-01, 2.3380e-01, 2.2890e-01, 2.2410e-01, 2.1950e-01, 2.1490e-01, 2.1050e-01, 2.0630e-01, 2.0210e-01, 1.9810e-01, 1.9420e-01, 1.9040e-01, 1.8670e-01, 1.8310e-01, 1.7960e-01, 1.7620e-01, 1.7290e-01, 1.6960e-01, 1.6650e-01, 1.6340e-01, 1.6050e-01, 1.5760e-01, 1.5470e-01, 1.5200e-01, 1.4930e-01, 1.4670e-01, 1.4420e-01, 1.4170e-01, 1.3930e-01, 1.3690e-01, 1.3460e-01, 1.3240e-01, 1.3020e-01, 1.2810e-01, 1.2600e-01, 1.2400e-01, 1.2200e-01, 1.2010e-01, 1.1820e-01, 1.1630e-01, 1.1450e-01, 1.1280e-01, 1.1110e-01, 1.0940e-01, 1.0780e-01, 1.0620e-01, 1.0460e-01, 1.0310e-01, 1.0160e-01, 1.0010e-01, 9.8700e-02, 9.7300e-02, 9.5900e-02, 9.4600e-02, 9.3300e-02, 9.2000e-02, 9.0700e-02, 8.9500e-02, 8.8300e-02, 8.7100e-02, 8.6000e-02, 8.4800e-02, 8.3700e-02, 8.2600e-02, 8.1600e-02, 8.0500e-02, 7.9500e-02, 7.8500e-02, 7.7500e-02, 7.6600e-02, 7.5600e-02, 7.4700e-02, 7.3800e-02, 7.2900e-02, 7.2000e-02, 7.1100e-02, 7.0300e-02, 6.9500e-02, 6.8600e-02, 6.7800e-02, 6.7100e-02, 6.6300e-02, 6.5500e-02, 6.4800e-02, 6.4000e-02, 6.3300e-02, 6.2600e-02, 6.1900e-02, 6.1200e-02, 6.0600e-02, 5.9900e-02, 5.9200e-02, 5.8600e-02, 5.8000e-02, 5.7400e-02, 5.6800e-02, 5.6100e-02, 5.5600e-02, 5.5000e-02, 5.4400e-02, 5.3800e-02, 5.3300e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0600e-02, 5.0100e-02, 4.9600e-02, 4.9100e-02, 4.8700e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1000e-02, 4.0700e-02, 4.0300e-02, 3.9900e-02, 3.9600e-02, 3.9200e-02, 3.8900e-02, 3.8500e-02, 3.8200e-02, 3.7900e-02, 3.7600e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5100e-02, 3.4800e-02, 3.4500e-02, 3.4200e-02, 3.3900e-02, 3.3600e-02, 3.3400e-02, 3.3100e-02, 3.2800e-02, 3.2500e-02, 3.2300e-02, 3.2000e-02}); + } + break; + case 51: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.1000e+01, 5.0717e+01, 4.9914e+01, 4.8708e+01, 4.7247e+01, 4.5664e+01, 4.4055e+01, 4.2476e+01, 4.0955e+01, 3.9497e+01, 3.8100e+01, 3.6758e+01, 3.5465e+01, 3.4218e+01, 3.3015e+01, 3.1857e+01, 3.0744e+01, 2.9678e+01, 2.8662e+01, 2.7696e+01, 2.6783e+01, 2.5921e+01, 2.5112e+01, 2.4354e+01, 2.3645e+01, 2.2983e+01, 2.2365e+01, 2.1790e+01, 2.1253e+01, 2.0750e+01, 2.0280e+01, 1.9839e+01, 1.9423e+01, 1.9030e+01, 1.8657e+01, 1.8300e+01, 1.7958e+01, 1.7629e+01, 1.7310e+01, 1.7000e+01, 1.6697e+01, 1.6401e+01, 1.6109e+01, 1.5822e+01, 1.5538e+01, 1.5257e+01, 1.4979e+01, 1.4703e+01, 1.4429e+01, 1.4157e+01, 1.3887e+01, 1.3620e+01, 1.3355e+01, 1.3092e+01, 1.2832e+01, 1.2575e+01, 1.2320e+01, 1.2070e+01, 1.1823e+01, 1.1579e+01, 1.1340e+01, 1.1106e+01, 1.0876e+01, 1.0650e+01, 1.0430e+01, 1.0214e+01, 1.0004e+01, 9.7997e+00, 9.6004e+00, 9.4067e+00, 9.2185e+00, 9.0359e+00, 8.8590e+00, 8.6876e+00, 8.5219e+00, 8.3617e+00, 8.2069e+00, 8.0576e+00, 7.9136e+00, 7.7749e+00, 7.6413e+00, 7.5127e+00, 7.3890e+00, 7.2701e+00, 7.1559e+00, 7.0461e+00, 6.9406e+00, 6.8393e+00, 6.7422e+00, 6.6489e+00, 6.5593e+00, 6.4733e+00, 6.3907e+00, 6.3115e+00, 6.2355e+00, 6.1623e+00, 6.0920e+00, 6.0243e+00, 5.9594e+00, 5.8969e+00, 5.8366e+00, 5.7784e+00, 5.7222e+00, 5.6680e+00, 5.6157e+00, 5.5652e+00, 5.5162e+00, 5.4684e+00, 5.4220e+00, 5.3771e+00, 5.3335e+00, 5.2911e+00, 5.2496e+00, 5.2089e+00, 5.1689e+00, 5.1299e+00, 5.0919e+00, 5.0547e+00, 5.0181e+00, 4.9818e+00, 4.9458e+00, 4.9103e+00, 4.8755e+00, 4.8414e+00, 4.8078e+00, 4.7743e+00, 4.7408e+00, 4.7072e+00, 4.6740e+00, 4.6412e+00, 4.6091e+00, 4.5773e+00, 4.5455e+00, 4.5135e+00, 4.4811e+00, 4.4488e+00, 4.4169e+00, 4.3855e+00, 4.3546e+00, 4.3238e+00, 4.2927e+00, 4.2611e+00, 4.2293e+00, 4.1975e+00, 4.1661e+00, 4.1353e+00, 4.1050e+00, 4.0748e+00, 4.0442e+00, 4.0131e+00, 3.9817e+00, 3.9501e+00, 3.9190e+00, 3.8885e+00, 3.8587e+00, 3.8292e+00, 3.7995e+00, 3.7693e+00, 3.7386e+00, 3.7076e+00, 3.6768e+00, 3.6464e+00, 3.6169e+00, 3.5882e+00, 3.5597e+00, 3.5310e+00, 3.5019e+00, 3.4722e+00, 3.4422e+00, 3.4123e+00, 3.3829e+00, 3.3544e+00, 3.3268e+00, 3.2998e+00, 3.2728e+00, 3.2454e+00, 3.2176e+00, 3.1893e+00, 3.1608e+00, 3.1325e+00, 3.1049e+00, 3.0784e+00, 3.0528e+00, 3.0278e+00, 3.0029e+00, 2.9776e+00, 2.9518e+00, 2.9256e+00, 2.8992e+00, 2.8728e+00, 2.8471e+00, 2.8223e+00, 2.7986e+00, 2.7758e+00, 2.7534e+00, 2.7309e+00, 2.7079e+00, 2.6844e+00, 2.6606e+00, 2.6366e+00, 2.6127e+00, 2.5894e+00, 2.5672e+00, 2.5462e+00, 2.5261e+00, 2.5065e+00, 2.4867e+00, 2.4666e+00, 2.4459e+00, 2.4250e+00, 2.4038e+00, 2.3825e+00, 2.3615e+00, 2.3413e+00, 2.3223e+00, 2.3044e+00, 2.2875e+00, 2.2708e+00, 2.2538e+00, 2.2364e+00, 2.2186e+00, 2.2005e+00, 2.1822e+00, 2.1637e+00, 2.1454e+00, 2.1277e+00, 2.1110e+00, 2.0957e+00, 2.0814e+00, 2.0675e+00, 2.0536e+00, 2.0393e+00, 2.0245e+00, 2.0093e+00, 1.9940e+00, 1.9784e+00, 1.9627e+00, 1.9471e+00, 1.9320e+00, 1.9180e+00, 1.9053e+00}); + feg = Vctr_cpu({1.0990e+01, 1.0835e+01, 1.0398e+01, 9.7507e+00, 8.9816e+00, 8.1736e+00, 7.3879e+00, 6.6614e+00, 6.0105e+00, 5.4382e+00, 4.9400e+00, 4.5074e+00, 4.1312e+00, 3.8026e+00, 3.5138e+00, 3.2581e+00, 3.0300e+00, 2.8252e+00, 2.6402e+00, 2.4720e+00, 2.3184e+00, 2.1777e+00, 2.0482e+00, 1.9289e+00, 1.8187e+00, 1.7166e+00, 1.6221e+00, 1.5344e+00, 1.4530e+00, 1.3774e+00, 1.3071e+00, 1.2417e+00, 1.1808e+00, 1.1242e+00, 1.0714e+00, 1.0222e+00, 9.7630e-01, 9.3350e-01, 8.9340e-01, 8.5600e-01, 8.2100e-01, 7.8820e-01, 7.5740e-01, 7.2860e-01, 7.0140e-01, 6.7590e-01, 6.5190e-01, 6.2920e-01, 6.0780e-01, 5.8760e-01, 5.6850e-01, 5.5030e-01, 5.3310e-01, 5.1680e-01, 5.0120e-01, 4.8640e-01, 4.7230e-01, 4.5880e-01, 4.4600e-01, 4.3370e-01, 4.2190e-01, 4.1060e-01, 3.9970e-01, 3.8930e-01, 3.7930e-01, 3.6970e-01, 3.6040e-01, 3.5150e-01, 3.4290e-01, 3.3450e-01, 3.2650e-01, 3.1880e-01, 3.1130e-01, 3.0410e-01, 2.9710e-01, 2.9030e-01, 2.8370e-01, 2.7740e-01, 2.7120e-01, 2.6520e-01, 2.5940e-01, 2.5380e-01, 2.4840e-01, 2.4310e-01, 2.3790e-01, 2.3300e-01, 2.2810e-01, 2.2340e-01, 2.1890e-01, 2.1440e-01, 2.1010e-01, 2.0590e-01, 2.0180e-01, 1.9790e-01, 1.9400e-01, 1.9030e-01, 1.8660e-01, 1.8300e-01, 1.7960e-01, 1.7620e-01, 1.7290e-01, 1.6980e-01, 1.6670e-01, 1.6360e-01, 1.6070e-01, 1.5780e-01, 1.5500e-01, 1.5230e-01, 1.4960e-01, 1.4700e-01, 1.4450e-01, 1.4210e-01, 1.3970e-01, 1.3730e-01, 1.3500e-01, 1.3280e-01, 1.3060e-01, 1.2850e-01, 1.2650e-01, 1.2440e-01, 1.2250e-01, 1.2050e-01, 1.1870e-01, 1.1680e-01, 1.1500e-01, 1.1330e-01, 1.1160e-01, 1.0990e-01, 1.0830e-01, 1.0670e-01, 1.0510e-01, 1.0360e-01, 1.0210e-01, 1.0060e-01, 9.9200e-02, 9.7800e-02, 9.6400e-02, 9.5100e-02, 9.3800e-02, 9.2500e-02, 9.1300e-02, 9.0000e-02, 8.8800e-02, 8.7600e-02, 8.6500e-02, 8.5400e-02, 8.4200e-02, 8.3200e-02, 8.2100e-02, 8.1000e-02, 8.0000e-02, 7.9000e-02, 7.8000e-02, 7.7100e-02, 7.6100e-02, 7.5200e-02, 7.4300e-02, 7.3400e-02, 7.2500e-02, 7.1600e-02, 7.0800e-02, 7.0000e-02, 6.9100e-02, 6.8300e-02, 6.7500e-02, 6.6800e-02, 6.6000e-02, 6.5300e-02, 6.4500e-02, 6.3800e-02, 6.3100e-02, 6.2400e-02, 6.1700e-02, 6.1000e-02, 6.0400e-02, 5.9700e-02, 5.9100e-02, 5.8400e-02, 5.7800e-02, 5.7200e-02, 5.6600e-02, 5.6000e-02, 5.5400e-02, 5.4900e-02, 5.4300e-02, 5.3700e-02, 5.3200e-02, 5.2600e-02, 5.2100e-02, 5.1600e-02, 5.1100e-02, 5.0600e-02, 5.0100e-02, 4.9600e-02, 4.9100e-02, 4.8600e-02, 4.8100e-02, 4.7700e-02, 4.7200e-02, 4.6800e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0300e-02, 4.0000e-02, 3.9600e-02, 3.9300e-02, 3.8900e-02, 3.8600e-02, 3.8300e-02, 3.7900e-02, 3.7600e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02, 3.5400e-02, 3.5100e-02, 3.4800e-02, 3.4600e-02, 3.4300e-02, 3.4000e-02, 3.3700e-02, 3.3400e-02, 3.3200e-02, 3.2900e-02, 3.2600e-02}); + } + break; + case 52: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.2000e+01, 5.1717e+01, 5.0907e+01, 4.9681e+01, 4.8178e+01, 4.6533e+01, 4.4853e+01, 4.3207e+01, 4.1630e+01, 4.0133e+01, 3.8716e+01, 3.7370e+01, 3.6086e+01, 3.4855e+01, 3.3672e+01, 3.2532e+01, 3.1433e+01, 3.0377e+01, 2.9363e+01, 2.8393e+01, 2.7469e+01, 2.6591e+01, 2.5760e+01, 2.4976e+01, 2.4238e+01, 2.3546e+01, 2.2898e+01, 2.2291e+01, 2.1724e+01, 2.1193e+01, 2.0697e+01, 2.0232e+01, 1.9795e+01, 1.9383e+01, 1.8994e+01, 1.8625e+01, 1.8273e+01, 1.7937e+01, 1.7613e+01, 1.7301e+01, 1.6998e+01, 1.6703e+01, 1.6414e+01, 1.6131e+01, 1.5853e+01, 1.5578e+01, 1.5307e+01, 1.5038e+01, 1.4771e+01, 1.4507e+01, 1.4244e+01, 1.3984e+01, 1.3725e+01, 1.3468e+01, 1.3213e+01, 1.2961e+01, 1.2711e+01, 1.2463e+01, 1.2219e+01, 1.1977e+01, 1.1739e+01, 1.1505e+01, 1.1274e+01, 1.1047e+01, 1.0825e+01, 1.0606e+01, 1.0393e+01, 1.0184e+01, 9.9796e+00, 9.7804e+00, 9.5863e+00, 9.3974e+00, 9.2137e+00, 9.0352e+00, 8.8620e+00, 8.6940e+00, 8.5313e+00, 8.3739e+00, 8.2216e+00, 8.0744e+00, 7.9324e+00, 7.7953e+00, 7.6631e+00, 7.5357e+00, 7.4129e+00, 7.2948e+00, 7.1812e+00, 7.0718e+00, 6.9667e+00, 6.8656e+00, 6.7685e+00, 6.6752e+00, 6.5855e+00, 6.4992e+00, 6.4164e+00, 6.3369e+00, 6.2605e+00, 6.1869e+00, 6.1162e+00, 6.0481e+00, 5.9827e+00, 5.9197e+00, 5.8591e+00, 5.8005e+00, 5.7439e+00, 5.6892e+00, 5.6366e+00, 5.5858e+00, 5.5365e+00, 5.4886e+00, 5.4420e+00, 5.3968e+00, 5.3530e+00, 5.3105e+00, 5.2691e+00, 5.2285e+00, 5.1887e+00, 5.1497e+00, 5.1116e+00, 5.0746e+00, 5.0383e+00, 5.0025e+00, 4.9671e+00, 4.9319e+00, 4.8973e+00, 4.8633e+00, 4.8301e+00, 4.7973e+00, 4.7647e+00, 4.7321e+00, 4.6995e+00, 4.6671e+00, 4.6351e+00, 4.6038e+00, 4.5728e+00, 4.5420e+00, 4.5110e+00, 4.4797e+00, 4.4483e+00, 4.4171e+00, 4.3863e+00, 4.3561e+00, 4.3263e+00, 4.2963e+00, 4.2660e+00, 4.2353e+00, 4.2044e+00, 4.1735e+00, 4.1432e+00, 4.1135e+00, 4.0841e+00, 4.0548e+00, 4.0252e+00, 3.9951e+00, 3.9645e+00, 3.9339e+00, 3.9036e+00, 3.8739e+00, 3.8449e+00, 3.8163e+00, 3.7876e+00, 3.7586e+00, 3.7290e+00, 3.6989e+00, 3.6687e+00, 3.6390e+00, 3.6100e+00, 3.5818e+00, 3.5541e+00, 3.5265e+00, 3.4987e+00, 3.4703e+00, 3.4414e+00, 3.4121e+00, 3.3831e+00, 3.3547e+00, 3.3272e+00, 3.3006e+00, 3.2745e+00, 3.2485e+00, 3.2221e+00, 3.1953e+00, 3.1678e+00, 3.1400e+00, 3.1124e+00, 3.0854e+00, 3.0595e+00, 3.0346e+00, 3.0103e+00, 2.9864e+00, 2.9623e+00, 2.9378e+00, 2.9127e+00, 2.8870e+00, 2.8611e+00, 2.8356e+00, 2.8110e+00, 2.7876e+00, 2.7651e+00, 2.7433e+00, 2.7218e+00, 2.7002e+00, 2.6783e+00, 2.6557e+00, 2.6325e+00, 2.6090e+00, 2.5857e+00, 2.5631e+00, 2.5417e+00, 2.5214e+00, 2.5020e+00, 2.4831e+00, 2.4644e+00, 2.4455e+00, 2.4262e+00, 2.4062e+00, 2.3856e+00, 2.3647e+00, 2.3439e+00, 2.3240e+00, 2.3052e+00, 2.2876e+00, 2.2709e+00, 2.2547e+00, 2.2388e+00, 2.2228e+00, 2.2066e+00, 2.1898e+00, 2.1724e+00, 2.1543e+00, 2.1360e+00, 2.1181e+00, 2.1011e+00, 2.0853e+00, 2.0707e+00, 2.0570e+00, 2.0436e+00, 2.0304e+00, 2.0172e+00, 2.0038e+00, 1.9900e+00}); + feg = Vctr_cpu({1.0990e+01, 1.0853e+01, 1.0460e+01, 9.8675e+00, 9.1484e+00, 8.3740e+00, 7.6021e+00, 6.8719e+00, 6.2051e+00, 5.6102e+00, 5.0869e+00, 4.6299e+00, 4.2319e+00, 3.8848e+00, 3.5809e+00, 3.3134e+00, 3.0765e+00, 2.8652e+00, 2.6755e+00, 2.5041e+00, 2.3485e+00, 2.2064e+00, 2.0761e+00, 1.9563e+00, 1.8457e+00, 1.7434e+00, 1.6486e+00, 1.5606e+00, 1.4788e+00, 1.4027e+00, 1.3319e+00, 1.2659e+00, 1.2044e+00, 1.1469e+00, 1.0934e+00, 1.0433e+00, 9.9650e-01, 9.5280e-01, 9.1190e-01, 8.7360e-01, 8.3770e-01, 8.0410e-01, 7.7250e-01, 7.4290e-01, 7.1500e-01, 6.8880e-01, 6.6410e-01, 6.4080e-01, 6.1880e-01, 5.9800e-01, 5.7830e-01, 5.5970e-01, 5.4200e-01, 5.2530e-01, 5.0940e-01, 4.9420e-01, 4.7980e-01, 4.6600e-01, 4.5280e-01, 4.4030e-01, 4.2830e-01, 4.1670e-01, 4.0570e-01, 3.9510e-01, 3.8500e-01, 3.7520e-01, 3.6580e-01, 3.5670e-01, 3.4800e-01, 3.3960e-01, 3.3150e-01, 3.2360e-01, 3.1610e-01, 3.0870e-01, 3.0170e-01, 2.9480e-01, 2.8820e-01, 2.8180e-01, 2.7550e-01, 2.6950e-01, 2.6370e-01, 2.5800e-01, 2.5250e-01, 2.4720e-01, 2.4200e-01, 2.3690e-01, 2.3210e-01, 2.2730e-01, 2.2270e-01, 2.1820e-01, 2.1380e-01, 2.0960e-01, 2.0550e-01, 2.0150e-01, 1.9760e-01, 1.9380e-01, 1.9010e-01, 1.8650e-01, 1.8300e-01, 1.7950e-01, 1.7620e-01, 1.7300e-01, 1.6980e-01, 1.6680e-01, 1.6380e-01, 1.6090e-01, 1.5800e-01, 1.5520e-01, 1.5250e-01, 1.4990e-01, 1.4730e-01, 1.4480e-01, 1.4240e-01, 1.4000e-01, 1.3770e-01, 1.3540e-01, 1.3320e-01, 1.3110e-01, 1.2900e-01, 1.2690e-01, 1.2490e-01, 1.2290e-01, 1.2100e-01, 1.1910e-01, 1.1730e-01, 1.1550e-01, 1.1380e-01, 1.1210e-01, 1.1040e-01, 1.0880e-01, 1.0720e-01, 1.0560e-01, 1.0410e-01, 1.0260e-01, 1.0110e-01, 9.9700e-02, 9.8300e-02, 9.7000e-02, 9.5600e-02, 9.4300e-02, 9.3000e-02, 9.1800e-02, 9.0500e-02, 8.9300e-02, 8.8200e-02, 8.7000e-02, 8.5900e-02, 8.4800e-02, 8.3700e-02, 8.2600e-02, 8.1600e-02, 8.0500e-02, 7.9500e-02, 7.8500e-02, 7.7600e-02, 7.6600e-02, 7.5700e-02, 7.4800e-02, 7.3900e-02, 7.3000e-02, 7.2100e-02, 7.1300e-02, 7.0400e-02, 6.9600e-02, 6.8800e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5700e-02, 6.5000e-02, 6.4300e-02, 6.3600e-02, 6.2900e-02, 6.2200e-02, 6.1500e-02, 6.0800e-02, 6.0200e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7700e-02, 5.7000e-02, 5.6500e-02, 5.5900e-02, 5.5300e-02, 5.4700e-02, 5.4200e-02, 5.3600e-02, 5.3100e-02, 5.2500e-02, 5.2000e-02, 5.1500e-02, 5.1000e-02, 5.0500e-02, 5.0000e-02, 4.9500e-02, 4.9000e-02, 4.8600e-02, 4.8100e-02, 4.7600e-02, 4.7200e-02, 4.6700e-02, 4.6300e-02, 4.5900e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8600e-02, 3.8300e-02, 3.8000e-02, 3.7700e-02, 3.7300e-02, 3.7000e-02, 3.6700e-02, 3.6400e-02, 3.6100e-02, 3.5800e-02, 3.5500e-02, 3.5200e-02, 3.4900e-02, 3.4600e-02, 3.4300e-02, 3.4100e-02, 3.3800e-02, 3.3500e-02, 3.3200e-02}); + } + break; + case 53: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.3000e+01, 5.2718e+01, 5.1909e+01, 5.0672e+01, 4.9140e+01, 4.7445e+01, 4.5700e+01, 4.3982e+01, 4.2339e+01, 4.0788e+01, 3.9333e+01, 3.7966e+01, 3.6676e+01, 3.5450e+01, 3.4279e+01, 3.3156e+01, 3.2075e+01, 3.1033e+01, 3.0030e+01, 2.9065e+01, 2.8140e+01, 2.7255e+01, 2.6411e+01, 2.5610e+01, 2.4850e+01, 2.4133e+01, 2.3458e+01, 2.2823e+01, 2.2227e+01, 2.1668e+01, 2.1144e+01, 2.0653e+01, 2.0192e+01, 1.9759e+01, 1.9351e+01, 1.8965e+01, 1.8599e+01, 1.8252e+01, 1.7919e+01, 1.7601e+01, 1.7294e+01, 1.6997e+01, 1.6708e+01, 1.6427e+01, 1.6151e+01, 1.5880e+01, 1.5614e+01, 1.5351e+01, 1.5091e+01, 1.4833e+01, 1.4578e+01, 1.4324e+01, 1.4072e+01, 1.3822e+01, 1.3573e+01, 1.3327e+01, 1.3082e+01, 1.2839e+01, 1.2598e+01, 1.2360e+01, 1.2125e+01, 1.1892e+01, 1.1662e+01, 1.1436e+01, 1.1213e+01, 1.0993e+01, 1.0778e+01, 1.0566e+01, 1.0359e+01, 1.0156e+01, 9.9576e+00, 9.7638e+00, 9.5747e+00, 9.3904e+00, 9.2109e+00, 9.0363e+00, 8.8667e+00, 8.7020e+00, 8.5423e+00, 8.3875e+00, 8.2376e+00, 8.0926e+00, 7.9523e+00, 7.8169e+00, 7.6861e+00, 7.5598e+00, 7.4381e+00, 7.3207e+00, 7.2077e+00, 7.0988e+00, 6.9940e+00, 6.8931e+00, 6.7960e+00, 6.7027e+00, 6.6129e+00, 6.5266e+00, 6.4435e+00, 6.3636e+00, 6.2867e+00, 6.2128e+00, 6.1417e+00, 6.0733e+00, 6.0074e+00, 5.9438e+00, 5.8826e+00, 5.8237e+00, 5.7668e+00, 5.7119e+00, 5.6588e+00, 5.6074e+00, 5.5576e+00, 5.5095e+00, 5.4629e+00, 5.4178e+00, 5.3738e+00, 5.3308e+00, 5.2890e+00, 5.2483e+00, 5.2088e+00, 5.1702e+00, 5.1325e+00, 5.0953e+00, 5.0587e+00, 5.0227e+00, 4.9876e+00, 4.9533e+00, 4.9195e+00, 4.8862e+00, 4.8530e+00, 4.8201e+00, 4.7874e+00, 4.7553e+00, 4.7237e+00, 4.6927e+00, 4.6619e+00, 4.6310e+00, 4.6000e+00, 4.5690e+00, 4.5382e+00, 4.5079e+00, 4.4781e+00, 4.4486e+00, 4.4191e+00, 4.3893e+00, 4.3593e+00, 4.3291e+00, 4.2990e+00, 4.2693e+00, 4.2401e+00, 4.2113e+00, 4.1826e+00, 4.1536e+00, 4.1241e+00, 4.0943e+00, 4.0644e+00, 4.0348e+00, 4.0057e+00, 3.9772e+00, 3.9491e+00, 3.9209e+00, 3.8923e+00, 3.8632e+00, 3.8337e+00, 3.8041e+00, 3.7748e+00, 3.7462e+00, 3.7183e+00, 3.6908e+00, 3.6635e+00, 3.6359e+00, 3.6077e+00, 3.5790e+00, 3.5500e+00, 3.5211e+00, 3.4929e+00, 3.4655e+00, 3.4388e+00, 3.4126e+00, 3.3865e+00, 3.3601e+00, 3.3331e+00, 3.3054e+00, 3.2775e+00, 3.2498e+00, 3.2227e+00, 3.1965e+00, 3.1713e+00, 3.1466e+00, 3.1223e+00, 3.0979e+00, 3.0729e+00, 3.0473e+00, 3.0211e+00, 2.9948e+00, 2.9689e+00, 2.9438e+00, 2.9198e+00, 2.8967e+00, 2.8743e+00, 2.8522e+00, 2.8300e+00, 2.8074e+00, 2.7841e+00, 2.7601e+00, 2.7358e+00, 2.7118e+00, 2.6886e+00, 2.6664e+00, 2.6453e+00, 2.6250e+00, 2.6054e+00, 2.5859e+00, 2.5663e+00, 2.5461e+00, 2.5252e+00, 2.5036e+00, 2.4817e+00, 2.4601e+00, 2.4393e+00, 2.4196e+00, 2.4010e+00, 2.3833e+00, 2.3663e+00, 2.3496e+00, 2.3330e+00, 2.3159e+00, 2.2981e+00, 2.2794e+00, 2.2602e+00, 2.2409e+00, 2.2221e+00, 2.2042e+00, 2.1875e+00, 2.1718e+00, 2.1569e+00, 2.1427e+00, 2.1288e+00, 2.1150e+00, 2.1009e+00, 2.0861e+00, 2.0704e+00}); + feg = Vctr_cpu({1.0915e+01, 1.0793e+01, 1.0441e+01, 9.9033e+00, 9.2391e+00, 8.5090e+00, 7.7655e+00, 7.0474e+00, 6.3792e+00, 5.7733e+00, 5.2336e+00, 4.7579e+00, 4.3411e+00, 3.9767e+00, 3.6576e+00, 3.3774e+00, 3.1301e+00, 2.9107e+00, 2.7149e+00, 2.5390e+00, 2.3800e+00, 2.2356e+00, 2.1037e+00, 1.9828e+00, 1.8715e+00, 1.7687e+00, 1.6735e+00, 1.5852e+00, 1.5031e+00, 1.4267e+00, 1.3554e+00, 1.2890e+00, 1.2269e+00, 1.1689e+00, 1.1147e+00, 1.0639e+00, 1.0165e+00, 9.7200e-01, 9.3030e-01, 8.9120e-01, 8.5460e-01, 8.2020e-01, 7.8780e-01, 7.5750e-01, 7.2890e-01, 7.0190e-01, 6.7660e-01, 6.5270e-01, 6.3010e-01, 6.0870e-01, 5.8850e-01, 5.6940e-01, 5.5130e-01, 5.3410e-01, 5.1780e-01, 5.0220e-01, 4.8740e-01, 4.7340e-01, 4.5990e-01, 4.4710e-01, 4.3480e-01, 4.2310e-01, 4.1180e-01, 4.0100e-01, 3.9070e-01, 3.8070e-01, 3.7120e-01, 3.6200e-01, 3.5310e-01, 3.4460e-01, 3.3640e-01, 3.2840e-01, 3.2080e-01, 3.1340e-01, 3.0620e-01, 2.9930e-01, 2.9260e-01, 2.8610e-01, 2.7980e-01, 2.7370e-01, 2.6780e-01, 2.6210e-01, 2.5660e-01, 2.5120e-01, 2.4590e-01, 2.4080e-01, 2.3590e-01, 2.3110e-01, 2.2640e-01, 2.2190e-01, 2.1750e-01, 2.1320e-01, 2.0900e-01, 2.0500e-01, 2.0100e-01, 1.9720e-01, 1.9340e-01, 1.8980e-01, 1.8630e-01, 1.8280e-01, 1.7940e-01, 1.7620e-01, 1.7300e-01, 1.6990e-01, 1.6680e-01, 1.6390e-01, 1.6100e-01, 1.5820e-01, 1.5540e-01, 1.5280e-01, 1.5010e-01, 1.4760e-01, 1.4510e-01, 1.4270e-01, 1.4030e-01, 1.3800e-01, 1.3580e-01, 1.3360e-01, 1.3140e-01, 1.2930e-01, 1.2730e-01, 1.2530e-01, 1.2330e-01, 1.2140e-01, 1.1960e-01, 1.1780e-01, 1.1600e-01, 1.1420e-01, 1.1250e-01, 1.1090e-01, 1.0920e-01, 1.0770e-01, 1.0610e-01, 1.0460e-01, 1.0310e-01, 1.0160e-01, 1.0020e-01, 9.8800e-02, 9.7400e-02, 9.6100e-02, 9.4800e-02, 9.3500e-02, 9.2300e-02, 9.1000e-02, 8.9800e-02, 8.8600e-02, 8.7500e-02, 8.6400e-02, 8.5200e-02, 8.4200e-02, 8.3100e-02, 8.2000e-02, 8.1000e-02, 8.0000e-02, 7.9000e-02, 7.8000e-02, 7.7100e-02, 7.6200e-02, 7.5200e-02, 7.4300e-02, 7.3500e-02, 7.2600e-02, 7.1700e-02, 7.0900e-02, 7.0100e-02, 6.9300e-02, 6.8500e-02, 6.7700e-02, 6.6900e-02, 6.6200e-02, 6.5400e-02, 6.4700e-02, 6.4000e-02, 6.3300e-02, 6.2600e-02, 6.1900e-02, 6.1300e-02, 6.0600e-02, 6.0000e-02, 5.9300e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6300e-02, 5.5700e-02, 5.5200e-02, 5.4600e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2400e-02, 5.1900e-02, 5.1400e-02, 5.0900e-02, 5.0400e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8500e-02, 4.8000e-02, 4.7600e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.5800e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8700e-02, 3.8300e-02, 3.8000e-02, 3.7700e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4400e-02, 3.4100e-02, 3.3900e-02}); + } + break; + case 54: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.4000e+01, 5.3721e+01, 5.2917e+01, 5.1677e+01, 5.0125e+01, 4.8391e+01, 4.6588e+01, 4.4802e+01, 4.3087e+01, 4.1473e+01, 3.9966e+01, 3.8562e+01, 3.7250e+01, 3.6017e+01, 3.4850e+01, 3.3737e+01, 3.2670e+01, 3.1645e+01, 3.0656e+01, 2.9703e+01, 2.8784e+01, 2.7900e+01, 2.7053e+01, 2.6242e+01, 2.5469e+01, 2.4734e+01, 2.4037e+01, 2.3378e+01, 2.2757e+01, 2.2171e+01, 2.1621e+01, 2.1104e+01, 2.0618e+01, 2.0161e+01, 1.9731e+01, 1.9325e+01, 1.8943e+01, 1.8580e+01, 1.8235e+01, 1.7906e+01, 1.7592e+01, 1.7289e+01, 1.6997e+01, 1.6714e+01, 1.6438e+01, 1.6169e+01, 1.5906e+01, 1.5647e+01, 1.5391e+01, 1.5139e+01, 1.4889e+01, 1.4642e+01, 1.4397e+01, 1.4153e+01, 1.3911e+01, 1.3671e+01, 1.3432e+01, 1.3195e+01, 1.2959e+01, 1.2725e+01, 1.2494e+01, 1.2264e+01, 1.2037e+01, 1.1812e+01, 1.1591e+01, 1.1372e+01, 1.1156e+01, 1.0944e+01, 1.0735e+01, 1.0530e+01, 1.0329e+01, 1.0131e+01, 9.9384e+00, 9.7497e+00, 9.5653e+00, 9.3854e+00, 9.2100e+00, 9.0392e+00, 8.8731e+00, 8.7115e+00, 8.5547e+00, 8.4025e+00, 8.2549e+00, 8.1119e+00, 7.9735e+00, 7.8396e+00, 7.7102e+00, 7.5851e+00, 7.4643e+00, 7.3478e+00, 7.2354e+00, 7.1270e+00, 7.0225e+00, 6.9218e+00, 6.8248e+00, 6.7315e+00, 6.6416e+00, 6.5551e+00, 6.4717e+00, 6.3915e+00, 6.3144e+00, 6.2401e+00, 6.1686e+00, 6.0997e+00, 6.0333e+00, 5.9693e+00, 5.9077e+00, 5.8483e+00, 5.7910e+00, 5.7355e+00, 5.6819e+00, 5.6302e+00, 5.5801e+00, 5.5318e+00, 5.4849e+00, 5.4393e+00, 5.3949e+00, 5.3518e+00, 5.3100e+00, 5.2693e+00, 5.2298e+00, 5.1911e+00, 5.1531e+00, 5.1159e+00, 5.0795e+00, 5.0439e+00, 5.0091e+00, 4.9750e+00, 4.9414e+00, 4.9081e+00, 4.8751e+00, 4.8426e+00, 4.8106e+00, 4.7792e+00, 4.7482e+00, 4.7176e+00, 4.6870e+00, 4.6564e+00, 4.6259e+00, 4.5956e+00, 4.5658e+00, 4.5365e+00, 4.5075e+00, 4.4784e+00, 4.4493e+00, 4.4199e+00, 4.3904e+00, 4.3611e+00, 4.3322e+00, 4.3037e+00, 4.2755e+00, 4.2474e+00, 4.2190e+00, 4.1903e+00, 4.1613e+00, 4.1322e+00, 4.1034e+00, 4.0751e+00, 4.0473e+00, 4.0197e+00, 3.9921e+00, 3.9641e+00, 3.9357e+00, 3.9069e+00, 3.8781e+00, 3.8496e+00, 3.8216e+00, 3.7943e+00, 3.7673e+00, 3.7404e+00, 3.7132e+00, 3.6855e+00, 3.6573e+00, 3.6289e+00, 3.6007e+00, 3.5730e+00, 3.5460e+00, 3.5196e+00, 3.4937e+00, 3.4678e+00, 3.4416e+00, 3.4149e+00, 3.3876e+00, 3.3601e+00, 3.3327e+00, 3.3059e+00, 3.2799e+00, 3.2548e+00, 3.2303e+00, 3.2059e+00, 3.1815e+00, 3.1565e+00, 3.1310e+00, 3.1050e+00, 3.0788e+00, 3.0530e+00, 3.0279e+00, 3.0038e+00, 2.9806e+00, 2.9581e+00, 2.9358e+00, 2.9134e+00, 2.8905e+00, 2.8670e+00, 2.8430e+00, 2.8186e+00, 2.7945e+00, 2.7710e+00, 2.7486e+00, 2.7272e+00, 2.7068e+00, 2.6868e+00, 2.6670e+00, 2.6469e+00, 2.6263e+00, 2.6050e+00, 2.5832e+00, 2.5610e+00, 2.5391e+00, 2.5179e+00, 2.4977e+00, 2.4788e+00, 2.4607e+00, 2.4434e+00, 2.4263e+00, 2.4090e+00, 2.3914e+00, 2.3730e+00, 2.3540e+00, 2.3344e+00, 2.3146e+00, 2.2953e+00, 2.2768e+00, 2.2595e+00, 2.2434e+00, 2.2282e+00, 2.2136e+00, 2.1993e+00, 2.1848e+00, 2.1700e+00, 2.1546e+00}); + feg = Vctr_cpu({1.0796e+01, 1.0687e+01, 1.0372e+01, 9.8849e+00, 9.2746e+00, 8.5923e+00, 7.8847e+00, 7.1886e+00, 6.5294e+00, 5.9224e+00, 5.3742e+00, 4.8857e+00, 4.4542e+00, 4.0747e+00, 3.7415e+00, 3.4487e+00, 3.1906e+00, 2.9622e+00, 2.7591e+00, 2.5774e+00, 2.4141e+00, 2.2663e+00, 2.1320e+00, 2.0094e+00, 1.8968e+00, 1.7931e+00, 1.6973e+00, 1.6085e+00, 1.5261e+00, 1.4493e+00, 1.3777e+00, 1.3109e+00, 1.2484e+00, 1.1899e+00, 1.1352e+00, 1.0839e+00, 1.0359e+00, 9.9080e-01, 9.4850e-01, 9.0870e-01, 8.7140e-01, 8.3630e-01, 8.0330e-01, 7.7220e-01, 7.4300e-01, 7.1540e-01, 6.8940e-01, 6.6490e-01, 6.4170e-01, 6.1980e-01, 5.9910e-01, 5.7950e-01, 5.6090e-01, 5.4320e-01, 5.2650e-01, 5.1050e-01, 4.9540e-01, 4.8090e-01, 4.6720e-01, 4.5410e-01, 4.4150e-01, 4.2950e-01, 4.1800e-01, 4.0700e-01, 3.9650e-01, 3.8640e-01, 3.7660e-01, 3.6730e-01, 3.5830e-01, 3.4960e-01, 3.4130e-01, 3.3320e-01, 3.2550e-01, 3.1800e-01, 3.1070e-01, 3.0370e-01, 2.9690e-01, 2.9040e-01, 2.8400e-01, 2.7790e-01, 2.7190e-01, 2.6610e-01, 2.6050e-01, 2.5510e-01, 2.4980e-01, 2.4470e-01, 2.3970e-01, 2.3480e-01, 2.3010e-01, 2.2550e-01, 2.2110e-01, 2.1680e-01, 2.1250e-01, 2.0840e-01, 2.0440e-01, 2.0060e-01, 1.9680e-01, 1.9310e-01, 1.8950e-01, 1.8600e-01, 1.8260e-01, 1.7930e-01, 1.7610e-01, 1.7290e-01, 1.6980e-01, 1.6680e-01, 1.6390e-01, 1.6110e-01, 1.5830e-01, 1.5560e-01, 1.5290e-01, 1.5030e-01, 1.4780e-01, 1.4540e-01, 1.4300e-01, 1.4060e-01, 1.3830e-01, 1.3610e-01, 1.3390e-01, 1.3180e-01, 1.2970e-01, 1.2770e-01, 1.2570e-01, 1.2370e-01, 1.2180e-01, 1.2000e-01, 1.1820e-01, 1.1640e-01, 1.1470e-01, 1.1300e-01, 1.1130e-01, 1.0970e-01, 1.0810e-01, 1.0660e-01, 1.0500e-01, 1.0360e-01, 1.0210e-01, 1.0070e-01, 9.9300e-02, 9.7900e-02, 9.6600e-02, 9.5300e-02, 9.4000e-02, 9.2700e-02, 9.1500e-02, 9.0300e-02, 8.9100e-02, 8.8000e-02, 8.6800e-02, 8.5700e-02, 8.4600e-02, 8.3600e-02, 8.2500e-02, 8.1500e-02, 8.0500e-02, 7.9500e-02, 7.8500e-02, 7.7600e-02, 7.6600e-02, 7.5700e-02, 7.4800e-02, 7.3900e-02, 7.3100e-02, 7.2200e-02, 7.1400e-02, 7.0500e-02, 6.9700e-02, 6.8900e-02, 6.8200e-02, 6.7400e-02, 6.6600e-02, 6.5900e-02, 6.5200e-02, 6.4400e-02, 6.3700e-02, 6.3100e-02, 6.2400e-02, 6.1700e-02, 6.1000e-02, 6.0400e-02, 5.9800e-02, 5.9100e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6700e-02, 5.6100e-02, 5.5600e-02, 5.5000e-02, 5.4500e-02, 5.3900e-02, 5.3400e-02, 5.2800e-02, 5.2300e-02, 5.1800e-02, 5.1300e-02, 5.0800e-02, 5.0300e-02, 4.9800e-02, 4.9400e-02, 4.8900e-02, 4.8400e-02, 4.8000e-02, 4.7500e-02, 4.7100e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5400e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.3000e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8000e-02, 3.7700e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5300e-02, 3.5000e-02, 3.4700e-02, 3.4500e-02}); + } + break; + case 55: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.5000e+01, 5.4589e+01, 5.3530e+01, 5.2138e+01, 5.0602e+01, 4.8977e+01, 4.7290e+01, 4.5578e+01, 4.3888e+01, 4.2258e+01, 4.0712e+01, 3.9261e+01, 3.7903e+01, 3.6633e+01, 3.5439e+01, 3.4312e+01, 3.3241e+01, 3.2218e+01, 3.1236e+01, 3.0291e+01, 2.9381e+01, 2.8505e+01, 2.7660e+01, 2.6849e+01, 2.6071e+01, 2.5327e+01, 2.4617e+01, 2.3942e+01, 2.3301e+01, 2.2695e+01, 2.2122e+01, 2.1581e+01, 2.1071e+01, 2.0591e+01, 2.0139e+01, 1.9712e+01, 1.9310e+01, 1.8929e+01, 1.8569e+01, 1.8227e+01, 1.7900e+01, 1.7588e+01, 1.7289e+01, 1.7001e+01, 1.6722e+01, 1.6451e+01, 1.6188e+01, 1.5930e+01, 1.5677e+01, 1.5428e+01, 1.5183e+01, 1.4941e+01, 1.4701e+01, 1.4463e+01, 1.4227e+01, 1.3993e+01, 1.3760e+01, 1.3529e+01, 1.3299e+01, 1.3071e+01, 1.2844e+01, 1.2619e+01, 1.2395e+01, 1.2174e+01, 1.1955e+01, 1.1738e+01, 1.1523e+01, 1.1312e+01, 1.1103e+01, 1.0898e+01, 1.0695e+01, 1.0496e+01, 1.0301e+01, 1.0109e+01, 9.9211e+00, 9.7374e+00, 9.5581e+00, 9.3823e+00, 9.2104e+00, 9.0433e+00, 8.8810e+00, 8.7228e+00, 8.5683e+00, 8.4182e+00, 8.2732e+00, 8.1328e+00, 7.9963e+00, 7.8634e+00, 7.7349e+00, 7.6114e+00, 7.4922e+00, 7.3766e+00, 7.2642e+00, 7.1558e+00, 7.0519e+00, 6.9522e+00, 6.8557e+00, 6.7618e+00, 6.6711e+00, 6.5844e+00, 6.5014e+00, 6.4216e+00, 6.3441e+00, 6.2687e+00, 6.1961e+00, 6.1269e+00, 6.0607e+00, 5.9969e+00, 5.9348e+00, 5.8741e+00, 5.8156e+00, 5.7599e+00, 5.7064e+00, 5.6548e+00, 5.6047e+00, 5.5553e+00, 5.5071e+00, 5.4610e+00, 5.4169e+00, 5.3741e+00, 5.3326e+00, 5.2919e+00, 5.2512e+00, 5.2116e+00, 5.1736e+00, 5.1370e+00, 5.1011e+00, 5.0662e+00, 5.0316e+00, 4.9967e+00, 4.9623e+00, 4.9292e+00, 4.8971e+00, 4.8654e+00, 4.8342e+00, 4.8036e+00, 4.7726e+00, 4.7411e+00, 4.7102e+00, 4.6806e+00, 4.6514e+00, 4.6222e+00, 4.5934e+00, 4.5650e+00, 4.5360e+00, 4.5061e+00, 4.4768e+00, 4.4487e+00, 4.4209e+00, 4.3928e+00, 4.3649e+00, 4.3376e+00, 4.3099e+00, 4.2811e+00, 4.2521e+00, 4.2240e+00, 4.1969e+00, 4.1696e+00, 4.1420e+00, 4.1148e+00, 4.0880e+00, 4.0606e+00, 4.0321e+00, 4.0033e+00, 3.9756e+00, 3.9489e+00, 3.9221e+00, 3.8949e+00, 3.8679e+00, 3.8415e+00, 3.8150e+00, 3.7873e+00, 3.7588e+00, 3.7307e+00, 3.7040e+00, 3.6779e+00, 3.6516e+00, 3.6250e+00, 3.5988e+00, 3.5732e+00, 3.5473e+00, 3.5203e+00, 3.4924e+00, 3.4649e+00, 3.4388e+00, 3.4137e+00, 3.3885e+00, 3.3630e+00, 3.3377e+00, 3.3130e+00, 3.2887e+00, 3.2635e+00, 3.2372e+00, 3.2104e+00, 3.1843e+00, 3.1599e+00, 3.1363e+00, 3.1126e+00, 3.0887e+00, 3.0651e+00, 3.0421e+00, 3.0194e+00, 2.9961e+00, 2.9717e+00, 2.9464e+00, 2.9216e+00, 2.8983e+00, 2.8763e+00, 2.8547e+00, 2.8330e+00, 2.8113e+00, 2.7901e+00, 2.7695e+00, 2.7489e+00, 2.7274e+00, 2.7049e+00, 2.6817e+00, 2.6588e+00, 2.6376e+00, 2.6177e+00, 2.5984e+00, 2.5791e+00, 2.5599e+00, 2.5411e+00, 2.5228e+00, 2.5048e+00, 2.4863e+00, 2.4667e+00, 2.4462e+00, 2.4252e+00, 2.4050e+00, 2.3865e+00, 2.3693e+00, 2.3525e+00, 2.3359e+00, 2.3195e+00, 2.3034e+00, 2.2878e+00, 2.2725e+00, 2.2567e+00, 2.2400e+00}); + feg = Vctr_cpu({1.6396e+01, 1.5723e+01, 1.4073e+01, 1.2177e+01, 1.0525e+01, 9.2251e+00, 8.2016e+00, 7.3636e+00, 6.6490e+00, 6.0241e+00, 5.4715e+00, 4.9812e+00, 4.5466e+00, 4.1619e+00, 3.8217e+00, 3.5210e+00, 3.2548e+00, 3.0188e+00, 2.8087e+00, 2.6210e+00, 2.4526e+00, 2.3007e+00, 2.1631e+00, 2.0378e+00, 1.9233e+00, 1.8181e+00, 1.7211e+00, 1.6315e+00, 1.5483e+00, 1.4710e+00, 1.3989e+00, 1.3317e+00, 1.2688e+00, 1.2100e+00, 1.1548e+00, 1.1031e+00, 1.0546e+00, 1.0090e+00, 9.6610e-01, 9.2580e-01, 8.8790e-01, 8.5230e-01, 8.1860e-01, 7.8700e-01, 7.5710e-01, 7.2900e-01, 7.0240e-01, 6.7730e-01, 6.5360e-01, 6.3110e-01, 6.0990e-01, 5.8980e-01, 5.7070e-01, 5.5260e-01, 5.3540e-01, 5.1910e-01, 5.0360e-01, 4.8880e-01, 4.7470e-01, 4.6130e-01, 4.4840e-01, 4.3620e-01, 4.2440e-01, 4.1320e-01, 4.0240e-01, 3.9210e-01, 3.8220e-01, 3.7270e-01, 3.6350e-01, 3.5470e-01, 3.4620e-01, 3.3810e-01, 3.3020e-01, 3.2260e-01, 3.1520e-01, 3.0810e-01, 3.0130e-01, 2.9460e-01, 2.8820e-01, 2.8200e-01, 2.7590e-01, 2.7010e-01, 2.6440e-01, 2.5890e-01, 2.5360e-01, 2.4840e-01, 2.4340e-01, 2.3850e-01, 2.3370e-01, 2.2910e-01, 2.2460e-01, 2.2020e-01, 2.1600e-01, 2.1180e-01, 2.0780e-01, 2.0390e-01, 2.0000e-01, 1.9630e-01, 1.9270e-01, 1.8920e-01, 1.8570e-01, 1.8240e-01, 1.7910e-01, 1.7590e-01, 1.7280e-01, 1.6980e-01, 1.6680e-01, 1.6390e-01, 1.6110e-01, 1.5830e-01, 1.5570e-01, 1.5300e-01, 1.5050e-01, 1.4800e-01, 1.4550e-01, 1.4320e-01, 1.4080e-01, 1.3860e-01, 1.3640e-01, 1.3420e-01, 1.3210e-01, 1.3000e-01, 1.2800e-01, 1.2600e-01, 1.2410e-01, 1.2220e-01, 1.2040e-01, 1.1860e-01, 1.1680e-01, 1.1510e-01, 1.1340e-01, 1.1170e-01, 1.1010e-01, 1.0850e-01, 1.0700e-01, 1.0550e-01, 1.0400e-01, 1.0250e-01, 1.0110e-01, 9.9700e-02, 9.8400e-02, 9.7000e-02, 9.5700e-02, 9.4400e-02, 9.3200e-02, 9.2000e-02, 9.0800e-02, 8.9600e-02, 8.8400e-02, 8.7300e-02, 8.6200e-02, 8.5100e-02, 8.4000e-02, 8.3000e-02, 8.1900e-02, 8.0900e-02, 7.9900e-02, 7.9000e-02, 7.8000e-02, 7.7100e-02, 7.6200e-02, 7.5300e-02, 7.4400e-02, 7.3500e-02, 7.2600e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9400e-02, 6.8600e-02, 6.7800e-02, 6.7100e-02, 6.6300e-02, 6.5600e-02, 6.4900e-02, 6.4200e-02, 6.3500e-02, 6.2800e-02, 6.2100e-02, 6.1500e-02, 6.0800e-02, 6.0200e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7700e-02, 5.7100e-02, 5.6500e-02, 5.6000e-02, 5.5400e-02, 5.4900e-02, 5.4300e-02, 5.3800e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0700e-02, 5.0200e-02, 4.9700e-02, 4.9300e-02, 4.8800e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2600e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0100e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7400e-02, 3.7100e-02, 3.6800e-02, 3.6500e-02, 3.6200e-02, 3.5900e-02, 3.5600e-02, 3.5400e-02, 3.5100e-02}); + } + break; + case 56: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.6000e+01, 5.5543e+01, 5.4348e+01, 5.2781e+01, 5.1122e+01, 4.9473e+01, 4.7837e+01, 4.6206e+01, 4.4585e+01, 4.2994e+01, 4.1455e+01, 3.9986e+01, 3.8597e+01, 3.7290e+01, 3.6063e+01, 3.4908e+01, 3.3818e+01, 3.2783e+01, 3.1797e+01, 3.0854e+01, 2.9948e+01, 2.9076e+01, 2.8237e+01, 2.7429e+01, 2.6651e+01, 2.5904e+01, 2.5188e+01, 2.4503e+01, 2.3850e+01, 2.3227e+01, 2.2636e+01, 2.2076e+01, 2.1545e+01, 2.1044e+01, 2.0570e+01, 2.0123e+01, 1.9700e+01, 1.9301e+01, 1.8923e+01, 1.8564e+01, 1.8224e+01, 1.7900e+01, 1.7590e+01, 1.7294e+01, 1.7008e+01, 1.6733e+01, 1.6466e+01, 1.6207e+01, 1.5954e+01, 1.5706e+01, 1.5463e+01, 1.5225e+01, 1.4989e+01, 1.4755e+01, 1.4525e+01, 1.4296e+01, 1.4069e+01, 1.3843e+01, 1.3619e+01, 1.3396e+01, 1.3175e+01, 1.2954e+01, 1.2736e+01, 1.2518e+01, 1.2303e+01, 1.2089e+01, 1.1878e+01, 1.1668e+01, 1.1461e+01, 1.1256e+01, 1.1054e+01, 1.0855e+01, 1.0659e+01, 1.0466e+01, 1.0276e+01, 1.0089e+01, 9.9062e+00, 9.7273e+00, 9.5522e+00, 9.3805e+00, 9.2125e+00, 9.0490e+00, 8.8900e+00, 8.7347e+00, 8.5830e+00, 8.4354e+00, 8.2927e+00, 8.1544e+00, 8.0196e+00, 7.8882e+00, 7.7611e+00, 7.6387e+00, 7.5207e+00, 7.4060e+00, 7.2941e+00, 7.1861e+00, 7.0826e+00, 6.9833e+00, 6.8871e+00, 6.7933e+00, 6.7023e+00, 6.6151e+00, 6.5321e+00, 6.4524e+00, 6.3748e+00, 6.2990e+00, 6.2255e+00, 6.1555e+00, 6.0891e+00, 6.0253e+00, 5.9630e+00, 5.9018e+00, 5.8422e+00, 5.7853e+00, 5.7317e+00, 5.6802e+00, 5.6300e+00, 5.5803e+00, 5.5314e+00, 5.4840e+00, 5.4393e+00, 5.3969e+00, 5.3556e+00, 5.3149e+00, 5.2743e+00, 5.2339e+00, 5.1948e+00, 5.1579e+00, 5.1227e+00, 5.0883e+00, 5.0540e+00, 5.0196e+00, 4.9849e+00, 4.9507e+00, 4.9182e+00, 4.8874e+00, 4.8573e+00, 4.8271e+00, 4.7968e+00, 4.7660e+00, 4.7348e+00, 4.7042e+00, 4.6751e+00, 4.6474e+00, 4.6198e+00, 4.5918e+00, 4.5637e+00, 4.5351e+00, 4.5058e+00, 4.4766e+00, 4.4488e+00, 4.4223e+00, 4.3960e+00, 4.3692e+00, 4.3421e+00, 4.3149e+00, 4.2870e+00, 4.2584e+00, 4.2302e+00, 4.2036e+00, 4.1781e+00, 4.1522e+00, 4.1256e+00, 4.0989e+00, 4.0723e+00, 4.0450e+00, 4.0166e+00, 3.9886e+00, 3.9621e+00, 3.9370e+00, 3.9116e+00, 3.8854e+00, 3.8589e+00, 3.8327e+00, 3.8064e+00, 3.7790e+00, 3.7509e+00, 3.7237e+00, 3.6982e+00, 3.6737e+00, 3.6487e+00, 3.6228e+00, 3.5968e+00, 3.5713e+00, 3.5458e+00, 3.5193e+00, 3.4918e+00, 3.4649e+00, 3.4398e+00, 3.4161e+00, 3.3924e+00, 3.3677e+00, 3.3424e+00, 3.3176e+00, 3.2934e+00, 3.2688e+00, 3.2431e+00, 3.2167e+00, 3.1911e+00, 3.1675e+00, 3.1454e+00, 3.1232e+00, 3.1000e+00, 3.0760e+00, 3.0525e+00, 3.0298e+00, 3.0071e+00, 2.9834e+00, 2.9586e+00, 2.9340e+00, 2.9111e+00, 2.8902e+00, 2.8703e+00, 2.8497e+00, 2.8280e+00, 2.8059e+00, 2.7845e+00, 2.7639e+00, 2.7432e+00, 2.7215e+00, 2.6986e+00, 2.6759e+00, 2.6548e+00, 2.6357e+00, 2.6180e+00, 2.6001e+00, 2.5811e+00, 2.5613e+00, 2.5418e+00, 2.5231e+00, 2.5049e+00, 2.4862e+00, 2.4663e+00, 2.4456e+00, 2.4253e+00, 2.4068e+00, 2.3903e+00, 2.3752e+00, 2.3600e+00, 2.3436e+00, 2.3263e+00}); + feg = Vctr_cpu({1.8164e+01, 1.7509e+01, 1.5818e+01, 1.3696e+01, 1.1675e+01, 9.9984e+00, 8.6829e+00, 7.6539e+00, 6.8300e+00, 6.1489e+00, 5.5698e+00, 5.0681e+00, 4.6280e+00, 4.2395e+00, 3.8953e+00, 3.5898e+00, 3.3182e+00, 3.0764e+00, 2.8605e+00, 2.6674e+00, 2.4941e+00, 2.3379e+00, 2.1966e+00, 2.0682e+00, 1.9512e+00, 1.8440e+00, 1.7454e+00, 1.6545e+00, 1.5703e+00, 1.4923e+00, 1.4196e+00, 1.3518e+00, 1.2885e+00, 1.2292e+00, 1.1737e+00, 1.1215e+00, 1.0726e+00, 1.0266e+00, 9.8330e-01, 9.4250e-01, 9.0410e-01, 8.6790e-01, 8.3380e-01, 8.0160e-01, 7.7130e-01, 7.4260e-01, 7.1550e-01, 6.8980e-01, 6.6560e-01, 6.4260e-01, 6.2090e-01, 6.0030e-01, 5.8080e-01, 5.6230e-01, 5.4470e-01, 5.2790e-01, 5.1200e-01, 4.9690e-01, 4.8240e-01, 4.6870e-01, 4.5550e-01, 4.4300e-01, 4.3100e-01, 4.1950e-01, 4.0850e-01, 3.9800e-01, 3.8790e-01, 3.7820e-01, 3.6890e-01, 3.5990e-01, 3.5130e-01, 3.4290e-01, 3.3490e-01, 3.2720e-01, 3.1980e-01, 3.1260e-01, 3.0560e-01, 2.9890e-01, 2.9240e-01, 2.8610e-01, 2.7990e-01, 2.7400e-01, 2.6830e-01, 2.6270e-01, 2.5730e-01, 2.5210e-01, 2.4700e-01, 2.4210e-01, 2.3730e-01, 2.3260e-01, 2.2810e-01, 2.2360e-01, 2.1930e-01, 2.1520e-01, 2.1110e-01, 2.0710e-01, 2.0330e-01, 1.9950e-01, 1.9580e-01, 1.9230e-01, 1.8880e-01, 1.8540e-01, 1.8210e-01, 1.7880e-01, 1.7570e-01, 1.7260e-01, 1.6960e-01, 1.6670e-01, 1.6390e-01, 1.6110e-01, 1.5840e-01, 1.5570e-01, 1.5310e-01, 1.5060e-01, 1.4810e-01, 1.4570e-01, 1.4330e-01, 1.4100e-01, 1.3880e-01, 1.3660e-01, 1.3450e-01, 1.3240e-01, 1.3030e-01, 1.2830e-01, 1.2630e-01, 1.2440e-01, 1.2250e-01, 1.2070e-01, 1.1890e-01, 1.1720e-01, 1.1540e-01, 1.1380e-01, 1.1210e-01, 1.1050e-01, 1.0890e-01, 1.0740e-01, 1.0590e-01, 1.0440e-01, 1.0300e-01, 1.0150e-01, 1.0020e-01, 9.8800e-02, 9.7500e-02, 9.6200e-02, 9.4900e-02, 9.3600e-02, 9.2400e-02, 9.1200e-02, 9.0000e-02, 8.8900e-02, 8.7700e-02, 8.6600e-02, 8.5500e-02, 8.4500e-02, 8.3400e-02, 8.2400e-02, 8.1400e-02, 8.0400e-02, 7.9400e-02, 7.8500e-02, 7.7500e-02, 7.6600e-02, 7.5700e-02, 7.4800e-02, 7.3900e-02, 7.3100e-02, 7.2200e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9000e-02, 6.8200e-02, 6.7500e-02, 6.6700e-02, 6.6000e-02, 6.5300e-02, 6.4600e-02, 6.3900e-02, 6.3200e-02, 6.2500e-02, 6.1900e-02, 6.1200e-02, 6.0600e-02, 6.0000e-02, 5.9300e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6400e-02, 5.5800e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3600e-02, 5.3100e-02, 5.2600e-02, 5.2100e-02, 5.1600e-02, 5.1100e-02, 5.0600e-02, 5.0100e-02, 4.9600e-02, 4.9200e-02, 4.8700e-02, 4.8300e-02, 4.7800e-02, 4.7400e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2200e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0100e-02, 3.9700e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6300e-02, 3.6000e-02, 3.5700e-02}); + } + break; + case 57: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.7000e+01, 5.6550e+01, 5.5352e+01, 5.3735e+01, 5.1982e+01, 5.0232e+01, 4.8522e+01, 4.6849e+01, 4.5211e+01, 4.3616e+01, 4.2077e+01, 4.0606e+01, 3.9211e+01, 3.7896e+01, 3.6658e+01, 3.5494e+01, 3.4396e+01, 3.3357e+01, 3.2369e+01, 3.1426e+01, 3.0522e+01, 2.9653e+01, 2.8816e+01, 2.8009e+01, 2.7230e+01, 2.6480e+01, 2.5758e+01, 2.5065e+01, 2.4400e+01, 2.3764e+01, 2.3157e+01, 2.2579e+01, 2.2030e+01, 2.1509e+01, 2.1015e+01, 2.0548e+01, 2.0105e+01, 1.9687e+01, 1.9291e+01, 1.8916e+01, 1.8560e+01, 1.8222e+01, 1.7900e+01, 1.7593e+01, 1.7299e+01, 1.7017e+01, 1.6745e+01, 1.6482e+01, 1.6227e+01, 1.5978e+01, 1.5736e+01, 1.5498e+01, 1.5265e+01, 1.5035e+01, 1.4808e+01, 1.4584e+01, 1.4361e+01, 1.4141e+01, 1.3922e+01, 1.3704e+01, 1.3488e+01, 1.3273e+01, 1.3060e+01, 1.2847e+01, 1.2636e+01, 1.2427e+01, 1.2218e+01, 1.2012e+01, 1.1807e+01, 1.1604e+01, 1.1404e+01, 1.1205e+01, 1.1010e+01, 1.0816e+01, 1.0625e+01, 1.0438e+01, 1.0254e+01, 1.0072e+01, 9.8936e+00, 9.7189e+00, 9.5481e+00, 9.3807e+00, 9.2163e+00, 9.0559e+00, 8.8998e+00, 8.7479e+00, 8.5992e+00, 8.4539e+00, 8.3127e+00, 8.1762e+00, 8.0438e+00, 7.9147e+00, 7.7886e+00, 7.6666e+00, 7.5492e+00, 7.4360e+00, 7.3259e+00, 7.2185e+00, 7.1143e+00, 7.0143e+00, 6.9187e+00, 6.8263e+00, 6.7363e+00, 6.6484e+00, 6.5636e+00, 6.4828e+00, 6.4057e+00, 6.3312e+00, 6.2584e+00, 6.1871e+00, 6.1183e+00, 6.0529e+00, 5.9908e+00, 5.9310e+00, 5.8725e+00, 5.8148e+00, 5.7585e+00, 5.7048e+00, 5.6540e+00, 5.6055e+00, 5.5584e+00, 5.5116e+00, 5.4651e+00, 5.4199e+00, 5.3768e+00, 5.3361e+00, 5.2971e+00, 5.2589e+00, 5.2207e+00, 5.1822e+00, 5.1442e+00, 5.1080e+00, 5.0736e+00, 5.0407e+00, 5.0086e+00, 4.9765e+00, 4.9437e+00, 4.9104e+00, 4.8779e+00, 4.8470e+00, 4.8175e+00, 4.7888e+00, 4.7606e+00, 4.7321e+00, 4.7027e+00, 4.6724e+00, 4.6427e+00, 4.6144e+00, 4.5872e+00, 4.5606e+00, 4.5343e+00, 4.5081e+00, 4.4809e+00, 4.4525e+00, 4.4238e+00, 4.3961e+00, 4.3697e+00, 4.3439e+00, 4.3183e+00, 4.2930e+00, 4.2676e+00, 4.2412e+00, 4.2134e+00, 4.1852e+00, 4.1581e+00, 4.1323e+00, 4.1070e+00, 4.0817e+00, 4.0566e+00, 4.0318e+00, 4.0064e+00, 3.9795e+00, 3.9516e+00, 3.9241e+00, 3.8980e+00, 3.8729e+00, 3.8479e+00, 3.8228e+00, 3.7980e+00, 3.7737e+00, 3.7487e+00, 3.7222e+00, 3.6946e+00, 3.6674e+00, 3.6416e+00, 3.6171e+00, 3.5927e+00, 3.5680e+00, 3.5436e+00, 3.5197e+00, 3.4960e+00, 3.4712e+00, 3.4449e+00, 3.4178e+00, 3.3917e+00, 3.3674e+00, 3.3440e+00, 3.3205e+00, 3.2967e+00, 3.2732e+00, 3.2504e+00, 3.2280e+00, 3.2047e+00, 3.1799e+00, 3.1540e+00, 3.1286e+00, 3.1050e+00, 3.0829e+00, 3.0611e+00, 3.0389e+00, 3.0165e+00, 2.9947e+00, 2.9737e+00, 2.9530e+00, 2.9312e+00, 2.9078e+00, 2.8834e+00, 2.8597e+00, 2.8378e+00, 2.8176e+00, 2.7978e+00, 2.7776e+00, 2.7571e+00, 2.7370e+00, 2.7178e+00, 2.6992e+00, 2.6802e+00, 2.6598e+00, 2.6379e+00, 2.6154e+00, 2.5942e+00, 2.5750e+00, 2.5572e+00, 2.5398e+00, 2.5219e+00, 2.5036e+00, 2.4857e+00, 2.4688e+00, 2.4527e+00, 2.4363e+00, 2.4187e+00}); + feg = Vctr_cpu({1.7787e+01, 1.7233e+01, 1.5779e+01, 1.3894e+01, 1.2011e+01, 1.0366e+01, 9.0180e+00, 7.9332e+00, 7.0539e+00, 6.3275e+00, 5.7146e+00, 5.1884e+00, 4.7306e+00, 4.3288e+00, 3.9743e+00, 3.6602e+00, 3.3812e+00, 3.1328e+00, 2.9111e+00, 2.7128e+00, 2.5349e+00, 2.3747e+00, 2.2299e+00, 2.0987e+00, 1.9792e+00, 1.8700e+00, 1.7698e+00, 1.6775e+00, 1.5923e+00, 1.5134e+00, 1.4400e+00, 1.3716e+00, 1.3077e+00, 1.2480e+00, 1.1920e+00, 1.1395e+00, 1.0902e+00, 1.0437e+00, 1.0000e+00, 9.5880e-01, 9.2000e-01, 8.8340e-01, 8.4880e-01, 8.1610e-01, 7.8530e-01, 7.5610e-01, 7.2850e-01, 7.0240e-01, 6.7770e-01, 6.5430e-01, 6.3210e-01, 6.1100e-01, 5.9110e-01, 5.7210e-01, 5.5410e-01, 5.3700e-01, 5.2070e-01, 5.0520e-01, 4.9040e-01, 4.7630e-01, 4.6280e-01, 4.5000e-01, 4.3770e-01, 4.2600e-01, 4.1480e-01, 4.0400e-01, 3.9370e-01, 3.8380e-01, 3.7430e-01, 3.6510e-01, 3.5630e-01, 3.4790e-01, 3.3970e-01, 3.3190e-01, 3.2430e-01, 3.1700e-01, 3.0990e-01, 3.0310e-01, 2.9650e-01, 2.9010e-01, 2.8390e-01, 2.7790e-01, 2.7210e-01, 2.6650e-01, 2.6100e-01, 2.5570e-01, 2.5060e-01, 2.4560e-01, 2.4080e-01, 2.3600e-01, 2.3140e-01, 2.2700e-01, 2.2260e-01, 2.1840e-01, 2.1430e-01, 2.1030e-01, 2.0640e-01, 2.0260e-01, 1.9890e-01, 1.9530e-01, 1.9180e-01, 1.8830e-01, 1.8500e-01, 1.8170e-01, 1.7860e-01, 1.7550e-01, 1.7240e-01, 1.6950e-01, 1.6660e-01, 1.6380e-01, 1.6100e-01, 1.5830e-01, 1.5570e-01, 1.5320e-01, 1.5070e-01, 1.4820e-01, 1.4580e-01, 1.4350e-01, 1.4120e-01, 1.3900e-01, 1.3680e-01, 1.3470e-01, 1.3260e-01, 1.3060e-01, 1.2860e-01, 1.2660e-01, 1.2470e-01, 1.2280e-01, 1.2100e-01, 1.1920e-01, 1.1750e-01, 1.1580e-01, 1.1410e-01, 1.1250e-01, 1.1090e-01, 1.0930e-01, 1.0780e-01, 1.0630e-01, 1.0480e-01, 1.0340e-01, 1.0200e-01, 1.0060e-01, 9.9200e-02, 9.7900e-02, 9.6600e-02, 9.5300e-02, 9.4100e-02, 9.2800e-02, 9.1600e-02, 9.0500e-02, 8.9300e-02, 8.8200e-02, 8.7000e-02, 8.6000e-02, 8.4900e-02, 8.3800e-02, 8.2800e-02, 8.1800e-02, 8.0800e-02, 7.9800e-02, 7.8900e-02, 7.7900e-02, 7.7000e-02, 7.6100e-02, 7.5200e-02, 7.4400e-02, 7.3500e-02, 7.2700e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9400e-02, 6.8700e-02, 6.7900e-02, 6.7200e-02, 6.6400e-02, 6.5700e-02, 6.5000e-02, 6.4300e-02, 6.3600e-02, 6.2900e-02, 6.2300e-02, 6.1600e-02, 6.1000e-02, 6.0400e-02, 5.9700e-02, 5.9100e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6800e-02, 5.6200e-02, 5.5600e-02, 5.5100e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2000e-02, 5.1500e-02, 5.1000e-02, 5.0500e-02, 5.0000e-02, 4.9500e-02, 4.9100e-02, 4.8600e-02, 4.8200e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3300e-02, 4.2900e-02, 4.2500e-02, 4.2100e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6900e-02, 3.6600e-02, 3.6300e-02}); + } + break; + case 58: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.8000e+01, 5.7560e+01, 5.6385e+01, 5.4789e+01, 5.3047e+01, 5.1297e+01, 4.9579e+01, 4.7890e+01, 4.6232e+01, 4.4611e+01, 4.3041e+01, 4.1536e+01, 4.0103e+01, 3.8749e+01, 3.7473e+01, 3.6271e+01, 3.5138e+01, 3.4067e+01, 3.3050e+01, 3.2081e+01, 3.1154e+01, 3.0264e+01, 2.9408e+01, 2.8584e+01, 2.7790e+01, 2.7025e+01, 2.6288e+01, 2.5580e+01, 2.4900e+01, 2.4249e+01, 2.3627e+01, 2.3033e+01, 2.2468e+01, 2.1931e+01, 2.1421e+01, 2.0938e+01, 2.0480e+01, 2.0047e+01, 1.9637e+01, 1.9249e+01, 1.8881e+01, 1.8532e+01, 1.8200e+01, 1.7884e+01, 1.7582e+01, 1.7293e+01, 1.7016e+01, 1.6749e+01, 1.6490e+01, 1.6240e+01, 1.5996e+01, 1.5759e+01, 1.5526e+01, 1.5298e+01, 1.5073e+01, 1.4851e+01, 1.4632e+01, 1.4415e+01, 1.4200e+01, 1.3987e+01, 1.3775e+01, 1.3564e+01, 1.3355e+01, 1.3146e+01, 1.2939e+01, 1.2733e+01, 1.2528e+01, 1.2325e+01, 1.2123e+01, 1.1923e+01, 1.1724e+01, 1.1527e+01, 1.1333e+01, 1.1140e+01, 1.0950e+01, 1.0762e+01, 1.0577e+01, 1.0395e+01, 1.0215e+01, 1.0038e+01, 9.8654e+00, 9.6954e+00, 9.5281e+00, 9.3644e+00, 9.2047e+00, 9.0488e+00, 8.8960e+00, 8.7462e+00, 8.6004e+00, 8.4590e+00, 8.3216e+00, 8.1872e+00, 8.0558e+00, 7.9283e+00, 7.8053e+00, 7.6863e+00, 7.5705e+00, 7.4573e+00, 7.3474e+00, 7.2416e+00, 7.1401e+00, 7.0419e+00, 6.9462e+00, 6.8527e+00, 6.7623e+00, 6.6760e+00, 6.5934e+00, 6.5135e+00, 6.4355e+00, 6.3591e+00, 6.2854e+00, 6.2152e+00, 6.1483e+00, 6.0839e+00, 6.0210e+00, 5.9590e+00, 5.8986e+00, 5.8410e+00, 5.7864e+00, 5.7342e+00, 5.6835e+00, 5.6334e+00, 5.5838e+00, 5.5355e+00, 5.4896e+00, 5.4462e+00, 5.4045e+00, 5.3639e+00, 5.3234e+00, 5.2828e+00, 5.2429e+00, 5.2048e+00, 5.1687e+00, 5.1342e+00, 5.1005e+00, 5.0671e+00, 5.0330e+00, 4.9987e+00, 4.9652e+00, 4.9334e+00, 4.9031e+00, 4.8737e+00, 4.8448e+00, 4.8158e+00, 4.7859e+00, 4.7553e+00, 4.7253e+00, 4.6968e+00, 4.6695e+00, 4.6428e+00, 4.6165e+00, 4.5902e+00, 4.5631e+00, 4.5349e+00, 4.5064e+00, 4.4789e+00, 4.4528e+00, 4.4272e+00, 4.4020e+00, 4.3771e+00, 4.3520e+00, 4.3260e+00, 4.2987e+00, 4.2710e+00, 4.2444e+00, 4.2190e+00, 4.1942e+00, 4.1694e+00, 4.1448e+00, 4.1205e+00, 4.0956e+00, 4.0692e+00, 4.0419e+00, 4.0149e+00, 3.9893e+00, 3.9647e+00, 3.9402e+00, 3.9156e+00, 3.8914e+00, 3.8674e+00, 3.8429e+00, 3.8169e+00, 3.7898e+00, 3.7630e+00, 3.7377e+00, 3.7135e+00, 3.6894e+00, 3.6651e+00, 3.6410e+00, 3.6175e+00, 3.5940e+00, 3.5695e+00, 3.5435e+00, 3.5168e+00, 3.4910e+00, 3.4668e+00, 3.4435e+00, 3.4203e+00, 3.3966e+00, 3.3732e+00, 3.3505e+00, 3.3281e+00, 3.3049e+00, 3.2801e+00, 3.2544e+00, 3.2291e+00, 3.2054e+00, 3.1833e+00, 3.1614e+00, 3.1391e+00, 3.1167e+00, 3.0947e+00, 3.0736e+00, 3.0527e+00, 3.0307e+00, 3.0072e+00, 2.9828e+00, 2.9589e+00, 2.9368e+00, 2.9163e+00, 2.8962e+00, 2.8757e+00, 2.8549e+00, 2.8345e+00, 2.8149e+00, 2.7960e+00, 2.7766e+00, 2.7558e+00, 2.7336e+00, 2.7109e+00, 2.6894e+00, 2.6697e+00, 2.6515e+00, 2.6336e+00, 2.6152e+00, 2.5965e+00, 2.5781e+00, 2.5607e+00, 2.5440e+00, 2.5271e+00, 2.5090e+00}); + feg = Vctr_cpu({1.7362e+01, 1.6838e+01, 1.5458e+01, 1.3661e+01, 1.1854e+01, 1.0267e+01, 8.9579e+00, 7.9007e+00, 7.0413e+00, 6.3297e+00, 5.7282e+00, 5.2106e+00, 4.7593e+00, 4.3621e+00, 4.0105e+00, 3.6981e+00, 3.4198e+00, 3.1713e+00, 2.9489e+00, 2.7494e+00, 2.5701e+00, 2.4084e+00, 2.2622e+00, 2.1294e+00, 2.0084e+00, 1.8979e+00, 1.7964e+00, 1.7030e+00, 1.6167e+00, 1.5368e+00, 1.4625e+00, 1.3934e+00, 1.3288e+00, 1.2683e+00, 1.2117e+00, 1.1586e+00, 1.1086e+00, 1.0616e+00, 1.0174e+00, 9.7560e-01, 9.3630e-01, 8.9910e-01, 8.6400e-01, 8.3080e-01, 7.9950e-01, 7.6980e-01, 7.4170e-01, 7.1510e-01, 6.8990e-01, 6.6600e-01, 6.4340e-01, 6.2190e-01, 6.0150e-01, 5.8210e-01, 5.6370e-01, 5.4620e-01, 5.2960e-01, 5.1370e-01, 4.9860e-01, 4.8420e-01, 4.7040e-01, 4.5730e-01, 4.4480e-01, 4.3280e-01, 4.2130e-01, 4.1030e-01, 3.9970e-01, 3.8960e-01, 3.7990e-01, 3.7060e-01, 3.6160e-01, 3.5300e-01, 3.4470e-01, 3.3670e-01, 3.2900e-01, 3.2160e-01, 3.1440e-01, 3.0750e-01, 3.0080e-01, 2.9430e-01, 2.8800e-01, 2.8190e-01, 2.7610e-01, 2.7040e-01, 2.6480e-01, 2.5950e-01, 2.5420e-01, 2.4920e-01, 2.4430e-01, 2.3950e-01, 2.3490e-01, 2.3030e-01, 2.2600e-01, 2.2170e-01, 2.1750e-01, 2.1350e-01, 2.0950e-01, 2.0570e-01, 2.0200e-01, 1.9830e-01, 1.9480e-01, 1.9130e-01, 1.8790e-01, 1.8460e-01, 1.8140e-01, 1.7830e-01, 1.7520e-01, 1.7220e-01, 1.6930e-01, 1.6640e-01, 1.6370e-01, 1.6090e-01, 1.5830e-01, 1.5570e-01, 1.5320e-01, 1.5070e-01, 1.4830e-01, 1.4590e-01, 1.4360e-01, 1.4130e-01, 1.3910e-01, 1.3700e-01, 1.3490e-01, 1.3280e-01, 1.3080e-01, 1.2880e-01, 1.2690e-01, 1.2500e-01, 1.2310e-01, 1.2130e-01, 1.1950e-01, 1.1780e-01, 1.1610e-01, 1.1440e-01, 1.1280e-01, 1.1120e-01, 1.0970e-01, 1.0810e-01, 1.0660e-01, 1.0520e-01, 1.0370e-01, 1.0230e-01, 1.0090e-01, 9.9600e-02, 9.8300e-02, 9.7000e-02, 9.5700e-02, 9.4500e-02, 9.3200e-02, 9.2000e-02, 9.0900e-02, 8.9700e-02, 8.8600e-02, 8.7500e-02, 8.6400e-02, 8.5300e-02, 8.4300e-02, 8.3200e-02, 8.2200e-02, 8.1200e-02, 8.0200e-02, 7.9300e-02, 7.8400e-02, 7.7400e-02, 7.6500e-02, 7.5600e-02, 7.4800e-02, 7.3900e-02, 7.3100e-02, 7.2200e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8300e-02, 6.7600e-02, 6.6800e-02, 6.6100e-02, 6.5400e-02, 6.4700e-02, 6.4000e-02, 6.3300e-02, 6.2700e-02, 6.2000e-02, 6.1400e-02, 6.0700e-02, 6.0100e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7700e-02, 5.7100e-02, 5.6600e-02, 5.6000e-02, 5.5500e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3300e-02, 5.2800e-02, 5.2300e-02, 5.1800e-02, 5.1300e-02, 5.0800e-02, 5.0400e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7200e-02, 4.6800e-02, 4.6400e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3200e-02, 4.2800e-02, 4.2500e-02, 4.2100e-02, 4.1800e-02, 4.1400e-02, 4.1100e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9100e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02, 3.7200e-02, 3.6900e-02}); + } + break; + case 59: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({5.9000e+01, 5.8572e+01, 5.7440e+01, 5.5923e+01, 5.4278e+01, 5.2615e+01, 5.0950e+01, 4.9278e+01, 4.7601e+01, 4.5939e+01, 4.4313e+01, 4.2744e+01, 4.1246e+01, 3.9826e+01, 3.8486e+01, 3.7224e+01, 3.6034e+01, 3.4909e+01, 3.3842e+01, 3.2826e+01, 3.1856e+01, 3.0927e+01, 3.0036e+01, 2.9179e+01, 2.8355e+01, 2.7562e+01, 2.6801e+01, 2.6070e+01, 2.5369e+01, 2.4698e+01, 2.4058e+01, 2.3448e+01, 2.2866e+01, 2.2314e+01, 2.1791e+01, 2.1294e+01, 2.0824e+01, 2.0379e+01, 1.9958e+01, 1.9560e+01, 1.9182e+01, 1.8824e+01, 1.8485e+01, 1.8162e+01, 1.7854e+01, 1.7559e+01, 1.7277e+01, 1.7007e+01, 1.6745e+01, 1.6493e+01, 1.6248e+01, 1.6010e+01, 1.5777e+01, 1.5549e+01, 1.5325e+01, 1.5105e+01, 1.4888e+01, 1.4674e+01, 1.4461e+01, 1.4251e+01, 1.4042e+01, 1.3834e+01, 1.3628e+01, 1.3423e+01, 1.3219e+01, 1.3016e+01, 1.2814e+01, 1.2614e+01, 1.2415e+01, 1.2217e+01, 1.2020e+01, 1.1825e+01, 1.1632e+01, 1.1441e+01, 1.1251e+01, 1.1064e+01, 1.0879e+01, 1.0697e+01, 1.0517e+01, 1.0339e+01, 1.0165e+01, 9.9932e+00, 9.8245e+00, 9.6584e+00, 9.4958e+00, 9.3370e+00, 9.1817e+00, 9.0290e+00, 8.8793e+00, 8.7336e+00, 8.5921e+00, 8.4541e+00, 8.3189e+00, 8.1866e+00, 8.0583e+00, 7.9343e+00, 7.8142e+00, 7.6968e+00, 7.5820e+00, 7.4705e+00, 7.3632e+00, 7.2600e+00, 7.1600e+00, 7.0621e+00, 6.9665e+00, 6.8743e+00, 6.7860e+00, 6.7014e+00, 6.6193e+00, 6.5390e+00, 6.4605e+00, 6.3847e+00, 6.3125e+00, 6.2436e+00, 6.1770e+00, 6.1119e+00, 6.0478e+00, 5.9855e+00, 5.9261e+00, 5.8697e+00, 5.8156e+00, 5.7630e+00, 5.7111e+00, 5.6598e+00, 5.6100e+00, 5.5627e+00, 5.5178e+00, 5.4746e+00, 5.4324e+00, 5.3906e+00, 5.3489e+00, 5.3079e+00, 5.2688e+00, 5.2318e+00, 5.1963e+00, 5.1615e+00, 5.1270e+00, 5.0924e+00, 5.0575e+00, 5.0235e+00, 4.9912e+00, 4.9605e+00, 4.9305e+00, 4.9009e+00, 4.8714e+00, 4.8414e+00, 4.8109e+00, 4.7808e+00, 4.7521e+00, 4.7249e+00, 4.6981e+00, 4.6714e+00, 4.6448e+00, 4.6180e+00, 4.5903e+00, 4.5621e+00, 4.5348e+00, 4.5089e+00, 4.4839e+00, 4.4587e+00, 4.4335e+00, 4.4085e+00, 4.3831e+00, 4.3567e+00, 4.3296e+00, 4.3032e+00, 4.2782e+00, 4.2541e+00, 4.2297e+00, 4.2051e+00, 4.1806e+00, 4.1562e+00, 4.1310e+00, 4.1046e+00, 4.0780e+00, 4.0527e+00, 4.0287e+00, 4.0050e+00, 3.9808e+00, 3.9563e+00, 3.9322e+00, 3.9082e+00, 3.8834e+00, 3.8574e+00, 3.8310e+00, 3.8057e+00, 3.7820e+00, 3.7588e+00, 3.7351e+00, 3.7109e+00, 3.6869e+00, 3.6634e+00, 3.6398e+00, 3.6150e+00, 3.5891e+00, 3.5633e+00, 3.5390e+00, 3.5162e+00, 3.4937e+00, 3.4706e+00, 3.4469e+00, 3.4236e+00, 3.4009e+00, 3.3782e+00, 3.3546e+00, 3.3298e+00, 3.3045e+00, 3.2804e+00, 3.2581e+00, 3.2369e+00, 3.2153e+00, 3.1930e+00, 3.1703e+00, 3.1483e+00, 3.1270e+00, 3.1056e+00, 3.0832e+00, 3.0595e+00, 3.0355e+00, 3.0126e+00, 2.9916e+00, 2.9719e+00, 2.9522e+00, 2.9316e+00, 2.9105e+00, 2.8898e+00, 2.8700e+00, 2.8505e+00, 2.8305e+00, 2.8092e+00, 2.7869e+00, 2.7648e+00, 2.7440e+00, 2.7253e+00, 2.7077e+00, 2.6899e+00, 2.6713e+00, 2.6523e+00, 2.6336e+00, 2.6157e+00, 2.5983e+00}); + feg = Vctr_cpu({1.6942e+01, 1.6385e+01, 1.4936e+01, 1.3094e+01, 1.1301e+01, 9.7798e+00, 8.5625e+00, 7.5982e+00, 6.8204e+00, 6.1748e+00, 5.6241e+00, 5.1446e+00, 4.7214e+00, 4.3446e+00, 4.0079e+00, 3.7062e+00, 3.4354e+00, 3.1922e+00, 2.9735e+00, 2.7765e+00, 2.5986e+00, 2.4377e+00, 2.2916e+00, 2.1587e+00, 2.0374e+00, 1.9262e+00, 1.8240e+00, 1.7298e+00, 1.6427e+00, 1.5619e+00, 1.4867e+00, 1.4167e+00, 1.3513e+00, 1.2900e+00, 1.2326e+00, 1.1787e+00, 1.1280e+00, 1.0803e+00, 1.0354e+00, 9.9300e-01, 9.5300e-01, 9.1520e-01, 8.7950e-01, 8.4580e-01, 8.1390e-01, 7.8370e-01, 7.5510e-01, 7.2800e-01, 7.0230e-01, 6.7800e-01, 6.5490e-01, 6.3290e-01, 6.1210e-01, 5.9230e-01, 5.7350e-01, 5.5570e-01, 5.3870e-01, 5.2240e-01, 5.0700e-01, 4.9230e-01, 4.7820e-01, 4.6480e-01, 4.5200e-01, 4.3970e-01, 4.2800e-01, 4.1680e-01, 4.0600e-01, 3.9570e-01, 3.8580e-01, 3.7630e-01, 3.6720e-01, 3.5840e-01, 3.4990e-01, 3.4180e-01, 3.3390e-01, 3.2630e-01, 3.1900e-01, 3.1200e-01, 3.0520e-01, 2.9860e-01, 2.9220e-01, 2.8600e-01, 2.8010e-01, 2.7430e-01, 2.6870e-01, 2.6320e-01, 2.5790e-01, 2.5280e-01, 2.4780e-01, 2.4300e-01, 2.3830e-01, 2.3370e-01, 2.2930e-01, 2.2500e-01, 2.2080e-01, 2.1670e-01, 2.1270e-01, 2.0880e-01, 2.0500e-01, 2.0130e-01, 1.9770e-01, 1.9420e-01, 1.9080e-01, 1.8750e-01, 1.8420e-01, 1.8110e-01, 1.7800e-01, 1.7490e-01, 1.7200e-01, 1.6910e-01, 1.6630e-01, 1.6350e-01, 1.6080e-01, 1.5820e-01, 1.5560e-01, 1.5310e-01, 1.5070e-01, 1.4830e-01, 1.4600e-01, 1.4370e-01, 1.4140e-01, 1.3920e-01, 1.3710e-01, 1.3500e-01, 1.3300e-01, 1.3100e-01, 1.2900e-01, 1.2710e-01, 1.2520e-01, 1.2340e-01, 1.2160e-01, 1.1980e-01, 1.1810e-01, 1.1640e-01, 1.1470e-01, 1.1310e-01, 1.1150e-01, 1.1000e-01, 1.0850e-01, 1.0700e-01, 1.0550e-01, 1.0410e-01, 1.0270e-01, 1.0130e-01, 1.0000e-01, 9.8600e-02, 9.7300e-02, 9.6100e-02, 9.4800e-02, 9.3600e-02, 9.2400e-02, 9.1200e-02, 9.0100e-02, 8.9000e-02, 8.7900e-02, 8.6800e-02, 8.5700e-02, 8.4700e-02, 8.3600e-02, 8.2600e-02, 8.1600e-02, 8.0600e-02, 7.9700e-02, 7.8800e-02, 7.7800e-02, 7.6900e-02, 7.6000e-02, 7.5200e-02, 7.4300e-02, 7.3500e-02, 7.2600e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9500e-02, 6.8700e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5100e-02, 6.4400e-02, 6.3700e-02, 6.3100e-02, 6.2400e-02, 6.1800e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.6900e-02, 5.6400e-02, 5.5800e-02, 5.5300e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0700e-02, 5.0300e-02, 4.9800e-02, 4.9300e-02, 4.8900e-02, 4.8400e-02, 4.8000e-02, 4.7600e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5100e-02, 4.4700e-02, 4.4300e-02, 4.3900e-02, 4.3500e-02, 4.3200e-02, 4.2800e-02, 4.2400e-02, 4.2100e-02, 4.1700e-02, 4.1400e-02, 4.1000e-02, 4.0700e-02, 4.0400e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02, 3.7800e-02, 3.7500e-02}); + } + break; + case 60: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.0000e+01, 5.9583e+01, 5.8473e+01, 5.6974e+01, 5.5338e+01, 5.3678e+01, 5.2011e+01, 5.0332e+01, 4.8645e+01, 4.6967e+01, 4.5319e+01, 4.3722e+01, 4.2192e+01, 4.0738e+01, 3.9362e+01, 3.8064e+01, 3.6839e+01, 3.5680e+01, 3.4582e+01, 3.3538e+01, 3.2542e+01, 3.1589e+01, 3.0675e+01, 2.9797e+01, 2.8954e+01, 2.8143e+01, 2.7363e+01, 2.6615e+01, 2.5897e+01, 2.5209e+01, 2.4551e+01, 2.3924e+01, 2.3325e+01, 2.2756e+01, 2.2215e+01, 2.1702e+01, 2.1215e+01, 2.0755e+01, 2.0318e+01, 1.9905e+01, 1.9514e+01, 1.9143e+01, 1.8792e+01, 1.8458e+01, 1.8140e+01, 1.7837e+01, 1.7548e+01, 1.7270e+01, 1.7004e+01, 1.6747e+01, 1.6499e+01, 1.6258e+01, 1.6024e+01, 1.5796e+01, 1.5572e+01, 1.5353e+01, 1.5138e+01, 1.4925e+01, 1.4716e+01, 1.4508e+01, 1.4302e+01, 1.4098e+01, 1.3896e+01, 1.3694e+01, 1.3494e+01, 1.3295e+01, 1.3097e+01, 1.2900e+01, 1.2704e+01, 1.2510e+01, 1.2316e+01, 1.2124e+01, 1.1933e+01, 1.1744e+01, 1.1556e+01, 1.1370e+01, 1.1187e+01, 1.1004e+01, 1.0825e+01, 1.0647e+01, 1.0472e+01, 1.0299e+01, 1.0129e+01, 9.9622e+00, 9.7982e+00, 9.6367e+00, 9.4779e+00, 9.3224e+00, 9.1705e+00, 9.0219e+00, 8.8761e+00, 8.7332e+00, 8.5938e+00, 8.4583e+00, 8.3265e+00, 8.1974e+00, 8.0711e+00, 7.9483e+00, 7.8294e+00, 7.7144e+00, 7.6023e+00, 7.4927e+00, 7.3859e+00, 7.2827e+00, 7.1834e+00, 7.0875e+00, 6.9941e+00, 6.9027e+00, 6.8138e+00, 6.7284e+00, 6.6466e+00, 6.5678e+00, 6.4910e+00, 6.4158e+00, 6.3426e+00, 6.2721e+00, 6.2049e+00, 6.1406e+00, 6.0781e+00, 6.0168e+00, 5.9568e+00, 5.8985e+00, 5.8427e+00, 5.7898e+00, 5.7390e+00, 5.6892e+00, 5.6401e+00, 5.5919e+00, 5.5448e+00, 5.4999e+00, 5.4573e+00, 5.4165e+00, 5.3763e+00, 5.3365e+00, 5.2970e+00, 5.2581e+00, 5.2204e+00, 5.1848e+00, 5.1509e+00, 5.1177e+00, 5.0845e+00, 5.0513e+00, 5.0183e+00, 4.9856e+00, 4.9538e+00, 4.9238e+00, 4.8952e+00, 4.8668e+00, 4.8380e+00, 4.8091e+00, 4.7803e+00, 4.7513e+00, 4.7227e+00, 4.6954e+00, 4.6696e+00, 4.6442e+00, 4.6183e+00, 4.5920e+00, 4.5656e+00, 4.5391e+00, 4.5122e+00, 4.4857e+00, 4.4606e+00, 4.4366e+00, 4.4127e+00, 4.3881e+00, 4.3630e+00, 4.3378e+00, 4.3126e+00, 4.2869e+00, 4.2610e+00, 4.2362e+00, 4.2128e+00, 4.1898e+00, 4.1661e+00, 4.1416e+00, 4.1169e+00, 4.0924e+00, 4.0677e+00, 4.0423e+00, 4.0169e+00, 3.9926e+00, 3.9697e+00, 3.9472e+00, 3.9238e+00, 3.8995e+00, 3.8751e+00, 3.8510e+00, 3.8268e+00, 3.8020e+00, 3.7766e+00, 3.7521e+00, 3.7291e+00, 3.7070e+00, 3.6847e+00, 3.6612e+00, 3.6370e+00, 3.6130e+00, 3.5896e+00, 3.5660e+00, 3.5416e+00, 3.5167e+00, 3.4927e+00, 3.4703e+00, 3.4490e+00, 3.4275e+00, 3.4049e+00, 3.3814e+00, 3.3581e+00, 3.3353e+00, 3.3129e+00, 3.2898e+00, 3.2660e+00, 3.2422e+00, 3.2196e+00, 3.1988e+00, 3.1788e+00, 3.1584e+00, 3.1368e+00, 3.1143e+00, 3.0921e+00, 3.0707e+00, 3.0496e+00, 3.0280e+00, 3.0056e+00, 2.9829e+00, 2.9613e+00, 2.9414e+00, 2.9229e+00, 2.9045e+00, 2.8852e+00, 2.8647e+00, 2.8438e+00, 2.8235e+00, 2.8039e+00, 2.7845e+00, 2.7645e+00, 2.7437e+00, 2.7227e+00, 2.7029e+00, 2.6848e+00}); + feg = Vctr_cpu({1.6488e+01, 1.5973e+01, 1.4622e+01, 1.2877e+01, 1.1157e+01, 9.6835e+00, 8.4981e+00, 7.5555e+00, 6.7939e+00, 6.1616e+00, 5.6219e+00, 5.1515e+00, 4.7356e+00, 4.3646e+00, 4.0321e+00, 3.7334e+00, 3.4646e+00, 3.2225e+00, 3.0042e+00, 2.8070e+00, 2.6287e+00, 2.4671e+00, 2.3202e+00, 2.1863e+00, 2.0640e+00, 1.9519e+00, 1.8488e+00, 1.7537e+00, 1.6658e+00, 1.5842e+00, 1.5083e+00, 1.4376e+00, 1.3715e+00, 1.3097e+00, 1.2517e+00, 1.1972e+00, 1.1460e+00, 1.0978e+00, 1.0523e+00, 1.0095e+00, 9.6900e-01, 9.3070e-01, 8.9460e-01, 8.6040e-01, 8.2800e-01, 7.9730e-01, 7.6830e-01, 7.4070e-01, 7.1460e-01, 6.8980e-01, 6.6630e-01, 6.4400e-01, 6.2280e-01, 6.0260e-01, 5.8340e-01, 5.6520e-01, 5.4780e-01, 5.3130e-01, 5.1550e-01, 5.0040e-01, 4.8610e-01, 4.7240e-01, 4.5930e-01, 4.4680e-01, 4.3480e-01, 4.2330e-01, 4.1230e-01, 4.0180e-01, 3.9170e-01, 3.8200e-01, 3.7270e-01, 3.6370e-01, 3.5510e-01, 3.4680e-01, 3.3880e-01, 3.3110e-01, 3.2360e-01, 3.1650e-01, 3.0950e-01, 3.0280e-01, 2.9630e-01, 2.9010e-01, 2.8400e-01, 2.7810e-01, 2.7250e-01, 2.6690e-01, 2.6160e-01, 2.5640e-01, 2.5140e-01, 2.4650e-01, 2.4170e-01, 2.3710e-01, 2.3260e-01, 2.2820e-01, 2.2390e-01, 2.1980e-01, 2.1580e-01, 2.1180e-01, 2.0800e-01, 2.0430e-01, 2.0070e-01, 1.9710e-01, 1.9370e-01, 1.9030e-01, 1.8700e-01, 1.8380e-01, 1.8070e-01, 1.7760e-01, 1.7460e-01, 1.7170e-01, 1.6890e-01, 1.6610e-01, 1.6340e-01, 1.6070e-01, 1.5810e-01, 1.5560e-01, 1.5310e-01, 1.5070e-01, 1.4830e-01, 1.4600e-01, 1.4370e-01, 1.4150e-01, 1.3930e-01, 1.3720e-01, 1.3510e-01, 1.3310e-01, 1.3110e-01, 1.2920e-01, 1.2730e-01, 1.2540e-01, 1.2360e-01, 1.2180e-01, 1.2010e-01, 1.1830e-01, 1.1670e-01, 1.1500e-01, 1.1340e-01, 1.1180e-01, 1.1030e-01, 1.0880e-01, 1.0730e-01, 1.0580e-01, 1.0440e-01, 1.0300e-01, 1.0170e-01, 1.0030e-01, 9.9000e-02, 9.7700e-02, 9.6400e-02, 9.5200e-02, 9.4000e-02, 9.2800e-02, 9.1600e-02, 9.0500e-02, 8.9300e-02, 8.8200e-02, 8.7100e-02, 8.6100e-02, 8.5000e-02, 8.4000e-02, 8.3000e-02, 8.2000e-02, 8.1000e-02, 8.0100e-02, 7.9100e-02, 7.8200e-02, 7.7300e-02, 7.6400e-02, 7.5600e-02, 7.4700e-02, 7.3900e-02, 7.3000e-02, 7.2200e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6200e-02, 6.5500e-02, 6.4800e-02, 6.4100e-02, 6.3400e-02, 6.2800e-02, 6.2100e-02, 6.1500e-02, 6.0900e-02, 6.0200e-02, 5.9600e-02, 5.9000e-02, 5.8500e-02, 5.7900e-02, 5.7300e-02, 5.6700e-02, 5.6200e-02, 5.5600e-02, 5.5100e-02, 5.4600e-02, 5.4100e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2000e-02, 5.1500e-02, 5.1100e-02, 5.0600e-02, 5.0100e-02, 4.9700e-02, 4.9200e-02, 4.8800e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4300e-02, 4.3900e-02, 4.3500e-02, 4.3100e-02, 4.2800e-02, 4.2400e-02, 4.2000e-02, 4.1700e-02, 4.1300e-02, 4.1000e-02, 4.0700e-02, 4.0300e-02, 4.0000e-02, 3.9700e-02, 3.9400e-02, 3.9000e-02, 3.8700e-02, 3.8400e-02, 3.8100e-02}); + } + break; + case 61: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.1000e+01, 6.0591e+01, 5.9499e+01, 5.8020e+01, 5.6398e+01, 5.4744e+01, 5.3078e+01, 5.1396e+01, 4.9701e+01, 4.8009e+01, 4.6342e+01, 4.4721e+01, 4.3161e+01, 4.1675e+01, 4.0265e+01, 3.8931e+01, 3.7671e+01, 3.6479e+01, 3.5349e+01, 3.4275e+01, 3.3252e+01, 3.2273e+01, 3.1335e+01, 3.0436e+01, 2.9571e+01, 2.8740e+01, 2.7942e+01, 2.7175e+01, 2.6438e+01, 2.5733e+01, 2.5057e+01, 2.4412e+01, 2.3796e+01, 2.3209e+01, 2.2651e+01, 2.2120e+01, 2.1617e+01, 2.1140e+01, 2.0688e+01, 2.0260e+01, 1.9854e+01, 1.9470e+01, 1.9105e+01, 1.8760e+01, 1.8431e+01, 1.8119e+01, 1.7821e+01, 1.7536e+01, 1.7263e+01, 1.7001e+01, 1.6748e+01, 1.6504e+01, 1.6267e+01, 1.6037e+01, 1.5813e+01, 1.5594e+01, 1.5379e+01, 1.5168e+01, 1.4960e+01, 1.4754e+01, 1.4551e+01, 1.4350e+01, 1.4151e+01, 1.3953e+01, 1.3756e+01, 1.3561e+01, 1.3367e+01, 1.3173e+01, 1.2981e+01, 1.2790e+01, 1.2600e+01, 1.2410e+01, 1.2222e+01, 1.2036e+01, 1.1850e+01, 1.1666e+01, 1.1483e+01, 1.1303e+01, 1.1124e+01, 1.0947e+01, 1.0772e+01, 1.0599e+01, 1.0429e+01, 1.0261e+01, 1.0096e+01, 9.9323e+00, 9.7724e+00, 9.6154e+00, 9.4608e+00, 9.3087e+00, 9.1597e+00, 9.0144e+00, 8.8724e+00, 8.7331e+00, 8.5963e+00, 8.4626e+00, 8.3330e+00, 8.2070e+00, 8.0839e+00, 7.9632e+00, 7.8452e+00, 7.7310e+00, 7.6207e+00, 7.5138e+00, 7.4093e+00, 7.3069e+00, 7.2073e+00, 7.1114e+00, 7.0193e+00, 6.9301e+00, 6.8431e+00, 6.7578e+00, 6.6748e+00, 6.5950e+00, 6.5188e+00, 6.4454e+00, 6.3739e+00, 6.3039e+00, 6.2353e+00, 6.1690e+00, 6.1058e+00, 6.0456e+00, 5.9873e+00, 5.9302e+00, 5.8741e+00, 5.8190e+00, 5.7659e+00, 5.7155e+00, 5.6675e+00, 5.6210e+00, 5.5753e+00, 5.5302e+00, 5.4855e+00, 5.4420e+00, 5.4007e+00, 5.3616e+00, 5.3238e+00, 5.2866e+00, 5.2497e+00, 5.2130e+00, 5.1765e+00, 5.1410e+00, 5.1075e+00, 5.0756e+00, 5.0445e+00, 5.0135e+00, 4.9826e+00, 4.9517e+00, 4.9205e+00, 4.8899e+00, 4.8608e+00, 4.8332e+00, 4.8063e+00, 4.7792e+00, 4.7522e+00, 4.7250e+00, 4.6975e+00, 4.6695e+00, 4.6423e+00, 4.6167e+00, 4.5921e+00, 4.5676e+00, 4.5427e+00, 4.5177e+00, 4.4927e+00, 4.4671e+00, 4.4409e+00, 4.4151e+00, 4.3907e+00, 4.3674e+00, 4.3442e+00, 4.3204e+00, 4.2964e+00, 4.2725e+00, 4.2483e+00, 4.2233e+00, 4.1978e+00, 4.1730e+00, 4.1497e+00, 4.1272e+00, 4.1045e+00, 4.0810e+00, 4.0573e+00, 4.0339e+00, 4.0103e+00, 3.9858e+00, 3.9606e+00, 3.9358e+00, 3.9125e+00, 3.8903e+00, 3.8682e+00, 3.8452e+00, 3.8217e+00, 3.7984e+00, 3.7754e+00, 3.7520e+00, 3.7277e+00, 3.7027e+00, 3.6784e+00, 3.6557e+00, 3.6341e+00, 3.6125e+00, 3.5899e+00, 3.5668e+00, 3.5439e+00, 3.5215e+00, 3.4990e+00, 3.4756e+00, 3.4513e+00, 3.4271e+00, 3.4043e+00, 3.3830e+00, 3.3625e+00, 3.3414e+00, 3.3193e+00, 3.2969e+00, 3.2750e+00, 3.2536e+00, 3.2321e+00, 3.2097e+00, 3.1864e+00, 3.1631e+00, 3.1411e+00, 3.1207e+00, 3.1015e+00, 3.0820e+00, 3.0615e+00, 3.0403e+00, 3.0194e+00, 2.9992e+00, 2.9793e+00, 2.9590e+00, 2.9377e+00, 2.9156e+00, 2.8939e+00, 2.8735e+00, 2.8549e+00, 2.8375e+00, 2.8198e+00, 2.8011e+00, 2.7816e+00}); + feg = Vctr_cpu({1.6177e+01, 1.5677e+01, 1.4367e+01, 1.2679e+01, 1.1014e+01, 9.5830e+00, 8.4270e+00, 7.5058e+00, 6.7608e+00, 6.1418e+00, 5.6132e+00, 5.1521e+00, 4.7438e+00, 4.3789e+00, 4.0512e+00, 3.7560e+00, 3.4896e+00, 3.2491e+00, 3.0317e+00, 2.8349e+00, 2.6565e+00, 2.4945e+00, 2.3471e+00, 2.2125e+00, 2.0895e+00, 1.9766e+00, 1.8727e+00, 1.7768e+00, 1.6881e+00, 1.6059e+00, 1.5293e+00, 1.4580e+00, 1.3913e+00, 1.3289e+00, 1.2704e+00, 1.2154e+00, 1.1637e+00, 1.1150e+00, 1.0691e+00, 1.0257e+00, 9.8480e-01, 9.4610e-01, 9.0950e-01, 8.7480e-01, 8.4200e-01, 8.1090e-01, 7.8140e-01, 7.5350e-01, 7.2690e-01, 7.0180e-01, 6.7780e-01, 6.5510e-01, 6.3350e-01, 6.1300e-01, 5.9340e-01, 5.7480e-01, 5.5710e-01, 5.4020e-01, 5.2410e-01, 5.0870e-01, 4.9410e-01, 4.8010e-01, 4.6670e-01, 4.5390e-01, 4.4170e-01, 4.3000e-01, 4.1870e-01, 4.0800e-01, 3.9770e-01, 3.8780e-01, 3.7830e-01, 3.6910e-01, 3.6030e-01, 3.5190e-01, 3.4370e-01, 3.3590e-01, 3.2830e-01, 3.2100e-01, 3.1390e-01, 3.0710e-01, 3.0050e-01, 2.9420e-01, 2.8800e-01, 2.8200e-01, 2.7630e-01, 2.7070e-01, 2.6520e-01, 2.6000e-01, 2.5490e-01, 2.4990e-01, 2.4510e-01, 2.4040e-01, 2.3580e-01, 2.3140e-01, 2.2710e-01, 2.2290e-01, 2.1880e-01, 2.1490e-01, 2.1100e-01, 2.0720e-01, 2.0360e-01, 2.0000e-01, 1.9650e-01, 1.9310e-01, 1.8970e-01, 1.8650e-01, 1.8330e-01, 1.8020e-01, 1.7720e-01, 1.7430e-01, 1.7140e-01, 1.6860e-01, 1.6580e-01, 1.6320e-01, 1.6050e-01, 1.5800e-01, 1.5550e-01, 1.5300e-01, 1.5060e-01, 1.4830e-01, 1.4600e-01, 1.4370e-01, 1.4150e-01, 1.3940e-01, 1.3730e-01, 1.3520e-01, 1.3320e-01, 1.3130e-01, 1.2930e-01, 1.2740e-01, 1.2560e-01, 1.2380e-01, 1.2200e-01, 1.2030e-01, 1.1860e-01, 1.1690e-01, 1.1530e-01, 1.1370e-01, 1.1210e-01, 1.1060e-01, 1.0910e-01, 1.0760e-01, 1.0610e-01, 1.0470e-01, 1.0330e-01, 1.0200e-01, 1.0060e-01, 9.9300e-02, 9.8000e-02, 9.6800e-02, 9.5500e-02, 9.4300e-02, 9.3100e-02, 9.2000e-02, 9.0800e-02, 8.9700e-02, 8.8600e-02, 8.7500e-02, 8.6500e-02, 8.5400e-02, 8.4400e-02, 8.3400e-02, 8.2400e-02, 8.1400e-02, 8.0500e-02, 7.9500e-02, 7.8600e-02, 7.7700e-02, 7.6800e-02, 7.5900e-02, 7.5100e-02, 7.4200e-02, 7.3400e-02, 7.2600e-02, 7.1800e-02, 7.1000e-02, 7.0200e-02, 6.9500e-02, 6.8700e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5100e-02, 6.4500e-02, 6.3800e-02, 6.3100e-02, 6.2500e-02, 6.1900e-02, 6.1200e-02, 6.0600e-02, 6.0000e-02, 5.9400e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7100e-02, 5.6500e-02, 5.6000e-02, 5.5500e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3400e-02, 5.2900e-02, 5.2400e-02, 5.1900e-02, 5.1400e-02, 5.0900e-02, 5.0500e-02, 5.0000e-02, 4.9600e-02, 4.9100e-02, 4.8700e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.5000e-02, 4.4600e-02, 4.4200e-02, 4.3800e-02, 4.3400e-02, 4.3100e-02, 4.2700e-02, 4.2400e-02, 4.2000e-02, 4.1700e-02, 4.1300e-02, 4.1000e-02, 4.0600e-02, 4.0300e-02, 4.0000e-02, 3.9700e-02, 3.9300e-02, 3.9000e-02, 3.8700e-02}); + } + break; + case 62: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.2000e+01, 6.1599e+01, 6.0527e+01, 5.9067e+01, 5.7458e+01, 5.5811e+01, 5.4148e+01, 5.2465e+01, 5.0764e+01, 4.9062e+01, 4.7379e+01, 4.5737e+01, 4.4151e+01, 4.2635e+01, 4.1192e+01, 3.9825e+01, 3.8532e+01, 3.7306e+01, 3.6144e+01, 3.5040e+01, 3.3987e+01, 3.2982e+01, 3.2019e+01, 3.1096e+01, 3.0209e+01, 2.9357e+01, 2.8539e+01, 2.7752e+01, 2.6997e+01, 2.6272e+01, 2.5578e+01, 2.4914e+01, 2.4280e+01, 2.3675e+01, 2.3099e+01, 2.2552e+01, 2.2031e+01, 2.1537e+01, 2.1069e+01, 2.0625e+01, 2.0204e+01, 1.9805e+01, 1.9428e+01, 1.9069e+01, 1.8729e+01, 1.8406e+01, 1.8098e+01, 1.7805e+01, 1.7524e+01, 1.7255e+01, 1.6997e+01, 1.6748e+01, 1.6508e+01, 1.6275e+01, 1.6049e+01, 1.5829e+01, 1.5613e+01, 1.5402e+01, 1.5195e+01, 1.4991e+01, 1.4790e+01, 1.4591e+01, 1.4395e+01, 1.4200e+01, 1.4006e+01, 1.3814e+01, 1.3623e+01, 1.3434e+01, 1.3245e+01, 1.3057e+01, 1.2870e+01, 1.2684e+01, 1.2499e+01, 1.2315e+01, 1.2132e+01, 1.1950e+01, 1.1770e+01, 1.1591e+01, 1.1414e+01, 1.1238e+01, 1.1064e+01, 1.0892e+01, 1.0722e+01, 1.0554e+01, 1.0388e+01, 1.0224e+01, 1.0063e+01, 9.9043e+00, 9.7481e+00, 9.5940e+00, 9.4428e+00, 9.2950e+00, 9.1503e+00, 9.0081e+00, 8.8681e+00, 8.7311e+00, 8.5978e+00, 8.4681e+00, 8.3411e+00, 8.2163e+00, 8.0942e+00, 7.9757e+00, 7.8610e+00, 7.7496e+00, 7.6405e+00, 7.5336e+00, 7.4294e+00, 7.3288e+00, 7.2319e+00, 7.1381e+00, 7.0463e+00, 6.9564e+00, 6.8688e+00, 6.7844e+00, 6.7036e+00, 6.6256e+00, 6.5497e+00, 6.4752e+00, 6.4023e+00, 6.3318e+00, 6.2645e+00, 6.2002e+00, 6.1379e+00, 6.0770e+00, 6.0171e+00, 5.9584e+00, 5.9018e+00, 5.8479e+00, 5.7966e+00, 5.7469e+00, 5.6981e+00, 5.6499e+00, 5.6024e+00, 5.5563e+00, 5.5123e+00, 5.4707e+00, 5.4305e+00, 5.3910e+00, 5.3520e+00, 5.3132e+00, 5.2748e+00, 5.2375e+00, 5.2022e+00, 5.1687e+00, 5.1360e+00, 5.1036e+00, 5.0715e+00, 5.0393e+00, 5.0070e+00, 4.9753e+00, 4.9453e+00, 4.9168e+00, 4.8890e+00, 4.8613e+00, 4.8336e+00, 4.8059e+00, 4.7778e+00, 4.7495e+00, 4.7219e+00, 4.6960e+00, 4.6711e+00, 4.6464e+00, 4.6214e+00, 4.5963e+00, 4.5712e+00, 4.5456e+00, 4.5195e+00, 4.4938e+00, 4.4694e+00, 4.4463e+00, 4.4233e+00, 4.3997e+00, 4.3759e+00, 4.3523e+00, 4.3284e+00, 4.3037e+00, 4.2785e+00, 4.2541e+00, 4.2311e+00, 4.2090e+00, 4.1866e+00, 4.1635e+00, 4.1403e+00, 4.1172e+00, 4.0940e+00, 4.0700e+00, 4.0453e+00, 4.0209e+00, 3.9980e+00, 3.9762e+00, 3.9544e+00, 3.9319e+00, 3.9088e+00, 3.8859e+00, 3.8633e+00, 3.8404e+00, 3.8164e+00, 3.7919e+00, 3.7680e+00, 3.7456e+00, 3.7243e+00, 3.7030e+00, 3.6807e+00, 3.6579e+00, 3.6353e+00, 3.6132e+00, 3.5910e+00, 3.5678e+00, 3.5438e+00, 3.5199e+00, 3.4973e+00, 3.4762e+00, 3.4558e+00, 3.4348e+00, 3.4129e+00, 3.3907e+00, 3.3689e+00, 3.3476e+00, 3.3262e+00, 3.3039e+00, 3.2807e+00, 3.2575e+00, 3.2355e+00, 3.2151e+00, 3.1958e+00, 3.1763e+00, 3.1558e+00, 3.1345e+00, 3.1135e+00, 3.0932e+00, 3.0732e+00, 3.0528e+00, 3.0314e+00, 3.0093e+00, 2.9875e+00, 2.9670e+00, 2.9482e+00, 2.9305e+00, 2.9126e+00, 2.8936e+00, 2.8739e+00}); + feg = Vctr_cpu({1.5835e+01, 1.5357e+01, 1.4103e+01, 1.2480e+01, 1.0871e+01, 9.4802e+00, 8.3527e+00, 7.4520e+00, 6.7227e+00, 6.1165e+00, 5.5988e+00, 5.1470e+00, 4.7465e+00, 4.3880e+00, 4.0653e+00, 3.7740e+00, 3.5105e+00, 3.2720e+00, 3.0559e+00, 2.8599e+00, 2.6818e+00, 2.5198e+00, 2.3721e+00, 2.2371e+00, 2.1135e+00, 2.0000e+00, 1.8955e+00, 1.7990e+00, 1.7097e+00, 1.6268e+00, 1.5497e+00, 1.4778e+00, 1.4106e+00, 1.3477e+00, 1.2886e+00, 1.2332e+00, 1.1810e+00, 1.1318e+00, 1.0855e+00, 1.0417e+00, 1.0003e+00, 9.6120e-01, 9.2420e-01, 8.8910e-01, 8.5590e-01, 8.2440e-01, 7.9450e-01, 7.6610e-01, 7.3920e-01, 7.1360e-01, 6.8930e-01, 6.6620e-01, 6.4430e-01, 6.2330e-01, 6.0340e-01, 5.8450e-01, 5.6640e-01, 5.4920e-01, 5.3280e-01, 5.1710e-01, 5.0220e-01, 4.8790e-01, 4.7420e-01, 4.6120e-01, 4.4870e-01, 4.3670e-01, 4.2530e-01, 4.1430e-01, 4.0380e-01, 3.9370e-01, 3.8400e-01, 3.7460e-01, 3.6570e-01, 3.5700e-01, 3.4870e-01, 3.4070e-01, 3.3300e-01, 3.2560e-01, 3.1840e-01, 3.1150e-01, 3.0480e-01, 2.9830e-01, 2.9200e-01, 2.8600e-01, 2.8010e-01, 2.7440e-01, 2.6890e-01, 2.6360e-01, 2.5840e-01, 2.5340e-01, 2.4850e-01, 2.4370e-01, 2.3910e-01, 2.3460e-01, 2.3030e-01, 2.2600e-01, 2.2190e-01, 2.1790e-01, 2.1400e-01, 2.1010e-01, 2.0640e-01, 2.0280e-01, 1.9930e-01, 1.9580e-01, 1.9250e-01, 1.8920e-01, 1.8600e-01, 1.8290e-01, 1.7980e-01, 1.7680e-01, 1.7390e-01, 1.7110e-01, 1.6830e-01, 1.6560e-01, 1.6290e-01, 1.6030e-01, 1.5780e-01, 1.5530e-01, 1.5290e-01, 1.5050e-01, 1.4820e-01, 1.4590e-01, 1.4370e-01, 1.4150e-01, 1.3940e-01, 1.3730e-01, 1.3530e-01, 1.3330e-01, 1.3140e-01, 1.2940e-01, 1.2760e-01, 1.2570e-01, 1.2390e-01, 1.2220e-01, 1.2050e-01, 1.1880e-01, 1.1710e-01, 1.1550e-01, 1.1390e-01, 1.1240e-01, 1.1080e-01, 1.0930e-01, 1.0790e-01, 1.0640e-01, 1.0500e-01, 1.0360e-01, 1.0230e-01, 1.0090e-01, 9.9600e-02, 9.8400e-02, 9.7100e-02, 9.5900e-02, 9.4700e-02, 9.3500e-02, 9.2300e-02, 9.1200e-02, 9.0000e-02, 8.8900e-02, 8.7900e-02, 8.6800e-02, 8.5800e-02, 8.4700e-02, 8.3700e-02, 8.2700e-02, 8.1800e-02, 8.0800e-02, 7.9900e-02, 7.9000e-02, 7.8100e-02, 7.7200e-02, 7.6300e-02, 7.5400e-02, 7.4600e-02, 7.3800e-02, 7.2900e-02, 7.2100e-02, 7.1400e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6200e-02, 6.5500e-02, 6.4800e-02, 6.4100e-02, 6.3500e-02, 6.2800e-02, 6.2200e-02, 6.1600e-02, 6.1000e-02, 6.0300e-02, 5.9700e-02, 5.9200e-02, 5.8600e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6300e-02, 5.5800e-02, 5.5300e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1300e-02, 5.0800e-02, 5.0300e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8100e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3400e-02, 4.3000e-02, 4.2700e-02, 4.2300e-02, 4.2000e-02, 4.1600e-02, 4.1300e-02, 4.0900e-02, 4.0600e-02, 4.0300e-02, 3.9900e-02, 3.9600e-02, 3.9300e-02}); + } + break; + case 63: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.3000e+01, 6.2607e+01, 6.1554e+01, 6.0113e+01, 5.8517e+01, 5.6878e+01, 5.5218e+01, 5.3535e+01, 5.1832e+01, 5.0121e+01, 4.8424e+01, 4.6762e+01, 4.5153e+01, 4.3609e+01, 4.2136e+01, 4.0736e+01, 3.9410e+01, 3.8152e+01, 3.6958e+01, 3.5824e+01, 3.4742e+01, 3.3710e+01, 3.2721e+01, 3.1774e+01, 3.0864e+01, 2.9991e+01, 2.9151e+01, 2.8344e+01, 2.7570e+01, 2.6826e+01, 2.6113e+01, 2.5431e+01, 2.4778e+01, 2.4155e+01, 2.3561e+01, 2.2995e+01, 2.2457e+01, 2.1946e+01, 2.1461e+01, 2.1001e+01, 2.0565e+01, 2.0151e+01, 1.9759e+01, 1.9388e+01, 1.9035e+01, 1.8700e+01, 1.8382e+01, 1.8079e+01, 1.7789e+01, 1.7513e+01, 1.7248e+01, 1.6993e+01, 1.6748e+01, 1.6512e+01, 1.6282e+01, 1.6060e+01, 1.5843e+01, 1.5632e+01, 1.5425e+01, 1.5221e+01, 1.5021e+01, 1.4824e+01, 1.4629e+01, 1.4437e+01, 1.4246e+01, 1.4057e+01, 1.3869e+01, 1.3682e+01, 1.3496e+01, 1.3312e+01, 1.3128e+01, 1.2945e+01, 1.2764e+01, 1.2583e+01, 1.2403e+01, 1.2224e+01, 1.2046e+01, 1.1869e+01, 1.1694e+01, 1.1520e+01, 1.1347e+01, 1.1176e+01, 1.1007e+01, 1.0840e+01, 1.0674e+01, 1.0510e+01, 1.0348e+01, 1.0189e+01, 1.0032e+01, 9.8766e+00, 9.7239e+00, 9.5743e+00, 9.4276e+00, 9.2830e+00, 9.1405e+00, 9.0008e+00, 8.8645e+00, 8.7316e+00, 8.6012e+00, 8.4730e+00, 8.3472e+00, 8.2249e+00, 8.1063e+00, 7.9908e+00, 7.8776e+00, 7.7664e+00, 7.6579e+00, 7.5530e+00, 7.4517e+00, 7.3533e+00, 7.2571e+00, 7.1627e+00, 7.0706e+00, 6.9818e+00, 6.8965e+00, 6.8141e+00, 6.7338e+00, 6.6549e+00, 6.5778e+00, 6.5031e+00, 6.4316e+00, 6.3631e+00, 6.2968e+00, 6.2319e+00, 6.1682e+00, 6.1057e+00, 6.0455e+00, 5.9880e+00, 5.9332e+00, 5.8801e+00, 5.8280e+00, 5.7767e+00, 5.7262e+00, 5.6771e+00, 5.6303e+00, 5.5859e+00, 5.5430e+00, 5.5011e+00, 5.4596e+00, 5.4186e+00, 5.3780e+00, 5.3386e+00, 5.3014e+00, 5.2660e+00, 5.2315e+00, 5.1974e+00, 5.1637e+00, 5.1300e+00, 5.0963e+00, 5.0634e+00, 5.0322e+00, 5.0026e+00, 4.9738e+00, 4.9451e+00, 4.9165e+00, 4.8880e+00, 4.8592e+00, 4.8302e+00, 4.8022e+00, 4.7756e+00, 4.7503e+00, 4.7252e+00, 4.6999e+00, 4.6746e+00, 4.6492e+00, 4.6235e+00, 4.5972e+00, 4.5715e+00, 4.5471e+00, 4.5239e+00, 4.5009e+00, 4.4775e+00, 4.4539e+00, 4.4303e+00, 4.4066e+00, 4.3821e+00, 4.3572e+00, 4.3331e+00, 4.3103e+00, 4.2885e+00, 4.2664e+00, 4.2437e+00, 4.2208e+00, 4.1981e+00, 4.1752e+00, 4.1516e+00, 4.1273e+00, 4.1033e+00, 4.0808e+00, 4.0594e+00, 4.0380e+00, 4.0158e+00, 3.9932e+00, 3.9707e+00, 3.9485e+00, 3.9259e+00, 3.9023e+00, 3.8783e+00, 3.8548e+00, 3.8327e+00, 3.8118e+00, 3.7908e+00, 3.7689e+00, 3.7464e+00, 3.7242e+00, 3.7024e+00, 3.6804e+00, 3.6576e+00, 3.6340e+00, 3.6104e+00, 3.5880e+00, 3.5671e+00, 3.5469e+00, 3.5262e+00, 3.5045e+00, 3.4824e+00, 3.4608e+00, 3.4397e+00, 3.4184e+00, 3.3963e+00, 3.3733e+00, 3.3502e+00, 3.3283e+00, 3.3080e+00, 3.2887e+00, 3.2692e+00, 3.2487e+00, 3.2275e+00, 3.2065e+00, 3.1862e+00, 3.1662e+00, 3.1458e+00, 3.1243e+00, 3.1022e+00, 3.0804e+00, 3.0598e+00, 3.0409e+00, 3.0230e+00, 3.0049e+00, 2.9858e+00, 2.9659e+00}); + feg = Vctr_cpu({1.5507e+01, 1.5050e+01, 1.3847e+01, 1.2286e+01, 1.0729e+01, 9.3780e+00, 8.2778e+00, 7.3967e+00, 6.6825e+00, 6.0888e+00, 5.5816e+00, 5.1389e+00, 4.7460e+00, 4.3939e+00, 4.0764e+00, 3.7891e+00, 3.5287e+00, 3.2925e+00, 3.0779e+00, 2.8828e+00, 2.7052e+00, 2.5434e+00, 2.3956e+00, 2.2604e+00, 2.1364e+00, 2.0225e+00, 1.9175e+00, 1.8204e+00, 1.7306e+00, 1.6471e+00, 1.5695e+00, 1.4971e+00, 1.4294e+00, 1.3660e+00, 1.3065e+00, 1.2506e+00, 1.1979e+00, 1.1484e+00, 1.1016e+00, 1.0574e+00, 1.0156e+00, 9.7610e-01, 9.3870e-01, 9.0320e-01, 8.6960e-01, 8.3770e-01, 8.0750e-01, 7.7870e-01, 7.5140e-01, 7.2550e-01, 7.0080e-01, 6.7730e-01, 6.5500e-01, 6.3380e-01, 6.1350e-01, 5.9420e-01, 5.7580e-01, 5.5830e-01, 5.4160e-01, 5.2560e-01, 5.1040e-01, 4.9580e-01, 4.8190e-01, 4.6860e-01, 4.5580e-01, 4.4360e-01, 4.3190e-01, 4.2070e-01, 4.1000e-01, 3.9970e-01, 3.8980e-01, 3.8020e-01, 3.7110e-01, 3.6230e-01, 3.5380e-01, 3.4570e-01, 3.3780e-01, 3.3020e-01, 3.2290e-01, 3.1590e-01, 3.0910e-01, 3.0250e-01, 2.9610e-01, 2.8990e-01, 2.8400e-01, 2.7820e-01, 2.7260e-01, 2.6720e-01, 2.6190e-01, 2.5680e-01, 2.5190e-01, 2.4710e-01, 2.4240e-01, 2.3780e-01, 2.3340e-01, 2.2910e-01, 2.2490e-01, 2.2090e-01, 2.1690e-01, 2.1300e-01, 2.0930e-01, 2.0560e-01, 2.0200e-01, 1.9860e-01, 1.9520e-01, 1.9180e-01, 1.8860e-01, 1.8550e-01, 1.8240e-01, 1.7940e-01, 1.7640e-01, 1.7350e-01, 1.7070e-01, 1.6800e-01, 1.6530e-01, 1.6270e-01, 1.6010e-01, 1.5760e-01, 1.5520e-01, 1.5280e-01, 1.5040e-01, 1.4810e-01, 1.4590e-01, 1.4370e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3340e-01, 1.3140e-01, 1.2950e-01, 1.2770e-01, 1.2590e-01, 1.2410e-01, 1.2230e-01, 1.2060e-01, 1.1900e-01, 1.1730e-01, 1.1570e-01, 1.1410e-01, 1.1260e-01, 1.1110e-01, 1.0960e-01, 1.0810e-01, 1.0670e-01, 1.0530e-01, 1.0390e-01, 1.0260e-01, 1.0120e-01, 9.9900e-02, 9.8700e-02, 9.7400e-02, 9.6200e-02, 9.5000e-02, 9.3800e-02, 9.2600e-02, 9.1500e-02, 9.0400e-02, 8.9300e-02, 8.8200e-02, 8.7100e-02, 8.6100e-02, 8.5100e-02, 8.4100e-02, 8.3100e-02, 8.2100e-02, 8.1200e-02, 8.0200e-02, 7.9300e-02, 7.8400e-02, 7.7500e-02, 7.6600e-02, 7.5800e-02, 7.4900e-02, 7.4100e-02, 7.3300e-02, 7.2500e-02, 7.1700e-02, 7.0900e-02, 7.0200e-02, 6.9400e-02, 6.8700e-02, 6.8000e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5200e-02, 6.4500e-02, 6.3800e-02, 6.3200e-02, 6.2500e-02, 6.1900e-02, 6.1300e-02, 6.0700e-02, 6.0100e-02, 5.9500e-02, 5.8900e-02, 5.8300e-02, 5.7800e-02, 5.7200e-02, 5.6700e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2100e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0200e-02, 4.9700e-02, 4.9300e-02, 4.8900e-02, 4.8400e-02, 4.8000e-02, 4.7600e-02, 4.7200e-02, 4.6800e-02, 4.6400e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4400e-02, 4.4000e-02, 4.3700e-02, 4.3300e-02, 4.3000e-02, 4.2600e-02, 4.2300e-02, 4.1900e-02, 4.1600e-02, 4.1200e-02, 4.0900e-02, 4.0600e-02, 4.0200e-02, 3.9900e-02}); + } + break; + case 64: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.4000e+01, 6.3611e+01, 6.2555e+01, 6.1078e+01, 5.9416e+01, 5.7703e+01, 5.5988e+01, 5.4278e+01, 5.2571e+01, 5.0873e+01, 4.9195e+01, 4.7550e+01, 4.5952e+01, 4.4412e+01, 4.2936e+01, 4.1529e+01, 4.0191e+01, 3.8919e+01, 3.7709e+01, 3.6559e+01, 3.5462e+01, 3.4415e+01, 3.3412e+01, 3.2452e+01, 3.1529e+01, 3.0643e+01, 2.9791e+01, 2.8971e+01, 2.8183e+01, 2.7425e+01, 2.6697e+01, 2.5999e+01, 2.5330e+01, 2.4690e+01, 2.4078e+01, 2.3494e+01, 2.2937e+01, 2.2407e+01, 2.1903e+01, 2.1424e+01, 2.0969e+01, 2.0538e+01, 2.0128e+01, 1.9740e+01, 1.9372e+01, 1.9022e+01, 1.8689e+01, 1.8373e+01, 1.8072e+01, 1.7785e+01, 1.7511e+01, 1.7248e+01, 1.6995e+01, 1.6753e+01, 1.6518e+01, 1.6292e+01, 1.6072e+01, 1.5858e+01, 1.5650e+01, 1.5446e+01, 1.5246e+01, 1.5050e+01, 1.4857e+01, 1.4666e+01, 1.4478e+01, 1.4292e+01, 1.4107e+01, 1.3924e+01, 1.3742e+01, 1.3560e+01, 1.3380e+01, 1.3201e+01, 1.3023e+01, 1.2846e+01, 1.2669e+01, 1.2494e+01, 1.2319e+01, 1.2146e+01, 1.1973e+01, 1.1801e+01, 1.1630e+01, 1.1462e+01, 1.1294e+01, 1.1127e+01, 1.0962e+01, 1.0799e+01, 1.0638e+01, 1.0479e+01, 1.0321e+01, 1.0165e+01, 1.0012e+01, 9.8615e+00, 9.7125e+00, 9.5656e+00, 9.4213e+00, 9.2801e+00, 9.1417e+00, 9.0054e+00, 8.8711e+00, 8.7395e+00, 8.6112e+00, 8.4862e+00, 8.3638e+00, 8.2435e+00, 8.1254e+00, 8.0103e+00, 7.8987e+00, 7.7904e+00, 7.6846e+00, 7.5808e+00, 7.4790e+00, 7.3800e+00, 7.2845e+00, 7.1923e+00, 7.1027e+00, 7.0149e+00, 6.9287e+00, 6.8447e+00, 6.7637e+00, 6.6860e+00, 6.6111e+00, 6.5381e+00, 6.4664e+00, 6.3960e+00, 6.3276e+00, 6.2620e+00, 6.1994e+00, 6.1390e+00, 6.0802e+00, 6.0224e+00, 5.9653e+00, 5.9096e+00, 5.8563e+00, 5.8056e+00, 5.7569e+00, 5.7097e+00, 5.6633e+00, 5.6172e+00, 5.5716e+00, 5.5274e+00, 5.4853e+00, 5.4454e+00, 5.4069e+00, 5.3694e+00, 5.3322e+00, 5.2950e+00, 5.2578e+00, 5.2216e+00, 5.1872e+00, 5.1546e+00, 5.1231e+00, 5.0923e+00, 5.0618e+00, 5.0311e+00, 5.0001e+00, 4.9690e+00, 4.9391e+00, 4.9109e+00, 4.8839e+00, 4.8574e+00, 4.8313e+00, 4.8052e+00, 4.7788e+00, 4.7517e+00, 4.7244e+00, 4.6979e+00, 4.6728e+00, 4.6489e+00, 4.6253e+00, 4.6018e+00, 4.5784e+00, 4.5547e+00, 4.5303e+00, 4.5052e+00, 4.4800e+00, 4.4560e+00, 4.4333e+00, 4.4112e+00, 4.3891e+00, 4.3670e+00, 4.3448e+00, 4.3225e+00, 4.2994e+00, 4.2753e+00, 4.2510e+00, 4.2276e+00, 4.2056e+00, 4.1843e+00, 4.1629e+00, 4.1413e+00, 4.1196e+00, 4.0981e+00, 4.0761e+00, 4.0531e+00, 4.0292e+00, 4.0054e+00, 3.9828e+00, 3.9615e+00, 3.9407e+00, 3.9195e+00, 3.8980e+00, 3.8766e+00, 3.8554e+00, 3.8340e+00, 3.8116e+00, 3.7882e+00, 3.7644e+00, 3.7415e+00, 3.7201e+00, 3.6997e+00, 3.6792e+00, 3.6581e+00, 3.6368e+00, 3.6158e+00, 3.5951e+00, 3.5741e+00, 3.5521e+00, 3.5290e+00, 3.5056e+00, 3.4831e+00, 3.4622e+00, 3.4424e+00, 3.4227e+00, 3.4023e+00, 3.3815e+00, 3.3610e+00, 3.3409e+00, 3.3210e+00, 3.3005e+00, 3.2788e+00, 3.2562e+00, 3.2337e+00, 3.2125e+00, 3.1929e+00, 3.1743e+00, 3.1555e+00, 3.1362e+00, 3.1164e+00, 3.0968e+00, 3.0778e+00, 3.0592e+00}); + feg = Vctr_cpu({1.5276e+01, 1.4884e+01, 1.3835e+01, 1.2431e+01, 1.0972e+01, 9.6455e+00, 8.5224e+00, 7.5979e+00, 6.8382e+00, 6.2059e+00, 5.6696e+00, 5.2062e+00, 4.7996e+00, 4.4385e+00, 4.1153e+00, 3.8244e+00, 3.5615e+00, 3.3234e+00, 3.1073e+00, 2.9109e+00, 2.7321e+00, 2.5690e+00, 2.4201e+00, 2.2838e+00, 2.1587e+00, 2.0438e+00, 1.9379e+00, 1.8401e+00, 1.7495e+00, 1.6654e+00, 1.5872e+00, 1.5143e+00, 1.4461e+00, 1.3823e+00, 1.3225e+00, 1.2662e+00, 1.2133e+00, 1.1634e+00, 1.1164e+00, 1.0719e+00, 1.0299e+00, 9.9010e-01, 9.5240e-01, 9.1660e-01, 8.8270e-01, 8.5060e-01, 8.2000e-01, 7.9100e-01, 7.6330e-01, 7.3710e-01, 7.1210e-01, 6.8830e-01, 6.6570e-01, 6.4410e-01, 6.2350e-01, 6.0390e-01, 5.8520e-01, 5.6740e-01, 5.5040e-01, 5.3410e-01, 5.1860e-01, 5.0380e-01, 4.8960e-01, 4.7600e-01, 4.6300e-01, 4.5050e-01, 4.3860e-01, 4.2720e-01, 4.1620e-01, 4.0570e-01, 3.9560e-01, 3.8590e-01, 3.7660e-01, 3.6760e-01, 3.5900e-01, 3.5060e-01, 3.4260e-01, 3.3490e-01, 3.2750e-01, 3.2030e-01, 3.1330e-01, 3.0660e-01, 3.0020e-01, 2.9390e-01, 2.8780e-01, 2.8200e-01, 2.7630e-01, 2.7080e-01, 2.6540e-01, 2.6030e-01, 2.5520e-01, 2.5040e-01, 2.4560e-01, 2.4100e-01, 2.3650e-01, 2.3220e-01, 2.2790e-01, 2.2380e-01, 2.1980e-01, 2.1590e-01, 2.1210e-01, 2.0840e-01, 2.0480e-01, 2.0130e-01, 1.9780e-01, 1.9450e-01, 1.9120e-01, 1.8800e-01, 1.8490e-01, 1.8180e-01, 1.7890e-01, 1.7600e-01, 1.7310e-01, 1.7040e-01, 1.6770e-01, 1.6500e-01, 1.6240e-01, 1.5990e-01, 1.5740e-01, 1.5500e-01, 1.5260e-01, 1.5030e-01, 1.4800e-01, 1.4580e-01, 1.4360e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3340e-01, 1.3150e-01, 1.2960e-01, 1.2780e-01, 1.2600e-01, 1.2420e-01, 1.2250e-01, 1.2080e-01, 1.1910e-01, 1.1750e-01, 1.1590e-01, 1.1430e-01, 1.1280e-01, 1.1130e-01, 1.0980e-01, 1.0830e-01, 1.0690e-01, 1.0550e-01, 1.0420e-01, 1.0280e-01, 1.0150e-01, 1.0020e-01, 9.8900e-02, 9.7700e-02, 9.6500e-02, 9.5300e-02, 9.4100e-02, 9.2900e-02, 9.1800e-02, 9.0700e-02, 8.9600e-02, 8.8500e-02, 8.7500e-02, 8.6400e-02, 8.5400e-02, 8.4400e-02, 8.3400e-02, 8.2400e-02, 8.1500e-02, 8.0600e-02, 7.9600e-02, 7.8700e-02, 7.7800e-02, 7.7000e-02, 7.6100e-02, 7.5300e-02, 7.4500e-02, 7.3600e-02, 7.2800e-02, 7.2000e-02, 7.1300e-02, 7.0500e-02, 6.9800e-02, 6.9000e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6200e-02, 6.5500e-02, 6.4800e-02, 6.4200e-02, 6.3500e-02, 6.2900e-02, 6.2200e-02, 6.1600e-02, 6.1000e-02, 6.0400e-02, 5.9800e-02, 5.9200e-02, 5.8700e-02, 5.8100e-02, 5.7500e-02, 5.7000e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3400e-02, 5.2900e-02, 5.2400e-02, 5.1900e-02, 5.1400e-02, 5.1000e-02, 5.0500e-02, 5.0100e-02, 4.9600e-02, 4.9200e-02, 4.8700e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.5900e-02, 4.5500e-02, 4.5100e-02, 4.4700e-02, 4.4300e-02, 4.4000e-02, 4.3600e-02, 4.3200e-02, 4.2900e-02, 4.2500e-02, 4.2200e-02, 4.1800e-02, 4.1500e-02, 4.1200e-02, 4.0800e-02, 4.0500e-02}); + } + break; + case 65: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.5000e+01, 6.4622e+01, 6.3603e+01, 6.2200e+01, 6.0632e+01, 5.9011e+01, 5.7362e+01, 5.5684e+01, 5.3978e+01, 5.2256e+01, 5.0539e+01, 4.8846e+01, 4.7196e+01, 4.5602e+01, 4.4074e+01, 4.2616e+01, 4.1227e+01, 3.9907e+01, 3.8651e+01, 3.7456e+01, 3.6317e+01, 3.5229e+01, 3.4188e+01, 3.3191e+01, 3.2233e+01, 3.1314e+01, 3.0431e+01, 2.9582e+01, 2.8766e+01, 2.7983e+01, 2.7231e+01, 2.6510e+01, 2.5819e+01, 2.5158e+01, 2.4527e+01, 2.3925e+01, 2.3351e+01, 2.2804e+01, 2.2285e+01, 2.1791e+01, 2.1322e+01, 2.0877e+01, 2.0455e+01, 2.0054e+01, 1.9675e+01, 1.9314e+01, 1.8972e+01, 1.8647e+01, 1.8337e+01, 1.8043e+01, 1.7761e+01, 1.7492e+01, 1.7234e+01, 1.6987e+01, 1.6748e+01, 1.6518e+01, 1.6296e+01, 1.6080e+01, 1.5870e+01, 1.5665e+01, 1.5464e+01, 1.5268e+01, 1.5075e+01, 1.4885e+01, 1.4698e+01, 1.4513e+01, 1.4330e+01, 1.4148e+01, 1.3968e+01, 1.3790e+01, 1.3612e+01, 1.3435e+01, 1.3260e+01, 1.3085e+01, 1.2911e+01, 1.2737e+01, 1.2565e+01, 1.2394e+01, 1.2223e+01, 1.2053e+01, 1.1885e+01, 1.1718e+01, 1.1552e+01, 1.1386e+01, 1.1223e+01, 1.1061e+01, 1.0900e+01, 1.0741e+01, 1.0583e+01, 1.0428e+01, 1.0274e+01, 1.0123e+01, 9.9736e+00, 9.8256e+00, 9.6802e+00, 9.5376e+00, 9.3977e+00, 9.2596e+00, 9.1233e+00, 8.9894e+00, 8.8588e+00, 8.7313e+00, 8.6064e+00, 8.4832e+00, 8.3621e+00, 8.2438e+00, 8.1290e+00, 8.0175e+00, 7.9084e+00, 7.8011e+00, 7.6957e+00, 7.5930e+00, 7.4939e+00, 7.3980e+00, 7.3046e+00, 7.2130e+00, 7.1230e+00, 7.0352e+00, 6.9504e+00, 6.8689e+00, 6.7902e+00, 6.7134e+00, 6.6380e+00, 6.5639e+00, 6.4918e+00, 6.4227e+00, 6.3564e+00, 6.2925e+00, 6.2302e+00, 6.1690e+00, 6.1087e+00, 6.0498e+00, 5.9933e+00, 5.9395e+00, 5.8877e+00, 5.8375e+00, 5.7882e+00, 5.7394e+00, 5.6913e+00, 5.6445e+00, 5.6000e+00, 5.5576e+00, 5.5167e+00, 5.4767e+00, 5.4374e+00, 5.3983e+00, 5.3593e+00, 5.3213e+00, 5.2851e+00, 5.2508e+00, 5.2175e+00, 5.1850e+00, 5.1529e+00, 5.1210e+00, 5.0888e+00, 5.0567e+00, 5.0257e+00, 4.9965e+00, 4.9684e+00, 4.9408e+00, 4.9136e+00, 4.8866e+00, 4.8596e+00, 4.8321e+00, 4.8043e+00, 4.7774e+00, 4.7519e+00, 4.7275e+00, 4.7033e+00, 4.6792e+00, 4.6553e+00, 4.6315e+00, 4.6072e+00, 4.5820e+00, 4.5569e+00, 4.5330e+00, 4.5103e+00, 4.4881e+00, 4.4658e+00, 4.4433e+00, 4.4212e+00, 4.3990e+00, 4.3763e+00, 4.3525e+00, 4.3286e+00, 4.3056e+00, 4.2839e+00, 4.2628e+00, 4.2414e+00, 4.2197e+00, 4.1981e+00, 4.1768e+00, 4.1553e+00, 4.1329e+00, 4.1095e+00, 4.0862e+00, 4.0641e+00, 4.0432e+00, 4.0226e+00, 4.0015e+00, 3.9800e+00, 3.9587e+00, 3.9378e+00, 3.9168e+00, 3.8950e+00, 3.8721e+00, 3.8489e+00, 3.8265e+00, 3.8055e+00, 3.7854e+00, 3.7650e+00, 3.7439e+00, 3.7226e+00, 3.7016e+00, 3.6812e+00, 3.6606e+00, 3.6391e+00, 3.6164e+00, 3.5935e+00, 3.5714e+00, 3.5508e+00, 3.5312e+00, 3.5115e+00, 3.4911e+00, 3.4702e+00, 3.4496e+00, 3.4296e+00, 3.4098e+00, 3.3896e+00, 3.3682e+00, 3.3459e+00, 3.3238e+00, 3.3027e+00, 3.2832e+00, 3.2646e+00, 3.2458e+00, 3.2262e+00, 3.2061e+00, 3.1864e+00, 3.1672e+00, 3.1486e+00}); + feg = Vctr_cpu({1.4910e+01, 1.4486e+01, 1.3370e+01, 1.1914e+01, 1.0453e+01, 9.1739e+00, 8.1248e+00, 7.2807e+00, 6.5950e+00, 6.0248e+00, 5.5378e+00, 5.1125e+00, 4.7347e+00, 4.3954e+00, 4.0884e+00, 3.8097e+00, 3.5561e+00, 3.3249e+00, 3.1141e+00, 2.9217e+00, 2.7459e+00, 2.5851e+00, 2.4378e+00, 2.3027e+00, 2.1784e+00, 2.0639e+00, 1.9583e+00, 1.8605e+00, 1.7698e+00, 1.6855e+00, 1.6070e+00, 1.5338e+00, 1.4652e+00, 1.4010e+00, 1.3407e+00, 1.2840e+00, 1.2306e+00, 1.1803e+00, 1.1328e+00, 1.0879e+00, 1.0454e+00, 1.0051e+00, 9.6700e-01, 9.3090e-01, 8.9650e-01, 8.6390e-01, 8.3300e-01, 8.0360e-01, 7.7560e-01, 7.4890e-01, 7.2360e-01, 6.9940e-01, 6.7650e-01, 6.5450e-01, 6.3370e-01, 6.1370e-01, 5.9470e-01, 5.7660e-01, 5.5930e-01, 5.4270e-01, 5.2690e-01, 5.1180e-01, 4.9740e-01, 4.8350e-01, 4.7030e-01, 4.5760e-01, 4.4540e-01, 4.3380e-01, 4.2260e-01, 4.1190e-01, 4.0160e-01, 3.9170e-01, 3.8220e-01, 3.7310e-01, 3.6430e-01, 3.5580e-01, 3.4760e-01, 3.3980e-01, 3.3220e-01, 3.2490e-01, 3.1780e-01, 3.1100e-01, 3.0440e-01, 2.9800e-01, 2.9190e-01, 2.8590e-01, 2.8010e-01, 2.7450e-01, 2.6910e-01, 2.6380e-01, 2.5870e-01, 2.5380e-01, 2.4900e-01, 2.4430e-01, 2.3970e-01, 2.3530e-01, 2.3100e-01, 2.2690e-01, 2.2280e-01, 2.1880e-01, 2.1500e-01, 2.1120e-01, 2.0760e-01, 2.0400e-01, 2.0050e-01, 1.9710e-01, 1.9380e-01, 1.9060e-01, 1.8740e-01, 1.8440e-01, 1.8140e-01, 1.7840e-01, 1.7560e-01, 1.7270e-01, 1.7000e-01, 1.6730e-01, 1.6470e-01, 1.6220e-01, 1.5960e-01, 1.5720e-01, 1.5480e-01, 1.5240e-01, 1.5020e-01, 1.4790e-01, 1.4570e-01, 1.4360e-01, 1.4150e-01, 1.3940e-01, 1.3740e-01, 1.3540e-01, 1.3340e-01, 1.3150e-01, 1.2970e-01, 1.2790e-01, 1.2610e-01, 1.2430e-01, 1.2260e-01, 1.2090e-01, 1.1930e-01, 1.1760e-01, 1.1610e-01, 1.1450e-01, 1.1300e-01, 1.1150e-01, 1.1000e-01, 1.0860e-01, 1.0710e-01, 1.0580e-01, 1.0440e-01, 1.0310e-01, 1.0170e-01, 1.0050e-01, 9.9200e-02, 9.8000e-02, 9.6700e-02, 9.5500e-02, 9.4400e-02, 9.3200e-02, 9.2100e-02, 9.1000e-02, 8.9900e-02, 8.8800e-02, 8.7800e-02, 8.6700e-02, 8.5700e-02, 8.4700e-02, 8.3700e-02, 8.2800e-02, 8.1800e-02, 8.0900e-02, 8.0000e-02, 7.9100e-02, 7.8200e-02, 7.7300e-02, 7.6400e-02, 7.5600e-02, 7.4800e-02, 7.4000e-02, 7.3200e-02, 7.2400e-02, 7.1600e-02, 7.0800e-02, 7.0100e-02, 6.9300e-02, 6.8600e-02, 6.7900e-02, 6.7200e-02, 6.6500e-02, 6.5800e-02, 6.5200e-02, 6.4500e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1300e-02, 6.0700e-02, 6.0100e-02, 5.9600e-02, 5.9000e-02, 5.8400e-02, 5.7900e-02, 5.7300e-02, 5.6800e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1700e-02, 5.1300e-02, 5.0800e-02, 5.0400e-02, 4.9900e-02, 4.9500e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4300e-02, 4.3900e-02, 4.3500e-02, 4.3200e-02, 4.2800e-02, 4.2500e-02, 4.2100e-02, 4.1800e-02, 4.1500e-02, 4.1100e-02}); + } + break; + case 66: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.6000e+01, 6.5629e+01, 6.4628e+01, 6.3242e+01, 6.1689e+01, 6.0077e+01, 5.8434e+01, 5.6760e+01, 5.5055e+01, 5.3331e+01, 5.1605e+01, 4.9900e+01, 4.8233e+01, 4.6618e+01, 4.5066e+01, 4.3580e+01, 4.2163e+01, 4.0813e+01, 3.9528e+01, 3.8303e+01, 3.7135e+01, 3.6020e+01, 3.4952e+01, 3.3929e+01, 3.2947e+01, 3.2004e+01, 3.1098e+01, 3.0227e+01, 2.9390e+01, 2.8586e+01, 2.7814e+01, 2.7073e+01, 2.6363e+01, 2.5683e+01, 2.5033e+01, 2.4412e+01, 2.3819e+01, 2.3254e+01, 2.2717e+01, 2.2206e+01, 2.1720e+01, 2.1258e+01, 2.0820e+01, 2.0405e+01, 2.0010e+01, 1.9636e+01, 1.9281e+01, 1.8944e+01, 1.8623e+01, 1.8317e+01, 1.8026e+01, 1.7749e+01, 1.7483e+01, 1.7228e+01, 1.6984e+01, 1.6749e+01, 1.6521e+01, 1.6302e+01, 1.6089e+01, 1.5882e+01, 1.5680e+01, 1.5483e+01, 1.5289e+01, 1.5100e+01, 1.4913e+01, 1.4729e+01, 1.4547e+01, 1.4368e+01, 1.4190e+01, 1.4014e+01, 1.3838e+01, 1.3665e+01, 1.3492e+01, 1.3320e+01, 1.3149e+01, 1.2978e+01, 1.2809e+01, 1.2640e+01, 1.2472e+01, 1.2305e+01, 1.2139e+01, 1.1974e+01, 1.1810e+01, 1.1646e+01, 1.1484e+01, 1.1324e+01, 1.1165e+01, 1.1007e+01, 1.0850e+01, 1.0694e+01, 1.0541e+01, 1.0390e+01, 1.0240e+01, 1.0092e+01, 9.9455e+00, 9.8020e+00, 9.6608e+00, 9.5213e+00, 9.3833e+00, 9.2476e+00, 9.1149e+00, 8.9852e+00, 8.8578e+00, 8.7321e+00, 8.6082e+00, 8.4870e+00, 8.3692e+00, 8.2544e+00, 8.1420e+00, 8.0313e+00, 7.9225e+00, 7.8163e+00, 7.7135e+00, 7.6139e+00, 7.5167e+00, 7.4213e+00, 7.3275e+00, 7.2358e+00, 7.1472e+00, 7.0618e+00, 6.9791e+00, 6.8985e+00, 6.8192e+00, 6.7413e+00, 6.6654e+00, 6.5925e+00, 6.5225e+00, 6.4549e+00, 6.3889e+00, 6.3241e+00, 6.2603e+00, 6.1980e+00, 6.1381e+00, 6.0809e+00, 6.0260e+00, 5.9725e+00, 5.9201e+00, 5.8684e+00, 5.8173e+00, 5.7678e+00, 5.7205e+00, 5.6754e+00, 5.6319e+00, 5.5895e+00, 5.5477e+00, 5.5063e+00, 5.4651e+00, 5.4250e+00, 5.3868e+00, 5.3505e+00, 5.3154e+00, 5.2811e+00, 5.2473e+00, 5.2138e+00, 5.1801e+00, 5.1466e+00, 5.1143e+00, 5.0837e+00, 5.0544e+00, 5.0257e+00, 4.9974e+00, 4.9695e+00, 4.9416e+00, 4.9132e+00, 4.8847e+00, 4.8571e+00, 4.8310e+00, 4.8059e+00, 4.7812e+00, 4.7566e+00, 4.7323e+00, 4.7081e+00, 4.6834e+00, 4.6580e+00, 4.6328e+00, 4.6086e+00, 4.5858e+00, 4.5635e+00, 4.5411e+00, 4.5186e+00, 4.4965e+00, 4.4744e+00, 4.4516e+00, 4.4280e+00, 4.4042e+00, 4.3814e+00, 4.3599e+00, 4.3389e+00, 4.3178e+00, 4.2963e+00, 4.2749e+00, 4.2539e+00, 4.2327e+00, 4.2105e+00, 4.1875e+00, 4.1645e+00, 4.1427e+00, 4.1221e+00, 4.1018e+00, 4.0811e+00, 4.0600e+00, 4.0390e+00, 4.0184e+00, 3.9978e+00, 3.9763e+00, 3.9538e+00, 3.9310e+00, 3.9090e+00, 3.8883e+00, 3.8685e+00, 3.8484e+00, 3.8277e+00, 3.8067e+00, 3.7861e+00, 3.7659e+00, 3.7456e+00, 3.7244e+00, 3.7021e+00, 3.6795e+00, 3.6577e+00, 3.6373e+00, 3.6180e+00, 3.5985e+00, 3.5783e+00, 3.5576e+00, 3.5372e+00, 3.5174e+00, 3.4978e+00, 3.4777e+00, 3.4565e+00, 3.4345e+00, 3.4125e+00, 3.3916e+00, 3.3722e+00, 3.3536e+00, 3.3349e+00, 3.3153e+00, 3.2954e+00, 3.2757e+00, 3.2566e+00, 3.2379e+00}); + feg = Vctr_cpu({1.4617e+01, 1.4211e+01, 1.3138e+01, 1.1734e+01, 1.0318e+01, 9.0729e+00, 8.0478e+00, 7.2211e+00, 6.5488e+00, 5.9896e+00, 5.5122e+00, 5.0953e+00, 4.7247e+00, 4.3917e+00, 4.0901e+00, 3.8158e+00, 3.5657e+00, 3.3374e+00, 3.1288e+00, 2.9380e+00, 2.7633e+00, 2.6033e+00, 2.4565e+00, 2.3216e+00, 2.1974e+00, 2.0829e+00, 1.9771e+00, 1.8791e+00, 1.7882e+00, 1.7036e+00, 1.6248e+00, 1.5512e+00, 1.4823e+00, 1.4177e+00, 1.3571e+00, 1.3001e+00, 1.2463e+00, 1.1957e+00, 1.1478e+00, 1.1026e+00, 1.0598e+00, 1.0192e+00, 9.8080e-01, 9.4430e-01, 9.0970e-01, 8.7680e-01, 8.4550e-01, 8.1570e-01, 7.8740e-01, 7.6050e-01, 7.3480e-01, 7.1040e-01, 6.8710e-01, 6.6490e-01, 6.4370e-01, 6.2350e-01, 6.0420e-01, 5.8580e-01, 5.6820e-01, 5.5130e-01, 5.3530e-01, 5.1990e-01, 5.0520e-01, 4.9110e-01, 4.7760e-01, 4.6470e-01, 4.5230e-01, 4.4050e-01, 4.2910e-01, 4.1810e-01, 4.0760e-01, 3.9760e-01, 3.8790e-01, 3.7860e-01, 3.6960e-01, 3.6100e-01, 3.5260e-01, 3.4460e-01, 3.3690e-01, 3.2950e-01, 3.2230e-01, 3.1530e-01, 3.0860e-01, 3.0210e-01, 2.9590e-01, 2.8980e-01, 2.8390e-01, 2.7820e-01, 2.7270e-01, 2.6740e-01, 2.6220e-01, 2.5720e-01, 2.5230e-01, 2.4750e-01, 2.4290e-01, 2.3850e-01, 2.3410e-01, 2.2990e-01, 2.2570e-01, 2.2170e-01, 2.1780e-01, 2.1400e-01, 2.1030e-01, 2.0670e-01, 2.0320e-01, 1.9980e-01, 1.9640e-01, 1.9310e-01, 1.9000e-01, 1.8680e-01, 1.8380e-01, 1.8080e-01, 1.7790e-01, 1.7510e-01, 1.7230e-01, 1.6960e-01, 1.6700e-01, 1.6440e-01, 1.6190e-01, 1.5940e-01, 1.5700e-01, 1.5460e-01, 1.5230e-01, 1.5000e-01, 1.4780e-01, 1.4560e-01, 1.4350e-01, 1.4140e-01, 1.3930e-01, 1.3730e-01, 1.3540e-01, 1.3340e-01, 1.3160e-01, 1.2970e-01, 1.2790e-01, 1.2610e-01, 1.2440e-01, 1.2270e-01, 1.2100e-01, 1.1940e-01, 1.1780e-01, 1.1620e-01, 1.1460e-01, 1.1310e-01, 1.1160e-01, 1.1020e-01, 1.0870e-01, 1.0730e-01, 1.0600e-01, 1.0460e-01, 1.0330e-01, 1.0200e-01, 1.0070e-01, 9.9400e-02, 9.8200e-02, 9.7000e-02, 9.5800e-02, 9.4600e-02, 9.3500e-02, 9.2400e-02, 9.1300e-02, 9.0200e-02, 8.9100e-02, 8.8000e-02, 8.7000e-02, 8.6000e-02, 8.5000e-02, 8.4000e-02, 8.3100e-02, 8.2100e-02, 8.1200e-02, 8.0300e-02, 7.9400e-02, 7.8500e-02, 7.7600e-02, 7.6800e-02, 7.5900e-02, 7.5100e-02, 7.4300e-02, 7.3500e-02, 7.2700e-02, 7.1900e-02, 7.1200e-02, 7.0400e-02, 6.9700e-02, 6.8900e-02, 6.8200e-02, 6.7500e-02, 6.6800e-02, 6.6100e-02, 6.5500e-02, 6.4800e-02, 6.4200e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1700e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8700e-02, 5.8200e-02, 5.7600e-02, 5.7100e-02, 5.6500e-02, 5.6000e-02, 5.5500e-02, 5.5000e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2500e-02, 5.2000e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0200e-02, 4.9800e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7200e-02, 4.6800e-02, 4.6400e-02, 4.6100e-02, 4.5700e-02, 4.5300e-02, 4.4900e-02, 4.4500e-02, 4.4200e-02, 4.3800e-02, 4.3500e-02, 4.3100e-02, 4.2700e-02, 4.2400e-02, 4.2100e-02, 4.1700e-02}); + } + break; + case 67: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.7000e+01, 6.6636e+01, 6.5651e+01, 6.4284e+01, 6.2744e+01, 6.1142e+01, 5.9506e+01, 5.7836e+01, 5.6132e+01, 5.4406e+01, 5.2674e+01, 5.0958e+01, 4.9275e+01, 4.7641e+01, 4.6065e+01, 4.4554e+01, 4.3109e+01, 4.1731e+01, 4.0417e+01, 3.9163e+01, 3.7967e+01, 3.6824e+01, 3.5730e+01, 3.4681e+01, 3.3675e+01, 3.2709e+01, 3.1780e+01, 3.0887e+01, 3.0029e+01, 2.9204e+01, 2.8412e+01, 2.7651e+01, 2.6921e+01, 2.6222e+01, 2.5552e+01, 2.4912e+01, 2.4301e+01, 2.3718e+01, 2.3163e+01, 2.2634e+01, 2.2130e+01, 2.1652e+01, 2.1198e+01, 2.0767e+01, 2.0357e+01, 1.9969e+01, 1.9600e+01, 1.9250e+01, 1.8917e+01, 1.8600e+01, 1.8299e+01, 1.8011e+01, 1.7737e+01, 1.7474e+01, 1.7223e+01, 1.6981e+01, 1.6749e+01, 1.6525e+01, 1.6308e+01, 1.6098e+01, 1.5893e+01, 1.5694e+01, 1.5500e+01, 1.5310e+01, 1.5123e+01, 1.4940e+01, 1.4759e+01, 1.4581e+01, 1.4404e+01, 1.4230e+01, 1.4057e+01, 1.3885e+01, 1.3715e+01, 1.3546e+01, 1.3377e+01, 1.3210e+01, 1.3043e+01, 1.2877e+01, 1.2712e+01, 1.2547e+01, 1.2384e+01, 1.2222e+01, 1.2060e+01, 1.1898e+01, 1.1738e+01, 1.1579e+01, 1.1422e+01, 1.1265e+01, 1.1109e+01, 1.0955e+01, 1.0803e+01, 1.0652e+01, 1.0502e+01, 1.0354e+01, 1.0207e+01, 1.0063e+01, 9.9211e+00, 9.7807e+00, 9.6416e+00, 9.5046e+00, 9.3703e+00, 9.2388e+00, 9.1094e+00, 8.9816e+00, 8.8555e+00, 8.7319e+00, 8.6114e+00, 8.4939e+00, 8.3786e+00, 8.2649e+00, 8.1529e+00, 8.0436e+00, 7.9375e+00, 7.8344e+00, 7.7338e+00, 7.6349e+00, 7.5375e+00, 7.4422e+00, 7.3499e+00, 7.2608e+00, 7.1744e+00, 7.0900e+00, 7.0070e+00, 6.9254e+00, 6.8458e+00, 6.7692e+00, 6.6955e+00, 6.6242e+00, 6.5547e+00, 6.4863e+00, 6.4189e+00, 6.3532e+00, 6.2899e+00, 6.2294e+00, 6.1711e+00, 6.1144e+00, 6.0588e+00, 6.0039e+00, 5.9499e+00, 5.8974e+00, 5.8473e+00, 5.7994e+00, 5.7532e+00, 5.7081e+00, 5.6638e+00, 5.6199e+00, 5.5763e+00, 5.5340e+00, 5.4936e+00, 5.4551e+00, 5.4180e+00, 5.3817e+00, 5.3460e+00, 5.3107e+00, 5.2753e+00, 5.2402e+00, 5.2063e+00, 5.1743e+00, 5.1436e+00, 5.1136e+00, 5.0840e+00, 5.0549e+00, 5.0259e+00, 4.9965e+00, 4.9670e+00, 4.9385e+00, 4.9116e+00, 4.8857e+00, 4.8603e+00, 4.8351e+00, 4.8102e+00, 4.7855e+00, 4.7603e+00, 4.7345e+00, 4.7088e+00, 4.6844e+00, 4.6612e+00, 4.6386e+00, 4.6160e+00, 4.5935e+00, 4.5712e+00, 4.5490e+00, 4.5262e+00, 4.5026e+00, 4.4788e+00, 4.4560e+00, 4.4345e+00, 4.4137e+00, 4.3926e+00, 4.3713e+00, 4.3502e+00, 4.3293e+00, 4.3083e+00, 4.2863e+00, 4.2635e+00, 4.2409e+00, 4.2193e+00, 4.1990e+00, 4.1790e+00, 4.1586e+00, 4.1378e+00, 4.1171e+00, 4.0969e+00, 4.0765e+00, 4.0554e+00, 4.0332e+00, 4.0108e+00, 3.9891e+00, 3.9688e+00, 3.9492e+00, 3.9295e+00, 3.9091e+00, 3.8885e+00, 3.8682e+00, 3.8484e+00, 3.8283e+00, 3.8074e+00, 3.7855e+00, 3.7632e+00, 3.7418e+00, 3.7217e+00, 3.7025e+00, 3.6833e+00, 3.6633e+00, 3.6429e+00, 3.6228e+00, 3.6032e+00, 3.5838e+00, 3.5639e+00, 3.5430e+00, 3.5212e+00, 3.4994e+00, 3.4787e+00, 3.4595e+00, 3.4410e+00, 3.4224e+00, 3.4030e+00, 3.3831e+00, 3.3635e+00, 3.3445e+00, 3.3259e+00}); + feg = Vctr_cpu({1.4334e+01, 1.3944e+01, 1.2913e+01, 1.1558e+01, 1.0186e+01, 8.9737e+00, 7.9719e+00, 7.1621e+00, 6.5027e+00, 5.9542e+00, 5.4859e+00, 5.0770e+00, 4.7136e+00, 4.3866e+00, 4.0902e+00, 3.8202e+00, 3.5737e+00, 3.3483e+00, 3.1419e+00, 2.9528e+00, 2.7794e+00, 2.6203e+00, 2.4741e+00, 2.3395e+00, 2.2155e+00, 2.1010e+00, 1.9951e+00, 1.8970e+00, 1.8058e+00, 1.7210e+00, 1.6419e+00, 1.5680e+00, 1.4988e+00, 1.4339e+00, 1.3730e+00, 1.3157e+00, 1.2617e+00, 1.2107e+00, 1.1625e+00, 1.1170e+00, 1.0739e+00, 1.0330e+00, 9.9430e-01, 9.5750e-01, 9.2260e-01, 8.8940e-01, 8.5780e-01, 8.2780e-01, 7.9920e-01, 7.7190e-01, 7.4600e-01, 7.2120e-01, 6.9770e-01, 6.7520e-01, 6.5370e-01, 6.3320e-01, 6.1360e-01, 5.9490e-01, 5.7700e-01, 5.6000e-01, 5.4360e-01, 5.2800e-01, 5.1300e-01, 4.9870e-01, 4.8500e-01, 4.7190e-01, 4.5930e-01, 4.4720e-01, 4.3560e-01, 4.2440e-01, 4.1380e-01, 4.0350e-01, 3.9360e-01, 3.8410e-01, 3.7500e-01, 3.6620e-01, 3.5770e-01, 3.4960e-01, 3.4170e-01, 3.3410e-01, 3.2680e-01, 3.1970e-01, 3.1290e-01, 3.0630e-01, 2.9990e-01, 2.9370e-01, 2.8780e-01, 2.8200e-01, 2.7640e-01, 2.7090e-01, 2.6570e-01, 2.6060e-01, 2.5560e-01, 2.5080e-01, 2.4610e-01, 2.4160e-01, 2.3720e-01, 2.3290e-01, 2.2870e-01, 2.2460e-01, 2.2070e-01, 2.1680e-01, 2.1310e-01, 2.0940e-01, 2.0590e-01, 2.0240e-01, 1.9900e-01, 1.9570e-01, 1.9250e-01, 1.8930e-01, 1.8620e-01, 1.8320e-01, 1.8030e-01, 1.7740e-01, 1.7460e-01, 1.7190e-01, 1.6920e-01, 1.6660e-01, 1.6410e-01, 1.6150e-01, 1.5910e-01, 1.5670e-01, 1.5440e-01, 1.5210e-01, 1.4980e-01, 1.4760e-01, 1.4550e-01, 1.4330e-01, 1.4130e-01, 1.3930e-01, 1.3730e-01, 1.3530e-01, 1.3340e-01, 1.3160e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2440e-01, 1.2280e-01, 1.2110e-01, 1.1950e-01, 1.1790e-01, 1.1630e-01, 1.1480e-01, 1.1330e-01, 1.1180e-01, 1.1030e-01, 1.0890e-01, 1.0750e-01, 1.0620e-01, 1.0480e-01, 1.0350e-01, 1.0220e-01, 1.0090e-01, 9.9700e-02, 9.8400e-02, 9.7200e-02, 9.6100e-02, 9.4900e-02, 9.3700e-02, 9.2600e-02, 9.1500e-02, 9.0400e-02, 8.9400e-02, 8.8300e-02, 8.7300e-02, 8.6300e-02, 8.5300e-02, 8.4300e-02, 8.3300e-02, 8.2400e-02, 8.1500e-02, 8.0600e-02, 7.9700e-02, 7.8800e-02, 7.7900e-02, 7.7100e-02, 7.6200e-02, 7.5400e-02, 7.4600e-02, 7.3800e-02, 7.3000e-02, 7.2200e-02, 7.1500e-02, 7.0700e-02, 7.0000e-02, 6.9300e-02, 6.8500e-02, 6.7800e-02, 6.7100e-02, 6.6500e-02, 6.5800e-02, 6.5100e-02, 6.4500e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1400e-02, 6.0800e-02, 6.0200e-02, 5.9600e-02, 5.9000e-02, 5.8500e-02, 5.7900e-02, 5.7400e-02, 5.6800e-02, 5.6300e-02, 5.5800e-02, 5.5300e-02, 5.4800e-02, 5.4300e-02, 5.3800e-02, 5.3300e-02, 5.2800e-02, 5.2300e-02, 5.1900e-02, 5.1400e-02, 5.1000e-02, 5.0500e-02, 5.0100e-02, 4.9600e-02, 4.9200e-02, 4.8800e-02, 4.8400e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6700e-02, 4.6300e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4800e-02, 4.4500e-02, 4.4100e-02, 4.3700e-02, 4.3400e-02, 4.3000e-02, 4.2700e-02, 4.2300e-02}); + } + break; + case 68: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.8000e+01, 6.7644e+01, 6.6676e+01, 6.5326e+01, 6.3799e+01, 6.2206e+01, 6.0577e+01, 5.8912e+01, 5.7211e+01, 5.5484e+01, 5.3748e+01, 5.2023e+01, 5.0327e+01, 4.8675e+01, 4.7079e+01, 4.5544e+01, 4.4073e+01, 4.2667e+01, 4.1325e+01, 4.0044e+01, 3.8820e+01, 3.7650e+01, 3.6529e+01, 3.5455e+01, 3.4424e+01, 3.3433e+01, 3.2482e+01, 3.1566e+01, 3.0686e+01, 2.9840e+01, 2.9027e+01, 2.8246e+01, 2.7496e+01, 2.6777e+01, 2.6088e+01, 2.5429e+01, 2.4799e+01, 2.4197e+01, 2.3623e+01, 2.3076e+01, 2.2556e+01, 2.2060e+01, 2.1589e+01, 2.1142e+01, 2.0717e+01, 2.0313e+01, 1.9930e+01, 1.9566e+01, 1.9221e+01, 1.8892e+01, 1.8579e+01, 1.8282e+01, 1.7997e+01, 1.7726e+01, 1.7467e+01, 1.7218e+01, 1.6980e+01, 1.6750e+01, 1.6528e+01, 1.6314e+01, 1.6107e+01, 1.5905e+01, 1.5709e+01, 1.5517e+01, 1.5329e+01, 1.5146e+01, 1.4965e+01, 1.4787e+01, 1.4612e+01, 1.4439e+01, 1.4268e+01, 1.4098e+01, 1.3930e+01, 1.3762e+01, 1.3597e+01, 1.3432e+01, 1.3268e+01, 1.3104e+01, 1.2942e+01, 1.2780e+01, 1.2619e+01, 1.2459e+01, 1.2299e+01, 1.2140e+01, 1.1983e+01, 1.1826e+01, 1.1669e+01, 1.1514e+01, 1.1361e+01, 1.1208e+01, 1.1056e+01, 1.0906e+01, 1.0757e+01, 1.0609e+01, 1.0464e+01, 1.0319e+01, 1.0176e+01, 1.0035e+01, 9.8959e+00, 9.7592e+00, 9.6241e+00, 9.4904e+00, 9.3584e+00, 9.2288e+00, 9.1021e+00, 8.9777e+00, 8.8551e+00, 8.7340e+00, 8.6150e+00, 8.4987e+00, 8.3854e+00, 8.2746e+00, 8.1658e+00, 8.0585e+00, 7.9531e+00, 7.8504e+00, 7.7508e+00, 7.6540e+00, 7.5593e+00, 7.4661e+00, 7.3745e+00, 7.2851e+00, 7.1984e+00, 7.1148e+00, 7.0337e+00, 6.9542e+00, 6.8761e+00, 6.7994e+00, 6.7247e+00, 6.6525e+00, 6.5832e+00, 6.5163e+00, 6.4507e+00, 6.3863e+00, 6.3230e+00, 6.2611e+00, 6.2012e+00, 6.1439e+00, 6.0890e+00, 6.0355e+00, 5.9830e+00, 5.9312e+00, 5.8804e+00, 5.8306e+00, 5.7827e+00, 5.7370e+00, 5.6932e+00, 5.6506e+00, 5.6085e+00, 5.5669e+00, 5.5259e+00, 5.4856e+00, 5.4464e+00, 5.4091e+00, 5.3737e+00, 5.3393e+00, 5.3052e+00, 5.2714e+00, 5.2379e+00, 5.2047e+00, 5.1720e+00, 5.1402e+00, 5.1100e+00, 5.0814e+00, 5.0534e+00, 5.0253e+00, 4.9971e+00, 4.9692e+00, 4.9415e+00, 4.9138e+00, 4.8866e+00, 4.8606e+00, 4.8360e+00, 4.8122e+00, 4.7883e+00, 4.7639e+00, 4.7396e+00, 4.7154e+00, 4.6912e+00, 4.6668e+00, 4.6427e+00, 4.6198e+00, 4.5982e+00, 4.5770e+00, 4.5554e+00, 4.5333e+00, 4.5110e+00, 4.4890e+00, 4.4669e+00, 4.4444e+00, 4.4217e+00, 4.3998e+00, 4.3792e+00, 4.3594e+00, 4.3395e+00, 4.3188e+00, 4.2976e+00, 4.2764e+00, 4.2555e+00, 4.2344e+00, 4.2128e+00, 4.1909e+00, 4.1697e+00, 4.1497e+00, 4.1307e+00, 4.1115e+00, 4.0914e+00, 4.0706e+00, 4.0498e+00, 4.0294e+00, 4.0090e+00, 3.9881e+00, 3.9666e+00, 3.9452e+00, 3.9247e+00, 3.9055e+00, 3.8869e+00, 3.8679e+00, 3.8479e+00, 3.8273e+00, 3.8067e+00, 3.7866e+00, 3.7667e+00, 3.7462e+00, 3.7251e+00, 3.7038e+00, 3.6832e+00, 3.6639e+00, 3.6456e+00, 3.6274e+00, 3.6083e+00, 3.5882e+00, 3.5678e+00, 3.5477e+00, 3.5282e+00, 3.5088e+00, 3.4887e+00, 3.4680e+00, 3.4471e+00, 3.4270e+00, 3.4082e+00}); + feg = Vctr_cpu({1.4017e+01, 1.3651e+01, 1.2675e+01, 1.1379e+01, 1.0054e+01, 8.8750e+00, 7.8962e+00, 7.1024e+00, 6.4553e+00, 5.9169e+00, 5.4575e+00, 5.0563e+00, 4.6997e+00, 4.3788e+00, 4.0875e+00, 3.8220e+00, 3.5791e+00, 3.3567e+00, 3.1527e+00, 2.9655e+00, 2.7935e+00, 2.6355e+00, 2.4900e+00, 2.3559e+00, 2.2322e+00, 2.1179e+00, 2.0120e+00, 1.9138e+00, 1.8226e+00, 1.7376e+00, 1.6583e+00, 1.5841e+00, 1.5147e+00, 1.4496e+00, 1.3884e+00, 1.3308e+00, 1.2765e+00, 1.2253e+00, 1.1768e+00, 1.1310e+00, 1.0877e+00, 1.0465e+00, 1.0075e+00, 9.7050e-01, 9.3530e-01, 9.0180e-01, 8.6990e-01, 8.3960e-01, 8.1070e-01, 7.8320e-01, 7.5700e-01, 7.3200e-01, 7.0810e-01, 6.8540e-01, 6.6360e-01, 6.4290e-01, 6.2300e-01, 6.0410e-01, 5.8590e-01, 5.6860e-01, 5.5200e-01, 5.3610e-01, 5.2090e-01, 5.0640e-01, 4.9240e-01, 4.7910e-01, 4.6620e-01, 4.5390e-01, 4.4210e-01, 4.3080e-01, 4.1990e-01, 4.0950e-01, 3.9940e-01, 3.8970e-01, 3.8040e-01, 3.7150e-01, 3.6290e-01, 3.5460e-01, 3.4650e-01, 3.3880e-01, 3.3140e-01, 3.2420e-01, 3.1720e-01, 3.1050e-01, 3.0400e-01, 2.9770e-01, 2.9170e-01, 2.8580e-01, 2.8010e-01, 2.7460e-01, 2.6920e-01, 2.6400e-01, 2.5900e-01, 2.5410e-01, 2.4940e-01, 2.4470e-01, 2.4030e-01, 2.3590e-01, 2.3170e-01, 2.2760e-01, 2.2350e-01, 2.1960e-01, 2.1580e-01, 2.1210e-01, 2.0850e-01, 2.0500e-01, 2.0160e-01, 1.9820e-01, 1.9500e-01, 1.9180e-01, 1.8870e-01, 1.8560e-01, 1.8270e-01, 1.7980e-01, 1.7690e-01, 1.7420e-01, 1.7150e-01, 1.6880e-01, 1.6620e-01, 1.6370e-01, 1.6120e-01, 1.5880e-01, 1.5640e-01, 1.5410e-01, 1.5180e-01, 1.4960e-01, 1.4740e-01, 1.4530e-01, 1.4320e-01, 1.4120e-01, 1.3920e-01, 1.3720e-01, 1.3530e-01, 1.3340e-01, 1.3150e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2280e-01, 1.2120e-01, 1.1960e-01, 1.1800e-01, 1.1640e-01, 1.1490e-01, 1.1340e-01, 1.1190e-01, 1.1050e-01, 1.0910e-01, 1.0770e-01, 1.0630e-01, 1.0500e-01, 1.0370e-01, 1.0240e-01, 1.0110e-01, 9.9900e-02, 9.8700e-02, 9.7500e-02, 9.6300e-02, 9.5100e-02, 9.4000e-02, 9.2900e-02, 9.1800e-02, 9.0700e-02, 8.9600e-02, 8.8600e-02, 8.7600e-02, 8.6500e-02, 8.5600e-02, 8.4600e-02, 8.3600e-02, 8.2700e-02, 8.1800e-02, 8.0800e-02, 8.0000e-02, 7.9100e-02, 7.8200e-02, 7.7400e-02, 7.6500e-02, 7.5700e-02, 7.4900e-02, 7.4100e-02, 7.3300e-02, 7.2500e-02, 7.1800e-02, 7.1000e-02, 7.0300e-02, 6.9500e-02, 6.8800e-02, 6.8100e-02, 6.7400e-02, 6.6800e-02, 6.6100e-02, 6.5400e-02, 6.4800e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1700e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4600e-02, 5.4100e-02, 5.3600e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1700e-02, 5.1200e-02, 5.0800e-02, 5.0300e-02, 4.9900e-02, 4.9500e-02, 4.9100e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5800e-02, 4.5500e-02, 4.5100e-02, 4.4700e-02, 4.4400e-02, 4.4000e-02, 4.3600e-02, 4.3300e-02, 4.2900e-02}); + } + break; + case 69: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({6.9000e+01, 6.8650e+01, 6.7698e+01, 6.6365e+01, 6.4852e+01, 6.3269e+01, 6.1647e+01, 5.9988e+01, 5.8290e+01, 5.6563e+01, 5.4823e+01, 5.3090e+01, 5.1382e+01, 4.9714e+01, 4.8097e+01, 4.6540e+01, 4.5044e+01, 4.3613e+01, 4.2244e+01, 4.0935e+01, 3.9684e+01, 3.8487e+01, 3.7340e+01, 3.6240e+01, 3.5185e+01, 3.4171e+01, 3.3196e+01, 3.2259e+01, 3.1357e+01, 3.0490e+01, 2.9656e+01, 2.8854e+01, 2.8084e+01, 2.7346e+01, 2.6638e+01, 2.5959e+01, 2.5310e+01, 2.4690e+01, 2.4098e+01, 2.3532e+01, 2.2994e+01, 2.2481e+01, 2.1993e+01, 2.1529e+01, 2.1088e+01, 2.0670e+01, 2.0272e+01, 1.9894e+01, 1.9535e+01, 1.9193e+01, 1.8869e+01, 1.8560e+01, 1.8266e+01, 1.7985e+01, 1.7717e+01, 1.7460e+01, 1.7214e+01, 1.6978e+01, 1.6751e+01, 1.6532e+01, 1.6320e+01, 1.6115e+01, 1.5916e+01, 1.5722e+01, 1.5533e+01, 1.5348e+01, 1.5167e+01, 1.4989e+01, 1.4815e+01, 1.4642e+01, 1.4472e+01, 1.4304e+01, 1.4137e+01, 1.3972e+01, 1.3808e+01, 1.3646e+01, 1.3484e+01, 1.3323e+01, 1.3163e+01, 1.3004e+01, 1.2845e+01, 1.2688e+01, 1.2530e+01, 1.2374e+01, 1.2219e+01, 1.2064e+01, 1.1910e+01, 1.1757e+01, 1.1604e+01, 1.1454e+01, 1.1303e+01, 1.1154e+01, 1.1006e+01, 1.0859e+01, 1.0714e+01, 1.0570e+01, 1.0428e+01, 1.0286e+01, 1.0147e+01, 1.0010e+01, 9.8742e+00, 9.7397e+00, 9.6067e+00, 9.4760e+00, 9.3479e+00, 9.2220e+00, 9.0976e+00, 8.9747e+00, 8.8537e+00, 8.7352e+00, 8.6196e+00, 8.5064e+00, 8.3949e+00, 8.2850e+00, 8.1769e+00, 8.0713e+00, 7.9687e+00, 7.8689e+00, 7.7710e+00, 7.6747e+00, 7.5799e+00, 7.4871e+00, 7.3972e+00, 7.3102e+00, 7.2257e+00, 7.1428e+00, 7.0613e+00, 6.9812e+00, 6.9031e+00, 6.8275e+00, 6.7548e+00, 6.6844e+00, 6.6155e+00, 6.5478e+00, 6.4812e+00, 6.4161e+00, 6.3530e+00, 6.2925e+00, 6.2344e+00, 6.1779e+00, 6.1223e+00, 6.0676e+00, 6.0139e+00, 5.9613e+00, 5.9106e+00, 5.8622e+00, 5.8158e+00, 5.7706e+00, 5.7260e+00, 5.6820e+00, 5.6387e+00, 5.5961e+00, 5.5548e+00, 5.5153e+00, 5.4778e+00, 5.4415e+00, 5.4055e+00, 5.3698e+00, 5.3346e+00, 5.2998e+00, 5.2654e+00, 5.2321e+00, 5.2005e+00, 5.1705e+00, 5.1411e+00, 5.1118e+00, 5.0825e+00, 5.0534e+00, 5.0247e+00, 4.9960e+00, 4.9678e+00, 4.9410e+00, 4.9156e+00, 4.8910e+00, 4.8664e+00, 4.8414e+00, 4.8164e+00, 4.7917e+00, 4.7670e+00, 4.7422e+00, 4.7177e+00, 4.6944e+00, 4.6725e+00, 4.6510e+00, 4.6292e+00, 4.6069e+00, 4.5845e+00, 4.5623e+00, 4.5401e+00, 4.5176e+00, 4.4949e+00, 4.4730e+00, 4.4524e+00, 4.4327e+00, 4.4128e+00, 4.3922e+00, 4.3711e+00, 4.3501e+00, 4.3294e+00, 4.3085e+00, 4.2870e+00, 4.2654e+00, 4.2444e+00, 4.2247e+00, 4.2058e+00, 4.1869e+00, 4.1671e+00, 4.1466e+00, 4.1261e+00, 4.1059e+00, 4.0858e+00, 4.0653e+00, 4.0441e+00, 4.0230e+00, 4.0028e+00, 3.9839e+00, 3.9656e+00, 3.9469e+00, 3.9272e+00, 3.9069e+00, 3.8867e+00, 3.8669e+00, 3.8472e+00, 3.8271e+00, 3.8063e+00, 3.7853e+00, 3.7650e+00, 3.7459e+00, 3.7279e+00, 3.7099e+00, 3.6911e+00, 3.6713e+00, 3.6511e+00, 3.6313e+00, 3.6120e+00, 3.5927e+00, 3.5729e+00, 3.5524e+00, 3.5318e+00, 3.5118e+00, 3.4932e+00}); + feg = Vctr_cpu({1.3756e+01, 1.3403e+01, 1.2463e+01, 1.1212e+01, 9.9270e+00, 8.7783e+00, 7.8213e+00, 7.0433e+00, 6.4083e+00, 5.8797e+00, 5.4288e+00, 5.0351e+00, 4.6851e+00, 4.3700e+00, 4.0839e+00, 3.8226e+00, 3.5834e+00, 3.3639e+00, 3.1623e+00, 2.9770e+00, 2.8065e+00, 2.6496e+00, 2.5049e+00, 2.3714e+00, 2.2481e+00, 2.1340e+00, 2.0282e+00, 1.9300e+00, 1.8386e+00, 1.7535e+00, 1.6741e+00, 1.5997e+00, 1.5301e+00, 1.4647e+00, 1.4033e+00, 1.3455e+00, 1.2909e+00, 1.2394e+00, 1.1908e+00, 1.1447e+00, 1.1011e+00, 1.0597e+00, 1.0204e+00, 9.8310e-01, 9.4770e-01, 9.1400e-01, 8.8180e-01, 8.5130e-01, 8.2210e-01, 7.9440e-01, 7.6790e-01, 7.4260e-01, 7.1850e-01, 6.9550e-01, 6.7350e-01, 6.5250e-01, 6.3240e-01, 6.1310e-01, 5.9480e-01, 5.7720e-01, 5.6040e-01, 5.4430e-01, 5.2880e-01, 5.1400e-01, 4.9990e-01, 4.8630e-01, 4.7320e-01, 4.6070e-01, 4.4870e-01, 4.3720e-01, 4.2610e-01, 4.1550e-01, 4.0530e-01, 3.9540e-01, 3.8600e-01, 3.7680e-01, 3.6810e-01, 3.5960e-01, 3.5140e-01, 3.4360e-01, 3.3600e-01, 3.2870e-01, 3.2160e-01, 3.1480e-01, 3.0820e-01, 3.0180e-01, 2.9560e-01, 2.8960e-01, 2.8380e-01, 2.7820e-01, 2.7280e-01, 2.6750e-01, 2.6240e-01, 2.5740e-01, 2.5260e-01, 2.4790e-01, 2.4340e-01, 2.3900e-01, 2.3470e-01, 2.3050e-01, 2.2640e-01, 2.2250e-01, 2.1860e-01, 2.1490e-01, 2.1120e-01, 2.0760e-01, 2.0420e-01, 2.0080e-01, 1.9750e-01, 1.9420e-01, 1.9110e-01, 1.8800e-01, 1.8500e-01, 1.8210e-01, 1.7920e-01, 1.7640e-01, 1.7370e-01, 1.7100e-01, 1.6840e-01, 1.6580e-01, 1.6330e-01, 1.6090e-01, 1.5850e-01, 1.5610e-01, 1.5380e-01, 1.5160e-01, 1.4940e-01, 1.4720e-01, 1.4510e-01, 1.4310e-01, 1.4100e-01, 1.3910e-01, 1.3710e-01, 1.3520e-01, 1.3330e-01, 1.3150e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2280e-01, 1.2120e-01, 1.1960e-01, 1.1800e-01, 1.1650e-01, 1.1500e-01, 1.1350e-01, 1.1210e-01, 1.1060e-01, 1.0920e-01, 1.0780e-01, 1.0650e-01, 1.0520e-01, 1.0390e-01, 1.0260e-01, 1.0130e-01, 1.0010e-01, 9.8900e-02, 9.7700e-02, 9.6500e-02, 9.5300e-02, 9.4200e-02, 9.3100e-02, 9.2000e-02, 9.0900e-02, 8.9900e-02, 8.8800e-02, 8.7800e-02, 8.6800e-02, 8.5800e-02, 8.4800e-02, 8.3900e-02, 8.3000e-02, 8.2000e-02, 8.1100e-02, 8.0200e-02, 7.9300e-02, 7.8500e-02, 7.7600e-02, 7.6800e-02, 7.6000e-02, 7.5200e-02, 7.4400e-02, 7.3600e-02, 7.2800e-02, 7.2000e-02, 7.1300e-02, 7.0600e-02, 6.9800e-02, 6.9100e-02, 6.8400e-02, 6.7700e-02, 6.7100e-02, 6.6400e-02, 6.5700e-02, 6.5100e-02, 6.4400e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1400e-02, 6.0800e-02, 6.0200e-02, 5.9600e-02, 5.9100e-02, 5.8500e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5300e-02, 5.4800e-02, 5.4300e-02, 5.3900e-02, 5.3400e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1500e-02, 5.1100e-02, 5.0600e-02, 5.0200e-02, 4.9800e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5700e-02, 4.5400e-02, 4.5000e-02, 4.4600e-02, 4.4300e-02, 4.3900e-02, 4.3600e-02}); + } + break; + case 70: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.0000e+01, 6.9660e+01, 6.8728e+01, 6.7410e+01, 6.5907e+01, 6.4332e+01, 6.2717e+01, 6.1062e+01, 5.9367e+01, 5.7642e+01, 5.5901e+01, 5.4161e+01, 5.2442e+01, 5.0760e+01, 4.9125e+01, 4.7546e+01, 4.6027e+01, 4.4571e+01, 4.3176e+01, 4.1841e+01, 4.0563e+01, 3.9340e+01, 3.8167e+01, 3.7042e+01, 3.5962e+01, 3.4925e+01, 3.3927e+01, 3.2967e+01, 3.2043e+01, 3.1155e+01, 3.0300e+01, 2.9478e+01, 2.8688e+01, 2.7930e+01, 2.7202e+01, 2.6504e+01, 2.5836e+01, 2.5197e+01, 2.4586e+01, 2.4003e+01, 2.3446e+01, 2.2916e+01, 2.2411e+01, 2.1930e+01, 2.1473e+01, 2.1038e+01, 2.0625e+01, 2.0233e+01, 1.9860e+01, 1.9505e+01, 1.9168e+01, 1.8847e+01, 1.8542e+01, 1.8251e+01, 1.7973e+01, 1.7708e+01, 1.7454e+01, 1.7211e+01, 1.6977e+01, 1.6753e+01, 1.6536e+01, 1.6326e+01, 1.6124e+01, 1.5927e+01, 1.5736e+01, 1.5549e+01, 1.5367e+01, 1.5188e+01, 1.5013e+01, 1.4841e+01, 1.4671e+01, 1.4504e+01, 1.4338e+01, 1.4174e+01, 1.4012e+01, 1.3852e+01, 1.3692e+01, 1.3533e+01, 1.3376e+01, 1.3219e+01, 1.3063e+01, 1.2907e+01, 1.2753e+01, 1.2599e+01, 1.2446e+01, 1.2293e+01, 1.2142e+01, 1.1991e+01, 1.1841e+01, 1.1691e+01, 1.1542e+01, 1.1395e+01, 1.1248e+01, 1.1103e+01, 1.0959e+01, 1.0815e+01, 1.0673e+01, 1.0533e+01, 1.0394e+01, 1.0256e+01, 1.0120e+01, 9.9853e+00, 9.8523e+00, 9.7211e+00, 9.5917e+00, 9.4642e+00, 9.3385e+00, 9.2145e+00, 9.0923e+00, 8.9721e+00, 8.8543e+00, 8.7387e+00, 8.6250e+00, 8.5129e+00, 8.4028e+00, 8.2950e+00, 8.1896e+00, 8.0866e+00, 7.9856e+00, 7.8865e+00, 7.7891e+00, 7.6936e+00, 7.6007e+00, 7.5104e+00, 7.4223e+00, 7.3360e+00, 7.2513e+00, 7.1683e+00, 7.0872e+00, 7.0085e+00, 6.9324e+00, 6.8584e+00, 6.7860e+00, 6.7149e+00, 6.6452e+00, 6.5772e+00, 6.5113e+00, 6.4477e+00, 6.3862e+00, 6.3263e+00, 6.2676e+00, 6.2097e+00, 6.1531e+00, 6.0981e+00, 6.0451e+00, 5.9939e+00, 5.9445e+00, 5.8964e+00, 5.8490e+00, 5.8022e+00, 5.7562e+00, 5.7117e+00, 5.6688e+00, 5.6273e+00, 5.5874e+00, 5.5486e+00, 5.5105e+00, 5.4725e+00, 5.4348e+00, 5.3982e+00, 5.3628e+00, 5.3286e+00, 5.2955e+00, 5.2636e+00, 5.2326e+00, 5.2017e+00, 5.1706e+00, 5.1396e+00, 5.1095e+00, 5.0804e+00, 5.0521e+00, 5.0245e+00, 4.9979e+00, 4.9722e+00, 4.9466e+00, 4.9205e+00, 4.8941e+00, 4.8681e+00, 4.8429e+00, 4.8184e+00, 4.7944e+00, 4.7709e+00, 4.7481e+00, 4.7260e+00, 4.7038e+00, 4.6808e+00, 4.6573e+00, 4.6341e+00, 4.6118e+00, 4.5900e+00, 4.5683e+00, 4.5468e+00, 4.5260e+00, 4.5060e+00, 4.4859e+00, 4.4651e+00, 4.4435e+00, 4.4217e+00, 4.4004e+00, 4.3798e+00, 4.3595e+00, 4.3392e+00, 4.3189e+00, 4.2992e+00, 4.2803e+00, 4.2613e+00, 4.2415e+00, 4.2207e+00, 4.1996e+00, 4.1790e+00, 4.1591e+00, 4.1395e+00, 4.1198e+00, 4.0999e+00, 4.0804e+00, 4.0616e+00, 4.0433e+00, 4.0246e+00, 4.0048e+00, 3.9841e+00, 3.9633e+00, 3.9432e+00, 3.9239e+00, 3.9047e+00, 3.8853e+00, 3.8656e+00, 3.8463e+00, 3.8276e+00, 3.8096e+00, 3.7915e+00, 3.7724e+00, 3.7521e+00, 3.7314e+00, 3.7112e+00, 3.6918e+00, 3.6730e+00, 3.6542e+00, 3.6350e+00, 3.6156e+00, 3.5966e+00, 3.5784e+00}); + feg = Vctr_cpu({1.3347e+01, 1.3033e+01, 1.2182e+01, 1.1021e+01, 9.7961e+00, 8.6818e+00, 7.7468e+00, 6.9852e+00, 6.3620e+00, 5.8423e+00, 5.3991e+00, 5.0128e+00, 4.6693e+00, 4.3597e+00, 4.0784e+00, 3.8216e+00, 3.5860e+00, 3.3695e+00, 3.1703e+00, 2.9870e+00, 2.8181e+00, 2.6623e+00, 2.5186e+00, 2.3858e+00, 2.2629e+00, 2.1491e+00, 2.0435e+00, 1.9453e+00, 1.8540e+00, 1.7688e+00, 1.6892e+00, 1.6147e+00, 1.5449e+00, 1.4794e+00, 1.4177e+00, 1.3597e+00, 1.3049e+00, 1.2532e+00, 1.2043e+00, 1.1581e+00, 1.1142e+00, 1.0726e+00, 1.0331e+00, 9.9560e-01, 9.5990e-01, 9.2590e-01, 8.9350e-01, 8.6270e-01, 8.3340e-01, 8.0530e-01, 7.7860e-01, 7.5310e-01, 7.2870e-01, 7.0550e-01, 6.8320e-01, 6.6200e-01, 6.4160e-01, 6.2220e-01, 6.0360e-01, 5.8580e-01, 5.6870e-01, 5.5240e-01, 5.3670e-01, 5.2170e-01, 5.0730e-01, 4.9350e-01, 4.8030e-01, 4.6760e-01, 4.5540e-01, 4.4370e-01, 4.3240e-01, 4.2160e-01, 4.1120e-01, 4.0120e-01, 3.9150e-01, 3.8220e-01, 3.7330e-01, 3.6470e-01, 3.5640e-01, 3.4840e-01, 3.4070e-01, 3.3320e-01, 3.2600e-01, 3.1910e-01, 3.1240e-01, 3.0590e-01, 2.9960e-01, 2.9350e-01, 2.8760e-01, 2.8190e-01, 2.7640e-01, 2.7100e-01, 2.6580e-01, 2.6080e-01, 2.5590e-01, 2.5110e-01, 2.4650e-01, 2.4200e-01, 2.3770e-01, 2.3340e-01, 2.2930e-01, 2.2530e-01, 2.2140e-01, 2.1760e-01, 2.1390e-01, 2.1030e-01, 2.0670e-01, 2.0330e-01, 2.0000e-01, 1.9670e-01, 1.9350e-01, 1.9040e-01, 1.8740e-01, 1.8440e-01, 1.8150e-01, 1.7870e-01, 1.7590e-01, 1.7320e-01, 1.7060e-01, 1.6800e-01, 1.6540e-01, 1.6300e-01, 1.6050e-01, 1.5820e-01, 1.5580e-01, 1.5360e-01, 1.5140e-01, 1.4920e-01, 1.4700e-01, 1.4500e-01, 1.4290e-01, 1.4090e-01, 1.3890e-01, 1.3700e-01, 1.3510e-01, 1.3330e-01, 1.3140e-01, 1.2970e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2290e-01, 1.2130e-01, 1.1970e-01, 1.1810e-01, 1.1660e-01, 1.1510e-01, 1.1360e-01, 1.1220e-01, 1.1070e-01, 1.0930e-01, 1.0800e-01, 1.0660e-01, 1.0530e-01, 1.0400e-01, 1.0270e-01, 1.0150e-01, 1.0020e-01, 9.9000e-02, 9.7900e-02, 9.6700e-02, 9.5500e-02, 9.4400e-02, 9.3300e-02, 9.2200e-02, 9.1100e-02, 9.0100e-02, 8.9100e-02, 8.8000e-02, 8.7000e-02, 8.6100e-02, 8.5100e-02, 8.4100e-02, 8.3200e-02, 8.2300e-02, 8.1400e-02, 8.0500e-02, 7.9600e-02, 7.8800e-02, 7.7900e-02, 7.7100e-02, 7.6200e-02, 7.5400e-02, 7.4600e-02, 7.3900e-02, 7.3100e-02, 7.2300e-02, 7.1600e-02, 7.0800e-02, 7.0100e-02, 6.9400e-02, 6.8700e-02, 6.8000e-02, 6.7300e-02, 6.6700e-02, 6.6000e-02, 6.5300e-02, 6.4700e-02, 6.4100e-02, 6.3500e-02, 6.2800e-02, 6.2200e-02, 6.1600e-02, 6.1100e-02, 6.0500e-02, 5.9900e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4600e-02, 5.4100e-02, 5.3700e-02, 5.3200e-02, 5.2700e-02, 5.2200e-02, 5.1800e-02, 5.1300e-02, 5.0900e-02, 5.0500e-02, 5.0000e-02, 4.9600e-02, 4.9200e-02, 4.8800e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6800e-02, 4.6400e-02, 4.6000e-02, 4.5600e-02, 4.5200e-02, 4.4900e-02, 4.4500e-02, 4.4200e-02}); + } + break; + case 71: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.1000e+01, 7.0660e+01, 6.9718e+01, 6.8363e+01, 6.6794e+01, 6.5146e+01, 6.3476e+01, 6.1794e+01, 6.0099e+01, 5.8392e+01, 5.6680e+01, 5.4972e+01, 5.3280e+01, 5.1618e+01, 4.9997e+01, 4.8424e+01, 4.6904e+01, 4.5442e+01, 4.4037e+01, 4.2689e+01, 4.1396e+01, 4.0157e+01, 3.8968e+01, 3.7828e+01, 3.6731e+01, 3.5678e+01, 3.4664e+01, 3.3689e+01, 3.2750e+01, 3.1846e+01, 3.0976e+01, 3.0139e+01, 2.9332e+01, 2.8557e+01, 2.7813e+01, 2.7098e+01, 2.6412e+01, 2.5755e+01, 2.5126e+01, 2.4524e+01, 2.3949e+01, 2.3400e+01, 2.2876e+01, 2.2377e+01, 2.1901e+01, 2.1449e+01, 2.1018e+01, 2.0608e+01, 2.0219e+01, 1.9849e+01, 1.9496e+01, 1.9161e+01, 1.8842e+01, 1.8538e+01, 1.8249e+01, 1.7972e+01, 1.7709e+01, 1.7456e+01, 1.7214e+01, 1.6982e+01, 1.6758e+01, 1.6543e+01, 1.6335e+01, 1.6134e+01, 1.5939e+01, 1.5749e+01, 1.5565e+01, 1.5384e+01, 1.5208e+01, 1.5036e+01, 1.4866e+01, 1.4699e+01, 1.4534e+01, 1.4372e+01, 1.4211e+01, 1.4052e+01, 1.3894e+01, 1.3738e+01, 1.3583e+01, 1.3429e+01, 1.3275e+01, 1.3123e+01, 1.2971e+01, 1.2820e+01, 1.2669e+01, 1.2519e+01, 1.2370e+01, 1.2222e+01, 1.2074e+01, 1.1926e+01, 1.1780e+01, 1.1634e+01, 1.1490e+01, 1.1346e+01, 1.1203e+01, 1.1061e+01, 1.0920e+01, 1.0781e+01, 1.0642e+01, 1.0505e+01, 1.0369e+01, 1.0235e+01, 1.0101e+01, 9.9698e+00, 9.8399e+00, 9.7117e+00, 9.5849e+00, 9.4598e+00, 9.3364e+00, 9.2150e+00, 9.0956e+00, 8.9781e+00, 8.8623e+00, 8.7483e+00, 8.6360e+00, 8.5259e+00, 8.4182e+00, 8.3127e+00, 8.2090e+00, 8.1069e+00, 8.0066e+00, 7.9084e+00, 7.8127e+00, 7.7194e+00, 7.6281e+00, 7.5385e+00, 7.4504e+00, 7.3641e+00, 7.2799e+00, 7.1982e+00, 7.1189e+00, 7.0415e+00, 6.9655e+00, 6.8909e+00, 6.8178e+00, 6.7466e+00, 6.6777e+00, 6.6111e+00, 6.5465e+00, 6.4832e+00, 6.4209e+00, 6.3597e+00, 6.3000e+00, 6.2422e+00, 6.1865e+00, 6.1327e+00, 6.0805e+00, 6.0293e+00, 5.9788e+00, 5.9289e+00, 5.8803e+00, 5.8334e+00, 5.7882e+00, 5.7448e+00, 5.7027e+00, 5.6615e+00, 5.6207e+00, 5.5801e+00, 5.5402e+00, 5.5015e+00, 5.4644e+00, 5.4287e+00, 5.3942e+00, 5.3608e+00, 5.3278e+00, 5.2948e+00, 5.2617e+00, 5.2291e+00, 5.1976e+00, 5.1673e+00, 5.1382e+00, 5.1099e+00, 5.0825e+00, 5.0556e+00, 5.0284e+00, 5.0008e+00, 4.9731e+00, 4.9462e+00, 4.9204e+00, 4.8954e+00, 4.8711e+00, 4.8475e+00, 4.8246e+00, 4.8017e+00, 4.7783e+00, 4.7542e+00, 4.7301e+00, 4.7066e+00, 4.6840e+00, 4.6620e+00, 4.6406e+00, 4.6195e+00, 4.5991e+00, 4.5788e+00, 4.5581e+00, 4.5365e+00, 4.5143e+00, 4.4923e+00, 4.4712e+00, 4.4508e+00, 4.4308e+00, 4.4109e+00, 4.3914e+00, 4.3724e+00, 4.3536e+00, 4.3341e+00, 4.3136e+00, 4.2925e+00, 4.2715e+00, 4.2512e+00, 4.2317e+00, 4.2125e+00, 4.1933e+00, 4.1743e+00, 4.1557e+00, 4.1376e+00, 4.1192e+00, 4.1000e+00, 4.0796e+00, 4.0588e+00, 4.0384e+00, 4.0188e+00, 3.9999e+00, 3.9811e+00, 3.9623e+00, 3.9435e+00, 3.9251e+00, 3.9073e+00, 3.8894e+00, 3.8708e+00, 3.8509e+00, 3.8303e+00, 3.8098e+00, 3.7903e+00, 3.7715e+00, 3.7531e+00, 3.7346e+00, 3.7159e+00, 3.6974e+00, 3.6794e+00, 3.6619e+00}); + feg = Vctr_cpu({1.3293e+01, 1.3021e+01, 1.2273e+01, 1.1221e+01, 1.0066e+01, 8.9665e+00, 8.0036e+00, 7.1948e+00, 6.5227e+00, 5.9605e+00, 5.4836e+00, 5.0726e+00, 4.7123e+00, 4.3917e+00, 4.1035e+00, 3.8423e+00, 3.6044e+00, 3.3866e+00, 3.1868e+00, 3.0031e+00, 2.8341e+00, 2.6782e+00, 2.5343e+00, 2.4013e+00, 2.2783e+00, 2.1642e+00, 2.0583e+00, 1.9599e+00, 1.8683e+00, 1.7828e+00, 1.7030e+00, 1.6282e+00, 1.5582e+00, 1.4925e+00, 1.4306e+00, 1.3724e+00, 1.3175e+00, 1.2656e+00, 1.2166e+00, 1.1701e+00, 1.1261e+00, 1.0844e+00, 1.0447e+00, 1.0070e+00, 9.7120e-01, 9.3700e-01, 9.0450e-01, 8.7360e-01, 8.4400e-01, 8.1580e-01, 7.8890e-01, 7.6320e-01, 7.3870e-01, 7.1520e-01, 6.9270e-01, 6.7130e-01, 6.5070e-01, 6.3110e-01, 6.1230e-01, 5.9420e-01, 5.7700e-01, 5.6040e-01, 5.4460e-01, 5.2940e-01, 5.1480e-01, 5.0080e-01, 4.8730e-01, 4.7440e-01, 4.6200e-01, 4.5010e-01, 4.3870e-01, 4.2770e-01, 4.1710e-01, 4.0690e-01, 3.9710e-01, 3.8770e-01, 3.7860e-01, 3.6980e-01, 3.6140e-01, 3.5320e-01, 3.4540e-01, 3.3780e-01, 3.3050e-01, 3.2340e-01, 3.1660e-01, 3.1000e-01, 3.0360e-01, 2.9740e-01, 2.9140e-01, 2.8560e-01, 2.8000e-01, 2.7450e-01, 2.6920e-01, 2.6410e-01, 2.5920e-01, 2.5430e-01, 2.4960e-01, 2.4510e-01, 2.4070e-01, 2.3640e-01, 2.3220e-01, 2.2810e-01, 2.2410e-01, 2.2030e-01, 2.1650e-01, 2.1290e-01, 2.0930e-01, 2.0580e-01, 2.0240e-01, 1.9910e-01, 1.9590e-01, 1.9280e-01, 1.8970e-01, 1.8670e-01, 1.8380e-01, 1.8090e-01, 1.7810e-01, 1.7540e-01, 1.7270e-01, 1.7010e-01, 1.6750e-01, 1.6500e-01, 1.6260e-01, 1.6020e-01, 1.5780e-01, 1.5550e-01, 1.5330e-01, 1.5110e-01, 1.4890e-01, 1.4680e-01, 1.4470e-01, 1.4270e-01, 1.4070e-01, 1.3880e-01, 1.3690e-01, 1.3500e-01, 1.3320e-01, 1.3140e-01, 1.2960e-01, 1.2790e-01, 1.2620e-01, 1.2450e-01, 1.2290e-01, 1.2130e-01, 1.1970e-01, 1.1810e-01, 1.1660e-01, 1.1510e-01, 1.1370e-01, 1.1220e-01, 1.1080e-01, 1.0940e-01, 1.0810e-01, 1.0670e-01, 1.0540e-01, 1.0410e-01, 1.0290e-01, 1.0160e-01, 1.0040e-01, 9.9200e-02, 9.8000e-02, 9.6900e-02, 9.5700e-02, 9.4600e-02, 9.3500e-02, 9.2400e-02, 9.1400e-02, 9.0300e-02, 8.9300e-02, 8.8300e-02, 8.7300e-02, 8.6300e-02, 8.5300e-02, 8.4400e-02, 8.3400e-02, 8.2500e-02, 8.1600e-02, 8.0700e-02, 7.9900e-02, 7.9000e-02, 7.8200e-02, 7.7300e-02, 7.6500e-02, 7.5700e-02, 7.4900e-02, 7.4100e-02, 7.3400e-02, 7.2600e-02, 7.1900e-02, 7.1100e-02, 7.0400e-02, 6.9700e-02, 6.9000e-02, 6.8300e-02, 6.7600e-02, 6.6900e-02, 6.6300e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3700e-02, 6.3100e-02, 6.2500e-02, 6.1900e-02, 6.1300e-02, 6.0700e-02, 6.0200e-02, 5.9600e-02, 5.9100e-02, 5.8500e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4400e-02, 5.3900e-02, 5.3400e-02, 5.3000e-02, 5.2500e-02, 5.2100e-02, 5.1600e-02, 5.1200e-02, 5.0700e-02, 5.0300e-02, 4.9900e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02, 4.6200e-02, 4.5900e-02, 4.5500e-02, 4.5100e-02, 4.4800e-02}); + } + break; + case 72: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.2000e+01, 7.1666e+01, 7.0733e+01, 6.9371e+01, 6.7770e+01, 6.6067e+01, 6.4335e+01, 6.2602e+01, 6.0874e+01, 5.9152e+01, 5.7437e+01, 5.5735e+01, 5.4056e+01, 5.2407e+01, 5.0797e+01, 4.9231e+01, 4.7717e+01, 4.6255e+01, 4.4848e+01, 4.3495e+01, 4.2196e+01, 4.0948e+01, 3.9750e+01, 3.8598e+01, 3.7491e+01, 3.6426e+01, 3.5401e+01, 3.4414e+01, 3.3462e+01, 3.2545e+01, 3.1662e+01, 3.0810e+01, 2.9990e+01, 2.9200e+01, 2.8440e+01, 2.7709e+01, 2.7006e+01, 2.6332e+01, 2.5685e+01, 2.5065e+01, 2.4472e+01, 2.3905e+01, 2.3362e+01, 2.2845e+01, 2.2351e+01, 2.1880e+01, 2.1431e+01, 2.1004e+01, 2.0598e+01, 2.0211e+01, 1.9842e+01, 1.9492e+01, 1.9159e+01, 1.8841e+01, 1.8538e+01, 1.8250e+01, 1.7974e+01, 1.7711e+01, 1.7460e+01, 1.7219e+01, 1.6987e+01, 1.6765e+01, 1.6551e+01, 1.6345e+01, 1.6145e+01, 1.5951e+01, 1.5764e+01, 1.5581e+01, 1.5402e+01, 1.5228e+01, 1.5058e+01, 1.4891e+01, 1.4726e+01, 1.4564e+01, 1.4405e+01, 1.4247e+01, 1.4091e+01, 1.3936e+01, 1.3783e+01, 1.3631e+01, 1.3480e+01, 1.3330e+01, 1.3181e+01, 1.3032e+01, 1.2885e+01, 1.2737e+01, 1.2591e+01, 1.2445e+01, 1.2300e+01, 1.2155e+01, 1.2011e+01, 1.1867e+01, 1.1725e+01, 1.1583e+01, 1.1442e+01, 1.1302e+01, 1.1162e+01, 1.1024e+01, 1.0886e+01, 1.0750e+01, 1.0615e+01, 1.0481e+01, 1.0348e+01, 1.0216e+01, 1.0086e+01, 9.9578e+00, 9.8310e+00, 9.7053e+00, 9.5810e+00, 9.4582e+00, 9.3374e+00, 9.2187e+00, 9.1017e+00, 8.9863e+00, 8.8722e+00, 8.7598e+00, 8.6496e+00, 8.5418e+00, 8.4361e+00, 8.3321e+00, 8.2295e+00, 8.1284e+00, 8.0294e+00, 7.9329e+00, 7.8388e+00, 7.7468e+00, 7.6562e+00, 7.5671e+00, 7.4795e+00, 7.3940e+00, 7.3110e+00, 7.2304e+00, 7.1518e+00, 7.0747e+00, 6.9987e+00, 6.9241e+00, 6.8513e+00, 6.7807e+00, 6.7125e+00, 6.6464e+00, 6.5819e+00, 6.5183e+00, 6.4557e+00, 6.3943e+00, 6.3346e+00, 6.2770e+00, 6.2216e+00, 6.1680e+00, 6.1157e+00, 6.0640e+00, 6.0129e+00, 5.9627e+00, 5.9140e+00, 5.8669e+00, 5.8218e+00, 5.7784e+00, 5.7363e+00, 5.6947e+00, 5.6532e+00, 5.6122e+00, 5.5720e+00, 5.5331e+00, 5.4958e+00, 5.4600e+00, 5.4256e+00, 5.3921e+00, 5.3587e+00, 5.3252e+00, 5.2918e+00, 5.2590e+00, 5.2272e+00, 5.1966e+00, 5.1673e+00, 5.1392e+00, 5.1120e+00, 5.0849e+00, 5.0574e+00, 5.0295e+00, 5.0019e+00, 4.9749e+00, 4.9486e+00, 4.9233e+00, 4.8990e+00, 4.8758e+00, 4.8531e+00, 4.8303e+00, 4.8068e+00, 4.7829e+00, 4.7589e+00, 4.7353e+00, 4.7124e+00, 4.6901e+00, 4.6685e+00, 4.6478e+00, 4.6279e+00, 4.6080e+00, 4.5875e+00, 4.5662e+00, 4.5444e+00, 4.5227e+00, 4.5014e+00, 4.4807e+00, 4.4603e+00, 4.4405e+00, 4.4214e+00, 4.4031e+00, 4.3849e+00, 4.3659e+00, 4.3460e+00, 4.3253e+00, 4.3047e+00, 4.2845e+00, 4.2646e+00, 4.2450e+00, 4.2257e+00, 4.2070e+00, 4.1891e+00, 4.1717e+00, 4.1541e+00, 4.1356e+00, 4.1159e+00, 4.0957e+00, 4.0757e+00, 4.0560e+00, 4.0367e+00, 4.0176e+00, 3.9986e+00, 3.9800e+00, 3.9622e+00, 3.9451e+00, 3.9281e+00, 3.9103e+00, 3.8914e+00, 3.8716e+00, 3.8516e+00, 3.8320e+00, 3.8129e+00, 3.7941e+00, 3.7752e+00, 3.7564e+00, 3.7380e+00}); + feg = Vctr_cpu({1.3045e+01, 1.2803e+01, 1.2134e+01, 1.1185e+01, 1.0124e+01, 9.0886e+00, 8.1535e+00, 7.3446e+00, 6.6571e+00, 6.0742e+00, 5.5768e+00, 5.1474e+00, 4.7719e+00, 4.4396e+00, 4.1427e+00, 3.8751e+00, 3.6324e+00, 3.4113e+00, 3.2091e+00, 3.0237e+00, 2.8533e+00, 2.6963e+00, 2.5516e+00, 2.4179e+00, 2.2942e+00, 2.1796e+00, 2.0732e+00, 1.9744e+00, 1.8823e+00, 1.7965e+00, 1.7163e+00, 1.6413e+00, 1.5710e+00, 1.5050e+00, 1.4430e+00, 1.3846e+00, 1.3295e+00, 1.2774e+00, 1.2282e+00, 1.1817e+00, 1.1375e+00, 1.0956e+00, 1.0559e+00, 1.0180e+00, 9.8210e-01, 9.4780e-01, 9.1520e-01, 8.8400e-01, 8.5430e-01, 8.2600e-01, 7.9890e-01, 7.7310e-01, 7.4830e-01, 7.2470e-01, 7.0210e-01, 6.8040e-01, 6.5970e-01, 6.3990e-01, 6.2090e-01, 6.0260e-01, 5.8520e-01, 5.6840e-01, 5.5240e-01, 5.3700e-01, 5.2220e-01, 5.0800e-01, 4.9440e-01, 4.8130e-01, 4.6870e-01, 4.5660e-01, 4.4500e-01, 4.3380e-01, 4.2310e-01, 4.1270e-01, 4.0280e-01, 3.9320e-01, 3.8390e-01, 3.7500e-01, 3.6640e-01, 3.5810e-01, 3.5010e-01, 3.4240e-01, 3.3500e-01, 3.2780e-01, 3.2080e-01, 3.1410e-01, 3.0760e-01, 3.0130e-01, 2.9520e-01, 2.8930e-01, 2.8360e-01, 2.7810e-01, 2.7270e-01, 2.6750e-01, 2.6250e-01, 2.5750e-01, 2.5280e-01, 2.4820e-01, 2.4370e-01, 2.3930e-01, 2.3510e-01, 2.3090e-01, 2.2690e-01, 2.2300e-01, 2.1920e-01, 2.1550e-01, 2.1190e-01, 2.0840e-01, 2.0490e-01, 2.0160e-01, 1.9830e-01, 1.9510e-01, 1.9200e-01, 1.8900e-01, 1.8600e-01, 1.8310e-01, 1.8030e-01, 1.7750e-01, 1.7480e-01, 1.7220e-01, 1.6960e-01, 1.6710e-01, 1.6460e-01, 1.6220e-01, 1.5980e-01, 1.5750e-01, 1.5520e-01, 1.5300e-01, 1.5080e-01, 1.4870e-01, 1.4660e-01, 1.4450e-01, 1.4250e-01, 1.4060e-01, 1.3860e-01, 1.3670e-01, 1.3490e-01, 1.3310e-01, 1.3130e-01, 1.2950e-01, 1.2780e-01, 1.2610e-01, 1.2450e-01, 1.2290e-01, 1.2130e-01, 1.1970e-01, 1.1820e-01, 1.1670e-01, 1.1520e-01, 1.1370e-01, 1.1230e-01, 1.1090e-01, 1.0950e-01, 1.0820e-01, 1.0690e-01, 1.0560e-01, 1.0430e-01, 1.0300e-01, 1.0180e-01, 1.0060e-01, 9.9400e-02, 9.8200e-02, 9.7000e-02, 9.5900e-02, 9.4800e-02, 9.3700e-02, 9.2600e-02, 9.1500e-02, 9.0500e-02, 8.9500e-02, 8.8500e-02, 8.7500e-02, 8.6500e-02, 8.5500e-02, 8.4600e-02, 8.3700e-02, 8.2800e-02, 8.1900e-02, 8.1000e-02, 8.0100e-02, 7.9200e-02, 7.8400e-02, 7.7600e-02, 7.6800e-02, 7.5900e-02, 7.5200e-02, 7.4400e-02, 7.3600e-02, 7.2900e-02, 7.2100e-02, 7.1400e-02, 7.0700e-02, 6.9900e-02, 6.9200e-02, 6.8500e-02, 6.7900e-02, 6.7200e-02, 6.6500e-02, 6.5900e-02, 6.5300e-02, 6.4600e-02, 6.4000e-02, 6.3400e-02, 6.2800e-02, 6.2200e-02, 6.1600e-02, 6.1000e-02, 6.0400e-02, 5.9900e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3700e-02, 5.3200e-02, 5.2800e-02, 5.2300e-02, 5.1900e-02, 5.1400e-02, 5.1000e-02, 5.0500e-02, 5.0100e-02, 4.9700e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02, 4.8100e-02, 4.7700e-02, 4.7300e-02, 4.6900e-02, 4.6500e-02, 4.6100e-02, 4.5800e-02, 4.5400e-02}); + } + break; + case 73: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.3000e+01, 7.2673e+01, 7.1751e+01, 7.0386e+01, 6.8755e+01, 6.7002e+01, 6.5213e+01, 6.3427e+01, 6.1656e+01, 5.9905e+01, 5.8175e+01, 5.6470e+01, 5.4793e+01, 5.3150e+01, 5.1548e+01, 4.9991e+01, 4.8483e+01, 4.7025e+01, 4.5620e+01, 4.4267e+01, 4.2966e+01, 4.1715e+01, 4.0511e+01, 3.9353e+01, 3.8239e+01, 3.7166e+01, 3.6132e+01, 3.5136e+01, 3.4175e+01, 3.3247e+01, 3.2352e+01, 3.1489e+01, 3.0656e+01, 2.9853e+01, 2.9079e+01, 2.8333e+01, 2.7615e+01, 2.6925e+01, 2.6262e+01, 2.5625e+01, 2.5014e+01, 2.4429e+01, 2.3869e+01, 2.3333e+01, 2.2821e+01, 2.2332e+01, 2.1866e+01, 2.1421e+01, 2.0997e+01, 2.0593e+01, 2.0208e+01, 1.9842e+01, 1.9493e+01, 1.9161e+01, 1.8845e+01, 1.8543e+01, 1.8255e+01, 1.7981e+01, 1.7718e+01, 1.7467e+01, 1.7227e+01, 1.6997e+01, 1.6775e+01, 1.6562e+01, 1.6357e+01, 1.6158e+01, 1.5966e+01, 1.5779e+01, 1.5598e+01, 1.5422e+01, 1.5249e+01, 1.5081e+01, 1.4916e+01, 1.4754e+01, 1.4595e+01, 1.4437e+01, 1.4282e+01, 1.4129e+01, 1.3977e+01, 1.3827e+01, 1.3678e+01, 1.3530e+01, 1.3383e+01, 1.3238e+01, 1.3092e+01, 1.2947e+01, 1.2803e+01, 1.2660e+01, 1.2518e+01, 1.2375e+01, 1.2233e+01, 1.2092e+01, 1.1952e+01, 1.1813e+01, 1.1673e+01, 1.1535e+01, 1.1397e+01, 1.1261e+01, 1.1125e+01, 1.0989e+01, 1.0855e+01, 1.0722e+01, 1.0590e+01, 1.0459e+01, 1.0330e+01, 1.0201e+01, 1.0074e+01, 9.9480e+00, 9.8234e+00, 9.7004e+00, 9.5790e+00, 9.4591e+00, 9.3407e+00, 9.2238e+00, 9.1085e+00, 8.9950e+00, 8.8834e+00, 8.7736e+00, 8.6655e+00, 8.5590e+00, 8.4542e+00, 8.3512e+00, 8.2503e+00, 8.1515e+00, 8.0546e+00, 7.9593e+00, 7.8656e+00, 7.7735e+00, 7.6836e+00, 7.5958e+00, 7.5101e+00, 7.4263e+00, 7.3441e+00, 7.2632e+00, 7.1839e+00, 7.1065e+00, 7.0313e+00, 6.9583e+00, 6.8871e+00, 6.8174e+00, 6.7488e+00, 6.6815e+00, 6.6157e+00, 6.5519e+00, 6.4900e+00, 6.4302e+00, 6.3719e+00, 6.3148e+00, 6.2585e+00, 6.2031e+00, 6.1490e+00, 6.0967e+00, 6.0463e+00, 5.9976e+00, 5.9503e+00, 5.9039e+00, 5.8581e+00, 5.8128e+00, 5.7684e+00, 5.7253e+00, 5.6839e+00, 5.6440e+00, 5.6055e+00, 5.5680e+00, 5.5309e+00, 5.4941e+00, 5.4575e+00, 5.4215e+00, 5.3866e+00, 5.3532e+00, 5.3212e+00, 5.2902e+00, 5.2599e+00, 5.2300e+00, 5.2001e+00, 5.1700e+00, 5.1401e+00, 5.1109e+00, 5.0829e+00, 5.0561e+00, 5.0303e+00, 5.0051e+00, 4.9804e+00, 4.9557e+00, 4.9306e+00, 4.9052e+00, 4.8798e+00, 4.8550e+00, 4.8312e+00, 4.8085e+00, 4.7865e+00, 4.7649e+00, 4.7437e+00, 4.7226e+00, 4.7010e+00, 4.6787e+00, 4.6561e+00, 4.6337e+00, 4.6121e+00, 4.5914e+00, 4.5714e+00, 4.5519e+00, 4.5327e+00, 4.5137e+00, 4.4945e+00, 4.4748e+00, 4.4543e+00, 4.4333e+00, 4.4123e+00, 4.3921e+00, 4.3728e+00, 4.3541e+00, 4.3358e+00, 4.3176e+00, 4.2997e+00, 4.2817e+00, 4.2634e+00, 4.2443e+00, 4.2243e+00, 4.2039e+00, 4.1838e+00, 4.1646e+00, 4.1462e+00, 4.1283e+00, 4.1105e+00, 4.0929e+00, 4.0754e+00, 4.0579e+00, 4.0402e+00, 4.0218e+00, 4.0023e+00, 3.9822e+00, 3.9622e+00, 3.9430e+00, 3.9246e+00, 3.9069e+00, 3.8895e+00, 3.8720e+00, 3.8545e+00, 3.8373e+00, 3.8202e+00}); + feg = Vctr_cpu({1.2738e+01, 1.2532e+01, 1.1958e+01, 1.1122e+01, 1.0159e+01, 9.1870e+00, 8.2829e+00, 7.4816e+00, 6.7877e+00, 6.1909e+00, 5.6769e+00, 5.2314e+00, 4.8418e+00, 4.4977e+00, 4.1912e+00, 3.9160e+00, 3.6674e+00, 3.4418e+00, 3.2361e+00, 3.0479e+00, 2.8753e+00, 2.7166e+00, 2.5705e+00, 2.4357e+00, 2.3110e+00, 2.1955e+00, 2.0885e+00, 1.9890e+00, 1.8964e+00, 1.8101e+00, 1.7295e+00, 1.6541e+00, 1.5835e+00, 1.5172e+00, 1.4549e+00, 1.3963e+00, 1.3410e+00, 1.2888e+00, 1.2395e+00, 1.1927e+00, 1.1485e+00, 1.1065e+00, 1.0666e+00, 1.0286e+00, 9.9250e-01, 9.5820e-01, 9.2540e-01, 8.9410e-01, 8.6430e-01, 8.3580e-01, 8.0860e-01, 7.8260e-01, 7.5780e-01, 7.3400e-01, 7.1120e-01, 6.8940e-01, 6.6850e-01, 6.4850e-01, 6.2930e-01, 6.1090e-01, 5.9330e-01, 5.7630e-01, 5.6010e-01, 5.4450e-01, 5.2960e-01, 5.1520e-01, 5.0140e-01, 4.8810e-01, 4.7540e-01, 4.6310e-01, 4.5130e-01, 4.4000e-01, 4.2910e-01, 4.1860e-01, 4.0840e-01, 3.9870e-01, 3.8930e-01, 3.8020e-01, 3.7150e-01, 3.6310e-01, 3.5490e-01, 3.4710e-01, 3.3950e-01, 3.3220e-01, 3.2510e-01, 3.1830e-01, 3.1170e-01, 3.0530e-01, 2.9910e-01, 2.9310e-01, 2.8730e-01, 2.8170e-01, 2.7620e-01, 2.7090e-01, 2.6580e-01, 2.6080e-01, 2.5600e-01, 2.5130e-01, 2.4670e-01, 2.4230e-01, 2.3800e-01, 2.3380e-01, 2.2970e-01, 2.2570e-01, 2.2190e-01, 2.1810e-01, 2.1450e-01, 2.1090e-01, 2.0740e-01, 2.0400e-01, 2.0070e-01, 1.9750e-01, 1.9430e-01, 1.9130e-01, 1.8830e-01, 1.8530e-01, 1.8250e-01, 1.7970e-01, 1.7690e-01, 1.7430e-01, 1.7160e-01, 1.6910e-01, 1.6660e-01, 1.6410e-01, 1.6170e-01, 1.5940e-01, 1.5710e-01, 1.5490e-01, 1.5270e-01, 1.5050e-01, 1.4840e-01, 1.4630e-01, 1.4430e-01, 1.4230e-01, 1.4040e-01, 1.3850e-01, 1.3660e-01, 1.3470e-01, 1.3290e-01, 1.3120e-01, 1.2940e-01, 1.2770e-01, 1.2610e-01, 1.2440e-01, 1.2280e-01, 1.2120e-01, 1.1970e-01, 1.1820e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1100e-01, 1.0960e-01, 1.0830e-01, 1.0690e-01, 1.0570e-01, 1.0440e-01, 1.0310e-01, 1.0190e-01, 1.0070e-01, 9.9500e-02, 9.8300e-02, 9.7200e-02, 9.6100e-02, 9.5000e-02, 9.3900e-02, 9.2800e-02, 9.1700e-02, 9.0700e-02, 8.9700e-02, 8.8700e-02, 8.7700e-02, 8.6700e-02, 8.5800e-02, 8.4800e-02, 8.3900e-02, 8.3000e-02, 8.2100e-02, 8.1200e-02, 8.0300e-02, 7.9500e-02, 7.8600e-02, 7.7800e-02, 7.7000e-02, 7.6200e-02, 7.5400e-02, 7.4600e-02, 7.3900e-02, 7.3100e-02, 7.2400e-02, 7.1600e-02, 7.0900e-02, 7.0200e-02, 6.9500e-02, 6.8800e-02, 6.8100e-02, 6.7500e-02, 6.6800e-02, 6.6200e-02, 6.5500e-02, 6.4900e-02, 6.4300e-02, 6.3600e-02, 6.3000e-02, 6.2400e-02, 6.1900e-02, 6.1300e-02, 6.0700e-02, 6.0100e-02, 5.9600e-02, 5.9000e-02, 5.8500e-02, 5.8000e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4400e-02, 5.4000e-02, 5.3500e-02, 5.3000e-02, 5.2600e-02, 5.2100e-02, 5.1700e-02, 5.1200e-02, 5.0800e-02, 5.0400e-02, 4.9900e-02, 4.9500e-02, 4.9100e-02, 4.8700e-02, 4.8300e-02, 4.7900e-02, 4.7500e-02, 4.7100e-02, 4.6700e-02, 4.6400e-02, 4.6000e-02}); + } + break; + case 74: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.4000e+01, 7.3679e+01, 7.2769e+01, 7.1409e+01, 6.9765e+01, 6.7977e+01, 6.6139e+01, 6.4300e+01, 6.2481e+01, 6.0691e+01, 5.8932e+01, 5.7208e+01, 5.5520e+01, 5.3873e+01, 5.2271e+01, 5.0716e+01, 4.9210e+01, 4.7755e+01, 4.6353e+01, 4.5002e+01, 4.3701e+01, 4.2449e+01, 4.1244e+01, 4.0084e+01, 3.8966e+01, 3.7889e+01, 3.6850e+01, 3.5847e+01, 3.4879e+01, 3.3944e+01, 3.3041e+01, 3.2168e+01, 3.1325e+01, 3.0511e+01, 2.9725e+01, 2.8966e+01, 2.8235e+01, 2.7531e+01, 2.6852e+01, 2.6200e+01, 2.5573e+01, 2.4971e+01, 2.4393e+01, 2.3840e+01, 2.3310e+01, 2.2804e+01, 2.2320e+01, 2.1857e+01, 2.1416e+01, 2.0994e+01, 2.0593e+01, 2.0210e+01, 1.9846e+01, 1.9498e+01, 1.9167e+01, 1.8852e+01, 1.8551e+01, 1.8264e+01, 1.7990e+01, 1.7728e+01, 1.7478e+01, 1.7238e+01, 1.7008e+01, 1.6787e+01, 1.6575e+01, 1.6370e+01, 1.6172e+01, 1.5981e+01, 1.5796e+01, 1.5617e+01, 1.5441e+01, 1.5271e+01, 1.5104e+01, 1.4941e+01, 1.4781e+01, 1.4624e+01, 1.4469e+01, 1.4317e+01, 1.4166e+01, 1.4018e+01, 1.3870e+01, 1.3724e+01, 1.3579e+01, 1.3435e+01, 1.3292e+01, 1.3150e+01, 1.3008e+01, 1.2868e+01, 1.2728e+01, 1.2588e+01, 1.2449e+01, 1.2310e+01, 1.2172e+01, 1.2035e+01, 1.1898e+01, 1.1762e+01, 1.1626e+01, 1.1491e+01, 1.1357e+01, 1.1223e+01, 1.1091e+01, 1.0959e+01, 1.0828e+01, 1.0698e+01, 1.0569e+01, 1.0441e+01, 1.0314e+01, 1.0188e+01, 1.0064e+01, 9.9406e+00, 9.8188e+00, 9.6984e+00, 9.5794e+00, 9.4616e+00, 9.3453e+00, 9.2307e+00, 9.1177e+00, 9.0065e+00, 8.8968e+00, 8.7886e+00, 8.6819e+00, 8.5769e+00, 8.4739e+00, 8.3729e+00, 8.2737e+00, 8.1760e+00, 8.0798e+00, 7.9853e+00, 7.8927e+00, 7.8022e+00, 7.7138e+00, 7.6271e+00, 7.5420e+00, 7.4582e+00, 7.3760e+00, 7.2957e+00, 7.2175e+00, 7.1414e+00, 7.0672e+00, 6.9943e+00, 6.9227e+00, 6.8524e+00, 6.7836e+00, 6.7168e+00, 6.6519e+00, 6.5891e+00, 6.5278e+00, 6.4676e+00, 6.4084e+00, 6.3502e+00, 6.2933e+00, 6.2382e+00, 6.1850e+00, 6.1336e+00, 6.0835e+00, 6.0345e+00, 5.9861e+00, 5.9383e+00, 5.8915e+00, 5.8460e+00, 5.8022e+00, 5.7600e+00, 5.7192e+00, 5.6794e+00, 5.6402e+00, 5.6013e+00, 5.5627e+00, 5.5248e+00, 5.4881e+00, 5.4528e+00, 5.4190e+00, 5.3863e+00, 5.3543e+00, 5.3228e+00, 5.2913e+00, 5.2598e+00, 5.2285e+00, 5.1980e+00, 5.1687e+00, 5.1407e+00, 5.1137e+00, 5.0874e+00, 5.0615e+00, 5.0358e+00, 5.0098e+00, 4.9835e+00, 4.9572e+00, 4.9316e+00, 4.9071e+00, 4.8836e+00, 4.8610e+00, 4.8389e+00, 4.8171e+00, 4.7953e+00, 4.7732e+00, 4.7505e+00, 4.7275e+00, 4.7047e+00, 4.6828e+00, 4.6617e+00, 4.6415e+00, 4.6219e+00, 4.6025e+00, 4.5833e+00, 4.5640e+00, 4.5441e+00, 4.5235e+00, 4.5025e+00, 4.4815e+00, 4.4612e+00, 4.4419e+00, 4.4232e+00, 4.4050e+00, 4.3870e+00, 4.3692e+00, 4.3514e+00, 4.3331e+00, 4.3141e+00, 4.2943e+00, 4.2741e+00, 4.2542e+00, 4.2351e+00, 4.2168e+00, 4.1991e+00, 4.1817e+00, 4.1644e+00, 4.1473e+00, 4.1301e+00, 4.1126e+00, 4.0943e+00, 4.0751e+00, 4.0553e+00, 4.0355e+00, 4.0165e+00, 3.9984e+00, 3.9809e+00, 3.9637e+00, 3.9467e+00, 3.9297e+00, 3.9129e+00, 3.8960e+00}); + feg = Vctr_cpu({1.2480e+01, 1.2296e+01, 1.1780e+01, 1.1022e+01, 1.0136e+01, 9.2256e+00, 8.3616e+00, 7.5806e+00, 6.8924e+00, 6.2923e+00, 5.7701e+00, 5.3144e+00, 4.9143e+00, 4.5605e+00, 4.2454e+00, 3.9629e+00, 3.7082e+00, 3.4775e+00, 3.2676e+00, 3.0760e+00, 2.9006e+00, 2.7397e+00, 2.5916e+00, 2.4552e+00, 2.3291e+00, 2.2125e+00, 2.1045e+00, 2.0041e+00, 1.9108e+00, 1.8239e+00, 1.7428e+00, 1.6669e+00, 1.5959e+00, 1.5293e+00, 1.4667e+00, 1.4078e+00, 1.3522e+00, 1.2998e+00, 1.2503e+00, 1.2035e+00, 1.1590e+00, 1.1169e+00, 1.0769e+00, 1.0388e+00, 1.0026e+00, 9.6820e-01, 9.3530e-01, 9.0390e-01, 8.7400e-01, 8.4540e-01, 8.1810e-01, 7.9190e-01, 7.6690e-01, 7.4300e-01, 7.2010e-01, 6.9810e-01, 6.7710e-01, 6.5690e-01, 6.3760e-01, 6.1900e-01, 6.0120e-01, 5.8420e-01, 5.6780e-01, 5.5200e-01, 5.3690e-01, 5.2230e-01, 5.0840e-01, 4.9490e-01, 4.8200e-01, 4.6960e-01, 4.5760e-01, 4.4610e-01, 4.3510e-01, 4.2440e-01, 4.1410e-01, 4.0420e-01, 3.9470e-01, 3.8550e-01, 3.7660e-01, 3.6800e-01, 3.5980e-01, 3.5180e-01, 3.4410e-01, 3.3670e-01, 3.2950e-01, 3.2250e-01, 3.1580e-01, 3.0930e-01, 3.0300e-01, 2.9690e-01, 2.9100e-01, 2.8530e-01, 2.7970e-01, 2.7440e-01, 2.6910e-01, 2.6410e-01, 2.5920e-01, 2.5440e-01, 2.4980e-01, 2.4530e-01, 2.4090e-01, 2.3670e-01, 2.3250e-01, 2.2850e-01, 2.2460e-01, 2.2080e-01, 2.1710e-01, 2.1340e-01, 2.0990e-01, 2.0650e-01, 2.0310e-01, 1.9990e-01, 1.9670e-01, 1.9350e-01, 1.9050e-01, 1.8750e-01, 1.8460e-01, 1.8180e-01, 1.7900e-01, 1.7630e-01, 1.7370e-01, 1.7110e-01, 1.6860e-01, 1.6610e-01, 1.6370e-01, 1.6130e-01, 1.5900e-01, 1.5670e-01, 1.5450e-01, 1.5230e-01, 1.5020e-01, 1.4810e-01, 1.4610e-01, 1.4410e-01, 1.4210e-01, 1.4020e-01, 1.3830e-01, 1.3640e-01, 1.3460e-01, 1.3280e-01, 1.3110e-01, 1.2930e-01, 1.2770e-01, 1.2600e-01, 1.2440e-01, 1.2280e-01, 1.2120e-01, 1.1970e-01, 1.1820e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1100e-01, 1.0970e-01, 1.0830e-01, 1.0700e-01, 1.0570e-01, 1.0450e-01, 1.0320e-01, 1.0200e-01, 1.0080e-01, 9.9600e-02, 9.8500e-02, 9.7300e-02, 9.6200e-02, 9.5100e-02, 9.4000e-02, 9.3000e-02, 9.1900e-02, 9.0900e-02, 8.9900e-02, 8.8900e-02, 8.7900e-02, 8.6900e-02, 8.6000e-02, 8.5000e-02, 8.4100e-02, 8.3200e-02, 8.2300e-02, 8.1400e-02, 8.0600e-02, 7.9700e-02, 7.8900e-02, 7.8000e-02, 7.7200e-02, 7.6400e-02, 7.5600e-02, 7.4900e-02, 7.4100e-02, 7.3300e-02, 7.2600e-02, 7.1900e-02, 7.1100e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8400e-02, 6.7700e-02, 6.7000e-02, 6.6400e-02, 6.5800e-02, 6.5100e-02, 6.4500e-02, 6.3900e-02, 6.3300e-02, 6.2700e-02, 6.2100e-02, 6.1500e-02, 6.1000e-02, 6.0400e-02, 5.9800e-02, 5.9300e-02, 5.8800e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2800e-02, 5.2400e-02, 5.1900e-02, 5.1500e-02, 5.1000e-02, 5.0600e-02, 5.0200e-02, 4.9800e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02, 4.7400e-02, 4.7000e-02, 4.6600e-02}); + } + break; + case 75: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.5000e+01, 7.4684e+01, 7.3787e+01, 7.2436e+01, 7.0786e+01, 6.8975e+01, 6.7098e+01, 6.5211e+01, 6.3343e+01, 6.1508e+01, 5.9712e+01, 5.7959e+01, 5.6250e+01, 5.4589e+01, 5.2978e+01, 5.1417e+01, 4.9910e+01, 4.8455e+01, 4.7053e+01, 4.5703e+01, 4.4404e+01, 4.3153e+01, 4.1948e+01, 4.0788e+01, 3.9670e+01, 3.8591e+01, 3.7550e+01, 3.6544e+01, 3.5572e+01, 3.4632e+01, 3.3723e+01, 3.2844e+01, 3.1993e+01, 3.1170e+01, 3.0374e+01, 2.9605e+01, 2.8863e+01, 2.8145e+01, 2.7454e+01, 2.6787e+01, 2.6145e+01, 2.5528e+01, 2.4934e+01, 2.4364e+01, 2.3818e+01, 2.3294e+01, 2.2792e+01, 2.2313e+01, 2.1854e+01, 2.1416e+01, 2.0997e+01, 2.0598e+01, 2.0217e+01, 1.9854e+01, 1.9508e+01, 1.9178e+01, 1.8863e+01, 1.8563e+01, 1.8276e+01, 1.8002e+01, 1.7741e+01, 1.7491e+01, 1.7251e+01, 1.7022e+01, 1.6801e+01, 1.6589e+01, 1.6385e+01, 1.6189e+01, 1.5998e+01, 1.5814e+01, 1.5636e+01, 1.5462e+01, 1.5293e+01, 1.5128e+01, 1.4967e+01, 1.4809e+01, 1.4653e+01, 1.4501e+01, 1.4351e+01, 1.4203e+01, 1.4056e+01, 1.3912e+01, 1.3768e+01, 1.3626e+01, 1.3485e+01, 1.3345e+01, 1.3206e+01, 1.3068e+01, 1.2930e+01, 1.2793e+01, 1.2656e+01, 1.2520e+01, 1.2384e+01, 1.2249e+01, 1.2115e+01, 1.1981e+01, 1.1848e+01, 1.1715e+01, 1.1582e+01, 1.1451e+01, 1.1320e+01, 1.1190e+01, 1.1060e+01, 1.0931e+01, 1.0803e+01, 1.0676e+01, 1.0550e+01, 1.0425e+01, 1.0301e+01, 1.0178e+01, 1.0056e+01, 9.9356e+00, 9.8165e+00, 9.6984e+00, 9.5815e+00, 9.4658e+00, 9.3518e+00, 9.2395e+00, 9.1288e+00, 9.0195e+00, 8.9114e+00, 8.8047e+00, 8.6996e+00, 8.5965e+00, 8.4954e+00, 8.3960e+00, 8.2980e+00, 8.2012e+00, 8.1060e+00, 8.0126e+00, 7.9214e+00, 7.8322e+00, 7.7448e+00, 7.6589e+00, 7.5742e+00, 7.4909e+00, 7.4093e+00, 7.3298e+00, 7.2524e+00, 7.1770e+00, 7.1031e+00, 7.0304e+00, 6.9588e+00, 6.8886e+00, 6.8201e+00, 6.7536e+00, 6.6892e+00, 6.6266e+00, 6.5653e+00, 6.5049e+00, 6.4454e+00, 6.3870e+00, 6.3302e+00, 6.2751e+00, 6.2219e+00, 6.1705e+00, 6.1203e+00, 6.0710e+00, 6.0222e+00, 5.9741e+00, 5.9270e+00, 5.8813e+00, 5.8372e+00, 5.7949e+00, 5.7539e+00, 5.7140e+00, 5.6744e+00, 5.6351e+00, 5.5962e+00, 5.5581e+00, 5.5210e+00, 5.4854e+00, 5.4512e+00, 5.4182e+00, 5.3862e+00, 5.3546e+00, 5.3229e+00, 5.2911e+00, 5.2597e+00, 5.2290e+00, 5.1992e+00, 5.1706e+00, 5.1432e+00, 5.1169e+00, 5.0912e+00, 5.0655e+00, 5.0395e+00, 5.0132e+00, 4.9870e+00, 4.9613e+00, 4.9362e+00, 4.9121e+00, 4.8890e+00, 4.8668e+00, 4.8453e+00, 4.8240e+00, 4.8022e+00, 4.7799e+00, 4.7571e+00, 4.7345e+00, 4.7122e+00, 4.6906e+00, 4.6697e+00, 4.6496e+00, 4.6304e+00, 4.6117e+00, 4.5931e+00, 4.5739e+00, 4.5539e+00, 4.5334e+00, 4.5128e+00, 4.4924e+00, 4.4724e+00, 4.4530e+00, 4.4342e+00, 4.4161e+00, 4.3987e+00, 4.3817e+00, 4.3645e+00, 4.3465e+00, 4.3276e+00, 4.3081e+00, 4.2885e+00, 4.2691e+00, 4.2502e+00, 4.2316e+00, 4.2135e+00, 4.1960e+00, 4.1793e+00, 4.1630e+00, 4.1468e+00, 4.1298e+00, 4.1119e+00, 4.0931e+00, 4.0739e+00, 4.0548e+00, 4.0360e+00, 4.0176e+00, 3.9996e+00, 3.9819e+00, 3.9648e+00}); + feg = Vctr_cpu({1.2263e+01, 1.2093e+01, 1.1614e+01, 1.0911e+01, 1.0085e+01, 9.2286e+00, 8.4057e+00, 7.6503e+00, 6.9748e+00, 6.3784e+00, 5.8542e+00, 5.3932e+00, 4.9861e+00, 4.6249e+00, 4.3027e+00, 4.0136e+00, 3.7531e+00, 3.5173e+00, 3.3030e+00, 3.1077e+00, 2.9291e+00, 2.7654e+00, 2.6150e+00, 2.4766e+00, 2.3489e+00, 2.2308e+00, 2.1215e+00, 2.0201e+00, 1.9258e+00, 1.8381e+00, 1.7563e+00, 1.6798e+00, 1.6083e+00, 1.5412e+00, 1.4783e+00, 1.4190e+00, 1.3633e+00, 1.3106e+00, 1.2609e+00, 1.2138e+00, 1.1693e+00, 1.1270e+00, 1.0869e+00, 1.0487e+00, 1.0124e+00, 9.7780e-01, 9.4480e-01, 9.1340e-01, 8.8330e-01, 8.5460e-01, 8.2720e-01, 8.0090e-01, 7.7580e-01, 7.5180e-01, 7.2870e-01, 7.0670e-01, 6.8550e-01, 6.6520e-01, 6.4570e-01, 6.2700e-01, 6.0910e-01, 5.9180e-01, 5.7530e-01, 5.5940e-01, 5.4410e-01, 5.2940e-01, 5.1530e-01, 5.0170e-01, 4.8860e-01, 4.7600e-01, 4.6390e-01, 4.5230e-01, 4.4110e-01, 4.3020e-01, 4.1980e-01, 4.0980e-01, 4.0010e-01, 3.9070e-01, 3.8170e-01, 3.7300e-01, 3.6470e-01, 3.5650e-01, 3.4870e-01, 3.4120e-01, 3.3380e-01, 3.2680e-01, 3.1990e-01, 3.1330e-01, 3.0690e-01, 3.0070e-01, 2.9470e-01, 2.8890e-01, 2.8330e-01, 2.7780e-01, 2.7250e-01, 2.6740e-01, 2.6240e-01, 2.5760e-01, 2.5290e-01, 2.4830e-01, 2.4390e-01, 2.3950e-01, 2.3530e-01, 2.3130e-01, 2.2730e-01, 2.2340e-01, 2.1970e-01, 2.1600e-01, 2.1240e-01, 2.0890e-01, 2.0550e-01, 2.0220e-01, 1.9900e-01, 1.9580e-01, 1.9280e-01, 1.8980e-01, 1.8680e-01, 1.8400e-01, 1.8120e-01, 1.7840e-01, 1.7570e-01, 1.7310e-01, 1.7060e-01, 1.6810e-01, 1.6560e-01, 1.6320e-01, 1.6090e-01, 1.5860e-01, 1.5630e-01, 1.5410e-01, 1.5200e-01, 1.4990e-01, 1.4780e-01, 1.4580e-01, 1.4380e-01, 1.4180e-01, 1.3990e-01, 1.3810e-01, 1.3620e-01, 1.3440e-01, 1.3270e-01, 1.3090e-01, 1.2920e-01, 1.2750e-01, 1.2590e-01, 1.2430e-01, 1.2270e-01, 1.2120e-01, 1.1960e-01, 1.1810e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0970e-01, 1.0840e-01, 1.0710e-01, 1.0580e-01, 1.0460e-01, 1.0330e-01, 1.0210e-01, 1.0090e-01, 9.9700e-02, 9.8600e-02, 9.7500e-02, 9.6300e-02, 9.5200e-02, 9.4200e-02, 9.3100e-02, 9.2100e-02, 9.1000e-02, 9.0000e-02, 8.9000e-02, 8.8000e-02, 8.7100e-02, 8.6100e-02, 8.5200e-02, 8.4300e-02, 8.3400e-02, 8.2500e-02, 8.1600e-02, 8.0800e-02, 7.9900e-02, 7.9100e-02, 7.8200e-02, 7.7400e-02, 7.6600e-02, 7.5900e-02, 7.5100e-02, 7.4300e-02, 7.3600e-02, 7.2800e-02, 7.2100e-02, 7.1400e-02, 7.0700e-02, 7.0000e-02, 6.9300e-02, 6.8600e-02, 6.7900e-02, 6.7300e-02, 6.6600e-02, 6.6000e-02, 6.5400e-02, 6.4800e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2400e-02, 6.1800e-02, 6.1200e-02, 6.0600e-02, 6.0100e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.7900e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1700e-02, 5.1300e-02, 5.0900e-02, 5.0400e-02, 5.0000e-02, 4.9600e-02, 4.9200e-02, 4.8800e-02, 4.8400e-02, 4.8000e-02, 4.7600e-02, 4.7200e-02}); + } + break; + case 76: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.6000e+01, 7.5692e+01, 7.4812e+01, 7.3476e+01, 7.1829e+01, 7.0003e+01, 6.8094e+01, 6.6165e+01, 6.4251e+01, 6.2370e+01, 6.0531e+01, 5.8740e+01, 5.7001e+01, 5.5316e+01, 5.3685e+01, 5.2112e+01, 5.0594e+01, 4.9133e+01, 4.7728e+01, 4.6376e+01, 4.5075e+01, 4.3825e+01, 4.2621e+01, 4.1461e+01, 4.0344e+01, 3.9266e+01, 3.8225e+01, 3.7219e+01, 3.6246e+01, 3.5304e+01, 3.4392e+01, 3.3509e+01, 3.2654e+01, 3.1825e+01, 3.1022e+01, 3.0245e+01, 2.9493e+01, 2.8766e+01, 2.8063e+01, 2.7384e+01, 2.6729e+01, 2.6098e+01, 2.5490e+01, 2.4905e+01, 2.4342e+01, 2.3802e+01, 2.3284e+01, 2.2788e+01, 2.2312e+01, 2.1857e+01, 2.1422e+01, 2.1006e+01, 2.0608e+01, 2.0229e+01, 1.9867e+01, 1.9522e+01, 1.9193e+01, 1.8878e+01, 1.8578e+01, 1.8292e+01, 1.8018e+01, 1.7757e+01, 1.7507e+01, 1.7267e+01, 1.7038e+01, 1.6818e+01, 1.6606e+01, 1.6403e+01, 1.6206e+01, 1.6017e+01, 1.5834e+01, 1.5656e+01, 1.5483e+01, 1.5316e+01, 1.5152e+01, 1.4992e+01, 1.4836e+01, 1.4683e+01, 1.4532e+01, 1.4384e+01, 1.4238e+01, 1.4095e+01, 1.3952e+01, 1.3812e+01, 1.3672e+01, 1.3534e+01, 1.3397e+01, 1.3260e+01, 1.3125e+01, 1.2990e+01, 1.2856e+01, 1.2722e+01, 1.2589e+01, 1.2457e+01, 1.2324e+01, 1.2193e+01, 1.2062e+01, 1.1931e+01, 1.1801e+01, 1.1671e+01, 1.1542e+01, 1.1414e+01, 1.1286e+01, 1.1159e+01, 1.1032e+01, 1.0906e+01, 1.0781e+01, 1.0657e+01, 1.0534e+01, 1.0412e+01, 1.0290e+01, 1.0170e+01, 1.0051e+01, 9.9327e+00, 9.8156e+00, 9.6998e+00, 9.5855e+00, 9.4725e+00, 9.3608e+00, 9.2502e+00, 9.1409e+00, 9.0331e+00, 8.9270e+00, 8.8227e+00, 8.7198e+00, 8.6183e+00, 8.5181e+00, 8.4193e+00, 8.3223e+00, 8.2272e+00, 8.1340e+00, 8.0424e+00, 7.9522e+00, 7.8633e+00, 7.7759e+00, 7.6902e+00, 7.6066e+00, 7.5249e+00, 7.4449e+00, 7.3664e+00, 7.2891e+00, 7.2130e+00, 7.1385e+00, 7.0659e+00, 6.9952e+00, 6.9264e+00, 6.8592e+00, 6.7933e+00, 6.7283e+00, 6.6644e+00, 6.6020e+00, 6.5412e+00, 6.4824e+00, 6.4253e+00, 6.3697e+00, 6.3152e+00, 6.2615e+00, 6.2085e+00, 6.1566e+00, 6.1061e+00, 6.0572e+00, 6.0100e+00, 5.9643e+00, 5.9198e+00, 5.8759e+00, 5.8326e+00, 5.7897e+00, 5.7477e+00, 5.7068e+00, 5.6674e+00, 5.6295e+00, 5.5928e+00, 5.5571e+00, 5.5220e+00, 5.4870e+00, 5.4523e+00, 5.4179e+00, 5.3843e+00, 5.3519e+00, 5.3207e+00, 5.2907e+00, 5.2617e+00, 5.2333e+00, 5.2051e+00, 5.1768e+00, 5.1484e+00, 5.1201e+00, 5.0925e+00, 5.0659e+00, 5.0403e+00, 5.0157e+00, 4.9919e+00, 4.9686e+00, 4.9454e+00, 4.9220e+00, 4.8981e+00, 4.8741e+00, 4.8503e+00, 4.8271e+00, 4.8049e+00, 4.7835e+00, 4.7629e+00, 4.7428e+00, 4.7230e+00, 4.7032e+00, 4.6829e+00, 4.6620e+00, 4.6407e+00, 4.6195e+00, 4.5988e+00, 4.5789e+00, 4.5597e+00, 4.5411e+00, 4.5230e+00, 4.5053e+00, 4.4876e+00, 4.4696e+00, 4.4508e+00, 4.4313e+00, 4.4114e+00, 4.3917e+00, 4.3726e+00, 4.3542e+00, 4.3364e+00, 4.3191e+00, 4.3022e+00, 4.2855e+00, 4.2690e+00, 4.2521e+00, 4.2344e+00, 4.2159e+00, 4.1967e+00, 4.1775e+00, 4.1588e+00, 4.1407e+00, 4.1233e+00, 4.1063e+00, 4.0896e+00, 4.0733e+00, 4.0573e+00, 4.0412e+00}); + feg = Vctr_cpu({1.1952e+01, 1.1801e+01, 1.1374e+01, 1.0739e+01, 9.9826e+00, 9.1866e+00, 8.4096e+00, 7.6859e+00, 7.0300e+00, 6.4439e+00, 5.9236e+00, 5.4623e+00, 5.0524e+00, 4.6869e+00, 4.3597e+00, 4.0657e+00, 3.8003e+00, 3.5600e+00, 3.3415e+00, 3.1425e+00, 2.9606e+00, 2.7939e+00, 2.6410e+00, 2.5002e+00, 2.3705e+00, 2.2507e+00, 2.1399e+00, 2.0372e+00, 1.9418e+00, 1.8530e+00, 1.7704e+00, 1.6932e+00, 1.6210e+00, 1.5534e+00, 1.4899e+00, 1.4303e+00, 1.3742e+00, 1.3212e+00, 1.2713e+00, 1.2240e+00, 1.1792e+00, 1.1368e+00, 1.0965e+00, 1.0582e+00, 1.0218e+00, 9.8710e-01, 9.5400e-01, 9.2250e-01, 8.9230e-01, 8.6350e-01, 8.3600e-01, 8.0970e-01, 7.8450e-01, 7.6030e-01, 7.3720e-01, 7.1500e-01, 6.9370e-01, 6.7330e-01, 6.5370e-01, 6.3480e-01, 6.1680e-01, 5.9940e-01, 5.8270e-01, 5.6670e-01, 5.5120e-01, 5.3640e-01, 5.2210e-01, 5.0840e-01, 4.9520e-01, 4.8250e-01, 4.7020e-01, 4.5840e-01, 4.4700e-01, 4.3610e-01, 4.2550e-01, 4.1530e-01, 4.0550e-01, 3.9600e-01, 3.8690e-01, 3.7810e-01, 3.6950e-01, 3.6130e-01, 3.5340e-01, 3.4570e-01, 3.3830e-01, 3.3110e-01, 3.2410e-01, 3.1740e-01, 3.1090e-01, 3.0460e-01, 2.9850e-01, 2.9260e-01, 2.8690e-01, 2.8130e-01, 2.7600e-01, 2.7070e-01, 2.6570e-01, 2.6080e-01, 2.5600e-01, 2.5130e-01, 2.4680e-01, 2.4250e-01, 2.3820e-01, 2.3400e-01, 2.3000e-01, 2.2610e-01, 2.2230e-01, 2.1860e-01, 2.1490e-01, 2.1140e-01, 2.0800e-01, 2.0460e-01, 2.0130e-01, 1.9810e-01, 1.9500e-01, 1.9200e-01, 1.8900e-01, 1.8610e-01, 1.8330e-01, 1.8050e-01, 1.7780e-01, 1.7520e-01, 1.7260e-01, 1.7000e-01, 1.6760e-01, 1.6510e-01, 1.6280e-01, 1.6050e-01, 1.5820e-01, 1.5600e-01, 1.5380e-01, 1.5160e-01, 1.4960e-01, 1.4750e-01, 1.4550e-01, 1.4350e-01, 1.4160e-01, 1.3970e-01, 1.3790e-01, 1.3600e-01, 1.3420e-01, 1.3250e-01, 1.3080e-01, 1.2910e-01, 1.2740e-01, 1.2580e-01, 1.2420e-01, 1.2260e-01, 1.2110e-01, 1.1960e-01, 1.1810e-01, 1.1670e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0970e-01, 1.0840e-01, 1.0710e-01, 1.0590e-01, 1.0460e-01, 1.0340e-01, 1.0220e-01, 1.0100e-01, 9.9800e-02, 9.8700e-02, 9.7600e-02, 9.6500e-02, 9.5400e-02, 9.4300e-02, 9.3200e-02, 9.2200e-02, 9.1200e-02, 9.0200e-02, 8.9200e-02, 8.8200e-02, 8.7300e-02, 8.6300e-02, 8.5400e-02, 8.4500e-02, 8.3600e-02, 8.2700e-02, 8.1800e-02, 8.1000e-02, 8.0100e-02, 7.9300e-02, 7.8500e-02, 7.7600e-02, 7.6900e-02, 7.6100e-02, 7.5300e-02, 7.4500e-02, 7.3800e-02, 7.3000e-02, 7.2300e-02, 7.1600e-02, 7.0900e-02, 7.0200e-02, 6.9500e-02, 6.8800e-02, 6.8200e-02, 6.7500e-02, 6.6900e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3800e-02, 6.3200e-02, 6.2600e-02, 6.2000e-02, 6.1400e-02, 6.0900e-02, 6.0300e-02, 5.9800e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1500e-02, 5.1100e-02, 5.0700e-02, 5.0300e-02, 4.9800e-02, 4.9400e-02, 4.9000e-02, 4.8600e-02, 4.8200e-02, 4.7800e-02}); + } + break; + case 77: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.7000e+01, 7.6700e+01, 7.5838e+01, 7.4520e+01, 7.2879e+01, 7.1043e+01, 6.9110e+01, 6.7145e+01, 6.5187e+01, 6.3260e+01, 6.1377e+01, 5.9546e+01, 5.7771e+01, 5.6055e+01, 5.4400e+01, 5.2806e+01, 5.1273e+01, 4.9801e+01, 4.8386e+01, 4.7029e+01, 4.5725e+01, 4.4473e+01, 4.3269e+01, 4.2110e+01, 4.0993e+01, 3.9916e+01, 3.8877e+01, 3.7872e+01, 3.6900e+01, 3.5958e+01, 3.5046e+01, 3.4161e+01, 3.3304e+01, 3.2472e+01, 3.1665e+01, 3.0882e+01, 3.0123e+01, 2.9388e+01, 2.8676e+01, 2.7987e+01, 2.7321e+01, 2.6678e+01, 2.6057e+01, 2.5458e+01, 2.4881e+01, 2.4326e+01, 2.3792e+01, 2.3280e+01, 2.2788e+01, 2.2316e+01, 2.1865e+01, 2.1432e+01, 2.1019e+01, 2.0624e+01, 2.0246e+01, 1.9885e+01, 1.9541e+01, 1.9212e+01, 1.8898e+01, 1.8598e+01, 1.8311e+01, 1.8038e+01, 1.7776e+01, 1.7526e+01, 1.7287e+01, 1.7057e+01, 1.6837e+01, 1.6625e+01, 1.6422e+01, 1.6226e+01, 1.6037e+01, 1.5854e+01, 1.5678e+01, 1.5506e+01, 1.5339e+01, 1.5177e+01, 1.5018e+01, 1.4864e+01, 1.4712e+01, 1.4563e+01, 1.4417e+01, 1.4274e+01, 1.4132e+01, 1.3992e+01, 1.3854e+01, 1.3717e+01, 1.3581e+01, 1.3446e+01, 1.3313e+01, 1.3180e+01, 1.3048e+01, 1.2917e+01, 1.2786e+01, 1.2656e+01, 1.2526e+01, 1.2397e+01, 1.2268e+01, 1.2140e+01, 1.2012e+01, 1.1885e+01, 1.1758e+01, 1.1631e+01, 1.1505e+01, 1.1380e+01, 1.1255e+01, 1.1131e+01, 1.1007e+01, 1.0884e+01, 1.0762e+01, 1.0641e+01, 1.0520e+01, 1.0401e+01, 1.0282e+01, 1.0164e+01, 1.0047e+01, 9.9316e+00, 9.8170e+00, 9.7036e+00, 9.5914e+00, 9.4804e+00, 9.3705e+00, 9.2619e+00, 9.1547e+00, 9.0490e+00, 8.9448e+00, 8.8419e+00, 8.7404e+00, 8.6402e+00, 8.5414e+00, 8.4444e+00, 8.3490e+00, 8.2553e+00, 8.1630e+00, 8.0721e+00, 7.9826e+00, 7.8946e+00, 7.8084e+00, 7.7240e+00, 7.6414e+00, 7.5603e+00, 7.4805e+00, 7.4021e+00, 7.3250e+00, 7.2496e+00, 7.1760e+00, 7.1042e+00, 7.0341e+00, 6.9654e+00, 6.8979e+00, 6.8314e+00, 6.7663e+00, 6.7028e+00, 6.6409e+00, 6.5808e+00, 6.5223e+00, 6.4651e+00, 6.4089e+00, 6.3535e+00, 6.2991e+00, 6.2460e+00, 6.1945e+00, 6.1445e+00, 6.0961e+00, 6.0489e+00, 6.0027e+00, 5.9572e+00, 5.9122e+00, 5.8681e+00, 5.8250e+00, 5.7832e+00, 5.7430e+00, 5.7040e+00, 5.6661e+00, 5.6289e+00, 5.5922e+00, 5.5558e+00, 5.5198e+00, 5.4846e+00, 5.4503e+00, 5.4173e+00, 5.3856e+00, 5.3548e+00, 5.3247e+00, 5.2950e+00, 5.2655e+00, 5.2360e+00, 5.2067e+00, 5.1778e+00, 5.1499e+00, 5.1230e+00, 5.0972e+00, 5.0723e+00, 5.0478e+00, 5.0235e+00, 4.9992e+00, 4.9748e+00, 4.9502e+00, 4.9257e+00, 4.9018e+00, 4.8787e+00, 4.8567e+00, 4.8354e+00, 4.8147e+00, 4.7941e+00, 4.7736e+00, 4.7529e+00, 4.7318e+00, 4.7104e+00, 4.6889e+00, 4.6679e+00, 4.6476e+00, 4.6282e+00, 4.6095e+00, 4.5912e+00, 4.5731e+00, 4.5550e+00, 4.5366e+00, 4.5179e+00, 4.4986e+00, 4.4789e+00, 4.4592e+00, 4.4399e+00, 4.4215e+00, 4.4039e+00, 4.3868e+00, 4.3701e+00, 4.3533e+00, 4.3364e+00, 4.3193e+00, 4.3018e+00, 4.2836e+00, 4.2649e+00, 4.2460e+00, 4.2273e+00, 4.2093e+00, 4.1922e+00, 4.1757e+00, 4.1596e+00, 4.1435e+00, 4.1274e+00, 4.1111e+00}); + feg = Vctr_cpu({1.1638e+01, 1.1505e+01, 1.1125e+01, 1.0553e+01, 9.8631e+00, 9.1246e+00, 8.3929e+00, 7.7020e+00, 7.0682e+00, 6.4957e+00, 5.9825e+00, 5.5238e+00, 5.1135e+00, 4.7459e+00, 4.4156e+00, 4.1177e+00, 3.8484e+00, 3.6041e+00, 3.3819e+00, 3.1793e+00, 2.9941e+00, 2.8245e+00, 2.6688e+00, 2.5257e+00, 2.3938e+00, 2.2721e+00, 2.1596e+00, 2.0554e+00, 1.9587e+00, 1.8688e+00, 1.7851e+00, 1.7070e+00, 1.6341e+00, 1.5658e+00, 1.5018e+00, 1.4417e+00, 1.3851e+00, 1.3318e+00, 1.2815e+00, 1.2340e+00, 1.1890e+00, 1.1464e+00, 1.1059e+00, 1.0675e+00, 1.0309e+00, 9.9610e-01, 9.6290e-01, 9.3130e-01, 9.0100e-01, 8.7220e-01, 8.4450e-01, 8.1810e-01, 7.9280e-01, 7.6860e-01, 7.4530e-01, 7.2300e-01, 7.0160e-01, 6.8110e-01, 6.6140e-01, 6.4250e-01, 6.2430e-01, 6.0680e-01, 5.9000e-01, 5.7380e-01, 5.5830e-01, 5.4330e-01, 5.2890e-01, 5.1500e-01, 5.0170e-01, 4.8880e-01, 4.7640e-01, 4.6450e-01, 4.5300e-01, 4.4190e-01, 4.3120e-01, 4.2090e-01, 4.1090e-01, 4.0130e-01, 3.9210e-01, 3.8310e-01, 3.7450e-01, 3.6610e-01, 3.5800e-01, 3.5020e-01, 3.4270e-01, 3.3540e-01, 3.2840e-01, 3.2150e-01, 3.1490e-01, 3.0850e-01, 3.0230e-01, 2.9630e-01, 2.9050e-01, 2.8490e-01, 2.7940e-01, 2.7410e-01, 2.6900e-01, 2.6400e-01, 2.5910e-01, 2.5440e-01, 2.4980e-01, 2.4540e-01, 2.4110e-01, 2.3690e-01, 2.3280e-01, 2.2880e-01, 2.2490e-01, 2.2110e-01, 2.1750e-01, 2.1390e-01, 2.1040e-01, 2.0700e-01, 2.0370e-01, 2.0040e-01, 1.9730e-01, 1.9420e-01, 1.9120e-01, 1.8830e-01, 1.8540e-01, 1.8260e-01, 1.7980e-01, 1.7720e-01, 1.7460e-01, 1.7200e-01, 1.6950e-01, 1.6700e-01, 1.6460e-01, 1.6230e-01, 1.6000e-01, 1.5780e-01, 1.5560e-01, 1.5340e-01, 1.5130e-01, 1.4920e-01, 1.4720e-01, 1.4520e-01, 1.4330e-01, 1.4130e-01, 1.3950e-01, 1.3760e-01, 1.3580e-01, 1.3410e-01, 1.3230e-01, 1.3060e-01, 1.2890e-01, 1.2730e-01, 1.2570e-01, 1.2410e-01, 1.2260e-01, 1.2100e-01, 1.1950e-01, 1.1810e-01, 1.1660e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0980e-01, 1.0850e-01, 1.0720e-01, 1.0590e-01, 1.0470e-01, 1.0350e-01, 1.0230e-01, 1.0110e-01, 9.9900e-02, 9.8800e-02, 9.7700e-02, 9.6600e-02, 9.5500e-02, 9.4400e-02, 9.3400e-02, 9.2300e-02, 9.1300e-02, 9.0300e-02, 8.9300e-02, 8.8400e-02, 8.7400e-02, 8.6500e-02, 8.5600e-02, 8.4600e-02, 8.3700e-02, 8.2900e-02, 8.2000e-02, 8.1100e-02, 8.0300e-02, 7.9500e-02, 7.8700e-02, 7.7800e-02, 7.7100e-02, 7.6300e-02, 7.5500e-02, 7.4700e-02, 7.4000e-02, 7.3300e-02, 7.2500e-02, 7.1800e-02, 7.1100e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8400e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.5800e-02, 6.5200e-02, 6.4600e-02, 6.4000e-02, 6.3400e-02, 6.2800e-02, 6.2200e-02, 6.1700e-02, 6.1100e-02, 6.0600e-02, 6.0000e-02, 5.9500e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1800e-02, 5.1300e-02, 5.0900e-02, 5.0500e-02, 5.0100e-02, 4.9700e-02, 4.9300e-02, 4.8900e-02, 4.8500e-02}); + } + break; + case 78: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.8000e+01, 7.7721e+01, 7.6915e+01, 7.5666e+01, 7.4086e+01, 7.2281e+01, 7.0342e+01, 6.8338e+01, 6.6315e+01, 6.4309e+01, 6.2342e+01, 6.0429e+01, 5.8580e+01, 5.6800e+01, 5.5093e+01, 5.3458e+01, 5.1895e+01, 5.0402e+01, 4.8975e+01, 4.7612e+01, 4.6307e+01, 4.5057e+01, 4.3859e+01, 4.2707e+01, 4.1599e+01, 4.0531e+01, 3.9500e+01, 3.8503e+01, 3.7538e+01, 3.6602e+01, 3.5694e+01, 3.4813e+01, 3.3956e+01, 3.3124e+01, 3.2315e+01, 3.1529e+01, 3.0765e+01, 3.0023e+01, 2.9303e+01, 2.8605e+01, 2.7928e+01, 2.7273e+01, 2.6640e+01, 2.6027e+01, 2.5436e+01, 2.4866e+01, 2.4317e+01, 2.3788e+01, 2.3280e+01, 2.2792e+01, 2.2323e+01, 2.1874e+01, 2.1444e+01, 2.1032e+01, 2.0639e+01, 2.0262e+01, 1.9902e+01, 1.9558e+01, 1.9229e+01, 1.8916e+01, 1.8616e+01, 1.8330e+01, 1.8056e+01, 1.7795e+01, 1.7544e+01, 1.7305e+01, 1.7076e+01, 1.6856e+01, 1.6645e+01, 1.6441e+01, 1.6246e+01, 1.6057e+01, 1.5875e+01, 1.5699e+01, 1.5529e+01, 1.5363e+01, 1.5202e+01, 1.5045e+01, 1.4892e+01, 1.4742e+01, 1.4595e+01, 1.4451e+01, 1.4309e+01, 1.4169e+01, 1.4032e+01, 1.3896e+01, 1.3761e+01, 1.3628e+01, 1.3496e+01, 1.3365e+01, 1.3235e+01, 1.3106e+01, 1.2977e+01, 1.2849e+01, 1.2722e+01, 1.2595e+01, 1.2469e+01, 1.2343e+01, 1.2217e+01, 1.2092e+01, 1.1967e+01, 1.1843e+01, 1.1719e+01, 1.1595e+01, 1.1472e+01, 1.1350e+01, 1.1228e+01, 1.1107e+01, 1.0986e+01, 1.0866e+01, 1.0746e+01, 1.0627e+01, 1.0509e+01, 1.0392e+01, 1.0276e+01, 1.0161e+01, 1.0046e+01, 9.9327e+00, 9.8203e+00, 9.7090e+00, 9.5990e+00, 9.4902e+00, 9.3823e+00, 9.2755e+00, 9.1700e+00, 9.0659e+00, 8.9633e+00, 8.8621e+00, 8.7623e+00, 8.6637e+00, 8.5664e+00, 8.4704e+00, 8.3760e+00, 8.2833e+00, 8.1923e+00, 8.1027e+00, 8.0145e+00, 7.9275e+00, 7.8419e+00, 7.7579e+00, 7.6756e+00, 7.5951e+00, 7.5163e+00, 7.4389e+00, 7.3628e+00, 7.2879e+00, 7.2143e+00, 7.1422e+00, 7.0719e+00, 7.0034e+00, 6.9365e+00, 6.8710e+00, 6.8066e+00, 6.7433e+00, 6.6811e+00, 6.6202e+00, 6.5609e+00, 6.5033e+00, 6.4473e+00, 6.3927e+00, 6.3392e+00, 6.2865e+00, 6.2347e+00, 6.1838e+00, 6.1341e+00, 6.0859e+00, 6.0391e+00, 5.9938e+00, 5.9497e+00, 5.9064e+00, 5.8638e+00, 5.8218e+00, 5.7804e+00, 5.7399e+00, 5.7005e+00, 5.6624e+00, 5.6256e+00, 5.5899e+00, 5.5551e+00, 5.5208e+00, 5.4868e+00, 5.4531e+00, 5.4199e+00, 5.3873e+00, 5.3556e+00, 5.3250e+00, 5.2955e+00, 5.2670e+00, 5.2392e+00, 5.2117e+00, 5.1842e+00, 5.1568e+00, 5.1296e+00, 5.1027e+00, 5.0764e+00, 5.0509e+00, 5.0263e+00, 5.0026e+00, 4.9797e+00, 4.9571e+00, 4.9346e+00, 4.9119e+00, 4.8890e+00, 4.8661e+00, 4.8434e+00, 4.8211e+00, 4.7993e+00, 4.7783e+00, 4.7581e+00, 4.7387e+00, 4.7196e+00, 4.7004e+00, 4.6810e+00, 4.6611e+00, 4.6411e+00, 4.6209e+00, 4.6009e+00, 4.5812e+00, 4.5619e+00, 4.5433e+00, 4.5255e+00, 4.5083e+00, 4.4914e+00, 4.4743e+00, 4.4567e+00, 4.4386e+00, 4.4202e+00, 4.4016e+00, 4.3829e+00, 4.3644e+00, 4.3461e+00, 4.3284e+00, 4.3114e+00, 4.2950e+00, 4.2792e+00, 4.2635e+00, 4.2473e+00, 4.2306e+00, 4.2133e+00, 4.1955e+00, 4.1776e+00}); + feg = Vctr_cpu({1.0807e+01, 1.0699e+01, 1.0392e+01, 9.9291e+00, 9.3676e+00, 8.7597e+00, 8.1455e+00, 7.5513e+00, 6.9915e+00, 6.4725e+00, 5.9960e+00, 5.5608e+00, 5.1643e+00, 4.8036e+00, 4.4755e+00, 4.1769e+00, 3.9049e+00, 3.6568e+00, 3.4304e+00, 3.2235e+00, 3.0341e+00, 2.8605e+00, 2.7012e+00, 2.5548e+00, 2.4200e+00, 2.2957e+00, 2.1809e+00, 2.0747e+00, 1.9763e+00, 1.8850e+00, 1.8001e+00, 1.7209e+00, 1.6471e+00, 1.5780e+00, 1.5134e+00, 1.4527e+00, 1.3957e+00, 1.3420e+00, 1.2914e+00, 1.2436e+00, 1.1984e+00, 1.1556e+00, 1.1150e+00, 1.0764e+00, 1.0397e+00, 1.0048e+00, 9.7150e-01, 9.3980e-01, 9.0950e-01, 8.8050e-01, 8.5280e-01, 8.2630e-01, 8.0090e-01, 7.7660e-01, 7.5330e-01, 7.3090e-01, 7.0940e-01, 6.8880e-01, 6.6900e-01, 6.5000e-01, 6.3170e-01, 6.1410e-01, 5.9720e-01, 5.8090e-01, 5.6520e-01, 5.5010e-01, 5.3560e-01, 5.2160e-01, 5.0810e-01, 4.9510e-01, 4.8260e-01, 4.7050e-01, 4.5890e-01, 4.4770e-01, 4.3690e-01, 4.2640e-01, 4.1630e-01, 4.0660e-01, 3.9720e-01, 3.8810e-01, 3.7940e-01, 3.7090e-01, 3.6270e-01, 3.5480e-01, 3.4720e-01, 3.3980e-01, 3.3260e-01, 3.2570e-01, 3.1900e-01, 3.1250e-01, 3.0620e-01, 3.0010e-01, 2.9420e-01, 2.8850e-01, 2.8290e-01, 2.7750e-01, 2.7230e-01, 2.6720e-01, 2.6230e-01, 2.5750e-01, 2.5290e-01, 2.4840e-01, 2.4400e-01, 2.3970e-01, 2.3550e-01, 2.3150e-01, 2.2760e-01, 2.2370e-01, 2.2000e-01, 2.1640e-01, 2.1280e-01, 2.0940e-01, 2.0600e-01, 2.0280e-01, 1.9960e-01, 1.9640e-01, 1.9340e-01, 1.9040e-01, 1.8750e-01, 1.8470e-01, 1.8190e-01, 1.7920e-01, 1.7650e-01, 1.7400e-01, 1.7140e-01, 1.6890e-01, 1.6650e-01, 1.6410e-01, 1.6180e-01, 1.5960e-01, 1.5730e-01, 1.5520e-01, 1.5300e-01, 1.5090e-01, 1.4890e-01, 1.4690e-01, 1.4490e-01, 1.4300e-01, 1.4110e-01, 1.3920e-01, 1.3740e-01, 1.3560e-01, 1.3390e-01, 1.3210e-01, 1.3040e-01, 1.2880e-01, 1.2720e-01, 1.2560e-01, 1.2400e-01, 1.2250e-01, 1.2090e-01, 1.1950e-01, 1.1800e-01, 1.1660e-01, 1.1520e-01, 1.1380e-01, 1.1240e-01, 1.1110e-01, 1.0980e-01, 1.0850e-01, 1.0720e-01, 1.0590e-01, 1.0470e-01, 1.0350e-01, 1.0230e-01, 1.0120e-01, 1.0000e-01, 9.8900e-02, 9.7800e-02, 9.6700e-02, 9.5600e-02, 9.4500e-02, 9.3500e-02, 9.2500e-02, 9.1400e-02, 9.0500e-02, 8.9500e-02, 8.8500e-02, 8.7600e-02, 8.6600e-02, 8.5700e-02, 8.4800e-02, 8.3900e-02, 8.3000e-02, 8.2200e-02, 8.1300e-02, 8.0500e-02, 7.9600e-02, 7.8800e-02, 7.8000e-02, 7.7200e-02, 7.6500e-02, 7.5700e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2700e-02, 7.2000e-02, 7.1300e-02, 7.0600e-02, 6.9900e-02, 6.9300e-02, 6.8600e-02, 6.8000e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5400e-02, 6.4800e-02, 6.4200e-02, 6.3600e-02, 6.3000e-02, 6.2500e-02, 6.1900e-02, 6.1300e-02, 6.0800e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5200e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0300e-02, 4.9900e-02, 4.9500e-02, 4.9100e-02}); + } + break; + case 79: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({7.9000e+01, 7.8727e+01, 7.7937e+01, 7.6706e+01, 7.5136e+01, 7.3332e+01, 7.1380e+01, 6.9350e+01, 6.7295e+01, 6.5249e+01, 6.3240e+01, 6.1284e+01, 5.9393e+01, 5.7575e+01, 5.5833e+01, 5.4168e+01, 5.2579e+01, 5.1064e+01, 4.9620e+01, 4.8242e+01, 4.6927e+01, 4.5670e+01, 4.4467e+01, 4.3313e+01, 4.2204e+01, 4.1137e+01, 4.0108e+01, 3.9113e+01, 3.8151e+01, 3.7218e+01, 3.6313e+01, 3.5433e+01, 3.4578e+01, 3.3747e+01, 3.2938e+01, 3.2150e+01, 3.1384e+01, 3.0639e+01, 2.9915e+01, 2.9210e+01, 2.8527e+01, 2.7863e+01, 2.7220e+01, 2.6598e+01, 2.5995e+01, 2.5413e+01, 2.4851e+01, 2.4308e+01, 2.3786e+01, 2.3283e+01, 2.2800e+01, 2.2335e+01, 2.1890e+01, 2.1462e+01, 2.1053e+01, 2.0661e+01, 2.0285e+01, 1.9926e+01, 1.9583e+01, 1.9255e+01, 1.8941e+01, 1.8642e+01, 1.8355e+01, 1.8081e+01, 1.7820e+01, 1.7569e+01, 1.7329e+01, 1.7100e+01, 1.6880e+01, 1.6668e+01, 1.6465e+01, 1.6269e+01, 1.6081e+01, 1.5899e+01, 1.5724e+01, 1.5553e+01, 1.5389e+01, 1.5228e+01, 1.5072e+01, 1.4920e+01, 1.4772e+01, 1.4626e+01, 1.4484e+01, 1.4344e+01, 1.4206e+01, 1.4070e+01, 1.3936e+01, 1.3804e+01, 1.3673e+01, 1.3543e+01, 1.3415e+01, 1.3287e+01, 1.3161e+01, 1.3035e+01, 1.2909e+01, 1.2785e+01, 1.2661e+01, 1.2537e+01, 1.2414e+01, 1.2291e+01, 1.2168e+01, 1.2046e+01, 1.1924e+01, 1.1803e+01, 1.1682e+01, 1.1562e+01, 1.1441e+01, 1.1322e+01, 1.1203e+01, 1.1084e+01, 1.0966e+01, 1.0848e+01, 1.0732e+01, 1.0616e+01, 1.0500e+01, 1.0385e+01, 1.0272e+01, 1.0159e+01, 1.0047e+01, 9.9354e+00, 9.8250e+00, 9.7158e+00, 9.6077e+00, 9.5008e+00, 9.3950e+00, 9.2903e+00, 9.1866e+00, 9.0841e+00, 8.9829e+00, 8.8832e+00, 8.7849e+00, 8.6879e+00, 8.5921e+00, 8.4976e+00, 8.4043e+00, 8.3125e+00, 8.2223e+00, 8.1338e+00, 8.0467e+00, 7.9609e+00, 7.8764e+00, 7.7932e+00, 7.7114e+00, 7.6312e+00, 7.5528e+00, 7.4759e+00, 7.4005e+00, 7.3264e+00, 7.2535e+00, 7.1818e+00, 7.1116e+00, 7.0429e+00, 6.9758e+00, 6.9104e+00, 6.8464e+00, 6.7836e+00, 6.7219e+00, 6.6612e+00, 6.6018e+00, 6.5437e+00, 6.4871e+00, 6.4321e+00, 6.3785e+00, 6.3261e+00, 6.2747e+00, 6.2241e+00, 6.1743e+00, 6.1256e+00, 6.0781e+00, 6.0319e+00, 5.9872e+00, 5.9436e+00, 5.9012e+00, 5.8595e+00, 5.8184e+00, 5.7779e+00, 5.7380e+00, 5.6992e+00, 5.6614e+00, 5.6248e+00, 5.5894e+00, 5.5549e+00, 5.5212e+00, 5.4880e+00, 5.4551e+00, 5.4224e+00, 5.3903e+00, 5.3589e+00, 5.3284e+00, 5.2989e+00, 5.2704e+00, 5.2427e+00, 5.2156e+00, 5.1888e+00, 5.1621e+00, 5.1355e+00, 5.1090e+00, 5.0828e+00, 5.0574e+00, 5.0327e+00, 5.0089e+00, 4.9859e+00, 4.9634e+00, 4.9413e+00, 4.9193e+00, 4.8971e+00, 4.8748e+00, 4.8523e+00, 4.8301e+00, 4.8084e+00, 4.7874e+00, 4.7670e+00, 4.7473e+00, 4.7281e+00, 4.7092e+00, 4.6904e+00, 4.6715e+00, 4.6521e+00, 4.6324e+00, 4.6125e+00, 4.5929e+00, 4.5737e+00, 4.5551e+00, 4.5371e+00, 4.5196e+00, 4.5025e+00, 4.4856e+00, 4.4688e+00, 4.4517e+00, 4.4341e+00, 4.4160e+00, 4.3976e+00, 4.3791e+00, 4.3610e+00, 4.3434e+00, 4.3263e+00, 4.3097e+00, 4.2935e+00, 4.2776e+00, 4.2619e+00, 4.2461e+00}); + feg = Vctr_cpu({1.0553e+01, 1.0456e+01, 1.0181e+01, 9.7617e+00, 9.2469e+00, 8.6826e+00, 8.1057e+00, 7.5412e+00, 7.0038e+00, 6.5009e+00, 6.0352e+00, 5.6068e+00, 5.2140e+00, 4.8547e+00, 4.5263e+00, 4.2263e+00, 3.9522e+00, 3.7017e+00, 3.4725e+00, 3.2627e+00, 3.0705e+00, 2.8942e+00, 2.7322e+00, 2.5834e+00, 2.4463e+00, 2.3199e+00, 2.2032e+00, 2.0952e+00, 1.9953e+00, 1.9025e+00, 1.8163e+00, 1.7360e+00, 1.6612e+00, 1.5913e+00, 1.5259e+00, 1.4645e+00, 1.4069e+00, 1.3528e+00, 1.3017e+00, 1.2535e+00, 1.2080e+00, 1.1649e+00, 1.1241e+00, 1.0853e+00, 1.0484e+00, 1.0134e+00, 9.8000e-01, 9.4810e-01, 9.1770e-01, 8.8860e-01, 8.6080e-01, 8.3430e-01, 8.0880e-01, 7.8440e-01, 7.6100e-01, 7.3850e-01, 7.1700e-01, 6.9630e-01, 6.7640e-01, 6.5720e-01, 6.3890e-01, 6.2120e-01, 6.0410e-01, 5.8780e-01, 5.7200e-01, 5.5680e-01, 5.4210e-01, 5.2800e-01, 5.1450e-01, 5.0140e-01, 4.8870e-01, 4.7650e-01, 4.6480e-01, 4.5340e-01, 4.4250e-01, 4.3190e-01, 4.2170e-01, 4.1190e-01, 4.0240e-01, 3.9320e-01, 3.8430e-01, 3.7570e-01, 3.6740e-01, 3.5940e-01, 3.5160e-01, 3.4410e-01, 3.3690e-01, 3.2980e-01, 3.2300e-01, 3.1640e-01, 3.1010e-01, 3.0390e-01, 2.9790e-01, 2.9210e-01, 2.8640e-01, 2.8100e-01, 2.7570e-01, 2.7050e-01, 2.6550e-01, 2.6060e-01, 2.5590e-01, 2.5130e-01, 2.4690e-01, 2.4260e-01, 2.3830e-01, 2.3420e-01, 2.3020e-01, 2.2640e-01, 2.2260e-01, 2.1890e-01, 2.1530e-01, 2.1180e-01, 2.0840e-01, 2.0510e-01, 2.0180e-01, 1.9870e-01, 1.9560e-01, 1.9260e-01, 1.8960e-01, 1.8680e-01, 1.8400e-01, 1.8120e-01, 1.7850e-01, 1.7590e-01, 1.7340e-01, 1.7080e-01, 1.6840e-01, 1.6600e-01, 1.6360e-01, 1.6140e-01, 1.5910e-01, 1.5690e-01, 1.5470e-01, 1.5260e-01, 1.5060e-01, 1.4850e-01, 1.4650e-01, 1.4460e-01, 1.4270e-01, 1.4080e-01, 1.3900e-01, 1.3720e-01, 1.3540e-01, 1.3360e-01, 1.3190e-01, 1.3030e-01, 1.2860e-01, 1.2700e-01, 1.2540e-01, 1.2390e-01, 1.2240e-01, 1.2090e-01, 1.1940e-01, 1.1790e-01, 1.1650e-01, 1.1510e-01, 1.1370e-01, 1.1240e-01, 1.1110e-01, 1.0980e-01, 1.0850e-01, 1.0720e-01, 1.0600e-01, 1.0470e-01, 1.0350e-01, 1.0240e-01, 1.0120e-01, 1.0010e-01, 9.8900e-02, 9.7800e-02, 9.6700e-02, 9.5700e-02, 9.4600e-02, 9.3600e-02, 9.2600e-02, 9.1600e-02, 9.0600e-02, 8.9600e-02, 8.8600e-02, 8.7700e-02, 8.6800e-02, 8.5800e-02, 8.4900e-02, 8.4100e-02, 8.3200e-02, 8.2300e-02, 8.1500e-02, 8.0600e-02, 7.9800e-02, 7.9000e-02, 7.8200e-02, 7.7400e-02, 7.6600e-02, 7.5900e-02, 7.5100e-02, 7.4400e-02, 7.3700e-02, 7.2900e-02, 7.2200e-02, 7.1500e-02, 7.0800e-02, 7.0200e-02, 6.9500e-02, 6.8800e-02, 6.8200e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3300e-02, 6.2700e-02, 6.2100e-02, 6.1600e-02, 6.1000e-02, 6.0500e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7800e-02, 5.7300e-02, 5.6800e-02, 5.6400e-02, 5.5900e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1800e-02, 5.1400e-02, 5.0900e-02, 5.0500e-02, 5.0100e-02, 4.9700e-02}); + } + break; + case 80: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.0000e+01, 7.9718e+01, 7.8901e+01, 7.7632e+01, 7.6021e+01, 7.4179e+01, 7.2199e+01, 7.0152e+01, 6.8087e+01, 6.6038e+01, 6.4027e+01, 6.2069e+01, 6.0175e+01, 5.8350e+01, 5.6597e+01, 5.4920e+01, 5.3316e+01, 5.1785e+01, 5.0324e+01, 4.8930e+01, 4.7599e+01, 4.6327e+01, 4.5111e+01, 4.3945e+01, 4.2827e+01, 4.1751e+01, 4.0716e+01, 3.9716e+01, 3.8750e+01, 3.7815e+01, 3.6909e+01, 3.6029e+01, 3.5173e+01, 3.4342e+01, 3.3532e+01, 3.2745e+01, 3.1977e+01, 3.1231e+01, 3.0504e+01, 2.9797e+01, 2.9109e+01, 2.8440e+01, 2.7791e+01, 2.7162e+01, 2.6551e+01, 2.5960e+01, 2.5387e+01, 2.4834e+01, 2.4300e+01, 2.3785e+01, 2.3289e+01, 2.2811e+01, 2.2352e+01, 2.1910e+01, 2.1486e+01, 2.1079e+01, 2.0689e+01, 2.0316e+01, 1.9958e+01, 1.9616e+01, 1.9288e+01, 1.8975e+01, 1.8675e+01, 1.8388e+01, 1.8114e+01, 1.7852e+01, 1.7601e+01, 1.7360e+01, 1.7130e+01, 1.6909e+01, 1.6697e+01, 1.6494e+01, 1.6297e+01, 1.6109e+01, 1.5927e+01, 1.5751e+01, 1.5581e+01, 1.5416e+01, 1.5257e+01, 1.5101e+01, 1.4950e+01, 1.4802e+01, 1.4658e+01, 1.4516e+01, 1.4378e+01, 1.4241e+01, 1.4107e+01, 1.3975e+01, 1.3845e+01, 1.3716e+01, 1.3588e+01, 1.3462e+01, 1.3337e+01, 1.3213e+01, 1.3089e+01, 1.2966e+01, 1.2844e+01, 1.2722e+01, 1.2601e+01, 1.2481e+01, 1.2360e+01, 1.2241e+01, 1.2121e+01, 1.2002e+01, 1.1883e+01, 1.1765e+01, 1.1647e+01, 1.1529e+01, 1.1412e+01, 1.1295e+01, 1.1179e+01, 1.1063e+01, 1.0947e+01, 1.0833e+01, 1.0718e+01, 1.0605e+01, 1.0492e+01, 1.0380e+01, 1.0268e+01, 1.0158e+01, 1.0048e+01, 9.9387e+00, 9.8307e+00, 9.7237e+00, 9.6177e+00, 9.5127e+00, 9.4086e+00, 9.3056e+00, 9.2037e+00, 9.1030e+00, 9.0037e+00, 8.9056e+00, 8.8087e+00, 8.7130e+00, 8.6183e+00, 8.5250e+00, 8.4331e+00, 8.3428e+00, 8.2539e+00, 8.1663e+00, 8.0800e+00, 7.9948e+00, 7.9110e+00, 7.8285e+00, 7.7477e+00, 7.6686e+00, 7.5909e+00, 7.5145e+00, 7.4393e+00, 7.3653e+00, 7.2926e+00, 7.2213e+00, 7.1516e+00, 7.0836e+00, 7.0170e+00, 6.9518e+00, 6.8877e+00, 6.8245e+00, 6.7625e+00, 6.7018e+00, 6.6425e+00, 6.5848e+00, 6.5287e+00, 6.4738e+00, 6.4200e+00, 6.3670e+00, 6.3149e+00, 6.2637e+00, 6.2137e+00, 6.1650e+00, 6.1178e+00, 6.0720e+00, 6.0273e+00, 5.9834e+00, 5.9403e+00, 5.8977e+00, 5.8558e+00, 5.8147e+00, 5.7747e+00, 5.7360e+00, 5.6986e+00, 5.6623e+00, 5.6267e+00, 5.5918e+00, 5.5572e+00, 5.5229e+00, 5.4891e+00, 5.4559e+00, 5.4237e+00, 5.3926e+00, 5.3626e+00, 5.3335e+00, 5.3050e+00, 5.2769e+00, 5.2490e+00, 5.2212e+00, 5.1935e+00, 5.1662e+00, 5.1394e+00, 5.1136e+00, 5.0888e+00, 5.0648e+00, 5.0414e+00, 5.0183e+00, 4.9955e+00, 4.9726e+00, 4.9495e+00, 4.9264e+00, 4.9034e+00, 4.8809e+00, 4.8591e+00, 4.8382e+00, 4.8181e+00, 4.7984e+00, 4.7790e+00, 4.7597e+00, 4.7403e+00, 4.7206e+00, 4.7006e+00, 4.6804e+00, 4.6604e+00, 4.6407e+00, 4.6219e+00, 4.6038e+00, 4.5862e+00, 4.5691e+00, 4.5520e+00, 4.5350e+00, 4.5177e+00, 4.5001e+00, 4.4820e+00, 4.4635e+00, 4.4449e+00, 4.4266e+00, 4.4090e+00, 4.3921e+00, 4.3758e+00, 4.3599e+00, 4.3442e+00, 4.3284e+00, 4.3125e+00}); + feg = Vctr_cpu({1.0922e+01, 1.0820e+01, 1.0525e+01, 1.0076e+01, 9.5230e+00, 8.9163e+00, 8.2978e+00, 7.6962e+00, 7.1280e+00, 6.6009e+00, 6.1168e+00, 5.6747e+00, 5.2721e+00, 4.9058e+00, 4.5723e+00, 4.2685e+00, 3.9915e+00, 3.7386e+00, 3.5074e+00, 3.2958e+00, 3.1019e+00, 2.9239e+00, 2.7604e+00, 2.6100e+00, 2.4714e+00, 2.3435e+00, 2.2254e+00, 2.1161e+00, 2.0148e+00, 1.9208e+00, 1.8335e+00, 1.7522e+00, 1.6764e+00, 1.6055e+00, 1.5393e+00, 1.4772e+00, 1.4190e+00, 1.3642e+00, 1.3126e+00, 1.2640e+00, 1.2180e+00, 1.1745e+00, 1.1334e+00, 1.0943e+00, 1.0572e+00, 1.0219e+00, 9.8830e-01, 9.5630e-01, 9.2580e-01, 8.9660e-01, 8.6870e-01, 8.4200e-01, 8.1640e-01, 7.9190e-01, 7.6840e-01, 7.4590e-01, 7.2420e-01, 7.0350e-01, 6.8350e-01, 6.6430e-01, 6.4580e-01, 6.2800e-01, 6.1090e-01, 5.9440e-01, 5.7860e-01, 5.6330e-01, 5.4860e-01, 5.3440e-01, 5.2070e-01, 5.0750e-01, 4.9470e-01, 4.8240e-01, 4.7060e-01, 4.5910e-01, 4.4810e-01, 4.3740e-01, 4.2710e-01, 4.1710e-01, 4.0750e-01, 3.9820e-01, 3.8920e-01, 3.8050e-01, 3.7210e-01, 3.6400e-01, 3.5610e-01, 3.4850e-01, 3.4120e-01, 3.3400e-01, 3.2710e-01, 3.2040e-01, 3.1400e-01, 3.0770e-01, 3.0160e-01, 2.9570e-01, 2.9000e-01, 2.8440e-01, 2.7900e-01, 2.7380e-01, 2.6870e-01, 2.6380e-01, 2.5900e-01, 2.5440e-01, 2.4980e-01, 2.4540e-01, 2.4120e-01, 2.3700e-01, 2.3300e-01, 2.2900e-01, 2.2520e-01, 2.2140e-01, 2.1780e-01, 2.1430e-01, 2.1080e-01, 2.0740e-01, 2.0410e-01, 2.0090e-01, 1.9780e-01, 1.9480e-01, 1.9180e-01, 1.8890e-01, 1.8600e-01, 1.8320e-01, 1.8050e-01, 1.7790e-01, 1.7530e-01, 1.7280e-01, 1.7030e-01, 1.6780e-01, 1.6550e-01, 1.6310e-01, 1.6090e-01, 1.5860e-01, 1.5650e-01, 1.5430e-01, 1.5220e-01, 1.5020e-01, 1.4820e-01, 1.4620e-01, 1.4430e-01, 1.4240e-01, 1.4050e-01, 1.3870e-01, 1.3690e-01, 1.3520e-01, 1.3340e-01, 1.3170e-01, 1.3010e-01, 1.2850e-01, 1.2690e-01, 1.2530e-01, 1.2370e-01, 1.2220e-01, 1.2070e-01, 1.1930e-01, 1.1780e-01, 1.1640e-01, 1.1500e-01, 1.1370e-01, 1.1230e-01, 1.1100e-01, 1.0970e-01, 1.0850e-01, 1.0720e-01, 1.0600e-01, 1.0480e-01, 1.0360e-01, 1.0240e-01, 1.0120e-01, 1.0010e-01, 9.9000e-02, 9.7900e-02, 9.6800e-02, 9.5800e-02, 9.4700e-02, 9.3700e-02, 9.2700e-02, 9.1700e-02, 9.0700e-02, 8.9700e-02, 8.8800e-02, 8.7800e-02, 8.6900e-02, 8.6000e-02, 8.5100e-02, 8.4200e-02, 8.3300e-02, 8.2500e-02, 8.1600e-02, 8.0800e-02, 8.0000e-02, 7.9200e-02, 7.8400e-02, 7.7600e-02, 7.6800e-02, 7.6100e-02, 7.5300e-02, 7.4600e-02, 7.3800e-02, 7.3100e-02, 7.2400e-02, 7.1700e-02, 7.1000e-02, 7.0300e-02, 6.9700e-02, 6.9000e-02, 6.8400e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.5900e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1800e-02, 6.1200e-02, 6.0700e-02, 6.0100e-02, 5.9600e-02, 5.9100e-02, 5.8600e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5600e-02, 5.5100e-02, 5.4700e-02, 5.4200e-02, 5.3800e-02, 5.3300e-02, 5.2900e-02, 5.2400e-02, 5.2000e-02, 5.1600e-02, 5.1100e-02, 5.0700e-02, 5.0300e-02}); + } + break; + case 81: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.1000e+01, 8.0673e+01, 7.9749e+01, 7.8370e+01, 7.6690e+01, 7.4831e+01, 7.2871e+01, 7.0860e+01, 6.8833e+01, 6.6816e+01, 6.4828e+01, 6.2882e+01, 6.0990e+01, 5.9159e+01, 5.7394e+01, 5.5699e+01, 5.4075e+01, 5.2522e+01, 5.1039e+01, 4.9622e+01, 4.8271e+01, 4.6980e+01, 4.5746e+01, 4.4566e+01, 4.3435e+01, 4.2350e+01, 4.1307e+01, 4.0302e+01, 3.9332e+01, 3.8395e+01, 3.7487e+01, 3.6607e+01, 3.5752e+01, 3.4922e+01, 3.4113e+01, 3.3327e+01, 3.2560e+01, 3.1813e+01, 3.1086e+01, 3.0377e+01, 2.9687e+01, 2.9015e+01, 2.8362e+01, 2.7727e+01, 2.7110e+01, 2.6511e+01, 2.5930e+01, 2.5368e+01, 2.4824e+01, 2.4297e+01, 2.3789e+01, 2.3299e+01, 2.2827e+01, 2.2372e+01, 2.1934e+01, 2.1513e+01, 2.1109e+01, 2.0721e+01, 2.0349e+01, 1.9993e+01, 1.9651e+01, 1.9324e+01, 1.9011e+01, 1.8711e+01, 1.8424e+01, 1.8149e+01, 1.7886e+01, 1.7634e+01, 1.7393e+01, 1.7162e+01, 1.6941e+01, 1.6728e+01, 1.6524e+01, 1.6327e+01, 1.6138e+01, 1.5956e+01, 1.5780e+01, 1.5610e+01, 1.5445e+01, 1.5286e+01, 1.5131e+01, 1.4980e+01, 1.4833e+01, 1.4689e+01, 1.4549e+01, 1.4412e+01, 1.4277e+01, 1.4144e+01, 1.4014e+01, 1.3885e+01, 1.3758e+01, 1.3633e+01, 1.3508e+01, 1.3385e+01, 1.3263e+01, 1.3142e+01, 1.3022e+01, 1.2902e+01, 1.2783e+01, 1.2664e+01, 1.2546e+01, 1.2428e+01, 1.2311e+01, 1.2194e+01, 1.2077e+01, 1.1961e+01, 1.1845e+01, 1.1730e+01, 1.1614e+01, 1.1499e+01, 1.1385e+01, 1.1271e+01, 1.1158e+01, 1.1044e+01, 1.0931e+01, 1.0819e+01, 1.0707e+01, 1.0596e+01, 1.0486e+01, 1.0376e+01, 1.0267e+01, 1.0158e+01, 1.0050e+01, 9.9435e+00, 9.8379e+00, 9.7333e+00, 9.6293e+00, 9.5259e+00, 9.4233e+00, 9.3218e+00, 9.2217e+00, 9.1231e+00, 9.0258e+00, 8.9293e+00, 8.8335e+00, 8.7387e+00, 8.6451e+00, 8.5531e+00, 8.4628e+00, 8.3740e+00, 8.2864e+00, 8.1997e+00, 8.1139e+00, 8.0292e+00, 7.9460e+00, 7.8645e+00, 7.7847e+00, 7.7066e+00, 7.6298e+00, 7.5539e+00, 7.4787e+00, 7.4047e+00, 7.3322e+00, 7.2613e+00, 7.1923e+00, 7.1249e+00, 7.0590e+00, 6.9939e+00, 6.9296e+00, 6.8661e+00, 6.8038e+00, 6.7431e+00, 6.6840e+00, 6.6265e+00, 6.5707e+00, 6.5161e+00, 6.4622e+00, 6.4087e+00, 6.3560e+00, 6.3045e+00, 6.2542e+00, 6.2054e+00, 6.1581e+00, 6.1123e+00, 6.0677e+00, 6.0238e+00, 5.9802e+00, 5.9370e+00, 5.8944e+00, 5.8530e+00, 5.8127e+00, 5.7737e+00, 5.7359e+00, 5.6995e+00, 5.6642e+00, 5.6292e+00, 5.5942e+00, 5.5593e+00, 5.5249e+00, 5.4913e+00, 5.4588e+00, 5.4272e+00, 5.3967e+00, 5.3673e+00, 5.3390e+00, 5.3112e+00, 5.2832e+00, 5.2550e+00, 5.2268e+00, 5.1990e+00, 5.1721e+00, 5.1459e+00, 5.1204e+00, 5.0958e+00, 5.0722e+00, 5.0495e+00, 5.0271e+00, 5.0045e+00, 4.9813e+00, 4.9578e+00, 4.9346e+00, 4.9120e+00, 4.8900e+00, 4.8685e+00, 4.8476e+00, 4.8274e+00, 4.8082e+00, 4.7896e+00, 4.7709e+00, 4.7517e+00, 4.7318e+00, 4.7114e+00, 4.6913e+00, 4.6717e+00, 4.6526e+00, 4.6338e+00, 4.6155e+00, 4.5977e+00, 4.5808e+00, 4.5645e+00, 4.5484e+00, 4.5317e+00, 4.5141e+00, 4.4958e+00, 4.4773e+00, 4.4591e+00, 4.4414e+00, 4.4240e+00, 4.4069e+00, 4.3901e+00, 4.3739e+00}); + feg = Vctr_cpu({1.2724e+01, 1.2524e+01, 1.1972e+01, 1.1190e+01, 1.0315e+01, 9.4495e+00, 8.6474e+00, 7.9248e+00, 7.2799e+00, 6.7055e+00, 6.1929e+00, 5.7339e+00, 5.3213e+00, 4.9490e+00, 4.6120e+00, 4.3060e+00, 4.0275e+00, 3.7734e+00, 3.5412e+00, 3.3285e+00, 3.1333e+00, 2.9541e+00, 2.7893e+00, 2.6374e+00, 2.4974e+00, 2.3681e+00, 2.2485e+00, 2.1378e+00, 2.0352e+00, 1.9400e+00, 1.8514e+00, 1.7690e+00, 1.6921e+00, 1.6203e+00, 1.5532e+00, 1.4903e+00, 1.4313e+00, 1.3759e+00, 1.3237e+00, 1.2745e+00, 1.2281e+00, 1.1842e+00, 1.1427e+00, 1.1033e+00, 1.0659e+00, 1.0304e+00, 9.9660e-01, 9.6440e-01, 9.3370e-01, 9.0440e-01, 8.7630e-01, 8.4950e-01, 8.2380e-01, 7.9930e-01, 7.7570e-01, 7.5310e-01, 7.3130e-01, 7.1050e-01, 6.9040e-01, 6.7110e-01, 6.5260e-01, 6.3470e-01, 6.1750e-01, 6.0100e-01, 5.8500e-01, 5.6970e-01, 5.5480e-01, 5.4050e-01, 5.2680e-01, 5.1350e-01, 5.0060e-01, 4.8820e-01, 4.7630e-01, 4.6470e-01, 4.5360e-01, 4.4280e-01, 4.3240e-01, 4.2230e-01, 4.1260e-01, 4.0320e-01, 3.9410e-01, 3.8530e-01, 3.7680e-01, 3.6860e-01, 3.6060e-01, 3.5290e-01, 3.4550e-01, 3.3820e-01, 3.3120e-01, 3.2450e-01, 3.1790e-01, 3.1150e-01, 3.0540e-01, 2.9940e-01, 2.9360e-01, 2.8790e-01, 2.8250e-01, 2.7720e-01, 2.7200e-01, 2.6700e-01, 2.6210e-01, 2.5740e-01, 2.5280e-01, 2.4840e-01, 2.4400e-01, 2.3980e-01, 2.3570e-01, 2.3170e-01, 2.2780e-01, 2.2400e-01, 2.2030e-01, 2.1670e-01, 2.1320e-01, 2.0980e-01, 2.0650e-01, 2.0320e-01, 2.0000e-01, 1.9690e-01, 1.9390e-01, 1.9100e-01, 1.8810e-01, 1.8530e-01, 1.8250e-01, 1.7990e-01, 1.7720e-01, 1.7470e-01, 1.7220e-01, 1.6970e-01, 1.6730e-01, 1.6490e-01, 1.6260e-01, 1.6040e-01, 1.5820e-01, 1.5600e-01, 1.5390e-01, 1.5180e-01, 1.4980e-01, 1.4780e-01, 1.4590e-01, 1.4390e-01, 1.4210e-01, 1.4020e-01, 1.3840e-01, 1.3660e-01, 1.3490e-01, 1.3320e-01, 1.3150e-01, 1.2990e-01, 1.2830e-01, 1.2670e-01, 1.2510e-01, 1.2360e-01, 1.2210e-01, 1.2060e-01, 1.1920e-01, 1.1780e-01, 1.1630e-01, 1.1500e-01, 1.1360e-01, 1.1230e-01, 1.1100e-01, 1.0970e-01, 1.0840e-01, 1.0720e-01, 1.0600e-01, 1.0480e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0010e-01, 9.9000e-02, 9.8000e-02, 9.6900e-02, 9.5800e-02, 9.4800e-02, 9.3800e-02, 9.2700e-02, 9.1800e-02, 9.0800e-02, 8.9800e-02, 8.8900e-02, 8.7900e-02, 8.7000e-02, 8.6100e-02, 8.5200e-02, 8.4300e-02, 8.3500e-02, 8.2600e-02, 8.1800e-02, 8.0900e-02, 8.0100e-02, 7.9300e-02, 7.8500e-02, 7.7800e-02, 7.7000e-02, 7.6200e-02, 7.5500e-02, 7.4700e-02, 7.4000e-02, 7.3300e-02, 7.2600e-02, 7.1900e-02, 7.1200e-02, 7.0500e-02, 6.9900e-02, 6.9200e-02, 6.8600e-02, 6.7900e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5400e-02, 6.4800e-02, 6.4300e-02, 6.3700e-02, 6.3100e-02, 6.2500e-02, 6.2000e-02, 6.1400e-02, 6.0900e-02, 6.0300e-02, 5.9800e-02, 5.9300e-02, 5.8800e-02, 5.8300e-02, 5.7800e-02, 5.7300e-02, 5.6800e-02, 5.6300e-02, 5.5800e-02, 5.5300e-02, 5.4900e-02, 5.4400e-02, 5.4000e-02, 5.3500e-02, 5.3100e-02, 5.2600e-02, 5.2200e-02, 5.1800e-02, 5.1400e-02, 5.0900e-02}); + } + break; + case 82: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.2000e+01, 8.1664e+01, 8.0713e+01, 7.9283e+01, 7.7537e+01, 7.5609e+01, 7.3595e+01, 7.1554e+01, 6.9518e+01, 6.7508e+01, 6.5535e+01, 6.3607e+01, 6.1731e+01, 5.9912e+01, 5.8154e+01, 5.6459e+01, 5.4829e+01, 5.3265e+01, 5.1767e+01, 5.0334e+01, 4.8965e+01, 4.7655e+01, 4.6404e+01, 4.5206e+01, 4.4060e+01, 4.2961e+01, 4.1906e+01, 4.0891e+01, 3.9914e+01, 3.8970e+01, 3.8058e+01, 3.7175e+01, 3.6319e+01, 3.5487e+01, 3.4678e+01, 3.3892e+01, 3.3126e+01, 3.2379e+01, 3.1652e+01, 3.0942e+01, 3.0251e+01, 2.9578e+01, 2.8922e+01, 2.8283e+01, 2.7662e+01, 2.7058e+01, 2.6471e+01, 2.5901e+01, 2.5349e+01, 2.4813e+01, 2.4295e+01, 2.3795e+01, 2.3311e+01, 2.2844e+01, 2.2394e+01, 2.1960e+01, 2.1543e+01, 2.1142e+01, 2.0756e+01, 2.0386e+01, 2.0031e+01, 1.9690e+01, 1.9364e+01, 1.9051e+01, 1.8751e+01, 1.8463e+01, 1.8188e+01, 1.7925e+01, 1.7672e+01, 1.7431e+01, 1.7199e+01, 1.6976e+01, 1.6763e+01, 1.6558e+01, 1.6361e+01, 1.6171e+01, 1.5988e+01, 1.5812e+01, 1.5641e+01, 1.5477e+01, 1.5317e+01, 1.5162e+01, 1.5012e+01, 1.4865e+01, 1.4722e+01, 1.4583e+01, 1.4446e+01, 1.4313e+01, 1.4181e+01, 1.4052e+01, 1.3925e+01, 1.3800e+01, 1.3676e+01, 1.3553e+01, 1.3432e+01, 1.3312e+01, 1.3193e+01, 1.3075e+01, 1.2958e+01, 1.2841e+01, 1.2724e+01, 1.2609e+01, 1.2493e+01, 1.2379e+01, 1.2264e+01, 1.2150e+01, 1.2036e+01, 1.1923e+01, 1.1810e+01, 1.1697e+01, 1.1585e+01, 1.1472e+01, 1.1360e+01, 1.1248e+01, 1.1138e+01, 1.1027e+01, 1.0917e+01, 1.0807e+01, 1.0698e+01, 1.0588e+01, 1.0480e+01, 1.0373e+01, 1.0267e+01, 1.0161e+01, 1.0055e+01, 9.9498e+00, 9.8456e+00, 9.7426e+00, 9.6409e+00, 9.5401e+00, 9.4400e+00, 9.3403e+00, 9.2413e+00, 9.1434e+00, 9.0470e+00, 8.9522e+00, 8.8588e+00, 8.7663e+00, 8.6745e+00, 8.5833e+00, 8.4931e+00, 8.4044e+00, 8.3174e+00, 8.2323e+00, 8.1486e+00, 8.0659e+00, 7.9839e+00, 7.9027e+00, 7.8224e+00, 7.7437e+00, 7.6668e+00, 7.5919e+00, 7.5186e+00, 7.4464e+00, 7.3751e+00, 7.3045e+00, 7.2346e+00, 7.1659e+00, 7.0988e+00, 7.0338e+00, 6.9706e+00, 6.9089e+00, 6.8482e+00, 6.7882e+00, 6.7288e+00, 6.6700e+00, 6.6123e+00, 6.5560e+00, 6.5017e+00, 6.4492e+00, 6.3982e+00, 6.3482e+00, 6.2987e+00, 6.2498e+00, 6.2013e+00, 6.1534e+00, 6.1065e+00, 6.0611e+00, 6.0175e+00, 5.9756e+00, 5.9348e+00, 5.8948e+00, 5.8551e+00, 5.8158e+00, 5.7767e+00, 5.7379e+00, 5.6998e+00, 5.6629e+00, 5.6277e+00, 5.5941e+00, 5.5616e+00, 5.5297e+00, 5.4981e+00, 5.4667e+00, 5.4354e+00, 5.4041e+00, 5.3730e+00, 5.3424e+00, 5.3129e+00, 5.2850e+00, 5.2585e+00, 5.2329e+00, 5.2076e+00, 5.1825e+00, 5.1573e+00, 5.1322e+00, 5.1069e+00, 5.0814e+00, 5.0560e+00, 5.0314e+00, 5.0080e+00, 4.9860e+00, 4.9651e+00, 4.9446e+00, 4.9242e+00, 4.9036e+00, 4.8829e+00, 4.8621e+00, 4.8410e+00, 4.8195e+00, 4.7979e+00, 4.7768e+00, 4.7568e+00, 4.7381e+00, 4.7205e+00, 4.7033e+00, 4.6860e+00, 4.6685e+00, 4.6508e+00, 4.6330e+00, 4.6148e+00, 4.5961e+00, 4.5770e+00, 4.5577e+00, 4.5389e+00, 4.5213e+00, 4.5049e+00, 4.4894e+00, 4.4742e+00, 4.4589e+00, 4.4431e+00}); + feg = Vctr_cpu({1.3040e+01, 1.2850e+01, 1.2321e+01, 1.1559e+01, 1.0683e+01, 9.7895e+00, 8.9402e+00, 8.1637e+00, 7.4683e+00, 6.8513e+00, 6.3051e+00, 5.8209e+00, 5.3900e+00, 5.0049e+00, 4.6590e+00, 4.3470e+00, 4.0644e+00, 3.8075e+00, 3.5732e+00, 3.3590e+00, 3.1626e+00, 2.9823e+00, 2.8164e+00, 2.6635e+00, 2.5223e+00, 2.3919e+00, 2.2712e+00, 2.1594e+00, 2.0557e+00, 1.9593e+00, 1.8697e+00, 1.7862e+00, 1.7083e+00, 1.6356e+00, 1.5676e+00, 1.5039e+00, 1.4441e+00, 1.3880e+00, 1.3352e+00, 1.2855e+00, 1.2385e+00, 1.1942e+00, 1.1523e+00, 1.1125e+00, 1.0748e+00, 1.0390e+00, 1.0049e+00, 9.7250e-01, 9.4160e-01, 9.1210e-01, 8.8390e-01, 8.5690e-01, 8.3120e-01, 8.0640e-01, 7.8280e-01, 7.6000e-01, 7.3820e-01, 7.1730e-01, 6.9720e-01, 6.7780e-01, 6.5920e-01, 6.4120e-01, 6.2400e-01, 6.0740e-01, 5.9130e-01, 5.7590e-01, 5.6100e-01, 5.4660e-01, 5.3270e-01, 5.1930e-01, 5.0640e-01, 4.9400e-01, 4.8190e-01, 4.7030e-01, 4.5900e-01, 4.4820e-01, 4.3760e-01, 4.2750e-01, 4.1770e-01, 4.0820e-01, 3.9900e-01, 3.9010e-01, 3.8150e-01, 3.7320e-01, 3.6510e-01, 3.5730e-01, 3.4980e-01, 3.4250e-01, 3.3540e-01, 3.2850e-01, 3.2180e-01, 3.1540e-01, 3.0910e-01, 3.0310e-01, 2.9720e-01, 2.9140e-01, 2.8590e-01, 2.8050e-01, 2.7530e-01, 2.7020e-01, 2.6530e-01, 2.6050e-01, 2.5580e-01, 2.5130e-01, 2.4690e-01, 2.4260e-01, 2.3840e-01, 2.3440e-01, 2.3040e-01, 2.2660e-01, 2.2280e-01, 2.1920e-01, 2.1560e-01, 2.1220e-01, 2.0880e-01, 2.0550e-01, 2.0230e-01, 1.9920e-01, 1.9610e-01, 1.9310e-01, 1.9020e-01, 1.8730e-01, 1.8460e-01, 1.8180e-01, 1.7920e-01, 1.7660e-01, 1.7400e-01, 1.7160e-01, 1.6910e-01, 1.6670e-01, 1.6440e-01, 1.6210e-01, 1.5990e-01, 1.5770e-01, 1.5560e-01, 1.5350e-01, 1.5140e-01, 1.4940e-01, 1.4740e-01, 1.4550e-01, 1.4360e-01, 1.4180e-01, 1.3990e-01, 1.3810e-01, 1.3640e-01, 1.3470e-01, 1.3300e-01, 1.3130e-01, 1.2970e-01, 1.2810e-01, 1.2650e-01, 1.2500e-01, 1.2340e-01, 1.2200e-01, 1.2050e-01, 1.1910e-01, 1.1760e-01, 1.1630e-01, 1.1490e-01, 1.1360e-01, 1.1220e-01, 1.1090e-01, 1.0970e-01, 1.0840e-01, 1.0720e-01, 1.0600e-01, 1.0480e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8000e-02, 9.6900e-02, 9.5900e-02, 9.4800e-02, 9.3800e-02, 9.2800e-02, 9.1800e-02, 9.0900e-02, 8.9900e-02, 8.9000e-02, 8.8000e-02, 8.7100e-02, 8.6200e-02, 8.5300e-02, 8.4500e-02, 8.3600e-02, 8.2700e-02, 8.1900e-02, 8.1100e-02, 8.0300e-02, 7.9500e-02, 7.8700e-02, 7.7900e-02, 7.7100e-02, 7.6400e-02, 7.5600e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2800e-02, 7.2100e-02, 7.1400e-02, 7.0700e-02, 7.0000e-02, 6.9400e-02, 6.8700e-02, 6.8100e-02, 6.7500e-02, 6.6900e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3300e-02, 6.2700e-02, 6.2200e-02, 6.1600e-02, 6.1100e-02, 6.0500e-02, 6.0000e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.8000e-02, 5.7500e-02, 5.7000e-02, 5.6500e-02, 5.6000e-02, 5.5500e-02, 5.5100e-02, 5.4600e-02, 5.4200e-02, 5.3700e-02, 5.3300e-02, 5.2800e-02, 5.2400e-02, 5.2000e-02, 5.1600e-02}); + } + break; + case 83: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.3000e+01, 8.2664e+01, 8.1703e+01, 8.0240e+01, 7.8435e+01, 7.6438e+01, 7.4361e+01, 7.2274e+01, 7.0212e+01, 6.8191e+01, 6.6221e+01, 6.4305e+01, 6.2445e+01, 6.0642e+01, 5.8895e+01, 5.7207e+01, 5.5578e+01, 5.4011e+01, 5.2505e+01, 5.1060e+01, 4.9675e+01, 4.8348e+01, 4.7078e+01, 4.5863e+01, 4.4699e+01, 4.3583e+01, 4.2513e+01, 4.1485e+01, 4.0496e+01, 3.9544e+01, 3.8624e+01, 3.7736e+01, 3.6875e+01, 3.6041e+01, 3.5231e+01, 3.4444e+01, 3.3678e+01, 3.2931e+01, 3.2204e+01, 3.1495e+01, 3.0804e+01, 3.0130e+01, 2.9473e+01, 2.8832e+01, 2.8208e+01, 2.7601e+01, 2.7009e+01, 2.6434e+01, 2.5875e+01, 2.5333e+01, 2.4807e+01, 2.4297e+01, 2.3804e+01, 2.3327e+01, 2.2865e+01, 2.2420e+01, 2.1991e+01, 2.1578e+01, 2.1179e+01, 2.0796e+01, 2.0427e+01, 2.0074e+01, 1.9734e+01, 1.9408e+01, 1.9095e+01, 1.8795e+01, 1.8508e+01, 1.8232e+01, 1.7968e+01, 1.7714e+01, 1.7471e+01, 1.7239e+01, 1.7015e+01, 1.6801e+01, 1.6595e+01, 1.6397e+01, 1.6206e+01, 1.6023e+01, 1.5846e+01, 1.5675e+01, 1.5510e+01, 1.5350e+01, 1.5195e+01, 1.5045e+01, 1.4899e+01, 1.4756e+01, 1.4617e+01, 1.4481e+01, 1.4348e+01, 1.4218e+01, 1.4090e+01, 1.3964e+01, 1.3840e+01, 1.3718e+01, 1.3598e+01, 1.3479e+01, 1.3360e+01, 1.3243e+01, 1.3127e+01, 1.3012e+01, 1.2897e+01, 1.2783e+01, 1.2670e+01, 1.2557e+01, 1.2444e+01, 1.2332e+01, 1.2221e+01, 1.2110e+01, 1.1998e+01, 1.1887e+01, 1.1777e+01, 1.1667e+01, 1.1557e+01, 1.1448e+01, 1.1338e+01, 1.1229e+01, 1.1120e+01, 1.1012e+01, 1.0905e+01, 1.0798e+01, 1.0690e+01, 1.0584e+01, 1.0478e+01, 1.0373e+01, 1.0268e+01, 1.0164e+01, 1.0061e+01, 9.9580e+00, 9.8560e+00, 9.7550e+00, 9.6547e+00, 9.5552e+00, 9.4566e+00, 9.3590e+00, 9.2622e+00, 9.1664e+00, 9.0716e+00, 8.9777e+00, 8.8850e+00, 8.7934e+00, 8.7030e+00, 8.6136e+00, 8.5254e+00, 8.4382e+00, 8.3521e+00, 8.2673e+00, 8.1836e+00, 8.1012e+00, 8.0202e+00, 7.9405e+00, 7.8620e+00, 7.7846e+00, 7.7082e+00, 7.6329e+00, 7.5590e+00, 7.4865e+00, 7.4155e+00, 7.3459e+00, 7.2775e+00, 7.2101e+00, 7.1437e+00, 7.0784e+00, 7.0142e+00, 6.9514e+00, 6.8900e+00, 6.8301e+00, 6.7716e+00, 6.7142e+00, 6.6576e+00, 6.6017e+00, 6.5467e+00, 6.4929e+00, 6.4404e+00, 6.3893e+00, 6.3396e+00, 6.2911e+00, 6.2436e+00, 6.1969e+00, 6.1507e+00, 6.1051e+00, 6.0603e+00, 6.0166e+00, 5.9742e+00, 5.9331e+00, 5.8933e+00, 5.8544e+00, 5.8162e+00, 5.7785e+00, 5.7412e+00, 5.7042e+00, 5.6678e+00, 5.6323e+00, 5.5979e+00, 5.5648e+00, 5.5329e+00, 5.5017e+00, 5.4711e+00, 5.4407e+00, 5.4105e+00, 5.3805e+00, 5.3508e+00, 5.3215e+00, 5.2931e+00, 5.2656e+00, 5.2393e+00, 5.2141e+00, 5.1893e+00, 5.1648e+00, 5.1402e+00, 5.1157e+00, 5.0911e+00, 5.0667e+00, 5.0426e+00, 5.0189e+00, 4.9960e+00, 4.9743e+00, 4.9535e+00, 4.9334e+00, 4.9133e+00, 4.8930e+00, 4.8725e+00, 4.8519e+00, 4.8313e+00, 4.8106e+00, 4.7901e+00, 4.7698e+00, 4.7505e+00, 4.7321e+00, 4.7148e+00, 4.6978e+00, 4.6807e+00, 4.6632e+00, 4.6454e+00, 4.6275e+00, 4.6094e+00, 4.5911e+00, 4.5727e+00, 4.5543e+00, 4.5366e+00, 4.5198e+00, 4.5039e+00}); + feg = Vctr_cpu({1.3020e+01, 1.2863e+01, 1.2417e+01, 1.1743e+01, 1.0926e+01, 1.0052e+01, 9.1896e+00, 8.3826e+00, 7.6518e+00, 7.0011e+00, 6.4255e+00, 5.9167e+00, 5.4661e+00, 5.0661e+00, 4.7095e+00, 4.3899e+00, 4.1019e+00, 3.8412e+00, 3.6042e+00, 3.3881e+00, 3.1904e+00, 3.0090e+00, 2.8421e+00, 2.6883e+00, 2.5464e+00, 2.4151e+00, 2.2935e+00, 2.1808e+00, 2.0761e+00, 1.9787e+00, 1.8881e+00, 1.8037e+00, 1.7249e+00, 1.6513e+00, 1.5824e+00, 1.5179e+00, 1.4574e+00, 1.4005e+00, 1.3471e+00, 1.2967e+00, 1.2492e+00, 1.2044e+00, 1.1620e+00, 1.1219e+00, 1.0838e+00, 1.0476e+00, 1.0133e+00, 9.8060e-01, 9.4940e-01, 9.1970e-01, 8.9140e-01, 8.6430e-01, 8.3830e-01, 8.1350e-01, 7.8970e-01, 7.6690e-01, 7.4500e-01, 7.2390e-01, 7.0370e-01, 6.8430e-01, 6.6560e-01, 6.4760e-01, 6.3030e-01, 6.1360e-01, 5.9750e-01, 5.8190e-01, 5.6700e-01, 5.5250e-01, 5.3860e-01, 5.2510e-01, 5.1210e-01, 4.9960e-01, 4.8740e-01, 4.7570e-01, 4.6440e-01, 4.5340e-01, 4.4280e-01, 4.3260e-01, 4.2270e-01, 4.1310e-01, 4.0380e-01, 3.9480e-01, 3.8620e-01, 3.7770e-01, 3.6960e-01, 3.6170e-01, 3.5410e-01, 3.4670e-01, 3.3950e-01, 3.3250e-01, 3.2580e-01, 3.1920e-01, 3.1290e-01, 3.0670e-01, 3.0080e-01, 2.9500e-01, 2.8940e-01, 2.8390e-01, 2.7860e-01, 2.7350e-01, 2.6850e-01, 2.6360e-01, 2.5890e-01, 2.5430e-01, 2.4980e-01, 2.4550e-01, 2.4120e-01, 2.3710e-01, 2.3310e-01, 2.2920e-01, 2.2540e-01, 2.2170e-01, 2.1810e-01, 2.1460e-01, 2.1120e-01, 2.0780e-01, 2.0460e-01, 2.0140e-01, 1.9830e-01, 1.9520e-01, 1.9230e-01, 1.8940e-01, 1.8660e-01, 1.8380e-01, 1.8110e-01, 1.7850e-01, 1.7590e-01, 1.7340e-01, 1.7100e-01, 1.6850e-01, 1.6620e-01, 1.6390e-01, 1.6160e-01, 1.5940e-01, 1.5730e-01, 1.5510e-01, 1.5310e-01, 1.5100e-01, 1.4900e-01, 1.4710e-01, 1.4520e-01, 1.4330e-01, 1.4140e-01, 1.3960e-01, 1.3790e-01, 1.3610e-01, 1.3440e-01, 1.3270e-01, 1.3110e-01, 1.2950e-01, 1.2790e-01, 1.2630e-01, 1.2480e-01, 1.2330e-01, 1.2180e-01, 1.2040e-01, 1.1890e-01, 1.1750e-01, 1.1620e-01, 1.1480e-01, 1.1350e-01, 1.1220e-01, 1.1090e-01, 1.0960e-01, 1.0840e-01, 1.0710e-01, 1.0590e-01, 1.0470e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.5900e-02, 9.4900e-02, 9.3900e-02, 9.2900e-02, 9.1900e-02, 9.0900e-02, 9.0000e-02, 8.9000e-02, 8.8100e-02, 8.7200e-02, 8.6300e-02, 8.5400e-02, 8.4600e-02, 8.3700e-02, 8.2900e-02, 8.2000e-02, 8.1200e-02, 8.0400e-02, 7.9600e-02, 7.8800e-02, 7.8000e-02, 7.7300e-02, 7.6500e-02, 7.5800e-02, 7.5100e-02, 7.4300e-02, 7.3600e-02, 7.2900e-02, 7.2200e-02, 7.1600e-02, 7.0900e-02, 7.0200e-02, 6.9600e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7000e-02, 6.6400e-02, 6.5800e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3500e-02, 6.2900e-02, 6.2400e-02, 6.1800e-02, 6.1300e-02, 6.0700e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02, 5.7200e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5300e-02, 5.4800e-02, 5.4400e-02, 5.3900e-02, 5.3500e-02, 5.3000e-02, 5.2600e-02, 5.2200e-02}); + } + break; + case 84: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.4000e+01, 8.3683e+01, 8.2768e+01, 8.1352e+01, 7.9566e+01, 7.7544e+01, 7.5403e+01, 7.3227e+01, 7.1074e+01, 6.8975e+01, 6.6946e+01, 6.4992e+01, 6.3111e+01, 6.1301e+01, 5.9559e+01, 5.7880e+01, 5.6263e+01, 5.4706e+01, 5.3207e+01, 5.1765e+01, 5.0379e+01, 4.9047e+01, 4.7769e+01, 4.6542e+01, 4.5365e+01, 4.4235e+01, 4.3150e+01, 4.2107e+01, 4.1104e+01, 4.0138e+01, 3.9207e+01, 3.8308e+01, 3.7439e+01, 3.6597e+01, 3.5782e+01, 3.4990e+01, 3.4220e+01, 3.3471e+01, 3.2742e+01, 3.2032e+01, 3.1340e+01, 3.0665e+01, 3.0007e+01, 2.9365e+01, 2.8740e+01, 2.8130e+01, 2.7536e+01, 2.6957e+01, 2.6394e+01, 2.5847e+01, 2.5315e+01, 2.4799e+01, 2.4298e+01, 2.3813e+01, 2.3343e+01, 2.2888e+01, 2.2449e+01, 2.2024e+01, 2.1615e+01, 2.1220e+01, 2.0840e+01, 2.0474e+01, 2.0122e+01, 1.9784e+01, 1.9458e+01, 1.9146e+01, 1.8846e+01, 1.8559e+01, 1.8282e+01, 1.8018e+01, 1.7764e+01, 1.7520e+01, 1.7286e+01, 1.7061e+01, 1.6846e+01, 1.6639e+01, 1.6440e+01, 1.6248e+01, 1.6063e+01, 1.5886e+01, 1.5714e+01, 1.5548e+01, 1.5388e+01, 1.5232e+01, 1.5082e+01, 1.4935e+01, 1.4793e+01, 1.4654e+01, 1.4519e+01, 1.4386e+01, 1.4257e+01, 1.4130e+01, 1.4005e+01, 1.3882e+01, 1.3761e+01, 1.3642e+01, 1.3524e+01, 1.3407e+01, 1.3292e+01, 1.3178e+01, 1.3064e+01, 1.2952e+01, 1.2840e+01, 1.2729e+01, 1.2618e+01, 1.2508e+01, 1.2398e+01, 1.2289e+01, 1.2180e+01, 1.2071e+01, 1.1962e+01, 1.1854e+01, 1.1746e+01, 1.1639e+01, 1.1532e+01, 1.1425e+01, 1.1318e+01, 1.1211e+01, 1.1105e+01, 1.1000e+01, 1.0895e+01, 1.0790e+01, 1.0685e+01, 1.0580e+01, 1.0477e+01, 1.0374e+01, 1.0272e+01, 1.0170e+01, 1.0069e+01, 9.9676e+00, 9.8673e+00, 9.7679e+00, 9.6697e+00, 9.5724e+00, 9.4760e+00, 9.3801e+00, 9.2847e+00, 9.1900e+00, 9.0962e+00, 9.0039e+00, 8.9129e+00, 8.8232e+00, 8.7345e+00, 8.6464e+00, 8.5589e+00, 8.4721e+00, 8.3866e+00, 8.3026e+00, 8.2204e+00, 8.1396e+00, 8.0600e+00, 7.9812e+00, 7.9030e+00, 7.8255e+00, 7.7490e+00, 7.6740e+00, 7.6008e+00, 7.5295e+00, 7.4596e+00, 7.3909e+00, 7.3229e+00, 7.2553e+00, 7.1884e+00, 7.1224e+00, 7.0580e+00, 6.9955e+00, 6.9348e+00, 6.8758e+00, 6.8180e+00, 6.7608e+00, 6.7040e+00, 6.6475e+00, 6.5916e+00, 6.5370e+00, 6.4839e+00, 6.4328e+00, 6.3835e+00, 6.3356e+00, 6.2887e+00, 6.2422e+00, 6.1958e+00, 6.1495e+00, 6.1036e+00, 6.0586e+00, 6.0152e+00, 5.9735e+00, 5.9337e+00, 5.8952e+00, 5.8578e+00, 5.8208e+00, 5.7838e+00, 5.7465e+00, 5.7092e+00, 5.6722e+00, 5.6362e+00, 5.6016e+00, 5.5688e+00, 5.5375e+00, 5.5075e+00, 5.4783e+00, 5.4494e+00, 5.4202e+00, 5.3906e+00, 5.3605e+00, 5.3303e+00, 5.3008e+00, 5.2724e+00, 5.2456e+00, 5.2203e+00, 5.1963e+00, 5.1732e+00, 5.1506e+00, 5.1278e+00, 5.1045e+00, 5.0805e+00, 5.0557e+00, 5.0308e+00, 5.0063e+00, 4.9829e+00, 4.9609e+00, 4.9403e+00, 4.9209e+00, 4.9023e+00, 4.8842e+00, 4.8660e+00, 4.8473e+00, 4.8278e+00, 4.8072e+00, 4.7859e+00, 4.7645e+00, 4.7436e+00, 4.7238e+00, 4.7053e+00, 4.6881e+00, 4.6720e+00, 4.6565e+00, 4.6414e+00, 4.6261e+00, 4.6104e+00, 4.5936e+00, 4.5757e+00}); + feg = Vctr_cpu({1.2261e+01, 1.2141e+01, 1.1796e+01, 1.1268e+01, 1.0613e+01, 9.8886e+00, 9.1451e+00, 8.4190e+00, 7.7342e+00, 7.1032e+00, 6.5306e+00, 6.0158e+00, 5.5550e+00, 5.1434e+00, 4.7753e+00, 4.4455e+00, 4.1490e+00, 3.8816e+00, 3.6395e+00, 3.4194e+00, 3.2187e+00, 3.0351e+00, 2.8666e+00, 2.7115e+00, 2.5686e+00, 2.4364e+00, 2.3141e+00, 2.2006e+00, 2.0952e+00, 1.9972e+00, 1.9059e+00, 1.8207e+00, 1.7412e+00, 1.6669e+00, 1.5973e+00, 1.5321e+00, 1.4709e+00, 1.4134e+00, 1.3593e+00, 1.3084e+00, 1.2603e+00, 1.2150e+00, 1.1721e+00, 1.1315e+00, 1.0930e+00, 1.0565e+00, 1.0219e+00, 9.8890e-01, 9.5740e-01, 9.2750e-01, 8.9890e-01, 8.7160e-01, 8.4550e-01, 8.2050e-01, 7.9660e-01, 7.7360e-01, 7.5160e-01, 7.3050e-01, 7.1020e-01, 6.9060e-01, 6.7180e-01, 6.5380e-01, 6.3640e-01, 6.1960e-01, 6.0340e-01, 5.8780e-01, 5.7280e-01, 5.5830e-01, 5.4420e-01, 5.3070e-01, 5.1760e-01, 5.0500e-01, 4.9280e-01, 4.8100e-01, 4.6960e-01, 4.5860e-01, 4.4790e-01, 4.3760e-01, 4.2760e-01, 4.1790e-01, 4.0860e-01, 3.9950e-01, 3.9080e-01, 3.8230e-01, 3.7400e-01, 3.6610e-01, 3.5830e-01, 3.5080e-01, 3.4360e-01, 3.3650e-01, 3.2970e-01, 3.2310e-01, 3.1670e-01, 3.1050e-01, 3.0440e-01, 2.9850e-01, 2.9280e-01, 2.8730e-01, 2.8190e-01, 2.7670e-01, 2.7160e-01, 2.6670e-01, 2.6190e-01, 2.5730e-01, 2.5270e-01, 2.4830e-01, 2.4400e-01, 2.3990e-01, 2.3580e-01, 2.3180e-01, 2.2800e-01, 2.2420e-01, 2.2060e-01, 2.1700e-01, 2.1350e-01, 2.1010e-01, 2.0680e-01, 2.0360e-01, 2.0050e-01, 1.9740e-01, 1.9440e-01, 1.9150e-01, 1.8860e-01, 1.8580e-01, 1.8310e-01, 1.8040e-01, 1.7780e-01, 1.7530e-01, 1.7280e-01, 1.7040e-01, 1.6800e-01, 1.6560e-01, 1.6340e-01, 1.6110e-01, 1.5890e-01, 1.5680e-01, 1.5470e-01, 1.5260e-01, 1.5060e-01, 1.4860e-01, 1.4670e-01, 1.4480e-01, 1.4290e-01, 1.4110e-01, 1.3930e-01, 1.3760e-01, 1.3580e-01, 1.3410e-01, 1.3250e-01, 1.3080e-01, 1.2920e-01, 1.2770e-01, 1.2610e-01, 1.2460e-01, 1.2310e-01, 1.2170e-01, 1.2020e-01, 1.1880e-01, 1.1740e-01, 1.1600e-01, 1.1470e-01, 1.1340e-01, 1.1210e-01, 1.1080e-01, 1.0950e-01, 1.0830e-01, 1.0710e-01, 1.0590e-01, 1.0470e-01, 1.0360e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.4900e-02, 9.3900e-02, 9.2900e-02, 9.2000e-02, 9.1000e-02, 9.0100e-02, 8.9100e-02, 8.8200e-02, 8.7300e-02, 8.6400e-02, 8.5500e-02, 8.4700e-02, 8.3800e-02, 8.3000e-02, 8.2100e-02, 8.1300e-02, 8.0500e-02, 7.9700e-02, 7.9000e-02, 7.8200e-02, 7.7400e-02, 7.6700e-02, 7.5900e-02, 7.5200e-02, 7.4500e-02, 7.3800e-02, 7.3100e-02, 7.2400e-02, 7.1700e-02, 7.1000e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8400e-02, 6.7800e-02, 6.7200e-02, 6.6600e-02, 6.6000e-02, 6.5400e-02, 6.4800e-02, 6.4200e-02, 6.3700e-02, 6.3100e-02, 6.2600e-02, 6.2000e-02, 6.1500e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.6900e-02, 5.6400e-02, 5.5900e-02, 5.5500e-02, 5.5000e-02, 5.4600e-02, 5.4100e-02, 5.3700e-02, 5.3200e-02, 5.2800e-02}); + } + break; + case 85: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.5000e+01, 8.4653e+01, 8.3656e+01, 8.2130e+01, 8.0232e+01, 7.8118e+01, 7.5914e+01, 7.3710e+01, 7.1557e+01, 6.9479e+01, 6.7483e+01, 6.5568e+01, 6.3726e+01, 6.1950e+01, 6.0236e+01, 5.8577e+01, 5.6973e+01, 5.5421e+01, 5.3920e+01, 5.2471e+01, 5.1074e+01, 4.9729e+01, 4.8435e+01, 4.7191e+01, 4.5996e+01, 4.4850e+01, 4.3749e+01, 4.2692e+01, 4.1677e+01, 4.0700e+01, 3.9760e+01, 3.8853e+01, 3.7979e+01, 3.7133e+01, 3.6314e+01, 3.5520e+01, 3.4750e+01, 3.4001e+01, 3.3272e+01, 3.2562e+01, 3.1871e+01, 3.1196e+01, 3.0538e+01, 2.9896e+01, 2.9269e+01, 2.8658e+01, 2.8062e+01, 2.7480e+01, 2.6913e+01, 2.6361e+01, 2.5824e+01, 2.5301e+01, 2.4793e+01, 2.4300e+01, 2.3822e+01, 2.3358e+01, 2.2908e+01, 2.2474e+01, 2.2053e+01, 2.1648e+01, 2.1256e+01, 2.0878e+01, 2.0514e+01, 2.0163e+01, 1.9826e+01, 1.9502e+01, 1.9190e+01, 1.8890e+01, 1.8602e+01, 1.8326e+01, 1.8061e+01, 1.7806e+01, 1.7562e+01, 1.7327e+01, 1.7102e+01, 1.6885e+01, 1.6677e+01, 1.6478e+01, 1.6285e+01, 1.6100e+01, 1.5922e+01, 1.5749e+01, 1.5583e+01, 1.5422e+01, 1.5267e+01, 1.5116e+01, 1.4970e+01, 1.4828e+01, 1.4689e+01, 1.4554e+01, 1.4422e+01, 1.4294e+01, 1.4167e+01, 1.4043e+01, 1.3922e+01, 1.3802e+01, 1.3684e+01, 1.3568e+01, 1.3453e+01, 1.3339e+01, 1.3227e+01, 1.3115e+01, 1.3005e+01, 1.2895e+01, 1.2786e+01, 1.2677e+01, 1.2569e+01, 1.2461e+01, 1.2354e+01, 1.2247e+01, 1.2140e+01, 1.2034e+01, 1.1928e+01, 1.1823e+01, 1.1718e+01, 1.1612e+01, 1.1507e+01, 1.1402e+01, 1.1298e+01, 1.1194e+01, 1.1091e+01, 1.0987e+01, 1.0884e+01, 1.0781e+01, 1.0678e+01, 1.0576e+01, 1.0475e+01, 1.0375e+01, 1.0274e+01, 1.0174e+01, 1.0075e+01, 9.9754e+00, 9.8771e+00, 9.7799e+00, 9.6837e+00, 9.5882e+00, 9.4931e+00, 9.3984e+00, 9.3042e+00, 9.2110e+00, 9.1191e+00, 9.0286e+00, 8.9393e+00, 8.8508e+00, 8.7629e+00, 8.6754e+00, 8.5887e+00, 8.5031e+00, 8.4190e+00, 8.3366e+00, 8.2556e+00, 8.1757e+00, 8.0965e+00, 8.0179e+00, 7.9399e+00, 7.8628e+00, 7.7873e+00, 7.7135e+00, 7.6414e+00, 7.5709e+00, 7.5014e+00, 7.4325e+00, 7.3641e+00, 7.2963e+00, 7.2295e+00, 7.1641e+00, 7.1006e+00, 7.0390e+00, 6.9789e+00, 6.9200e+00, 6.8617e+00, 6.8038e+00, 6.7463e+00, 6.6893e+00, 6.6336e+00, 6.5794e+00, 6.5272e+00, 6.4767e+00, 6.4276e+00, 6.3794e+00, 6.3317e+00, 6.2842e+00, 6.2368e+00, 6.1898e+00, 6.1438e+00, 6.0992e+00, 6.0564e+00, 6.0154e+00, 5.9758e+00, 5.9371e+00, 5.8988e+00, 5.8607e+00, 5.8225e+00, 5.7842e+00, 5.7463e+00, 5.7093e+00, 5.6738e+00, 5.6400e+00, 5.6077e+00, 5.5766e+00, 5.5463e+00, 5.5162e+00, 5.4861e+00, 5.4557e+00, 5.4250e+00, 5.3942e+00, 5.3639e+00, 5.3348e+00, 5.3072e+00, 5.2812e+00, 5.2564e+00, 5.2324e+00, 5.2087e+00, 5.1851e+00, 5.1612e+00, 5.1367e+00, 5.1117e+00, 5.0864e+00, 5.0615e+00, 5.0376e+00, 5.0151e+00, 4.9941e+00, 4.9742e+00, 4.9549e+00, 4.9360e+00, 4.9171e+00, 4.8979e+00, 4.8781e+00, 4.8575e+00, 4.8362e+00, 4.8148e+00, 4.7937e+00, 4.7737e+00, 4.7551e+00, 4.7378e+00, 4.7214e+00, 4.7054e+00, 4.6897e+00, 4.6738e+00, 4.6576e+00, 4.6409e+00}); + feg = Vctr_cpu({1.3447e+01, 1.3296e+01, 1.2865e+01, 1.2212e+01, 1.1412e+01, 1.0542e+01, 9.6645e+00, 8.8231e+00, 8.0436e+00, 7.3378e+00, 6.7078e+00, 6.1499e+00, 5.6575e+00, 5.2229e+00, 4.8384e+00, 4.4970e+00, 4.1924e+00, 3.9194e+00, 3.6734e+00, 3.4505e+00, 3.2479e+00, 3.0627e+00, 2.8930e+00, 2.7370e+00, 2.5930e+00, 2.4600e+00, 2.3368e+00, 2.2224e+00, 2.1161e+00, 2.0171e+00, 1.9249e+00, 1.8388e+00, 1.7584e+00, 1.6832e+00, 1.6128e+00, 1.5467e+00, 1.4848e+00, 1.4266e+00, 1.3718e+00, 1.3202e+00, 1.2716e+00, 1.2257e+00, 1.1823e+00, 1.1412e+00, 1.1023e+00, 1.0655e+00, 1.0304e+00, 9.9710e-01, 9.6540e-01, 9.3520e-01, 9.0640e-01, 8.7890e-01, 8.5260e-01, 8.2750e-01, 8.0340e-01, 7.8030e-01, 7.5820e-01, 7.3700e-01, 7.1650e-01, 6.9690e-01, 6.7810e-01, 6.5990e-01, 6.4240e-01, 6.2560e-01, 6.0930e-01, 5.9370e-01, 5.7850e-01, 5.6400e-01, 5.4990e-01, 5.3630e-01, 5.2310e-01, 5.1040e-01, 4.9820e-01, 4.8630e-01, 4.7480e-01, 4.6370e-01, 4.5300e-01, 4.4260e-01, 4.3250e-01, 4.2280e-01, 4.1330e-01, 4.0420e-01, 3.9530e-01, 3.8680e-01, 3.7850e-01, 3.7040e-01, 3.6260e-01, 3.5500e-01, 3.4770e-01, 3.4060e-01, 3.3370e-01, 3.2700e-01, 3.2050e-01, 3.1420e-01, 3.0800e-01, 3.0210e-01, 2.9630e-01, 2.9070e-01, 2.8530e-01, 2.8000e-01, 2.7480e-01, 2.6990e-01, 2.6500e-01, 2.6030e-01, 2.5570e-01, 2.5120e-01, 2.4690e-01, 2.4260e-01, 2.3850e-01, 2.3450e-01, 2.3060e-01, 2.2680e-01, 2.2310e-01, 2.1950e-01, 2.1590e-01, 2.1250e-01, 2.0910e-01, 2.0590e-01, 2.0270e-01, 1.9960e-01, 1.9650e-01, 1.9360e-01, 1.9070e-01, 1.8790e-01, 1.8510e-01, 1.8240e-01, 1.7980e-01, 1.7720e-01, 1.7470e-01, 1.7220e-01, 1.6980e-01, 1.6740e-01, 1.6510e-01, 1.6280e-01, 1.6060e-01, 1.5850e-01, 1.5630e-01, 1.5420e-01, 1.5220e-01, 1.5020e-01, 1.4830e-01, 1.4630e-01, 1.4440e-01, 1.4260e-01, 1.4080e-01, 1.3900e-01, 1.3730e-01, 1.3560e-01, 1.3390e-01, 1.3220e-01, 1.3060e-01, 1.2900e-01, 1.2750e-01, 1.2590e-01, 1.2440e-01, 1.2300e-01, 1.2150e-01, 1.2010e-01, 1.1870e-01, 1.1730e-01, 1.1590e-01, 1.1460e-01, 1.1330e-01, 1.1200e-01, 1.1070e-01, 1.0950e-01, 1.0830e-01, 1.0700e-01, 1.0590e-01, 1.0470e-01, 1.0350e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8100e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3000e-02, 9.2000e-02, 9.1100e-02, 9.0100e-02, 8.9200e-02, 8.8300e-02, 8.7400e-02, 8.6500e-02, 8.5600e-02, 8.4800e-02, 8.3900e-02, 8.3100e-02, 8.2200e-02, 8.1400e-02, 8.0600e-02, 7.9900e-02, 7.9100e-02, 7.8300e-02, 7.7500e-02, 7.6800e-02, 7.6100e-02, 7.5300e-02, 7.4600e-02, 7.3900e-02, 7.3200e-02, 7.2500e-02, 7.1900e-02, 7.1200e-02, 7.0500e-02, 6.9900e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7400e-02, 6.6800e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4400e-02, 6.3800e-02, 6.3300e-02, 6.2700e-02, 6.2200e-02, 6.1600e-02, 6.1100e-02, 6.0600e-02, 6.0100e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.8000e-02, 5.7600e-02, 5.7100e-02, 5.6600e-02, 5.6100e-02, 5.5700e-02, 5.5200e-02, 5.4800e-02, 5.4300e-02, 5.3900e-02, 5.3400e-02}); + } + break; + case 86: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.6000e+01, 8.5652e+01, 8.4649e+01, 8.3106e+01, 8.1173e+01, 7.9008e+01, 7.6742e+01, 7.4473e+01, 7.2261e+01, 7.0137e+01, 6.8110e+01, 6.6178e+01, 6.4332e+01, 6.2563e+01, 6.0861e+01, 5.9219e+01, 5.7630e+01, 5.6092e+01, 5.4603e+01, 5.3160e+01, 5.1766e+01, 5.0418e+01, 4.9117e+01, 4.7864e+01, 4.6658e+01, 4.5498e+01, 4.4382e+01, 4.3310e+01, 4.2279e+01, 4.1288e+01, 4.0335e+01, 3.9416e+01, 3.8531e+01, 3.7676e+01, 3.6850e+01, 3.6050e+01, 3.5275e+01, 3.4523e+01, 3.3792e+01, 3.3080e+01, 3.2388e+01, 3.1713e+01, 3.1054e+01, 3.0412e+01, 2.9785e+01, 2.9173e+01, 2.8576e+01, 2.7993e+01, 2.7424e+01, 2.6869e+01, 2.6328e+01, 2.5801e+01, 2.5288e+01, 2.4790e+01, 2.4305e+01, 2.3833e+01, 2.3376e+01, 2.2933e+01, 2.2504e+01, 2.2088e+01, 2.1686e+01, 2.1298e+01, 2.0923e+01, 2.0561e+01, 2.0212e+01, 1.9876e+01, 1.9553e+01, 1.9241e+01, 1.8942e+01, 1.8654e+01, 1.8378e+01, 1.8112e+01, 1.7857e+01, 1.7611e+01, 1.7376e+01, 1.7150e+01, 1.6932e+01, 1.6723e+01, 1.6522e+01, 1.6329e+01, 1.6142e+01, 1.5963e+01, 1.5790e+01, 1.5623e+01, 1.5462e+01, 1.5306e+01, 1.5155e+01, 1.5008e+01, 1.4866e+01, 1.4727e+01, 1.4592e+01, 1.4461e+01, 1.4332e+01, 1.4207e+01, 1.4084e+01, 1.3963e+01, 1.3844e+01, 1.3727e+01, 1.3612e+01, 1.3498e+01, 1.3386e+01, 1.3275e+01, 1.3165e+01, 1.3056e+01, 1.2948e+01, 1.2841e+01, 1.2735e+01, 1.2629e+01, 1.2523e+01, 1.2418e+01, 1.2313e+01, 1.2209e+01, 1.2105e+01, 1.2001e+01, 1.1898e+01, 1.1794e+01, 1.1691e+01, 1.1588e+01, 1.1486e+01, 1.1384e+01, 1.1282e+01, 1.1180e+01, 1.1078e+01, 1.0977e+01, 1.0876e+01, 1.0775e+01, 1.0676e+01, 1.0576e+01, 1.0477e+01, 1.0377e+01, 1.0278e+01, 1.0180e+01, 1.0083e+01, 9.9867e+00, 9.8908e+00, 9.7953e+00, 9.7000e+00, 9.6053e+00, 9.5113e+00, 9.4184e+00, 9.3267e+00, 9.2361e+00, 9.1461e+00, 9.0567e+00, 8.9677e+00, 8.8793e+00, 8.7919e+00, 8.7059e+00, 8.6214e+00, 8.5381e+00, 8.4559e+00, 8.3744e+00, 8.2933e+00, 8.2128e+00, 8.1333e+00, 8.0551e+00, 7.9785e+00, 7.9037e+00, 7.8302e+00, 7.7577e+00, 7.6859e+00, 7.6145e+00, 7.5437e+00, 7.4738e+00, 7.4054e+00, 7.3388e+00, 7.2739e+00, 7.2106e+00, 7.1484e+00, 7.0869e+00, 7.0258e+00, 6.9650e+00, 6.9049e+00, 6.8460e+00, 6.7887e+00, 6.7332e+00, 6.6794e+00, 6.6271e+00, 6.5758e+00, 6.5249e+00, 6.4742e+00, 6.4237e+00, 6.3737e+00, 6.3247e+00, 6.2772e+00, 6.2314e+00, 6.1874e+00, 6.1449e+00, 6.1033e+00, 6.0623e+00, 6.0214e+00, 5.9804e+00, 5.9394e+00, 5.8988e+00, 5.8593e+00, 5.8212e+00, 5.7849e+00, 5.7501e+00, 5.7166e+00, 5.6840e+00, 5.6518e+00, 5.6194e+00, 5.5867e+00, 5.5537e+00, 5.5207e+00, 5.4885e+00, 5.4574e+00, 5.4279e+00, 5.3999e+00, 5.3732e+00, 5.3475e+00, 5.3223e+00, 5.2971e+00, 5.2716e+00, 5.2454e+00, 5.2186e+00, 5.1918e+00, 5.1655e+00, 5.1402e+00, 5.1164e+00, 5.0940e+00, 5.0728e+00, 5.0524e+00, 5.0326e+00, 5.0128e+00, 4.9926e+00, 4.9717e+00, 4.9499e+00, 4.9275e+00, 4.9051e+00, 4.8832e+00, 4.8625e+00, 4.8430e+00, 4.8249e+00, 4.8077e+00, 4.7912e+00, 4.7750e+00, 4.7589e+00, 4.7424e+00, 4.7251e+00, 4.7067e+00}); + feg = Vctr_cpu({1.3471e+01, 1.3331e+01, 1.2930e+01, 1.2315e+01, 1.1553e+01, 1.0711e+01, 9.8477e+00, 9.0082e+00, 8.2203e+00, 7.4995e+00, 6.8508e+00, 6.2733e+00, 5.7621e+00, 5.3106e+00, 4.9115e+00, 4.5580e+00, 4.2437e+00, 3.9629e+00, 3.7109e+00, 3.4835e+00, 3.2774e+00, 3.0898e+00, 2.9181e+00, 2.7606e+00, 2.6156e+00, 2.4816e+00, 2.3576e+00, 2.2425e+00, 2.1355e+00, 2.0359e+00, 1.9430e+00, 1.8563e+00, 1.7752e+00, 1.6993e+00, 1.6281e+00, 1.5614e+00, 1.4988e+00, 1.4399e+00, 1.3845e+00, 1.3323e+00, 1.2831e+00, 1.2367e+00, 1.1928e+00, 1.1513e+00, 1.1119e+00, 1.0746e+00, 1.0392e+00, 1.0056e+00, 9.7360e-01, 9.4310e-01, 9.1400e-01, 8.8630e-01, 8.5980e-01, 8.3450e-01, 8.1020e-01, 7.8700e-01, 7.6470e-01, 7.4330e-01, 7.2280e-01, 7.0310e-01, 6.8410e-01, 6.6590e-01, 6.4830e-01, 6.3140e-01, 6.1510e-01, 5.9930e-01, 5.8410e-01, 5.6950e-01, 5.5530e-01, 5.4170e-01, 5.2850e-01, 5.1570e-01, 5.0340e-01, 4.9140e-01, 4.7990e-01, 4.6870e-01, 4.5790e-01, 4.4740e-01, 4.3730e-01, 4.2750e-01, 4.1800e-01, 4.0880e-01, 3.9990e-01, 3.9120e-01, 3.8280e-01, 3.7470e-01, 3.6680e-01, 3.5920e-01, 3.5180e-01, 3.4460e-01, 3.3760e-01, 3.3080e-01, 3.2420e-01, 3.1790e-01, 3.1170e-01, 3.0570e-01, 2.9980e-01, 2.9410e-01, 2.8860e-01, 2.8330e-01, 2.7810e-01, 2.7300e-01, 2.6810e-01, 2.6330e-01, 2.5860e-01, 2.5410e-01, 2.4970e-01, 2.4540e-01, 2.4120e-01, 2.3720e-01, 2.3320e-01, 2.2930e-01, 2.2560e-01, 2.2190e-01, 2.1830e-01, 2.1490e-01, 2.1150e-01, 2.0820e-01, 2.0490e-01, 2.0180e-01, 1.9870e-01, 1.9570e-01, 1.9280e-01, 1.8990e-01, 1.8710e-01, 1.8440e-01, 1.8170e-01, 1.7910e-01, 1.7650e-01, 1.7400e-01, 1.7160e-01, 1.6920e-01, 1.6680e-01, 1.6460e-01, 1.6230e-01, 1.6010e-01, 1.5800e-01, 1.5590e-01, 1.5380e-01, 1.5180e-01, 1.4980e-01, 1.4790e-01, 1.4600e-01, 1.4410e-01, 1.4230e-01, 1.4050e-01, 1.3870e-01, 1.3700e-01, 1.3530e-01, 1.3360e-01, 1.3200e-01, 1.3040e-01, 1.2880e-01, 1.2720e-01, 1.2570e-01, 1.2420e-01, 1.2280e-01, 1.2130e-01, 1.1990e-01, 1.1850e-01, 1.1710e-01, 1.1580e-01, 1.1450e-01, 1.1320e-01, 1.1190e-01, 1.1060e-01, 1.0940e-01, 1.0820e-01, 1.0700e-01, 1.0580e-01, 1.0460e-01, 1.0350e-01, 1.0240e-01, 1.0130e-01, 1.0020e-01, 9.9100e-02, 9.8100e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3000e-02, 9.2100e-02, 9.1100e-02, 9.0200e-02, 8.9300e-02, 8.8300e-02, 8.7400e-02, 8.6600e-02, 8.5700e-02, 8.4800e-02, 8.4000e-02, 8.3200e-02, 8.2300e-02, 8.1500e-02, 8.0700e-02, 8.0000e-02, 7.9200e-02, 7.8400e-02, 7.7700e-02, 7.6900e-02, 7.6200e-02, 7.5500e-02, 7.4800e-02, 7.4100e-02, 7.3400e-02, 7.2700e-02, 7.2000e-02, 7.1300e-02, 7.0700e-02, 7.0000e-02, 6.9400e-02, 6.8800e-02, 6.8100e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5700e-02, 6.5200e-02, 6.4600e-02, 6.4000e-02, 6.3500e-02, 6.2900e-02, 6.2300e-02, 6.1800e-02, 6.1300e-02, 6.0800e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02, 5.7300e-02, 5.6800e-02, 5.6300e-02, 5.5800e-02, 5.5400e-02, 5.4900e-02, 5.4500e-02, 5.4000e-02}); + } + break; + case 87: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.7000e+01, 8.6547e+01, 8.5330e+01, 8.3638e+01, 8.1692e+01, 7.9601e+01, 7.7427e+01, 7.5222e+01, 7.3034e+01, 7.0901e+01, 6.8846e+01, 6.6880e+01, 6.5003e+01, 6.3210e+01, 6.1493e+01, 5.9845e+01, 5.8257e+01, 5.6724e+01, 5.5242e+01, 5.3807e+01, 5.2418e+01, 5.1075e+01, 4.9775e+01, 4.8520e+01, 4.7309e+01, 4.6142e+01, 4.5017e+01, 4.3934e+01, 4.2891e+01, 4.1888e+01, 4.0922e+01, 3.9991e+01, 3.9095e+01, 3.8230e+01, 3.7394e+01, 3.6586e+01, 3.5804e+01, 3.5046e+01, 3.4310e+01, 3.3595e+01, 3.2899e+01, 3.2222e+01, 3.1562e+01, 3.0919e+01, 3.0291e+01, 2.9678e+01, 2.9079e+01, 2.8495e+01, 2.7925e+01, 2.7368e+01, 2.6825e+01, 2.6295e+01, 2.5778e+01, 2.5275e+01, 2.4785e+01, 2.4308e+01, 2.3844e+01, 2.3394e+01, 2.2957e+01, 2.2533e+01, 2.2122e+01, 2.1725e+01, 2.1340e+01, 2.0968e+01, 2.0609e+01, 2.0263e+01, 1.9928e+01, 1.9606e+01, 1.9296e+01, 1.8997e+01, 1.8709e+01, 1.8433e+01, 1.8167e+01, 1.7911e+01, 1.7665e+01, 1.7428e+01, 1.7201e+01, 1.6983e+01, 1.6772e+01, 1.6570e+01, 1.6376e+01, 1.6189e+01, 1.6008e+01, 1.5834e+01, 1.5666e+01, 1.5504e+01, 1.5348e+01, 1.5195e+01, 1.5048e+01, 1.4906e+01, 1.4767e+01, 1.4633e+01, 1.4501e+01, 1.4372e+01, 1.4247e+01, 1.4125e+01, 1.4005e+01, 1.3886e+01, 1.3770e+01, 1.3656e+01, 1.3544e+01, 1.3433e+01, 1.3324e+01, 1.3215e+01, 1.3107e+01, 1.3001e+01, 1.2895e+01, 1.2791e+01, 1.2687e+01, 1.2582e+01, 1.2479e+01, 1.2376e+01, 1.2274e+01, 1.2173e+01, 1.2072e+01, 1.1970e+01, 1.1868e+01, 1.1767e+01, 1.1666e+01, 1.1566e+01, 1.1467e+01, 1.1367e+01, 1.1266e+01, 1.1166e+01, 1.1067e+01, 1.0968e+01, 1.0870e+01, 1.0772e+01, 1.0674e+01, 1.0576e+01, 1.0477e+01, 1.0380e+01, 1.0284e+01, 1.0189e+01, 1.0094e+01, 9.9991e+00, 9.9044e+00, 9.8096e+00, 9.7157e+00, 9.6232e+00, 9.5317e+00, 9.4409e+00, 9.3509e+00, 9.2617e+00, 9.1724e+00, 9.0831e+00, 8.9950e+00, 8.9087e+00, 8.8236e+00, 8.7393e+00, 8.6560e+00, 8.5738e+00, 8.4920e+00, 8.4102e+00, 8.3290e+00, 8.2497e+00, 8.1723e+00, 8.0959e+00, 8.0204e+00, 7.9462e+00, 7.8732e+00, 7.8005e+00, 7.7277e+00, 7.6558e+00, 7.5858e+00, 7.5179e+00, 7.4512e+00, 7.3853e+00, 7.3207e+00, 7.2574e+00, 7.1948e+00, 7.1321e+00, 7.0696e+00, 7.0085e+00, 6.9497e+00, 6.8926e+00, 6.8366e+00, 6.7813e+00, 6.7273e+00, 6.6746e+00, 6.6225e+00, 6.5700e+00, 6.5175e+00, 6.4663e+00, 6.4172e+00, 6.3701e+00, 6.3240e+00, 6.2786e+00, 6.2342e+00, 6.1910e+00, 6.1487e+00, 6.1062e+00, 6.0631e+00, 6.0203e+00, 5.9789e+00, 5.9397e+00, 5.9021e+00, 5.8654e+00, 5.8293e+00, 5.7940e+00, 5.7598e+00, 5.7262e+00, 5.6924e+00, 5.6579e+00, 5.6229e+00, 5.5889e+00, 5.5569e+00, 5.5267e+00, 5.4976e+00, 5.4689e+00, 5.4408e+00, 5.4135e+00, 5.3870e+00, 5.3607e+00, 5.3337e+00, 5.3058e+00, 5.2774e+00, 5.2498e+00, 5.2239e+00, 5.1999e+00, 5.1768e+00, 5.1542e+00, 5.1320e+00, 5.1103e+00, 5.0893e+00, 5.0686e+00, 5.0474e+00, 5.0252e+00, 5.0018e+00, 4.9783e+00, 4.9556e+00, 4.9348e+00, 4.9155e+00, 4.8970e+00, 4.8789e+00, 4.8610e+00, 4.8435e+00, 4.8265e+00, 4.8098e+00, 4.7925e+00, 4.7741e+00}); + feg = Vctr_cpu({1.7903e+01, 1.7362e+01, 1.5989e+01, 1.4304e+01, 1.2705e+01, 1.1334e+01, 1.0183e+01, 9.2046e+00, 8.3564e+00, 7.6110e+00, 6.9518e+00, 6.3676e+00, 5.8497e+00, 5.3906e+00, 4.9834e+00, 4.6217e+00, 4.2995e+00, 4.0117e+00, 3.7535e+00, 3.5210e+00, 3.3107e+00, 3.1196e+00, 2.9452e+00, 2.7855e+00, 2.6387e+00, 2.5034e+00, 2.3783e+00, 2.2622e+00, 2.1545e+00, 2.0541e+00, 1.9606e+00, 1.8732e+00, 1.7915e+00, 1.7150e+00, 1.6433e+00, 1.5760e+00, 1.5127e+00, 1.4533e+00, 1.3973e+00, 1.3446e+00, 1.2948e+00, 1.2479e+00, 1.2035e+00, 1.1615e+00, 1.1217e+00, 1.0840e+00, 1.0482e+00, 1.0142e+00, 9.8190e-01, 9.5110e-01, 9.2170e-01, 8.9370e-01, 8.6700e-01, 8.4150e-01, 8.1700e-01, 7.9360e-01, 7.7120e-01, 7.4970e-01, 7.2900e-01, 7.0920e-01, 6.9010e-01, 6.7180e-01, 6.5410e-01, 6.3710e-01, 6.2070e-01, 6.0490e-01, 5.8960e-01, 5.7490e-01, 5.6070e-01, 5.4700e-01, 5.3370e-01, 5.2090e-01, 5.0850e-01, 4.9650e-01, 4.8490e-01, 4.7360e-01, 4.6280e-01, 4.5220e-01, 4.4200e-01, 4.3210e-01, 4.2260e-01, 4.1330e-01, 4.0430e-01, 3.9560e-01, 3.8710e-01, 3.7890e-01, 3.7100e-01, 3.6330e-01, 3.5580e-01, 3.4850e-01, 3.4150e-01, 3.3460e-01, 3.2800e-01, 3.2160e-01, 3.1530e-01, 3.0920e-01, 3.0330e-01, 2.9760e-01, 2.9200e-01, 2.8660e-01, 2.8130e-01, 2.7620e-01, 2.7120e-01, 2.6630e-01, 2.6160e-01, 2.5700e-01, 2.5260e-01, 2.4820e-01, 2.4400e-01, 2.3990e-01, 2.3580e-01, 2.3190e-01, 2.2810e-01, 2.2440e-01, 2.2080e-01, 2.1730e-01, 2.1380e-01, 2.1050e-01, 2.0720e-01, 2.0400e-01, 2.0090e-01, 1.9780e-01, 1.9480e-01, 1.9190e-01, 1.8910e-01, 1.8630e-01, 1.8360e-01, 1.8100e-01, 1.7840e-01, 1.7590e-01, 1.7340e-01, 1.7100e-01, 1.6860e-01, 1.6630e-01, 1.6400e-01, 1.6180e-01, 1.5960e-01, 1.5750e-01, 1.5540e-01, 1.5340e-01, 1.5140e-01, 1.4940e-01, 1.4750e-01, 1.4560e-01, 1.4370e-01, 1.4190e-01, 1.4010e-01, 1.3840e-01, 1.3670e-01, 1.3500e-01, 1.3330e-01, 1.3170e-01, 1.3010e-01, 1.2860e-01, 1.2700e-01, 1.2550e-01, 1.2400e-01, 1.2260e-01, 1.2120e-01, 1.1970e-01, 1.1840e-01, 1.1700e-01, 1.1570e-01, 1.1440e-01, 1.1310e-01, 1.1180e-01, 1.1050e-01, 1.0930e-01, 1.0810e-01, 1.0690e-01, 1.0570e-01, 1.0460e-01, 1.0350e-01, 1.0230e-01, 1.0120e-01, 1.0020e-01, 9.9100e-02, 9.8100e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3000e-02, 9.2100e-02, 9.1100e-02, 9.0200e-02, 8.9300e-02, 8.8400e-02, 8.7500e-02, 8.6600e-02, 8.5800e-02, 8.4900e-02, 8.4100e-02, 8.3300e-02, 8.2400e-02, 8.1600e-02, 8.0800e-02, 8.0100e-02, 7.9300e-02, 7.8500e-02, 7.7800e-02, 7.7000e-02, 7.6300e-02, 7.5600e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2800e-02, 7.2100e-02, 7.1500e-02, 7.0800e-02, 7.0200e-02, 6.9500e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.5900e-02, 6.5300e-02, 6.4700e-02, 6.4200e-02, 6.3600e-02, 6.3100e-02, 6.2500e-02, 6.2000e-02, 6.1400e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.7000e-02, 5.6500e-02, 5.6000e-02, 5.5600e-02, 5.5100e-02, 5.4700e-02}); + } + break; + case 88: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.8000e+01, 8.7496e+01, 8.6146e+01, 8.4302e+01, 8.2257e+01, 8.0153e+01, 7.8031e+01, 7.5899e+01, 7.3771e+01, 7.1671e+01, 6.9620e+01, 6.7638e+01, 6.5735e+01, 6.3913e+01, 6.2171e+01, 6.0504e+01, 5.8904e+01, 5.7366e+01, 5.5883e+01, 5.4452e+01, 5.3067e+01, 5.1728e+01, 5.0432e+01, 4.9178e+01, 4.7965e+01, 4.6793e+01, 4.5662e+01, 4.4571e+01, 4.3518e+01, 4.2503e+01, 4.1526e+01, 4.0583e+01, 3.9674e+01, 3.8797e+01, 3.7951e+01, 3.7133e+01, 3.6342e+01, 3.5576e+01, 3.4833e+01, 3.4113e+01, 3.3413e+01, 3.2732e+01, 3.2069e+01, 3.1423e+01, 3.0794e+01, 3.0179e+01, 2.9580e+01, 2.8994e+01, 2.8423e+01, 2.7864e+01, 2.7319e+01, 2.6787e+01, 2.6268e+01, 2.5761e+01, 2.5267e+01, 2.4786e+01, 2.4317e+01, 2.3861e+01, 2.3417e+01, 2.2986e+01, 2.2568e+01, 2.2162e+01, 2.1769e+01, 2.1388e+01, 2.1019e+01, 2.0663e+01, 2.0318e+01, 1.9986e+01, 1.9665e+01, 1.9355e+01, 1.9056e+01, 1.8769e+01, 1.8492e+01, 1.8226e+01, 1.7969e+01, 1.7722e+01, 1.7485e+01, 1.7257e+01, 1.7037e+01, 1.6825e+01, 1.6622e+01, 1.6427e+01, 1.6238e+01, 1.6055e+01, 1.5881e+01, 1.5712e+01, 1.5549e+01, 1.5391e+01, 1.5238e+01, 1.5090e+01, 1.4948e+01, 1.4809e+01, 1.4672e+01, 1.4540e+01, 1.4412e+01, 1.4288e+01, 1.4166e+01, 1.4045e+01, 1.3927e+01, 1.3812e+01, 1.3699e+01, 1.3589e+01, 1.3479e+01, 1.3369e+01, 1.3261e+01, 1.3155e+01, 1.3051e+01, 1.2948e+01, 1.2845e+01, 1.2741e+01, 1.2639e+01, 1.2537e+01, 1.2437e+01, 1.2338e+01, 1.2239e+01, 1.2138e+01, 1.2037e+01, 1.1938e+01, 1.1839e+01, 1.1742e+01, 1.1645e+01, 1.1547e+01, 1.1447e+01, 1.1348e+01, 1.1251e+01, 1.1154e+01, 1.1058e+01, 1.0962e+01, 1.0866e+01, 1.0768e+01, 1.0671e+01, 1.0575e+01, 1.0480e+01, 1.0386e+01, 1.0293e+01, 1.0199e+01, 1.0105e+01, 1.0010e+01, 9.9165e+00, 9.8242e+00, 9.7334e+00, 9.6436e+00, 9.5545e+00, 9.4655e+00, 9.3759e+00, 9.2859e+00, 9.1970e+00, 9.1101e+00, 9.0247e+00, 8.9404e+00, 8.8572e+00, 8.7747e+00, 8.6920e+00, 8.6089e+00, 8.5262e+00, 8.4454e+00, 8.3668e+00, 8.2895e+00, 8.2132e+00, 8.1382e+00, 8.0641e+00, 7.9899e+00, 7.9152e+00, 7.8412e+00, 7.7693e+00, 7.6996e+00, 7.6314e+00, 7.5640e+00, 7.4980e+00, 7.4332e+00, 7.3689e+00, 7.3041e+00, 7.2392e+00, 7.1758e+00, 7.1149e+00, 7.0560e+00, 6.9980e+00, 6.9408e+00, 6.8850e+00, 6.8306e+00, 6.7765e+00, 6.7219e+00, 6.6669e+00, 6.6133e+00, 6.5622e+00, 6.5132e+00, 6.4652e+00, 6.4177e+00, 6.3711e+00, 6.3262e+00, 6.2821e+00, 6.2378e+00, 6.1925e+00, 6.1474e+00, 6.1039e+00, 6.0630e+00, 6.0239e+00, 5.9853e+00, 5.9470e+00, 5.9097e+00, 5.8737e+00, 5.8388e+00, 5.8035e+00, 5.7671e+00, 5.7302e+00, 5.6943e+00, 5.6609e+00, 5.6295e+00, 5.5991e+00, 5.5687e+00, 5.5385e+00, 5.5094e+00, 5.4816e+00, 5.4543e+00, 5.4263e+00, 5.3970e+00, 5.3669e+00, 5.3379e+00, 5.3111e+00, 5.2864e+00, 5.2626e+00, 5.2386e+00, 5.2147e+00, 5.1914e+00, 5.1692e+00, 5.1479e+00, 5.1262e+00, 5.1032e+00, 5.0788e+00, 5.0540e+00, 5.0305e+00, 5.0093e+00, 4.9899e+00, 4.9711e+00, 4.9519e+00, 4.9326e+00, 4.9138e+00, 4.8960e+00, 4.8789e+00, 4.8616e+00, 4.8430e+00}); + feg = Vctr_cpu({1.9909e+01, 1.9311e+01, 1.7747e+01, 1.5736e+01, 1.3746e+01, 1.2019e+01, 1.0604e+01, 9.4573e+00, 8.5138e+00, 7.7200e+00, 7.0383e+00, 6.4440e+00, 5.9210e+00, 5.4578e+00, 5.0463e+00, 4.6797e+00, 4.3523e+00, 4.0591e+00, 3.7959e+00, 3.5587e+00, 3.3443e+00, 3.1497e+00, 2.9724e+00, 2.8103e+00, 2.6616e+00, 2.5247e+00, 2.3983e+00, 2.2813e+00, 2.1727e+00, 2.0716e+00, 1.9774e+00, 1.8895e+00, 1.8072e+00, 1.7302e+00, 1.6579e+00, 1.5901e+00, 1.5264e+00, 1.4664e+00, 1.4099e+00, 1.3567e+00, 1.3065e+00, 1.2590e+00, 1.2142e+00, 1.1717e+00, 1.1315e+00, 1.0934e+00, 1.0572e+00, 1.0229e+00, 9.9020e-01, 9.5910e-01, 9.2950e-01, 9.0120e-01, 8.7420e-01, 8.4850e-01, 8.2380e-01, 8.0020e-01, 7.7760e-01, 7.5600e-01, 7.3520e-01, 7.1520e-01, 6.9600e-01, 6.7760e-01, 6.5980e-01, 6.4270e-01, 6.2620e-01, 6.1030e-01, 5.9500e-01, 5.8020e-01, 5.6590e-01, 5.5210e-01, 5.3880e-01, 5.2590e-01, 5.1340e-01, 5.0140e-01, 4.8970e-01, 4.7840e-01, 4.6750e-01, 4.5690e-01, 4.4670e-01, 4.3670e-01, 4.2710e-01, 4.1770e-01, 4.0870e-01, 3.9990e-01, 3.9140e-01, 3.8310e-01, 3.7510e-01, 3.6740e-01, 3.5980e-01, 3.5250e-01, 3.4540e-01, 3.3850e-01, 3.3180e-01, 3.2520e-01, 3.1890e-01, 3.1280e-01, 3.0680e-01, 3.0100e-01, 2.9540e-01, 2.8990e-01, 2.8450e-01, 2.7930e-01, 2.7430e-01, 2.6940e-01, 2.6460e-01, 2.6000e-01, 2.5540e-01, 2.5100e-01, 2.4670e-01, 2.4260e-01, 2.3850e-01, 2.3450e-01, 2.3070e-01, 2.2690e-01, 2.2320e-01, 2.1970e-01, 2.1620e-01, 2.1280e-01, 2.0950e-01, 2.0620e-01, 2.0310e-01, 2.0000e-01, 1.9700e-01, 1.9400e-01, 1.9110e-01, 1.8830e-01, 1.8560e-01, 1.8290e-01, 1.8030e-01, 1.7770e-01, 1.7520e-01, 1.7280e-01, 1.7040e-01, 1.6800e-01, 1.6570e-01, 1.6350e-01, 1.6130e-01, 1.5910e-01, 1.5700e-01, 1.5490e-01, 1.5290e-01, 1.5090e-01, 1.4900e-01, 1.4710e-01, 1.4520e-01, 1.4340e-01, 1.4160e-01, 1.3980e-01, 1.3810e-01, 1.3640e-01, 1.3470e-01, 1.3310e-01, 1.3140e-01, 1.2990e-01, 1.2830e-01, 1.2680e-01, 1.2530e-01, 1.2380e-01, 1.2240e-01, 1.2100e-01, 1.1960e-01, 1.1820e-01, 1.1690e-01, 1.1550e-01, 1.1420e-01, 1.1290e-01, 1.1170e-01, 1.1040e-01, 1.0920e-01, 1.0800e-01, 1.0680e-01, 1.0570e-01, 1.0450e-01, 1.0340e-01, 1.0230e-01, 1.0120e-01, 1.0010e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0200e-02, 8.9300e-02, 8.8400e-02, 8.7600e-02, 8.6700e-02, 8.5800e-02, 8.5000e-02, 8.4100e-02, 8.3300e-02, 8.2500e-02, 8.1700e-02, 8.0900e-02, 8.0100e-02, 7.9400e-02, 7.8600e-02, 7.7900e-02, 7.7100e-02, 7.6400e-02, 7.5700e-02, 7.5000e-02, 7.4300e-02, 7.3600e-02, 7.2900e-02, 7.2300e-02, 7.1600e-02, 7.1000e-02, 7.0300e-02, 6.9700e-02, 6.9000e-02, 6.8400e-02, 6.7800e-02, 6.7200e-02, 6.6600e-02, 6.6000e-02, 6.5500e-02, 6.4900e-02, 6.4300e-02, 6.3800e-02, 6.3200e-02, 6.2700e-02, 6.2100e-02, 6.1600e-02, 6.1100e-02, 6.0600e-02, 6.0100e-02, 5.9600e-02, 5.9100e-02, 5.8600e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02, 5.6700e-02, 5.6200e-02, 5.5700e-02, 5.5300e-02}); + } + break; + case 89: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({8.9000e+01, 8.8479e+01, 8.7073e+01, 8.5128e+01, 8.2966e+01, 8.0765e+01, 7.8585e+01, 7.6436e+01, 7.4318e+01, 7.2239e+01, 7.0210e+01, 6.8244e+01, 6.6350e+01, 6.4531e+01, 6.2789e+01, 6.1119e+01, 5.9517e+01, 5.7977e+01, 5.6494e+01, 5.5062e+01, 5.3678e+01, 5.2340e+01, 5.1044e+01, 4.9789e+01, 4.8575e+01, 4.7400e+01, 4.6264e+01, 4.5166e+01, 4.4106e+01, 4.3084e+01, 4.2097e+01, 4.1145e+01, 4.0227e+01, 3.9342e+01, 3.8486e+01, 3.7660e+01, 3.6862e+01, 3.6090e+01, 3.5341e+01, 3.4616e+01, 3.3911e+01, 3.3227e+01, 3.2561e+01, 3.1913e+01, 3.1282e+01, 3.0666e+01, 3.0065e+01, 2.9478e+01, 2.8905e+01, 2.8345e+01, 2.7798e+01, 2.7264e+01, 2.6742e+01, 2.6233e+01, 2.5736e+01, 2.5251e+01, 2.4778e+01, 2.4317e+01, 2.3868e+01, 2.3431e+01, 2.3006e+01, 2.2593e+01, 2.2193e+01, 2.1804e+01, 2.1427e+01, 2.1061e+01, 2.0708e+01, 2.0366e+01, 2.0035e+01, 1.9716e+01, 1.9408e+01, 1.9110e+01, 1.8824e+01, 1.8547e+01, 1.8281e+01, 1.8025e+01, 1.7777e+01, 1.7540e+01, 1.7311e+01, 1.7091e+01, 1.6878e+01, 1.6674e+01, 1.6478e+01, 1.6289e+01, 1.6106e+01, 1.5929e+01, 1.5760e+01, 1.5596e+01, 1.5438e+01, 1.5284e+01, 1.5135e+01, 1.4992e+01, 1.4853e+01, 1.4718e+01, 1.4585e+01, 1.4456e+01, 1.4331e+01, 1.4210e+01, 1.4091e+01, 1.3973e+01, 1.3858e+01, 1.3745e+01, 1.3635e+01, 1.3527e+01, 1.3419e+01, 1.3313e+01, 1.3207e+01, 1.3103e+01, 1.3001e+01, 1.2900e+01, 1.2800e+01, 1.2699e+01, 1.2598e+01, 1.2498e+01, 1.2400e+01, 1.2303e+01, 1.2206e+01, 1.2108e+01, 1.2010e+01, 1.1912e+01, 1.1815e+01, 1.1720e+01, 1.1625e+01, 1.1529e+01, 1.1433e+01, 1.1335e+01, 1.1239e+01, 1.1144e+01, 1.1050e+01, 1.0957e+01, 1.0863e+01, 1.0768e+01, 1.0672e+01, 1.0577e+01, 1.0483e+01, 1.0391e+01, 1.0300e+01, 1.0209e+01, 1.0117e+01, 1.0025e+01, 9.9321e+00, 9.8403e+00, 9.7505e+00, 9.6625e+00, 9.5753e+00, 9.4881e+00, 9.4006e+00, 9.3129e+00, 9.2249e+00, 9.1378e+00, 9.0529e+00, 8.9701e+00, 8.8886e+00, 8.8074e+00, 8.7263e+00, 8.6452e+00, 8.5640e+00, 8.4830e+00, 8.4036e+00, 8.3267e+00, 8.2520e+00, 8.1783e+00, 8.1048e+00, 8.0317e+00, 7.9590e+00, 7.8862e+00, 7.8136e+00, 7.7424e+00, 7.6740e+00, 7.6079e+00, 7.5430e+00, 7.4785e+00, 7.4144e+00, 7.3510e+00, 7.2878e+00, 7.2246e+00, 7.1618e+00, 7.1010e+00, 7.0431e+00, 6.9873e+00, 6.9323e+00, 6.8775e+00, 6.8231e+00, 6.7696e+00, 6.7165e+00, 6.6631e+00, 6.6099e+00, 6.5583e+00, 6.5094e+00, 6.4630e+00, 6.4177e+00, 6.3725e+00, 6.3273e+00, 6.2830e+00, 6.2394e+00, 6.1959e+00, 6.1519e+00, 6.1081e+00, 6.0661e+00, 6.0268e+00, 5.9899e+00, 5.9538e+00, 5.9174e+00, 5.8809e+00, 5.8451e+00, 5.8101e+00, 5.7754e+00, 5.7400e+00, 5.7042e+00, 5.6693e+00, 5.6367e+00, 5.6067e+00, 5.5784e+00, 5.5501e+00, 5.5212e+00, 5.4921e+00, 5.4638e+00, 5.4363e+00, 5.4088e+00, 5.3804e+00, 5.3513e+00, 5.3228e+00, 5.2963e+00, 5.2724e+00, 5.2504e+00, 5.2286e+00, 5.2060e+00, 5.1827e+00, 5.1598e+00, 5.1376e+00, 5.1159e+00, 5.0936e+00, 5.0701e+00, 5.0460e+00, 5.0227e+00, 5.0014e+00, 4.9826e+00, 4.9655e+00, 4.9485e+00, 4.9304e+00, 4.9114e+00}); + feg = Vctr_cpu({2.0495e+01, 1.9937e+01, 1.8450e+01, 1.6474e+01, 1.4441e+01, 1.2614e+01, 1.1079e+01, 9.8190e+00, 8.7848e+00, 7.9241e+00, 7.1954e+00, 6.5688e+00, 6.0234e+00, 5.5444e+00, 5.1211e+00, 4.7452e+00, 4.4103e+00, 4.1107e+00, 3.8420e+00, 3.6000e+00, 3.3815e+00, 3.1834e+00, 3.0031e+00, 2.8384e+00, 2.6876e+00, 2.5489e+00, 2.4209e+00, 2.3026e+00, 2.1928e+00, 2.0907e+00, 1.9957e+00, 1.9069e+00, 1.8239e+00, 1.7462e+00, 1.6733e+00, 1.6049e+00, 1.5406e+00, 1.4800e+00, 1.4230e+00, 1.3692e+00, 1.3185e+00, 1.2705e+00, 1.2252e+00, 1.1823e+00, 1.1417e+00, 1.1031e+00, 1.0666e+00, 1.0318e+00, 9.9880e-01, 9.6740e-01, 9.3750e-01, 9.0890e-01, 8.8170e-01, 8.5570e-01, 8.3080e-01, 8.0700e-01, 7.8420e-01, 7.6240e-01, 7.4140e-01, 7.2130e-01, 7.0200e-01, 6.8340e-01, 6.6550e-01, 6.4830e-01, 6.3170e-01, 6.1580e-01, 6.0040e-01, 5.8550e-01, 5.7110e-01, 5.5730e-01, 5.4390e-01, 5.3090e-01, 5.1840e-01, 5.0630e-01, 4.9450e-01, 4.8320e-01, 4.7220e-01, 4.6150e-01, 4.5120e-01, 4.4120e-01, 4.3150e-01, 4.2210e-01, 4.1300e-01, 4.0420e-01, 3.9560e-01, 3.8730e-01, 3.7920e-01, 3.7140e-01, 3.6380e-01, 3.5640e-01, 3.4920e-01, 3.4220e-01, 3.3550e-01, 3.2890e-01, 3.2250e-01, 3.1630e-01, 3.1030e-01, 3.0440e-01, 2.9870e-01, 2.9310e-01, 2.8770e-01, 2.8250e-01, 2.7740e-01, 2.7240e-01, 2.6760e-01, 2.6290e-01, 2.5830e-01, 2.5390e-01, 2.4950e-01, 2.4530e-01, 2.4120e-01, 2.3710e-01, 2.3320e-01, 2.2940e-01, 2.2570e-01, 2.2210e-01, 2.1850e-01, 2.1510e-01, 2.1170e-01, 2.0850e-01, 2.0530e-01, 2.0210e-01, 1.9910e-01, 1.9610e-01, 1.9320e-01, 1.9030e-01, 1.8760e-01, 1.8480e-01, 1.8220e-01, 1.7960e-01, 1.7710e-01, 1.7460e-01, 1.7210e-01, 1.6980e-01, 1.6740e-01, 1.6520e-01, 1.6290e-01, 1.6080e-01, 1.5860e-01, 1.5650e-01, 1.5450e-01, 1.5250e-01, 1.5050e-01, 1.4860e-01, 1.4670e-01, 1.4480e-01, 1.4300e-01, 1.4120e-01, 1.3950e-01, 1.3780e-01, 1.3610e-01, 1.3440e-01, 1.3280e-01, 1.3120e-01, 1.2960e-01, 1.2810e-01, 1.2660e-01, 1.2510e-01, 1.2360e-01, 1.2220e-01, 1.2080e-01, 1.1940e-01, 1.1800e-01, 1.1670e-01, 1.1540e-01, 1.1410e-01, 1.1280e-01, 1.1160e-01, 1.1030e-01, 1.0910e-01, 1.0790e-01, 1.0680e-01, 1.0560e-01, 1.0450e-01, 1.0340e-01, 1.0230e-01, 1.0120e-01, 1.0010e-01, 9.9100e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7600e-02, 8.6700e-02, 8.5900e-02, 8.5000e-02, 8.4200e-02, 8.3400e-02, 8.2600e-02, 8.1800e-02, 8.1000e-02, 8.0200e-02, 7.9500e-02, 7.8700e-02, 7.8000e-02, 7.7200e-02, 7.6500e-02, 7.5800e-02, 7.5100e-02, 7.4400e-02, 7.3700e-02, 7.3100e-02, 7.2400e-02, 7.1700e-02, 7.1100e-02, 7.0400e-02, 6.9800e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7400e-02, 6.6800e-02, 6.6200e-02, 6.5600e-02, 6.5000e-02, 6.4500e-02, 6.3900e-02, 6.3400e-02, 6.2800e-02, 6.2300e-02, 6.1800e-02, 6.1200e-02, 6.0700e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7800e-02, 5.7300e-02, 5.6800e-02, 5.6400e-02, 5.5900e-02}); + } + break; + case 90: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.0000e+01, 8.9485e+01, 8.8076e+01, 8.6087e+01, 8.3834e+01, 8.1526e+01, 7.9255e+01, 7.7047e+01, 7.4903e+01, 7.2820e+01, 7.0800e+01, 6.8847e+01, 6.6965e+01, 6.5156e+01, 6.3419e+01, 6.1752e+01, 6.0151e+01, 5.8611e+01, 5.7128e+01, 5.5696e+01, 5.4313e+01, 5.2974e+01, 5.1677e+01, 5.0420e+01, 4.9203e+01, 4.8023e+01, 4.6882e+01, 4.5778e+01, 4.4710e+01, 4.3679e+01, 4.2683e+01, 4.1721e+01, 4.0793e+01, 3.9897e+01, 3.9033e+01, 3.8197e+01, 3.7390e+01, 3.6610e+01, 3.5855e+01, 3.5123e+01, 3.4413e+01, 3.3724e+01, 3.3055e+01, 3.2404e+01, 3.1769e+01, 3.1151e+01, 3.0549e+01, 2.9961e+01, 2.9386e+01, 2.8825e+01, 2.8277e+01, 2.7742e+01, 2.7218e+01, 2.6707e+01, 2.6207e+01, 2.5719e+01, 2.5243e+01, 2.4778e+01, 2.4325e+01, 2.3883e+01, 2.3452e+01, 2.3033e+01, 2.2626e+01, 2.2230e+01, 2.1845e+01, 2.1472e+01, 2.1110e+01, 2.0759e+01, 2.0420e+01, 2.0091e+01, 1.9773e+01, 1.9466e+01, 1.9170e+01, 1.8884e+01, 1.8608e+01, 1.8341e+01, 1.8085e+01, 1.7837e+01, 1.7599e+01, 1.7369e+01, 1.7148e+01, 1.6935e+01, 1.6730e+01, 1.6532e+01, 1.6341e+01, 1.6158e+01, 1.5981e+01, 1.5810e+01, 1.5645e+01, 1.5485e+01, 1.5332e+01, 1.5183e+01, 1.5038e+01, 1.4898e+01, 1.4761e+01, 1.4630e+01, 1.4502e+01, 1.4377e+01, 1.4254e+01, 1.4134e+01, 1.4017e+01, 1.3903e+01, 1.3792e+01, 1.3681e+01, 1.3572e+01, 1.3465e+01, 1.3360e+01, 1.3258e+01, 1.3156e+01, 1.3054e+01, 1.2953e+01, 1.2852e+01, 1.2753e+01, 1.2656e+01, 1.2560e+01, 1.2463e+01, 1.2366e+01, 1.2268e+01, 1.2172e+01, 1.2078e+01, 1.1984e+01, 1.1890e+01, 1.1795e+01, 1.1700e+01, 1.1604e+01, 1.1510e+01, 1.1417e+01, 1.1325e+01, 1.1232e+01, 1.1139e+01, 1.1044e+01, 1.0950e+01, 1.0857e+01, 1.0765e+01, 1.0674e+01, 1.0584e+01, 1.0493e+01, 1.0401e+01, 1.0308e+01, 1.0216e+01, 1.0126e+01, 1.0037e+01, 9.9494e+00, 9.8620e+00, 9.7742e+00, 9.6855e+00, 9.5964e+00, 9.5080e+00, 9.4214e+00, 9.3368e+00, 9.2536e+00, 9.1709e+00, 9.0884e+00, 9.0054e+00, 8.9219e+00, 8.8385e+00, 8.7566e+00, 8.6770e+00, 8.5994e+00, 8.5230e+00, 8.4472e+00, 8.3717e+00, 8.2960e+00, 8.2197e+00, 8.1438e+00, 8.0694e+00, 7.9976e+00, 7.9279e+00, 7.8595e+00, 7.7919e+00, 7.7250e+00, 7.6581e+00, 7.5910e+00, 7.5235e+00, 7.4570e+00, 7.3927e+00, 7.3310e+00, 7.2711e+00, 7.2123e+00, 7.1542e+00, 7.0968e+00, 7.0396e+00, 6.9822e+00, 6.9243e+00, 6.8671e+00, 6.8120e+00, 6.7596e+00, 6.7092e+00, 6.6598e+00, 6.6110e+00, 6.5630e+00, 6.5156e+00, 6.4682e+00, 6.4202e+00, 6.3719e+00, 6.3246e+00, 6.2796e+00, 6.2373e+00, 6.1966e+00, 6.1566e+00, 6.1170e+00, 6.0780e+00, 6.0398e+00, 6.0017e+00, 5.9629e+00, 5.9233e+00, 5.8841e+00, 5.8468e+00, 5.8121e+00, 5.7795e+00, 5.7477e+00, 5.7160e+00, 5.6846e+00, 5.6539e+00, 5.6239e+00, 5.5938e+00, 5.5626e+00, 5.5305e+00, 5.4986e+00, 5.4684e+00, 5.4408e+00, 5.4153e+00, 5.3906e+00, 5.3657e+00, 5.3407e+00, 5.3163e+00, 5.2926e+00, 5.2692e+00, 5.2450e+00, 5.2194e+00, 5.1930e+00, 5.1671e+00, 5.1432e+00, 5.1218e+00, 5.1021e+00, 5.0829e+00, 5.0632e+00, 5.0432e+00, 5.0236e+00, 5.0048e+00, 4.9863e+00}); + feg = Vctr_cpu({2.0189e+01, 1.9712e+01, 1.8420e+01, 1.6652e+01, 1.4758e+01, 1.2980e+01, 1.1430e+01, 1.0123e+01, 9.0334e+00, 8.1221e+00, 7.3523e+00, 6.6944e+00, 6.1257e+00, 5.6295e+00, 5.1934e+00, 4.8077e+00, 4.4650e+00, 4.1592e+00, 3.8852e+00, 3.6388e+00, 3.4165e+00, 3.2152e+00, 3.0321e+00, 2.8652e+00, 2.7123e+00, 2.5719e+00, 2.4425e+00, 2.3230e+00, 2.2121e+00, 2.1092e+00, 2.0133e+00, 1.9238e+00, 1.8402e+00, 1.7618e+00, 1.6884e+00, 1.6194e+00, 1.5545e+00, 1.4934e+00, 1.4359e+00, 1.3816e+00, 1.3304e+00, 1.2820e+00, 1.2362e+00, 1.1929e+00, 1.1518e+00, 1.1129e+00, 1.0759e+00, 1.0408e+00, 1.0074e+00, 9.7570e-01, 9.4540e-01, 9.1660e-01, 8.8910e-01, 8.6290e-01, 8.3780e-01, 8.1370e-01, 7.9080e-01, 7.6870e-01, 7.4760e-01, 7.2730e-01, 7.0790e-01, 6.8920e-01, 6.7120e-01, 6.5390e-01, 6.3720e-01, 6.2110e-01, 6.0560e-01, 5.9070e-01, 5.7620e-01, 5.6230e-01, 5.4880e-01, 5.3580e-01, 5.2320e-01, 5.1100e-01, 4.9930e-01, 4.8780e-01, 4.7680e-01, 4.6610e-01, 4.5570e-01, 4.4570e-01, 4.3590e-01, 4.2640e-01, 4.1730e-01, 4.0840e-01, 3.9980e-01, 3.9140e-01, 3.8320e-01, 3.7530e-01, 3.6770e-01, 3.6020e-01, 3.5300e-01, 3.4600e-01, 3.3920e-01, 3.3250e-01, 3.2610e-01, 3.1980e-01, 3.1370e-01, 3.0780e-01, 3.0200e-01, 2.9640e-01, 2.9100e-01, 2.8570e-01, 2.8050e-01, 2.7550e-01, 2.7060e-01, 2.6580e-01, 2.6120e-01, 2.5670e-01, 2.5230e-01, 2.4800e-01, 2.4380e-01, 2.3980e-01, 2.3580e-01, 2.3200e-01, 2.2820e-01, 2.2450e-01, 2.2090e-01, 2.1740e-01, 2.1400e-01, 2.1070e-01, 2.0750e-01, 2.0430e-01, 2.0120e-01, 1.9820e-01, 1.9520e-01, 1.9240e-01, 1.8950e-01, 1.8680e-01, 1.8410e-01, 1.8150e-01, 1.7890e-01, 1.7640e-01, 1.7390e-01, 1.7150e-01, 1.6920e-01, 1.6690e-01, 1.6460e-01, 1.6240e-01, 1.6020e-01, 1.5810e-01, 1.5610e-01, 1.5400e-01, 1.5200e-01, 1.5010e-01, 1.4820e-01, 1.4630e-01, 1.4440e-01, 1.4260e-01, 1.4090e-01, 1.3910e-01, 1.3740e-01, 1.3580e-01, 1.3410e-01, 1.3250e-01, 1.3090e-01, 1.2940e-01, 1.2780e-01, 1.2630e-01, 1.2490e-01, 1.2340e-01, 1.2200e-01, 1.2060e-01, 1.1920e-01, 1.1790e-01, 1.1650e-01, 1.1520e-01, 1.1400e-01, 1.1270e-01, 1.1140e-01, 1.1020e-01, 1.0900e-01, 1.0780e-01, 1.0670e-01, 1.0550e-01, 1.0440e-01, 1.0330e-01, 1.0220e-01, 1.0110e-01, 1.0010e-01, 9.9000e-02, 9.8000e-02, 9.7000e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7600e-02, 8.6800e-02, 8.5900e-02, 8.5100e-02, 8.4300e-02, 8.3500e-02, 8.2700e-02, 8.1900e-02, 8.1100e-02, 8.0300e-02, 7.9500e-02, 7.8800e-02, 7.8100e-02, 7.7300e-02, 7.6600e-02, 7.5900e-02, 7.5200e-02, 7.4500e-02, 7.3800e-02, 7.3200e-02, 7.2500e-02, 7.1800e-02, 7.1200e-02, 7.0600e-02, 6.9900e-02, 6.9300e-02, 6.8700e-02, 6.8100e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5700e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3500e-02, 6.3000e-02, 6.2400e-02, 6.1900e-02, 6.1400e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.8900e-02, 5.8400e-02, 5.7900e-02, 5.7400e-02, 5.7000e-02, 5.6500e-02}); + } + break; + case 91: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.1000e+01, 9.0503e+01, 8.9145e+01, 8.7234e+01, 8.5062e+01, 8.2810e+01, 8.0553e+01, 7.8315e+01, 7.6106e+01, 7.3937e+01, 7.1822e+01, 6.9774e+01, 6.7804e+01, 6.5918e+01, 6.4115e+01, 6.2395e+01, 6.0752e+01, 5.9181e+01, 5.7674e+01, 5.6226e+01, 5.4833e+01, 5.3488e+01, 5.2189e+01, 5.0933e+01, 4.9718e+01, 4.8543e+01, 4.7405e+01, 4.6305e+01, 4.5242e+01, 4.4214e+01, 4.3220e+01, 4.2261e+01, 4.1334e+01, 4.0439e+01, 3.9574e+01, 3.8739e+01, 3.7930e+01, 3.7148e+01, 3.6391e+01, 3.5657e+01, 3.4945e+01, 3.4254e+01, 3.3582e+01, 3.2928e+01, 3.2291e+01, 3.1670e+01, 3.1064e+01, 3.0473e+01, 2.9895e+01, 2.9331e+01, 2.8779e+01, 2.8240e+01, 2.7712e+01, 2.7197e+01, 2.6692e+01, 2.6199e+01, 2.5718e+01, 2.5247e+01, 2.4788e+01, 2.4340e+01, 2.3903e+01, 2.3477e+01, 2.3062e+01, 2.2659e+01, 2.2266e+01, 2.1885e+01, 2.1514e+01, 2.1154e+01, 2.0806e+01, 2.0468e+01, 2.0141e+01, 1.9825e+01, 1.9519e+01, 1.9223e+01, 1.8937e+01, 1.8661e+01, 1.8395e+01, 1.8139e+01, 1.7891e+01, 1.7652e+01, 1.7422e+01, 1.7201e+01, 1.6987e+01, 1.6781e+01, 1.6582e+01, 1.6391e+01, 1.6207e+01, 1.6029e+01, 1.5857e+01, 1.5691e+01, 1.5531e+01, 1.5377e+01, 1.5227e+01, 1.5082e+01, 1.4941e+01, 1.4805e+01, 1.4673e+01, 1.4544e+01, 1.4418e+01, 1.4295e+01, 1.4176e+01, 1.4060e+01, 1.3947e+01, 1.3835e+01, 1.3724e+01, 1.3616e+01, 1.3510e+01, 1.3406e+01, 1.3304e+01, 1.3202e+01, 1.3101e+01, 1.3001e+01, 1.2902e+01, 1.2806e+01, 1.2710e+01, 1.2614e+01, 1.2518e+01, 1.2422e+01, 1.2327e+01, 1.2233e+01, 1.2141e+01, 1.2048e+01, 1.1955e+01, 1.1861e+01, 1.1767e+01, 1.1674e+01, 1.1583e+01, 1.1492e+01, 1.1401e+01, 1.1309e+01, 1.1216e+01, 1.1123e+01, 1.1032e+01, 1.0941e+01, 1.0852e+01, 1.0762e+01, 1.0673e+01, 1.0582e+01, 1.0491e+01, 1.0400e+01, 1.0310e+01, 1.0223e+01, 1.0135e+01, 1.0049e+01, 9.9614e+00, 9.8735e+00, 9.7851e+00, 9.6972e+00, 9.6111e+00, 9.5267e+00, 9.4434e+00, 9.3606e+00, 9.2779e+00, 9.1950e+00, 9.1115e+00, 9.0281e+00, 8.9460e+00, 8.8661e+00, 8.7879e+00, 8.7107e+00, 8.6340e+00, 8.5577e+00, 8.4813e+00, 8.4045e+00, 8.3279e+00, 8.2528e+00, 8.1800e+00, 8.1092e+00, 8.0393e+00, 7.9702e+00, 7.9018e+00, 7.8338e+00, 7.7655e+00, 7.6969e+00, 7.6292e+00, 7.5637e+00, 7.5005e+00, 7.4389e+00, 7.3782e+00, 7.3181e+00, 7.2589e+00, 7.2002e+00, 7.1413e+00, 7.0820e+00, 7.0234e+00, 6.9668e+00, 6.9127e+00, 6.8605e+00, 6.8090e+00, 6.7581e+00, 6.7079e+00, 6.6587e+00, 6.6097e+00, 6.5601e+00, 6.5103e+00, 6.4615e+00, 6.4150e+00, 6.3709e+00, 6.3283e+00, 6.2863e+00, 6.2445e+00, 6.2035e+00, 6.1635e+00, 6.1238e+00, 6.0835e+00, 6.0425e+00, 6.0020e+00, 5.9632e+00, 5.9270e+00, 5.8927e+00, 5.8592e+00, 5.8256e+00, 5.7923e+00, 5.7599e+00, 5.7283e+00, 5.6968e+00, 5.6644e+00, 5.6312e+00, 5.5982e+00, 5.5668e+00, 5.5380e+00, 5.5111e+00, 5.4849e+00, 5.4585e+00, 5.4321e+00, 5.4062e+00, 5.3812e+00, 5.3566e+00, 5.3314e+00, 5.3050e+00, 5.2778e+00, 5.2512e+00, 5.2264e+00, 5.2040e+00, 5.1833e+00, 5.1630e+00, 5.1422e+00, 5.1212e+00, 5.1006e+00, 5.0808e+00, 5.0614e+00}); + feg = Vctr_cpu({1.9518e+01, 1.9039e+01, 1.7754e+01, 1.6024e+01, 1.4211e+01, 1.2545e+01, 1.1113e+01, 9.9133e+00, 8.9118e+00, 8.0669e+00, 7.3442e+00, 6.7176e+00, 6.1685e+00, 5.6835e+00, 5.2527e+00, 4.8684e+00, 4.5246e+00, 4.2162e+00, 3.9388e+00, 3.6887e+00, 3.4625e+00, 3.2573e+00, 3.0707e+00, 2.9004e+00, 2.7445e+00, 2.6014e+00, 2.4695e+00, 2.3478e+00, 2.2350e+00, 2.1304e+00, 2.0330e+00, 1.9422e+00, 1.8573e+00, 1.7779e+00, 1.7035e+00, 1.6337e+00, 1.5681e+00, 1.5063e+00, 1.4482e+00, 1.3934e+00, 1.3416e+00, 1.2927e+00, 1.2465e+00, 1.2027e+00, 1.1613e+00, 1.1220e+00, 1.0847e+00, 1.0493e+00, 1.0156e+00, 9.8360e-01, 9.5310e-01, 9.2400e-01, 8.9630e-01, 8.6980e-01, 8.4450e-01, 8.2030e-01, 7.9720e-01, 7.7500e-01, 7.5370e-01, 7.3330e-01, 7.1370e-01, 6.9490e-01, 6.7680e-01, 6.5940e-01, 6.4260e-01, 6.2640e-01, 6.1090e-01, 5.9580e-01, 5.8130e-01, 5.6730e-01, 5.5380e-01, 5.4070e-01, 5.2800e-01, 5.1580e-01, 5.0390e-01, 4.9250e-01, 4.8140e-01, 4.7060e-01, 4.6020e-01, 4.5010e-01, 4.4020e-01, 4.3070e-01, 4.2150e-01, 4.1260e-01, 4.0390e-01, 3.9540e-01, 3.8730e-01, 3.7930e-01, 3.7160e-01, 3.6410e-01, 3.5680e-01, 3.4970e-01, 3.4280e-01, 3.3610e-01, 3.2960e-01, 3.2330e-01, 3.1720e-01, 3.1120e-01, 3.0540e-01, 2.9970e-01, 2.9420e-01, 2.8880e-01, 2.8360e-01, 2.7850e-01, 2.7360e-01, 2.6880e-01, 2.6410e-01, 2.5950e-01, 2.5510e-01, 2.5080e-01, 2.4650e-01, 2.4240e-01, 2.3840e-01, 2.3450e-01, 2.3070e-01, 2.2700e-01, 2.2330e-01, 2.1980e-01, 2.1640e-01, 2.1300e-01, 2.0970e-01, 2.0650e-01, 2.0340e-01, 2.0030e-01, 1.9730e-01, 1.9440e-01, 1.9160e-01, 1.8880e-01, 1.8600e-01, 1.8340e-01, 1.8080e-01, 1.7820e-01, 1.7580e-01, 1.7330e-01, 1.7090e-01, 1.6860e-01, 1.6630e-01, 1.6410e-01, 1.6190e-01, 1.5970e-01, 1.5760e-01, 1.5560e-01, 1.5360e-01, 1.5160e-01, 1.4970e-01, 1.4780e-01, 1.4590e-01, 1.4410e-01, 1.4230e-01, 1.4050e-01, 1.3880e-01, 1.3710e-01, 1.3550e-01, 1.3380e-01, 1.3220e-01, 1.3070e-01, 1.2910e-01, 1.2760e-01, 1.2610e-01, 1.2460e-01, 1.2320e-01, 1.2180e-01, 1.2040e-01, 1.1900e-01, 1.1770e-01, 1.1640e-01, 1.1510e-01, 1.1380e-01, 1.1260e-01, 1.1130e-01, 1.1010e-01, 1.0890e-01, 1.0770e-01, 1.0660e-01, 1.0540e-01, 1.0430e-01, 1.0320e-01, 1.0210e-01, 1.0110e-01, 1.0000e-01, 9.9000e-02, 9.8000e-02, 9.6900e-02, 9.6000e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6800e-02, 8.6000e-02, 8.5100e-02, 8.4300e-02, 8.3500e-02, 8.2700e-02, 8.1900e-02, 8.1100e-02, 8.0400e-02, 7.9600e-02, 7.8900e-02, 7.8100e-02, 7.7400e-02, 7.6700e-02, 7.6000e-02, 7.5300e-02, 7.4600e-02, 7.3900e-02, 7.3300e-02, 7.2600e-02, 7.1900e-02, 7.1300e-02, 7.0700e-02, 7.0000e-02, 6.9400e-02, 6.8800e-02, 6.8200e-02, 6.7600e-02, 6.7000e-02, 6.6400e-02, 6.5900e-02, 6.5300e-02, 6.4700e-02, 6.4200e-02, 6.3600e-02, 6.3100e-02, 6.2600e-02, 6.2100e-02, 6.1500e-02, 6.1000e-02, 6.0500e-02, 6.0000e-02, 5.9500e-02, 5.9000e-02, 5.8500e-02, 5.8100e-02, 5.7600e-02, 5.7100e-02}); + } + break; + case 92: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.2000e+01, 9.1514e+01, 9.0180e+01, 8.8289e+01, 8.6123e+01, 8.3860e+01, 8.1581e+01, 7.9312e+01, 7.7066e+01, 7.4858e+01, 7.2701e+01, 7.0611e+01, 6.8598e+01, 6.6671e+01, 6.4830e+01, 6.3075e+01, 6.1402e+01, 5.9805e+01, 5.8277e+01, 5.6812e+01, 5.5405e+01, 5.4051e+01, 5.2745e+01, 5.1485e+01, 5.0266e+01, 4.9089e+01, 4.7950e+01, 4.6848e+01, 4.5784e+01, 4.4754e+01, 4.3759e+01, 4.2798e+01, 4.1869e+01, 4.0971e+01, 4.0104e+01, 3.9265e+01, 3.8454e+01, 3.7669e+01, 3.6908e+01, 3.6171e+01, 3.5456e+01, 3.4762e+01, 3.4087e+01, 3.3431e+01, 3.2792e+01, 3.2169e+01, 3.1561e+01, 3.0968e+01, 3.0388e+01, 2.9822e+01, 2.9268e+01, 2.8726e+01, 2.8196e+01, 2.7678e+01, 2.7171e+01, 2.6674e+01, 2.6189e+01, 2.5715e+01, 2.5251e+01, 2.4798e+01, 2.4356e+01, 2.3924e+01, 2.3504e+01, 2.3093e+01, 2.2694e+01, 2.2305e+01, 2.1927e+01, 2.1560e+01, 2.1203e+01, 2.0857e+01, 2.0521e+01, 2.0196e+01, 1.9881e+01, 1.9576e+01, 1.9281e+01, 1.8996e+01, 1.8721e+01, 1.8455e+01, 1.8198e+01, 1.7950e+01, 1.7711e+01, 1.7480e+01, 1.7258e+01, 1.7044e+01, 1.6837e+01, 1.6637e+01, 1.6445e+01, 1.6261e+01, 1.6082e+01, 1.5909e+01, 1.5742e+01, 1.5581e+01, 1.5426e+01, 1.5275e+01, 1.5129e+01, 1.4987e+01, 1.4851e+01, 1.4718e+01, 1.4589e+01, 1.4463e+01, 1.4340e+01, 1.4220e+01, 1.4104e+01, 1.3991e+01, 1.3880e+01, 1.3770e+01, 1.3661e+01, 1.3556e+01, 1.3453e+01, 1.3351e+01, 1.3251e+01, 1.3151e+01, 1.3051e+01, 1.2954e+01, 1.2858e+01, 1.2763e+01, 1.2669e+01, 1.2574e+01, 1.2480e+01, 1.2386e+01, 1.2293e+01, 1.2202e+01, 1.2111e+01, 1.2020e+01, 1.1928e+01, 1.1836e+01, 1.1744e+01, 1.1654e+01, 1.1565e+01, 1.1476e+01, 1.1386e+01, 1.1296e+01, 1.1205e+01, 1.1114e+01, 1.1024e+01, 1.0936e+01, 1.0849e+01, 1.0761e+01, 1.0672e+01, 1.0583e+01, 1.0494e+01, 1.0405e+01, 1.0317e+01, 1.0232e+01, 1.0146e+01, 1.0060e+01, 9.9746e+00, 9.8880e+00, 9.8012e+00, 9.7151e+00, 9.6306e+00, 9.5479e+00, 9.4661e+00, 9.3845e+00, 9.3028e+00, 9.2209e+00, 9.1387e+00, 9.0567e+00, 8.9760e+00, 8.8973e+00, 8.8204e+00, 8.7443e+00, 8.6685e+00, 8.5928e+00, 8.5172e+00, 8.4414e+00, 8.3659e+00, 8.2916e+00, 8.2195e+00, 8.1496e+00, 8.0807e+00, 8.0122e+00, 7.9440e+00, 7.8762e+00, 7.8086e+00, 7.7409e+00, 7.6738e+00, 7.6085e+00, 7.5455e+00, 7.4846e+00, 7.4245e+00, 7.3647e+00, 7.3053e+00, 7.2465e+00, 7.1880e+00, 7.1294e+00, 7.0711e+00, 7.0143e+00, 6.9599e+00, 6.9079e+00, 6.8569e+00, 6.8063e+00, 6.7558e+00, 6.7060e+00, 6.6568e+00, 6.6077e+00, 6.5584e+00, 6.5095e+00, 6.4623e+00, 6.4175e+00, 6.3750e+00, 6.3334e+00, 6.2918e+00, 6.2503e+00, 6.2094e+00, 6.1692e+00, 6.1292e+00, 6.0888e+00, 6.0483e+00, 6.0088e+00, 5.9714e+00, 5.9365e+00, 5.9032e+00, 5.8702e+00, 5.8368e+00, 5.8035e+00, 5.7709e+00, 5.7389e+00, 5.7069e+00, 5.6744e+00, 5.6415e+00, 5.6093e+00, 5.5790e+00, 5.5512e+00, 5.5251e+00, 5.4994e+00, 5.4733e+00, 5.4468e+00, 5.4205e+00, 5.3950e+00, 5.3699e+00, 5.3443e+00, 5.3179e+00, 5.2911e+00, 5.2652e+00, 5.2412e+00, 5.2195e+00, 5.1995e+00, 5.1797e+00, 5.1592e+00, 5.1381e+00}); + feg = Vctr_cpu({1.9069e+01, 1.8622e+01, 1.7420e+01, 1.5790e+01, 1.4066e+01, 1.2468e+01, 1.1083e+01, 9.9160e+00, 8.9354e+00, 8.1043e+00, 7.3904e+00, 6.7693e+00, 6.2232e+00, 5.7394e+00, 5.3083e+00, 4.9228e+00, 4.5770e+00, 4.2660e+00, 3.9858e+00, 3.7326e+00, 3.5034e+00, 3.2953e+00, 3.1058e+00, 2.9329e+00, 2.7746e+00, 2.6292e+00, 2.4953e+00, 2.3718e+00, 2.2574e+00, 2.1513e+00, 2.0526e+00, 1.9606e+00, 1.8747e+00, 1.7944e+00, 1.7191e+00, 1.6485e+00, 1.5822e+00, 1.5198e+00, 1.4610e+00, 1.4056e+00, 1.3533e+00, 1.3039e+00, 1.2572e+00, 1.2130e+00, 1.1711e+00, 1.1314e+00, 1.0938e+00, 1.0580e+00, 1.0240e+00, 9.9170e-01, 9.6090e-01, 9.3160e-01, 9.0360e-01, 8.7690e-01, 8.5140e-01, 8.2700e-01, 8.0360e-01, 7.8130e-01, 7.5980e-01, 7.3930e-01, 7.1950e-01, 7.0060e-01, 6.8240e-01, 6.6480e-01, 6.4790e-01, 6.3170e-01, 6.1600e-01, 6.0090e-01, 5.8630e-01, 5.7220e-01, 5.5860e-01, 5.4550e-01, 5.3270e-01, 5.2040e-01, 5.0850e-01, 4.9700e-01, 4.8580e-01, 4.7500e-01, 4.6450e-01, 4.5440e-01, 4.4450e-01, 4.3490e-01, 4.2570e-01, 4.1670e-01, 4.0790e-01, 3.9940e-01, 3.9120e-01, 3.8320e-01, 3.7540e-01, 3.6790e-01, 3.6050e-01, 3.5340e-01, 3.4640e-01, 3.3970e-01, 3.3310e-01, 3.2680e-01, 3.2060e-01, 3.1450e-01, 3.0870e-01, 3.0290e-01, 2.9740e-01, 2.9200e-01, 2.8670e-01, 2.8160e-01, 2.7660e-01, 2.7170e-01, 2.6700e-01, 2.6240e-01, 2.5790e-01, 2.5350e-01, 2.4920e-01, 2.4510e-01, 2.4100e-01, 2.3710e-01, 2.3320e-01, 2.2940e-01, 2.2580e-01, 2.2220e-01, 2.1870e-01, 2.1530e-01, 2.1200e-01, 2.0870e-01, 2.0550e-01, 2.0240e-01, 1.9940e-01, 1.9650e-01, 1.9360e-01, 1.9080e-01, 1.8800e-01, 1.8530e-01, 1.8270e-01, 1.8010e-01, 1.7760e-01, 1.7510e-01, 1.7270e-01, 1.7030e-01, 1.6800e-01, 1.6570e-01, 1.6350e-01, 1.6140e-01, 1.5920e-01, 1.5720e-01, 1.5510e-01, 1.5310e-01, 1.5120e-01, 1.4920e-01, 1.4740e-01, 1.4550e-01, 1.4370e-01, 1.4190e-01, 1.4020e-01, 1.3850e-01, 1.3680e-01, 1.3510e-01, 1.3350e-01, 1.3190e-01, 1.3040e-01, 1.2890e-01, 1.2740e-01, 1.2590e-01, 1.2440e-01, 1.2300e-01, 1.2160e-01, 1.2020e-01, 1.1890e-01, 1.1750e-01, 1.1620e-01, 1.1490e-01, 1.1370e-01, 1.1240e-01, 1.1120e-01, 1.1000e-01, 1.0880e-01, 1.0760e-01, 1.0650e-01, 1.0540e-01, 1.0420e-01, 1.0320e-01, 1.0210e-01, 1.0100e-01, 1.0000e-01, 9.8900e-02, 9.7900e-02, 9.6900e-02, 9.5900e-02, 9.5000e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2800e-02, 8.2000e-02, 8.1200e-02, 8.0400e-02, 7.9700e-02, 7.8900e-02, 7.8200e-02, 7.7500e-02, 7.6800e-02, 7.6100e-02, 7.5400e-02, 7.4700e-02, 7.4000e-02, 7.3400e-02, 7.2700e-02, 7.2000e-02, 7.1400e-02, 7.0800e-02, 7.0100e-02, 6.9500e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7100e-02, 6.6600e-02, 6.6000e-02, 6.5400e-02, 6.4900e-02, 6.4300e-02, 6.3800e-02, 6.3200e-02, 6.2700e-02, 6.2200e-02, 6.1700e-02, 6.1200e-02, 6.0700e-02, 6.0200e-02, 5.9700e-02, 5.9200e-02, 5.8700e-02, 5.8200e-02, 5.7700e-02}); + } + break; + case 93: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.3000e+01, 9.2523e+01, 9.1210e+01, 8.9337e+01, 8.7178e+01, 8.4910e+01, 8.2614e+01, 8.0321e+01, 7.8046e+01, 7.5803e+01, 7.3608e+01, 7.1476e+01, 6.9421e+01, 6.7452e+01, 6.5571e+01, 6.3779e+01, 6.2071e+01, 6.0444e+01, 5.8891e+01, 5.7406e+01, 5.5982e+01, 5.4615e+01, 5.3299e+01, 5.2031e+01, 5.0807e+01, 4.9626e+01, 4.8484e+01, 4.7381e+01, 4.6315e+01, 4.5284e+01, 4.4288e+01, 4.3325e+01, 4.2394e+01, 4.1494e+01, 4.0624e+01, 3.9783e+01, 3.8970e+01, 3.8182e+01, 3.7419e+01, 3.6680e+01, 3.5962e+01, 3.5266e+01, 3.4589e+01, 3.3930e+01, 3.3289e+01, 3.2664e+01, 3.2054e+01, 3.1459e+01, 3.0877e+01, 3.0309e+01, 2.9753e+01, 2.9210e+01, 2.8678e+01, 2.8157e+01, 2.7647e+01, 2.7148e+01, 2.6660e+01, 2.6182e+01, 2.5714e+01, 2.5257e+01, 2.4811e+01, 2.4374e+01, 2.3948e+01, 2.3532e+01, 2.3126e+01, 2.2731e+01, 2.2346e+01, 2.1971e+01, 2.1607e+01, 2.1253e+01, 2.0909e+01, 2.0576e+01, 2.0252e+01, 1.9939e+01, 1.9635e+01, 1.9341e+01, 1.9056e+01, 1.8781e+01, 1.8515e+01, 1.8259e+01, 1.8010e+01, 1.7771e+01, 1.7540e+01, 1.7317e+01, 1.7102e+01, 1.6894e+01, 1.6694e+01, 1.6502e+01, 1.6315e+01, 1.6135e+01, 1.5961e+01, 1.5794e+01, 1.5633e+01, 1.5476e+01, 1.5324e+01, 1.5177e+01, 1.5036e+01, 1.4899e+01, 1.4765e+01, 1.4635e+01, 1.4508e+01, 1.4386e+01, 1.4266e+01, 1.4150e+01, 1.4036e+01, 1.3924e+01, 1.3814e+01, 1.3707e+01, 1.3603e+01, 1.3500e+01, 1.3399e+01, 1.3298e+01, 1.3198e+01, 1.3101e+01, 1.3005e+01, 1.2910e+01, 1.2816e+01, 1.2722e+01, 1.2628e+01, 1.2535e+01, 1.2444e+01, 1.2353e+01, 1.2264e+01, 1.2174e+01, 1.2083e+01, 1.1992e+01, 1.1902e+01, 1.1813e+01, 1.1725e+01, 1.1637e+01, 1.1549e+01, 1.1460e+01, 1.1371e+01, 1.1282e+01, 1.1194e+01, 1.1107e+01, 1.1021e+01, 1.0934e+01, 1.0847e+01, 1.0759e+01, 1.0671e+01, 1.0583e+01, 1.0497e+01, 1.0412e+01, 1.0328e+01, 1.0243e+01, 1.0158e+01, 1.0072e+01, 9.9861e+00, 9.9006e+00, 9.8167e+00, 9.7344e+00, 9.6530e+00, 9.5718e+00, 9.4903e+00, 9.4086e+00, 9.3265e+00, 9.2446e+00, 9.1638e+00, 9.0850e+00, 9.0078e+00, 8.9315e+00, 8.8552e+00, 8.7791e+00, 8.7030e+00, 8.6267e+00, 8.5506e+00, 8.4756e+00, 8.4028e+00, 8.3319e+00, 8.2622e+00, 8.1927e+00, 8.1235e+00, 8.0547e+00, 7.9859e+00, 7.9171e+00, 7.8489e+00, 7.7823e+00, 7.7181e+00, 7.6557e+00, 7.5942e+00, 7.5330e+00, 7.4722e+00, 7.4119e+00, 7.3518e+00, 7.2917e+00, 7.2320e+00, 7.1736e+00, 7.1177e+00, 7.0639e+00, 7.0113e+00, 6.9589e+00, 6.9068e+00, 6.8553e+00, 6.8044e+00, 6.7536e+00, 6.7026e+00, 6.6521e+00, 6.6032e+00, 6.5567e+00, 6.5124e+00, 6.4690e+00, 6.4257e+00, 6.3825e+00, 6.3399e+00, 6.2980e+00, 6.2563e+00, 6.2143e+00, 6.1722e+00, 6.1311e+00, 6.0921e+00, 6.0556e+00, 6.0206e+00, 5.9859e+00, 5.9510e+00, 5.9161e+00, 5.8819e+00, 5.8484e+00, 5.8149e+00, 5.7810e+00, 5.7467e+00, 5.7132e+00, 5.6815e+00, 5.6522e+00, 5.6247e+00, 5.5976e+00, 5.5702e+00, 5.5424e+00, 5.5149e+00, 5.4881e+00, 5.4617e+00, 5.4350e+00, 5.4075e+00, 5.3797e+00, 5.3527e+00, 5.3277e+00, 5.3049e+00, 5.2838e+00, 5.2629e+00, 5.2414e+00, 5.2193e+00}); + feg = Vctr_cpu({1.8704e+01, 1.8281e+01, 1.7141e+01, 1.5587e+01, 1.3935e+01, 1.2393e+01, 1.1048e+01, 9.9085e+00, 8.9475e+00, 8.1302e+00, 7.4261e+00, 6.8118e+00, 6.2702e+00, 5.7890e+00, 5.3590e+00, 4.9733e+00, 4.6265e+00, 4.3138e+00, 4.0314e+00, 3.7757e+00, 3.5439e+00, 3.3332e+00, 3.1411e+00, 2.9657e+00, 2.8051e+00, 2.6575e+00, 2.5217e+00, 2.3963e+00, 2.2803e+00, 2.1727e+00, 2.0727e+00, 1.9795e+00, 1.8925e+00, 1.8112e+00, 1.7350e+00, 1.6636e+00, 1.5965e+00, 1.5334e+00, 1.4740e+00, 1.4180e+00, 1.3651e+00, 1.3152e+00, 1.2680e+00, 1.2234e+00, 1.1811e+00, 1.1410e+00, 1.1030e+00, 1.0668e+00, 1.0325e+00, 9.9990e-01, 9.6880e-01, 9.3920e-01, 9.1090e-01, 8.8400e-01, 8.5820e-01, 8.3360e-01, 8.1010e-01, 7.8750e-01, 7.6590e-01, 7.4520e-01, 7.2530e-01, 7.0620e-01, 6.8790e-01, 6.7020e-01, 6.5330e-01, 6.3690e-01, 6.2110e-01, 6.0590e-01, 5.9120e-01, 5.7710e-01, 5.6340e-01, 5.5020e-01, 5.3740e-01, 5.2500e-01, 5.1300e-01, 5.0150e-01, 4.9020e-01, 4.7940e-01, 4.6880e-01, 4.5860e-01, 4.4870e-01, 4.3910e-01, 4.2980e-01, 4.2070e-01, 4.1190e-01, 4.0340e-01, 3.9510e-01, 3.8700e-01, 3.7920e-01, 3.7160e-01, 3.6420e-01, 3.5700e-01, 3.5000e-01, 3.4320e-01, 3.3660e-01, 3.3020e-01, 3.2400e-01, 3.1790e-01, 3.1190e-01, 3.0620e-01, 3.0060e-01, 2.9510e-01, 2.8980e-01, 2.8460e-01, 2.7960e-01, 2.7470e-01, 2.6990e-01, 2.6520e-01, 2.6070e-01, 2.5620e-01, 2.5190e-01, 2.4770e-01, 2.4360e-01, 2.3960e-01, 2.3570e-01, 2.3190e-01, 2.2820e-01, 2.2460e-01, 2.2100e-01, 2.1760e-01, 2.1420e-01, 2.1090e-01, 2.0770e-01, 2.0460e-01, 2.0150e-01, 1.9850e-01, 1.9560e-01, 1.9280e-01, 1.9000e-01, 1.8720e-01, 1.8460e-01, 1.8200e-01, 1.7940e-01, 1.7690e-01, 1.7450e-01, 1.7210e-01, 1.6970e-01, 1.6740e-01, 1.6520e-01, 1.6300e-01, 1.6090e-01, 1.5870e-01, 1.5670e-01, 1.5470e-01, 1.5270e-01, 1.5070e-01, 1.4880e-01, 1.4700e-01, 1.4510e-01, 1.4330e-01, 1.4160e-01, 1.3980e-01, 1.3810e-01, 1.3650e-01, 1.3480e-01, 1.3320e-01, 1.3170e-01, 1.3010e-01, 1.2860e-01, 1.2710e-01, 1.2560e-01, 1.2420e-01, 1.2280e-01, 1.2140e-01, 1.2000e-01, 1.1870e-01, 1.1740e-01, 1.1610e-01, 1.1480e-01, 1.1350e-01, 1.1230e-01, 1.1110e-01, 1.0990e-01, 1.0870e-01, 1.0750e-01, 1.0640e-01, 1.0530e-01, 1.0420e-01, 1.0310e-01, 1.0200e-01, 1.0090e-01, 9.9900e-02, 9.8900e-02, 9.7900e-02, 9.6900e-02, 9.5900e-02, 9.4900e-02, 9.4000e-02, 9.3100e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2800e-02, 8.2000e-02, 8.1200e-02, 8.0500e-02, 7.9700e-02, 7.9000e-02, 7.8300e-02, 7.7600e-02, 7.6900e-02, 7.6200e-02, 7.5500e-02, 7.4800e-02, 7.4100e-02, 7.3400e-02, 7.2800e-02, 7.2100e-02, 7.1500e-02, 7.0900e-02, 7.0300e-02, 6.9600e-02, 6.9000e-02, 6.8400e-02, 6.7800e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5500e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3400e-02, 6.2800e-02, 6.2300e-02, 6.1800e-02, 6.1300e-02, 6.0800e-02, 6.0300e-02, 5.9800e-02, 5.9300e-02, 5.8800e-02, 5.8400e-02}); + } + break; + case 94: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.4000e+01, 9.3539e+01, 9.2276e+01, 9.0480e+01, 8.8405e+01, 8.6199e+01, 8.3929e+01, 8.1623e+01, 7.9302e+01, 7.6991e+01, 7.4718e+01, 7.2505e+01, 7.0371e+01, 6.8327e+01, 6.6379e+01, 6.4526e+01, 6.2767e+01, 6.1094e+01, 5.9503e+01, 5.7986e+01, 5.6536e+01, 5.5148e+01, 5.3816e+01, 5.2537e+01, 5.1305e+01, 5.0118e+01, 4.8973e+01, 4.7868e+01, 4.6802e+01, 4.5772e+01, 4.4777e+01, 4.3816e+01, 4.2888e+01, 4.1990e+01, 4.1123e+01, 4.0283e+01, 3.9471e+01, 3.8685e+01, 3.7923e+01, 3.7184e+01, 3.6467e+01, 3.5771e+01, 3.5093e+01, 3.4434e+01, 3.3792e+01, 3.3167e+01, 3.2556e+01, 3.1959e+01, 3.1377e+01, 3.0807e+01, 3.0249e+01, 2.9703e+01, 2.9169e+01, 2.8645e+01, 2.8132e+01, 2.7630e+01, 2.7138e+01, 2.6656e+01, 2.6185e+01, 2.5723e+01, 2.5271e+01, 2.4829e+01, 2.4398e+01, 2.3976e+01, 2.3564e+01, 2.3162e+01, 2.2770e+01, 2.2388e+01, 2.2017e+01, 2.1655e+01, 2.1303e+01, 2.0961e+01, 2.0629e+01, 2.0307e+01, 1.9995e+01, 1.9692e+01, 1.9399e+01, 1.9115e+01, 1.8840e+01, 1.8574e+01, 1.8318e+01, 1.8070e+01, 1.7830e+01, 1.7598e+01, 1.7375e+01, 1.7160e+01, 1.6952e+01, 1.6751e+01, 1.6556e+01, 1.6369e+01, 1.6189e+01, 1.6015e+01, 1.5847e+01, 1.5683e+01, 1.5526e+01, 1.5374e+01, 1.5227e+01, 1.5085e+01, 1.4946e+01, 1.4811e+01, 1.4681e+01, 1.4555e+01, 1.4432e+01, 1.4312e+01, 1.4195e+01, 1.4080e+01, 1.3969e+01, 1.3860e+01, 1.3754e+01, 1.3649e+01, 1.3545e+01, 1.3443e+01, 1.3344e+01, 1.3247e+01, 1.3151e+01, 1.3055e+01, 1.2960e+01, 1.2865e+01, 1.2772e+01, 1.2681e+01, 1.2591e+01, 1.2501e+01, 1.2411e+01, 1.2320e+01, 1.2230e+01, 1.2141e+01, 1.2054e+01, 1.1967e+01, 1.1880e+01, 1.1793e+01, 1.1704e+01, 1.1616e+01, 1.1529e+01, 1.1443e+01, 1.1357e+01, 1.1272e+01, 1.1186e+01, 1.1100e+01, 1.1012e+01, 1.0925e+01, 1.0840e+01, 1.0755e+01, 1.0671e+01, 1.0587e+01, 1.0503e+01, 1.0418e+01, 1.0332e+01, 1.0247e+01, 1.0163e+01, 1.0080e+01, 9.9985e+00, 9.9168e+00, 9.8353e+00, 9.7534e+00, 9.6709e+00, 9.5883e+00, 9.5068e+00, 9.4270e+00, 9.3484e+00, 9.2704e+00, 9.1928e+00, 9.1156e+00, 9.0382e+00, 8.9604e+00, 8.8827e+00, 8.8062e+00, 8.7316e+00, 8.6584e+00, 8.5860e+00, 8.5141e+00, 8.4428e+00, 8.3720e+00, 8.3009e+00, 8.2296e+00, 8.1590e+00, 8.0902e+00, 8.0234e+00, 7.9579e+00, 7.8929e+00, 7.8286e+00, 7.7651e+00, 7.7022e+00, 7.6392e+00, 7.5759e+00, 7.5132e+00, 7.4523e+00, 7.3936e+00, 7.3364e+00, 7.2799e+00, 7.2238e+00, 7.1686e+00, 7.1143e+00, 7.0603e+00, 7.0061e+00, 6.9517e+00, 6.8982e+00, 6.8468e+00, 6.7975e+00, 6.7496e+00, 6.7022e+00, 6.6550e+00, 6.6088e+00, 6.5635e+00, 6.5187e+00, 6.4735e+00, 6.4280e+00, 6.3829e+00, 6.3395e+00, 6.2983e+00, 6.2589e+00, 6.2202e+00, 6.1816e+00, 6.1433e+00, 6.1060e+00, 6.0695e+00, 6.0333e+00, 5.9966e+00, 5.9593e+00, 5.9224e+00, 5.8870e+00, 5.8538e+00, 5.8225e+00, 5.7918e+00, 5.7610e+00, 5.7304e+00, 5.7004e+00, 5.6713e+00, 5.6427e+00, 5.6138e+00, 5.5840e+00, 5.5537e+00, 5.5240e+00, 5.4960e+00, 5.4702e+00, 5.4460e+00, 5.4221e+00, 5.3980e+00, 5.3738e+00, 5.3501e+00, 5.3272e+00, 5.3048e+00}); + feg = Vctr_cpu({1.8085e+01, 1.7654e+01, 1.6506e+01, 1.4976e+01, 1.3392e+01, 1.1949e+01, 1.0712e+01, 9.6730e+00, 8.7947e+00, 8.0412e+00, 7.3839e+00, 6.8027e+00, 6.2836e+00, 5.8172e+00, 5.3965e+00, 5.0162e+00, 4.6721e+00, 4.3602e+00, 4.0772e+00, 3.8203e+00, 3.5866e+00, 3.3737e+00, 3.1793e+00, 3.0015e+00, 2.8385e+00, 2.6887e+00, 2.5507e+00, 2.4233e+00, 2.3053e+00, 2.1960e+00, 2.0944e+00, 1.9997e+00, 1.9114e+00, 1.8289e+00, 1.7516e+00, 1.6792e+00, 1.6112e+00, 1.5473e+00, 1.4871e+00, 1.4304e+00, 1.3770e+00, 1.3265e+00, 1.2788e+00, 1.2336e+00, 1.1909e+00, 1.1504e+00, 1.1120e+00, 1.0755e+00, 1.0408e+00, 1.0079e+00, 9.7650e-01, 9.4660e-01, 9.1810e-01, 8.9100e-01, 8.6500e-01, 8.4020e-01, 8.1650e-01, 7.9370e-01, 7.7200e-01, 7.5110e-01, 7.3110e-01, 7.1190e-01, 6.9340e-01, 6.7560e-01, 6.5850e-01, 6.4200e-01, 6.2620e-01, 6.1090e-01, 5.9610e-01, 5.8190e-01, 5.6810e-01, 5.5480e-01, 5.4200e-01, 5.2960e-01, 5.1750e-01, 5.0590e-01, 4.9460e-01, 4.8370e-01, 4.7310e-01, 4.6280e-01, 4.5280e-01, 4.4320e-01, 4.3380e-01, 4.2470e-01, 4.1590e-01, 4.0730e-01, 3.9890e-01, 3.9080e-01, 3.8300e-01, 3.7530e-01, 3.6790e-01, 3.6060e-01, 3.5360e-01, 3.4680e-01, 3.4010e-01, 3.3360e-01, 3.2730e-01, 3.2120e-01, 3.1520e-01, 3.0940e-01, 3.0370e-01, 2.9820e-01, 2.9290e-01, 2.8760e-01, 2.8250e-01, 2.7760e-01, 2.7280e-01, 2.6800e-01, 2.6350e-01, 2.5900e-01, 2.5460e-01, 2.5040e-01, 2.4620e-01, 2.4220e-01, 2.3820e-01, 2.3440e-01, 2.3060e-01, 2.2700e-01, 2.2340e-01, 2.1990e-01, 2.1650e-01, 2.1320e-01, 2.0990e-01, 2.0670e-01, 2.0360e-01, 2.0060e-01, 1.9770e-01, 1.9480e-01, 1.9190e-01, 1.8920e-01, 1.8650e-01, 1.8380e-01, 1.8130e-01, 1.7870e-01, 1.7620e-01, 1.7380e-01, 1.7150e-01, 1.6910e-01, 1.6690e-01, 1.6470e-01, 1.6250e-01, 1.6030e-01, 1.5830e-01, 1.5620e-01, 1.5420e-01, 1.5220e-01, 1.5030e-01, 1.4840e-01, 1.4660e-01, 1.4480e-01, 1.4300e-01, 1.4120e-01, 1.3950e-01, 1.3780e-01, 1.3620e-01, 1.3450e-01, 1.3300e-01, 1.3140e-01, 1.2990e-01, 1.2830e-01, 1.2690e-01, 1.2540e-01, 1.2400e-01, 1.2260e-01, 1.2120e-01, 1.1980e-01, 1.1850e-01, 1.1720e-01, 1.1590e-01, 1.1460e-01, 1.1340e-01, 1.1210e-01, 1.1090e-01, 1.0970e-01, 1.0860e-01, 1.0740e-01, 1.0630e-01, 1.0520e-01, 1.0410e-01, 1.0300e-01, 1.0190e-01, 1.0090e-01, 9.9800e-02, 9.8800e-02, 9.7800e-02, 9.6800e-02, 9.5900e-02, 9.4900e-02, 9.4000e-02, 9.3000e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2800e-02, 8.2100e-02, 8.1300e-02, 8.0500e-02, 7.9800e-02, 7.9100e-02, 7.8300e-02, 7.7600e-02, 7.6900e-02, 7.6200e-02, 7.5500e-02, 7.4900e-02, 7.4200e-02, 7.3500e-02, 7.2900e-02, 7.2200e-02, 7.1600e-02, 7.1000e-02, 7.0400e-02, 6.9700e-02, 6.9100e-02, 6.8500e-02, 6.7900e-02, 6.7400e-02, 6.6800e-02, 6.6200e-02, 6.5700e-02, 6.5100e-02, 6.4600e-02, 6.4000e-02, 6.3500e-02, 6.3000e-02, 6.2400e-02, 6.1900e-02, 6.1400e-02, 6.0900e-02, 6.0400e-02, 5.9900e-02, 5.9400e-02, 5.9000e-02}); + } + break; + case 95: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.5000e+01, 9.4548e+01, 9.3306e+01, 9.1533e+01, 8.9472e+01, 8.7271e+01, 8.4996e+01, 8.2677e+01, 8.0336e+01, 7.7999e+01, 7.5694e+01, 7.3444e+01, 7.1269e+01, 6.9183e+01, 6.7191e+01, 6.5296e+01, 6.3496e+01, 6.1787e+01, 6.0162e+01, 5.8615e+01, 5.7140e+01, 5.5731e+01, 5.4381e+01, 5.3086e+01, 5.1842e+01, 5.0645e+01, 4.9493e+01, 4.8382e+01, 4.7311e+01, 4.6277e+01, 4.5279e+01, 4.4316e+01, 4.3385e+01, 4.2486e+01, 4.1617e+01, 4.0776e+01, 3.9963e+01, 3.9175e+01, 3.8412e+01, 3.7672e+01, 3.6954e+01, 3.6257e+01, 3.5578e+01, 3.4919e+01, 3.4276e+01, 3.3649e+01, 3.3038e+01, 3.2441e+01, 3.1857e+01, 3.1287e+01, 3.0728e+01, 3.0181e+01, 2.9645e+01, 2.9121e+01, 2.8606e+01, 2.8102e+01, 2.7608e+01, 2.7124e+01, 2.6650e+01, 2.6185e+01, 2.5730e+01, 2.5284e+01, 2.4848e+01, 2.4422e+01, 2.4005e+01, 2.3598e+01, 2.3200e+01, 2.2812e+01, 2.2434e+01, 2.2065e+01, 2.1706e+01, 2.1357e+01, 2.1018e+01, 2.0687e+01, 2.0367e+01, 2.0056e+01, 1.9755e+01, 1.9462e+01, 1.9178e+01, 1.8904e+01, 1.8639e+01, 1.8383e+01, 1.8134e+01, 1.7894e+01, 1.7662e+01, 1.7439e+01, 1.7222e+01, 1.7013e+01, 1.6811e+01, 1.6617e+01, 1.6429e+01, 1.6248e+01, 1.6072e+01, 1.5902e+01, 1.5739e+01, 1.5581e+01, 1.5428e+01, 1.5279e+01, 1.5135e+01, 1.4996e+01, 1.4862e+01, 1.4732e+01, 1.4604e+01, 1.4480e+01, 1.4359e+01, 1.4242e+01, 1.4128e+01, 1.4017e+01, 1.3908e+01, 1.3800e+01, 1.3695e+01, 1.3592e+01, 1.3492e+01, 1.3394e+01, 1.3296e+01, 1.3199e+01, 1.3103e+01, 1.3009e+01, 1.2917e+01, 1.2826e+01, 1.2736e+01, 1.2646e+01, 1.2555e+01, 1.2466e+01, 1.2377e+01, 1.2290e+01, 1.2204e+01, 1.2117e+01, 1.2031e+01, 1.1944e+01, 1.1857e+01, 1.1770e+01, 1.1685e+01, 1.1601e+01, 1.1517e+01, 1.1432e+01, 1.1347e+01, 1.1261e+01, 1.1175e+01, 1.1091e+01, 1.1007e+01, 1.0924e+01, 1.0841e+01, 1.0758e+01, 1.0674e+01, 1.0589e+01, 1.0505e+01, 1.0422e+01, 1.0340e+01, 1.0258e+01, 1.0177e+01, 1.0096e+01, 1.0015e+01, 9.9324e+00, 9.8501e+00, 9.7688e+00, 9.6890e+00, 9.6100e+00, 9.5318e+00, 9.4541e+00, 9.3766e+00, 9.2987e+00, 9.2201e+00, 9.1419e+00, 9.0649e+00, 8.9894e+00, 8.9151e+00, 8.8415e+00, 8.7687e+00, 8.6966e+00, 8.6245e+00, 8.5518e+00, 8.4790e+00, 8.4072e+00, 8.3372e+00, 8.2687e+00, 8.2012e+00, 8.1344e+00, 8.0686e+00, 8.0036e+00, 7.9387e+00, 7.8735e+00, 7.8080e+00, 7.7436e+00, 7.6811e+00, 7.6203e+00, 7.5606e+00, 7.5015e+00, 7.4434e+00, 7.3864e+00, 7.3300e+00, 7.2735e+00, 7.2165e+00, 7.1598e+00, 7.1044e+00, 7.0512e+00, 6.9995e+00, 6.9487e+00, 6.8984e+00, 6.8491e+00, 6.8009e+00, 6.7536e+00, 6.7062e+00, 6.6581e+00, 6.6099e+00, 6.5628e+00, 6.5177e+00, 6.4745e+00, 6.4323e+00, 6.3906e+00, 6.3494e+00, 6.3092e+00, 6.2702e+00, 6.2318e+00, 6.1930e+00, 6.1534e+00, 6.1137e+00, 6.0749e+00, 6.0381e+00, 6.0033e+00, 5.9694e+00, 5.9359e+00, 5.9027e+00, 5.8702e+00, 5.8388e+00, 5.8083e+00, 5.7777e+00, 5.7463e+00, 5.7141e+00, 5.6819e+00, 5.6509e+00, 5.6221e+00, 5.5949e+00, 5.5684e+00, 5.5420e+00, 5.5157e+00, 5.4901e+00, 5.4655e+00, 5.4417e+00, 5.4179e+00, 5.3932e+00}); + feg = Vctr_cpu({1.7721e+01, 1.7310e+01, 1.6215e+01, 1.4752e+01, 1.3231e+01, 1.1839e+01, 1.0641e+01, 9.6306e+00, 8.7740e+00, 8.0373e+00, 7.3931e+00, 6.8221e+00, 6.3107e+00, 5.8500e+00, 5.4332e+00, 5.0554e+00, 4.7125e+00, 4.4009e+00, 4.1175e+00, 3.8596e+00, 3.6245e+00, 3.4099e+00, 3.2138e+00, 3.0341e+00, 2.8692e+00, 2.7176e+00, 2.5779e+00, 2.4488e+00, 2.3293e+00, 2.2185e+00, 2.1155e+00, 2.0197e+00, 1.9302e+00, 1.8466e+00, 1.7684e+00, 1.6951e+00, 1.6262e+00, 1.5615e+00, 1.5007e+00, 1.4433e+00, 1.3893e+00, 1.3382e+00, 1.2900e+00, 1.2443e+00, 1.2011e+00, 1.1602e+00, 1.1213e+00, 1.0845e+00, 1.0495e+00, 1.0162e+00, 9.8450e-01, 9.5430e-01, 9.2550e-01, 8.9810e-01, 8.7190e-01, 8.4690e-01, 8.2290e-01, 8.0000e-01, 7.7810e-01, 7.5700e-01, 7.3680e-01, 7.1750e-01, 6.9890e-01, 6.8100e-01, 6.6370e-01, 6.4720e-01, 6.3120e-01, 6.1580e-01, 6.0100e-01, 5.8660e-01, 5.7280e-01, 5.5940e-01, 5.4650e-01, 5.3400e-01, 5.2190e-01, 5.1020e-01, 4.9890e-01, 4.8790e-01, 4.7720e-01, 4.6690e-01, 4.5690e-01, 4.4720e-01, 4.3780e-01, 4.2860e-01, 4.1970e-01, 4.1110e-01, 4.0270e-01, 3.9460e-01, 3.8660e-01, 3.7890e-01, 3.7150e-01, 3.6420e-01, 3.5710e-01, 3.5020e-01, 3.4350e-01, 3.3700e-01, 3.3060e-01, 3.2450e-01, 3.1840e-01, 3.1260e-01, 3.0690e-01, 3.0130e-01, 2.9590e-01, 2.9060e-01, 2.8550e-01, 2.8050e-01, 2.7560e-01, 2.7090e-01, 2.6620e-01, 2.6170e-01, 2.5730e-01, 2.5300e-01, 2.4880e-01, 2.4470e-01, 2.4070e-01, 2.3690e-01, 2.3310e-01, 2.2940e-01, 2.2570e-01, 2.2220e-01, 2.1880e-01, 2.1540e-01, 2.1210e-01, 2.0890e-01, 2.0580e-01, 2.0270e-01, 1.9970e-01, 1.9680e-01, 1.9390e-01, 1.9110e-01, 1.8840e-01, 1.8570e-01, 1.8310e-01, 1.8050e-01, 1.7800e-01, 1.7560e-01, 1.7320e-01, 1.7090e-01, 1.6860e-01, 1.6630e-01, 1.6410e-01, 1.6190e-01, 1.5980e-01, 1.5780e-01, 1.5570e-01, 1.5370e-01, 1.5180e-01, 1.4990e-01, 1.4800e-01, 1.4620e-01, 1.4440e-01, 1.4260e-01, 1.4090e-01, 1.3920e-01, 1.3750e-01, 1.3590e-01, 1.3420e-01, 1.3270e-01, 1.3110e-01, 1.2960e-01, 1.2810e-01, 1.2660e-01, 1.2520e-01, 1.2370e-01, 1.2240e-01, 1.2100e-01, 1.1960e-01, 1.1830e-01, 1.1700e-01, 1.1570e-01, 1.1450e-01, 1.1320e-01, 1.1200e-01, 1.1080e-01, 1.0960e-01, 1.0840e-01, 1.0730e-01, 1.0620e-01, 1.0510e-01, 1.0400e-01, 1.0290e-01, 1.0180e-01, 1.0080e-01, 9.9800e-02, 9.8800e-02, 9.7800e-02, 9.6800e-02, 9.5800e-02, 9.4900e-02, 9.3900e-02, 9.3000e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5200e-02, 8.4400e-02, 8.3600e-02, 8.2900e-02, 8.2100e-02, 8.1300e-02, 8.0600e-02, 7.9800e-02, 7.9100e-02, 7.8400e-02, 7.7700e-02, 7.7000e-02, 7.6300e-02, 7.5600e-02, 7.4900e-02, 7.4300e-02, 7.3600e-02, 7.3000e-02, 7.2300e-02, 7.1700e-02, 7.1100e-02, 7.0400e-02, 6.9800e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7500e-02, 6.6900e-02, 6.6300e-02, 6.5800e-02, 6.5200e-02, 6.4700e-02, 6.4100e-02, 6.3600e-02, 6.3100e-02, 6.2600e-02, 6.2000e-02, 6.1500e-02, 6.1000e-02, 6.0500e-02, 6.0100e-02, 5.9600e-02}); + } + break; + case 96: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.6000e+01, 9.5550e+01, 9.4301e+01, 9.2492e+01, 9.0372e+01, 8.8109e+01, 8.5789e+01, 8.3450e+01, 8.1108e+01, 7.8782e+01, 7.6489e+01, 7.4247e+01, 7.2074e+01, 6.9980e+01, 6.7975e+01, 6.6061e+01, 6.4239e+01, 6.2505e+01, 6.0855e+01, 5.9285e+01, 5.7788e+01, 5.6358e+01, 5.4991e+01, 5.3681e+01, 5.2423e+01, 5.1214e+01, 5.0051e+01, 4.8931e+01, 4.7852e+01, 4.6810e+01, 4.5805e+01, 4.4835e+01, 4.3898e+01, 4.2993e+01, 4.2119e+01, 4.1273e+01, 4.0454e+01, 3.9662e+01, 3.8895e+01, 3.8151e+01, 3.7429e+01, 3.6729e+01, 3.6048e+01, 3.5386e+01, 3.4742e+01, 3.4113e+01, 3.3501e+01, 3.2903e+01, 3.2318e+01, 3.1747e+01, 3.1188e+01, 3.0641e+01, 3.0105e+01, 2.9580e+01, 2.9065e+01, 2.8560e+01, 2.8066e+01, 2.7580e+01, 2.7105e+01, 2.6638e+01, 2.6181e+01, 2.5733e+01, 2.5294e+01, 2.4865e+01, 2.4444e+01, 2.4033e+01, 2.3631e+01, 2.3238e+01, 2.2855e+01, 2.2481e+01, 2.2116e+01, 2.1760e+01, 2.1414e+01, 2.1077e+01, 2.0749e+01, 2.0431e+01, 2.0121e+01, 1.9821e+01, 1.9530e+01, 1.9247e+01, 1.8974e+01, 1.8708e+01, 1.8451e+01, 1.8203e+01, 1.7963e+01, 1.7731e+01, 1.7506e+01, 1.7289e+01, 1.7080e+01, 1.6877e+01, 1.6682e+01, 1.6492e+01, 1.6310e+01, 1.6133e+01, 1.5963e+01, 1.5798e+01, 1.5639e+01, 1.5484e+01, 1.5335e+01, 1.5191e+01, 1.5051e+01, 1.4915e+01, 1.4783e+01, 1.4655e+01, 1.4531e+01, 1.4411e+01, 1.4293e+01, 1.4178e+01, 1.4065e+01, 1.3956e+01, 1.3849e+01, 1.3745e+01, 1.3643e+01, 1.3542e+01, 1.3442e+01, 1.3344e+01, 1.3249e+01, 1.3155e+01, 1.3063e+01, 1.2971e+01, 1.2879e+01, 1.2788e+01, 1.2699e+01, 1.2611e+01, 1.2524e+01, 1.2438e+01, 1.2351e+01, 1.2264e+01, 1.2177e+01, 1.2092e+01, 1.2008e+01, 1.1924e+01, 1.1841e+01, 1.1757e+01, 1.1672e+01, 1.1587e+01, 1.1503e+01, 1.1420e+01, 1.1338e+01, 1.1256e+01, 1.1174e+01, 1.1091e+01, 1.1007e+01, 1.0923e+01, 1.0841e+01, 1.0759e+01, 1.0678e+01, 1.0598e+01, 1.0517e+01, 1.0435e+01, 1.0353e+01, 1.0271e+01, 1.0189e+01, 1.0109e+01, 1.0030e+01, 9.9516e+00, 9.8732e+00, 9.7942e+00, 9.7149e+00, 9.6354e+00, 9.5562e+00, 9.4778e+00, 9.4011e+00, 9.3259e+00, 9.2513e+00, 9.1766e+00, 9.1016e+00, 9.0265e+00, 8.9515e+00, 8.8767e+00, 8.8028e+00, 8.7305e+00, 8.6600e+00, 8.5907e+00, 8.5217e+00, 8.4524e+00, 8.3832e+00, 8.3143e+00, 8.2456e+00, 8.1772e+00, 8.1100e+00, 8.0447e+00, 7.9813e+00, 7.9191e+00, 7.8571e+00, 7.7951e+00, 7.7332e+00, 7.6717e+00, 7.6106e+00, 7.5499e+00, 7.4899e+00, 7.4316e+00, 7.3754e+00, 7.3210e+00, 7.2672e+00, 7.2134e+00, 7.1595e+00, 7.1060e+00, 7.0532e+00, 7.0007e+00, 6.9485e+00, 6.8970e+00, 6.8472e+00, 6.7996e+00, 6.7538e+00, 6.7087e+00, 6.6635e+00, 6.6181e+00, 6.5730e+00, 6.5286e+00, 6.4847e+00, 6.4410e+00, 6.3975e+00, 6.3550e+00, 6.3145e+00, 6.2761e+00, 6.2392e+00, 6.2026e+00, 6.1656e+00, 6.1284e+00, 6.0915e+00, 6.0553e+00, 6.0197e+00, 5.9840e+00, 5.9484e+00, 5.9133e+00, 5.8799e+00, 5.8486e+00, 5.8191e+00, 5.7903e+00, 5.7612e+00, 5.7314e+00, 5.7015e+00, 5.6720e+00, 5.6433e+00, 5.6148e+00, 5.5862e+00, 5.5574e+00, 5.5291e+00, 5.5022e+00, 5.4775e+00}); + feg = Vctr_cpu({1.7598e+01, 1.7241e+01, 1.6269e+01, 1.4926e+01, 1.3470e+01, 1.2087e+01, 1.0861e+01, 9.8082e+00, 8.9103e+00, 8.1401e+00, 7.4716e+00, 6.8842e+00, 6.3627e+00, 5.8958e+00, 5.4754e+00, 5.0955e+00, 4.7511e+00, 4.4383e+00, 4.1538e+00, 3.8946e+00, 3.6582e+00, 3.4422e+00, 3.2446e+00, 3.0635e+00, 2.8971e+00, 2.7440e+00, 2.6029e+00, 2.4725e+00, 2.3518e+00, 2.2398e+00, 2.1357e+00, 2.0388e+00, 1.9484e+00, 1.8639e+00, 1.7849e+00, 1.7108e+00, 1.6412e+00, 1.5759e+00, 1.5144e+00, 1.4565e+00, 1.4018e+00, 1.3502e+00, 1.3015e+00, 1.2553e+00, 1.2117e+00, 1.1703e+00, 1.1311e+00, 1.0938e+00, 1.0584e+00, 1.0248e+00, 9.9280e-01, 9.6230e-01, 9.3320e-01, 9.0550e-01, 8.7900e-01, 8.5370e-01, 8.2960e-01, 8.0640e-01, 7.8430e-01, 7.6300e-01, 7.4270e-01, 7.2310e-01, 7.0440e-01, 6.8630e-01, 6.6900e-01, 6.5230e-01, 6.3620e-01, 6.2070e-01, 6.0580e-01, 5.9130e-01, 5.7740e-01, 5.6400e-01, 5.5100e-01, 5.3840e-01, 5.2620e-01, 5.1450e-01, 5.0310e-01, 4.9200e-01, 4.8130e-01, 4.7090e-01, 4.6090e-01, 4.5110e-01, 4.4160e-01, 4.3240e-01, 4.2350e-01, 4.1480e-01, 4.0640e-01, 3.9820e-01, 3.9030e-01, 3.8250e-01, 3.7500e-01, 3.6770e-01, 3.6050e-01, 3.5360e-01, 3.4690e-01, 3.4030e-01, 3.3390e-01, 3.2770e-01, 3.2160e-01, 3.1570e-01, 3.1000e-01, 3.0440e-01, 2.9890e-01, 2.9360e-01, 2.8840e-01, 2.8340e-01, 2.7850e-01, 2.7370e-01, 2.6900e-01, 2.6440e-01, 2.6000e-01, 2.5560e-01, 2.5140e-01, 2.4730e-01, 2.4330e-01, 2.3930e-01, 2.3550e-01, 2.3180e-01, 2.2810e-01, 2.2450e-01, 2.2100e-01, 2.1760e-01, 2.1430e-01, 2.1110e-01, 2.0790e-01, 2.0480e-01, 2.0180e-01, 1.9880e-01, 1.9590e-01, 1.9310e-01, 1.9030e-01, 1.8760e-01, 1.8500e-01, 1.8240e-01, 1.7980e-01, 1.7740e-01, 1.7490e-01, 1.7260e-01, 1.7020e-01, 1.6800e-01, 1.6570e-01, 1.6350e-01, 1.6140e-01, 1.5930e-01, 1.5730e-01, 1.5530e-01, 1.5330e-01, 1.5130e-01, 1.4940e-01, 1.4760e-01, 1.4580e-01, 1.4400e-01, 1.4220e-01, 1.4050e-01, 1.3880e-01, 1.3720e-01, 1.3550e-01, 1.3390e-01, 1.3240e-01, 1.3080e-01, 1.2930e-01, 1.2780e-01, 1.2640e-01, 1.2490e-01, 1.2350e-01, 1.2210e-01, 1.2080e-01, 1.1940e-01, 1.1810e-01, 1.1680e-01, 1.1550e-01, 1.1430e-01, 1.1310e-01, 1.1180e-01, 1.1060e-01, 1.0950e-01, 1.0830e-01, 1.0720e-01, 1.0610e-01, 1.0500e-01, 1.0390e-01, 1.0280e-01, 1.0180e-01, 1.0070e-01, 9.9700e-02, 9.8700e-02, 9.7700e-02, 9.6700e-02, 9.5800e-02, 9.4800e-02, 9.3900e-02, 9.3000e-02, 9.2100e-02, 9.1200e-02, 9.0300e-02, 8.9400e-02, 8.8600e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2100e-02, 8.1400e-02, 8.0600e-02, 7.9900e-02, 7.9200e-02, 7.8400e-02, 7.7700e-02, 7.7000e-02, 7.6300e-02, 7.5700e-02, 7.5000e-02, 7.4300e-02, 7.3700e-02, 7.3000e-02, 7.2400e-02, 7.1800e-02, 7.1100e-02, 7.0500e-02, 6.9900e-02, 6.9300e-02, 6.8700e-02, 6.8100e-02, 6.7600e-02, 6.7000e-02, 6.6400e-02, 6.5900e-02, 6.5300e-02, 6.4800e-02, 6.4200e-02, 6.3700e-02, 6.3200e-02, 6.2700e-02, 6.2200e-02, 6.1700e-02, 6.1200e-02, 6.0700e-02, 6.0200e-02}); + } + break; + case 97: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.7000e+01, 9.6557e+01, 9.5325e+01, 9.3536e+01, 9.1430e+01, 8.9174e+01, 8.6853e+01, 8.4505e+01, 8.2149e+01, 7.9802e+01, 7.7483e+01, 7.5210e+01, 7.3001e+01, 7.0869e+01, 6.8823e+01, 6.6868e+01, 6.5006e+01, 6.3233e+01, 6.1548e+01, 5.9945e+01, 5.8418e+01, 5.6962e+01, 5.5572e+01, 5.4242e+01, 5.2968e+01, 5.1746e+01, 5.0572e+01, 4.9442e+01, 4.8355e+01, 4.7308e+01, 4.6298e+01, 4.5324e+01, 4.4384e+01, 4.3476e+01, 4.2599e+01, 4.1751e+01, 4.0931e+01, 4.0138e+01, 3.9369e+01, 3.8625e+01, 3.7902e+01, 3.7201e+01, 3.6520e+01, 3.5857e+01, 3.5212e+01, 3.4583e+01, 3.3970e+01, 3.3372e+01, 3.2787e+01, 3.2215e+01, 3.1656e+01, 3.1108e+01, 3.0572e+01, 3.0046e+01, 2.9530e+01, 2.9025e+01, 2.8529e+01, 2.8042e+01, 2.7564e+01, 2.7096e+01, 2.6637e+01, 2.6186e+01, 2.5744e+01, 2.5311e+01, 2.4887e+01, 2.4472e+01, 2.4065e+01, 2.3668e+01, 2.3279e+01, 2.2899e+01, 2.2529e+01, 2.2167e+01, 2.1814e+01, 2.1470e+01, 2.1136e+01, 2.0810e+01, 2.0493e+01, 2.0185e+01, 1.9886e+01, 1.9595e+01, 1.9314e+01, 1.9041e+01, 1.8776e+01, 1.8519e+01, 1.8271e+01, 1.8031e+01, 1.7798e+01, 1.7573e+01, 1.7355e+01, 1.7145e+01, 1.6942e+01, 1.6745e+01, 1.6555e+01, 1.6371e+01, 1.6194e+01, 1.6023e+01, 1.5857e+01, 1.5697e+01, 1.5541e+01, 1.5391e+01, 1.5246e+01, 1.5106e+01, 1.4969e+01, 1.4836e+01, 1.4707e+01, 1.4582e+01, 1.4461e+01, 1.4343e+01, 1.4228e+01, 1.4115e+01, 1.4005e+01, 1.3898e+01, 1.3794e+01, 1.3692e+01, 1.3591e+01, 1.3492e+01, 1.3394e+01, 1.3298e+01, 1.3205e+01, 1.3113e+01, 1.3022e+01, 1.2932e+01, 1.2842e+01, 1.2752e+01, 1.2664e+01, 1.2578e+01, 1.2493e+01, 1.2409e+01, 1.2324e+01, 1.2238e+01, 1.2153e+01, 1.2069e+01, 1.1986e+01, 1.1904e+01, 1.1822e+01, 1.1740e+01, 1.1658e+01, 1.1574e+01, 1.1491e+01, 1.1409e+01, 1.1328e+01, 1.1248e+01, 1.1168e+01, 1.1087e+01, 1.1006e+01, 1.0924e+01, 1.0842e+01, 1.0761e+01, 1.0681e+01, 1.0602e+01, 1.0523e+01, 1.0444e+01, 1.0364e+01, 1.0284e+01, 1.0203e+01, 1.0123e+01, 1.0044e+01, 9.9670e+00, 9.8901e+00, 9.8136e+00, 9.7370e+00, 9.6598e+00, 9.5818e+00, 9.5040e+00, 9.4272e+00, 9.3519e+00, 9.2777e+00, 9.2044e+00, 9.1316e+00, 9.0593e+00, 8.9866e+00, 8.9133e+00, 8.8398e+00, 8.7671e+00, 8.6959e+00, 8.6262e+00, 8.5577e+00, 8.4899e+00, 8.4230e+00, 8.3565e+00, 8.2900e+00, 8.2229e+00, 8.1556e+00, 8.0891e+00, 8.0244e+00, 7.9614e+00, 7.8996e+00, 7.8386e+00, 7.7784e+00, 7.7192e+00, 7.6603e+00, 7.6012e+00, 7.5415e+00, 7.4821e+00, 7.4239e+00, 7.3676e+00, 7.3130e+00, 7.2595e+00, 7.2066e+00, 7.1547e+00, 7.1037e+00, 7.0534e+00, 7.0028e+00, 6.9517e+00, 6.9004e+00, 6.8501e+00, 6.8017e+00, 6.7552e+00, 6.7099e+00, 6.6652e+00, 6.6212e+00, 6.5782e+00, 6.5362e+00, 6.4945e+00, 6.4525e+00, 6.4098e+00, 6.3670e+00, 6.3251e+00, 6.2851e+00, 6.2470e+00, 6.2101e+00, 6.1737e+00, 6.1377e+00, 6.1025e+00, 6.0683e+00, 6.0349e+00, 6.0014e+00, 5.9671e+00, 5.9320e+00, 5.8970e+00, 5.8634e+00, 5.8317e+00, 5.8016e+00, 5.7725e+00, 5.7436e+00, 5.7150e+00, 5.6870e+00, 5.6600e+00, 5.6338e+00, 5.6075e+00, 5.5805e+00}); + feg = Vctr_cpu({1.7325e+01, 1.6979e+01, 1.6038e+01, 1.4739e+01, 1.3331e+01, 1.1988e+01, 1.0794e+01, 9.7652e+00, 8.8861e+00, 8.1306e+00, 7.4739e+00, 6.8961e+00, 6.3821e+00, 5.9211e+00, 5.5051e+00, 5.1283e+00, 4.7859e+00, 4.4742e+00, 4.1901e+00, 3.9307e+00, 3.6936e+00, 3.4766e+00, 3.2777e+00, 3.0952e+00, 2.9273e+00, 2.7727e+00, 2.6301e+00, 2.4982e+00, 2.3760e+00, 2.2627e+00, 2.1573e+00, 2.0592e+00, 1.9677e+00, 1.8821e+00, 1.8021e+00, 1.7271e+00, 1.6567e+00, 1.5906e+00, 1.5283e+00, 1.4697e+00, 1.4144e+00, 1.3622e+00, 1.3129e+00, 1.2663e+00, 1.2222e+00, 1.1803e+00, 1.1407e+00, 1.1030e+00, 1.0673e+00, 1.0333e+00, 1.0009e+00, 9.7010e-01, 9.4070e-01, 9.1280e-01, 8.8600e-01, 8.6050e-01, 8.3610e-01, 8.1280e-01, 7.9040e-01, 7.6900e-01, 7.4850e-01, 7.2880e-01, 7.0980e-01, 6.9170e-01, 6.7420e-01, 6.5740e-01, 6.4120e-01, 6.2560e-01, 6.1050e-01, 5.9600e-01, 5.8200e-01, 5.6850e-01, 5.5540e-01, 5.4280e-01, 5.3050e-01, 5.1870e-01, 5.0720e-01, 4.9610e-01, 4.8540e-01, 4.7490e-01, 4.6480e-01, 4.5500e-01, 4.4550e-01, 4.3630e-01, 4.2730e-01, 4.1860e-01, 4.1010e-01, 4.0180e-01, 3.9380e-01, 3.8610e-01, 3.7850e-01, 3.7110e-01, 3.6400e-01, 3.5700e-01, 3.5020e-01, 3.4360e-01, 3.3720e-01, 3.3090e-01, 3.2480e-01, 3.1890e-01, 3.1310e-01, 3.0740e-01, 3.0190e-01, 2.9660e-01, 2.9140e-01, 2.8630e-01, 2.8130e-01, 2.7650e-01, 2.7170e-01, 2.6710e-01, 2.6270e-01, 2.5830e-01, 2.5400e-01, 2.4980e-01, 2.4580e-01, 2.4180e-01, 2.3790e-01, 2.3410e-01, 2.3050e-01, 2.2680e-01, 2.2330e-01, 2.1990e-01, 2.1650e-01, 2.1320e-01, 2.1000e-01, 2.0690e-01, 2.0380e-01, 2.0080e-01, 1.9790e-01, 1.9510e-01, 1.9230e-01, 1.8950e-01, 1.8680e-01, 1.8420e-01, 1.8170e-01, 1.7910e-01, 1.7670e-01, 1.7430e-01, 1.7190e-01, 1.6960e-01, 1.6740e-01, 1.6520e-01, 1.6300e-01, 1.6090e-01, 1.5880e-01, 1.5680e-01, 1.5480e-01, 1.5280e-01, 1.5090e-01, 1.4900e-01, 1.4720e-01, 1.4540e-01, 1.4360e-01, 1.4190e-01, 1.4010e-01, 1.3850e-01, 1.3680e-01, 1.3520e-01, 1.3360e-01, 1.3210e-01, 1.3050e-01, 1.2900e-01, 1.2760e-01, 1.2610e-01, 1.2470e-01, 1.2330e-01, 1.2190e-01, 1.2060e-01, 1.1920e-01, 1.1790e-01, 1.1660e-01, 1.1540e-01, 1.1410e-01, 1.1290e-01, 1.1170e-01, 1.1050e-01, 1.0930e-01, 1.0820e-01, 1.0710e-01, 1.0590e-01, 1.0480e-01, 1.0380e-01, 1.0270e-01, 1.0170e-01, 1.0060e-01, 9.9600e-02, 9.8600e-02, 9.7600e-02, 9.6700e-02, 9.5700e-02, 9.4800e-02, 9.3800e-02, 9.2900e-02, 9.2000e-02, 9.1100e-02, 9.0300e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2100e-02, 8.1400e-02, 8.0700e-02, 7.9900e-02, 7.9200e-02, 7.8500e-02, 7.7800e-02, 7.7100e-02, 7.6400e-02, 7.5700e-02, 7.5000e-02, 7.4400e-02, 7.3700e-02, 7.3100e-02, 7.2500e-02, 7.1800e-02, 7.1200e-02, 7.0600e-02, 7.0000e-02, 6.9400e-02, 6.8800e-02, 6.8200e-02, 6.7700e-02, 6.7100e-02, 6.6500e-02, 6.6000e-02, 6.5400e-02, 6.4900e-02, 6.4300e-02, 6.3800e-02, 6.3300e-02, 6.2800e-02, 6.2300e-02, 6.1800e-02, 6.1300e-02, 6.0800e-02}); + } + break; + case 98: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.8000e+01, 9.7574e+01, 9.6393e+01, 9.4684e+01, 9.2668e+01, 9.0488e+01, 8.8211e+01, 8.5870e+01, 8.3487e+01, 8.1090e+01, 7.8706e+01, 7.6361e+01, 7.4077e+01, 7.1872e+01, 6.9757e+01, 6.7738e+01, 6.5816e+01, 6.3990e+01, 6.2255e+01, 6.0609e+01, 5.9043e+01, 5.7554e+01, 5.6134e+01, 5.4780e+01, 5.3485e+01, 5.2245e+01, 5.1057e+01, 4.9916e+01, 4.8821e+01, 4.7767e+01, 4.6753e+01, 4.5776e+01, 4.4835e+01, 4.3926e+01, 4.3050e+01, 4.2203e+01, 4.1385e+01, 4.0593e+01, 3.9827e+01, 3.9084e+01, 3.8364e+01, 3.7664e+01, 3.6985e+01, 3.6324e+01, 3.5681e+01, 3.5054e+01, 3.4442e+01, 3.3845e+01, 3.3261e+01, 3.2690e+01, 3.2131e+01, 3.1583e+01, 3.1047e+01, 3.0520e+01, 3.0004e+01, 2.9497e+01, 2.9000e+01, 2.8512e+01, 2.8032e+01, 2.7561e+01, 2.7099e+01, 2.6646e+01, 2.6201e+01, 2.5764e+01, 2.5336e+01, 2.4916e+01, 2.4505e+01, 2.4103e+01, 2.3709e+01, 2.3323e+01, 2.2947e+01, 2.2579e+01, 2.2220e+01, 2.1869e+01, 2.1528e+01, 2.1195e+01, 2.0871e+01, 2.0555e+01, 2.0248e+01, 1.9950e+01, 1.9660e+01, 1.9380e+01, 1.9107e+01, 1.8842e+01, 1.8585e+01, 1.8337e+01, 1.8097e+01, 1.7864e+01, 1.7638e+01, 1.7420e+01, 1.7209e+01, 1.7006e+01, 1.6808e+01, 1.6617e+01, 1.6433e+01, 1.6255e+01, 1.6083e+01, 1.5916e+01, 1.5754e+01, 1.5598e+01, 1.5447e+01, 1.5301e+01, 1.5160e+01, 1.5022e+01, 1.4889e+01, 1.4759e+01, 1.4633e+01, 1.4512e+01, 1.4394e+01, 1.4278e+01, 1.4164e+01, 1.4054e+01, 1.3947e+01, 1.3842e+01, 1.3740e+01, 1.3640e+01, 1.3540e+01, 1.3443e+01, 1.3347e+01, 1.3254e+01, 1.3162e+01, 1.3072e+01, 1.2982e+01, 1.2893e+01, 1.2804e+01, 1.2717e+01, 1.2632e+01, 1.2547e+01, 1.2463e+01, 1.2380e+01, 1.2295e+01, 1.2211e+01, 1.2128e+01, 1.2046e+01, 1.1966e+01, 1.1885e+01, 1.1804e+01, 1.1723e+01, 1.1641e+01, 1.1559e+01, 1.1479e+01, 1.1399e+01, 1.1320e+01, 1.1241e+01, 1.1162e+01, 1.1082e+01, 1.1001e+01, 1.0920e+01, 1.0841e+01, 1.0762e+01, 1.0684e+01, 1.0607e+01, 1.0529e+01, 1.0450e+01, 1.0371e+01, 1.0292e+01, 1.0213e+01, 1.0136e+01, 1.0059e+01, 9.9834e+00, 9.9075e+00, 9.8317e+00, 9.7555e+00, 9.6788e+00, 9.6020e+00, 9.5261e+00, 9.4516e+00, 9.3782e+00, 9.3054e+00, 9.2330e+00, 9.1608e+00, 9.0887e+00, 9.0164e+00, 8.9437e+00, 8.8714e+00, 8.8006e+00, 8.7314e+00, 8.6632e+00, 8.5955e+00, 8.5282e+00, 8.4615e+00, 8.3952e+00, 8.3286e+00, 8.2618e+00, 8.1955e+00, 8.1306e+00, 8.0675e+00, 8.0058e+00, 7.9446e+00, 7.8839e+00, 7.8238e+00, 7.7645e+00, 7.7054e+00, 7.6460e+00, 7.5866e+00, 7.5279e+00, 7.4711e+00, 7.4161e+00, 7.3624e+00, 7.3091e+00, 7.2562e+00, 7.2040e+00, 7.1527e+00, 7.1018e+00, 7.0508e+00, 6.9994e+00, 6.9485e+00, 6.8992e+00, 6.8519e+00, 6.8061e+00, 6.7611e+00, 6.7163e+00, 6.6719e+00, 6.6284e+00, 6.5857e+00, 6.5434e+00, 6.5007e+00, 6.4576e+00, 6.4150e+00, 6.3738e+00, 6.3347e+00, 6.2972e+00, 6.2604e+00, 6.2238e+00, 6.1873e+00, 6.1516e+00, 6.1167e+00, 6.0824e+00, 6.0480e+00, 6.0129e+00, 5.9776e+00, 5.9430e+00, 5.9099e+00, 5.8789e+00, 5.8493e+00, 5.8202e+00, 5.7910e+00, 5.7619e+00, 5.7333e+00, 5.7056e+00, 5.6784e+00}); + feg = Vctr_cpu({1.6678e+01, 1.6328e+01, 1.5385e+01, 1.4109e+01, 1.2761e+01, 1.1507e+01, 1.0413e+01, 9.4801e+00, 8.6835e+00, 7.9944e+00, 7.3886e+00, 6.8484e+00, 6.3618e+00, 5.9203e+00, 5.5180e+00, 5.1505e+00, 4.8143e+00, 4.5065e+00, 4.2247e+00, 3.9664e+00, 3.7295e+00, 3.5121e+00, 3.3124e+00, 3.1287e+00, 2.9595e+00, 2.8034e+00, 2.6592e+00, 2.5258e+00, 2.4021e+00, 2.2873e+00, 2.1805e+00, 2.0810e+00, 1.9882e+00, 1.9015e+00, 1.8203e+00, 1.7442e+00, 1.6728e+00, 1.6058e+00, 1.5427e+00, 1.4833e+00, 1.4273e+00, 1.3745e+00, 1.3245e+00, 1.2773e+00, 1.2327e+00, 1.1903e+00, 1.1502e+00, 1.1122e+00, 1.0760e+00, 1.0416e+00, 1.0090e+00, 9.7780e-01, 9.4820e-01, 9.1990e-01, 8.9290e-01, 8.6720e-01, 8.4260e-01, 8.1900e-01, 7.9650e-01, 7.7490e-01, 7.5420e-01, 7.3430e-01, 7.1530e-01, 6.9690e-01, 6.7930e-01, 6.6240e-01, 6.4610e-01, 6.3040e-01, 6.1520e-01, 6.0060e-01, 5.8650e-01, 5.7290e-01, 5.5980e-01, 5.4710e-01, 5.3480e-01, 5.2290e-01, 5.1140e-01, 5.0020e-01, 4.8940e-01, 4.7890e-01, 4.6870e-01, 4.5890e-01, 4.4930e-01, 4.4000e-01, 4.3100e-01, 4.2220e-01, 4.1370e-01, 4.0540e-01, 3.9740e-01, 3.8960e-01, 3.8190e-01, 3.7450e-01, 3.6730e-01, 3.6030e-01, 3.5350e-01, 3.4690e-01, 3.4040e-01, 3.3410e-01, 3.2790e-01, 3.2200e-01, 3.1610e-01, 3.1040e-01, 3.0490e-01, 2.9950e-01, 2.9430e-01, 2.8910e-01, 2.8410e-01, 2.7920e-01, 2.7450e-01, 2.6980e-01, 2.6530e-01, 2.6090e-01, 2.5660e-01, 2.5240e-01, 2.4830e-01, 2.4430e-01, 2.4040e-01, 2.3650e-01, 2.3280e-01, 2.2920e-01, 2.2560e-01, 2.2210e-01, 2.1870e-01, 2.1540e-01, 2.1220e-01, 2.0900e-01, 2.0590e-01, 2.0290e-01, 1.9990e-01, 1.9700e-01, 1.9420e-01, 1.9140e-01, 1.8870e-01, 1.8610e-01, 1.8350e-01, 1.8090e-01, 1.7850e-01, 1.7600e-01, 1.7370e-01, 1.7130e-01, 1.6900e-01, 1.6680e-01, 1.6460e-01, 1.6250e-01, 1.6040e-01, 1.5830e-01, 1.5630e-01, 1.5430e-01, 1.5240e-01, 1.5050e-01, 1.4860e-01, 1.4680e-01, 1.4500e-01, 1.4320e-01, 1.4150e-01, 1.3980e-01, 1.3810e-01, 1.3650e-01, 1.3490e-01, 1.3330e-01, 1.3180e-01, 1.3030e-01, 1.2880e-01, 1.2730e-01, 1.2590e-01, 1.2440e-01, 1.2310e-01, 1.2170e-01, 1.2030e-01, 1.1900e-01, 1.1770e-01, 1.1640e-01, 1.1520e-01, 1.1390e-01, 1.1270e-01, 1.1150e-01, 1.1040e-01, 1.0920e-01, 1.0810e-01, 1.0690e-01, 1.0580e-01, 1.0470e-01, 1.0370e-01, 1.0260e-01, 1.0160e-01, 1.0060e-01, 9.9500e-02, 9.8600e-02, 9.7600e-02, 9.6600e-02, 9.5700e-02, 9.4700e-02, 9.3800e-02, 9.2900e-02, 9.2000e-02, 9.1100e-02, 9.0200e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 7.9900e-02, 7.9200e-02, 7.8500e-02, 7.7800e-02, 7.7100e-02, 7.6400e-02, 7.5800e-02, 7.5100e-02, 7.4400e-02, 7.3800e-02, 7.3200e-02, 7.2500e-02, 7.1900e-02, 7.1300e-02, 7.0700e-02, 7.0100e-02, 6.9500e-02, 6.8900e-02, 6.8300e-02, 6.7700e-02, 6.7200e-02, 6.6600e-02, 6.6100e-02, 6.5500e-02, 6.5000e-02, 6.4400e-02, 6.3900e-02, 6.3400e-02, 6.2900e-02, 6.2400e-02, 6.1900e-02, 6.1400e-02}); + } + break; + case 99: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({9.9000e+01, 9.8582e+01, 9.7420e+01, 9.5732e+01, 9.3733e+01, 9.1562e+01, 8.9287e+01, 8.6943e+01, 8.4552e+01, 8.2140e+01, 7.9734e+01, 7.7362e+01, 7.5047e+01, 7.2807e+01, 7.0653e+01, 6.8594e+01, 6.6631e+01, 6.4765e+01, 6.2993e+01, 6.1310e+01, 5.9711e+01, 5.8191e+01, 5.6744e+01, 5.5365e+01, 5.4048e+01, 5.2790e+01, 5.1586e+01, 5.0431e+01, 4.9324e+01, 4.8260e+01, 4.7238e+01, 4.6254e+01, 4.5307e+01, 4.4394e+01, 4.3514e+01, 4.2664e+01, 4.1843e+01, 4.1050e+01, 4.0282e+01, 3.9538e+01, 3.8817e+01, 3.8117e+01, 3.7437e+01, 3.6776e+01, 3.6133e+01, 3.5506e+01, 3.4895e+01, 3.4298e+01, 3.3715e+01, 3.3144e+01, 3.2586e+01, 3.2039e+01, 3.1502e+01, 3.0976e+01, 3.0460e+01, 2.9953e+01, 2.9456e+01, 2.8967e+01, 2.8487e+01, 2.8015e+01, 2.7552e+01, 2.7097e+01, 2.6650e+01, 2.6211e+01, 2.5780e+01, 2.5358e+01, 2.4943e+01, 2.4537e+01, 2.4139e+01, 2.3749e+01, 2.3368e+01, 2.2995e+01, 2.2631e+01, 2.2274e+01, 2.1927e+01, 2.1587e+01, 2.1257e+01, 2.0934e+01, 2.0621e+01, 2.0315e+01, 2.0018e+01, 1.9730e+01, 1.9449e+01, 1.9177e+01, 1.8913e+01, 1.8657e+01, 1.8408e+01, 1.8168e+01, 1.7934e+01, 1.7708e+01, 1.7490e+01, 1.7279e+01, 1.7074e+01, 1.6875e+01, 1.6684e+01, 1.6499e+01, 1.6320e+01, 1.6146e+01, 1.5978e+01, 1.5816e+01, 1.5659e+01, 1.5507e+01, 1.5360e+01, 1.5217e+01, 1.5079e+01, 1.4944e+01, 1.4814e+01, 1.4688e+01, 1.4566e+01, 1.4446e+01, 1.4329e+01, 1.4216e+01, 1.4105e+01, 1.3998e+01, 1.3894e+01, 1.3791e+01, 1.3690e+01, 1.3590e+01, 1.3493e+01, 1.3398e+01, 1.3306e+01, 1.3214e+01, 1.3123e+01, 1.3033e+01, 1.2944e+01, 1.2857e+01, 1.2771e+01, 1.2687e+01, 1.2603e+01, 1.2519e+01, 1.2435e+01, 1.2352e+01, 1.2270e+01, 1.2189e+01, 1.2108e+01, 1.2029e+01, 1.1949e+01, 1.1868e+01, 1.1787e+01, 1.1707e+01, 1.1627e+01, 1.1549e+01, 1.1471e+01, 1.1393e+01, 1.1315e+01, 1.1236e+01, 1.1157e+01, 1.1078e+01, 1.0999e+01, 1.0922e+01, 1.0845e+01, 1.0768e+01, 1.0692e+01, 1.0614e+01, 1.0536e+01, 1.0458e+01, 1.0380e+01, 1.0304e+01, 1.0228e+01, 1.0153e+01, 1.0078e+01, 1.0003e+01, 9.9274e+00, 9.8514e+00, 9.7752e+00, 9.6998e+00, 9.6258e+00, 9.5528e+00, 9.4803e+00, 9.4081e+00, 9.3362e+00, 9.2643e+00, 9.1920e+00, 9.1194e+00, 9.0472e+00, 8.9763e+00, 8.9069e+00, 8.8385e+00, 8.7706e+00, 8.7030e+00, 8.6360e+00, 8.5692e+00, 8.5022e+00, 8.4349e+00, 8.3680e+00, 8.3025e+00, 8.2388e+00, 8.1763e+00, 8.1143e+00, 8.0528e+00, 7.9919e+00, 7.9316e+00, 7.8716e+00, 7.8113e+00, 7.7509e+00, 7.6913e+00, 7.6334e+00, 7.5773e+00, 7.5223e+00, 7.4679e+00, 7.4138e+00, 7.3604e+00, 7.3078e+00, 7.2557e+00, 7.2033e+00, 7.1507e+00, 7.0986e+00, 7.0480e+00, 6.9993e+00, 6.9521e+00, 6.9056e+00, 6.8594e+00, 6.8137e+00, 6.7687e+00, 6.7246e+00, 6.6808e+00, 6.6367e+00, 6.5923e+00, 6.5483e+00, 6.5057e+00, 6.4652e+00, 6.4262e+00, 6.3880e+00, 6.3499e+00, 6.3120e+00, 6.2748e+00, 6.2385e+00, 6.2028e+00, 6.1670e+00, 6.1306e+00, 6.0940e+00, 6.0580e+00, 6.0236e+00, 5.9912e+00, 5.9603e+00, 5.9298e+00, 5.8993e+00, 5.8689e+00, 5.8390e+00, 5.8100e+00, 5.7816e+00}); + feg = Vctr_cpu({1.6357e+01, 1.6023e+01, 1.5125e+01, 1.3903e+01, 1.2606e+01, 1.1393e+01, 1.0331e+01, 9.4226e+00, 8.6449e+00, 7.9709e+00, 7.3775e+00, 6.8478e+00, 6.3697e+00, 5.9351e+00, 5.5383e+00, 5.1750e+00, 4.8419e+00, 4.5363e+00, 4.2557e+00, 3.9980e+00, 3.7613e+00, 3.5436e+00, 3.3433e+00, 3.1587e+00, 2.9885e+00, 2.8313e+00, 2.6859e+00, 2.5513e+00, 2.4264e+00, 2.3104e+00, 2.2024e+00, 2.1018e+00, 2.0079e+00, 1.9202e+00, 1.8380e+00, 1.7611e+00, 1.6889e+00, 1.6210e+00, 1.5572e+00, 1.4971e+00, 1.4404e+00, 1.3869e+00, 1.3364e+00, 1.2887e+00, 1.2435e+00, 1.2007e+00, 1.1601e+00, 1.1216e+00, 1.0851e+00, 1.0503e+00, 1.0173e+00, 9.8590e-01, 9.5590e-01, 9.2730e-01, 9.0010e-01, 8.7410e-01, 8.4920e-01, 8.2540e-01, 8.0270e-01, 7.8090e-01, 7.6000e-01, 7.4000e-01, 7.2080e-01, 7.0230e-01, 6.8450e-01, 6.6750e-01, 6.5100e-01, 6.3520e-01, 6.2000e-01, 6.0530e-01, 5.9110e-01, 5.7740e-01, 5.6410e-01, 5.5130e-01, 5.3900e-01, 5.2700e-01, 5.1540e-01, 5.0420e-01, 4.9330e-01, 4.8280e-01, 4.7260e-01, 4.6270e-01, 4.5300e-01, 4.4370e-01, 4.3460e-01, 4.2580e-01, 4.1730e-01, 4.0900e-01, 4.0090e-01, 3.9300e-01, 3.8540e-01, 3.7790e-01, 3.7070e-01, 3.6360e-01, 3.5670e-01, 3.5010e-01, 3.4350e-01, 3.3720e-01, 3.3100e-01, 3.2500e-01, 3.1910e-01, 3.1340e-01, 3.0790e-01, 3.0240e-01, 2.9710e-01, 2.9200e-01, 2.8690e-01, 2.8200e-01, 2.7720e-01, 2.7250e-01, 2.6800e-01, 2.6350e-01, 2.5920e-01, 2.5490e-01, 2.5080e-01, 2.4670e-01, 2.4280e-01, 2.3890e-01, 2.3520e-01, 2.3150e-01, 2.2790e-01, 2.2440e-01, 2.2090e-01, 2.1760e-01, 2.1430e-01, 2.1110e-01, 2.0800e-01, 2.0490e-01, 2.0190e-01, 1.9900e-01, 1.9610e-01, 1.9340e-01, 1.9060e-01, 1.8790e-01, 1.8530e-01, 1.8270e-01, 1.8020e-01, 1.7780e-01, 1.7540e-01, 1.7300e-01, 1.7070e-01, 1.6840e-01, 1.6620e-01, 1.6410e-01, 1.6190e-01, 1.5980e-01, 1.5780e-01, 1.5580e-01, 1.5380e-01, 1.5190e-01, 1.5000e-01, 1.4820e-01, 1.4640e-01, 1.4460e-01, 1.4280e-01, 1.4110e-01, 1.3940e-01, 1.3780e-01, 1.3620e-01, 1.3460e-01, 1.3300e-01, 1.3150e-01, 1.3000e-01, 1.2850e-01, 1.2700e-01, 1.2560e-01, 1.2420e-01, 1.2280e-01, 1.2150e-01, 1.2010e-01, 1.1880e-01, 1.1750e-01, 1.1620e-01, 1.1500e-01, 1.1380e-01, 1.1260e-01, 1.1140e-01, 1.1020e-01, 1.0910e-01, 1.0790e-01, 1.0680e-01, 1.0570e-01, 1.0460e-01, 1.0360e-01, 1.0250e-01, 1.0150e-01, 1.0050e-01, 9.9500e-02, 9.8500e-02, 9.7500e-02, 9.6500e-02, 9.5600e-02, 9.4700e-02, 9.3700e-02, 9.2800e-02, 9.2000e-02, 9.1100e-02, 9.0200e-02, 8.9400e-02, 8.8500e-02, 8.7700e-02, 8.6900e-02, 8.6100e-02, 8.5300e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8500e-02, 7.7800e-02, 7.7200e-02, 7.6500e-02, 7.5800e-02, 7.5100e-02, 7.4500e-02, 7.3900e-02, 7.3200e-02, 7.2600e-02, 7.2000e-02, 7.1300e-02, 7.0700e-02, 7.0100e-02, 6.9500e-02, 6.9000e-02, 6.8400e-02, 6.7800e-02, 6.7300e-02, 6.6700e-02, 6.6100e-02, 6.5600e-02, 6.5100e-02, 6.4500e-02, 6.4000e-02, 6.3500e-02, 6.3000e-02, 6.2500e-02, 6.2000e-02}); + } + break; + case 100: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0000e+02, 9.9590e+01, 9.8448e+01, 9.6782e+01, 9.4800e+01, 9.2640e+01, 9.0370e+01, 8.8025e+01, 8.5628e+01, 8.3204e+01, 8.0782e+01, 7.8386e+01, 7.6043e+01, 7.3769e+01, 7.1578e+01, 6.9480e+01, 6.7477e+01, 6.5571e+01, 6.3759e+01, 6.2038e+01, 6.0404e+01, 5.8851e+01, 5.7373e+01, 5.5967e+01, 5.4626e+01, 5.3346e+01, 5.2122e+01, 5.0951e+01, 4.9830e+01, 4.8754e+01, 4.7721e+01, 4.6729e+01, 4.5775e+01, 4.4856e+01, 4.3970e+01, 4.3117e+01, 4.2293e+01, 4.1496e+01, 4.0727e+01, 3.9981e+01, 3.9260e+01, 3.8559e+01, 3.7879e+01, 3.7219e+01, 3.6575e+01, 3.5949e+01, 3.5339e+01, 3.4742e+01, 3.4160e+01, 3.3590e+01, 3.3033e+01, 3.2486e+01, 3.1951e+01, 3.1426e+01, 3.0910e+01, 3.0404e+01, 2.9907e+01, 2.9418e+01, 2.8938e+01, 2.8466e+01, 2.8002e+01, 2.7546e+01, 2.7097e+01, 2.6657e+01, 2.6224e+01, 2.5799e+01, 2.5382e+01, 2.4973e+01, 2.4572e+01, 2.4178e+01, 2.3793e+01, 2.3415e+01, 2.3046e+01, 2.2684e+01, 2.2331e+01, 2.1986e+01, 2.1649e+01, 2.1321e+01, 2.1001e+01, 2.0688e+01, 2.0384e+01, 2.0089e+01, 1.9801e+01, 1.9521e+01, 1.9250e+01, 1.8986e+01, 1.8730e+01, 1.8482e+01, 1.8241e+01, 1.8007e+01, 1.7781e+01, 1.7562e+01, 1.7350e+01, 1.7144e+01, 1.6945e+01, 1.6753e+01, 1.6567e+01, 1.6387e+01, 1.6212e+01, 1.6043e+01, 1.5880e+01, 1.5722e+01, 1.5570e+01, 1.5421e+01, 1.5277e+01, 1.5137e+01, 1.5002e+01, 1.4872e+01, 1.4745e+01, 1.4621e+01, 1.4501e+01, 1.4383e+01, 1.4270e+01, 1.4159e+01, 1.4052e+01, 1.3946e+01, 1.3842e+01, 1.3740e+01, 1.3641e+01, 1.3545e+01, 1.3450e+01, 1.3358e+01, 1.3266e+01, 1.3175e+01, 1.3085e+01, 1.2997e+01, 1.2911e+01, 1.2826e+01, 1.2742e+01, 1.2658e+01, 1.2574e+01, 1.2491e+01, 1.2409e+01, 1.2328e+01, 1.2249e+01, 1.2169e+01, 1.2090e+01, 1.2011e+01, 1.1931e+01, 1.1851e+01, 1.1773e+01, 1.1695e+01, 1.1618e+01, 1.1541e+01, 1.1464e+01, 1.1386e+01, 1.1308e+01, 1.1230e+01, 1.1153e+01, 1.1077e+01, 1.1001e+01, 1.0926e+01, 1.0850e+01, 1.0774e+01, 1.0697e+01, 1.0620e+01, 1.0543e+01, 1.0468e+01, 1.0393e+01, 1.0319e+01, 1.0245e+01, 1.0170e+01, 1.0096e+01, 1.0020e+01, 9.9449e+00, 9.8701e+00, 9.7967e+00, 9.7242e+00, 9.6522e+00, 9.5804e+00, 9.5089e+00, 9.4373e+00, 9.3653e+00, 9.2929e+00, 9.2209e+00, 9.1501e+00, 9.0807e+00, 9.0123e+00, 8.9442e+00, 8.8766e+00, 8.8093e+00, 8.7422e+00, 8.6749e+00, 8.6073e+00, 8.5401e+00, 8.4742e+00, 8.4099e+00, 8.3468e+00, 8.2843e+00, 8.2221e+00, 8.1605e+00, 8.0995e+00, 8.0387e+00, 7.9776e+00, 7.9164e+00, 7.8559e+00, 7.7971e+00, 7.7400e+00, 7.6840e+00, 7.6285e+00, 7.5734e+00, 7.5189e+00, 7.4652e+00, 7.4119e+00, 7.3583e+00, 7.3046e+00, 7.2513e+00, 7.1995e+00, 7.1495e+00, 7.1010e+00, 7.0532e+00, 7.0057e+00, 6.9586e+00, 6.9124e+00, 6.8669e+00, 6.8217e+00, 6.7762e+00, 6.7305e+00, 6.6852e+00, 6.6413e+00, 6.5993e+00, 6.5589e+00, 6.5192e+00, 6.4797e+00, 6.4405e+00, 6.4019e+00, 6.3642e+00, 6.3271e+00, 6.2899e+00, 6.2522e+00, 6.2143e+00, 6.1770e+00, 6.1413e+00, 6.1076e+00, 6.0752e+00, 6.0433e+00, 6.0115e+00, 5.9798e+00, 5.9487e+00, 5.9184e+00, 5.8886e+00}); + feg = Vctr_cpu({1.6028e+01, 1.5712e+01, 1.4857e+01, 1.3691e+01, 1.2445e+01, 1.1274e+01, 1.0244e+01, 9.3586e+00, 8.5994e+00, 7.9403e+00, 7.3594e+00, 6.8402e+00, 6.3710e+00, 5.9438e+00, 5.5529e+00, 5.1944e+00, 4.8650e+00, 4.5620e+00, 4.2834e+00, 4.0269e+00, 3.7907e+00, 3.5732e+00, 3.3726e+00, 3.1875e+00, 3.0166e+00, 2.8585e+00, 2.7122e+00, 2.5765e+00, 2.4505e+00, 2.3334e+00, 2.2244e+00, 2.1227e+00, 2.0278e+00, 1.9391e+00, 1.8560e+00, 1.7782e+00, 1.7051e+00, 1.6365e+00, 1.5719e+00, 1.5111e+00, 1.4537e+00, 1.3996e+00, 1.3485e+00, 1.3002e+00, 1.2545e+00, 1.2112e+00, 1.1702e+00, 1.1313e+00, 1.0943e+00, 1.0592e+00, 1.0258e+00, 9.9400e-01, 9.6370e-01, 9.3480e-01, 9.0730e-01, 8.8100e-01, 8.5590e-01, 8.3190e-01, 8.0890e-01, 7.8690e-01, 7.6590e-01, 7.4560e-01, 7.2630e-01, 7.0760e-01, 6.8970e-01, 6.7250e-01, 6.5600e-01, 6.4000e-01, 6.2470e-01, 6.0990e-01, 5.9560e-01, 5.8180e-01, 5.6850e-01, 5.5560e-01, 5.4310e-01, 5.3110e-01, 5.1950e-01, 5.0820e-01, 4.9720e-01, 4.8660e-01, 4.7640e-01, 4.6640e-01, 4.5670e-01, 4.4740e-01, 4.3820e-01, 4.2940e-01, 4.2080e-01, 4.1240e-01, 4.0430e-01, 3.9640e-01, 3.8870e-01, 3.8120e-01, 3.7390e-01, 3.6680e-01, 3.5990e-01, 3.5320e-01, 3.4670e-01, 3.4030e-01, 3.3410e-01, 3.2800e-01, 3.2210e-01, 3.1640e-01, 3.1080e-01, 3.0530e-01, 3.0000e-01, 2.9480e-01, 2.8970e-01, 2.8470e-01, 2.7990e-01, 2.7520e-01, 2.7060e-01, 2.6610e-01, 2.6170e-01, 2.5740e-01, 2.5330e-01, 2.4920e-01, 2.4520e-01, 2.4130e-01, 2.3750e-01, 2.3380e-01, 2.3020e-01, 2.2660e-01, 2.2320e-01, 2.1980e-01, 2.1650e-01, 2.1320e-01, 2.1010e-01, 2.0700e-01, 2.0390e-01, 2.0100e-01, 1.9810e-01, 1.9530e-01, 1.9250e-01, 1.8980e-01, 1.8710e-01, 1.8450e-01, 1.8200e-01, 1.7950e-01, 1.7710e-01, 1.7470e-01, 1.7240e-01, 1.7010e-01, 1.6780e-01, 1.6570e-01, 1.6350e-01, 1.6140e-01, 1.5930e-01, 1.5730e-01, 1.5530e-01, 1.5340e-01, 1.5150e-01, 1.4960e-01, 1.4780e-01, 1.4600e-01, 1.4420e-01, 1.4250e-01, 1.4080e-01, 1.3910e-01, 1.3750e-01, 1.3580e-01, 1.3430e-01, 1.3270e-01, 1.3120e-01, 1.2970e-01, 1.2820e-01, 1.2680e-01, 1.2540e-01, 1.2400e-01, 1.2260e-01, 1.2120e-01, 1.1990e-01, 1.1860e-01, 1.1730e-01, 1.1610e-01, 1.1480e-01, 1.1360e-01, 1.1240e-01, 1.1120e-01, 1.1010e-01, 1.0890e-01, 1.0780e-01, 1.0670e-01, 1.0560e-01, 1.0450e-01, 1.0340e-01, 1.0240e-01, 1.0140e-01, 1.0040e-01, 9.9400e-02, 9.8400e-02, 9.7400e-02, 9.6500e-02, 9.5500e-02, 9.4600e-02, 9.3700e-02, 9.2800e-02, 9.1900e-02, 9.1000e-02, 9.0200e-02, 8.9300e-02, 8.8500e-02, 8.7700e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7200e-02, 7.6500e-02, 7.5800e-02, 7.5200e-02, 7.4500e-02, 7.3900e-02, 7.3300e-02, 7.2600e-02, 7.2000e-02, 7.1400e-02, 7.0800e-02, 7.0200e-02, 6.9600e-02, 6.9000e-02, 6.8500e-02, 6.7900e-02, 6.7300e-02, 6.6800e-02, 6.6200e-02, 6.5700e-02, 6.5200e-02, 6.4600e-02, 6.4100e-02, 6.3600e-02, 6.3100e-02, 6.2600e-02}); + } + break; + case 101: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0100e+02, 1.0060e+02, 9.9474e+01, 9.7830e+01, 9.5865e+01, 9.3715e+01, 9.1450e+01, 8.9105e+01, 8.6703e+01, 8.4269e+01, 8.1830e+01, 7.9413e+01, 7.7042e+01, 7.4737e+01, 7.2511e+01, 7.0375e+01, 6.8334e+01, 6.6388e+01, 6.4537e+01, 6.2779e+01, 6.1109e+01, 5.9523e+01, 5.8014e+01, 5.6580e+01, 5.5213e+01, 5.3910e+01, 5.2667e+01, 5.1478e+01, 5.0341e+01, 4.9252e+01, 4.8208e+01, 4.7205e+01, 4.6242e+01, 4.5317e+01, 4.4425e+01, 4.3567e+01, 4.2739e+01, 4.1940e+01, 4.1167e+01, 4.0420e+01, 3.9697e+01, 3.8996e+01, 3.8315e+01, 3.7654e+01, 3.7011e+01, 3.6385e+01, 3.5775e+01, 3.5180e+01, 3.4598e+01, 3.4029e+01, 3.3473e+01, 3.2928e+01, 3.2393e+01, 3.1869e+01, 3.1354e+01, 3.0849e+01, 3.0352e+01, 2.9864e+01, 2.9384e+01, 2.8911e+01, 2.8447e+01, 2.7991e+01, 2.7541e+01, 2.7100e+01, 2.6666e+01, 2.6239e+01, 2.5820e+01, 2.5408e+01, 2.5004e+01, 2.4607e+01, 2.4218e+01, 2.3837e+01, 2.3463e+01, 2.3097e+01, 2.2739e+01, 2.2389e+01, 2.2047e+01, 2.1712e+01, 2.1386e+01, 2.1067e+01, 2.0757e+01, 2.0455e+01, 2.0160e+01, 1.9873e+01, 1.9594e+01, 1.9323e+01, 1.9060e+01, 1.8804e+01, 1.8556e+01, 1.8315e+01, 1.8081e+01, 1.7855e+01, 1.7636e+01, 1.7422e+01, 1.7216e+01, 1.7017e+01, 1.6824e+01, 1.6637e+01, 1.6455e+01, 1.6280e+01, 1.6110e+01, 1.5946e+01, 1.5787e+01, 1.5633e+01, 1.5483e+01, 1.5338e+01, 1.5198e+01, 1.5063e+01, 1.4931e+01, 1.4803e+01, 1.4678e+01, 1.4556e+01, 1.4439e+01, 1.4325e+01, 1.4214e+01, 1.4105e+01, 1.3999e+01, 1.3894e+01, 1.3793e+01, 1.3694e+01, 1.3598e+01, 1.3503e+01, 1.3410e+01, 1.3317e+01, 1.3226e+01, 1.3137e+01, 1.3050e+01, 1.2965e+01, 1.2880e+01, 1.2796e+01, 1.2712e+01, 1.2629e+01, 1.2547e+01, 1.2466e+01, 1.2387e+01, 1.2308e+01, 1.2229e+01, 1.2150e+01, 1.2071e+01, 1.1992e+01, 1.1915e+01, 1.1838e+01, 1.1762e+01, 1.1686e+01, 1.1610e+01, 1.1533e+01, 1.1456e+01, 1.1379e+01, 1.1303e+01, 1.1228e+01, 1.1153e+01, 1.1079e+01, 1.1005e+01, 1.0929e+01, 1.0854e+01, 1.0777e+01, 1.0702e+01, 1.0628e+01, 1.0554e+01, 1.0481e+01, 1.0408e+01, 1.0334e+01, 1.0260e+01, 1.0186e+01, 1.0111e+01, 1.0037e+01, 9.9646e+00, 9.8927e+00, 9.8214e+00, 9.7502e+00, 9.6791e+00, 9.6079e+00, 9.5363e+00, 9.4643e+00, 9.3926e+00, 9.3221e+00, 9.2529e+00, 9.1846e+00, 9.1166e+00, 9.0490e+00, 8.9817e+00, 8.9145e+00, 8.8470e+00, 8.7793e+00, 8.7119e+00, 8.6457e+00, 8.5810e+00, 8.5175e+00, 8.4545e+00, 8.3919e+00, 8.3297e+00, 8.2681e+00, 8.2066e+00, 8.1449e+00, 8.0830e+00, 8.0218e+00, 7.9622e+00, 7.9042e+00, 7.8474e+00, 7.7909e+00, 7.7349e+00, 7.6795e+00, 7.6247e+00, 7.5704e+00, 7.5158e+00, 7.4610e+00, 7.4067e+00, 7.3537e+00, 7.3025e+00, 7.2528e+00, 7.2038e+00, 7.1551e+00, 7.1068e+00, 7.0593e+00, 7.0125e+00, 6.9660e+00, 6.9193e+00, 6.8723e+00, 6.8257e+00, 6.7805e+00, 6.7372e+00, 6.6954e+00, 6.6543e+00, 6.6135e+00, 6.5729e+00, 6.5330e+00, 6.4939e+00, 6.4554e+00, 6.4168e+00, 6.3778e+00, 6.3386e+00, 6.3001e+00, 6.2631e+00, 6.2280e+00, 6.1942e+00, 6.1610e+00, 6.1279e+00, 6.0948e+00, 6.0624e+00, 6.0308e+00, 5.9998e+00}); + feg = Vctr_cpu({1.5723e+01, 1.5421e+01, 1.4606e+01, 1.3489e+01, 1.2291e+01, 1.1159e+01, 1.0158e+01, 9.2959e+00, 8.5543e+00, 7.9097e+00, 7.3408e+00, 6.8317e+00, 6.3710e+00, 5.9510e+00, 5.5660e+00, 5.2122e+00, 4.8864e+00, 4.5862e+00, 4.3095e+00, 4.0543e+00, 3.8189e+00, 3.6016e+00, 3.4010e+00, 3.2155e+00, 3.0440e+00, 2.8852e+00, 2.7380e+00, 2.6014e+00, 2.4744e+00, 2.3563e+00, 2.2463e+00, 2.1436e+00, 2.0477e+00, 1.9581e+00, 1.8741e+00, 1.7954e+00, 1.7215e+00, 1.6520e+00, 1.5867e+00, 1.5252e+00, 1.4672e+00, 1.4125e+00, 1.3608e+00, 1.3119e+00, 1.2657e+00, 1.2219e+00, 1.1804e+00, 1.1410e+00, 1.1036e+00, 1.0681e+00, 1.0343e+00, 1.0022e+00, 9.7160e-01, 9.4240e-01, 9.1460e-01, 8.8810e-01, 8.6270e-01, 8.3840e-01, 8.1520e-01, 7.9300e-01, 7.7180e-01, 7.5140e-01, 7.3180e-01, 7.1300e-01, 6.9500e-01, 6.7760e-01, 6.6090e-01, 6.4480e-01, 6.2940e-01, 6.1440e-01, 6.0010e-01, 5.8620e-01, 5.7280e-01, 5.5980e-01, 5.4730e-01, 5.3520e-01, 5.2340e-01, 5.1210e-01, 5.0110e-01, 4.9050e-01, 4.8010e-01, 4.7010e-01, 4.6040e-01, 4.5100e-01, 4.4180e-01, 4.3290e-01, 4.2430e-01, 4.1590e-01, 4.0770e-01, 3.9970e-01, 3.9200e-01, 3.8450e-01, 3.7720e-01, 3.7000e-01, 3.6310e-01, 3.5630e-01, 3.4980e-01, 3.4340e-01, 3.3710e-01, 3.3100e-01, 3.2510e-01, 3.1930e-01, 3.1360e-01, 3.0810e-01, 3.0280e-01, 2.9750e-01, 2.9240e-01, 2.8740e-01, 2.8260e-01, 2.7780e-01, 2.7320e-01, 2.6870e-01, 2.6430e-01, 2.5990e-01, 2.5570e-01, 2.5160e-01, 2.4760e-01, 2.4370e-01, 2.3980e-01, 2.3610e-01, 2.3240e-01, 2.2880e-01, 2.2540e-01, 2.2190e-01, 2.1860e-01, 2.1530e-01, 2.1210e-01, 2.0900e-01, 2.0600e-01, 2.0300e-01, 2.0010e-01, 1.9720e-01, 1.9440e-01, 1.9170e-01, 1.8900e-01, 1.8640e-01, 1.8380e-01, 1.8130e-01, 1.7880e-01, 1.7640e-01, 1.7410e-01, 1.7170e-01, 1.6950e-01, 1.6730e-01, 1.6510e-01, 1.6300e-01, 1.6090e-01, 1.5880e-01, 1.5680e-01, 1.5480e-01, 1.5290e-01, 1.5100e-01, 1.4920e-01, 1.4730e-01, 1.4560e-01, 1.4380e-01, 1.4210e-01, 1.4040e-01, 1.3870e-01, 1.3710e-01, 1.3550e-01, 1.3390e-01, 1.3240e-01, 1.3090e-01, 1.2940e-01, 1.2790e-01, 1.2650e-01, 1.2510e-01, 1.2370e-01, 1.2230e-01, 1.2100e-01, 1.1970e-01, 1.1840e-01, 1.1710e-01, 1.1590e-01, 1.1460e-01, 1.1340e-01, 1.1220e-01, 1.1110e-01, 1.0990e-01, 1.0880e-01, 1.0760e-01, 1.0650e-01, 1.0550e-01, 1.0440e-01, 1.0330e-01, 1.0230e-01, 1.0130e-01, 1.0030e-01, 9.9300e-02, 9.8300e-02, 9.7300e-02, 9.6400e-02, 9.5500e-02, 9.4500e-02, 9.3600e-02, 9.2700e-02, 9.1900e-02, 9.1000e-02, 9.0100e-02, 8.9300e-02, 8.8500e-02, 8.7600e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4500e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7200e-02, 7.6500e-02, 7.5900e-02, 7.5200e-02, 7.4600e-02, 7.3900e-02, 7.3300e-02, 7.2700e-02, 7.2100e-02, 7.1500e-02, 7.0900e-02, 7.0300e-02, 6.9700e-02, 6.9100e-02, 6.8500e-02, 6.8000e-02, 6.7400e-02, 6.6800e-02, 6.6300e-02, 6.5800e-02, 6.5200e-02, 6.4700e-02, 6.4200e-02, 6.3700e-02, 6.3200e-02}); + } + break; + case 102: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0200e+02, 1.0161e+02, 1.0050e+02, 9.8878e+01, 9.6930e+01, 9.4791e+01, 9.2532e+01, 9.0188e+01, 8.7783e+01, 8.5340e+01, 8.2888e+01, 8.0451e+01, 7.8055e+01, 7.5720e+01, 7.3461e+01, 7.1289e+01, 6.9209e+01, 6.7225e+01, 6.5336e+01, 6.3540e+01, 6.1833e+01, 6.0212e+01, 5.8672e+01, 5.7208e+01, 5.5814e+01, 5.4486e+01, 5.3221e+01, 5.2013e+01, 5.0858e+01, 4.9754e+01, 4.8697e+01, 4.7683e+01, 4.6710e+01, 4.5776e+01, 4.4878e+01, 4.4013e+01, 4.3181e+01, 4.2377e+01, 4.1602e+01, 4.0852e+01, 4.0127e+01, 3.9425e+01, 3.8744e+01, 3.8082e+01, 3.7439e+01, 3.6814e+01, 3.6204e+01, 3.5609e+01, 3.5029e+01, 3.4461e+01, 3.3906e+01, 3.3361e+01, 3.2828e+01, 3.2305e+01, 3.1791e+01, 3.1287e+01, 3.0791e+01, 3.0304e+01, 2.9824e+01, 2.9352e+01, 2.8888e+01, 2.8432e+01, 2.7982e+01, 2.7540e+01, 2.7105e+01, 2.6677e+01, 2.6256e+01, 2.5842e+01, 2.5436e+01, 2.5036e+01, 2.4644e+01, 2.4259e+01, 2.3882e+01, 2.3512e+01, 2.3150e+01, 2.2795e+01, 2.2448e+01, 2.2108e+01, 2.1776e+01, 2.1452e+01, 2.1136e+01, 2.0827e+01, 2.0526e+01, 2.0233e+01, 1.9947e+01, 1.9669e+01, 1.9398e+01, 1.9136e+01, 1.8880e+01, 1.8632e+01, 1.8391e+01, 1.8157e+01, 1.7930e+01, 1.7710e+01, 1.7497e+01, 1.7291e+01, 1.7090e+01, 1.6896e+01, 1.6708e+01, 1.6526e+01, 1.6350e+01, 1.6179e+01, 1.6013e+01, 1.5853e+01, 1.5698e+01, 1.5548e+01, 1.5403e+01, 1.5261e+01, 1.5124e+01, 1.4991e+01, 1.4862e+01, 1.4737e+01, 1.4616e+01, 1.4497e+01, 1.4381e+01, 1.4269e+01, 1.4159e+01, 1.4054e+01, 1.3950e+01, 1.3848e+01, 1.3748e+01, 1.3650e+01, 1.3555e+01, 1.3462e+01, 1.3371e+01, 1.3281e+01, 1.3192e+01, 1.3104e+01, 1.3017e+01, 1.2932e+01, 1.2849e+01, 1.2767e+01, 1.2686e+01, 1.2605e+01, 1.2524e+01, 1.2444e+01, 1.2364e+01, 1.2286e+01, 1.2209e+01, 1.2133e+01, 1.2056e+01, 1.1979e+01, 1.1902e+01, 1.1826e+01, 1.1749e+01, 1.1675e+01, 1.1600e+01, 1.1527e+01, 1.1452e+01, 1.1377e+01, 1.1302e+01, 1.1227e+01, 1.1152e+01, 1.1078e+01, 1.1005e+01, 1.0933e+01, 1.0860e+01, 1.0786e+01, 1.0713e+01, 1.0639e+01, 1.0565e+01, 1.0491e+01, 1.0418e+01, 1.0347e+01, 1.0276e+01, 1.0204e+01, 1.0132e+01, 1.0060e+01, 9.9875e+00, 9.9152e+00, 9.8432e+00, 9.7723e+00, 9.7026e+00, 9.6336e+00, 9.5645e+00, 9.4952e+00, 9.4257e+00, 9.3563e+00, 9.2869e+00, 9.2176e+00, 9.1490e+00, 9.0817e+00, 9.0157e+00, 8.9505e+00, 8.8853e+00, 8.8199e+00, 8.7546e+00, 8.6895e+00, 8.6247e+00, 8.5601e+00, 8.4959e+00, 8.4329e+00, 8.3715e+00, 8.3113e+00, 8.2516e+00, 8.1918e+00, 8.1320e+00, 8.0725e+00, 8.0135e+00, 7.9548e+00, 7.8963e+00, 7.8384e+00, 7.7817e+00, 7.7268e+00, 7.6733e+00, 7.6203e+00, 7.5673e+00, 7.5142e+00, 7.4615e+00, 7.4094e+00, 7.3579e+00, 7.3065e+00, 7.2554e+00, 7.2052e+00, 7.1565e+00, 7.1096e+00, 7.0639e+00, 7.0185e+00, 6.9730e+00, 6.9275e+00, 6.8823e+00, 6.8380e+00, 6.7941e+00, 6.7505e+00, 6.7070e+00, 6.6641e+00, 6.6226e+00, 6.5828e+00, 6.5446e+00, 6.5070e+00, 6.4694e+00, 6.4315e+00, 6.3936e+00, 6.3563e+00, 6.3198e+00, 6.2837e+00, 6.2477e+00, 6.2117e+00, 6.1762e+00, 6.1421e+00, 6.1097e+00}); + feg = Vctr_cpu({1.5397e+01, 1.5114e+01, 1.4345e+01, 1.3284e+01, 1.2135e+01, 1.1043e+01, 1.0071e+01, 9.2310e+00, 8.5067e+00, 7.8761e+00, 7.3189e+00, 6.8198e+00, 6.3676e+00, 5.9548e+00, 5.5758e+00, 5.2268e+00, 4.9050e+00, 4.6079e+00, 4.3334e+00, 4.0798e+00, 3.8453e+00, 3.6286e+00, 3.4281e+00, 3.2425e+00, 3.0706e+00, 2.9112e+00, 2.7632e+00, 2.6258e+00, 2.4980e+00, 2.3790e+00, 2.2680e+00, 2.1644e+00, 2.0676e+00, 1.9771e+00, 1.8922e+00, 1.8127e+00, 1.7380e+00, 1.6678e+00, 1.6017e+00, 1.5395e+00, 1.4808e+00, 1.4255e+00, 1.3732e+00, 1.3238e+00, 1.2770e+00, 1.2327e+00, 1.1907e+00, 1.1509e+00, 1.1131e+00, 1.0772e+00, 1.0430e+00, 1.0105e+00, 9.7960e-01, 9.5010e-01, 9.2200e-01, 8.9520e-01, 8.6950e-01, 8.4500e-01, 8.2160e-01, 7.9920e-01, 7.7770e-01, 7.5710e-01, 7.3740e-01, 7.1840e-01, 7.0020e-01, 6.8270e-01, 6.6590e-01, 6.4970e-01, 6.3410e-01, 6.1900e-01, 6.0450e-01, 5.9060e-01, 5.7710e-01, 5.6400e-01, 5.5140e-01, 5.3920e-01, 5.2740e-01, 5.1600e-01, 5.0490e-01, 4.9420e-01, 4.8380e-01, 4.7380e-01, 4.6400e-01, 4.5450e-01, 4.4530e-01, 4.3640e-01, 4.2770e-01, 4.1920e-01, 4.1100e-01, 4.0300e-01, 3.9530e-01, 3.8770e-01, 3.8040e-01, 3.7320e-01, 3.6620e-01, 3.5940e-01, 3.5280e-01, 3.4640e-01, 3.4010e-01, 3.3400e-01, 3.2800e-01, 3.2220e-01, 3.1650e-01, 3.1100e-01, 3.0550e-01, 3.0030e-01, 2.9510e-01, 2.9010e-01, 2.8520e-01, 2.8040e-01, 2.7580e-01, 2.7120e-01, 2.6680e-01, 2.6240e-01, 2.5820e-01, 2.5400e-01, 2.5000e-01, 2.4600e-01, 2.4220e-01, 2.3840e-01, 2.3470e-01, 2.3110e-01, 2.2760e-01, 2.2410e-01, 2.2070e-01, 2.1740e-01, 2.1420e-01, 2.1110e-01, 2.0800e-01, 2.0500e-01, 2.0200e-01, 1.9910e-01, 1.9630e-01, 1.9350e-01, 1.9080e-01, 1.8820e-01, 1.8560e-01, 1.8300e-01, 1.8060e-01, 1.7810e-01, 1.7570e-01, 1.7340e-01, 1.7110e-01, 1.6890e-01, 1.6670e-01, 1.6450e-01, 1.6240e-01, 1.6030e-01, 1.5830e-01, 1.5630e-01, 1.5440e-01, 1.5250e-01, 1.5060e-01, 1.4870e-01, 1.4690e-01, 1.4520e-01, 1.4340e-01, 1.4170e-01, 1.4000e-01, 1.3840e-01, 1.3680e-01, 1.3520e-01, 1.3360e-01, 1.3210e-01, 1.3060e-01, 1.2910e-01, 1.2770e-01, 1.2620e-01, 1.2480e-01, 1.2350e-01, 1.2210e-01, 1.2080e-01, 1.1950e-01, 1.1820e-01, 1.1690e-01, 1.1570e-01, 1.1440e-01, 1.1320e-01, 1.1210e-01, 1.1090e-01, 1.0970e-01, 1.0860e-01, 1.0750e-01, 1.0640e-01, 1.0530e-01, 1.0430e-01, 1.0320e-01, 1.0220e-01, 1.0120e-01, 1.0020e-01, 9.9200e-02, 9.8200e-02, 9.7300e-02, 9.6300e-02, 9.5400e-02, 9.4500e-02, 9.3600e-02, 9.2700e-02, 9.1800e-02, 9.0900e-02, 9.0100e-02, 8.9300e-02, 8.8400e-02, 8.7600e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7200e-02, 7.6600e-02, 7.5900e-02, 7.5300e-02, 7.4600e-02, 7.4000e-02, 7.3300e-02, 7.2700e-02, 7.2100e-02, 7.1500e-02, 7.0900e-02, 7.0300e-02, 6.9700e-02, 6.9200e-02, 6.8600e-02, 6.8000e-02, 6.7500e-02, 6.6900e-02, 6.6400e-02, 6.5800e-02, 6.5300e-02, 6.4800e-02, 6.4300e-02, 6.3800e-02}); + } + break; + case 103: + { + g = Vctr_cpu({0.0000e+00, 5.0000e-02, 1.0000e-01, 1.5000e-01, 2.0000e-01, 2.5000e-01, 3.0000e-01, 3.5000e-01, 4.0000e-01, 4.5000e-01, 5.0000e-01, 5.5000e-01, 6.0000e-01, 6.5000e-01, 7.0000e-01, 7.5000e-01, 8.0000e-01, 8.5000e-01, 9.0000e-01, 9.5000e-01, 1.0000e+00, 1.0500e+00, 1.1000e+00, 1.1500e+00, 1.2000e+00, 1.2500e+00, 1.3000e+00, 1.3500e+00, 1.4000e+00, 1.4500e+00, 1.5000e+00, 1.5500e+00, 1.6000e+00, 1.6500e+00, 1.7000e+00, 1.7500e+00, 1.8000e+00, 1.8500e+00, 1.9000e+00, 1.9500e+00, 2.0000e+00, 2.0500e+00, 2.1000e+00, 2.1500e+00, 2.2000e+00, 2.2500e+00, 2.3000e+00, 2.3500e+00, 2.4000e+00, 2.4500e+00, 2.5000e+00, 2.5500e+00, 2.6000e+00, 2.6500e+00, 2.7000e+00, 2.7500e+00, 2.8000e+00, 2.8500e+00, 2.9000e+00, 2.9500e+00, 3.0000e+00, 3.0500e+00, 3.1000e+00, 3.1500e+00, 3.2000e+00, 3.2500e+00, 3.3000e+00, 3.3500e+00, 3.4000e+00, 3.4500e+00, 3.5000e+00, 3.5500e+00, 3.6000e+00, 3.6500e+00, 3.7000e+00, 3.7500e+00, 3.8000e+00, 3.8500e+00, 3.9000e+00, 3.9500e+00, 4.0000e+00, 4.0500e+00, 4.1000e+00, 4.1500e+00, 4.2000e+00, 4.2500e+00, 4.3000e+00, 4.3500e+00, 4.4000e+00, 4.4500e+00, 4.5000e+00, 4.5500e+00, 4.6000e+00, 4.6500e+00, 4.7000e+00, 4.7500e+00, 4.8000e+00, 4.8500e+00, 4.9000e+00, 4.9500e+00, 5.0000e+00, 5.0500e+00, 5.1000e+00, 5.1500e+00, 5.2000e+00, 5.2500e+00, 5.3000e+00, 5.3500e+00, 5.4000e+00, 5.4500e+00, 5.5000e+00, 5.5500e+00, 5.6000e+00, 5.6500e+00, 5.7000e+00, 5.7500e+00, 5.8000e+00, 5.8500e+00, 5.9000e+00, 5.9500e+00, 6.0000e+00, 6.0500e+00, 6.1000e+00, 6.1500e+00, 6.2000e+00, 6.2500e+00, 6.3000e+00, 6.3500e+00, 6.4000e+00, 6.4500e+00, 6.5000e+00, 6.5500e+00, 6.6000e+00, 6.6500e+00, 6.7000e+00, 6.7500e+00, 6.8000e+00, 6.8500e+00, 6.9000e+00, 6.9500e+00, 7.0000e+00, 7.0500e+00, 7.1000e+00, 7.1500e+00, 7.2000e+00, 7.2500e+00, 7.3000e+00, 7.3500e+00, 7.4000e+00, 7.4500e+00, 7.5000e+00, 7.5500e+00, 7.6000e+00, 7.6500e+00, 7.7000e+00, 7.7500e+00, 7.8000e+00, 7.8500e+00, 7.9000e+00, 7.9500e+00, 8.0000e+00, 8.0500e+00, 8.1000e+00, 8.1500e+00, 8.2000e+00, 8.2500e+00, 8.3000e+00, 8.3500e+00, 8.4000e+00, 8.4500e+00, 8.5000e+00, 8.5500e+00, 8.6000e+00, 8.6500e+00, 8.7000e+00, 8.7500e+00, 8.8000e+00, 8.8500e+00, 8.9000e+00, 8.9500e+00, 9.0000e+00, 9.0500e+00, 9.1000e+00, 9.1500e+00, 9.2000e+00, 9.2500e+00, 9.3000e+00, 9.3500e+00, 9.4000e+00, 9.4500e+00, 9.5000e+00, 9.5500e+00, 9.6000e+00, 9.6500e+00, 9.7000e+00, 9.7500e+00, 9.8000e+00, 9.8500e+00, 9.9000e+00, 9.9500e+00, 1.0000e+01, 1.0050e+01, 1.0100e+01, 1.0150e+01, 1.0200e+01, 1.0250e+01, 1.0300e+01, 1.0350e+01, 1.0400e+01, 1.0450e+01, 1.0500e+01, 1.0550e+01, 1.0600e+01, 1.0650e+01, 1.0700e+01, 1.0750e+01, 1.0800e+01, 1.0850e+01, 1.0900e+01, 1.0950e+01, 1.1000e+01, 1.1050e+01, 1.1100e+01, 1.1150e+01, 1.1200e+01, 1.1250e+01, 1.1300e+01, 1.1350e+01, 1.1400e+01, 1.1450e+01, 1.1500e+01, 1.1550e+01, 1.1600e+01, 1.1650e+01, 1.1700e+01, 1.1750e+01, 1.1800e+01, 1.1850e+01, 1.1900e+01, 1.1950e+01, 1.2000e+01}); + fxg = Vctr_cpu({1.0300e+02, 1.0259e+02, 1.0146e+02, 9.9776e+01, 9.7763e+01, 9.5565e+01, 9.3270e+01, 9.0917e+01, 8.8527e+01, 8.6115e+01, 8.3699e+01, 8.1297e+01, 7.8928e+01, 7.6609e+01, 7.4355e+01, 7.2178e+01, 7.0084e+01, 6.8078e+01, 6.6163e+01, 6.4338e+01, 6.2601e+01, 6.0949e+01, 5.9378e+01, 5.7884e+01, 5.6463e+01, 5.5110e+01, 5.3820e+01, 5.2591e+01, 5.1416e+01, 5.0294e+01, 4.9221e+01, 4.8193e+01, 4.7207e+01, 4.6261e+01, 4.5353e+01, 4.4479e+01, 4.3638e+01, 4.2828e+01, 4.2046e+01, 4.1291e+01, 4.0561e+01, 3.9855e+01, 3.9170e+01, 3.8506e+01, 3.7860e+01, 3.7233e+01, 3.6622e+01, 3.6026e+01, 3.5445e+01, 3.4877e+01, 3.4322e+01, 3.3779e+01, 3.3246e+01, 3.2724e+01, 3.2211e+01, 3.1708e+01, 3.1213e+01, 3.0727e+01, 3.0248e+01, 2.9778e+01, 2.9314e+01, 2.8858e+01, 2.8409e+01, 2.7968e+01, 2.7532e+01, 2.7104e+01, 2.6683e+01, 2.6268e+01, 2.5861e+01, 2.5460e+01, 2.5066e+01, 2.4679e+01, 2.4299e+01, 2.3927e+01, 2.3561e+01, 2.3203e+01, 2.2852e+01, 2.2508e+01, 2.2171e+01, 2.1842e+01, 2.1520e+01, 2.1206e+01, 2.0900e+01, 2.0601e+01, 2.0309e+01, 2.0024e+01, 1.9747e+01, 1.9478e+01, 1.9216e+01, 1.8960e+01, 1.8712e+01, 1.8472e+01, 1.8238e+01, 1.8011e+01, 1.7790e+01, 1.7576e+01, 1.7369e+01, 1.7169e+01, 1.6974e+01, 1.6785e+01, 1.6602e+01, 1.6424e+01, 1.6253e+01, 1.6087e+01, 1.5925e+01, 1.5769e+01, 1.5617e+01, 1.5470e+01, 1.5328e+01, 1.5190e+01, 1.5056e+01, 1.4926e+01, 1.4799e+01, 1.4676e+01, 1.4557e+01, 1.4442e+01, 1.4329e+01, 1.4219e+01, 1.4111e+01, 1.4006e+01, 1.3904e+01, 1.3804e+01, 1.3707e+01, 1.3612e+01, 1.3518e+01, 1.3425e+01, 1.3334e+01, 1.3246e+01, 1.3159e+01, 1.3074e+01, 1.2990e+01, 1.2906e+01, 1.2823e+01, 1.2741e+01, 1.2660e+01, 1.2581e+01, 1.2503e+01, 1.2426e+01, 1.2348e+01, 1.2271e+01, 1.2193e+01, 1.2116e+01, 1.2041e+01, 1.1966e+01, 1.1893e+01, 1.1819e+01, 1.1745e+01, 1.1670e+01, 1.1595e+01, 1.1520e+01, 1.1447e+01, 1.1374e+01, 1.1303e+01, 1.1231e+01, 1.1158e+01, 1.1085e+01, 1.1012e+01, 1.0938e+01, 1.0865e+01, 1.0793e+01, 1.0722e+01, 1.0651e+01, 1.0581e+01, 1.0509e+01, 1.0438e+01, 1.0365e+01, 1.0293e+01, 1.0221e+01, 1.0150e+01, 1.0080e+01, 1.0011e+01, 9.9421e+00, 9.8728e+00, 9.8032e+00, 9.7331e+00, 9.6627e+00, 9.5924e+00, 9.5231e+00, 9.4552e+00, 9.3885e+00, 9.3223e+00, 9.2560e+00, 9.1897e+00, 9.1234e+00, 9.0568e+00, 8.9899e+00, 8.9232e+00, 8.8573e+00, 8.7931e+00, 8.7303e+00, 8.6683e+00, 8.6065e+00, 8.5447e+00, 8.4831e+00, 8.4217e+00, 8.3601e+00, 8.2983e+00, 8.2370e+00, 8.1768e+00, 8.1183e+00, 8.0614e+00, 8.0053e+00, 7.9494e+00, 7.8936e+00, 7.8381e+00, 7.7830e+00, 7.7280e+00, 7.6728e+00, 7.6177e+00, 7.5635e+00, 7.5109e+00, 7.4602e+00, 7.4107e+00, 7.3618e+00, 7.3129e+00, 7.2642e+00, 7.2160e+00, 7.1683e+00, 7.1207e+00, 7.0729e+00, 7.0252e+00, 6.9782e+00, 6.9328e+00, 6.8894e+00, 6.8474e+00, 6.8060e+00, 6.7647e+00, 6.7234e+00, 6.6825e+00, 6.6422e+00, 6.6023e+00, 6.5624e+00, 6.5222e+00, 6.4821e+00, 6.4429e+00, 6.4053e+00, 6.3697e+00, 6.3355e+00, 6.3017e+00, 6.2679e+00, 6.2339e+00}); + feg = Vctr_cpu({1.5837e+01, 1.5556e+01, 1.4789e+01, 1.3716e+01, 1.2535e+01, 1.1388e+01, 1.0350e+01, 9.4431e+00, 8.6599e+00, 7.9825e+00, 7.3910e+00, 6.8685e+00, 6.4014e+00, 5.9799e+00, 5.5965e+00, 5.2458e+00, 4.9238e+00, 4.6273e+00, 4.3538e+00, 4.1012e+00, 3.8676e+00, 3.6515e+00, 3.4513e+00, 3.2659e+00, 3.0939e+00, 2.9342e+00, 2.7859e+00, 2.6480e+00, 2.5196e+00, 2.3999e+00, 2.2882e+00, 2.1840e+00, 2.0864e+00, 1.9952e+00, 1.9096e+00, 1.8294e+00, 1.7540e+00, 1.6831e+00, 1.6165e+00, 1.5536e+00, 1.4944e+00, 1.4385e+00, 1.3857e+00, 1.3357e+00, 1.2885e+00, 1.2437e+00, 1.2013e+00, 1.1610e+00, 1.1228e+00, 1.0865e+00, 1.0520e+00, 1.0191e+00, 9.8790e-01, 9.5800e-01, 9.2960e-01, 9.0250e-01, 8.7660e-01, 8.5180e-01, 8.2820e-01, 8.0550e-01, 7.8380e-01, 7.6300e-01, 7.4310e-01, 7.2390e-01, 7.0560e-01, 6.8790e-01, 6.7090e-01, 6.5460e-01, 6.3880e-01, 6.2370e-01, 6.0910e-01, 5.9500e-01, 5.8140e-01, 5.6820e-01, 5.5550e-01, 5.4320e-01, 5.3140e-01, 5.1990e-01, 5.0880e-01, 4.9800e-01, 4.8750e-01, 4.7740e-01, 4.6760e-01, 4.5800e-01, 4.4880e-01, 4.3980e-01, 4.3110e-01, 4.2260e-01, 4.1430e-01, 4.0630e-01, 3.9850e-01, 3.9090e-01, 3.8350e-01, 3.7630e-01, 3.6930e-01, 3.6250e-01, 3.5580e-01, 3.4930e-01, 3.4300e-01, 3.3690e-01, 3.3090e-01, 3.2500e-01, 3.1930e-01, 3.1370e-01, 3.0830e-01, 3.0300e-01, 2.9780e-01, 2.9280e-01, 2.8780e-01, 2.8300e-01, 2.7830e-01, 2.7370e-01, 2.6930e-01, 2.6490e-01, 2.6060e-01, 2.5640e-01, 2.5230e-01, 2.4840e-01, 2.4450e-01, 2.4070e-01, 2.3690e-01, 2.3330e-01, 2.2970e-01, 2.2630e-01, 2.2290e-01, 2.1950e-01, 2.1630e-01, 2.1310e-01, 2.1000e-01, 2.0690e-01, 2.0400e-01, 2.0100e-01, 1.9820e-01, 1.9540e-01, 1.9270e-01, 1.9000e-01, 1.8740e-01, 1.8480e-01, 1.8230e-01, 1.7980e-01, 1.7740e-01, 1.7510e-01, 1.7270e-01, 1.7050e-01, 1.6830e-01, 1.6610e-01, 1.6390e-01, 1.6180e-01, 1.5980e-01, 1.5780e-01, 1.5580e-01, 1.5390e-01, 1.5200e-01, 1.5010e-01, 1.4830e-01, 1.4650e-01, 1.4470e-01, 1.4300e-01, 1.4130e-01, 1.3970e-01, 1.3800e-01, 1.3640e-01, 1.3490e-01, 1.3330e-01, 1.3180e-01, 1.3030e-01, 1.2880e-01, 1.2740e-01, 1.2600e-01, 1.2460e-01, 1.2320e-01, 1.2190e-01, 1.2050e-01, 1.1920e-01, 1.1800e-01, 1.1670e-01, 1.1550e-01, 1.1430e-01, 1.1310e-01, 1.1190e-01, 1.1070e-01, 1.0960e-01, 1.0850e-01, 1.0730e-01, 1.0630e-01, 1.0520e-01, 1.0410e-01, 1.0310e-01, 1.0210e-01, 1.0110e-01, 1.0010e-01, 9.9100e-02, 9.8100e-02, 9.7200e-02, 9.6200e-02, 9.5300e-02, 9.4400e-02, 9.3500e-02, 9.2600e-02, 9.1700e-02, 9.0900e-02, 9.0000e-02, 8.9200e-02, 8.8400e-02, 8.7600e-02, 8.6800e-02, 8.6000e-02, 8.5200e-02, 8.4400e-02, 8.3700e-02, 8.2900e-02, 8.2200e-02, 8.1400e-02, 8.0700e-02, 8.0000e-02, 7.9300e-02, 7.8600e-02, 7.7900e-02, 7.7300e-02, 7.6600e-02, 7.5900e-02, 7.5300e-02, 7.4600e-02, 7.4000e-02, 7.3400e-02, 7.2800e-02, 7.2200e-02, 7.1500e-02, 7.1000e-02, 7.0400e-02, 6.9800e-02, 6.9200e-02, 6.8600e-02, 6.8100e-02, 6.7500e-02, 6.7000e-02, 6.6400e-02, 6.5900e-02, 6.5400e-02, 6.4800e-02, 6.4300e-02}); + } + break; + } + } + + void load_fxeg_lobato(const dt_int32 Z, Vctr_cpu& g, Vctr_cpu& fxg, Vctr_cpu& feg) + { + + } + }; + } #endif \ No newline at end of file diff --git a/src/fxeg_tabulated_data.hpp b/src/fxeg_tabulated_data.hpp new file mode 100755 index 00000000..bb38d253 --- /dev/null +++ b/src/fxeg_tabulated_data.hpp @@ -0,0 +1,24540 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef FXEG_TABULATED_DATA_H +#define FXEG_TABULATED_DATA_H + +#ifdef _MSC_VER +#pragma once +#endif// _MSC_VER + +#include "math.cuh" +#include "types.cuh" + +class fxeg_Tabulated_Data{ + public: + void ReadTabData(int Z_i, int Type_i, int dng_i, int &n_o, double *g_o, double *g2_o, double *fx_o, double *fe_o) + { + + switch(Type_i) + { + case 0: + { + fxegActaCrys(Z_i); + } + break; + case 1: + { + fxegRez(Z_i); + } + break; + case 2: + { + fxegKirkland(Z_i); + } + break; + case 3: + { + fxegLobato(Z_i); + } + break; + } + + if(dng_i == 0 ) + { + dng_i = 1; + } + + int i = 0, j = 0; + + while (j0) + { + feg[i] = (Z-fxg[i])/(mt::c_2Pi2a0*g2[i]); + } + } + + g.resize(ng); + g2.resize(ng); + fxg.resize(ng); + feg.resize(ng); + } + + void fxegLobato(int Z) + { + + } + + mt::Vector g; + mt::Vector g2; + mt::Vector feg; + mt::Vector fxg; +}; + +#endif \ No newline at end of file diff --git a/src/gpu_detail.cuh b/src/gpu_detail.cuh new file mode 100755 index 00000000..34af0969 --- /dev/null +++ b/src/gpu_detail.cuh @@ -0,0 +1,719 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +// #if defined __CUDACC__ && !defined GPU_DETAIL_H + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "fcn_cos_tap.h" +#include "fcn_gauss.h" +#include "fcn_exp.h" +#include "fcn_fermi.h" +#include "fcn_butwth.h" +#include "fcn_hann.h" +#include "type_traits_gen.h" +#include "stream_gpu.h" +#include "cgpu_detail.cuh" + +#include +#include +#include + +namespace gpu_cg = cooperative_groups; + +namespace mt +{ + /* shared memory arrays */ + namespace gpu_detail + { + // Utility class used to avoid linker errors with extern + // unsized shared memory arrays with templated type + template + struct SharedMemory + { + __device__ inline operator T *() + { + extern __shared__ int __smem[]; + return (T *)__smem; + } + + __device__ inline operator const T *() const + { + extern __shared__ int __smem[]; + return (T *)__smem; + } + }; + + // specialize for double to avoid unaligned memory + // access compile errors + template<> + struct SharedMemory + { + __device__ inline operator double *() + { + extern __shared__ double __smem_d[]; + return (double *)__smem_d; + } + + __device__ inline operator const double *() const + { + extern __shared__ double __smem_d[]; + return (double *)__smem_d; + } + }; + } + + /* macros reduce */ + namespace gpu_detail + { + #define GPU_BLK_REDUCE(sum, tid, sdata, bid, gdata_o) \ + { \ + /* each thread puts its local sum into shared memory */ \ + sdata[tid] = sum; \ + cta.sync(); \ + \ + /* do reduction in shared mem */ \ + if ((blocksize >= 512) && (tid < 256)) \ + { \ + sdata[tid] = sum = sum + sdata[tid + 256]; \ + } \ + cta.sync(); \ + \ + if ((blocksize >= 256) && (tid < 128)) \ + { \ + sdata[tid] = sum = sum + sdata[tid + 128]; \ + } \ + cta.sync(); \ + \ + if ((blocksize >= 128) && (tid < 64)) \ + { \ + sdata[tid] = sum = sum + sdata[tid + 64]; \ + } \ + cta.sync(); \ + \ + gpu_cg::thread_block_tile<32> tile32 = gpu_cg::tiled_partition<32>(cta); \ + \ + if (cta.thread_rank() < 32) \ + { \ + /* Fetch final intermediate sum from 2nd warp */ \ + if (blocksize >= 64) \ + { \ + sum += sdata[tid + 32]; \ + } \ + /* Reduce final warp using shuffle */ \ + for (int offset = tile32.size()/2; offset > 0; offset /= 2) \ + { \ + sum += tile32.shfl_down(sum, offset); \ + } \ + } \ + \ + if (cta.thread_rank() == 0) \ + { \ + gdata_o[bid] = sum; \ + } \ + } + } + + /* atomicAdd - double */ + namespace gpu_detail + { + #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ < 600 + __device__ __forceinline__ + double atomicAdd(double *address, double val) + { + unsigned long long int* address_as_ull = (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + + do + { + assumed = old; + old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val +__longlong_as_double(assumed))); + } while (assumed != old); + + return __longlong_as_double(old); + } + #endif + } + + /* remainder summation */ + namespace gpu_detail + { + template + __global__ void fcn_sum_rem(pVctr_gpu_32 mx_i) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + T *sdata = SharedMemory(); + + dt_uint32 tid = threadIdx.x; + dt_uint32 blocksize = blockDim.x; + + KS sum = mx_i[tid]; + + GPU_BLK_REDUCE(sum, tid, sdata, 0, mx_i); + } + + template + enable_if_vctr_gpu> + fcn_sum_rem_gpu(TVctr& mx_i) + { + using T = Value_type; + int threads = mx_i.size(); + int smemSize = (threads <= 32) ? 2 * threads * sizeof(T) : threads * sizeof(T); + fcn_sum_rem<<>>(mx_i.ptr_32()); + T sum = 0; + cudaMemcpy(&sum, mx_i.data(), sizeof(T), cudaMemcpyDeviceToHost); + + return sum; + } + + template + enable_if_vctr_gpu> + fcn_sum_rem_cpu(TVctr& mx_i) + { + using T = Value_type; + + Vctr_cpu mx(mx_i); + KS sum(0); + + for (dt_int32 ik=0; ik + __global__ void fcn_fftsft_1d(iGrid_1d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_1DC(igrid.nx_h, cgpu_detail::fcn_fftsft_1d(ix, igrid, mx_io.m_data)); + } + + /* shift matrix respect to ny_h */ + template + __global__ void fcn_fftsft_bc_2d(iGrid_2d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny_h, cgpu_detail::fcn_fftsft_bc_2d(ix, iy, igrid, mx_io.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + __global__ void fcn_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_fftsft_2d(ix, iy, igrid, mx_io.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h) */ + template + __global__ void fcn_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_fftsft_2d(ix, iy, igrid, mx_i.m_data, mx_o.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + __global__ void fcn_fftsft_3d(iGrid_3d igrid, pVctr_gpu_32 mx_io) + { + FOR_LOOP_3DC(igrid.nx_h, igrid.ny_h, igrid.nz_h, cgpu_detail::fcn_fftsft_3d(ix, iy, iz, igrid, mx_io.m_data)); + } + + /* shift matrix respect to (nx_h, ny_h, nz_h) */ + template + __global__ void fcn_fftsft_3d(iGrid_3d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + FOR_LOOP_3DC(igrid.nx_h, igrid.ny_h, igrid.nz_h, cgpu_detail::fcn_fftsft_3d(ix, iy, iz, igrid, mx_i.m_data, mx_o.m_data)); + } + + /***************************************************************************************/ + /* add, scale and shift */ + template + __global__ void fcn_add_sc_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_fftsft_2d(ix, iy, igrid, mx_i.m_data, w, mx_o.m_data)); + } + + /* add, scale, square and shift */ + template + __global__ void fcn_add_sc_norm_2_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, U w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_fftsft_2d(ix, iy, igrid, mx_i.m_data, w, mx_o.m_data)); + } + + /***************************************************************************************/ + /* assign and crop */ + template + __global__ void fcn_assign_crop_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_assign_crop_2d(ix, iy, igrid, mx_i.m_data, iregion, mx_o.m_data)); + } + + /* assign, crop and shift */ + template + __global__ void fcn_assign_crop_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_assign_crop_fftsft_2d(ix, iy, igrid, mx_i.m_data, iregion, mx_o.m_data)); + } + + /* add, scale, crop and shift */ + template + __global__ void fcn_add_sc_crop_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_crop_fftsft_2d(ix, iy, igrid, mx_i.m_data, iregion, w, mx_o.m_data)); + } + + /* add, scale, square, crop and shift */ + template + __global__ void fcn_add_sc_norm_2_crop_fftsft_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, iRegion_Rect_2d& iregion, U w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx_h, igrid.ny_h, cgpu_detail::fcn_add_sc_norm_2_crop_fftsft_2d(ix, iy, igrid, mx_i.m_data, iregion, w, mx_o.m_data)); + } + } + + /* transpose - element wise matrix op vector */ + namespace gpu_detail + { + /* transpose */ + template + __global__ void fcn_trs_2d(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_trs_2d(ix, iy, igrid, mx_i.m_data, mx_o.m_data)); + } + + /***************************************************************************************/ + /* element wise addition: matrix + vector row */ + template + __global__ void fcn_ew_add_mx_vctr_row(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_row(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /* element wise addition: matrix + vector col */ + template + __global__ void fcn_ew_add_mx_vctr_col(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_add_mx_vctr_col(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /***************************************************************************************/ + /* element wise subtraction: matrix - vector row */ + template + __global__ void fcn_ew_sub_mx_vctr_row(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_row(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /* element wise subtraction: matrix - vector col */ + template + __global__ void fcn_ew_sub_mx_vctr_col(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_sub_mx_vctr_col(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /***************************************************************************************/ + /* element wise multiplication matrix X vector row */ + template + __global__ void fcn_ew_mult_mx_vctr_row(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_row(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + + /* element wise multiplication matrix X vector col */ + template + __global__ void fcn_ew_mult_mx_vctr_col(iGrid_2d igrid, pVctr_gpu_32 vctr, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_ew_mult_mx_vctr_col(ix, iy, igrid, vctr.m_data, mx_io.m_data)); + } + } + + /* aperture functions */ + namespace gpu_detail + { + template + __global__ void fcn_fermi_aperture(Grid_2d grid, T g2_cut, T alpha, T w, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fermi_aperture(ix, iy, grid, g2_cut, alpha, w, mx_io.m_data)); + } + + template + __global__ void fcn_hard_aperture(Grid_2d grid, T g2_cut, T w, pVctr_gpu_32 mx_io) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_hard_aperture(ix, iy, grid, g2_cut, w, mx_io.m_data)); + } + } + + /* phase shifts real space*/ + namespace gpu_detail + { + // phase factor 1d + template + __global__ void fcn_rs_exp_factor_1d(Grid_1d grid, pVctr_gpu_32 psi_i, T gx, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_rs_exp_factor_1d(ix, grid, psi_i.m_data, gx, w, psi_o.m_data)); + } + + // phase factor 2d by col + template + __global__ void fcn_rs_exp_factor_2d_bc(Grid_2d grid, pVctr_gpu_32 psi_i, T alpha, pVctr_gpu_32 gy, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d_bc(ix, iy, grid, psi_i.m_data, alpha, gy, w, psi_o.m_data)); + } + + // phase factor 2d + template + __global__ void fcn_rs_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_exp_factor_2d(ix, iy, grid, psi_i.m_data, g, w, psi_o.m_data)); + } + + // phase factor 2d multipositions + template + __global__ void fcn_rs_mul_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, pVctr_gpu_32> g, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_mul_exp_factor_2d(ix, iy, grid, psi_i.m_data, g.m_data, g.m_size, w, psi_o.m_data)); + } + } + + /* phase shifts fourier space*/ + namespace gpu_detail + { + // phase factor 1d + template + __global__ void fcn_fs_exp_factor_1d(Grid_1d grid, pVctr_gpu_32 psi_i, T rx, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_fs_exp_factor_1d(ix, grid, psi_i.m_data, rx, w, psi_o.m_data)); + } + + // phase factor 2d by col + template + __global__ void fcn_fs_exp_factor_2d_bc(Grid_2d grid, pVctr_gpu_32 psi_i, T alpha, pVctr_gpu_32 ry, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d_bc(ix, iy, grid, psi_i.m_data, alpha, ry, w, psi_o.m_data)); + } + + // phase factor 2d + template + __global__ void fcn_fs_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d r, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_exp_factor_2d(ix, iy, grid, psi_i.m_data, r, w, psi_o.m_data)); + } + + // phase factor 2d multi-positions + template + __global__ void fcn_fs_mul_exp_factor_2d(Grid_2d grid, pVctr_gpu_32 psi_i, pVctr_gpu_32> r, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_mul_exp_factor_2d(ix, iy, grid, psi_i.m_data, r.m_data, r.m_size, w, psi_o.m_data)); + } + } + + /* gradient */ + namespace gpu_detail + { + template + __global__ void fcn_grad_x(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 dmx_x) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_grad_x(ix, iy, igrid, mx_i.m_data, dmx_x.m_data)); + } + + template + __global__ void fcn_grad_y(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 dmx_y) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_grad_y(ix, iy, igrid, mx_i.m_data, dmx_y.m_data)); + } + + template + __global__ void fcn_grad(iGrid_2d igrid, pVctr_gpu_32 mx_i, pVctr_gpu_32 dmx_x, pVctr_gpu_32 dmx_y) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_grad(ix, iy, igrid, mx_i.m_data, dmx_x.m_data, dmx_y.m_data)); + } + } + + /* function multiplication fourier space */ + namespace gpu_detail + { + #define FCN_MULT_FS_FCN_GPU_DET(FN, FCN, POW, DIM) \ + template \ + __global__ void fcn_mult_fs_##FN##_##DIM##d(Grid_##DIM##d grid, FCN fcn, T w, pVctr_gpu_32 mx_io) \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_mult_fs_fcn_g##POW##_##DIM##d(IDX_ND(DIM), grid, fcn, w, mx_io.m_data)) \ + } + + /* gaussian */ + FCN_MULT_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 1); // fcn_mult_fs_gauss_1d + FCN_MULT_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 2); // fcn_mult_fs_gauss_2d + FCN_MULT_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 3); // fcn_mult_fs_gauss_3d + + /* exponential */ + FCN_MULT_FS_FCN_GPU_DET(exp, Fcn_Exp, , 1); // fcn_mult_fs_exp_1d + FCN_MULT_FS_FCN_GPU_DET(exp, Fcn_Exp, , 2); // fcn_mult_fs_exp_2d + FCN_MULT_FS_FCN_GPU_DET(exp, Fcn_Exp, , 3); // fcn_mult_fs_exp_3d + + /* fermi */ + FCN_MULT_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 1); // fcn_mult_fs_fermi_1d + FCN_MULT_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 2); // fcn_mult_fs_fermi_2d + FCN_MULT_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 3); // fcn_mult_fs_fermi_3d + + /* butterworth */ + FCN_MULT_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 1); // fcn_mult_fs_butwth_1d + FCN_MULT_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 2); // fcn_mult_fs_butwth_2d + FCN_MULT_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 3); // fcn_mult_fs_butwth_3d + + /* hann */ + FCN_MULT_FS_FCN_GPU_DET(hann, Fcn_Hann, , 1); // fcn_mult_fs_hann_1d + FCN_MULT_FS_FCN_GPU_DET(hann, Fcn_Hann, , 2); // fcn_mult_fs_hann_2d + FCN_MULT_FS_FCN_GPU_DET(hann, Fcn_Hann, , 3); // fcn_mult_fs_hann_3d + } + + /* deconvolution */ + namespace gpu_detail + { + #define FCN_DCV_FS_FCN_GPU_DET(FN, FCN, POW, DIM) \ + template \ + __global__ void fcn_dcv_fs_##FN##_##DIM##d(Grid_##DIM##d grid, FCN fcn, T psnr, T w, pVctr_gpu_32 mx_io) \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_dcv_fs_fcn_g##POW##_##DIM##d(IDX_ND(DIM), grid, fcn, psnr, w, mx_io.m_data)) \ + } + + /* gaussian */ + FCN_DCV_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 1); // fcn_dcv_fs_gauss_1d + FCN_DCV_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 2); // fcn_dcv_fs_gauss_2d + FCN_DCV_FS_FCN_GPU_DET(gauss, Fcn_Gauss, 2, 3); // fcn_dcv_fs_gauss_3d + + /* exponential */ + FCN_DCV_FS_FCN_GPU_DET(exp, Fcn_Exp, , 1); // fcn_dcv_fs_exp_1d + FCN_DCV_FS_FCN_GPU_DET(exp, Fcn_Exp, , 2); // fcn_dcv_fs_exp_2d + FCN_DCV_FS_FCN_GPU_DET(exp, Fcn_Exp, , 3); // fcn_dcv_fs_exp_3d + + /* fermi */ + FCN_DCV_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 1); // fcn_dcv_fs_fermi_1d + FCN_DCV_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 2); // fcn_dcv_fs_fermi_2d + FCN_DCV_FS_FCN_GPU_DET(fermi, Fcn_Fermi, 2, 3); // fcn_dcv_fs_fermi_3d + + /* butterworth */ + FCN_DCV_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 1); // fcn_dcv_fs_butwth_1d + FCN_DCV_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 2); // fcn_dcv_fs_butwth_2d + FCN_DCV_FS_FCN_GPU_DET(butwth, Fcn_Butwth, 2, 3); // fcn_dcv_fs_butwth_3d + + /* hann */ + FCN_DCV_FS_FCN_GPU_DET(hann, Fcn_Hann, , 1); // fcn_dcv_fs_hann_1d + FCN_DCV_FS_FCN_GPU_DET(hann, Fcn_Hann, , 2); // fcn_dcv_fs_hann_2d + FCN_DCV_FS_FCN_GPU_DET(hann, Fcn_Hann, , 3); // fcn_dcv_fs_hann_3d + } + + /* window functions */ + namespace gpu_detail + { + #define FCN_WD_FCN_GPU_DET(FN, FCN, DIM) \ + template \ + __global__ void fcn_wd_##FN##_##DIM##d(Grid_##DIM##d grid, FCN fcn, pVctr_gpu_32 mx_o) \ + { \ + if (sft) \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_sft_##DIM##d(IDX_ND(DIM), grid, fcn, mx_o.m_data)) \ + } \ + else \ + { \ + FOR_LOOP_NDC(DIM, F_SHAPE_ND(grid, DIM), cgpu_detail::fcn_wd_fcn_r2_##DIM##d(IDX_ND(DIM), grid, fcn, mx_o.m_data)) \ + } \ + } + + FCN_WD_FCN_GPU_DET(gauss, Wd_Gauss_1d, 1); // fcn_wd_gauss_1d + FCN_WD_FCN_GPU_DET(gauss, Wd_Gauss_2d, 2); // fcn_wd_gauss_2d + FCN_WD_FCN_GPU_DET(gauss, Wd_Gauss_3d, 3); // fcn_wd_gauss_3d + + FCN_WD_FCN_GPU_DET(exp, Wd_Exp_1d, 1); // fcn_wd_exp_1d + FCN_WD_FCN_GPU_DET(exp, Wd_Exp_2d, 2); // fcn_wd_exp_2d + FCN_WD_FCN_GPU_DET(exp, Wd_Exp_3d, 3); // fcn_wd_exp_3d + + FCN_WD_FCN_GPU_DET(fermi, Wd_Fermi_1d, 1); // fcn_wd_fermi_1d + FCN_WD_FCN_GPU_DET(fermi, Wd_Fermi_2d, 2); // fcn_wd_fermi_2d + FCN_WD_FCN_GPU_DET(fermi, Wd_Fermi_3d, 3); // fcn_wd_fermi_3d + + FCN_WD_FCN_GPU_DET(butwth, Wd_Butwth_1d, 1); // fcn_wd_butwth_1d + FCN_WD_FCN_GPU_DET(butwth, Wd_Butwth_2d, 2); // fcn_wd_butwth_2d + FCN_WD_FCN_GPU_DET(butwth, Wd_Butwth_3d, 3); // fcn_wd_butwth_3d + + FCN_WD_FCN_GPU_DET(hann, Wd_Hann_1d, 1); // fcn_wd_hann_1d + FCN_WD_FCN_GPU_DET(hann, Wd_Hann_2d, 2); // fcn_wd_hann_2d + FCN_WD_FCN_GPU_DET(hann, Wd_Hann_3d, 3); // fcn_wd_hann_3d + } + + /* phase correlation */ + namespace gpu_detail + { + /****************** pcf data processing real space *******************/ + template + __global__ void fcn_rs_pcf_1d_dp(Grid_1d grid, pVctr_gpu_32 mx_i, + Wd_Butwth_1d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_rs_pcf_1d_dp(ix, grid, mx_i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_rs_pcf_2d_dp(Grid_2d grid, pVctr_gpu_32 mx_i, + Wd_Butwth_2d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_rs_pcf_2d_dp(ix, iy, grid, mx_i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_rs_pcf_3d_dp(Grid_3d grid, pVctr_gpu_32 mx_i, + Wd_Butwth_3d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_3DC(grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_rs_pcf_2d_dp(ix, iy, iz, grid, mx_i.m_data, wd, w, mx_o.m_data)); + } + + /***************** pcf data processing fourier space *****************/ + template + __global__ void fcn_fs_pcf_1d_dp(Grid_1d grid, pVctr_gpu_32 mx_1i, pVctr_gpu_32 mx_2i, + Wd_Gauss_1d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_1DC(grid.nx, cgpu_detail::fcn_fs_pcf_1d_dp(ix, grid, mx_1i.m_data, mx_2i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_fs_pcf_2d_dp(Grid_2d grid, pVctr_gpu_32 mx_1i, pVctr_gpu_32 mx_2i, + Wd_Gauss_2d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail::fcn_fs_pcf_2d_dp(ix, iy, grid, mx_1i.m_data, mx_2i.m_data, wd, w, mx_o.m_data)); + } + + template + __global__ void fcn_fs_pcf_3d_dp(Grid_3d grid, pVctr_gpu_32 mx_1i, pVctr_gpu_32 mx_2i, + Wd_Gauss_3d wd, T w, pVctr_gpu_32 mx_o) + { + FOR_LOOP_3DC(grid.nx, grid.ny, grid.nz, cgpu_detail::fcn_fs_pcf_2d_dp(ix, iy, iz, grid, mx_1i.m_data, mx_2i.m_data, wd, w, mx_o.m_data)); + } + } + + /* optical flow */ + namespace gpu_detail + { + template + __global__ void fcn_opt_flow(iGrid_2d igrid, pVctr_gpu_32 mx_s, pVctr_gpu_32 mx_m, + T alpha, pVctr_gpu_32 dphi_x, pVctr_gpu_32 dphi_y) + { + FOR_LOOP_2DC(igrid.nx, igrid.ny, cgpu_detail::fcn_opt_flow(ix, iy, igrid, mx_s.m_data, mx_m.m_data, alpha, dphi_x.m_data, dphi_y.m_data)); + } + } + + /* bilinear interpolation */ + namespace gpu_detail + { + template + __global__ void fcn_intrpl_bl_rg_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, + pVctr_gpu_32 vrx, pVctr_gpu_32 vry, T bg, pVctr_gpu_32 mx_o) + { + FOR_LOOP_1DC(vrx.m_size, cgpu_detail::fcn_intrpl_bl_rg_2d(ix, grid_i, mx_i.m_data, vrx.m_data, vry.m_data, bg, mx_o.m_data)); + } + } + + // namespace gpu_detail + // { +// // scan noise xy + // template + // __global__ void sd_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, pVctr_gpu_32 dx_i, pVctr_gpu_32 dy_i, T bg, pVctr_gpu_32 mx_o) + // { + // (dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_i.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_i.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::sd_2d(ix, iy, grid_i, mx_i, dx_i, dy_i, bg, mx_o); + // } + // } + // } + + // template + // __global__ void sd_nr_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, pVctr_gpu_32 dx_i, pVctr_gpu_32 dy_i, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_i.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_i.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::sd_nr_2d(ix, iy, grid_i, mx_i, dx_i, dy_i, mx_o); + // } + // } + // } + + // // scaling xy + // template + // __global__ void sc_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, T fxy, Grid_2d grid_o, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_o.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_o.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::sc_2d(ix, iy, grid_i, mx_i, fxy, grid_o, mx_o); + // } + // } + // } + + // // rotate, scale and shift xy + // template + // __global__ void rot_sca_sft_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, T theta, R_2d p0, + // T fx, T fy, R_2d ps, T bg, Grid_2d grid_o, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_o.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_o.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::rot_sca_sft_2d(ix, iy, grid_i, mx_i, theta, p0, fx, fy, ps, bg, grid_o, mx_o); + // } + // } + // } + + // // 2d general affine transformation + // template + // __global__ void at_2d(Grid_2d grid_i, pVctr_gpu_32 mx_i, Mx_2x2 A, R_2d txy, T bg, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_i.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_i.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::at_2d(ix, iy, grid_i, mx_i, A, txy, bg, mx_o); + // } + // } + // } + +// // x-shear and y-scaling + // template + // __global__ void shx_scy(Grid_2d grid_i, pVctr_gpu_32 mx_i, T fx, T fy, T bg, Grid_2d grid_o, pVctr_gpu_32 mx_o) + // { + // for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < grid_o.nx; ix += blockDim.y*gridDim.y) + // { + // for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < grid_o.ny; iy += blockDim.x*gridDim.x) + // { + // cgpu_detail::shx_scy(ix, iy, grid_i, mx_i, fx, fy, bg, grid_o, mx_o); + // } + // } + // } + + // } +} diff --git a/src/gpu_detail_mt.cuh b/src/gpu_detail_mt.cuh new file mode 100755 index 00000000..e6046e78 --- /dev/null +++ b/src/gpu_detail_mt.cuh @@ -0,0 +1,332 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +// #if defined __CUDACC__ && !defined GPU_DETAIL_MT_H +#ifndef GPU_DETAIL_MT_H + #define GPU_DETAIL_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "type_traits_mt.cuh" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "quad_data.cuh" + #include "cgpu_detail_mt.cuh" + #include "gpu_detail.cuh" + + #include + #include + #include + #include + + namespace gpu_cg = cooperative_groups; + + namespace mt + { + /* atomic functions */ + namespace gpu_detail_mt + { + /************************** pFcn_clnl_3_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, pLNL_Coef_gpu coef, pVctr_gpu_32 fx, pFcn_clnl_3_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, pLNL_Coef_gpu coef, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_3_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /************************** pFcn_clnl_4_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T c, pLNL_Coef_gpu coef, pVctr_gpu_32 fx, pFcn_clnl_4_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], c, coef.cl, coef.cnl); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T c, pLNL_Coef_gpu coef, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_4_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], c, coef.cl, coef.cnl, fx1[ix], fx2[ix]); + } + } + + /************************** pFcn_clnl_6_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx, pFcn_clnl_6_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T z_0, T z_e, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_6_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + + /************************** pFcn_clnl_8_x ****************************/ + // evaluate function + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T z_0, T z_e, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx, pFcn_clnl_8_1 fcn) + { + FOR_IX_1DC(x.m_size) + { + fx[ix] = fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w); + } + } + + // evaluate two functions + template + __global__ void fcn_eval_fcn_coef_lnl(pVctr_gpu_32 x, T z_0, T z_e, pLNL_Coef_gpu coef, pQuad_Coef_1d_gpu quad, pVctr_gpu_32 fx1, pVctr_gpu_32 fx2, pFcn_clnl_8_2 fcn) + { + FOR_IX_1DC(x.m_size) + { + fcn(x[ix], z_0, z_e, coef.cl, coef.cnl, quad.m_size, quad.x, quad.w, fx1[ix], fx2[ix]); + } + } + } // gpu_detail + + /* detector integration */ + namespace gpu_detail_mt + { + /* integration over a detector ring */ + template + __global__ void fcn_int_det_ring(Grid_2d grid, T g2_min, T g2_max, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_ring(ix, iy, grid, g2_min, g2_max, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + /* norm_2 integration over a detector ring */ + template + __global__ void fcn_int_det_ring_norm_2(Grid_2d grid, T g2_min, T g2_max, pVctr_gpu_32 mx_i, pVctr_gpu_32> mx_o) + { + using U_r = Value_type_r; + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U_r *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U_r(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_ring_norm_2(ix, iy, grid, g2_min, g2_max, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + /* integration over a detector with sensitivity */ + template + __global__ void fcn_int_det_sen(Grid_2d grid, pVctr_gpu_32 sen_i, pVctr_gpu_32 mx_i, pVctr_gpu_32 mx_o) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_sen(ix, iy, grid, sen_i.m_data, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + /* norm_2 integration over a detector with sensitivity */ + template + __global__ void fcn_int_det_sen_norm_2(Grid_2d grid, pVctr_gpu_32> sen_i, pVctr_gpu_32 mx_i, pVctr_gpu_32> mx_o) + { + using U_r = Value_type_r; + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + U_r *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = U_r(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_int_det_sen_norm_2(ix, iy, grid, sen_i.m_data, mx_i.m_data, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + } + + /* wave propagation */ + namespace gpu_detail_mt + { + /* propagate */ + template + __global__ void fcn_fs_propagate(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g_0, T w_g2, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate(ix, iy, grid, psi_i.m_data, g_0, w_g2, w, psi_o.m_data)); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + __global__ void fcn_fs_propagate_bw_f(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g_0, T w_g2, T g2_cut, T alpha, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_f(ix, iy, grid, psi_i.m_data, g_0, w_g2, g2_cut, alpha, w, psi_o.m_data)); + } + + /* propagate and bandwith limit using a hard aperture */ + template + __global__ void fcn_fs_propagate_bw_h(Grid_2d grid, pVctr_gpu_32 psi_i, R_2d g_0, T w_g2, T g2_cut, T w, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_propagate_bw_h(ix, iy, grid, psi_i.m_data, g_0, w_g2, g2_cut, w, psi_o.m_data)); + } + } + + /* probe - ctf - pctf */ + namespace gpu_detail_mt + { + /* Convergent incident wave in Fourier space */ + template + __global__ void fcn_fs_probe(Grid_2d grid, Lens lens, R_2d r, R_2d gu, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_probe(ix, iy, grid, lens, r, gu, psi_o.m_data)); + } + + /* apply coherent transfer function */ + template + __global__ void fcn_fs_apply_ctf(Grid_2d grid, pVctr_gpu_32 psi_i, Lens lens, R_2d gu, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_apply_ctf(ix, iy, grid, psi_i.m_data, lens, gu, psi_o.m_data)); + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + __global__ void fcn_fs_apply_pctf(iGrid_2d grid, pVctr_gpu_32 psi_i, Lens lens, pVctr_gpu_32 psi_o) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_fs_apply_pctf(ix, iy, grid, psi_i.m_data, lens, psi_o.m_data)); + } + } + + /* transmission function */ + namespace gpu_detail_mt + { + template + __global__ void fcn_trans_fcn(iGrid_1d igrid, pVctr_gpu_32 vzp_i, const T& w, pVctr_gpu_32 tfcn_o) + { + FOR_LOOP_1DC(igrid.nx, cgpu_detail_mt::fcn_trans_fcn(ix, igrid, vzp_i.m_data, w, tfcn_o.m_data)); + } + } + + /* eels */ + namespace gpu_detail_mt + { + template + __global__ void fcn_eels_lorentz_norm_factor(Grid_2d grid, T gc2, T ge2, pVctr_gpu_32 mx_o) + { + gpu_cg::thread_block cta = gpu_cg::this_thread_block(); + T *sdata = gpu_detail::SharedMemory(); + + dt_uint32 tid = threadIdx.x + threadIdx.y*blockDim.x; + dt_uint32 bid = blockIdx.x + blockIdx.y*gridDim.x; + dt_uint32 blocksize = blockDim.x*blockDim.y; + + KS sum = T(0); + + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_lorentz_norm_factor(ix, iy, grid, gc2, ge2, sum)); + + GPU_BLK_REDUCE(sum, tid, sdata, bid, mx_o); + } + + template + __global__ void fcn_eels_w_xyz(Grid_2d grid, EELS eels, + pVctr_gpu_32 w_x, pVctr_gpu_32 w_y, pVctr_gpu_32 w_z) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_xyz(ix, iy, grid, eels, w_x.m_data, w_y.m_data, w_z.m_data)); + } + + template + __global__ void fcn_eels_w_x(Grid_2d grid, EELS eels, pVctr_gpu_32 w_x) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_x(ix, iy, grid, eels, w_x.m_data)); + } + + template + __global__ void fcn_eels_w_y(Grid_2d grid, EELS eels, pVctr_gpu_32 w_y) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_y(ix, iy, grid, eels, w_y.m_data)); + } + + template + __global__ void fcn_eels_w_z(Grid_2d grid, EELS eels, pVctr_gpu_32 w_z) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_z(ix, iy, grid, eels, w_z.m_data)); + } + + template + __global__ void fcn_eels_w_mn1(Grid_2d grid, EELS eels, pVctr_gpu_32 w_mn1) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mn1(ix, iy, grid, eels, w_mn1.m_data)); + } + + template + __global__ void fcn_eels_w_mp1(Grid_2d grid, EELS eels, pVctr_gpu_32 w_mp1) + { + FOR_LOOP_2DC(grid.nx, grid.ny, cgpu_detail_mt::fcn_eels_w_mp1(ix, iy, grid, eels, w_mp1.m_data)); + } + } + } + +#endif diff --git a/src/gpu_fcns_mt.cuh b/src/gpu_fcns_mt.cuh new file mode 100755 index 00000000..6c57122f --- /dev/null +++ b/src/gpu_fcns_mt.cuh @@ -0,0 +1,376 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef GPU_FCNS_MT_H + #define GPU_FCNS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "types.cuh" + #include "type_traits_mt.cuh" + #include "cgpu_vctr.cuh" + #include "cgpu_fft.cuh" + #include "cgpu_stream.cuh" + #include "gpu_detail_mt.cuh" + + /* atomic functions */ + namespace mt + { + /*********************************** pFcn_clnl_3_x **********************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx, pFcn_clnl_3_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_3_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, fx1, fx2, fcn); + } + + /********************************* pFcn_clnl_4_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& c, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx, pFcn_clnl_4_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, c, coef, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& c, const pLNL_Coef_gpu& coef, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_4_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, c, coef, fx1, fx2, fcn); + } + + /********************************* pFcn_clnl_6_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx, pFcn_clnl_6_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, quad, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_6_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, coef, quad, fx1, fx2, fcn); + } + + /********************************* pFcn_clnl_8_x ************************************/ + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx, pFcn_clnl_8_1 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, z_0, z_e, coef, quad, fx, fcn); + } + + template + void fcn_eval_fcn_coef_lnl(const pVctr_gpu_32& x, const T& z_0, const T& z_e, const pLNL_Coef_gpu& coef, const pQuad_Coef_1d_gpu& quad, pVctr_gpu_32& fx1, pVctr_gpu_32& fx2, pFcn_clnl_8_2 fcn) + { + gpu_detail_mt::fcn_eval_fcn_coef_lnl<<>>(x, z_0, z_e, coef, quad, fx1, fx2, fcn); + } + } + + /* detector integration */ + namespace mt + { + template + enable_if_vctr_gpu> + fcn_int_det_ring(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + TVctr sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_ring<<>>(grid, g2_min, g2_max, mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu> + fcn_int_det_ring_norm_2(Grid_2d& grid, T g_min, T g_max, TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + T g2_min = ::square(g_min); + T g2_max = ::square(g_max); + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + Vctr_gpu sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_ring_norm_2<<>>(grid, g2_min, g2_max, mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu> + fcn_int_det_sen(Grid_2d& grid, TVctr& sen_i, TVctr& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + TVctr sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_sen<<>>(grid, sen_i.ptr_32(), mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu_and_vctr_gpu> + fcn_int_det_sen_norm_2(Grid_2d& grid, TVctr_1& sen_i, TVctr_2& mx_i, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + using Ur = Value_type_r; + + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + Vctr_gpu sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_int_det_sen_norm_2<<>>(grid, sen_i.ptr_32(), mx_i.ptr_32(), sum_v.ptr_32()); + + return gpu_detail::fcn_sum_rem_cpu(sum_v); + } + } + + /* wave propagation */ + namespace mt + { + /* propagate */ + template + enable_if_vctr_gpu + fcn_fs_propagate(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail_mt::fcn_fs_propagate<<>>(grid, psi_i.ptr_32(), g_0, w_g2, w, psi_o.ptr_32()); + } + + /* propagate and bandwith limit using a fermi aperture */ + template + enable_if_vctr_gpu + fcn_fs_propagate_bw_f(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T alpha, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail_mt::fcn_fs_propagate_bw_f<<>>(grid, psi_i.ptr_32(), g_0, w_g2, g2_cut, alpha, w, psi_o.ptr_32()); + } + + /* propagate and bandwith limit using a hard aperture */ + template + enable_if_vctr_gpu + fcn_fs_propagate_bw_h(Grid_2d& grid, TVctr& psi_i, R_2d g_0, T w_g2, T g2_cut, T w, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + gpu_detail_mt::fcn_fs_propagate_bw_h<<>>(grid, psi_i.ptr_32(), g_0, w_g2, g2_cut, w, psi_o.ptr_32()); + } + } + + /* probe - ctf - pctf */ + namespace mt + { + template + enable_if_vctr_gpu + fcn_fs_probe(Grid_2d& grid, Lens& lens, R_2d r, R_2d gu, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + gpu_detail_mt::fcn_fs_probe<<>>(grid, lens, r, gu, psi_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_fs_probe<<>>(grid, lens, r, gu, psi_o.ptr_32()); + } + + auto tot_intensity = fcn_sum_norm_2(psi_o, pstream); + auto sc_fctr = ::sqrt(T(1)/tot_intensity); + + fcn_scale(sc_fctr, psi_o, pstream); + } + + template + enable_if_vctr_gpu + fcn_fs_apply_ctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, R_2d gu, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + gpu_detail_mt::fcn_fs_apply_ctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_fs_apply_ctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + } + + /* apply partial coherent transfer function */ + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 611 + // tp_inc_iehwgd: 08, spt_inc_theta_c: 611 + template + enable_if_vctr_gpu + fcn_fs_apply_pctf(Grid_2d& grid, TVctr& psi_i, Lens& lens, TVctr& psi_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + auto bb_phi_eq = lens.is_phi_required(); + + if (bb_phi_eq) + { + gpu_detail_mt::fcn_fs_apply_pctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_fs_apply_pctf<<>>(grid, psi_i, lens, gu, psi_o.ptr_32()); + } + } + } + + /* transmission function */ + namespace mt + { + template + enable_if_vctr_gpu_and_vctr_gpu + transmission_fcn(eElec_Spec_Interact_Mod esim, TVctr_1& vzp_i, T w, TVctr_2& tfcn_o, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + iGrid_1d igrid(vzp_i.size()); + + if (esim==eesim_weak_phase_object) + { + gpu_detail_mt::fcn_trans_fcn<<>>(igrid, vzp_i.ptr_32(), w, tfcn_o.ptr_32()); + } + else + { + gpu_detail_mt::fcn_trans_fcn<<>>(igrid, vzp_i.ptr_32(), w, tfcn_o.ptr_32()); + } + } + } + + /* eels */ + namespace mt + { + template + T fcn_eels_lorentz_norm_factor_gpu(Grid_2d& grid, EELS& eels, Stream_gpu* pstream = nullptr) + { + auto dgb = grid.d_grid_blk(dim3(c_thr_2d_x, c_thr_2d_y)); + Vctr_gpu sum_v(dgb.grid_size()); + + gpu_detail_mt::fcn_eels_lorentz_norm_factor<<>>(grid, eels.gc2, eels.ge2, sum_v.ptr_32()); + + return ::sqrt(eels.occ)/gpu_detail::fcn_sum_rem_cpu(sum_v); + } + + template + enable_if_vctr_gpu + fcn_eels_w_xyz(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_x, TVctr_c& w_y, TVctr_c& w_z, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_xyz<<>>(grid, eels, w_x.ptr_32(), w_y.ptr_32(), w_z.ptr_32()); + + fft.inverse(w_x); + fft.inverse(w_y); + fft.inverse(w_z); + } + + template + enable_if_vctr_gpu + fcn_eels_w_x(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_x, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_x<<>>(grid, eels, w_x.ptr_32()); + + fft.inverse(w_x); + } + + template + enable_if_vctr_gpu + fcn_eels_w_y(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_y, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_y<<>>(grid, eels, w_y.ptr_32()); + + fft.inverse(w_y); + } + + template + enable_if_vctr_gpu + fcn_eels_w_z(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_z, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_z<<>>(grid, eels, w_z.ptr_32()); + + fft.inverse(w_z); + } + + template + enable_if_vctr_gpu + fcn_eels_w_mn1(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_mn1, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_mn1<<>>(grid, eels, w_mn1.ptr_32()); + + fft.inverse(w_mn1); + } + + template + enable_if_vctr_gpu + fcn_eels_w_mp1(Grid_2d& grid, EELS& eels, FFT_gpu& fft, TVctr_c& w_mp1, Stream_gpu* pstream = nullptr) + { + using U = Value_type; + + eels.factor = fcn_eels_lorentz_norm_factor_gpu(grid, eels, pstream); + + gpu_detail_mt::fcn_eels_w_mp1<<>>(grid, eels, w_mp1.ptr_32()); + + fft.inverse(w_mp1); + } + } + +#endif \ No newline at end of file diff --git a/src/grid_1d.h b/src/grid_1d.h new file mode 100755 index 00000000..27614762 --- /dev/null +++ b/src/grid_1d.h @@ -0,0 +1,384 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "fcns_cgpu_gen.h" +#include "const_enum.h" +#include "igrid_1d.h" +#include "region.cuh" +#include "vctr_cpu.h" +#include "vctr_gpu.h" + +/* template definition */ +namespace mt +{ + template class Grid_sxd; + + template + using Grid_xd = Grid_sxd; +} + +/* derived class */ +namespace mt +{ + template + using Grid_1d_st = Grid_sxd; + + template + using Grid_1d = Grid_sxd; + + template + using Grid_1d_64 = Grid_sxd; +} + +/* template specialization 1d */ +namespace mt +{ + template + class Grid_sxd: public iGrid_sxd + { + public: + using value_type = T; + using size_type = ST; + + T bs_x; // simulation box size along x direction (Angstroms) + + T rx_0; // reference coordinate system along x + + dt_bool pbc_x; // peridic boundary condition along x + + dt_bool bwl; // band-width limit + + T sli_thick; // slice thicknes + + T drx; // x-sampling in real space + + T dgx; // x-sampling in reciprocal space + + /************************************* constructors ************************************/ + CGPU_EXEC + Grid_sxd(); + + Grid_sxd(const ST& nx); + + template + Grid_sxd(const U& bs_x, const SU& nx); + + template + Grid_sxd(const U& bs_x, const SU& nx, const U& rx_0, + dt_bool pbc_x = true, dt_bool bwl = false, U sli_thick = 0.5); + + /* copy constructor */ + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid); + + /* converting constructor */ + template + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid); + + /* converting assignment operator */ + template + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid); + + template + CGPU_EXEC + void assign(const Grid_sxd& grid); + + /************************ user define conversion operators ****************************/ + operator iRegion_Rect_xd() const; + + /***************************************************************************************/ + void set_in_data(const ST& nx); + + template + void set_in_data(const U& bs_x, const SU& nx); + + template + void set_in_data(const U& bs_x, const SU& nx, + const U& rx_0, dt_bool pbc_x = true, dt_bool bwl = false, U sli_thick = 0.5); + + void set_dep_var(); + + CGPU_EXEC + void set_r_0(const T& rx_0); + + /***************************************************************************************/ + CGPU_EXEC + T nx_r() const; + + CGPU_EXEC + T size_r() const; + + T isize_r() const; + + /***************************************************************************************/ + CGPU_EXEC + T bs_x_h() const; + + CGPU_EXEC + T bs_h() const; + + /***************************************************************************************/ + CGPU_EXEC + T rx_c() const; + + CGPU_EXEC + T rv_c() const; + + /***************************************************************************************/ + // maximum frequency + CGPU_EXEC + T g_max() const; + + // maximum square frequency + CGPU_EXEC + T g2_max() const; + + // maximum allowed frequency + CGPU_EXEC + T gl_max() const; + + // maximum square allowed frequency + CGPU_EXEC + T gl2_max() const; + + /***************************************************************************************/ + /****************************** Fourier space positions ********************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix) const; + + CGPU_EXEC + T gx2(const ST& ix) const; + + CGPU_EXEC + T g2(const ST& ix) const; + + CGPU_EXEC + T g(const ST& ix) const; + + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gx2(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T g2(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T g(const ST& ix, const T& gx_0) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + T gx_sft(const ST& ix) const; + + CGPU_EXEC + T gx2_sft(const ST& ix) const; + + CGPU_EXEC + T g2_sft(const ST& ix) const; + + CGPU_EXEC + T g_sft(const ST& ix) const; + + /***************************************************************************************/ + CGPU_EXEC + T gx_sft(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gx2_sft(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T g2_sft(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T g_sft(const ST& ix, const T& gx_0) const; + + /***************************************************************************************/ + /******************************** real space positions *********************************/ + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix) const; + + CGPU_EXEC + T rx2(const ST& ix) const; + + CGPU_EXEC + T r2(const ST& ix) const; + + CGPU_EXEC + T r(const ST& ix) const; + + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix, const T& x0) const; + + CGPU_EXEC + T rx2(const ST& ix, const T& x0) const; + + CGPU_EXEC + T r2(const ST& ix, const T& x0) const; + + CGPU_EXEC + T r(const ST& ix, const T& x0) const; + + /***************************************************************************************/ + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix) const; + + CGPU_EXEC + T rx2_sft(const ST& ix) const; + + CGPU_EXEC + T r2_sft(const ST& ix) const; + + CGPU_EXEC + T r_sft(const ST& ix) const; + + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix, const T& x0) const; + + CGPU_EXEC + T rx2_sft(const ST& ix, const T& x0) const; + + CGPU_EXEC + T r2_sft(const ST& ix, const T& x0) const; + + CGPU_EXEC + T r_sft(const ST& ix, const T& x0) const; + + /***************************************************************************************/ + /******************************* from position to index ********************************/ + /***************************************************************************************/ + template + void ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const; + + template + void ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const; + + /************ fds = floor/division by pixel size ************/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fd(const T& x) const; + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfd(const T& x) const; + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cd(const T& x) const; + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcd(const T& x) const; + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fds(const T& x) const; + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfds(const T& x) const; + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cds(const T& x) const; + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcds(const T& x) const; + + /************ From position to index by searching ***********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_b(const T& x, ST ix_min=0, ST ix_max=0) const; + + /***************************************************************************************/ + /********************************** check bounds ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const; + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const; + + /***************************************************************************************/ + /************************************ set bounds ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + T set_bound_x(const T& x) const; + + /***************************************************************************************/ + /*********************************** front/back ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx_front() const; + + CGPU_EXEC + T gx_back() const; + + /***************************************************************************************/ + CGPU_EXEC + T rx_front() const; + + CGPU_EXEC + T rx_back() const; + + /***************************************************************************************/ + /************************************** factors ****************************************/ + /***************************************************************************************/ + /* calculate fermi low-pass filter alpha parameter */ + CGPU_EXEC + T fermi_lpf_alpha() const; + + CGPU_EXEC + T factor_2pi_rx_ctr(const T& x) const; + + CPU_EXEC + Vctr factor_2pi_rv_ctr(const Vctr& rv) const; + + /***************************************************************************************/ + iRegion_Rect_xd iregion_rect(const T& r, const T& radius) const; + }; +} + + +#include "detail/grid_1d.inl" \ No newline at end of file diff --git a/src/grid_2d.h b/src/grid_2d.h new file mode 100755 index 00000000..59dd5eb3 --- /dev/null +++ b/src/grid_2d.h @@ -0,0 +1,638 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "grid_1d.h" +#include "igrid_2d.h" + +/* derived class */ +namespace mt +{ + template + using Grid_2d_st = Grid_sxd; + + template + using Grid_2d = Grid_sxd; + + template + using Grid_2d_64 = Grid_sxd; +} + +/* template specialization 2d */ +namespace mt +{ + template + class Grid_sxd: public iGrid_sxd + { + public: + using value_type = T; + using size_type = ST; + + T bs_x; // simulation box size along x direction (Angstroms) + T bs_y; // simulation box size along y direction (Angstroms) + + T rx_0; // reference coordinate system along x + T ry_0; // reference coordinate system along y + + dt_bool pbc_x; // peridic boundary condition along x + dt_bool pbc_y; // peridic boundary condition along y + + dt_bool bwl; // band-width limit + + T sli_thick; // slice thicknes + + T drx; // x-sampling in real space + T dry; // y-sampling in real space + + T dgx; // x-sampling in reciprocal space + T dgy; // y-sampling in reciprocal space + + /************************************* constructors ************************************/ + Grid_sxd(); + + Grid_sxd(const ST& nx, const ST& ny); + + template + Grid_sxd(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny); + + template + Grid_sxd(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny, const U& rx_0, const U& ry_0, + dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool bwl = false, U sli_thick = 0.5); + + /* copy constructor */ + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid); + + /* converting constructor */ + template + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid); + + /* converting assignment operator */ + template + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid); + + template + CGPU_EXEC + void assign(const Grid_sxd& grid); + + /************************** user define conversion operators ***************************/ + operator iRegion_Rect_xd() const; + + /***************************************************************************************/ + void set_in_data(const ST& nx, const ST& ny); + + template + void set_in_data(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny); + + template + void set_in_data(const U& bs_x, const U& bs_y, const SU& nx, const SU& ny, + const U& rx_0, const U& ry_0, dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool bwl = false, U sli_thick = 0.5); + + void set_dep_var(); + + CGPU_EXEC + void set_r_0(const T& rx_0, const T& ry_0); + + CGPU_EXEC + void set_r_0(const R_2d& r_0); + + /***************************************************************************************/ + CGPU_EXEC + T nx_r() const; + + CGPU_EXEC + T ny_r() const; + + CGPU_EXEC + T size_r() const; + + T isize_r() const; + + /***************************************************************************************/ + CGPU_EXEC + T bs_x_h() const; + + CGPU_EXEC + T bs_y_h() const; + + CGPU_EXEC + R_2d bs_h() const; + + /***************************************************************************************/ + CGPU_EXEC + T bs_min() const; + + CGPU_EXEC + T bs_max() const; + + CGPU_EXEC + T bs_h_min() const; + + CGPU_EXEC + T bs_h_max() const; + + CGPU_EXEC + T rx_c() const; + + CGPU_EXEC + T ry_c() const; + + CGPU_EXEC + R_2d rv_c() const; + + /***************************************************************************************/ + // maximum frequency + CGPU_EXEC + T g_max() const; + + // maximum square frequency + CGPU_EXEC + T g2_max() const; + + // maximum allowed frequency + CGPU_EXEC + T gl_max() const; + + // maximum square allowed frequency + CGPU_EXEC + T gl2_max() const; + + CGPU_EXEC + T r_0_min() const; + + CGPU_EXEC + T dr_min() const; + + CGPU_EXEC + T dg_min() const; + + /***************************************************************************************/ + /***************************** Fourier space positions *********************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix) const; + + CGPU_EXEC + T gy(const ST& iy) const; + + CGPU_EXEC + R_2d gv(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T gx2(const ST& ix) const; + + CGPU_EXEC + T gy2(const ST& iy) const; + + CGPU_EXEC + T g2(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T g(const ST& ix, const ST& iy) const; + + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + R_2d gv(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const; + + CGPU_EXEC + R_2d gv(const ST& ix, const ST& iy, const R_2d& g_0) const; + + CGPU_EXEC + T gx2(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy2(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const; + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const R_2d& g0) const; + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const; + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const R_2d& g0) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + T gx_sft(const ST& ix) const; + + CGPU_EXEC + T gy_sft(const ST& iy) const; + + CGPU_EXEC + R_2d gv_sft(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T gx2_sft(const ST& ix) const; + + CGPU_EXEC + T gy2_sft(const ST& iy) const; + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy) const; + + /***************************************************************************************/ + CGPU_EXEC + T gx_sft(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy_sft(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + R_2d gv_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const; + + CGPU_EXEC + R_2d gv_sft(const ST& ix, const ST& iy, const R_2d& g_0) const; + + CGPU_EXEC + T gx2_sft(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy2_sft(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const; + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const R_2d& g0) const; + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const T& gx_0, const T& gy_0) const; + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const R_2d& g0) const; + + /***************************************************************************************/ + /******************************* real space positions **********************************/ + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix) const; + + CGPU_EXEC + T ry(const ST& iy) const; + + CGPU_EXEC + R_2d rv(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T rx2(const ST& ix) const; + + CGPU_EXEC + T ry2(const ST& iy) const; + + CGPU_EXEC + T r2(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T r(const ST& ix, const ST& iy) const; + + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry(const ST& iy, const T& y0) const; + + CGPU_EXEC + R_2d rv(const ST& ix, const ST& iy, const T& x0, const T& y0) const; + + CGPU_EXEC + R_2d rv(const ST& ix, const ST& iy, const R_2d& r_0) const; + + CGPU_EXEC + T rx2(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry2(const ST& iy, const T& y0) const; + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const T& x0, const T& y0) const; + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const R_2d& r_0) const; + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const T& x0, const T& y0) const; + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const R_2d& r_0) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + T rx_sft(const ST& ix) const; + + CGPU_EXEC + T ry_sft(const ST& iy) const; + + CGPU_EXEC + R_2d rv_sft(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T rx2_sft(const ST& ix) const; + + CGPU_EXEC + T ry2_sft(const ST& iy) const; + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy) const; + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy) const; + + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry_sft(const ST& iy, const T& y0) const; + + CGPU_EXEC + R_2d rv_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const; + + CGPU_EXEC + R_2d rv_sft(const ST& ix, const ST& iy, const R_2d& r_0) const; + + CGPU_EXEC + T rx2_sft(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry2_sft(const ST& iy, const T& y0) const; + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const; + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const R_2d& r_0) const; + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const T& x0, const T& y0) const; + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const R_2d& r_0) const; + + /***************************************************************************************/ + /***************************** from position to index **********************************/ + /***************************************************************************************/ + template + void ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const; + + template + void iy_0_iy_n(const T& y, const T& y_max, SU& iy_0, SU& iy_n) const; + + template + void ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const; + + template + void iy_0_iy_e(const T& y, const T& y_max, SU& iy_0, SU& iy_e) const; + + /************ fds = floor/division by pixel size ************/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fd(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_fd(const T& x, const T& y) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fd_dr_min(const T& x) const; + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfd(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bfd(const T& x, const T& y) const; + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cd(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_cd(const T& x, const T& y) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cd_dr_min(const T& x) const; + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcd(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bcd(const T& x, const T& y) const; + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fds(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_fds(const T& x, const T& y) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fds_dr_min(const T& x) const; + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfds(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bfds(const T& x, const T& y) const; + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cds(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_cds(const T& x, const T& y) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cds_dr_min(const T& x) const; + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcds(const T& y) const; + + // locate x, y -> ind + CGPU_EXEC + ST rv_2_ir_bcds(const T& x, const T& y) const; + + /************ From position to index by searching ***********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_b(const T& x, ST ix_min=0, ST ix_max=0) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_b(const T& y, ST iy_min=0, ST iy_max=0) const; + + /***************************************************************************************/ + /********************************** check bounds ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const; + + CGPU_EXEC + dt_bool chk_bound_y(const T& y) const; + + CGPU_EXEC + dt_bool chk_bound(const R_2d& r) const; + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const; + + CGPU_EXEC + dt_bool chk_bound_y_eps(const T& y) const; + + CGPU_EXEC + dt_bool chk_bound_eps(const R_2d& r) const; + + /***************************************************************************************/ + /*********************************** set bounds ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T set_bound_x(const T& x) const; + + CGPU_EXEC + T set_bound_y(const T& y) const; + + CGPU_EXEC + R_2d set_bound(const R_2d& r) const; + + /***************************************************************************************/ + /************************************ front/back ***************************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx_front() const; + + CGPU_EXEC + T gx_back() const; + + CGPU_EXEC + T gy_front() const; + + CGPU_EXEC + T gy_back() const; + + /***************************************************************************************/ + CGPU_EXEC + T rx_front() const; + + CGPU_EXEC + T rx_back() const; + + CGPU_EXEC + T ry_front() const; + + CGPU_EXEC + T ry_back() const; + + /***************************************************************************************/ + /*********************************** factors *******************************************/ + /* calculate fermi low-pass filter alpha parameter */ + CGPU_EXEC + T fermi_lpf_alpha() const; + + CGPU_EXEC + T factor_2pi_rx_ctr(const T& x) const; + + CGPU_EXEC + T factor_2pi_ry_ctr(const T& y) const; + + CGPU_EXEC + R_2d factor_2pi_rv_ctr(const R_2d& r) const; + + CPU_EXEC + Vctr, edev_cpu> factor_2pi_rv_ctr(const Vctr, edev_cpu>& rv) const; + + /***************************************************************************************/ + iRegion_Rect_xd iregion_rect(const R_2d& r, const T& radius) const; + + iRegion_Rect_xd iregion_rect(const R_2d& r, const T& f0, const T& a, const T& b, const T& c); + }; +} + +#include "detail/grid_2d.inl" \ No newline at end of file diff --git a/src/grid_3d.h b/src/grid_3d.h new file mode 100755 index 00000000..3b6fdb32 --- /dev/null +++ b/src/grid_3d.h @@ -0,0 +1,767 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "grid_2d.h" +#include "igrid_3d.h" + +/* derived class */ +namespace mt +{ + template + using Grid_3d_st = Grid_sxd; + + template + using Grid_3d = Grid_sxd; + + template + using Grid_3d_64 = Grid_sxd; +} + +/* template specialization 3d */ +namespace mt +{ + template + class Grid_sxd: public iGrid_sxd + { + public: + using value_type = T; + using size_type = ST; + + T bs_x; // simulation box size along x direction (Angstroms) + T bs_y; // simulation box size along y direction (Angstroms) + T bs_z; // simulation box size along z direction (Angstroms) + + T rx_0; // reference coordinate system along x + T ry_0; // reference coordinate system along y + T rz_0; // reference coordinate system along z + + dt_bool pbc_x; // peridic boundary condition along x + dt_bool pbc_y; // peridic boundary condition along y + dt_bool pbc_z; // peridic boundary condition along z + + dt_bool bwl; // band-width limit + + T sli_thick; // slice thicknes + + T drx; // x-sampling in real space + T dry; // y-sampling in real space + T drz; // z-sampling in real space + + T dgx; // x-sampling in reciprocal space + T dgy; // y-sampling in reciprocal space + T dgz; // z-sampling in reciprocal space + + /************************************* constructors ************************************/ + Grid_sxd(); + + Grid_sxd(const ST& nx, const ST& ny, const ST& nz); + + template + Grid_sxd(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const ST& nz); + + template + Grid_sxd(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz, + const U& rx_0, const U& ry_0, const U& rz_0, dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool pbc_z = true, dt_bool bwl = false, U sli_thick = 0.5); + + /* copy constructor */ + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid); + + /* converting constructor */ + template + CGPU_EXEC + Grid_sxd(const Grid_sxd& grid); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid); + + /* converting assignment operator */ + template + CGPU_EXEC + Grid_sxd& operator=(const Grid_sxd& grid); + + template + CGPU_EXEC + void assign(const Grid_sxd& grid); + + /**************** user define conversion operators *******************/ + operator iRegion_Rect_xd() const; + + /***************************************************************************************/ + void set_in_data(const ST& nx, const ST& ny, const ST& nz); + + template + void set_in_data(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz); + + template + void set_in_data(const U& bs_x, const U& bs_y, const U& bs_z, const SU& nx, const SU& ny, const SU& nz, + const U& rx_0, const U& ry_0, const U& rz_0, dt_bool pbc_x = true, dt_bool pbc_y = true, dt_bool pbc_z = true, dt_bool bwl = false, U sli_thick = 0.5); + + void set_dep_var(); + + CGPU_EXEC + void set_r_0(const T& rx_0, const T& ry_0, const T& rz_0); + + CGPU_EXEC + void set_r_0(const R_3d& r_0); + + /***************************************************************************************/ + CGPU_EXEC + T nx_r() const; + + CGPU_EXEC + T ny_r() const; + + CGPU_EXEC + T nz_r() const; + + CGPU_EXEC + T size_r() const; + + T isize_r() const; + + /***************************************************************************************/ + CGPU_EXEC + T bs_x_h() const; + + CGPU_EXEC + T bs_y_h() const; + + CGPU_EXEC + T bs_z_h() const; + + CGPU_EXEC + R_3d bs_h() const; + + /***************************************************************************************/ + CGPU_EXEC + T bs_min() const; + + CGPU_EXEC + T bs_max() const; + + CGPU_EXEC + T bs_h_min() const; + + CGPU_EXEC + T bs_h_max() const; + + CGPU_EXEC + T rx_c() const; + + CGPU_EXEC + T ry_c() const; + + CGPU_EXEC + T rz_c() const; + + CGPU_EXEC + R_3d rv_c() const; + + /***************************************************************************************/ + // maximum frequency + CGPU_EXEC + T g_max() const; + + // maximum square frequency + CGPU_EXEC + T g2_max() const; + + // maximum allowed frequency + CGPU_EXEC + T gl_max() const; + + // maximum square allowed frequency + CGPU_EXEC + T gl2_max() const; + + CGPU_EXEC + T r_0_min() const; + + CGPU_EXEC + T dr_min() const; + + CGPU_EXEC + T dg_min() const; + + /***************************************************************************************/ + /********************** Fourier space positions **********************/ + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix) const; + + CGPU_EXEC + T gy(const ST& iy) const; + + CGPU_EXEC + T gz(const ST& iz) const; + + CGPU_EXEC + R_3d gv(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T gx2(const ST& ix) const; + + CGPU_EXEC + T gy2(const ST& iy) const; + + CGPU_EXEC + T gz2(const ST& iz) const; + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const ST& iz) const; + + /***************************************************************************************/ + CGPU_EXEC + T gx(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + T gz(const ST& iz, const T& gz_0) const; + + CGPU_EXEC + R_3d gv(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const; + + CGPU_EXEC + R_3d gv(const ST& ix, const ST& iy, const ST& iz, const R_3d& g_0) const; + + CGPU_EXEC + T gx2(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy2(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + T gz2(const ST& iz, const T& gz_0) const; + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const; + + CGPU_EXEC + T g2(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const; + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const; + + CGPU_EXEC + T g(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + T gx_sft(const ST& ix) const; + + CGPU_EXEC + T gy_sft(const ST& iy) const; + + CGPU_EXEC + T gz_sft(const ST& iz) const; + + CGPU_EXEC + R_3d gv_sft(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T gx2_sft(const ST& ix) const; + + CGPU_EXEC + T gy2_sft(const ST& iy) const; + + CGPU_EXEC + T gz2_sft(const ST& iz) const; + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const ST& iz) const; + + /***************************************************************************************/ + CGPU_EXEC + T gx_sft(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy_sft(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + T gz_sft(const ST& iz, const T& gz_0) const; + + CGPU_EXEC + R_3d gv_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const; + + CGPU_EXEC + R_3d gv_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g_0) const; + + CGPU_EXEC + T gx2_sft(const ST& ix, const T& gx_0) const; + + CGPU_EXEC + T gy2_sft(const ST& iy, const T& gy_0) const; + + CGPU_EXEC + T gz2_sft(const ST& iz, const T& gz_0) const; + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const; + + CGPU_EXEC + T g2_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const; + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const ST& iz, const T& gx_0, const T& gy_0, const T& gz_0) const; + + CGPU_EXEC + T g_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& g0) const; + + /***************************************************************************************/ + /******************************** real space positions *********************************/ + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix) const; + + CGPU_EXEC + T ry(const ST& iy) const; + + CGPU_EXEC + T rz(const ST& iz) const; + + CGPU_EXEC + R_3d rv(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T rx2(const ST& ix) const; + + CGPU_EXEC + T ry2(const ST& iy) const; + + CGPU_EXEC + T rz2(const ST& iz) const; + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const ST& iz) const; + + /***************************************************************************************/ + CGPU_EXEC + T rx(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry(const ST& iy, const T& y0) const; + + CGPU_EXEC + T rz(const ST& iz, const T& z0) const; + + CGPU_EXEC + R_3d rv(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const; + + CGPU_EXEC + R_3d rv(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const; + + CGPU_EXEC + T rx2(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry2(const ST& iy, const T& y0) const; + + CGPU_EXEC + T rz2(const ST& iz, const T& z0) const; + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const; + + CGPU_EXEC + T r2(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const; + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const; + + CGPU_EXEC + T r(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + T rx_sft(const ST& ix) const; + + CGPU_EXEC + T ry_sft(const ST& iy) const; + + CGPU_EXEC + T rz_sft(const ST& iz) const; + + CGPU_EXEC + R_3d rv_sft(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T rx2_sft(const ST& ix) const; + + CGPU_EXEC + T ry2_sft(const ST& iy) const; + + CGPU_EXEC + T rz2_sft(const ST& iz) const; + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const ST& iz) const; + + /***************************************************************************************/ + CGPU_EXEC + T rx_sft(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry_sft(const ST& iy, const T& y0) const; + + CGPU_EXEC + T rz_sft(const ST& iz, const T& z0) const; + + CGPU_EXEC + R_3d rv_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const; + + CGPU_EXEC + R_3d rv_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const; + + CGPU_EXEC + T rx2_sft(const ST& ix, const T& x0) const; + + CGPU_EXEC + T ry2_sft(const ST& iy, const T& y0) const; + + CGPU_EXEC + T rz2_sft(const ST& iz, const T& z0) const; + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const; + + CGPU_EXEC + T r2_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const; + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const ST& iz, const T& x0, const T& y0, const T& z0) const; + + CGPU_EXEC + T r_sft(const ST& ix, const ST& iy, const ST& iz, const R_3d& r_0) const; + + /***************************************************************************************/ + /******************** from position to index *************************/ + /***************************************************************************************/ + template + void ix_0_ix_n(const T& x, const T& x_max, SU& ix_0, SU& ix_n) const; + + template + void iy_0_iy_n(const T& y, const T& y_max, SU& iy_0, SU& iy_n) const; + + template + void iz_0_iz_n(const T& z, const T& z_max, SU& iz_0, SU& iz_n) const; + + template + void ix_0_ix_e(const T& x, const T& x_max, SU& ix_0, SU& ix_e) const; + + template + void iy_0_iy_e(const T& y, const T& y_max, SU& iy_0, SU& iy_e) const; + + template + void iz_0_iz_e(const T& z, const T& z_max, SU& iz_0, SU& iz_e) const; + + /*************** fds = floor/division by pixel size ******************/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fd(const T& y) const; + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_fd(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_fd(const T& x, const T& y, const T& z) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fd_dr_min(const T& x) const; + + /********* bfds = bound/floor/division by pixel size ********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfd(const T& y) const; + + // locate z-> irz + CGPU_EXEC + ST rz_2_irz_bfd(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bfd(const T& x, const T& y, const T& z) const; + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cd(const T& y) const; + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_cd(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_cd(const T& x, const T& y, const T& z) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cd_dr_min(const T& x) const; + + /****** bcds = bound/ceil/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcd(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcd(const T& y) const; + + // locate z -> iry + CGPU_EXEC + ST rz_2_irz_bcd(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bcd(const T& x, const T& y, const T& z) const; + + /********* fds = floor/division by pixel size/shift *********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_fds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_fds(const T& y) const; + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_fds(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_fds(const T& x, const T& y, const T& z) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_fds_dr_min(const T& x) const; + + /****** bfds = bound/floor/division by pixel size/shift ******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bfds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bfds(const T& y) const; + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_bfds(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bfds(const T& x, const T& y, const T& z) const; + + /********* cds = ceil/division by pixel size/shift **********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_cds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_cds(const T& y) const; + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_cds(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_cds(const T& x, const T& y, const T& z) const; + + // locate r -> ir using dr_min + CGPU_EXEC + ST r_2_ir_cds_dr_min(const T& x) const; + + /****** bcds = bound/ceil/division by pixel size/shift *******/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_bcds(const T& x) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_bcds(const T& y) const; + + // locate z -> irz + CGPU_EXEC + ST rz_2_irz_bcds(const T& z) const; + + // locate x, y, z -> ind + CGPU_EXEC + ST rv_2_ir_bcds(const T& x, const T& y, const T& z) const; + + /************ From position to index by searching ***********/ + // locate x -> irx + CGPU_EXEC + ST rx_2_irx_b(const T& x, ST ix_min=0, ST ix_max=0) const; + + // locate y -> iry + CGPU_EXEC + ST ry_2_iry_b(const T& y, ST iy_min=0, ST iy_max=0) const; + + // locate z-> irz + CGPU_EXEC + ST rz_2_irz_b(const T& z, ST iz_min=0, ST iz_max=0) const; + + /***************************************************************************************/ + /********************************* check bounds ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const; + + CGPU_EXEC + dt_bool chk_bound_y(const T& y) const; + + CGPU_EXEC + dt_bool chk_bound_z(const T& z) const; + + CGPU_EXEC + dt_bool chk_bound(const R_3d& r) const; + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const; + + CGPU_EXEC + dt_bool chk_bound_y_eps(const T& y) const; + + CGPU_EXEC + dt_bool chk_bound_z_eps(const T& z) const; + + CGPU_EXEC + dt_bool chk_bound_eps(const R_3d& r) const; + + /***************************************************************************************/ + /*********************************** set bounds ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T set_bound_x(const T& x) const; + + CGPU_EXEC + T set_bound_y(const T& y) const; + + CGPU_EXEC + T set_bound_z(const T& z) const; + + CGPU_EXEC + R_3d set_bound(const R_3d& r) const; + + /***************************************************************************************/ + /*********************************** front/back ****************************************/ + /***************************************************************************************/ + CGPU_EXEC + T gx_front() const; + + CGPU_EXEC + T gx_back() const; + + CGPU_EXEC + T gy_front() const; + + CGPU_EXEC + T gy_back() const; + + CGPU_EXEC + T gz_front() const; + + CGPU_EXEC + T gz_back() const; + + /***************************************************************************************/ + CGPU_EXEC + T rx_front() const; + + CGPU_EXEC + T rx_back() const; + + CGPU_EXEC + T ry_front() const; + + CGPU_EXEC + T ry_back() const; + + CGPU_EXEC + T rz_front() const; + + CGPU_EXEC + T rz_back() const; + + /***************************************************************************************/ + /************************************* factors *****************************************/ + /***************************************************************************************/ + /* calculate fermi low-pass filter alpha parameter */ + CGPU_EXEC + T fermi_lpf_alpha() const; + + CGPU_EXEC + T factor_2pi_rx_ctr(const T& x) const; + + CGPU_EXEC + T factor_2pi_ry_ctr(const T& y) const; + + CGPU_EXEC + T factor_2pi_rz_ctr(const T& z) const; + + CGPU_EXEC + R_3d factor_2pi_rv_ctr(const R_3d& r) const; + + CPU_EXEC + Vctr, edev_cpu> factor_2pi_rv_ctr(const Vctr, edev_cpu>& rv) const; + + /***************************************************************************************/ + iRegion_Rect_xd iregion_rect(const R_3d& r, const T& radius) const; + + iRegion_Rect_xd iregion_rect(const R_3d& r, const T& f0, const T& a, const T& b, const T& c); + }; +} + +#include "detail/grid_3d.inl" \ No newline at end of file diff --git a/src/host_device_classes.cuh b/src/host_device_classes.cuh new file mode 100755 index 00000000..9828001d --- /dev/null +++ b/src/host_device_classes.cuh @@ -0,0 +1,2796 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MULTEM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MULTEM. If not, see . + */ + +#ifndef HOST_DEVICE_CLASSES_H +#define HOST_DEVICE_CLASSES_H + +#include "math.cuh" +#include "types.cuh" +#include "traits.cuh" +#include "stream.cuh" +#include "fft.cuh" +#include "random.cuh" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +#include "host_device_functions.cuh" +#include "host_functions.hpp" + +#ifdef __CUDACC__ + #include "device_functions.cuh" +#endif +namespace mt +{ + /**************** Gaussian Conv ***************/ + template + class Gauss_Cv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Cv_1d():fft_1d(nullptr){} + + Gauss_Cv_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, TVector_c &Im) + { + fft1_shift(grid_1d, Im); + fft_1d->forward(Im); + + gauss_cv_1d(sigma_r, Im); + + fft_1d->inverse(Im); + fft1_shift(grid_1d, Im); + } + + void operator()(T sigma_r, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_1d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + for (auto ix = 0; ix < grid_1d.nx; ix++) + { + host_device_detail::gauss_cv_1d, TVector_c>(ix, grid_1d, alpha, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_1d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_1d.cuda_grid(); + device_detail::gauss_cv_1d, typename TVector_c::value_type><<>>(grid_1d, alpha, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Cv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Cv_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Gauss_Cv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVector_c &Im) + { + fft2_sft_bc(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, Im); + + fft_2d->inverse(Im); + fft2_sft_bc(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vector gauss_vector_1d(T alpha) + { + TVector_r fg; + fg.reserve(grid_2d.ny); + + for (auto iy=0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_shift(iy))/grid_2d.ny_r(); + fg.push_back(v); + } + return fg; + } + + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_2d_bc(T sigma_r, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::vector_col_x_matrix, TVector_r, TVector_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_2d_bc(T sigma_r, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha); + TVector_r fg = fg_h; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::vector_col_x_matrix, typename TVector_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Cv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Cv_2d():stream(nullptr), fft_2d(nullptr){} + + Gauss_Cv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, TVector_c &Im) + { + fft2_shift(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d(sigma_r, Im); + + fft_2d->inverse(Im); + fft2_shift(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_2d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::gauss_cv_2d, TVector_c>, grid_2d, alpha, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_2d(T sigma_r, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::gauss_cv_2d, typename TVector_c::value_type><<>>(grid_2d, alpha, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /**************** Gaussian Deconv ***************/ + template + class Gauss_Dcv_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Dcv_1d():fft_1d(nullptr){} + + Gauss_Dcv_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + } + + void operator()(T sigma_r, T PSNR, TVector_c &Im) + { + fft1_shift(grid_1d, Im); + fft_1d->forward(Im); + + gauss_dcv_1d(sigma_r, PSNR, Im); + + fft_1d->inverse(Im); + fft1_shift(grid_1d, Im); + } + + void operator()(T sigma_r, T PSNR, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_1d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_dcv_1d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + for (auto ix = 0; ix < grid_1d.nx; ix++) + { + host_device_detail::gauss_dcv_1d, TVector_c>(ix, grid_1d, alpha, PSNR, Im); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_dcv_1d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_1d.cuda_grid(); + device_detail::gauss_dcv_1d, typename TVector_c::value_type><<>>(grid_1d, alpha, PSNR, Im); + } + #endif + + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Gauss_Dcv_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Dcv_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Gauss_Dcv_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVector_c &Im) + { + fft2_sft_bc(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_cv_2d_bc(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fft2_sft_bc(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Vector gauss_vector_1d(T alpha, T PSNR) + { + TVector_r fg; + fg.reserve(grid_2d.ny); + + for (auto iy=0; iy < grid_2d.ny; iy++) + { + auto v = exp(-alpha*grid_2d.gy2_shift(iy)); + fg.push_back(v/((v*v+PSNR)*grid_2d.ny_r())); + } + return fg; + } + + /************************Host************************/ + template + enable_if_dev_host + gauss_cv_2d_bc(T sigma_r, T PSNR, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg = gauss_vector_1d(alpha, PSNR); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::vector_col_x_matrix, TVector_r, TVector_c>, grid_2d, fg, M_g); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_cv_2d_bc(T sigma_r, T PSNR, TVector_c &M_g) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + auto fg_h = gauss_vector_1d(alpha, PSNR); + TVector_r fg = fg_h; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::vector_col_x_matrix, typename TVector_c::value_type><<>>(grid_2d, fg, M_g); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Gauss_Dcv_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Gauss_Dcv_2d():stream(nullptr), fft_2d(nullptr){} + + Gauss_Dcv_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T sigma_r, T PSNR, TVector_c &Im) + { + fft2_shift(*stream, grid_2d, Im); + fft_2d->forward(Im); + + gauss_dcv_2d(sigma_r, PSNR, Im); + + fft_2d->inverse(Im); + fft2_shift(*stream, grid_2d, Im); + } + + void operator()(T sigma_r, T PSNR, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + + this->operator()(sigma_r, PSNR, Im_c); + + assign_real(Im_c, Im); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + /************************Host************************/ + template + enable_if_dev_host + gauss_dcv_2d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::gauss_dcv_2d, TVector_c>, grid_2d, alpha, PSNR, Im); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + gauss_dcv_2d(T sigma_r, T PSNR, TVector_c &Im) + { + auto alpha = 2*c_Pi2*sigma_r*sigma_r; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::gauss_dcv_2d, typename TVector_c::value_type><<>>(grid_2d, alpha, PSNR, Im); + } + #endif + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /****************Gauss_Spt***************/ + template + class Gauss_Spt + { + public: + using T_r = T; + using TVector_r = Vector; + + using size_type = std::size_t; + + static const eDevice device = dev; + + Gauss_Spt(): input_gauss_spt(nullptr), stream(nullptr), n_atoms_p(512){} + + void set_input_data(Input_Gauss_Spt *input_gauss_spt_i, Stream *stream_i) + { + input_gauss_spt = input_gauss_spt_i; + stream = stream_i; + + n_atoms_p = (device==e_host)?(stream->size()):512; + + if(device==e_host) + { + int nv = input_gauss_spt->get_nv(); + stream_data.resize(n_atoms_p); + for(auto i = 0; i + enable_if_dev_host + operator()(TVector_r &Im) + { + auto gauss_eval = [](Stream &stream, Grid_2d &grid_2d, + Vector, e_host> &gauss, TVector_r &M_o) + { + if(stream.n_act_stream<= 0) + { + return; + } + + for(auto istream = 0; istream < stream.n_act_stream-1; istream++) + { + stream[istream] = std::thread(std::bind(host_detail::gauss_eval, std::ref(stream), std::ref(grid_2d), std::ref(gauss[istream]), std::ref(M_o))); + } + + host_detail::gauss_eval(stream, grid_2d, gauss[stream.n_act_stream-1], M_o); + + stream.synchronize(); + }; + + mt::fill(*stream, Im, 0.0); + + int iatom_0 = 0; + int iatom_e = input_gauss_spt->atoms.size()-1; + + int iatoms = iatom_0; + while (iatoms <= iatom_e) + { + stream->set_n_act_stream(iatom_e-iatoms+1); + set_gauss_sp(iatoms, stream->n_act_stream, gauss_sp); + + gauss_eval(*stream, input_gauss_spt->grid_2d, gauss_sp, Im); + iatoms += stream->n_act_stream; + } + + stream->synchronize(); + } + + /***********************Device***********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector_r &Im) + { + auto get_eval_cubic_poly_gridBT = [](int natoms)->Grid_BT + { + Grid_BT grid_bt; + grid_bt.Blk = dim3(natoms, 1, 1); + grid_bt.Thr = dim3(c_thrnxny, c_thrnxny, 1); + + return grid_bt; + }; + + mt::fill(*stream, Im, 0.0); + + int iatom_0 = 0; + int iatom_e = input_gauss_spt->atoms.size()-1; + + int iatoms = iatom_0; + while (iatoms <= iatom_e) + { + int n_atoms = min(n_atoms_p, iatom_e-iatoms+1); + set_gauss_sp(iatoms, n_atoms, gauss_sp); + + auto grid_bt = get_eval_cubic_poly_gridBT(n_atoms); + device_detail::gauss_eval<<>>(input_gauss_spt->grid_2d, gauss_sp, Im); + + iatoms += n_atoms; + } + } + #endif + + Input_Gauss_Spt *input_gauss_spt; + Stream *stream; + private: + int n_atoms_p; + + struct Stream_Data + { + using value_type = T; + using size_type = std::size_t; + + static const eDevice device = e_host; + + size_type size() const + { + return iv.size(); + } + + void resize(const size_type &new_size) + { + iv.resize(new_size); + v.resize(new_size); + } + + Vector, e_host> iv; + Vector, e_host> v; + }; + + void set_gauss_sp(int iatoms, int n_atoms_p, Vector, dev> &gauss_sp) + { + for(auto istream = 0; istream < n_atoms_p; istream++) + { + gauss_sp_h[istream].x = input_gauss_spt->atoms.x[iatoms]; + gauss_sp_h[istream].y = input_gauss_spt->atoms.y[iatoms]; + gauss_sp_h[istream].a = input_gauss_spt->atoms.a[iatoms]; + gauss_sp_h[istream].alpha = input_gauss_spt->alpha(iatoms); + auto R_max = input_gauss_spt->R_max(iatoms); + auto R2_max = R_max*R_max; + gauss_sp_h[istream].R2_tap = pow(0.85*R_max, 2); + gauss_sp_h[istream].tap_cf = c_i2Pi/(R2_max-gauss_sp_h[istream].R2_tap); + gauss_sp_h[istream].R2_max = R2_max; + gauss_sp_h[istream].set_ix0_ixn(input_gauss_spt->grid_2d, R_max); + gauss_sp_h[istream].set_iy0_iyn(input_gauss_spt->grid_2d, R_max); + if(device==e_host) + { + gauss_sp_h[istream].iv = raw_pointer_cast(stream_data.iv[istream].data()); + gauss_sp_h[istream].v = raw_pointer_cast(stream_data.v[istream].data()); + } + iatoms++; + } + thrust::copy(gauss_sp_h.begin(), gauss_sp_h.end(), gauss_sp.begin()); + } + + Stream_Data stream_data; + Vector, e_host> gauss_sp_h; + Vector, dev> gauss_sp; + }; + + /****************affine transformations***************/ + template + class Sc_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Sc_2d(): stream(nullptr){} + + Sc_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T sxy, TVector &M_o) + { + if(isEqual(sxy, T(1))) + { + M_o = M_i; + } + + int nx_o = get_new_size(grid_2d.nx, sxy); + int ny_o = get_new_size(grid_2d.ny, sxy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::sc_2d, TVector>, grid_2d, M_i, sxy, grid_2d_o, M_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, T sxy, TVector &M_o) + { + if(isEqual(sxy, T(1))) + { + M_o = M_i; + } + + int nx_o = max(int(floor(grid_2d.nx*sxy)), 1); + int ny_o = max(int(floor(grid_2d.ny*sxy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + auto grid_bt = grid_2d_o.cuda_grid(); + device_detail::sc_2d, typename TVector::value_type><<>>(grid_2d, M_i, sxy, grid_2d_o, M_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Rot_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Rot_2d(): stream(nullptr){} + + Rot_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T theta, r2d p0, TVector &M_o) + { + if(isZero(theta)) + { + M_o = M_i; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::rot_2d, TVector>, grid_2d, M_i, theta, p0, bg, grid_2d_o, M_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, T theta, r2d p0, TVector &M_o) + { + if(isZero(theta)) + { + M_o = M_i; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + auto grid_bt = grid_2d_o.cuda_grid(); + device_detail::rot_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, bg, grid_2d_o, M_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Rot_Sca_sft_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Rot_Sca_sft_2d():stream(nullptr){} + + Rot_Sca_sft_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) + { + // calculate background + T bg = mean(*stream, M_i); + + int nx_o = get_new_size(grid_2d.nx, sx); + int ny_o = get_new_size(grid_2d.ny, sy); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) + { + // calculate background + T bg = mean(*stream, M_i); + + int nx_o = max(int(floor(grid_2d.nx*sx)), 1); + int ny_o = max(int(floor(grid_2d.ny*sy)), 1); + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + + auto grid_bt = grid_2d_o.cuda_grid(); + device_detail::rot_sca_sft_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Data_Aug_2d + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Data_Aug_2d():stream(nullptr){} + + Data_Aug_2d(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + /************************Host************************/ + template + enable_if_dev_host + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, T sim, + int nx_o, int ny_o, TVector &M_o) + { + // calculate maximum + auto M_max = *thrust::max_element(M_i.begin(), M_i.end()); + + // calculate background + auto g_max = grid_2d.gx_last(); + auto g_min = 0.9*g_max; + //T bg = sum_over_Det(*stream, grid_2d, g_min, g_max, M_i); + + T bg = 0.6*mean(*stream, M_i); + + T Rx_0 = p0.x*sx-(nx_o/2)*grid_2d.dRx; + T Ry_0 = p0.y*sy-(ny_o/2)*grid_2d.dRy; + + Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); + grid_2d_o.set_R_0(Rx_0, Ry_0); + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); + + normalized_data(M_o, M_max); + + // add Poisson noise + M_o = add_poiss_nois(*stream, M_o, sim); + + M_max = *thrust::max_element(M_o.begin(), M_o.end()); + normalized_data(M_o, M_max); + } + + protected: + void normalized_data(TVector &M, T M_max) + { + std::for_each(M.begin(), M.end(), [M_max](T &v){ v = (v>0)?v/M_max:0;}); + } + + Grid_2d grid_2d; + Stream *stream; + }; + + template + class Shx_Scy + { + public: + using T_r = T; + using TVector = Vector; + + static const eDevice device = dev; + + Shx_Scy():stream(nullptr){} + + Shx_Scy(Stream *stream_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + grid_2d = grid_2d_i; + } + + template + enable_if_dev_host + operator()(TVector &M_i, r2d af, TVector &M_o) + { + if(isZero(af.x) && isEqual(af.y, T(1))) + { + M_o = M_i; + } + + TVector M_o_t; + TVector *pM_o = &M_o; + + if (M_i.data() == M_o.data()) + { + M_o_t.resize(M_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + stream->set_n_act_stream(grid_2d_o.nx); + stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); + stream->exec_matrix(host_device_detail::shx_scy, TVector>, grid_2d, M_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (M_i.data() == M_o.data()) + { + M_o.assign(pM_o->begin(), pM_o->end()); + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + operator()(TVector &M_i, r2d af, TVector &M_o) + { + if(isZero(af.x) && isEqual(af.y, T(1))) + { + M_o = M_i; + } + + TVector M_o_t; + TVector *pM_o = &M_o; + + if (M_i.data() == M_o.data()) + { + M_o_t.resize(M_i.size()); + pM_o = &M_o_t; + } + + // calculate background + T bg = mean(*stream, M_i); + + Grid_2d grid_2d_o = grid_2d; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::shx_scy, typename TVector::value_type><<>>(grid_2d, M_i, af.x, af.y, bg, grid_2d_o, *pM_o); + + if (M_i.data() == M_o.data()) + { + M_o.assign(pM_o->begin(), pM_o->end()); + } + } + #endif + + protected: + Grid_2d grid_2d; + Stream *stream; + }; + + /**********************shift*************************/ + template + class Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Sft_1d():fft_1d(nullptr){} + + Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx); + } + + void operator()(T xs, TVector_c &Im) + { + fft1_shift(grid_1d, Im); + fft_1d->forward(Im); + exp_g_factor_1d(grid_1d, -c_2Pi*xs, Im, Im); + fft_1d->inverse(Im); + fft1_shift(grid_1d, Im); + } + + void operator()(T xs, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + T Im_min = min_element(Im); + + this->operator()(xs, Im_c); + assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_1d->cleanup(); + } + + protected: + FFT *fft_1d; + Grid_1d grid_1d; + }; + + template + class Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Sft_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(T alpha, TVector_r ys, TVector_c &Im) + { + fft2_sft_bc(*stream, grid_2d, Im); + fft_2d->forward(Im); + exp_g_factor_2d_bc(*stream, grid_2d, -c_2Pi*alpha, ys, Im, Im); + fft_2d->inverse(Im); + fft2_sft_bc(*stream, grid_2d, Im); + } + + void operator()(T alpha, TVector_r ys, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + T Im_min = min_element(Im); + + this->operator()(alpha, ys, Im_c); + assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + template + class Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Sft_2d():stream(nullptr), fft_2d(nullptr){} + + Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(r2d p, TVector_c &Im) + { + fft2_shift(*stream, grid_2d, Im); + fft_2d->forward(Im); + exp_g_factor_2d(*stream, grid_2d, -c_2Pi*p.x, -c_2Pi*p.y, Im, Im); + fft_2d->inverse(Im); + fft2_shift(*stream, grid_2d, Im); + } + + void operator()(r2d p, TVector_r &Im) + { + TVector_c Im_c(Im.begin(), Im.end()); + T Im_min = min_element(Im); + + this->operator()(p, Im_c); + assign_real(Im_c, Im, Im_min); + } + + void cleanup() + { + fft_2d->cleanup(); + } + protected: + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /******************phase correlation*****************/ + template + class Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Pcf_1d(): fft_1d(nullptr){} + + Pcf_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + fft_1d = fft_1d_i; + grid_1d = grid_1d_i; + + Prime_Num pn; + + int nx = pn(2*grid_1d.nx-1, eDST_Greater_Than); + + grid_1d_e.set_input_data(nx, grid_1d.dRx*nx); + + M_r_c.resize(grid_1d_e.nx); + M_s_c.resize(grid_1d_e.nx); + } + + void set_fft_plan() + { + fft_1d->create_plan_1d(grid_1d.nx, 1); + fft_1d_e.create_plan_1d(grid_1d_e.nx, 1); + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Border_1d bd, bool b_pv, TVector_r &M_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVector_c &pcf = M_s_c; + + // shift matrix + fft1_shift(grid_1d_e, M_r_c); + fft1_shift(grid_1d_e, M_s_c); + + // fft_1d_e + fft_1d_e.forward(M_r_c); + fft_1d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + + fft_1d_e.inverse(pcf); + + // shift pcf + fft1_shift(grid_1d_e, pcf); + + int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + this->assign_real(pcf, ix_s, M_o, b_pv); + } + + void cleanup() + { + fft_1d->destroy_plan(); + fft_1d_e.cleanup(); + } + + protected: + + void assign_real(TVector_c &M_i, int ix_s, TVector_r &M_o, bool b_pos = false) + { + auto first = M_i.begin() + ix_s; + auto last = first + grid_1d.nx; + + if(b_pos) + { + thrust::transform(first, last, M_o.begin(), functor::assign_max_real(0)); + } + else + { + thrust::transform(first, last, M_o.begin(), functor::assign_real()); + } + } + + /************************Host************************/ + template + enable_if_dev_host + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Butterworth_1d bw_1d(bd, bd.radius_ptl(p), 32); + + for (auto ix = 0; ix < grid_1d.nx; ix++) + { + host_device_detail::pcf_1d_pp(ix, ix_s, grid_1d, bw_1d, M_i, M_o); + } + } + + template + enable_if_dev_host + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_1d gs_1d(0, sigma_g); + + for (auto ix = 0; ix < grid_1d_e.nx; ix++) + { + host_device_detail::pcf_1d_gaussian(ix, grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + } + + /***********************Device***********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int ix_s = (grid_1d_e.nx-grid_1d.nx)/2; + + Butterworth_1d bw_1d(bd, bd.radius_ptl(p), 32); + + auto grid_bt = grid_1d.cuda_grid(); + device_detail::pcf_1d_pp, typename TVector_c::value_type><<>>(ix_s, grid_1d, bw_1d, M_i, M_o); + } + + template + enable_if_dev_device + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_1d gs_1d(0, sigma_g); + + auto grid_bt = grid_1d_e.cuda_grid(); + device_detail::pcf_1d_gaussian, typename TVector_c::value_type><<>>(grid_1d_e, gs_1d, M_r_c, M_s_c, pcf); + } + #endif + + TVector_c M_r_c; + TVector_c M_s_c; + + FFT *fft_1d; + Grid_1d grid_1d; + + private: + FFT fft_1d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Pcf_2d_BC():stream(nullptr), fft_2d(nullptr){} + + Pcf_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + grid_1d.set_input_data(grid_2d.ny, grid_2d.ly); + + Prime_Num pn; + + int ny = pn(2*grid_2d.ny-1, eDST_Greater_Than); + + grid_2d_e.set_input_data(grid_2d.nx, ny, grid_2d.lx, grid_2d.dRy*ny); + grid_1d_e.set_input_data(grid_2d_e.ny, grid_2d_e.ly); + + M_r_c.resize(grid_2d_e.nxy()); + M_s_c.resize(grid_2d_e.nxy()); + } + + void set_fft_plan() + { + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d_e.create_plan_1d_batch(grid_2d_e.ny, grid_2d_e.nx, stream->size()); + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Border_1d bd, bool b_pv, TVector_r &M_o) + { + thrust::fill(M_r_c.begin(), M_r_c.end(), T(0)); + thrust::fill(M_s_c.begin(), M_s_c.end(), T(0)); + + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVector_c &pcf = M_s_c; + + // shift matrix + fft2_sft_bc(*stream, grid_2d_e, M_r_c); + fft2_sft_bc(*stream, grid_2d_e, M_s_c); + + // fft_2d + fft_2d_e.forward(M_r_c); + fft_2d_e.forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + fft_2d_e.inverse(pcf); + + // shift pcf + fft2_sft_bc(*stream, grid_2d_e, pcf); + + int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + this->assign_real(pcf, iy_s, M_o, b_pv); + } + + void cleanup() + { + fft_2d->destroy_plan(); + fft_2d_e.cleanup(); + } + + protected: + + TVector_r gauss_vector_1d(Grid_1d &grid_1d, T sigma_g, bool b_norm = false) + { + Gauss_1d gs_1d(0, sigma_g); + + TVector_r fg; + fg.reserve(grid_1d.nx); + + for (auto ix=0; ix < grid_1d.nx; ix++) + { + T g2 = grid_1d.g2_shift(ix); + T v = gs_1d(g2); + fg.push_back(v); + } + return fg; + } + + /************************Host************************/ + template + enable_if_dev_host + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh = func_butterworth_1d(grid_1d, bd.radius_ptl(p), 32, false, bd); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::pcf_2d_bc_pp, TVector_r, TVector_c>, iy_s, grid_2d, grid_2d_e, M_i, fh, M_o); + } + + template + enable_if_dev_host + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + auto fg = gauss_vector_1d(grid_1d_e, sigma_g); + + stream->set_n_act_stream(grid_2d_e.nx); + stream->set_grid(grid_2d_e.nx, grid_2d_e.ny); + stream->exec_matrix(host_device_detail::pcf_2d_bc_gaussian, TVector_r, TVector_c>, grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_dev_host + assign_real(TVector_c &M_i, int iy_s, TVector_r &M_o, bool b_pos = false) + { + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + int ixy_i = grid_2d_e.ind_col(ix, iy+iy_s); + int ixy_o = grid_2d.ind_col(ix, iy); + auto v = M_i[ixy_i].real(); + M_o[ixy_o] = (!b_pos || (v>0))?v:0; + } + } + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + preprocessing(TVector_r &M_i, T p, Border_1d &bd, TVector_c &M_o) + { + int iy_s = (grid_2d_e.ny-grid_2d.ny)/2; + + auto fh_h = func_butterworth_1d>(grid_1d, bd.radius_ptl(p), 32, false, bd); + TVector_r fh = fh_h; + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_bc_pp, typename TVector_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, M_i, fh, M_o); + } + + template + enable_if_dev_device + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + auto fg_h = gauss_vector_1d(grid_1d_e, sigma_g); + TVector_r fg = fg_h; + + auto grid_bt = grid_2d_e.cuda_grid(); + device_detail::pcf_2d_bc_gaussian, typename TVector_c::value_type><<>>(grid_2d_e, M_r_c, M_s_c, fg, pcf); + } + + template + enable_if_dev_device + assign_real(TVector_c &M_i, int iy_s, TVector_r &M_o, bool b_pos = false) + { + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_bc_assign_real, typename TVector_c::value_type><<>>(iy_s, grid_2d, grid_2d_e, M_i, M_o, b_pos); + } + #endif + + Vector M_r_c; + Vector M_s_c; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + Grid_1d grid_1d; + + private: + FFT fft_2d_e; + Grid_2d grid_2d_e; + Grid_1d grid_1d_e; + }; + + template + class Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + static const eDevice device = dev; + + Pcf_2d():stream(nullptr), fft_2d(nullptr){} + + Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + stream = stream_i; + fft_2d = fft_2d_i; + grid_2d = grid_2d_i; + + M_r_c.resize(grid_2d.nxy()); + M_s_c.resize(grid_2d.nxy()); + } + + void set_fft_plan() + { + fft_2d->create_plan_2d(grid_2d.ny, grid_2d.nx, stream->size()); + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Border_2d bd, bool b_pv, TVector_r &M_o) + { + preprocessing(M_r, p, bd, M_r_c); + preprocessing(M_s, p, bd, M_s_c); + + TVector_c &pcf = M_s_c; + + // shift matrix + fft2_shift(*stream, grid_2d, M_r_c); + fft2_shift(*stream, grid_2d, M_s_c); + + // fft_2d + fft_2d->forward(M_r_c); + fft_2d->forward(M_s_c); + + pcf_g(M_r_c, M_s_c, sigma_g, pcf); + fft_2d->inverse(pcf); + + // shift pcf + fft2_shift(*stream, grid_2d, pcf); + + T pv = (b_pv)?1:-1; + assign_real(pcf, M_o, pv); + } + + void cleanup() + { + fft_2d->cleanup(); + } + + protected: + /************************Host************************/ + template + enable_if_dev_host + preprocessing(TVector_r &M_i, T p, Border_2d &bd, TVector_c &M_o) + { + Butterworth_2d bw_2d(bd, bd.radius_ptl(p), 32); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::pcf_2d_pp, TVector_r, TVector_c>, grid_2d, bw_2d, M_i, M_o); + } + + template + enable_if_dev_host + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_2d gs_2d(0, 0, sigma_g); + + stream->set_n_act_stream(grid_2d.nx); + stream->set_grid(grid_2d.nx, grid_2d.ny); + stream->exec_matrix(host_device_detail::pcf_2d_gaussian, TVector_c>, grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + + /**********************Device**********************/ + #ifdef __CUDACC__ + template + enable_if_dev_device + preprocessing(TVector_r &M_i, T p, Border_2d &bd, TVector_c &M_o) + { + Butterworth_2d bw_2d(bd, bd.radius_ptl(p), 32); + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_pp, typename TVector_c::value_type><<>>(grid_2d, bw_2d, M_i, M_o); + } + + template + enable_if_dev_device + pcf_g(TVector_c &M_r_c, TVector_c &M_s_c, T sigma_g, TVector_c &pcf) + { + Gauss_2d gs_2d(0, 0, sigma_g); + + auto grid_bt = grid_2d.cuda_grid(); + device_detail::pcf_2d_gaussian, typename TVector_c::value_type><<< grid_bt.Blk, grid_bt.Thr >>>(grid_2d, gs_2d, M_r_c, M_s_c, pcf); + } + #endif + + Vector M_r_c; + Vector M_s_c; + + Stream *stream; + FFT *fft_2d; + Grid_2d grid_2d; + }; + + /********************find shift**********************/ + template + class Fd_Sft_1d: public Pcf_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Fd_Sft_1d(): Pcf_1d(){} + + Fd_Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i): Pcf_1d() + { + set_input_data(fft_1d_i, grid_1d_i); + } + + inline + void set_input_data(FFT *fft_1d_i, Grid_1d &grid_1d_i) + { + Pcf_1d::set_input_data(fft_1d_i, grid_1d_i); + sft_1d.set_input_data(fft_1d_i, grid_1d_i); + } + + T operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, T dx, + Border_1d bd, int nit_pcf) + { + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.dRx, 0.9*sigma_r); + + TVector_r M = M_s; + TVector_r pcf(M.size()); + + if(nonZero(dx)) + { + sft_1d(dx, M); + } + + for (auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); + + // get maximun position + T x_c = host_device_detail::max_pos_1d(this->grid_1d, pcf); + + if(it==nit_pcf-1) + { + x_c = fit_max_pos_1d(this->grid_1d, pcf, x_c, sigma_r, radius); + } + + T dx_t = -(x_c - this->grid_1d.lxh()); + + if(it sft_1d; + }; + + template + class Fd_Sft_2d_BC: public Pcf_2d_BC + { + public: + using TB = std::pair; + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + using TVector_rh = Vector; + using TVector_ch = Vector; + + Fd_Sft_2d_BC(): Pcf_2d_BC() {} + + Fd_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Pcf_2d_BC() + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + Pcf_2d_BC::set_input_data(stream_i, fft_2d_i, grid_2d_i); + gauss_cv_2d_bc.set_input_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d_bc.set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + TVector_rh operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, TVector_rh dx, + Border_2d bd_2d, int nit_pcf) + { + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_1d.dRx, 0.9*sigma_r); + Border_1d bd_1d(bd_2d.ly, bd_2d.yb_0, bd_2d.yb_e); + Peaks peaks(this->grid_1d, &bd_1d); + + TVector_r M_r = M_r_i; + TVector_r M_s = M_s_i; + TVector_r pcf(M_r.size()); + + // Gaussian filter + gauss_cv_2d_bc(sigma_r, M_r); + gauss_cv_2d_bc(sigma_r, M_s); + + const int ix_0 = this->grid_2d.ceil_dRx(bd_2d.x_0()); + const int ix_e = this->grid_2d.floor_dRx(bd_2d.x_e()); + + bool dx_s = false; + for(auto ix=0; ixgrid_1d.nx, T(0)); + + for (auto it=0; it::operator()(M_r, M_s, p, sigma_g, bd_1d, false, pcf); + + // get maximum distance + T d_max = (it==0)?peaks.get_d_max_0(ix_0, ix_e, pcf):peaks.get_d_max(ix_0, ix_e, dx_t); + d_max = ::fmax(sigma_r, d_max); + + for(auto ix=ix_0; ixgrid_1d.nx, pcf.begin()+(ix+1)*this->grid_1d.nx); + + auto py = peaks.find(ix, M_r, M_s, y, d_max); + if(it==nit_pcf-1) + { + py = fit_max_pos_1d(this->grid_1d, y, py, sigma_r, radius); + } + dx_t[ix] = -(py - this->grid_1d.lxh()); + dx[ix] += dx_t[ix]; + } + + // shift by column + if(it gauss_cv_2d_bc; + Sft_2d_BC sft_2d_bc; + + private: + struct Peaks + { + public: + using TVector_ih = Vector; + + Peaks(): y_c(0), bd_1d(nullptr){} + + Peaks(Grid_1d &grid_1d_i, Border_1d *bd_1d_i) + { + set_input_data(grid_1d_i, bd_1d_i); + } + + inline + void set_input_data(Grid_1d &grid_1d_i, Border_1d *bd_1d_i) + { + grid_1d = grid_1d_i; + bd_1d = bd_1d_i; + fft_1d.create_plan_1d(grid_1d.nx, 1); + sft_1d.set_input_data(&fft_1d, grid_1d); + + ix_pk.resize(grid_1d.nx); + x_pk.resize(grid_1d.nx); + y_pk.resize(grid_1d.nx); + } + + T get_d_max_0(int ix_0, int ix_e, TVector_r &pcf) + { + T x_c = grid_1d.lxh(); + TVector_rh dx; + dx.reserve(grid_1d.nx); + + for(auto ix=ix_0; ixdx_max); }); + dx.resize(std::distance(dx.begin(), it)); + + T dx_std = sqrt(variance(dx)); + T d_max = max_element(dx) + 2*dx_std; + + return ::fmax(10*grid_1d.dRx, d_max); + } + + T get_d_max(int ix_0, int ix_e, TVector_rh &dx) + { + TVector_rh dx_h(dx.begin()+ix_0, dx.begin()+ix_e); + return ::fmax(10*grid_1d.dRx, 3*sqrt(variance(dx_h))); + } + + T find(int icol, TVector_r &M_r, TVector_r &M_s, TVector_rh &y, T d_max) + { + const T x_c = grid_1d.lxh(); + y_c = y[grid_1d.nxh]; + + // find peaks + fd_peaks(y); + + // remove peaks + remove_peaks(x_c-d_max, x_c+d_max); + + // return if x_pk is empty + if(empty()) + { + return x_c; + } + + // return if there is only one element + if(size() == 1) + { + return x_pk.front(); + } + + const int ix_max = idx_y_max(); + const int ix_clt = idx_x_clt(); + + // return if closest position is equal to maximum intensity position + // and the maximum intensity is greater than the second maximum intensity + if(fabs(x_pk[ix_max]-x_pk[ix_clt])<1) + { + T y_thr = 0.61*y_pk[ix_max]; + for(auto ix=0; ix grid_1d; + Border_1d *bd_1d; + + FFT fft_1d; + Sft_1d sft_1d; + + T y_c; + + bool empty() const + { + return ix_pk.empty(); + } + + int size() const + { + return ix_pk.size(); + } + + int idx_y_max() const + { + int idx_max = (std::max_element(y_pk.begin(), y_pk.end())-y_pk.begin()); + + return idx_max; + } + + int idx_x_clt() const + { + T x_c = grid_1d.lxh(); + + int idx_clt = 0; + if(x_pk.size()>1) + { + idx_clt = std::min_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)1) + { + idx_clt = std::max_element(x_pk.begin(), x_pk.end(), [x_c](T a, T b){return fabs(a-x_c)y_thr) + { + if((y[ix-1] bd_l = *bd_1d; + bd_l.xb_0 = max(bd_l.xb_0, d_fht); + bd_l.xb_e = max(bd_l.xb_e, d_fht); + + // get indexes + const int ix_0 = grid_1d.ceil_dRx(bd_l.x_0()); + const int ix_e = grid_1d.floor_dRx(bd_l.x_e()); + + // get reference data + TVector_rh yr_b(M_r.begin()+(icol-1)*grid_1d.nx, M_r.begin()+icol*grid_1d.nx); + TVector_rh yr(M_r.begin()+icol*grid_1d.nx, M_r.begin()+(icol+1)*grid_1d.nx); + TVector_rh yr_n(M_r.begin()+(icol+1)*grid_1d.nx, M_r.begin()+(icol+2)*grid_1d.nx); + + // get shifted data + TVector_rh ys_0(M_s.begin()+icol*grid_1d.nx, M_s.begin()+(icol+1)*grid_1d.nx); + + TVector_rh chi2_pk(size()); + + for(auto ix_pk=0; ix_pk + class Fd_Sft_2d: public Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Fd_Sft_2d(): Pcf_2d(){} + + Fd_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Pcf_2d() + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + Pcf_2d::set_input_data(stream_i, fft_2d_i, grid_2d_i); + sft_2d.set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + r2d operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, r2d dr, + Border_2d bd, int nit_pcf) + { + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 0.9*sigma_r); + + TVector_r M = M_s; + TVector_r pcf(M.size()); + + if(nonZero(dr)) + { + sft_2d(dr, M); + } + + for (auto it=0; it::operator()(M_r, M, p, sigma_g, bd, true, pcf); + + // get maximun position + r2d r_c = host_device_detail::max_pos_2d(this->grid_2d, pcf); + + if(it==nit_pcf-1) + { + r_c = fit_max_pos_2d(this->grid_2d, pcf, r_c, sigma_r, radius); + } + + r2d dr_t = -(r_c - r2d(this->grid_2d.lxh(), this->grid_2d.lyh())); + + if(it sft_2d; + }; + + /*******************Corrrect shift*******************/ + template + class Crt_Sft_1d: public Fd_Sft_1d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Crt_Sft_1d(): Fd_Sft_1d(){} + + Crt_Sft_1d(FFT *fft_1d_i, Grid_1d &grid_1d_i): + Fd_Sft_1d(fft_1d_i, grid_1d_i){} + + T operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, + Border_1d bd, int nit_pcf) + { + T dx = 0; + dx = Fd_Sft_1d::operator()(M_r_i, M_s_io, p, sigma_g, dx, bd, nit_pcf); + this->sft_1d(dx, M_s_io); + + return dx; + } + }; + + template + class Crt_Sft_2d_BC: public Fd_Sft_2d_BC + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + using TVector_rh = Vector; + using TVector_ch = Vector; + + Crt_Sft_2d_BC(): Fd_Sft_2d_BC(){} + + Crt_Sft_2d_BC(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): + Fd_Sft_2d_BC(stream_i, fft_2d_i, grid_2d_i){} + + TVector_rh operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, + Border_2d bd, int nit_pcf) + { + TVector_rh dr(this->grid_2d.ny, T(0)); + dr = Fd_Sft_2d_BC::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d_bc(1, dr, M_s_io); + + return dr; + } + }; + + template + class Crt_Sft_2d: public Fd_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Crt_Sft_2d(): Fd_Sft_2d(){} + + Crt_Sft_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): + Fd_Sft_2d(stream_i, fft_2d_i, grid_2d_i){} + + r2d operator()(TVector_r &M_r_i, TVector_r &M_s_io, T p, T sigma_g, + Border_2d bd, int nit_pcf) + { + r2d dr(0, 0); + dr = Fd_Sft_2d::operator()(M_r_i, M_s_io, p, sigma_g, dr, bd, nit_pcf); + this->sft_2d(dr, M_s_io); + + return dr; + } + }; + + /****************calculate Chi^2*****************/ + template + class Chi2_Pcf_2d: public Crt_Sft_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + Chi2_Pcf_2d(): Crt_Sft_2d(){} + + Chi2_Pcf_2d(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): Crt_Sft_2d() + { + set_input_data(stream_i, fft_2d_i, grid_2d_i); + } + + inline + void set_input_data(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i) + { + Crt_Sft_2d::set_input_data(stream_i, fft_2d_i, grid_2d_i); + shx_scy.set_input_data(this->stream, this->grid_2d); + } + + T operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, + r2d af, Border_2d bd, int nit_pcf, r2d &ds) + { + TVector_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVector_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, true, pcf); + + // cost function + return mean(*(this->stream), pcf); + } + + T operator()(TVector_r &M_r_i, TVector_r &M_s_i, T p, T sigma_g, + r2d af, Border_2d bd, int nit_pcf, r2d &ds, Vector &coef) + { + TVector_r M(M_r_i.size()); + shx_scy(M_s_i, af, M); + + // correct shift and set borders + ds = Crt_Sft_2d::operator()(M_r_i, M, p, sigma_g, bd, nit_pcf); + + // pcf + TVector_r &pcf = M; + Pcf_2d::operator()(M_r_i, M, p, sigma_g, bd, true, pcf); + + // cost function + auto chi2 = mean(*(this->stream), pcf); + + // get maximun position + r2d r_c = host_device_detail::max_pos_2d(this->grid_2d, pcf); + + // fitting + T sigma_r = 1.0/(c_2Pi*sigma_g); + T radius = ::fmax(3*this->grid_2d.dR_min(), 1.5*sigma_r); + Vector pcf_h = pcf; + coef = fit_ellipt_gauss_2d(this->grid_2d, pcf_h, r_c, sigma_r, radius); + coef[0] = ds.x + this->grid_2d.lxh(); + coef[1] = ds.y + this->grid_2d.lyh(); + + return chi2; + } + + protected: + Shx_Scy shx_scy; + }; + + template + class NM_Shx_Scy: public Chi2_Pcf_2d + { + public: + using T_r = T; + using T_c = complex; + using TVector_r = Vector; + using TVector_c = Vector; + + NM_Shx_Scy():Chi2_Pcf_2d(), nit_pcf(2){} + + NM_Shx_Scy(Stream *stream_i, FFT *fft_2d_i, Grid_2d &grid_2d_i): + Chi2_Pcf_2d(stream_i, fft_2d_i, grid_2d_i), nit_pcf(2){} + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Vector, e_host> &spx, Border_2d bd, int nit_nm) + { + int ic = 1; + + T d_pix_min = this->grid_2d.dg_min(); + T d_min = 0.05*d_pix_min; + T alpha = 1.0; + T beta = 0.5; + T gamma = 2.0; + + for(auto it=0; it ds_r(0, 0); + auto chi2_r = chi2_pcf(M_r, M_s, p, sigma_g, x_r, bd, nit_pcf, ds_r); + + if(chi2_r ds_e(0, 0); + auto chi2_e = chi2_pcf(M_r, M_s, p, sigma_g, x_e, bd, nit_pcf, ds_e); + if(chi2_e(x_e, ds_e, chi2_e); + } + else + { + spx[2] = Afp_2(x_r, ds_r, chi2_r); + } + } + else if(chi2_r(x_r, ds_r, chi2_r); + } + else if(chi2_r ds_rc(0, 0); + auto chi2_rc = chi2_pcf(M_r, M_s, p, sigma_g, x_rc, bd, nit_pcf, ds_rc); + if(chi2_rc(x_rc, ds_rc, chi2_rc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + else + { + auto x_wc = x_m + beta*(x_w-x_m); + r2d ds_wc(0, 0); + auto chi2_wc = chi2_pcf(M_r, M_s, p, sigma_g, x_wc, bd, nit_pcf, ds_wc); + if(chi2_wc(x_wc, ds_wc, chi2_wc); + } + else + { + contract_simplex(M_r, M_s, p, sigma_g, spx, bd, nit_pcf); + } + } + } + + } + + void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d &af, Border_2d bd, r2d &ds, int nit_nm) + { + auto spx = set_simplex(M_r, M_s, p, sigma_g, af, ds, bd, nit_nm); + this->operator()(M_r, M_s, p, sigma_g, spx, bd, nit_nm); + + af = spx[0].f; + ds = spx[0].ds; + + // // shear and scaling + // shx_scy(M_s, af, M_s); + // // correct shift + // ds = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds, bd, nit_pcf); + } + + protected: + r2d x_af(const r2d &af, const r2d &r) + { + return r2d(r.x+af.x*r.y, af.y*r.y); + } + + r2d x_iaf(const r2d &af, const r2d &r) + { + return r2d(r.x-af.x*r.y/af.y, r.y/af.y); + } + + Vector, e_host> set_simplex(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d x_0, r2d ds_0, Border_2d &bd, int nit_nm) + { + // global shift + if(isZero(ds_0)) + { + ds_0 = Fd_Sft_2d::operator()(M_r, M_s, p, sigma_g, ds_0, bd, nit_pcf); + bd.set_bd(ds_0); + } + + TVector_r M_s_t = M_s; + this->sft_2d(x_iaf(x_0, ds_0), M_s_t); + + // determine coefficients + Vector coef(6); + chi2_pcf(M_r, M_s_t, p, sigma_g, x_0, bd, nit_pcf, ds_0, coef); + + // calculate dd0 + T ff = coef[4]/coef[3]; + ff = (ff<1)?1/ff:ff; + ff = ::fmax(1.05, ff); + + T dd0 = sqrt(1.354e-04*pow(ff-1, 2)+6.622e-4*(ff-1)); + dd0 = ::fmax(dd0, this->grid_2d.dg_min()); + + T sin_t = sin(coef[5]); + T cos_t = cos(coef[5]); + + T sigma_x = pow(cos_t/coef[3], 2)+pow(sin_t/coef[4], 2); + sigma_x = sqrt(1/sigma_x); + + T sigma_y = pow(sin_t/coef[3], 2)+pow(cos_t/coef[4], 2); + sigma_y = sqrt(1/sigma_y); + + T theta = atan2(sigma_y, sigma_x); + + r2d u(dd0*cos(theta), dd0*sin(theta)); + r2d v(-u.y, u.x); + + // set simplex + Vector, e_host> spx(3); + + spx[0].f = x_0; + spx[0].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[0].f, bd, nit_pcf, spx[0].ds); + + spx[1].f = x_0+u; + spx[1].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[1].f, bd, nit_pcf, spx[1].ds); + + spx[2].f = x_0+v; + spx[2].chi2 = chi2_pcf(M_r, M_s, p, sigma_g, spx[2].f, bd, nit_pcf, spx[2].ds); + + // sort simplex + sort(spx); + + return spx; + } + + T chi2_pcf(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d af, Border_2d &bd, int nit_pcf, r2d &ds) + { + return Chi2_Pcf_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, ds); + } + + T chi2_pcf(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + r2d af, Border_2d &bd, int nit_pcf, r2d &ds, Vector &coef) + { + return Chi2_Pcf_2d::operator()(M_r, M_s, p, sigma_g, af, bd, nit_pcf, ds, coef); + } + + void sort(Vector, e_host> &spx) + { + std::sort(spx.begin(), spx.end(), [](const Afp_2 &x, const Afp_2 &y){ return x.chi2, e_host> &spx) + { + auto r0 = spx[0].f; + + r2d dr = spx[1].f - r0; + T d_max = dr.module(); + for(auto i=2; i dr = spx[i].f - r0; + d_max = ::fmax(d_max, dr.module()); + } + return d_max; + } + + T min_length(Vector, e_host> &spx) + { + auto r0 = spx[0].f; + r2d dr = spx[1].f - r0; + T d_min = dr.module(); + for(auto i=2; i dr = spx[i].f - r0; + d_min = ::fmin(d_min, dr.module()); + } + return d_min; + } + + r2d best_centroid(Vector, e_host> &spx) + { + r2d r_c(0, 0); + for(auto i=0; i, e_host> &spx, Border_2d &bd, int nit_pcf) + { + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.module(); + auto mp13 = p13.module(); + auto mp_max = ::fmax(mp12, mp13); + + T theta = angle(p12, p13); + + T theta_min = 10; + T theta_0 = theta_min*c_Pi/180; + T theta_e = c_Pi-theta_min*c_Pi/180; + + bool b_m = (mp12theta_e)||b_m) + { + if(b_m && (mp12(-u.y, u.x); + r2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[1] = Afp_2(x_o, ds_o, chi2_o); + } + else + { + T m = max_length(spx); + auto u = p12/module(p12); + auto x_o = spx[0].f + mp_max*r2d(-u.y, u.x); + r2d ds_o(0, 0); + auto chi2_o = chi2_pcf(M_r, M_s, p, sigma_g, x_o, bd, nit_pcf, ds_o); + + spx[2] = Afp_2(x_o, ds_o, chi2_o); + } + + sort(spx); + } + } + + void contract_simplex(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, + Vector, e_host> &spx, Border_2d &bd, int nit_pcf) + { + T ff = 0.5; + + auto p12 = spx[1].f-spx[0].f; + auto p13 = spx[2].f-spx[0].f; + auto mp12 = p12.module(); + auto mp13 = p13.module(); + + if(mp12(-u.y, u.x); + r2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[2] = Afp_2(x_c, ds_c, chi2_c); + } + else + { + auto u = p13/mp13; + auto x_c = spx[0].f + ff*mp12*r2d(-u.y, u.x); + r2d ds_c(0, 0); + auto chi2_c = chi2_pcf(M_r, M_s, p, sigma_g, x_c, bd, nit_pcf, ds_c); + + spx[1] = Afp_2(x_c, ds_c, chi2_c); + } + + sort(spx); + } + + int nit_pcf; + }; + +} // namespace mt + +#endif \ No newline at end of file diff --git a/src/igrid_1d.h b/src/igrid_1d.h new file mode 100755 index 00000000..642b6cbf --- /dev/null +++ b/src/igrid_1d.h @@ -0,0 +1,186 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "fcns_cgpu_gen.h" + +/* template definition */ +namespace mt +{ + template class iGrid_sxd; + + template + using iGrid_xd = iGrid_sxd; +} + +/* derived class */ +namespace mt +{ + template + using iGrid_1d_st = iGrid_sxd; + + using iGrid_1d = iGrid_sxd; + + using iGrid_1d_64 = iGrid_sxd; +} + +/* template specialization 1d */ +namespace mt +{ + template + class iGrid_sxd + { + public: + ST nx; // number of pixels in x direction + ST nx_h; // half number of pixels in x direction + + /************************************* constructors ************************************/ + CGPU_EXEC + iGrid_sxd(); + + iGrid_sxd(const ST& nx); + + /* copy constructor */ + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid); + + /* converting constructor */ + template + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid); + + /* converting assignment operator */ + template + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid); + + template + CGPU_EXEC + void assign(const iGrid_sxd& grid); + + /***************************************************************************************/ + void set_size(const ST& nx); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + virtual ST size() const; + + template + CGPU_EXEC + SU nx_cast() const; + + template + CGPU_EXEC + SU size_cast() const; + + template + CGPU_EXEC + SU isize_cast() const; + + dt_shape_st shape() const; + + /***************************************************************************************/ + /********************** apply boundary conditions to indices ***************************/ + /*********** https:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn *************/ + /***************************************************************************************/ + CGPU_EXEC + ST ind_x_pbc(const ST& ix) const; + + CGPU_EXEC + ST ind_x_bd(const ST& ix) const; + + CGPU_EXEC + void ind_pbc(ST& ix) const; + + /***************************************************************************************/ + /***************************** subindices -> linear indices ****************************/ + /***************************************************************************************/ + CGPU_EXEC + ST operator()(const ST& ix) const; + + CGPU_EXEC + ST sub_2_ind(const ST& ix) const; + + CGPU_EXEC + ST sub_2_ind_bd(const ST& ix) const; + + CGPU_EXEC + ST sub_2_ind_pbc(const ST& ix) const; + + CGPU_EXEC + ST sub_2_ind_irv_sft_pbc(ST ix) const; + + /***************************************************************************************/ + /**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub(const ST& ind, ST& ix) const; + + /***************************************************************************************/ + /****************************** Fourier space indices **********************************/ + /***************************************************************************************/ + CGPU_EXEC + ST igx(const ST& ix) const; + + /**************************************** shift ****************************************/ + CGPU_EXEC + ST igx_sft(const ST& ix) const; + + /***************************************************************************************/ + /******************************** real space indices ***********************************/ + /***************************************************************************************/ + CGPU_EXEC + ST irx(const ST& ix) const; + + /*************************************** shift *****************************************/ + CGPU_EXEC + ST irx_sft(const ST& ix) const; + + #ifdef __CUDACC__ + dim3 d_blk_size(); + + dim3 d_grid_size(const dim3 d_grid_max = dim3(128, 1, 1)); + + D_Grid_Blk d_grid_blk_size(const dim3 d_grid_max = dim3(128, 1, 1)); + + /***************************************************************************************/ + dim3 d_blk(); + + /***************************************************************************************/ + dim3 d_grid(const dim3 d_grid_max = dim3(128, 1, 1)); + + D_Grid_Blk d_grid_blk(const dim3 d_grid_max = dim3(128, 1, 1)); + + /***************************************************************************************/ + dim3 d_grid_h(const dim3 d_grid_max = dim3(128, 1, 1)); + + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(128, 1, 1)); + #endif + }; +} + +#include "detail/igrid_1d.inl" \ No newline at end of file diff --git a/src/igrid_2d.h b/src/igrid_2d.h new file mode 100755 index 00000000..f391ed90 --- /dev/null +++ b/src/igrid_2d.h @@ -0,0 +1,193 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "igrid_1d.h" + +/* derived class */ +namespace mt +{ + template + using iGrid_2d_st = iGrid_sxd; + + using iGrid_2d = iGrid_sxd; + + using iGrid_2d_64 = iGrid_sxd; +} + +/* template specialization 2d */ +namespace mt +{ + template + class iGrid_sxd: public iGrid_sxd + { + public: + ST ny; // number of pixels in y direction + ST ny_h; // half number of pixels in y direction + + /************************************* constructors ************************************/ + CGPU_EXEC + iGrid_sxd(); + + iGrid_sxd(const ST& nx, const ST& ny); + + /* copy constructor */ + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid); + + /* converting constructor */ + template + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid); + + /* converting assignment operator */ + template + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid); + + template + CGPU_EXEC + void assign(const iGrid_sxd& grid); + + /***************************************************************************************/ + void set_size(const ST& nx, const ST& ny); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + virtual ST size() const; + + template + CGPU_EXEC + SU ny_cast() const; + + dt_shape_st shape() const; + + /***************************************************************************************/ + /*********************** apply boundary conditions to indices **************************/ + /* https:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn */ + /***************************************************************************************/ + CGPU_EXEC + ST ind_y_pbc(const ST& iy) const; + + CGPU_EXEC + ST ind_y_bd(const ST& iy) const; + + CGPU_EXEC + void ind_pbc(ST& ix, ST& iy) const; + + /***************************************************************************************/ + /**************************** subindices -> linear indices *****************************/ + /***************************************************************************************/ + CGPU_EXEC + ST operator()(const ST& ix, const ST& iy) const; + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy) const; + + CGPU_EXEC + ST sub_2_ind_bd(const ST& ix, const ST& iy) const; + + CGPU_EXEC + ST sub_2_ind_pbc(const ST& ix, const ST& iy) const; + + CGPU_EXEC + ST sub_2_ind_irv_sft_pbc(ST ix, ST iy) const; + + /***************************************************************************************/ + /**************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub(const ST& ind, ST& ix, ST& iy) const; + + /***************************************************************************************/ + /******************* subindices to linear indices using 2nd dimension ******************/ + /***************************************************************************************/ + CGPU_EXEC + ST sub_2_ind_by_d2(const ST& ix, const ST& iy) const; + + CGPU_EXEC + ST sub_2_ind_by_d2_pbc(const ST& ix, const ST& iy) const; + + /***************************************************************************************/ + /****************** linear indices-> subindices using 2nd dimension ********************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub_by_d2(const ST& ind, ST& ix, ST& iy) const; + + /***************************************************************************************/ + /******************************* Fourier space indices *********************************/ + /***************************************************************************************/ + CGPU_EXEC + ST igy(const ST& iy) const; + + CGPU_EXEC + void igv(ST& ix, ST& iy) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + ST igy_sft(const ST& iy) const; + + CGPU_EXEC + void igv_sft(ST& ix, ST& iy) const; + + /***************************************************************************************/ + /******************************* real space indices ************************************/ + /***************************************************************************************/ + CGPU_EXEC + ST iry(const ST& iy) const; + + CGPU_EXEC + void irv(ST& ix, ST& iy) const; + + /***************************************** shift ***************************************/ + CGPU_EXEC + ST iry_sft(const ST& iy) const; + + CGPU_EXEC + void irv_sft(ST& ix, ST& iy) const; + + #ifdef __CUDACC__ + dim3 d_blk(); + + /***************************************************************************************/ + dim3 d_grid(const dim3 d_grid_max = dim3(64, 64, 0)); + + D_Grid_Blk d_grid_blk(const dim3 d_grid_max = dim3(64, 64, 1)); + + /***************************************************************************************/ + dim3 d_grid_h(const dim3 d_grid_max = dim3(64, 64, 1)); + + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(64, 64, 1)); + + /***************************************************************************************/ + dim3 d_grid_d0_h(const dim3 d_grid_max = dim3(64, 64, 1)); + + D_Grid_Blk d_grid_blk_d0_h(const dim3 d_grid_max = dim3(64, 64, 1)); + #endif + }; +} + +#include "detail/igrid_2d.inl" \ No newline at end of file diff --git a/src/igrid_3d.h b/src/igrid_3d.h new file mode 100755 index 00000000..2ee9305d --- /dev/null +++ b/src/igrid_3d.h @@ -0,0 +1,194 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "igrid_2d.h" + +/* derived class */ +namespace mt +{ + template + using iGrid_3d_st = iGrid_sxd; + + using iGrid_3d = iGrid_sxd; + + using iGrid_3d_64 = iGrid_sxd; +} + +/* template specialization 3d */ +namespace mt +{ + template + class iGrid_sxd: public iGrid_sxd + { + public: + ST nz; // number of pixels in z direction + ST nz_h; // half number of pixels in z direction + + /************************************* constructors ************************************/ + CGPU_EXEC + iGrid_sxd(); + + iGrid_sxd(const ST& nx, const ST& ny, const ST& nz); + + + /* copy constructor */ + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid); + + /* converting constructor */ + template + CGPU_EXEC + iGrid_sxd(const iGrid_sxd& grid); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid); + + /* converting assignment operator */ + template + CGPU_EXEC + iGrid_sxd& operator=(const iGrid_sxd& grid); + + template + CGPU_EXEC + void assign(const iGrid_sxd& grid); + + /***************************************************************************************/ + void set_size(const ST& nx, const ST& ny, const ST& nz); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + virtual ST size() const; + + template + CGPU_EXEC + SU nz_cast() const; + + dt_shape_st shape() const; + + /***************************************************************************************/ + /************************* apply boundary conditions to indices ************************/ + /* https:// en.wikipedia.org/wiki/Periodic_boundary_conditionsnn */ + /***************************************************************************************/ + CGPU_EXEC + ST ind_z_pbc(const ST& iz) const; + + CGPU_EXEC + ST ind_z_bd(const ST& iz) const; + + CGPU_EXEC + void ind_pbc(ST& ix, ST& iy, ST& iz) const; + + /***************************************************************************************/ + /**************************** subindices -> linear indices *****************************/ + /***************************************************************************************/ + CGPU_EXEC + ST operator()(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + ST sub_2_ind_bd(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + ST sub_2_ind_pbc(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + ST sub_2_ind_irv_sft_pbc(ST ix, ST iy, ST iz) const; + + /***************************************************************************************/ + //*************************** linear indices-> subindices ******************************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub(const ST& ind, ST& ix, ST& iy, ST& iz) const; + + /***************************************************************************************/ + /******************* subindices to linear indices using 2nd dimension ******************/ + /***************************************************************************************/ + CGPU_EXEC + ST sub_2_ind_by_d2(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + ST sub_2_ind_by_d2_pbc(const ST& ix, const ST& iy, const ST& iz) const; + + /***************************************************************************************/ + /****************** linear indices-> subindices using 2nd dimension ********************/ + /***************************************************************************************/ + CGPU_EXEC + void ind_2_sub_by_d2(const ST& ind, ST& ix, ST& iy, ST& iz) const; + + /***************************************************************************************/ + /****************************** Fourier space indices **********************************/ + /***************************************************************************************/ + CGPU_EXEC + ST igz(const ST& iz) const; + + CGPU_EXEC + void igv(ST& ix, ST& iy, ST& iz) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + ST igz_sft(const ST& iz) const; + + CGPU_EXEC + void igv_sft(ST& ix, ST& iy, ST& iz) const; + + /***************************************************************************************/ + /******************************* real space indices ************************************/ + /***************************************************************************************/ + CGPU_EXEC + ST irz(const ST& iz) const; + + CGPU_EXEC + void irv(ST& ix, ST& iy, ST& iz) const; + + /************************************* shift *******************************************/ + CGPU_EXEC + ST irz_sft(const ST& iz) const; + + CGPU_EXEC + void irv_sft(ST& ix, ST& iy, ST& iz) const; + + #ifdef __CUDACC__ + dim3 d_blk(); + + /***************************************************************************************/ + dim3 d_grid(const dim3 d_grid_max = dim3(64, 64, 64)); + + D_Grid_Blk d_grid_blk(const dim3 d_grid_max = dim3(64, 64, 64)); + + /***************************************************************************************/ + dim3 d_grid_h(const dim3 d_grid_max = dim3(64, 64, 64)); + + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(64, 64, 64)); + + /***************************************************************************************/ + dim3 d_grid_d0_h(const dim3 d_grid_max = dim3(64, 64, 64)); + + D_Grid_Blk d_grid_blk_d0_h(const dim3 d_grid_max = dim3(64, 64, 64)); + #endif + }; +} + +#include "detail/igrid_3d.inl" \ No newline at end of file diff --git a/src/image_functions.cuh b/src/image_functions.cuh deleted file mode 100644 index 86ef1cd0..00000000 --- a/src/image_functions.cuh +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef IMAGE_FUNCTIONS_H -#define IMAGE_FUNCTIONS_H - -#include -#include -#include -#include "math.cuh" -#include "types.cuh" -#include "matlab_types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "cpu_fcns.hpp" -#include "cgpu_classes.cuh" - -namespace mt -{ - // hist - template - void hist(TVector &v, int nbins, TVector &y, TVector *x = nullptr) - { - using T = Value_type; - auto minmax_temp = std::minmax_element(v.begin(), v.end()); - T v_min = *(minmax_temp.first); - T v_max = *(minmax_temp.second); - T dv = (v_max-v_min)/nbins; - - thrust::fill(y.begin(), y.end(), 0); - for(auto iv = 0; iv(floor((v[iv]-v_min)/dv)), nbins-1); - y[iy]++; - } - - if(x!= nullptr) - { - for(auto ix = 0; ix - Vector hist(TVector &v, int nbins) - { - TVector y(nbins); - hist(v, nbins, y); - return y; - } - - // Thresholding - template - Value_type otsu_thr(TVector &v, int nbins) - { - using T = Value_type; - - TVector v_rang(nbins); - TVector v_hist(nbins); - - hist(v, nbins, v_hist, &v_rang); - - T sum_I = 0; - for (auto ibins = 0; ibins(w_B)*static_cast(w_F)*(m_B-m_F)*(m_B-m_F); - - // Check if new maximum found - if (var_Between > var_Max) - { - var_Max = var_Between; - thr = v_rang[ibins]; - } - } - - return thr; - } - - // binarize - template - TVector binarize(Stream &stream, TVector &v_i, Value_type thr) - { - using value_type = Value_type; - TVector v_o(v_i.size()); - - auto thr_binarization = [&](const Range_2d &range) - { - thrust::transform(v_i.begin()+range.ixy_0, v_i.begin()+range.ixy_e, - v_o.begin()+range.ixy_0, functor::binarize(thr)); - }; - - stream.set_n_act_stream(v_i.size()); - stream.set_grid(1, v_i.size()); - stream.exec(thr_binarization); - - return v_o; - } - - // thresholding - template - TVector thresholding(Stream &stream, TVector &v_i, Value_type thr) - { - using value_type = Value_type; - TVector v_o(v_i.size()); - - auto thr_thring = [&](const Range_2d &range) - { - thrust::transform(v_i.begin()+range.ixy_0, v_i.begin()+range.ixy_e, - v_o.begin()+range.ixy_0, functor::thresholding(thr)); - }; - - stream.set_n_act_stream(v_i.size()); - stream.set_grid(1, v_i.size()); - stream.exec(thr_thring); - - return v_o; - } - - /******************************************************************************/ - // gray dilation - template - TVector morp_g_dilate(Stream &stream, int ny_i, int nx_i, TVector &Im_i, int nkr) - { - using T = Value_type; - - TVector Im_o(Im_i.size()); - - auto thr_dilate = [nkr](const Range_2d &range, TVector &Im_i, TVector &Im_o) - { - std::deque wd; - - const int ny = range.iy_e-range.iy_0; - const int wkr = 2*nkr+1; - - auto wedge_push = [ny](const int &ix, const int &iy, TVector &Im_i, std::deque &wd) - { - while((!wd.empty()) && (Im_i[ix*ny+wd.back()]<= Im_i[ix*ny+iy])) - { - wd.pop_back(); - } - wd.push_back(iy); - }; - - for(auto ix = range.ix_0; ix < range.ix_e; ix++) - { - int iy = 0; - int iy_tk = 0; - int iy_o = 0; - - for (; iy < nkr; iy++) - { - wedge_push(ix, iy, Im_i, wd); - } - - for (; iy < ny; iy++, iy_o++) - { - wedge_push(ix, iy, Im_i, wd); - - Im_o[ix*ny+iy_o] = Im_i[ix*ny+wd.front()]; - if (iy + 1 >= wkr) - { - if (wd.front() == iy_tk) - { - wd.pop_front(); - } - iy_tk++; - } - } - - for (; iy_o < ny; iy_o++) - { - Im_o[ix*ny+iy_o] = Im_i[ix*ny+wd.front()]; - if (wd.front() == iy_tk) - { - wd.pop_front(); - } - iy_tk++; - } - wd.clear(); - } - }; - - stream.set_n_act_stream(nx_i); - stream.set_grid(nx_i, ny_i); - stream.exec(thr_dilate, Im_i, Im_o); - - auto Im_t = Im_o; - trs(stream, ny_i, nx_i, Im_t); - - stream.set_n_act_stream(ny_i); - stream.set_grid(ny_i, nx_i); - stream.exec(thr_dilate, Im_t, Im_o); - - trs(stream, nx_i, ny_i, Im_o); - - return Im_o; - } - - // gray erosion - template - TVector morp_g_erode(Stream &stream, int ny_i, int nx_i, TVector &Im_i, int nkr) - { - using T = Value_type; - - TVector Im_o(Im_i.size()); - - auto thr_erode = [nkr](const Range_2d &range, TVector &Im_i, TVector &Im_o) - { - std::deque wd; - - const int ny = range.iy_e-range.iy_0; - const int wkr = 2*nkr+1; - - auto wedge_push = [ny](const int &ix, const int &iy, TVector &Im_i, std::deque &wd) - { - while((!wd.empty()) && (Im_i[ix*ny+wd.back()]>= Im_i[ix*ny+iy])) - { - wd.pop_back(); - } - wd.push_back(iy); - }; - - for(auto ix = range.ix_0; ix < range.ix_e; ix++) - { - int iy = 0; - int iy_tk = 0; - int iy_o = 0; - - for (; iy < nkr; iy++) - { - wedge_push(ix, iy, Im_i, wd); - } - - for (; iy < ny; iy++, iy_o++) - { - wedge_push(ix, iy, Im_i, wd); - - Im_o[ix*ny+iy_o] = Im_i[ix*ny+wd.front()]; - if (iy + 1 >= wkr) - { - if (wd.front() == iy_tk) - { - wd.pop_front(); - } - iy_tk++; - } - } - - for (; iy_o < ny; iy_o++) - { - Im_o[ix*ny+iy_o] = Im_i[ix*ny+wd.front()]; - if (wd.front() == iy_tk) - { - wd.pop_front(); - } - iy_tk++; - } - wd.clear(); - } - }; - - stream.set_n_act_stream(nx_i); - stream.set_grid(nx_i, ny_i); - stream.exec(thr_erode, Im_i, Im_o); - - auto Im_t = Im_o; - trs(stream, ny_i, nx_i, Im_t); - - stream.set_n_act_stream(ny_i); - stream.set_grid(ny_i, nx_i); - stream.exec(thr_erode, Im_t, Im_o); - - trs(stream, nx_i, ny_i, Im_o); - - return Im_o; - } - - // gray opening - template - TVector morp_g_open(Stream &stream, int ny_i, int nx_i, TVector &Im_i, int nkr) - { - auto Im = morp_g_erode(stream, ny_i, nx_i, Im_i, nkr); - return morp_g_dilate(stream, ny_i, nx_i, Im, nkr); - } - - // gray closing - template - TVector morp_g_close(Stream &stream, int ny_i, int nx_i, TVector &Im_i, int nkr) - { - auto Im = morp_g_dilate(stream, ny_i, nx_i, Im_i, nkr); - return morp_g_erode(stream, ny_i, nx_i, Im, nkr); - } - - // gray tophat - template - TVector morp_g_tophat(Stream &stream, int ny_i, int nx_i, TVector &Im_i, int nkr) - { - auto Im = morp_g_open(stream, ny_i, nx_i, Im_i, nkr); - add_scale(stream, 1, Im_i, -1, Im, Im); - return Im; - } - - /******************************************************************************/ - // forward anscombe transform - template - TVector anscombe_forward(Stream &stream, TVector &v_i) - { - using value_type = Value_type; - TVector v_o(v_i.size()); - - auto thr_anscombe_forward = [&](const Range_2d &range) - { - thrust::transform(v_i.begin()+range.ixy_0, v_i.begin()+range.ixy_e, - v_o.begin()+range.ixy_0, functor::anscombe_forward()); - }; - - stream.set_n_act_stream(v_i.size()); - stream.set_grid(1, v_i.size()); - stream.exec(thr_anscombe_forward); - - return v_o; - } - - // forward anscombe transform - template - TVector anscombe_inverse(Stream &stream, TVector &v_i) - { - using value_type = Value_type; - TVector v_o(v_i.size()); - - auto thr_anscombe_inverse = [&](const Range_2d &range) - { - thrust::transform(v_i.begin()+range.ixy_0, v_i.begin()+range.ixy_e, - v_o.begin()+range.ixy_0, functor::anscombe_inverse()); - }; - - stream.set_n_act_stream(v_i.size()); - stream.set_grid(1, v_i.size()); - stream.exec(thr_anscombe_inverse); - - return v_o; - } - - /******************************************************************************/ - // wiener filter 1d - template - TVector ftr_wiener_1d(Stream &stream, TVector &Im_i, int nkr) - { - if(nkr<=0) - { - return Im_i; - } - - using T = Value_type; - TVector Im_o(Im_i.size()); - - int nk0 = -nkr; - int nke = nkr+1; - int nx_i = Im_i.size(); - - TVector Im_mean(nx_i); - TVector Im_var(nx_i); - - T v2 = 0; - auto thr_mean_var = [&](const Range_2d &range) - { - T v2_partial = 0; - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - int ix_0 = max(ixy+nk0, 0); - int ixe = min(ixy+nke, nx_i); - - T x_mean = 0; - T x_var = 0; - for (auto ix = ix_0; ix < ixe; ix++) - { - T x = Im_i[ix]; - x_mean += x; - x_var += x*x; - } - x_mean = x_mean/(ixe-ix_0); - x_var = x_var/(ixe-ix_0) - x_mean*x_mean; - - Im_mean[ixy] = x_mean; - Im_var[ixy] = x_var; - - v2_partial += x_var; - } - - stream.stream_mutex.lock(); - v2 += v2_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(nx_i); - stream.set_grid(nx_i, 1); - stream.exec(thr_mean_var); - - v2 /= nx_i; - - auto thr_ftr_wiener = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - Im_o[ixy] = Im_mean[ixy] + ::fmax(T(0), Im_var[ixy]-v2)*(Im_i[ixy]-Im_mean[ixy])/::fmax(Im_var[ixy], v2); - } - }; - - stream.set_n_act_stream(nx_i); - stream.set_grid(nx_i, 1); - stream.exec(thr_ftr_wiener); - - return Im_o; - } - - // wiener filter by rows - template - TVector ftr_wiener_2d_br(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr) - { - if(nkr<=0) - { - return Im_i; - } - - using T = Value_type; - TVector Im_o(Im_i.size()); - - int nk0 = -nkr; - int nke = nkr+1; - - TVector Im_mean(grid_2d.nxy()); - TVector Im_var(grid_2d.nxy()); - - auto krn_mean_var = [&](const int &ix_i, const int &iy_i, TVector &Im_i, TVector &Im_mean, TVector &Im_var) - { - int ix_0 = max(ix_i+nk0, 0); - int ixe = min(ix_i+nke, grid_2d.nx); - - T x_mean = 0; - T x_var = 0; - for (auto ix = ix_0; ix < ixe; ix++) - { - T x = Im_i[grid_2d.ind_col(ix, iy_i)]; - x_mean += x; - x_var += x*x; - } - x_mean = x_mean/(ixe-ix_0); - x_var = x_var/(ixe-ix_0) - x_mean*x_mean; - - int ixy = grid_2d.ind_col(ix_i, iy_i); - Im_mean[ixy] = x_mean; - Im_var[ixy] = x_var; - }; - - auto thr_mean_var = [&](const Range_2d &range) - { - host_detail::matrix_iter(range, krn_mean_var, Im_i, Im_mean, Im_var); - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_mean_var); - - auto thr_ftr_wiener = [&](const Range_2d &range) - { - for(auto iy = range.ixy_0; iy < range.ixy_e; iy++) - { - T v2 = 0; - for(auto ix = 0; ix < grid_2d.nx; ix++) - { - v2 += Im_var[grid_2d.ind_col(ix, iy)]; - } - v2 /= grid_2d.nx; - - for(auto ix = 0; ix < grid_2d.nx; ix++) - { - auto ixy = grid_2d.ind_col(ix, iy); - Im_o[ixy] = Im_mean[ixy] + ::fmax(T(0), Im_var[ixy]-v2)*(Im_i[ixy]-Im_mean[ixy])/::fmax(Im_var[ixy], v2); - } - } - }; - - stream.set_n_act_stream(grid_2d.ny); - stream.set_grid(1, grid_2d.ny); - stream.exec(thr_ftr_wiener); - - return Im_o; - } - - // wiener filter 2d - template - TVector ftr_wiener_2d(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr) - { - if(nkr<=0) - { - return Im_i; - } - - using T = Value_type; - TVector Im_mean(Im_i.size()); - TVector Im_var(Im_i.size()); - TVector Im_t(Im_i.size()); - - // Kahan summation algorithm - // https:// en.wikipedia.org/wiki/Kahan_summation_algorithm - - auto thr_sum = [=](const Range_2d &range, TVector &Im_i, TVector &Im_sum) - { - const int ny = range.iy_e-range.iy_0; - const int wkr = 2*nkr+1; - - for(auto ix = range.ix_0; ix < range.ix_e; ix++) - { - int iy = 0; - int iy_tk = 0; - int iy_o = 0; - - T sum_v = 0; - T sum_ee = 0; - for (; iy < nkr; iy++) - { - T v = Im_i[ix*ny+iy]; - host_device_detail::kh_sum(sum_v, v, sum_ee); - } - - for (; iy < ny; iy++, iy_o++) - { - T v = Im_i[ix*ny+iy]; - host_device_detail::kh_sum(sum_v, v, sum_ee); - - Im_sum[ix*ny+iy_o] = sum_v; - if (iy + 1 >= wkr) - { - T v = Im_i[ix*ny+iy_tk]; - host_device_detail::kh_sum(sum_v, -v, sum_ee); - iy_tk++; - } - } - - for (; iy_o < ny; iy_o++) - { - Im_sum[ix*ny+iy_o] = sum_v; - - T v = Im_i[ix*ny+iy_tk]; - host_device_detail::kh_sum(sum_v, -v, sum_ee); - iy_tk++; - } - } - }; - - auto thr_sum2 = [=](const Range_2d &range, TVector &Im_i, TVector &Im_sum2) - { - const int ny = range.iy_e-range.iy_0; - const int wkr = 2*nkr+1; - - for(auto ix = range.ix_0; ix < range.ix_e; ix++) - { - int iy = 0; - int iy_tk = 0; - int iy_o = 0; - - T sum_v2 = 0; - T sum_ee = 0; - for (; iy < nkr; iy++) - { - T v = Im_i[ix*ny+iy]; - host_device_detail::kh_sum(sum_v2, v*v, sum_ee); - } - - for (; iy < ny; iy++, iy_o++) - { - T v = Im_i[ix*ny+iy]; - host_device_detail::kh_sum(sum_v2, v*v, sum_ee); - - Im_sum2[ix*ny+iy_o] = sum_v2; - if (iy + 1 >= wkr) - { - T v = Im_i[ix*ny+iy_tk]; - host_device_detail::kh_sum(sum_v2, -v*v, sum_ee); - iy_tk++; - } - } - - for (; iy_o < ny; iy_o++) - { - Im_sum2[ix*ny+iy_o] = sum_v2; - - T v = Im_i[ix*ny+iy_tk]; - host_device_detail::kh_sum(sum_v2, -v*v, sum_ee); - iy_tk++; - } - } - }; - - // sum - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_sum, Im_i, Im_mean); - - Im_t = Im_mean; - trs(stream, grid_2d.ny, grid_2d.nx, Im_t); - - stream.set_n_act_stream(grid_2d.ny); - stream.set_grid(grid_2d.ny, grid_2d.nx); - stream.exec(thr_sum, Im_t, Im_mean); - - trs(stream, grid_2d.nx, grid_2d.ny, Im_mean); - - // sum^2 - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_sum2, Im_i, Im_var); - - Im_t = Im_var; - trs(stream, grid_2d.ny, grid_2d.nx, Im_t); - - stream.set_n_act_stream(grid_2d.ny); - stream.set_grid(grid_2d.ny, grid_2d.nx); - stream.exec(thr_sum, Im_t, Im_var); - - trs(stream, grid_2d.nx, grid_2d.ny, Im_var); - - for(auto ix=0; ix - void ftr_mwiener(Stream &stream, int ny_i, int nx_i, TVector &Im_i, int nkr, TVector &Im_o) - { - using T = Value_type; - int nk0 = -nkr; - int nke = nkr+1; - Vector Im_median(nx_i*ny_i); - Vector Im_var(nx_i*ny_i); - - auto krn_median_var = [&](const int &ix_i, const int &iy_i, TVector &Im_i, Vector &Im_median, Vector &Im_var) - { - int ix_0 = max(ix_i+nk0, 0); - int ixe = min(ix_i+nke, nx_i); - - int iy_0 = max(iy_i+nk0, 0); - int iye = min(iy_i+nke, ny_i); - - T nxy = (ixe-ix_0)*(iye-iy_0); - Vector v(nxy); - int iv = 0; - T x_mean = 0; - T x_var = 0; - for (auto ix = ix_0; ix < ixe; ix++) - { - for (auto iy = iy_0; iy < iye; iy++) - { - T x = Im_i[ix*ny_i+iy]; - v[iv++] = x; - x_mean += x; - x_var += x*x; - } - } - auto median = v.begin() + nxy/2; - std::nth_element(v.begin(), median, v.end()); - - x_mean = x_mean/nxy; - x_var = x_var/nxy - x_mean*x_mean; - - int ixy = ix_i*ny_i+iy_i; - Im_median[ixy] = *median; - Im_var[ixy] = x_var; - }; - - auto thr_median_var = [&](const Range_2d &range) - { - host_detail::matrix_iter(range, krn_median_var, Im_i, Im_median, Im_var); - }; - - stream.set_n_act_stream(nx_i); - stream.set_grid(nx_i, ny_i); - stream.exec(thr_median_var); - - auto v2 = mt::mean(stream, Im_var); - - auto thr_ftr_mwiener = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - Im_o[ixy] = Im_median[ixy] + ::fmax(T(0), Im_var[ixy]-v2)*(Im_i[ixy]-Im_median[ixy])/::fmax(Im_var[ixy], v2); - } - }; - - stream.set_n_act_stream(nx_i); - stream.set_grid(nx_i, ny_i); - stream.exec(thr_ftr_mwiener); - } - - /******************************************************************************/ - // median filter 1d - template - TVector ftr_median_1d(Stream &stream, TVector &Im_i, int nkr) - { - if(nkr<=0) - { - return Im_i; - } - - using T = Value_type; - TVector Im_o(Im_i.size()); - - int nk0 = -nkr; - int nke = nkr+1; - int nx_i = Im_i.size(); - - auto thr_ftr_median = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - int ix_0 = max(ixy+nk0, 0); - int ixe = min(ixy+nke, nx_i); - - TVector v; - v.reserve(ixe-ix_0); - - for (auto ix = ix_0; ix < ixe; ix++) - { - v.push_back(Im_i[ix]); - } - auto median = v.begin() + v.size()/2; - std::nth_element(v.begin(), median, v.end()); - Im_o[ixy] = *median; - } - }; - - stream.set_n_act_stream(nx_i); - stream.set_grid(nx_i, 1); - stream.exec(thr_ftr_median); - - return Im_o; - } - - // median filter by rows - template - TVector ftr_median_2d_br(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr) - { - if(nkr<=0) - { - return Im_i; - } - - using T = Value_type; - TVector Im_o(grid_2d.nxy()); - - int nk0 = -nkr; - int nke = nkr+1; - - auto krn_ftr_median = [&](const int &ix_i, const int &iy_i, TVector &Im_i, TVector &Im_o) - { - int ix_0 = max(ix_i+nk0, 0); - int ixe = min(ix_i+nke, grid_2d.nx); - - TVector v; - v.reserve(ixe-ix_0); - - for (auto ix = ix_0; ix < ixe; ix++) - { - v.push_back(Im_i[grid_2d.ind_col(ix, iy_i)]); - } - auto median = v.begin() + v.size()/2; - std::nth_element(v.begin(), median, v.end()); - Im_o[grid_2d.ind_col(ix_i, iy_i)] = *median; - }; - - auto thr_ftr_median = [&](const Range_2d &range) - { - host_detail::matrix_iter(range, krn_ftr_median, Im_i, Im_o); - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_ftr_median); - - return Im_o; - } - - // median filter 2d - template - TVector ftr_median_2d(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr) - { - if(nkr<=0) - { - return Im_i; - } - - using T = Value_type; - TVector Im_o(grid_2d.nxy()); - - int nk0 = -nkr; - int nke = nkr+1; - auto R2_max = pow(nkr*grid_2d.dRx, 2) + Epsilon::abs; - - auto krn_ftr_median = [&](const int &ix_i, const int &iy_i, TVector &Im_i, TVector &Im_o) - { - auto x_i = grid_2d.Rx(ix_i); - auto y_i = grid_2d.Ry(iy_i); - - int ix_0 = max(ix_i+nk0, 0); - int ixe = min(ix_i+nke, grid_2d.nx); - - int iy_0 = max(iy_i+nk0, 0); - int iye = min(iy_i+nke, grid_2d.ny); - - TVector v; - v.reserve((ixe-ix_0)*(iye-iy_0)); - - for (auto ix = ix_0; ix < ixe; ix++) - { - for (auto iy = iy_0; iy < iye; iy++) - { - auto R2 = grid_2d.R2(ix, iy, x_i, y_i); - if(R2 < R2_max) - { - v.push_back(Im_i[grid_2d.ind_col(ix, iy)]); - } - } - } - auto median = v.begin() + v.size()/2; - std::nth_element(v.begin(), median, v.end()); - Im_o[grid_2d.ind_col(ix_i, iy_i)] = *median; - }; - - auto thr_ftr_median = [&](const Range_2d &range) - { - host_detail::matrix_iter(range, krn_ftr_median, Im_i, Im_o); - }; - - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_ftr_median); - - return Im_o; - } - - /******************************************************************************/ - // den poiss - template - TVector ftr_poiss_dnois_1d(Stream &stream, TVector &Im_i, int nkr_w, int nkr_m) - { - if((nkr_w == 0) && (nkr_m == 0)) - { - return Im_i; - } - - auto Im = anscombe_forward(stream, Im_i); - if(nkr_w>0) - { - Im = ftr_wiener_1d(stream, Im, nkr_w); - } - if(nkr_m>0) - { - Im = ftr_median_1d(stream, Im, nkr_m); - } - Im = anscombe_inverse(stream, Im); - - return Im; - } - - // den poiss - template - TVector ftr_poiss_dnois_2d_br(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr_w, int nkr_m) - { - if((nkr_w == 0) && (nkr_m == 0)) - { - return Im_i; - } - - auto Im = anscombe_forward(stream, Im_i); - if(nkr_w>0) - { - Im = ftr_wiener_2d_br(stream, grid_2d, Im, nkr_w); - } - if(nkr_m>0) - { - Im = ftr_median_2d_br(stream, grid_2d, Im, nkr_m); - } - Im = anscombe_inverse(stream, Im); - - return Im; - } - - // den poiss - template - TVector ftr_poiss_dnois_2d(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr_w, int nkr_m) - { - if((nkr_w == 0) && (nkr_m == 0)) - { - return Im_i; - } - - auto Im = anscombe_forward(stream, Im_i); - if(nkr_w>0) - { - Im = ftr_wiener_2d(stream, grid_2d, Im, nkr_w); - } - if(nkr_m>0) - { - Im = ftr_median_2d(stream, grid_2d, Im, nkr_m); - } - Im = anscombe_inverse(stream, Im); - - return Im; - } - - /******************************************************************************/ - - // get peak signal to noise ratio PSNR - template - Value_type get_PSNR(Stream &stream, TGrid &grid_2d, TVector &Im_i, int nkr_w, int nkr_m) - { - auto Im_s = ftr_poiss_dnois_2d(stream, grid_2d, Im_i, nkr_w, nkr_m); - - auto var_signal = variance(stream, Im_s); - - add_scale(stream, 1, Im_i, -1, Im_s, Im_s); - auto var_no = variance(stream, Im_s); - - // peak signal to noise ratio - return var_no/var_signal; - } - - // get peak signal to noise ratio PSNR - template - Value_type get_PSNR(Stream &stream, TVector &Im_i, TVector &Im_d) - { - auto var_signal = variance(stream, Im_d); - TVector Im_n(Im_d.size()); - add_scale(stream, 1, Im_i, -1, Im_d, Im_n); - auto var_no = variance(stream, Im_n); - - // peak signal to noise ratio - return var_no/var_signal; - } - - // scale_image - template - TVector scale_image_mean(Stream &stream, int ny_i, int nx_i, TVector &Im_i, Value_type shrink_factor, int &ny_o, int &nx_o) - { - using T = Value_type; - TVector Im_o; - - int nkr = max(int(1.0/(2.0*shrink_factor)), 1); - int nk0 = -nkr; - int nke = nkr+1; - - nx_o = max(int(floor(nx_i*shrink_factor)), 1); - ny_o = max(int(floor(ny_i*shrink_factor)), 1); - - if((nx_i == nx_o) && (ny_i == ny_o)) - { - Im_o.assign(Im_i.begin(), Im_i.end()); - return Im_o; - } - Im_o.resize(nx_o*ny_o); - - auto krn_scale_image = [&](const int &ix_i, const int &iy_i, TVector &Im_i, TVector &Im_o) - { - auto ix_t = static_cast(ix_i/shrink_factor); - auto iy_t = static_cast(iy_i/shrink_factor); - - int ix_0 = max(ix_t+nk0, 0); - int ixe = min(ix_t+nke, nx_i); - - int iy_0 = max(iy_t+nk0, 0); - int iye = min(iy_t+nke, ny_i); - - T sum = 0; - for (auto ix = ix_0; ix < ixe; ix++) - { - for (auto iy = iy_0; iy < iye; iy++) - { - sum += Im_i[ix*ny_i+iy]; - } - } - - Im_o[ix_i*ny_o+iy_i] = sum/((ixe-ix_0)*(iye-iy_0)); - }; - - auto thr_scale_image = [&](const Range_2d &range) - { - host_detail::matrix_iter(range, krn_scale_image, Im_i, Im_o); - }; - - stream.set_n_act_stream(nx_o); - stream.set_grid(nx_o, ny_o); - stream.exec(thr_scale_image); - - return Im_o; - } - - // copy image - template - TVector copy_image(Stream &stream, int ny_src, int nx_src, TVector &Im_src, int iy_0, int ix_0, int iye, int ixe, int ny_dst, int nx_dst) - { - TVector Im_dst(nx_dst*ny_dst); - - int nx = min(nx_src, nx_dst); - ixe = (ixe - TVector extract_shape(Stream &stream, FFT, e_host> &fft_2d, TGrid grid_2d, TVector &Im_i) - { - using T = Value_type; - - T sigma = 1.0; - T shrink = 0.5; - T dR = grid_2d.dR_min(); - - int nx_d = 1; - int ny_d = 1; - - // scale_image image - auto Im_d = scale_image_mean(stream, grid_2d.ny, grid_2d.nx, Im_i, shrink, ny_d, nx_d); - - // Otsu thr - int nbins = 256; - auto thr = mt::otsu_thr(Im_d, nbins); - - // binarize - Im_d = binarize(stream, Im_d, thr); - - // copy to the first quadrant - auto Im_o = copy_image(stream, ny_d, nx_d, Im_d, 0, 0, ny_d-1, nx_d-1, grid_2d.ny, grid_2d.nx); - - // dilate binary image - int nkr = static_cast(0.5*sigma/dR); - Im_o = morp_g_dilate(stream, grid_2d.ny, grid_2d.nx, Im_o, nkr); - - // gaussian convolution - Gauss_Cv_2d gauss_cv_2d(&stream, &fft_2d, grid_2d); - gauss_cv_2d(sigma, Im_o); - - // binarize - Im_o = binarize(stream, Im_o, 0.01); - - // copy to the first quadrant - Im_d = copy_image(stream, grid_2d.ny, grid_2d.nx, Im_o, 0, 0, ny_d-1, nx_d-1, ny_d, nx_d); - - // scale image - Im_o = scale_image_mean(stream, ny_d, nx_d, Im_d, 1.0/shrink, grid_2d.ny, grid_2d.nx); - - // binarize - Im_o = binarize(stream, Im_o, 0.5); - - return Im_o; - } - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/in_classes.cuh b/src/in_classes.cuh new file mode 100755 index 00000000..4e1c80b5 --- /dev/null +++ b/src/in_classes.cuh @@ -0,0 +1,66 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef IN_CLASSES_H + #define IN_CLASSES_H + + #include + + #include "math_mt.h" + #include "types.cuh" + #include "particles.cuh" + #include "system_config.h" + #include "cgpu_vctr.cuh" + #include "grid.h" + + /***************************************************************************************/ + /***************************** Input particle superposition ****************************/ + /***************************************************************************************/ + namespace mt + { + template class In_Spt_Ptc_xd; + + template + using In_Spt_Ptc_2d = In_Spt_Ptc_xd; + } + + namespace mt + { + template + class In_Spt_Ptc_xd + { + public: + using value_type = T; + + T scf_radius; + Grid_xd grid; + Ptc_2d_2 ptc; + + In_Spt_Ptc_xd(): scf_radius(3.5) {}; + + Ptc_s_fcn_xd ptc_s_fcn(const dt_int32& iptc, const T& tap_ftr) + { + const auto r_max = scf_radius*ptc.c_2[iptc]; + const auto r_tap = tap_ftr*r_max; + + return {ptc.get_pos(iptc), ptc.c_1[iptc], ptc.c_2[iptc], r_tap, r_max, grid}; + } + }; + } + +#endif \ No newline at end of file diff --git a/src/incident_wave.cuh b/src/incident_wave.cuh old mode 100644 new mode 100755 index d14f5575..47c0ee7e --- a/src/incident_wave.cuh +++ b/src/incident_wave.cuh @@ -1,143 +1,130 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef INCIDENT_WAVE_H -#define INCIDENT_WAVE_H - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" - -namespace mt -{ - template - class Incident_Wave{ - public: - using T_r = T; - using T_c = complex; - - static const eDevice device = dev; - - Incident_Wave(): input_multislice(nullptr), stream(nullptr), fft_2d(nullptr){} - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i, FFT *fft2_i) - { - input_multislice = input_multislice_i; - stream = stream_i; - fft_2d = fft2_i; - - if(input_multislice->is_user_define_wave()) - { - fpsi_0.assign(input_multislice->iw_psi.begin(), input_multislice->iw_psi.end()); - mt::fft2_shift(*stream, input_multislice->grid_2d, fpsi_0); - fft_2d->forward(fpsi_0); - } - else if(input_multislice->is_convergent_wave()) - { - fpsi_0.resize(input_multislice->grid_2d.nxy()); - } - } - - void operator()(Vector &psi, T_r gxu, T_r gyu, - Vector &x_b, Vector &y_b, T_r z_init=0) - { - switch(input_multislice->iw_type) - { - case eIWT_Plane_Wave: - { - mt::fill(*stream, psi, T_c(1.0, 0.0)); - } - break; - case eIWT_Convergent_Wave: - { - auto f_0 = input_multislice->cond_lens.c_10; - auto f_s = f_0 - (input_multislice->cond_lens.zero_defocus_plane-z_init); - input_multislice->cond_lens.set_defocus(f_s); - - mt::fill(*stream, psi, T_c(0)); - for(auto ib=0; ibgrid_2d.exp_factor_Rx(x_b[ib]); - auto y = input_multislice->grid_2d.exp_factor_Ry(y_b[ib]); - - mt::probe(*stream, input_multislice->grid_2d, input_multislice->cond_lens, x, y, gxu, gyu, fpsi_0); - mt::add(*stream, fpsi_0, psi); - } - fft_2d->inverse(psi); - - input_multislice->cond_lens.set_defocus(f_0); - } - break; - case eIWT_User_Define_Wave: - { - // we need to include defocus - auto f_s = -(input_multislice->cond_lens.zero_defocus_plane-z_init); - - Vector x(x_b.size()); - Vector y(y_b.size()); - for(auto ib=0; ibgrid_2d.exp_factor_Rx(x_b[ib]); - y[ib] = input_multislice->grid_2d.exp_factor_Ry(y_b[ib]); - } - - mt::mul_exp_g_factor_2d(*stream, input_multislice->grid_2d, x, y, fpsi_0, psi); - - fft_2d->inverse(psi); - } - break; - } - } - - template - void operator()(const eSpace &space, TOutput_multislice &output_multislice) - { - Vector psi(input_multislice->grid_2d.nxy()); - T_r gxu = input_multislice->gx_0(); - T_r gyu = input_multislice->gy_0(); - Vector &iw_x = input_multislice->iw_x; - Vector &iw_y = input_multislice->iw_y; - - this->operator()(psi, gxu, gyu, iw_x, iw_y); - - if(space == eS_Reciprocal) - { - fft_2d->forward(psi); - mt::scale(*stream, input_multislice->grid_2d.inxy(), psi); - } - - mt::copy_to_host(output_multislice.stream, psi, output_multislice.psi_0[0]); - } - - private: - Input_Multislice *input_multislice; - Stream *stream; - FFT *fft_2d; - - Vector fpsi_0; - }; - -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef INCIDENT_WAVE_H + #define INCIDENT_WAVE_H + + #include "math_mt.h" + #include "types.cuh" + #include "type_traits_gen.h" + #include "cgpu_stream.cuh" + #include "cgpu_fft.cuh" + #include "in_classes.cuh" + #include "output_multem.hpp" + #include "fcns_cpu.h" + #include "fcns_gpu.h" + + namespace mt + { + template + class Incident_Wave{ + public: + using T_r = T; + using T_c = complex; + + static const eDev device = Dev; + + Incident_Wave(): multem_in_parm(nullptr), stream(nullptr), fft_2d(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + multem_in_parm = multem_in_parm_i; + stream = stream_i; + fft_2d = fft2_i; + + if (multem_in_parm->is_user_define_wave()) + { + fpsi_0.assign(multem_in_parm->iw_psi.begin(), multem_in_parm->iw_psi.end()); + mt::fcn_fftsft_2d(*stream, multem_in_parm->grid_2d, fpsi_0); + fft_2d->forward(fpsi_0); + } + else if (multem_in_parm->is_convergent_wave()) + { + fpsi_0.resize(multem_in_parm->grid_2d.size()); + } + } + + void operator()(Vctr& psi, R_2d gu, Beam_Pos_2d& beam_pos_2d, T_r z_init=0) + { + switch(multem_in_parm->iw_type) + { + case eiwt_plane_wave: + { + mt::fill(*stream, psi, T_c(1.0, 0.0)); + } + break; + case eiwt_convergent_wave: + { + auto f_0 = multem_in_parm->cond_lens.c_10; + auto f_s = f_0 - (multem_in_parm->cond_lens.zero_def_plane-z_init); + multem_in_parm->cond_lens.set_defocus(f_s); + + mt::fill(*stream, psi, T_c(0)); + auto R = multem_in_parm->grid_2d.factor_2pi_rv_ctr(beam_pos_2d.p); + + for(auto ib=0; ibgrid_2d, multem_in_parm->cond_lens, R[ib], gu, fpsi_0); + mt::add(*stream, fpsi_0, psi); + } + fft_2d->inverse(psi); + + multem_in_parm->cond_lens.set_defocus(f_0); + } + break; + case eiwt_user_def_Wave: + { + // we need to include defocus + auto f_s = -(multem_in_parm->cond_lens.zero_def_plane-z_init); + + auto R = multem_in_parm->grid_2d.factor_2pi_rv_ctr(beam_pos_2d.p); + + mt::fcn_mul_exp_g_factor_2d(*stream, multem_in_parm->grid_2d, R, fpsi_0, psi); + + fft_2d->inverse(psi); + } + break; + } + } + + template + void operator()(const eSpace &space, TOutput_multislice &output_multem) + { + Vctr psi(multem_in_parm->grid_2d.size()); + this->operator()(psi, multem_in_parm->gu_0(), multem_in_parm->beam_pos_2d); + + if (space == esp_fourier) + { + fft_2d->forward(psi); + mt::fcn_scale(*stream, multem_in_parm->grid_2d.isize_r(), psi); + } + + mt::fcn_assign_crop_fftsft_2d(multem_in_parm->grid_2d, psi, multem_in_parm->output_area, output_multem.psi_0(0, 0)); + } + + private: + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + + Vctr fpsi_0; + }; + + } + #endif \ No newline at end of file diff --git a/src/info_cpu.h b/src/info_cpu.h new file mode 100755 index 00000000..1c929c78 --- /dev/null +++ b/src/info_cpu.h @@ -0,0 +1,49 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" + +namespace mt +{ + class Cpu_Info + { + public: + dt_int32 n_proc; // number of cores + dt_int32 n_threads; // number of threads + dt_float64 tot_mem; // size in Mb + dt_float64 free_mem; // size in Mb + + explicit Cpu_Info(); + }; + + /* device info */ + namespace dev_info + { + void cpu_tot_free_mem(::dt_float64 &tot, ::dt_float64 &free); + + ::dt_float64 cpu_free_mem(); + + ::dt_float64 cpu_tot_mem(); + + mt::Cpu_Info cpu_info(); + } +} + +#include "detail/info_cpu.inl" \ No newline at end of file diff --git a/src/info_gpu.h b/src/info_gpu.h new file mode 100755 index 00000000..02f4b793 --- /dev/null +++ b/src/info_gpu.h @@ -0,0 +1,57 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include + +namespace mt +{ +#ifdef __CUDACC__ + class Gpu_Info + { + public: + dt_int32 id; // gpu id + std::string name; // gpu name + dt_int32 comp_cap; // compute capability + dt_float64 tot_mem; // size in Mb + dt_float64 free_mem; // size in Mb + + Gpu_Info(); + }; + + /* device info */ + namespace dev_info + { + void gpu_tot_free_mem(dt_float64 &tot, dt_float64 &free, dt_int32 idx = 0); + + dt_float64 gpu_free_mem(); + + dt_float64 gpu_tot_mem(); + + dt_bool is_gpu_avbl(); + + dt_int32 gpu_n_avbl(); + + std::vector gpu_info(); + } +#endif +} + +#include "detail/info_gpu.inl" \ No newline at end of file diff --git a/src/input_multislice.cuh b/src/input_multislice.cuh deleted file mode 100644 index ee6664f6..00000000 --- a/src/input_multislice.cuh +++ /dev/null @@ -1,1382 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef INPUT_MULTISLICE_H -#define INPUT_MULTISLICE_H - -#include - -#include "math.cuh" -#include "types.cuh" -#include "lin_alg_def.cuh" -#include "atomic_data_mt.hpp" -#include "slicing.hpp" -#include "memory_info.cuh" - -namespace mt -{ - bool is_gpu_available(); - - int number_of_gpu_available(); - - template - DEVICE_CALLABLE FORCE_INLINE - T get_Vr_factor(const T &E_0, const T &theta); - - - /**************************************************************************************/ - inline - bool is_multislice(const eElec_Spec_Int_Model &int_model) - { - return int_model == mt::eESIM_Multislice; - } - - inline - bool is_phase_object(const eElec_Spec_Int_Model &int_model) - { - return int_model == mt::eESIM_Phase_Object; - } - - inline - bool is_weak_phase_object(const eElec_Spec_Int_Model &int_model) - { - return int_model == mt::eESIM_Weak_Phase_Object; - } - - /**************************************************************************************/ - inline - bool is_still_atom(const ePhonon_Model &pn_model) - { - return pn_model == ePM_Still_Atom; - } - - inline - bool is_absorptive_model(const ePhonon_Model &pn_model) - { - return pn_model == ePM_Absorptive_Model; - } - - inline - bool is_frozen_phonon(const ePhonon_Model &pn_model) - { - return pn_model == ePM_Frozen_Phonon; - } - - inline - bool is_frozen_phonon_single_conf(const ePhonon_Model &pn_model, const bool &pn_single_conf) - { - return is_frozen_phonon(pn_model) && pn_single_conf; - } - - /**************************************************************************************/ - inline - bool is_whole_spec(const eThick_Type &thick_type) - { - return thick_type == eTT_Whole_Spec; - } - - inline - bool is_through_slices(const eThick_Type &thick_type) - { - return thick_type == eTT_Through_Slices; - } - - inline - bool is_through_thick(const eThick_Type &thick_type) - { - return thick_type == eTT_Through_Thick; - } - - /**************************************************************************************/ - inline - bool is_slicing_by_planes(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) - { - return mt::is_multislice(int_model) && (pot_slic == mt::ePS_Planes); - } - - inline - bool is_slicing_by_dz(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) - { - return mt::is_multislice(int_model) && (pot_slic == mt::ePS_dz_Proj); - } - - inline - bool is_subslicing(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) - { - return mt::is_multislice(int_model) && (pot_slic == mt::ePS_dz_Sub); - } - - inline - bool is_subslicing_whole_spec(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic, const eThick_Type &thick_type) - { - return mt::is_subslicing(int_model, pot_slic) && is_whole_spec(thick_type); - } - - /**************************************************************************************/ - inline - bool is_plane_wave(eIncident_Wave_Type iw_type) - { - return iw_type == eIWT_Plane_Wave; - } - - inline - bool is_convergent_wave(eIncident_Wave_Type iw_type) - { - return iw_type == eIWT_Convergent_Wave; - } - - inline - bool is_user_define_wave(eIncident_Wave_Type iw_type) - { - return iw_type == eIWT_User_Define_Wave; - } - - /**************************************************************************************/ - inline - bool is_STEM(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_STEM; - } - - inline - bool is_ISTEM(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_ISTEM; - } - - inline - bool is_CBED(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_CBED; - } - - inline - bool is_CBEI(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_CBEI; - } - - inline - bool is_ED(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_ED; - } - - inline - bool is_HRTEM(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_HRTEM; - } - - inline - bool is_PED(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_PED; - } - - inline - bool is_HCTEM(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_HCTEM; - } - - inline - bool is_EWFS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_EWFS; - } - - inline - bool is_EWRS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_EWRS; - } - - inline - bool is_EWFS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) - { - return is_EWFS(sim_type) && (!is_frozen_phonon(pn_model) || is_frozen_phonon_single_conf(pn_model, pn_single_conf)); - } - - inline - bool is_EWRS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) - { - return is_EWRS(sim_type) && (!is_frozen_phonon(pn_model) || is_frozen_phonon_single_conf(pn_model, pn_single_conf)); - } - - inline - bool is_EELS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_EELS; - } - - inline - bool is_EFTEM(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_EFTEM; - } - - inline - bool is_IWFS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_IWFS; - } - - inline - bool is_IWRS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_IWRS; - } - - inline - bool is_PPFS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_PPFS; - } - - inline - bool is_PPRS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_PPRS; - } - - inline - bool is_TFFS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_TFFS; - } - - inline - bool is_TFRS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_TFRS; - } - - inline - bool is_PropFS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_PropFS; - } - - inline - bool is_PropRS(const eTEM_Sim_Type &sim_type) - { - return sim_type == mt::eTEMST_PropRS; - } - - inline - bool is_STEM_ISTEM(const eTEM_Sim_Type &sim_type) - { - return is_STEM(sim_type) || is_ISTEM(sim_type); - } - - inline - bool is_CBED_CBEI(const eTEM_Sim_Type &sim_type) - { - return is_CBED(sim_type) || is_CBEI(sim_type); - } - - inline - bool is_ED_HRTEM(const eTEM_Sim_Type &sim_type) - { - return is_ED(sim_type) || is_HRTEM(sim_type); - } - - inline - bool is_PED_HCTEM(const eTEM_Sim_Type &sim_type) - { - return is_PED(sim_type) || is_HCTEM(sim_type); - } - - inline - bool is_EWFS_EWRS(const eTEM_Sim_Type &sim_type) - { - return is_EWFS(sim_type) || is_EWRS(sim_type); - } - - inline - bool is_EWFS_EWRS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) - { - return is_EWFS_SC(sim_type, pn_model, pn_single_conf) || is_EWRS_SC(sim_type, pn_model, pn_single_conf); - } - - inline - bool is_EWFS_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) - { - return is_EWFS(sim_type) && is_convergent_wave(iw_type); - } - - inline - bool is_EWRS_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) - { - return is_EWRS(sim_type) && is_convergent_wave(iw_type); - } - - inline - bool is_EW_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) - { - return is_EWFS_EWRS(sim_type) && is_convergent_wave(iw_type); - } - - inline - bool is_EELS_EFTEM(const eTEM_Sim_Type &sim_type) - { - return is_EELS(sim_type) || is_EFTEM(sim_type); - } - - inline - bool is_IWFS_IWRS(const eTEM_Sim_Type &sim_type) - { - return is_IWFS(sim_type) || is_IWRS(sim_type); - } - - inline - bool is_PPFS_PPRS(const eTEM_Sim_Type &sim_type) - { - return is_PPFS(sim_type) || is_PPRS(sim_type); - } - - inline - bool is_TFFS_TFRS(const eTEM_Sim_Type &sim_type) - { - return is_TFFS(sim_type) || is_TFRS(sim_type); - } - - inline - bool is_PropFS_PropRS(const eTEM_Sim_Type &sim_type) - { - return is_PropFS(sim_type) || is_PropRS(sim_type); - } - - inline - bool is_grid_FS(const eTEM_Sim_Type &sim_type) - { - auto bb = is_CBED(sim_type) || is_ED(sim_type) || is_PED(sim_type) || is_EWFS(sim_type); - bb = bb || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); - return bb; - } - - inline - bool is_grid_RS(const eTEM_Sim_Type &sim_type) - { - return !is_grid_FS(sim_type); - } - - inline - bool is_simulation_type_FS(const eTEM_Sim_Type &sim_type) - { - auto bb = is_STEM(sim_type) || is_CBED(sim_type) || is_ED(sim_type); - bb = bb || is_PED(sim_type) || is_EWFS(sim_type) || is_EELS(sim_type); - bb = bb || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); - return bb; - } - - inline - bool is_simulation_type_RS(const eTEM_Sim_Type &sim_type) - { - return !is_simulation_type_FS(sim_type); - } - - inline - bool is_specimen_required(const eTEM_Sim_Type &sim_type) - { - return !(is_IWFS_IWRS(sim_type) || is_PropFS_PropRS(sim_type)); - } - - inline - bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(const eTEM_Sim_Type &sim_type) - { - return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEM(sim_type); - } - - inline - bool is_CBED_ED_EWFS_PED(const eTEM_Sim_Type &sim_type) - { - return is_CBED(sim_type) || is_ED(sim_type) || is_EWFS(sim_type) || is_PED(sim_type); - } - - inline - bool is_obj_lens_temp_spat(const eTEM_Sim_Type &sim_type) - { - return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEM(sim_type); - } - - inline - bool is_cond_lens_temp_spat(const eTEM_Sim_Type &sim_type) - { - return is_STEM_ISTEM(sim_type) || is_CBED_CBEI(sim_type) || is_EELS(sim_type); - } - - inline - eSpace get_simulation_space(const eTEM_Sim_Type &sim_type) - { - return (is_simulation_type_FS(sim_type) || is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(sim_type)) ? mt::eS_Reciprocal : mt::eS_Real; - } - - inline - bool is_scanning(const eTEM_Sim_Type &sim_type) - { - return is_STEM_ISTEM(sim_type) || is_EELS(sim_type); - } - - /**************************************************************************************/ - inline - eIncident_Wave_Type validate_incident_wave_type(const eTEM_Sim_Type &sim_type, eIncident_Wave_Type iw_type) - { - if (iw_type == eIWT_Auto) - { - auto bb = is_scanning(sim_type) || is_CBED_CBEI(sim_type); - bb = bb || ((is_EWFS_EWRS(sim_type) || is_IWFS_IWRS(sim_type)) && is_convergent_wave(iw_type)); - iw_type = (bb) ? mt::eIWT_Convergent_Wave : mt::eIWT_Plane_Wave; - } - - return iw_type; - } - - /**************************************************************************************/ - template - struct Slicing; - - template - class Input_Multislice - { - public: - using value_type = T; - - System_Configuration system_conf; // System information - - eElec_Spec_Int_Model interaction_model; // eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 - ePotential_Type potential_type; // potential type: 1: Doyle(0-4), 2: Peng(0-4), 3: peng(0-12), 4: Kirkland(0-12), 5:Weickenmeier(0-12) adn 6: Lobato(0-12) - - ePhonon_Model pn_model; // 1: Still atom model, 2: Absorptive potential model, 3: Frozen phonon - bool pn_coh_contrib; // true, false - bool pn_single_conf; // single configuration: true, false - FP_Dim pn_dim; // Phonon dimensions - int fp_dist; // 1: Gaussian (Phonon distribution) - int pn_seed; // Random seed(frozen phonon) - int pn_nconf; // true: single phonon configuration, false: number of frozen phonon configurations - int fp_iconf_0; // initial configuration - - Atom_Data atoms; // atoms - bool is_crystal; - - T spec_rot_theta; // angle - r3d spec_rot_u0; // unitary vector - eRot_Point_Type spec_rot_center_type; // 1: geometric center, 2: User define - r3d spec_rot_center_p; // rotation point - - eThick_Type thick_type; // eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 - host_vector thick; // Array of thickes - - ePotential_Slicing potential_slicing; // ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - - Grid_2d grid_2d; // grid information - - Range_2d output_area; // Output region information - - eTEM_Sim_Type simulation_type; // 11: Scanning, 12: ISTEM, 21: cbed, 22: cbei, 31: ED, 32: hrtem, 41: ped, 42: hci, ... 51: EW Fourier, 52: EW real - - eIncident_Wave_Type iw_type; // 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto - host_vector> iw_psi; // user define incident wave - host_vector iw_x; // x position - host_vector iw_y; // y position - - T E_0; // Acceleration volatage in KeV - T lambda; // lambda - T theta; // incident tilt (in spherical coordinates) (rad) - T phi; // incident tilt (in spherical coordinates) (rad) - - eIllumination_Model illumination_model; // 1: Partial coherente mode, 2: transmission cross coefficient - eTemporal_Spatial_Incoh temporal_spatial_incoh; // 1: Spatial and temporal, 2: Temporal, 3: Spatial - - Lens cond_lens; // Condenser lens - Lens obj_lens; // Objective lens - - Scanning scanning; // Scanning - - Detector detector; // STEM Detectors - - EELS eels_fr; // EELS - - eOperation_Mode operation_mode; // eOM_Normal = 1, eOM_Advanced = 2 - bool slice_storage; // true, false - bool reverse_multislice; // true, false - int mul_sign; // tem_simulation sign - - T Vrl; // Atomic potential cut-off - int nR; // Number of grid_bt points - - int nrot; // Total number of rotations - - eLens_Var_Type cdl_var_type; // eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 - host_vector cdl_var; // Array of thickes - - host_vector iscan; - host_vector beam_x; // temporal variables - host_vector beam_y; - - int islice; - bool dp_Shift; // Shift diffraction pattern - - Input_Multislice() :simulation_type(eTEMST_EWRS), pn_model(ePM_Still_Atom), interaction_model(eESIM_Multislice), - potential_slicing(ePS_Planes), potential_type(ePT_Lobato_0_12), fp_dist(1), pn_seed(300183), - pn_single_conf(false), pn_nconf(1), fp_iconf_0(1), spec_rot_theta(0), spec_rot_u0(0, 0, 1), - spec_rot_center_type(eRPT_geometric_center), spec_rot_center_p(1, 0, 0), illumination_model(eIM_Partial_Coherent), - temporal_spatial_incoh(eTSI_Temporal_Spatial), thick_type(eTT_Whole_Spec), - operation_mode(eOM_Normal), pn_coh_contrib(false), slice_storage(false), reverse_multislice(false), - mul_sign(1), E_0(300), lambda(0), theta(0), phi(0), nrot(1), Vrl(c_Vrl), nR(c_nR), iw_type(eIWT_Plane_Wave), - is_crystal(false), islice(0), dp_Shift(false) {}; - - template - void assign(TInput_Multislice &input_multislice) - { - interaction_model = input_multislice.interaction_model; - potential_type = input_multislice.potential_type; - - operation_mode = input_multislice.operation_mode; - slice_storage = input_multislice.slice_storage; - reverse_multislice = input_multislice.reverse_multislice; - mul_sign = input_multislice.mul_sign; - Vrl = input_multislice.Vrl; - nR = input_multislice.nR; - - pn_model = input_multislice.pn_model; - pn_coh_contrib = input_multislice.pn_coh_contrib; - pn_dim = input_multislice.pn_dim; - fp_dist = input_multislice.fp_dist; - pn_seed = input_multislice.pn_seed; - pn_single_conf = input_multislice.pn_single_conf; - pn_nconf = input_multislice.pn_nconf; - - atoms = input_multislice.atoms; - is_crystal = input_multislice.is_crystal; - - spec_rot_theta = input_multislice.spec_rot_theta; - spec_rot_u0 = input_multislice.spec_rot_u0; - spec_rot_center_type = input_multislice.spec_rot_center_type; - spec_rot_center_p = input_multislice.spec_rot_center_p; - - thick_type = input_multislice.thick_type; - thick = input_multislice.thick; - - potential_slicing = input_multislice.potential_slicing; - - grid_2d = input_multislice.grid_2d; - - simulation_type = input_multislice.simulation_type; - - iw_type = input_multislice.iw_type; - iw_psi = input_multislice.iw_psi; - iw_x = input_multislice.iw_x; - iw_y = input_multislice.iw_y; - - E_0 = input_multislice.E_0; - theta = input_multislice.theta; - phi = input_multislice.phi; - nrot = input_multislice.nrot; - - illumination_model = input_multislice.illumination_model; - temporal_spatial_incoh = input_multislice.temporal_spatial_incoh; - - cond_lens = input_multislice.cond_lens; - obj_lens = input_multislice.obj_lens; - - scanning = input_multislice.scanning; - detector = input_multislice.detector; - - eels_fr = input_multislice.eels_fr; - - cdl_var_type = input_multislice.cdl_var_type; - cdl_var = input_multislice.cdl_var; - - iscan = input_multislice.iscan; - beam_x = input_multislice.beam_x; - beam_y = input_multislice.beam_y; - - islice = input_multislice.islice; - dp_Shift = input_multislice.dp_Shift; - } - - template - Input_Multislice& operator=(TInput_Multislice &input_multislice) - { - assign(input_multislice); - return *this; - } - - void validate_parameters() - { - pn_seed = max(1, pn_seed); - - pn_nconf = (!is_frozen_phonon()) ? 1 : max(1, pn_nconf); - - fp_iconf_0 = (!is_frozen_phonon()) ? 1 : (pn_single_conf) ? pn_nconf : 1; - - islice = max(0, islice); - - if (isZero(Vrl)) - { - Vrl = c_Vrl; - } - - if (isZero(nR)) - { - nR = c_nR; - } - - dp_Shift = (is_PED()) ? true : false; - - if (!is_scanning()) - { - scanning.set_default(); - } - scanning.set_grid(); - - lambda = get_lambda(E_0); - - // tem_simulation sign - mul_sign = (reverse_multislice) ? -1 : 1; - - theta = set_incident_angle(theta); - nrot = max(1, nrot); - if (!is_PED_HCTEM()) - { - nrot = 1; - } - - // set beam position - set_beam_position(iw_x, iw_y); - - if (is_EELS_EFTEM()) - { - pn_coh_contrib = false; - interaction_model = mt::eESIM_Multislice; - illumination_model = eIM_Coherent; - } - - if (is_EWFS_EWRS()) - { - pn_coh_contrib = true; - illumination_model = eIM_Coherent; - } - - // It will be changed when you include spatial incoherences (beta) - if (is_CBED_CBEI() && !is_illu_mod_full_integration()) - { - illumination_model = eIM_Coherent; - } - - slice_storage = is_slice_storage(); - - if (!is_multislice()) - { - islice = 0; - potential_slicing = ePS_Planes; - if (is_through_slices()) - { - thick_type = eTT_Through_Thick; - } - slice_storage = slice_storage || !is_whole_spec(); - } - - if (is_subslicing() && is_through_thick()) - { - thick_type = eTT_Whole_Spec; - } - - if (!is_subslicing()) - { - pn_dim.z = false; - } - - if (is_spec_rot_active()) - { - thick_type = eTT_Whole_Spec; - spec_rot_u0.normalized(); - // get geometric center - if (spec_rot_center_type == eRPT_geometric_center) - { - spec_rot_center_p = r3d(atoms.x_mean, atoms.y_mean, atoms.z_mean); - } - // rotate atoms - rotate_atoms(atoms, spec_rot_theta, spec_rot_u0, spec_rot_center_p); - // get statistic - atoms.get_statistic(); - // reset theta - spec_rot_theta = 0; - } - - // temporal fix for phase object - if (!is_multislice() && is_whole_spec()) - { - potential_slicing = ePS_dz_Proj; - } - - // match slicing with the require thickness - Slicing slicing; - slicing.match_thickness(potential_slicing, atoms, thick_type, thick); - - // remove atoms outside the thickness range - T ee_z = 0.1; - T z_e = thick.back() + ee_z; - - if (atoms.z_max > z_e) - { - T z_0 = atoms.z_min - ee_z; - remove_atoms_outside_z_range(atoms, z_0, z_e); - // get statistic - atoms.get_statistic(); - } - - /************* verify lenses parameters **************/ - - if (isZero(cond_lens.si_sigma)) - { - temporal_spatial_incoh = eTSI_Temporal; - } - - if (!is_illu_mod_full_integration()) - { - cond_lens.si_rad_npts = 1; - cond_lens.si_azm_npts = 1; - cond_lens.ti_npts = 1; - - obj_lens.si_rad_npts = 1; - obj_lens.si_azm_npts = 1; - obj_lens.ti_npts = 1; - } - - if (is_incoh_temporal()) - { - cond_lens.si_rad_npts = 1; - cond_lens.si_azm_npts = 1; - - obj_lens.si_rad_npts = 1; - obj_lens.si_azm_npts = 1; - } - else if (is_incoh_spatial()) - { - cond_lens.ti_npts = 1; - obj_lens.ti_npts = 1; - } - - // set condenser lens parameters - cond_lens.set_input_data(E_0, grid_2d); - if (atoms.empty()) - { - cond_lens.zero_defocus_plane = 0; - } - else - { - cond_lens.zero_defocus_plane = cond_lens.get_zero_defocus_plane(atoms.z_min, atoms.z_max); - } - - cond_lens.zero_defocus_type = eZDT_User_Define; - - // set objetive lens parameters - obj_lens.set_input_data(E_0, grid_2d); - - // validate output area - validate_output_area(); - } - - /**************************************************************************************/ - void set_reverse_multislice(bool rm) - { - reverse_multislice = rm; - mul_sign = (reverse_multislice) ? -1 : 1; - } - - /**************************************************************************************/ - inline - int number_conf() - { - return (pn_nconf - fp_iconf_0 + 1); - } - - int number_of_beams() - { - return (is_plane_wave())?0:iw_x.size(); - } - - bool is_multi_beam() - { - return number_of_beams() > 0; - } - - template - void set_beam_position(TVector &x, TVector &y) - { - beam_x.assign(x.begin(), x.end()); - beam_y.assign(y.begin(), y.end()); - } - - void validate_output_area() - { - if((is_STEM() || is_EELS())) - { - output_area.ix_0 = 0; - output_area.ix_e = grid_2d.nx; - - output_area.iy_0 = 0; - output_area.iy_e = grid_2d.ny; - } - else - { - if(output_area.ix_0==output_area.ix_e) - { - output_area.ix_0 = 0; - output_area.ix_e = grid_2d.nx; - } - - if(output_area.iy_0==output_area.iy_e) - { - output_area.iy_0 = 0; - output_area.iy_e = grid_2d.ny; - } - - output_area.set_ascending_index(); - output_area.clip_ix(0, grid_2d.nx); - output_area.clip_iy(0, grid_2d.ny); - } - - output_area.ixy_0 = 0; - output_area.ixy_e = output_area.nxy(); - } - - void set_iscan_beam_position() - { - beam_x.resize(iscan.size()); - beam_y.resize(iscan.size()); - for (auto is = 0; is < iscan.size(); is++) - { - auto idx = iscan[is]; - beam_x[is] = scanning.x[idx]; - beam_y[is] = scanning.y[idx]; - } - } - - /**************************************************************************************/ - bool is_spec_rot_active() const - { - return mt::nonZero(spec_rot_theta); - } - - /**************************************************************************************/ - T Rx_exp_factor() - { - return grid_2d.exp_factor_Rx(beam_x); - } - - T Ry_exp_factor() - { - return grid_2d.exp_factor_Ry(beam_y); - } - - T set_incident_angle(const T &theta) const - { - T n = round(sin(theta) / (lambda*grid_2d.dg_min())); - return (isZero(theta)) ? 0 : asin(n*lambda*grid_2d.dg_min()); - } - - T get_phonon_rot_weight() const - { - int nconf = (!is_frozen_phonon() || pn_single_conf) ? 1 : pn_nconf; - return 1.0 / static_cast(nconf*nrot); - } - - void set_phi(const int &irot) - { - phi = (irot == 0) ? 0.0 : (c_2Pi*static_cast(irot)) / static_cast(nrot); - } - - inline - T get_propagator_factor(const T &z) const - { - return (-mul_sign*c_Pi*lambda*z); - } - - T Vr_factor() const - { - return (mul_sign*get_Vr_factor(E_0, theta)); - } - - T gx_0() const - { - return sin(theta)*cos(phi) / lambda; - } - - T gy_0() const - { - return sin(theta)*sin(phi) / lambda; - } - - void set_eels_fr_atom(const int &iatoms, const Atom_Data &atoms) - { - eels_fr.x = grid_2d.exp_factor_Rx(atoms.x[iatoms]); - eels_fr.y = grid_2d.exp_factor_Ry(atoms.y[iatoms]); - eels_fr.occ = atoms.occ[iatoms]; - } - - /**************************************************************************************/ - bool is_multislice() const - { - return mt::is_multislice(interaction_model); - } - - bool is_phase_object() const - { - return mt::is_phase_object(interaction_model); - } - - bool is_weak_phase_object() const - { - return mt::is_weak_phase_object(interaction_model); - } - - /**************************************************************************************/ - - bool is_still_atom() const - { - return mt::is_still_atom(pn_model); - } - - bool is_absorptive_model() const - { - return mt::is_absorptive_model(pn_model); - } - - bool is_frozen_phonon() const - { - return mt::is_frozen_phonon(pn_model); - } - - bool is_frozen_phonon_single_conf() const - { - return mt::is_frozen_phonon_single_conf(pn_model, pn_single_conf); - } - - /**************************************************************************************/ - bool is_whole_spec() const - { - return mt::is_whole_spec(thick_type); - } - - bool is_through_slices() const - { - return mt::is_through_slices(thick_type); - } - - bool is_through_thick() const - { - return mt::is_through_thick(thick_type); - } - - /**************************************************************************************/ - bool is_slicing_by_planes() const - { - return mt::is_slicing_by_planes(interaction_model, potential_slicing); - } - - bool is_slicing_by_dz() const - { - return mt::is_slicing_by_dz(interaction_model, potential_slicing); - } - - bool is_subslicing() const - { - return mt::is_subslicing(interaction_model, potential_slicing); - } - - bool is_subslicing_whole_spec() const - { - return mt::is_subslicing_whole_spec(interaction_model, potential_slicing, thick_type); - } - - /**************************************************************************************/ - bool is_plane_wave() const - { - return mt::is_plane_wave(iw_type); - } - - bool is_convergent_wave() const - { - return mt::is_convergent_wave(iw_type); - } - - bool is_user_define_wave() const - { - return mt::is_user_define_wave(iw_type); - } - - /**********************************************************/ - bool is_STEM() const - { - return mt::is_STEM(simulation_type); - } - - bool is_ISTEM() const - { - return mt::is_ISTEM(simulation_type); - } - - bool is_CBED() const - { - return mt::is_CBED(simulation_type); - } - - bool is_CBEI() const - { - return mt::is_CBEI(simulation_type); - } - - bool is_ED() const - { - return mt::is_ED(simulation_type); - } - - bool is_HRTEM() const - { - return mt::is_HRTEM(simulation_type); - } - - bool is_PED() const - { - return mt::is_PED(simulation_type); - } - - bool is_HCTEM() const - { - return mt::is_HCTEM(simulation_type); - } - - bool is_EWFS() const - { - return mt::is_EWFS(simulation_type); - } - - bool is_EWRS() const - { - return mt::is_EWRS(simulation_type); - } - - bool is_EWFS_SC() const - { - return mt::is_EWFS_SC(simulation_type, pn_model, pn_single_conf); - } - - bool is_EWRS_SC() const - { - return mt::is_EWRS_SC(simulation_type, pn_model, pn_single_conf); - } - - bool is_EELS() const - { - return mt::is_EELS(simulation_type); - } - - bool is_EFTEM() const - { - return mt::is_EFTEM(simulation_type); - } - - bool is_IWFS() const - { - return mt::is_IWFS(simulation_type); - } - - bool is_IWRS() const - { - return mt::is_IWRS(simulation_type); - } - - bool is_PPFS() const - { - return mt::is_PPFS(simulation_type); - } - - bool is_PPRS() const - { - return mt::is_PPRS(simulation_type); - } - - bool is_TFFS() const - { - return mt::is_TFFS(simulation_type); - } - - bool is_TFRS() const - { - return mt::is_TFRS(simulation_type); - } - - bool is_PropFS() const - { - return mt::is_PropFS(simulation_type); - } - - bool is_PropRS() const - { - return mt::is_PropRS(simulation_type); - } - - bool is_STEM_ISTEM() const - { - return mt::is_STEM_ISTEM(simulation_type); - } - - bool is_CBED_CBEI() const - { - return mt::is_CBED_CBEI(simulation_type); - } - - bool is_ED_HRTEM() const - { - return mt::is_ED_HRTEM(simulation_type); - } - - bool is_PED_HCTEM() const - { - return mt::is_PED_HCTEM(simulation_type); - } - - bool is_EWFS_EWRS() const - { - return mt::is_EWFS_EWRS(simulation_type); - } - - bool is_EWFS_EWRS_SC() const - { - return mt::is_EWFS_EWRS_SC(simulation_type, pn_model, pn_single_conf); - } - - bool is_EELS_EFTEM() const - { - return mt::is_EELS_EFTEM(simulation_type); - } - - bool is_IWFS_IWRS() const - { - return mt::is_IWFS_IWRS(simulation_type); - } - - bool is_PPFS_PPRS() const - { - return mt::is_PPFS_PPRS(simulation_type); - } - - bool is_TFFS_TFRS() const - { - return mt::is_TFFS_TFRS(simulation_type); - } - - bool is_PropFS_PropRS() const - { - return mt::is_PropFS_PropRS(simulation_type); - } - - bool is_grid_FS() const - { - return mt::is_grid_FS(simulation_type); - } - - bool is_grid_RS() const - { - return mt::is_grid_RS(simulation_type); - } - - bool is_simulation_type_FS() const - { - return mt::is_simulation_type_FS(simulation_type); - } - - bool is_simulation_type_RS() const - { - return mt::is_simulation_type_RS(simulation_type); - } - - bool is_specimen_required() const - { - return mt::is_specimen_required(simulation_type); - } - - bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM() const - { - return mt::is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(simulation_type); - } - - bool is_CBED_ED_EWFS_PED() const - { - return mt::is_CBED_ED_EWFS_PED(simulation_type); - } - - bool is_obj_lens_temp_spat() const - { - return mt::is_obj_lens_temp_spat(simulation_type); - } - - bool is_cond_lens_temp_spat() const - { - return mt::is_cond_lens_temp_spat(simulation_type); - } - - eSpace get_simulation_space() const - { - return mt::get_simulation_space(simulation_type); - } - - bool is_scanning() const - { - return mt::is_scanning(simulation_type); - } - - /**************************************************************************************/ - void set_incident_wave_type(eIncident_Wave_Type iw_type_i) - { - iw_type = mt::validate_incident_wave_type(simulation_type, iw_type_i); - } - - /**************************************************************************************/ - bool is_illu_mod_coherent() const - { - return illumination_model == eIM_Coherent; - } - - bool is_illu_mod_partial_coherent() const - { - return illumination_model == eIM_Partial_Coherent; - } - - bool is_illu_mod_trans_cross_coef() const - { - return illumination_model == eIM_Trans_Cross_Coef; - } - - bool is_illu_mod_full_integration() const - { - return illumination_model == eIM_Full_Integration; - } - - /**************************************************************************************/ - bool is_incoh_temporal_spatial() const - { - return temporal_spatial_incoh == eTSI_Temporal_Spatial; - } - - bool is_incoh_temporal() const - { - return temporal_spatial_incoh == eTSI_Temporal; - } - - bool is_incoh_spatial() const - { - return temporal_spatial_incoh == eTSI_Spatial; - } - - /**************************************************************************************/ - bool is_detector_circular() const - { - return detector.is_detector_circular(); - } - - bool is_detector_radial() const - { - return detector.is_detector_radial(); - } - - bool is_detector_matrix() const - { - return detector.is_detector_matrix(); - } - - /**************************************************************************************/ - bool is_slice_storage() const - { - bool slice_storage = is_PED_HCTEM() || is_EELS_EFTEM(); - slice_storage = slice_storage || is_ISTEM() || (is_STEM() && !pn_coh_contrib); - slice_storage = slice_storage || (is_CBED_CBEI() && is_illu_mod_full_integration()); - - return slice_storage; - } - - bool is_operation_mode_normal() const - { - return operation_mode == eOM_Normal; - } - - bool is_operation_mode_advanced() const - { - return operation_mode == eOM_Advanced; - } - - /**************************************************************************************/ - bool is_lvt_off() const - { - return cdl_var == eLVT_off; - } - - bool is_lvt_m() const - { - return cdl_var == eLVT_m; - } - - bool is_lvt_Cs3() const - { - return cdl_var == eLVT_Cs3; - } - - bool is_lvt_Cs5() const - { - return cdl_var == eLVT_Cs5; - } - - bool is_lvt_mfa2() const - { - return cdl_var == eLVT_mfa2; - } - - bool is_lvt_afa2() const - { - return cdl_var == eLVT_afa2; - } - - bool is_lvt_mfa3() const - { - return cdl_var == eLVT_mfa3; - } - - bool is_lvt_afa3() const - { - return cdl_var == eLVT_afa3; - } - - bool is_lvt_inner_aper_ang() const - { - return cdl_var == eLVT_inner_aper_ang; - } - - bool is_lvt_outer_aper_ang() const - { - return cdl_var == eLVT_outer_aper_ang; - } - - }; - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/input_tomography.cuh b/src/input_tomography.cuh old mode 100644 new mode 100755 index fc1987a1..96adb13a --- a/src/input_tomography.cuh +++ b/src/input_tomography.cuh @@ -1,6 +1,6 @@ /* * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato + * Copyright 2017 Ivan Lobato * * MULTEM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,10 +27,10 @@ #include "memory_info.cuh" #include "lin_alg_def.cuh" -#include "atomic_data_mt.hpp" -#include "cgpu_fcns.cuh" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" +#include "atom_data.hpp" +#include "host_device_functions.cuh" +#include "host_functions.hpp" +#include "device_functions.cuh" namespace mt { diff --git a/src/intrpl_coef.cuh b/src/intrpl_coef.cuh new file mode 100755 index 00000000..0f110d2b --- /dev/null +++ b/src/intrpl_coef.cuh @@ -0,0 +1,903 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef INTRPL_COEF_H + #define INTRPL_COEF_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + #include + + #include "const_enum.h" + #include "type_traits_gen.h" + #include "math_mt.h" + #include "r_2d.h" + #include "r_3d.h" + #include "fcns_cgpu_gen.h" + #include "cgpu_vctr.cuh" + #include "grid.h" + + /***************************************************************************************/ + /************************* linear and non-linear coefficients **************************/ + /***************************************************************************************/ + namespace mt + { + template class LNL_Coef; + + template + class pLNL_Coef + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ cl; // linear coefficient + T* __restrict__ cnl; // non-linear coefficient + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pLNL_Coef(): cl(nullptr), cnl(nullptr), m_size(0) {} + + CGPU_EXEC + pLNL_Coef(T* cl, T* cnl, const size_type& size): cl(cl), cnl(cnl), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pLNL_Coef(const pLNL_Coef& pcoef_lnl) + { + *this = pcoef_lnl; + } + + /* constructor from LNL_Coef */ + explicit pLNL_Coef(const LNL_Coef& coef_lnl) + { + *this = coef_lnl; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pLNL_Coef& operator=(const pLNL_Coef& pcoef_lnl) + { + if (this != &pcoef_lnl) + { + cl = pcoef_lnl.cl; + cnl = pcoef_lnl.cnl; + m_size = pcoef_lnl.m_size; + } + + return *this; + } + + /* Assignment operator: LNL_Coef -> pLNL_Coef */ + CPU_EXEC + pLNL_Coef& operator=(const LNL_Coef& coef_lnl) + { + cl = coef_lnl.cl.data(); + cnl = coef_lnl.cnl.data(); + m_size = size_type(coef_lnl.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pLNL_Coef_cpu = pLNL_Coef; + + template + using pLNL_Coef_gpu = pLNL_Coef; + + /***************************************************************************************/ + template + class LNL_Coef + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr cl; + mutable Vctr cnl; + + /************************************* constructors ************************************/ + LNL_Coef() {} + + LNL_Coef(const Vctr_cpu& cl, const Vctr_cpu& cnl): + cl(cl), cnl(cnl){} + + LNL_Coef(const dt_init_list_f64& cl, const dt_init_list_f64& cnl): + cl(cl), cnl(cnl) {} + + LNL_Coef(const size_type& new_size) + { + resize(new_size); + } + + LNL_Coef(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + LNL_Coef(const LNL_Coef& coef_lnl) + { + *this = coef_lnl; + } + + /* converting constructor */ + template + LNL_Coef(const LNL_Coef& coef_lnl) + { + *this = coef_lnl; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + LNL_Coef& operator=(const LNL_Coef& coef_lnl) + { + this->assign(coef_lnl); + + return *this; + } + + /* converting assignment operator */ + template + LNL_Coef& operator=(const LNL_Coef& coef_lnl) + { + this->assign(coef_lnl); + + return *this; + } + + template + void assign(const LNL_Coef& coef_lnl) + { + cl.assign(coef_lnl.cl); + cnl.assign(coef_lnl.cnl); + } + + /**************** user define conversion operators *******************/ + pLNL_Coef ptr() const + { + return pLNL_Coef(*this); + } + + /* user define conversion for pointer */ + operator pLNL_Coef() const + { + return pLNL_Coef(*this); + } + + void fill(const T& val_l, const T& val_nl) + { + cl.fill(val_l); + cnl.fill(val_nl); + } + + size_type size() const + { + return size_type(cl.size()); + } + + void clear() + { + cl.clear(); + cnl.clear(); + } + + void reserve(const size_type& new_size) + { + cl.reserve(new_size); + cnl.reserve(new_size); + } + + void resize(const size_type& new_size) + { + cl.resize(new_size); + cnl.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + cl.resize(new_size, value); + cnl.resize(new_size, value); + } + + void shrink_to_fit() + { + cl.shrink_to_fit(); + cnl.shrink_to_fit(); + } + }; + + template + using LNL_Coef_cpu = LNL_Coef; + + template + using LNL_Coef_gpu = LNL_Coef; + } + + /***************************************************************************************/ + /*************************** linear polynomial coefficients ****************************/ + /***************************************************************************************/ + namespace mt + { + template class Poly_Coef_1d; + + template + class pPoly_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ c0; + T* __restrict__ c1; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pPoly_Coef_1d(): c0(nullptr), c1(nullptr), m_size(0) {} + + CGPU_EXEC + pPoly_Coef_1d(T* c0, T* c1, const size_type& size): c0(c0), c1(c1), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pPoly_Coef_1d(const pPoly_Coef_1d& pcoef_poly1) + { + *this = pcoef_poly1; + } + + /* constructor from Poly_Coef_1d */ + explicit pPoly_Coef_1d(const Poly_Coef_1d& coef_poly1) + { + *this = coef_poly1; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pPoly_Coef_1d& operator=(const pPoly_Coef_1d& pcoef_poly1) + { + if (this != &pcoef_poly1) + { + c0 = pcoef_poly1.c0; + c1 = pcoef_poly1.c1; + m_size = pcoef_poly1.m_size; + } + + return *this; + } + + /* Assignment operator: Poly_Coef_1d -> pPoly_Coef_1d */ + CPU_EXEC + pPoly_Coef_1d& operator=(const Poly_Coef_1d& coef_poly1) + { + c0 = coef_poly1.c0.data(); + c1 = coef_poly1.c1.data(); + m_size = size_type(coef_poly1.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pPoly_Coef_1d_cpu = pPoly_Coef_1d; + + template + using pPoly_Coef_1d_gpu = pPoly_Coef_1d; + + /***************************************************************************************/ + template + class Poly_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr c0; + mutable Vctr c1; + + /************************************* constructors ************************************/ + Poly_Coef_1d() {} + + Poly_Coef_1d(const Vctr_cpu& c0, const Vctr_cpu& c1): + c0(c0), c1(c1){} + + Poly_Coef_1d(const dt_init_list_f64& c0, const dt_init_list_f64& c1): + c0(c0), c1(c1) {} + + Poly_Coef_1d(const size_type& new_size) + { + resize(new_size); + } + + Poly_Coef_1d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Poly_Coef_1d(const Poly_Coef_1d& coef_poly1) + { + *this = coef_poly1; + } + + /* converting constructor */ + template + Poly_Coef_1d(const Poly_Coef_1d& coef_poly1) + { + *this = coef_poly1; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Poly_Coef_1d& operator=(const Poly_Coef_1d& coef_poly1) + { + this->assign(coef_poly1); + + return *this; + } + + /* converting assignment operator */ + template + Poly_Coef_1d& operator=(const Poly_Coef_1d& coef_poly1) + { + this->assign(coef_poly1); + + return *this; + } + + template + void assign(const Poly_Coef_1d& coef_poly1) + { + c0.assign(coef_poly1.c0); + c1.assign(coef_poly1.c1); + } + + /**************** user define conversion operators *******************/ + pPoly_Coef_1d ptr() const + { + return pPoly_Coef_1d(*this); + } + + /* user define conversion for pointer Vctr */ + operator pPoly_Coef_1d() const + { + return pPoly_Coef_1d(*this); + } + + void fill(const T& val_c0, const T& val_c1) + { + c0.fill(val_c0); + c1.fill(val_c1); + } + + size_type size() const + { + return c0.size(); + } + + void clear() + { + c0.clear(); + c1.clear(); + } + + void reserve(const size_type& new_size) + { + c0.reserve(new_size); + c1.reserve(new_size); + } + + void resize(const size_type& new_size) + { + c0.resize(new_size); + c1.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + c0.resize(new_size, value); + c1.resize(new_size, value); + } + + void shrink_to_fit() + { + c0.shrink_to_fit(); + c1.shrink_to_fit(); + } + }; + + template + using Poly_Coef_1d_cpu = Poly_Coef_1d; + + template + using Poly_Coef_1d_gpu = Poly_Coef_1d; + } + + /***************************************************************************************/ + /************************* quadratic polynomial coefficients ***************************/ + /***************************************************************************************/ + namespace mt + { + template class Poly_Coef_2d; + + template + class pPoly_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ c0; + T* __restrict__ c1; + T* __restrict__ c2; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pPoly_Coef_2d(): c0(nullptr), c1(nullptr), c2(nullptr), m_size(0) {} + + CGPU_EXEC + pPoly_Coef_2d(T* c0, T* c1, T* c2, const size_type& size): c0(c0), c1(c1), c2(c2), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pPoly_Coef_2d(const pPoly_Coef_2d& pcoef_poly2) + { + *this = pcoef_poly2; + } + + /* constructor from Poly_Coef_2d */ + explicit pPoly_Coef_2d(const Poly_Coef_2d& coef_poly2) + { + *this = coef_poly2; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pPoly_Coef_2d& operator=(const pPoly_Coef_2d& pcoef_poly2) + { + if (this != &pcoef_poly2) + { + c0 = pcoef_poly2.c0; + c1 = pcoef_poly2.c1; + c2 = pcoef_poly2.c2; + m_size = pcoef_poly2.m_size; + } + + return *this; + } + + /* Assignment operator: Poly_Coef_2d -> pPoly_Coef_2d */ + CPU_EXEC + pPoly_Coef_2d& operator=(const Poly_Coef_2d& coef_poly2) + { + c0 = coef_poly2.c0.data(); + c1 = coef_poly2.c1.data(); + c2 = coef_poly2.c2.data(); + m_size = size_type(coef_poly2.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pPoly_Coef_2d_cpu = pPoly_Coef_2d; + + template + using pPoly_Coef_2d_gpu = pPoly_Coef_2d; + + /***************************************************************************************/ + template + class Poly_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr c0; + mutable Vctr c1; + mutable Vctr c2; + + /************************************* constructors ************************************/ + Poly_Coef_2d() {} + + Poly_Coef_2d(const Vctr_cpu& c0, const Vctr_cpu& c1, const Vctr_cpu& c2): + c0(c0), c1(c1), c2(c2){} + + Poly_Coef_2d(const dt_init_list_f64& c0, const dt_init_list_f64& c1, const dt_init_list_f64& c2): + c0(c0), c1(c1), c2(c2) {} + + Poly_Coef_2d(const size_type& new_size) + { + resize(new_size); + } + + Poly_Coef_2d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Poly_Coef_2d(const Poly_Coef_2d& coef_poly2) + { + *this = coef_poly2; + } + + /* converting constructor */ + template + Poly_Coef_2d(const Poly_Coef_2d& coef_poly2) + { + *this = coef_poly2; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Poly_Coef_2d& operator=(const Poly_Coef_2d& coef_poly2) + { + this->assign(coef_poly2); + + return *this; + } + + /* converting assignment operator */ + template + Poly_Coef_2d& operator=(const Poly_Coef_2d& coef_poly2) + { + this->assign(coef_poly2); + + return *this; + } + + template + void assign(const Poly_Coef_2d& coef_poly2) + { + c0.assign(coef_poly2.c0); + c1.assign(coef_poly2.c1); + c2.assign(coef_poly2.c2); + } + + /**************** user define conversion operators *******************/ + pPoly_Coef_2d ptr() const + { + return pPoly_Coef_2d(*this); + } + + /* user define conversion for pointer Vctr */ + operator pPoly_Coef_2d() const + { + return pPoly_Coef_2d(*this); + } + + void fill(const T& val_c0, const T& val_c1, const T& val_c2) + { + c0.fill(val_c0); + c1.fill(val_c1); + c2.fill(val_c2); + } + + size_type size() const + { + return c0.size(); + } + + void clear() + { + c0.clear(); + c1.clear(); + c2.clear(); + } + + void reserve(const size_type& new_size) + { + c0.reserve(new_size); + c1.reserve(new_size); + c2.reserve(new_size); + } + + void resize(const size_type& new_size) + { + c0.resize(new_size); + c1.resize(new_size); + c2.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + c0.resize(new_size, value); + c1.resize(new_size, value); + c2.resize(new_size, value); + } + + void shrink_to_fit() + { + c0.shrink_to_fit(); + c1.shrink_to_fit(); + c2.shrink_to_fit(); + } + }; + + template + using Poly_Coef_2d_cpu = Poly_Coef_2d; + + template + using Poly_Coef_2d_gpu = Poly_Coef_2d; + } + + /***************************************************************************************/ + /************************** cubic interpolation coefficients ***************************/ + /***************************************************************************************/ + namespace mt + { + template class Poly_Coef_3d; + + template + class pPoly_Coef_3d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ c0; + T* __restrict__ c1; + T* __restrict__ c2; + T* __restrict__ c3; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pPoly_Coef_3d(): c0(nullptr), c1(nullptr), c2(nullptr), c3(nullptr), m_size(0) {} + + CGPU_EXEC + pPoly_Coef_3d(T* c0, T* c1, T* c2, T* c3, const size_type& size): c0(c0), c1(c1), c2(c2), c3(c3), m_size(size) {} + + /* copy constructor */ + CGPU_EXEC + pPoly_Coef_3d(const pPoly_Coef_3d& pcoef_poly3) + { + *this = pcoef_poly3; + } + + /* constructor from Poly_Coef_3d */ + explicit pPoly_Coef_3d(const Poly_Coef_3d& coef_poly3) + { + *this = coef_poly3; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pPoly_Coef_3d& operator=(const pPoly_Coef_3d& pcoef_poly3) + { + if (this != &pcoef_poly3) + { + c0 = pcoef_poly3.c0; + c1 = pcoef_poly3.c1; + c2 = pcoef_poly3.c2; + c3 = pcoef_poly3.c3; + m_size = pcoef_poly3.m_size; + } + + return *this; + } + + /* Assignment operator: Poly_Coef_3d -> pPoly_Coef_3d */ + CPU_EXEC + pPoly_Coef_3d& operator=(const Poly_Coef_3d& coef_poly3) + { + c0 = coef_poly3.c0.data(); + c1 = coef_poly3.c1.data(); + c2 = coef_poly3.c2.data(); + c3 = coef_poly3.c3.data(); + m_size = size_type(coef_poly3.size()); + + return *this; + } + + size_type size() const + { + return m_size; + } + }; + + template + using pPoly_Coef_3d_cpu = pPoly_Coef_3d; + + template + using pPoly_Coef_3d_gpu = pPoly_Coef_3d; + + /***************************************************************************************/ + template + class Poly_Coef_3d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr c0; + mutable Vctr c1; + mutable Vctr c2; + mutable Vctr c3; + + /************************************* constructors ************************************/ + Poly_Coef_3d() {} + + Poly_Coef_3d(const Vctr_cpu& c0, const Vctr_cpu& c1, const Vctr_cpu& c2, const Vctr_cpu& c3): + c0(c0), c1(c1), c2(c2), c3(c3){} + + Poly_Coef_3d(const dt_init_list_f64& c0, const dt_init_list_f64& c1, const dt_init_list_f64& c2, const dt_init_list_f64& c3): + c0(c0), c1(c1), c2(c2), c3(c3) {} + + Poly_Coef_3d(const size_type& new_size) + { + resize(new_size); + } + + Poly_Coef_3d(const size_type& new_size, const T& value) + { + resize(new_size, value); + } + + /* copy constructor */ + Poly_Coef_3d(const Poly_Coef_3d& coef_poly3) + { + *this = coef_poly3; + } + + /* converting constructor */ + template + Poly_Coef_3d(const Poly_Coef_3d& coef_poly3) + { + *this = coef_poly3; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Poly_Coef_3d& operator=(const Poly_Coef_3d& coef_poly3) + { + this->assign(coef_poly3); + + return *this; + } + + /* converting assignment operator */ + template + Poly_Coef_3d& operator=(const Poly_Coef_3d& coef_poly3) + { + this->assign(coef_poly3); + + return *this; + } + + template + void assign(const Poly_Coef_3d& coef_poly3) + { + c0.assign(coef_poly3.c0); + c1.assign(coef_poly3.c1); + c2.assign(coef_poly3.c2); + c3.assign(coef_poly3.c3); + } + + /**************** user define conversion operators *******************/ + pPoly_Coef_3d ptr() const + { + return pPoly_Coef_3d(*this); + } + + /* user define conversion for pointer Vctr */ + operator pPoly_Coef_3d() const + { + return pPoly_Coef_3d(*this); + } + + void fill(const T& val_c0, const T& val_c1, const T& val_c2, const T& val_c3) + { + c0.fill(val_c0); + c1.fill(val_c1); + c2.fill(val_c2); + c3.fill(val_c3); + } + + size_type size() const + { + return c0.size(); + } + + void clear() + { + c0.clear(); + c1.clear(); + c2.clear(); + c3.clear(); + } + + void reserve(const size_type& new_size) + { + c0.reserve(new_size); + c1.reserve(new_size); + c2.reserve(new_size); + c3.reserve(new_size); + } + + void resize(const size_type& new_size) + { + c0.resize(new_size); + c1.resize(new_size); + c2.resize(new_size); + c3.resize(new_size); + } + + void resize(const size_type& new_size, const T& value) + { + c0.resize(new_size, value); + c1.resize(new_size, value); + c2.resize(new_size, value); + c3.resize(new_size, value); + } + + void shrink_to_fit() + { + c0.shrink_to_fit(); + c1.shrink_to_fit(); + c2.shrink_to_fit(); + c3.shrink_to_fit(); + } + }; + + template + using Poly_Coef_3d_cpu = Poly_Coef_3d; + + template + using Poly_Coef_3d_gpu = Poly_Coef_3d; + } +#endif \ No newline at end of file diff --git a/src/ithread_rect_1d.h b/src/ithread_rect_1d.h new file mode 100755 index 00000000..7af9f675 --- /dev/null +++ b/src/ithread_rect_1d.h @@ -0,0 +1,122 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ +#pragma once + +#include "const_enum.h" + +/* forward declaration */ +namespace mt +{ + template class iThread_Rect_sxd; + + template + using iThread_Rect_xd = iThread_Rect_sxd; +} + +/* derived class */ +namespace mt +{ + template + using iThread_Rect_1d_st = iThread_Rect_sxd; + + using iThread_Rect_1d = iThread_Rect_sxd; + + using iThread_Rect_1d_64 = iThread_Rect_sxd; +} + +/* template specialization 1d */ +namespace mt +{ + template + class iThread_Rect_sxd + { + public: + using size_type = ST; + + ST ind_0; // initial linear index + ST ind_e; // final linear index + + ST ix_0; // x initial index + ST ix_e; // x final index + + dt_int32 istm; // stream number + + /************************************* constructors ************************************/ + iThread_Rect_sxd(); + + iThread_Rect_sxd(const dt_init_list_int32& list); + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e); + + iThread_Rect_sxd(const ST& nx); + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& ind_0, const ST& ind_e); + + /* copy constructor */ + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread); + + /* converting constructor */ + template + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread); + + /* converting assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread); + + template + CGPU_EXEC + void assign(const iThread_Rect_sxd& ithread); + + /***************************************************************************************/ + CGPU_EXEC + void clear(); + + CGPU_EXEC + ST nx() const; + + CGPU_EXEC + ST size() const; + + CGPU_EXEC + dt_bool chk_bound_ix(const ST& ix) const; + + CGPU_EXEC + dt_bool chk_bound(const ST& ix) const; + + CGPU_EXEC + void apply_bound_ix(const ST& ix_0, const ST& ix_e); + + CGPU_EXEC + ST sub_2_ind(const ST& ix) const; + + CGPU_EXEC + void set_ind(const ST& ind_0, const ST& ind_e); + + void set_ind_asc_order(); + }; +} + +#include "detail/ithread_rect_1d.inl" \ No newline at end of file diff --git a/src/ithread_rect_2d.h b/src/ithread_rect_2d.h new file mode 100755 index 00000000..731eaf57 --- /dev/null +++ b/src/ithread_rect_2d.h @@ -0,0 +1,105 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ +#pragma once + +#include "ithread_rect_1d.h" + +/* derived class */ +namespace mt +{ + template + using iThread_Rect_2d_st = iThread_Rect_sxd; + + using iThread_Rect_2d = iThread_Rect_sxd; + + using iThread_Rect_2d_64 = iThread_Rect_sxd; +} + +/* template specialization 2d */ +namespace mt +{ + template + class iThread_Rect_sxd: public iThread_Rect_sxd + { + public: + using size_type = ST; + + ST iy_0; // y initial index + ST iy_e; // y final index + + /************************************* constructors ************************************/ + iThread_Rect_sxd(); + + iThread_Rect_sxd(const dt_init_list_int32& list); + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e); + + iThread_Rect_sxd(const ST& nx, const ST& ny); + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& ind_0, const ST& ind_e); + + /* copy constructor */ + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread); + + /* converting constructor */ + template + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread); + + /* converting assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread); + + template + CGPU_EXEC + void assign(const iThread_Rect_sxd& ithread); + + /***************************************************************************************/ + CGPU_EXEC + void clear(); + + CGPU_EXEC + ST ny() const; + + CGPU_EXEC + ST size() const; + + CGPU_EXEC + dt_bool chk_bound_iy(const ST& iy) const; + + CGPU_EXEC + dt_bool chk_bound(const ST& ix, const ST& iy) const; + + CGPU_EXEC + void apply_bound_iy(const ST& iy_0, const ST& iy_e); + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy) const; + + void set_ind_asc_order(); + }; +} + +#include "detail/ithread_rect_2d.inl" \ No newline at end of file diff --git a/src/ithread_rect_3d.h b/src/ithread_rect_3d.h new file mode 100755 index 00000000..2e5303a7 --- /dev/null +++ b/src/ithread_rect_3d.h @@ -0,0 +1,105 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ +#pragma once + +#include "ithread_rect_2d.h" + +/* derived class */ +namespace mt +{ + template + using iThread_Rect_3d_st = iThread_Rect_sxd; + + using iThread_Rect_3d = iThread_Rect_sxd; + + using iThread_Rect_3d_64 = iThread_Rect_sxd; +} + +/* template specialization 3d */ +namespace mt +{ + template + class iThread_Rect_sxd: public iThread_Rect_sxd + { + public: + using size_type = ST; + + ST iz_0; // z initial index + ST iz_e; // z final index + + /************************************* constructors ************************************/ + iThread_Rect_sxd(); + + iThread_Rect_sxd(const dt_init_list_int32& list); + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& iz_0, const ST& iz_e); + + iThread_Rect_sxd(const ST& nx, const ST& ny, const ST& nz); + + iThread_Rect_sxd(const ST& ix_0, const ST& ix_e, const ST& iy_0, const ST& iy_e, const ST& iz_0, const ST& iz_e, const ST& ind_0, const ST& ind_e); + + /* copy constructor */ + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread); + + /* converting constructor */ + template + CGPU_EXEC + iThread_Rect_sxd(const iThread_Rect_sxd& ithread); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread); + + /* converting assignment operator */ + template + CGPU_EXEC + iThread_Rect_sxd& operator=(const iThread_Rect_sxd& ithread); + + template + CGPU_EXEC + void assign(const iThread_Rect_sxd& ithread); + + /***************************************************************************************/ + CGPU_EXEC + void clear(); + + CGPU_EXEC + ST nz() const; + + CGPU_EXEC + ST size() const; + + CGPU_EXEC + dt_bool chk_bound_iz(const ST& iz) const; + + CGPU_EXEC + dt_bool chk_bound(const ST& ix, const ST& iy, const ST& iz) const; + + CGPU_EXEC + void apply_bound_iz(const ST& iz_0, const ST& iz_e); + + CGPU_EXEC + ST sub_2_ind(const ST& ix, const ST& iy, const ST& iz) const; + + void set_ind_asc_order(); + }; +} + +#include "detail/ithread_rect_3d.inl" \ No newline at end of file diff --git a/src/kahan_sum.h b/src/kahan_sum.h new file mode 100755 index 00000000..e68259d7 --- /dev/null +++ b/src/kahan_sum.h @@ -0,0 +1,110 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" + +/***************************************************************************************/ +/**************************** Kahan summation algorithm ********************************/ +/* https:// en.wikipedia.org/wiki/Kahan_summation_algorithmnnn */ +/***************************************************************************************/ +namespace mt +{ + template + class KS + { + public: + using value_type = T; + + T m_sum; + T m_error; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + KS(); + + /* Copy constructor */ + CGPU_EXEC + KS(const T& sum, T error=0); + + /* Copy constructor */ + CGPU_EXEC + KS(const KS& ks); + + /* Move constructor */ + CGPU_EXEC + KS(KS&& ks); + + /* converting copy constructor */ + template + CGPU_EXEC + KS(const KS& ks); + + /******************************** assignment operators *********************************/ + /* constructor from r */ + CGPU_EXEC + KS& operator=(const T& r); + + /* copy assignment operator */ + CGPU_EXEC + KS& operator=(const KS& ks); + + /* Move assignment operator */ + CGPU_EXEC + KS& operator=(KS&& ks); + + /* converting assignment operator */ + template + CGPU_EXEC + KS& operator=(const KS& ks); + + // user define conversion + CGPU_EXEC + T operator()(); + + // user define conversion + CGPU_EXEC + operator T(); + + /******************* Compound assignment operators *******************/ + CGPU_EXEC + KS& operator+=(T r); + + CGPU_EXEC + KS& operator+=(const KS& r); + + CGPU_EXEC + KS& operator-=(T r); + + CGPU_EXEC + KS& operator-=(const KS& r); + + CGPU_EXEC + KS& operator/=(T r); + + CGPU_EXEC + KS& operator/=(const KS& r); + + CGPU_EXEC + void add(T r); + }; +} + +#include "detail/kahan_sum.inl" \ No newline at end of file diff --git a/src/lapack.hpp b/src/lapack.hpp old mode 100644 new mode 100755 index a341c446..bccc2b2b --- a/src/lapack.hpp +++ b/src/lapack.hpp @@ -1,416 +1,812 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef LAPACK_H -#define LAPACK_H - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" - -namespace lapack -{ - extern "C" void sgesv_( - const int* n, - const int* nrhs, - float* a, - const int* lda, - int* ipiv, - float* b, - const int* ldb, - int* info - ); - - extern "C" void dgesv_( - const int* n, - const int* nrhs, - double* a, - const int* lda, - int* ipiv, - double* b, - const int* ldb, - int* info - ); - - extern "C" void sgels_( - const char *trans, - const int *m, - const int *n, - const int *nrhs, - float *a, - const int *lda, - float *b, - const int *ldb, - float *work, - const int *lwork, - int *info - ); - - extern "C" void dgels_( - const char *trans, - const int *m, - const int *n, - const int *nrhs, - double *a, - const int *lda, - double *b, - const int *ldb, - double *work, - const int *lwork, - int *info - ); - - extern "C" void sgelsd_( - const int *m, - const int *n, - const int *nrhs, - const float *a, - const int *lda, - float *b, - const int *ldb, - float *s, - const float *rcond, - int *rank, - float *work, - const int *lwork, - int *iwork, - int *info - ); - - extern "C" void dgelsd_( - const int *m, - const int *n, - const int *nrhs, - const double *a, - const int *lda, - double *b, - const int *ldb, - double *s, - const double *rcond, - int *rank, - double *work, - const int *lwork, - int *iwork, - int *info - ); - /* Fast least square fitting */ - template - struct FLSF - { - public: - using value_type = T; - - const mt::eDevice device; - - FLSF(): device(mt::e_host) {} - - void operator()(int A_rows, int A_cols, T *A, T *b, T *x) - { - using TVector = vector; - - // get ATA - TVector M; - M.reserve(A_cols*A_cols); - - for(auto ir=0; ir ipiv(n); - - gesv(n, nrhs, M.data(), lda, ipiv.data(), y.data(), ldb, info); - std::copy(y.begin(), y.end(), x); - } - - void operator()(int A_rows, int A_cols, T *A, T *b, T *x, T lambda, T *D, T *G) - { - using TVector = vector; - - // get ATA - TVector M; - M.reserve(A_cols*A_cols); - - for(auto ir=0; ir ipiv(n); - - gesv(n, nrhs, M.data(), lda, ipiv.data(), y.data(), ldb, info); - std::copy(y.begin(), y.end(), x); - } - - private: - void gesv(const int &n, const int &nrhs, float *a, const int &lda, - int *ipiv, float *b, const int &ldb, int &info) - { - sgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); - } - - void gesv(const int &n, const int &nrhs, double *a, const int &lda, - int *ipiv, double *b, const int &ldb, int &info) - { - dgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); - } - - vector ipiv; - vector M; - vector y; - }; - - /* The program computes the solution to the system of linear - equations with a square matrix A and multiple right-hand - sides B, where A is the coefficient matrix and b is the - right-hand side matrix: - */ - template - struct GESV - { - public: - using value_type = T; - - const mt::eDevice device; - - GESV(): device(mt::e_host) {} - - void operator()(int A_n, T *A, int b_cols, T *b, T *x) - { - int n = A_n; - int nrhs = b_cols; - int lda = n; - int ldb = n; - int info = 0; - - std::copy(b, b+n, x); - ipiv.resize(n); - - gesv(n, nrhs, A, lda, ipiv.data(), x, ldb, info); - } - - private: - void gesv(const int &n, const int &nrhs, float *a, const int &lda, - int *ipiv, float *b, const int &ldb, int &info) - { - sgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); - } - - void gesv(const int &n, const int &nrhs, double *a, const int &lda, - int *ipiv, double *b, const int &ldb, int &info) - { - dgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); - } - - vector ipiv; - }; - - /* The program solves overdetermined or underdetermined real - linear systems involving an M-by-N matrix A, or its trs, - using a QR or LQ factorization of A. It is assumed that A has full rank. - */ - template - struct GELS - { - public: - using value_type = T; - - const mt::eDevice device; - - GELS(): device(mt::e_host) {} - - void operator()(int A_rows, int A_cols, T *A, int b_cols, T *b, T *x) - { - const char trans = 'N'; - int m = A_rows; - int n = A_cols; - int nrhs = b_cols; - int lda = A_rows; - int ldb = max(b_cols, max(m, n)); - int min_mn = min(m, n); - T rcond = -1; - int info = 0; - - mt::Vector bv(b, b+m*b_cols); - - // query optimal size of work array - int lwork = -1; - T work_query= 0; - gels(trans, m, n, nrhs, A, lda, bv.data(), ldb, &work_query, lwork, info); - - // set arrays - lwork = max(1, int(work_query)); - work.resize(lwork); - - // perform minimum-norm solution - gels(trans, m, n, nrhs, A, lda, bv.data(), ldb, work.data(), lwork, info); - - for(auto ix=0; ix work; - }; - - template - struct GELSD - { - public: - using value_type = T; - - const mt::eDevice device; - - GELSD(): device(mt::e_host) {} - - void operator()(int A_rows, int A_cols, T *A, int b_cols, T *b, T *x) - { - int m = A_rows; - int n = A_cols; - int nrhs = b_cols; - int lda = A_rows; - int ldb = max(b_cols, max(m, n)); - int min_mn = min(m, n); - int rank = 0; - T rcond = -1; - int info = 0; - - mt::Vector bv(b, b+m*b_cols); - S.resize(min_mn); - - // query optimal size of work array - int lwork = -1; - T work_query= 0; - int iwork_query= 0; - gelsd(m, n, nrhs, A, lda, bv.data(), ldb, S.data(), rcond, rank, &work_query, lwork, &iwork_query, info); - - // set arrays - lwork = max(1, int(work_query)); - work.resize(lwork); - - int liwork = max(1, iwork_query); - iwork.resize(liwork); - - // perform minimum-norm solution - gelsd(m, n, nrhs, A, lda, bv.data(), ldb, S.data(), rcond, rank, work.data(), lwork, iwork.data(), info); - - for(auto ix= 0; ix iwork; - mt::Vector work; - mt::Vector S; - }; -} // namespace lapack - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef LAPACK_H + #define LAPACK_H + + #ifdef _MSC_VER + #pragma once + #endif + + #if defined(_WIN32) && defined(MATLAB_BLAS_LAPACK) + #define ssyevr_ ssyevr + #define dsyevr_ dsyevr + #define sgesv_ sgesv + #define dgesv_ dgesv + #define sgels_ sgels + #define dgels_ dgels + #define sgelsd_ sgelsd + #define dgelsd_ dgelsd + #endif + + #include "macros.h" + #include "math_mt.h" + #include "type_traits_gen.h" + #include "types.cuh" + #include "cgpu_vctr.cuh" + + namespace lapack + { + extern "C" void ssyevr_( + const char* jobz, + const char* range, + const char* uplo, + const MTL_BL_INT* n, + dt_float32* a, + const MTL_BL_INT* lda, + const dt_float32* vl, + const dt_float32* vu, + const MTL_BL_INT* il, + const MTL_BL_INT* iu, + const dt_float32* abstol, + MTL_BL_INT* m, + dt_float32* w, + dt_float32* z, + const MTL_BL_INT* ldz, + MTL_BL_INT* isuppz, + dt_float32* work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + const MTL_BL_INT* liwork, + MTL_BL_INT* info + ); + + extern "C" void dsyevr_( + const char* jobz, + const char* range, + const char* uplo, + const MTL_BL_INT* n, + dt_float64* a, + const MTL_BL_INT* lda, + const dt_float64* vl, + const dt_float64* vu, + const MTL_BL_INT* il, + const MTL_BL_INT* iu, + const dt_float64* abstol, + MTL_BL_INT* m, + dt_float64* w, + dt_float64* z, + const MTL_BL_INT* ldz, + MTL_BL_INT* isuppz, + dt_float64* work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + const MTL_BL_INT* liwork, + MTL_BL_INT* info + ); + + extern "C" void sgesv_( + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float32* a, + const MTL_BL_INT* lda, + MTL_BL_INT* ipiv, + dt_float32* b, + const MTL_BL_INT* ldb, + MTL_BL_INT* info + ); + + extern "C" void dgesv_( + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float64* a, + const MTL_BL_INT* lda, + MTL_BL_INT* ipiv, + dt_float64* b, + const MTL_BL_INT* ldb, + MTL_BL_INT* info + ); + + extern "C" void sgels_( + const char *trans, + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float32 *a, + const MTL_BL_INT* lda, + dt_float32 *b, + const MTL_BL_INT* ldb, + dt_float32 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* info + ); + + extern "C" void dgels_( + const char *trans, + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + dt_float64 *a, + const MTL_BL_INT* lda, + dt_float64 *b, + const MTL_BL_INT* ldb, + dt_float64 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* info + ); + + extern "C" void sgelsd_( + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + const dt_float32 *a, + const MTL_BL_INT* lda, + dt_float32 *b, + const MTL_BL_INT* ldb, + dt_float32 *s, + const dt_float32 *rcond, + MTL_BL_INT* rank, + dt_float32 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + MTL_BL_INT* info + ); + + extern "C" void dgelsd_( + const MTL_BL_INT* m, + const MTL_BL_INT* n, + const MTL_BL_INT* nrhs, + const dt_float64 *a, + const MTL_BL_INT* lda, + dt_float64 *b, + const MTL_BL_INT* ldb, + dt_float64 *s, + const dt_float64 *rcond, + MTL_BL_INT* rank, + dt_float64 *work, + const MTL_BL_INT* lwork, + MTL_BL_INT* iwork, + MTL_BL_INT* info + ); + + /* computes eigenvalue of a real symmetric matrix A */ + template + struct EIGR + { + public: + using value_type = T; + + const mt::eDev device; + + EIGR(): jobz('N'), range('I'), uplo('U'), n(0), lda(0), vl(0), vu(0), + il(1), iu(1), abstol(0), m(0), ldz(0), lwork(0), liwork(0), info(0), device(mt::edev_cpu) {} + + EIGR(MTL_BL_INT n_i): jobz('N'), range('I'), uplo('U'), n(n_i), lda(0), vl(0), vu(0), + il(1), iu(1), abstol(0), m(0), ldz(0), lwork(0), liwork(0), info(0), device(mt::edev_cpu) + { + init(n_i); + } + + // get eigenvalues + T operator()(T* AS, MTL_BL_INT idx=1) + { + il = max(1, idx); + iu = min(n, idx); + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + return w[0]; + } + + // get min eigenvalue + T eig_min(T* AS) + { + il = 1; + iu = 1; + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + return w[0]; + } + + // get max eigenvalue + T eig_max(T* AS) + { + il = n; + iu = n; + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + return w[0]; + } + + // get max eigenvalue + void eig_min_max(T* AS, T& eig_min, T& eig_max) + { + il = 1; + iu = n; + + std::copy(AS, AS+n*n, MS.begin()); + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), work.data(), lwork, iwork.data(), liwork, info); + + eig_min = w[0]; + eig_max = w[n-1]; + } + + void init(MTL_BL_INT n_i) + { + n = n_i; + lda = n; + vl = 0.0; + vu = 0.0; + il = 1; + iu = 1; + abstol = -1; + ldz = n; + + // (n*n-n)/2+n + MS.resize(n*n); + w.resize(n); + z.resize(n*n); + isuppz.resize(2*n); + + // query optimal size of work array + lwork = -1; + liwork = -1; + T work_query = 0; + MTL_BL_INT iwork_query = 0; + syevr_c(jobz, range, uplo, n, MS.data(), lda, vl, vu, il, iu, abstol, m, w.data(), z.data(), ldz, isuppz.data(), &work_query, lwork, &iwork_query, liwork, info); + + // set arrays + lwork = max(1, MTL_BL_INT(work_query)); + work.resize(lwork); + + liwork = max(1, iwork_query); + iwork.resize(liwork); + } + + private: + void syevr_c(const char &jobz, const char &range, const char &uplo, const MTL_BL_INT& n, dt_float32 *a, + const MTL_BL_INT& lda, const dt_float32 &vl, const dt_float32 &vu, const MTL_BL_INT& il, const MTL_BL_INT& iu, + const dt_float32 &abstol, MTL_BL_INT& m, dt_float32 *w, dt_float32 *z, const MTL_BL_INT& ldz, MTL_BL_INT* isuppz, dt_float32 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, const MTL_BL_INT& liwork, MTL_BL_INT& info) + { + ssyevr_(&jobz, &range, &uplo, &n, a, &lda, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info); + } + + void syevr_c(const char &jobz, const char &range, const char &uplo, const MTL_BL_INT& n, dt_float64 *a, + const MTL_BL_INT& lda, const dt_float64 &vl, const dt_float64 &vu, const MTL_BL_INT& il, const MTL_BL_INT& iu, + const dt_float64 &abstol, MTL_BL_INT& m, dt_float64 *w, dt_float64 *z, const MTL_BL_INT& ldz, MTL_BL_INT* isuppz, dt_float64 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, const MTL_BL_INT& liwork, MTL_BL_INT& info) + { + dsyevr_(&jobz, &range, &uplo, &n, a, &lda, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info); + } + + char jobz; + char range; + char uplo; + mt::Vctr_cpu MS; + MTL_BL_INT n; + MTL_BL_INT lda; + T vl; + T vu; + MTL_BL_INT il; + MTL_BL_INT iu; + T abstol; + MTL_BL_INT m; + mt::Vctr_cpu w; + mt::Vctr_cpu z; + MTL_BL_INT ldz; + mt::Vctr_cpu isuppz; + mt::Vctr_cpu work; + MTL_BL_INT lwork; + mt::Vctr_cpu iwork; + MTL_BL_INT liwork; + MTL_BL_INT info; + }; + + /* Fast least square fitting */ + template + struct LSF_1 + { + public: + using value_type = T; + + const mt::eDev device; + + LSF_1(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, T* b, T* x) + { + using TVctr = mt::Vctr_cpu; + + // get ATA + TVctr M; + M.reserve(A_cols*A_cols); + + for(auto ir=0; ir ipiv(n); + + gesv_c(n, nrhs, M.data(), lda, ipiv.data(), y.data(), ldb, info); + std::copy(y.begin(), y.end(), x); + } + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, T* b, T* x, T lambda, T* D, T* G) + { + using TVctr = mt::Vctr_cpu; + + // get ATA + TVctr M; + M.reserve(A_cols*A_cols); + + for(auto ir=0; ir ipiv(n); + + gesv_c(n, nrhs, M.data(), lda, ipiv.data(), y.data(), ldb, info); + std::copy(y.begin(), y.end(), x); + } + + private: + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float32 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + sgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float64 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + dgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + mt::Vctr_cpu ipiv; + mt::Vctr_cpu M; + mt::Vctr_cpu y; + }; + + /* RQ minimum-norm solution */ + template + struct MNS_QR + { + public: + using value_type = T; + + const mt::eDev device; + + MNS_QR(): trans('N'), info(0), lwork(-1), m(0), n(0), device(mt::edev_cpu) {} + + MNS_QR(MTL_BL_INT A_rows, MTL_BL_INT A_cols): trans('N'), info(0), lwork(-1), m(A_rows), n(A_cols), device(mt::edev_cpu) + { + init(A_rows, A_cols); + } + + void operator()(T* A, T* b, T* x) + { + MTL_BL_INT nrhs = 1; + MTL_BL_INT lda = n; + MTL_BL_INT ldb = n; + + std::copy(A, A+m*n, M.begin()); + std::copy(b, b+n, y.begin()); + + // perform minimum-norm solution + gels_c(trans, m, n, nrhs, M.data(), lda, y.data(), ldb, work.data(), lwork, info); + std::copy(y.begin(), y.end(), x); + } + + T operator()(T* A, T* b, T* x, T lambda) + { + MTL_BL_INT nrhs = 1; + MTL_BL_INT lda = n; + MTL_BL_INT ldb = n; + + std::copy(A, A+m*n, M.begin()); + std::copy(b, b+n, y.begin()); + + // get lambda and get maximum gradient + T G_max = 0; + for(auto ic=0; ic(1, MTL_BL_INT(work_query)); + work.resize(lwork); + } + + private: + void gels_c(const char &trans, const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, + const MTL_BL_INT& lda, dt_float32 *b, const MTL_BL_INT& ldb, dt_float32 *work, const MTL_BL_INT& lwork, MTL_BL_INT& info) + { + sgels_(&trans, &m, &n, &nrhs, a, &lda, b, &ldb, work, &lwork, &info); + } + + void gels_c(const char &trans, const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, + const MTL_BL_INT& lda, dt_float64 *b, const MTL_BL_INT& ldb, dt_float64 *work, const MTL_BL_INT& lwork, MTL_BL_INT& info) + { + dgels_(&trans, &m, &n, &nrhs, a, &lda, b, &ldb, work, &lwork, &info); + } + + const char trans; + MTL_BL_INT info; + MTL_BL_INT lwork; + MTL_BL_INT m; + MTL_BL_INT n; + mt::Vctr_cpu work; + + mt::Vctr_cpu M; + mt::Vctr_cpu y; + }; + + /* SVD minimum-norm solution */ + template + struct MNS_SVD + { + public: + using value_type = T; + + const mt::eDev device; + + MNS_SVD(): rcond(-1), info(0), rank(0), lwork(-1), m(0), n(0), device(mt::edev_cpu) {} + MNS_SVD(MTL_BL_INT A_rows, MTL_BL_INT A_cols): rcond(-1), info(0), rank(0), lwork(-1), m(A_rows), n(A_cols), device(mt::edev_cpu) + { + init(A_rows, A_cols); + } + + void operator()(T* A, T* b, T* x) + { + std::copy(A, A+m*n, M.begin()); + std::copy(b, b+n, y.begin()); + + // perform minimum-norm solution + gelsd_c(m, n, nrhs, M.data(), lda, y.data(), ldb, S.data(), rcond, rank, work.data(), lwork, iwork.data(), info); + std::copy(y.begin(), y.end(), x); + } + + void init(MTL_BL_INT A_rows, MTL_BL_INT A_cols) + { + m = A_rows; + n = A_cols; + + nrhs = 1; + lda = n; + ldb = n; + + S.resize(n); + M.resize(m*n); + y.resize(n); + + // query optimal size of work array + lwork = -1; + T work_query = 0; + MTL_BL_INT iwork_query = 0; + gelsd_c(m, n, nrhs, M.data(), lda, y.data(), ldb, S.data(), rcond, rank, &work_query, lwork, &iwork_query, info); + + // set arrays + lwork = max(1000, MTL_BL_INT(work_query)); + work.resize(lwork); + + liwork = max(1, iwork_query); + iwork.resize(liwork); + } + + private: + void gelsd_c(const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, const MTL_BL_INT& lda, + dt_float32 *b, const MTL_BL_INT& ldb, dt_float32 *s, const dt_float32 &rcond, MTL_BL_INT& rank, dt_float32 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, MTL_BL_INT& info) + { + sgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work, &lwork, iwork, &info); + } + + void gelsd_c(const MTL_BL_INT& m, const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, const MTL_BL_INT& lda, + dt_float64 *b, const MTL_BL_INT& ldb, dt_float64 *s, const dt_float64 &rcond, MTL_BL_INT& rank, dt_float64 *work, + const MTL_BL_INT& lwork, MTL_BL_INT* iwork, MTL_BL_INT& info) + { + dgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work, &lwork, iwork, &info); + } + + MTL_BL_INT m; + MTL_BL_INT n; + MTL_BL_INT nrhs; + MTL_BL_INT lda; + MTL_BL_INT ldb; + T rcond; + MTL_BL_INT info; + MTL_BL_INT rank; + MTL_BL_INT liwork; + MTL_BL_INT lwork; + mt::Vctr_cpu iwork; + mt::Vctr_cpu work; + mt::Vctr_cpu S; + + mt::Vctr_cpu M; + mt::Vctr_cpu y; + }; + + /* The program computes the solution to the system of linear + equations with a square matrix A and multiple right-hand + sides B, where A is the coefficient matrix and b is the + right-hand side matrix: + */ + + template + struct GESV + { + public: + using value_type = T; + + const mt::eDev device; + + GESV(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_n, T* A, MTL_BL_INT b_cols, T* b, T* x) + { + MTL_BL_INT n = A_n; + MTL_BL_INT nrhs = b_cols; + MTL_BL_INT lda = n; + MTL_BL_INT ldb = n; + MTL_BL_INT info = 0; + + std::copy(b, b+n, x); + ipiv.resize(n); + + gesv_c(n, nrhs, A, lda, ipiv.data(), x, ldb, info); + } + + private: + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float32 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float32 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + sgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + void gesv_c(const MTL_BL_INT& n, const MTL_BL_INT& nrhs, dt_float64 *a, const MTL_BL_INT& lda, + MTL_BL_INT* ipiv, dt_float64 *b, const MTL_BL_INT& ldb, MTL_BL_INT& info) + { + dgesv_(&n, &nrhs, a, &lda, ipiv, b, &ldb, &info); + } + + mt::Vctr_cpu ipiv; + }; + + /* The program solves overdetermined or underdetermined real + linear systems involving an M-by-N matrix A, or its trs, + using a QR or LQ factorization of A. It is assumed that A has full rank. + */ + template + struct GELS + { + public: + using value_type = T; + + const mt::eDev device; + + GELS(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, MTL_BL_INT b_cols, T* b, T* x) + { + const char trans = 'N'; + MTL_BL_INT m = A_rows; + MTL_BL_INT n = A_cols; + MTL_BL_INT nrhs = b_cols; + MTL_BL_INT lda = A_rows; + MTL_BL_INT ldb = max(b_cols, max(m, n)); + MTL_BL_INT min_mn = min(m, n); + T rcond = -1; + MTL_BL_INT info = 0; + + mt::Vctr bv(b, b+m*b_cols); + + // query optimal size of work array + MTL_BL_INT lwork = -1; + T work_query= 0; + gels_c(trans, m, n, nrhs, A, lda, bv.data(), ldb, &work_query, lwork, info); + + // set arrays + lwork = max(1, MTL_BL_INT(work_query)); + work.resize(lwork); + + // perform minimum-norm solution + gels_c(trans, m, n, nrhs, A, lda, bv.data(), ldb, work.data(), lwork, info); + + for(auto ix = 0; ix work; + }; + + /* The program solves overdetermined or underdetermined real + linear systems involving an M-by-N matrix A, or its trs, + using the singular value decomposition (SVD) of A. A is an m-by-n matrix which may be rank-deficient. + */ + template + struct GELSD + { + public: + using value_type = T; + + const mt::eDev device; + + GELSD(): device(mt::edev_cpu) {} + + void operator()(MTL_BL_INT A_rows, MTL_BL_INT A_cols, T* A, MTL_BL_INT b_cols, T* b, T* x) + { + MTL_BL_INT m = A_rows; + MTL_BL_INT n = A_cols; + MTL_BL_INT nrhs = b_cols; + MTL_BL_INT lda = A_rows; + MTL_BL_INT ldb = max(b_cols, max(m, n)); + MTL_BL_INT min_mn = min(m, n); + MTL_BL_INT rank = 0; + T rcond = -1; + MTL_BL_INT info = 0; + + mt::Vctr bv(b, b+m*b_cols); + S.resize(min_mn); + + // query optimal size of work array + MTL_BL_INT lwork = -1; + T work_query= 0; + MTL_BL_INT iwork_query= 0; + gelsd_c(m, n, nrhs, A, lda, bv.data(), ldb, S.data(), rcond, rank, &work_query, lwork, &iwork_query, info); + + // set arrays + lwork = max(1, MTL_BL_INT(work_query)); + work.resize(lwork); + + MTL_BL_INT liwork = max(1, iwork_query); + iwork.resize(liwork); + + // perform minimum-norm solution + gelsd_c(m, n, nrhs, A, lda, bv.data(), ldb, S.data(), rcond, rank, work.data(), lwork, iwork.data(), info); + + for(auto ix= 0; ix iwork; + mt::Vctr work; + mt::Vctr S; + }; +} // namespace lapack + #endif \ No newline at end of file diff --git a/src/lens.cuh b/src/lens.cuh new file mode 100755 index 00000000..607cc461 --- /dev/null +++ b/src/lens.cuh @@ -0,0 +1,634 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef LENS_H + #define LENS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "fcns_cgpu_gen.h" + #include "grid.h" + + namespace mt + { + /****************************** lens *********************************/ + template + class Lens + { + public: + using value_type = T; + + dt_int32 m; // Momentum of the vortex + + T c_10; // Defocus (Å) + T c_12; // 2-fold astigmatism (Å) + T phi_12; // Azimuthal angle of 2-fold astigmatism (rad) + + T c_21; // Axial coma (Å) + T phi_21; // Azimuthal angle of axial coma (rad) + T c_23; // 3-fold astigmatism (Å) + T phi_23; // Azimuthal angle of 3-fold astigmatism (rad) + + T c_30; // 3rd order spherical aberration (Å) + T c_32; // Axial star aberration (Å) + T phi_32; // Azimuthal angle of axial star aberration (rad) + T c_34; // 4-fold astigmatism (Å) + T phi_34; // Azimuthal angle of 4-fold astigmatism (rad) + + T c_41; // 4th order axial coma (Å) + T phi_41; // Azimuthal angle of 4th order axial coma (rad) + T c_43; // 3-lobe aberration (Å) + T phi_43; // Azimuthal angle of 3-lobe aberration (rad) + T c_45; // 5-fold astigmatism (Å) + T phi_45; // Azimuthal angle of 5-fold astigmatism (rad) + + T c_50; // 5th order spherical aberration (Å) + T c_52; // 5th order axial star aberration (Å) + T phi_52; // Azimuthal angle of 5th order axial star aberration (rad) + T c_54; // 5th order rosette aberration (Å) + T phi_54; // Azimuthal angle of 5th order rosette aberration (rad) + T c_56; // 6-fold astigmatism (Å) + T phi_56; // Azimuthal angle of 6-fold astigmatism (rad) + + T inner_aper_ang; // Inner aperture (rad); + T outer_aper_ang; // Outer aperture (rad); + + T tp_inc_a; // Height proportion of a normalized Gaussian [0, 1] + T tp_inc_sigma; // standard deviation of the defocus spread function for the Gaussian component: + T tp_inc_beta; // standard deviation of the defocus spread function for the exponential component: + dt_int32 tp_inc_npts; // number of integration points of the defocus spread function + + T tp_inc_iehwgd; // e^-1 half-width value of the Gaussian distribution + + T spt_inc_a; // Height proportion of a normalized Gaussian [0, 1] + T spt_inc_sigma; // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + T spt_inc_beta; // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + dt_int32 spt_inc_rad_npts; // number of radial integration points + dt_int32 spt_inc_azm_npts; // number of azimuth integration points + + T spt_inc_iehwgd; // e^-1 half-width value of the Gaussian distribution + T spt_inc_theta_c; // divergence semi-angle (rad) + + eZero_Def_Typ zero_def_typ;// Defocus type: ezdt_first = 1, ezdt_middle = 2, ezdt_last = 3, ezdt_user_def = 4 + T zero_def_plane; // plane + + T lambda; // wavelength(Angstrom) + + T c_c_10; // -pi*c_10*lambda + T c_c_12; // -pi*c_12*lambda + + T c_c_21; // -2*pi*c_21*lambda^2/3 + T c_c_23; // -2*pi*c_23*lambda^2/3 + + T c_c_30; // -pi*c_30*lambda^3/2 + T c_c_32; // -pi*c_32*lambda^3/2 + T c_c_34; // -pi*c_34*lambda^3/2 + + T c_c_41; // -2*pi*c_41*lambda^4/5 + T c_c_43; // -2*pi*c_43*lambda^4/5 + T c_c_45; // -2*pi*c_45*lambda^4/5 + + T c_c_50; // -pi*c_50*lambda^5/3 + T c_c_52; // -pi*c_52*lambda^5/3 + T c_c_54; // -pi*c_54*lambda^5/3 + T c_c_56; // -pi*c_56*lambda^5/3 + + T g2_inner; // inner_aper_ang/lambda + T g2_outer; // outer_aper_ang/lambda + + dt_int32 ngxs; // number of source sampling points x + dt_int32 ngys; // number of source sampling points y + T dgxs; // source sampling m_size; + T dgys; // source sampling m_size; + T g2_maxs; // q maximum square; + + /************************************* constructors ************************************/ + Lens(): m(0), c_10(0), c_12(0), phi_12(0), c_21(0), phi_21(0), c_23(0), phi_23(0), + c_30(0), c_32(0), phi_32(0), c_34(0), phi_34(0), + c_41(0), phi_41(0), c_43(0), phi_43(0), c_45(0), phi_45(0), + c_50(0), c_52(0), phi_52(0), c_54(0), phi_54(0), c_56(0), phi_56(0), + inner_aper_ang(0), outer_aper_ang(0), tp_inc_a(1.0), tp_inc_sigma(0), tp_inc_beta(0), tp_inc_npts(0), tp_inc_iehwgd(0), + spt_inc_a(1.0), spt_inc_sigma(0), spt_inc_beta(0), spt_inc_rad_npts(0), spt_inc_azm_npts(0), spt_inc_iehwgd(0), spt_inc_theta_c(0), + zero_def_typ(ezdt_last), zero_def_plane(0), lambda(0), g2_inner(0), g2_outer(0), ngxs(0), ngys(0), dgxs(0), dgys(0), g2_maxs(0), + c_c_10(0), c_c_12(0), c_c_21(0), c_c_23(0), c_c_30(0), c_c_32(0), c_c_34(0), c_c_41(0), + c_c_43(0), c_c_45(0), c_c_50(0), c_c_52(0), c_c_54(0), c_c_56(0) {} + + /* copy constructor */ + CGPU_EXEC + Lens(const Lens& lens): Lens() + { + *this = lens; + } + + /* converting constructor */ + template + CGPU_EXEC + Lens(const Lens& lens): Lens() + { + *this = lens; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Lens& operator=(const Lens& lens) + { + if (this != &lens) + { + m = lens.m; + + c_10 = lens.c_10; + c_12 = lens.c_12; + phi_12 = lens.phi_12; + + c_21 = lens.c_21; + phi_21 = lens.phi_21; + c_23 = lens.c_23; + phi_23 = lens.phi_23; + + c_30 = lens.c_30; + c_32 = lens.c_32; + phi_32 = lens.phi_32; + c_34 = lens.c_34; + phi_34 = lens.phi_34; + + c_41 = lens.c_41; + phi_41 = lens.phi_41; + c_43 = lens.c_43; + phi_43 = lens.phi_43; + c_45 = lens.c_45; + phi_45 = lens.phi_45; + + c_50 = lens.c_50; + c_52 = lens.c_52; + phi_52 = lens.phi_52; + c_54 = lens.c_54; + phi_54 = lens.phi_54; + c_56 = lens.c_56; + phi_56 = lens.phi_56; + + inner_aper_ang = lens.inner_aper_ang; + outer_aper_ang = lens.outer_aper_ang; + + tp_inc_a = lens.tp_inc_a; + tp_inc_sigma = lens.tp_inc_sigma; + tp_inc_beta = lens.tp_inc_beta; + tp_inc_npts = lens.tp_inc_npts; + tp_inc_iehwgd = lens.tp_inc_iehwgd; + + spt_inc_a = lens.spt_inc_a; + spt_inc_sigma = lens.spt_inc_sigma; + spt_inc_beta = lens.spt_inc_beta; + spt_inc_rad_npts = lens.spt_inc_rad_npts; + spt_inc_azm_npts = lens.spt_inc_azm_npts; + + spt_inc_iehwgd = lens.spt_inc_iehwgd; + spt_inc_theta_c = lens.spt_inc_theta_c; + + zero_def_typ = lens.zero_def_typ; + zero_def_plane = lens.zero_def_plane; + + lambda = lens.lambda; + + c_c_10 = lens.c_c_10; + c_c_12 = lens.c_c_12; + + c_c_21 = lens.c_c_21; + c_c_23 = lens.c_c_23; + + c_c_30 = lens.c_c_30; + c_c_32 = lens.c_c_32; + c_c_34 = lens.c_c_34; + + c_c_41 = lens.c_c_41; + c_c_43 = lens.c_c_43; + c_c_45 = lens.c_c_45; + + c_c_50 = lens.c_c_50; + c_c_52 = lens.c_c_52; + c_c_54 = lens.c_c_54; + c_c_56 = lens.c_c_56; + + g2_inner = lens.g2_inner; + g2_outer = lens.g2_outer; + + ngxs = lens.ngxs; + ngys = lens.ngys; + + dgxs = lens.dgxs; + dgys = lens.dgys; + g2_maxs = lens.g2_outers; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Lens& operator=(const Lens& lens) + { + m = lens.m; + + c_10 = T(lens.c_10); + c_12 = T(lens.c_12); + phi_12 = T(lens.phi_12); + + c_21 = T(lens.c_21); + phi_21 = T(lens.phi_21); + c_23 = T(lens.c_23); + phi_23 = T(lens.phi_23); + + c_30 = T(lens.c_30); + c_32 = T(lens.c_32); + phi_32 = T(lens.phi_32); + c_34 = T(lens.c_34); + phi_34 = T(lens.phi_34); + + c_41 = T(lens.c_41); + phi_41 = T(lens.phi_41); + c_43 = T(lens.c_43); + phi_43 = T(lens.phi_43); + c_45 = T(lens.c_45); + phi_45 = T(lens.phi_45); + + c_50 = T(lens.c_50); + c_52 = T(lens.c_52); + phi_52 = T(lens.phi_52); + c_54 = T(lens.c_54); + phi_54 = T(lens.phi_54); + c_56 = T(lens.c_56); + phi_56 = T(lens.phi_56); + + inner_aper_ang = T(lens.inner_aper_ang); + outer_aper_ang = T(lens.outer_aper_ang); + + tp_inc_a = T(lens.tp_inc_a); + tp_inc_sigma = T(lens.tp_inc_sigma); + tp_inc_beta = T(lens.tp_inc_beta); + tp_inc_npts = lens.tp_inc_npts; + tp_inc_iehwgd = lens.tp_inc_iehwgd; + + spt_inc_a = T(lens.spt_inc_a); + spt_inc_sigma = T(lens.spt_inc_sigma); + spt_inc_beta = T(lens.spt_inc_beta); + spt_inc_rad_npts = lens.spt_inc_rad_npts; + spt_inc_azm_npts = lens.spt_inc_azm_npts; + + spt_inc_iehwgd = T(lens.spt_inc_iehwgd); + spt_inc_theta_c = T(lens.spt_inc_theta_c); + + zero_def_typ = lens.zero_def_typ; + zero_def_plane = T(lens.zero_def_plane); + + lambda = T(lens.lambda); + + c_c_10 = T(lens.c_c_10); + c_c_12 = T(lens.c_c_12); + + c_c_21 = T(lens.c_c_21); + c_c_23 = T(lens.c_c_23); + + c_c_30 = T(lens.c_c_30); + c_c_32 = T(lens.c_c_32); + c_c_34 = T(lens.c_c_34); + + c_c_41 = T(lens.c_c_41); + c_c_43 = T(lens.c_c_43); + c_c_45 = T(lens.c_c_45); + + c_c_50 = T(lens.c_c_50); + c_c_52 = T(lens.c_c_52); + c_c_54 = T(lens.c_c_54); + c_c_56 = T(lens.c_c_56); + + g2_inner = T(lens.g2_inner); + g2_outer = T(lens.g2_outer); + + ngxs = lens.ngxs; + ngys = lens.ngys; + + dgxs = T(lens.dgxs); + dgys = T(lens.dgys); + g2_maxs = T(lens.g2_outers); + + return *this; + } + + template + void assign(const Lens& lens) + { + *this = lens; + } + + /***************************************************************************************/ + void set_dep_var(const T& E_0, const Grid_2d& grid) + { + lambda = fcn_lambda(E_0); + + c_c_10 = fcn_is_zero(c_10)?T(0):-c_pi*c_10*lambda; + c_c_12 = fcn_is_zero(c_12)?T(0):-c_pi*c_12*lambda; + + c_c_21 = fcn_is_zero(c_21)?T(0):-T(2)*c_pi*c_21*pow(lambda, 2)/T(3); + c_c_23 = fcn_is_zero(c_23)?T(0):-T(2)*c_pi*c_23*pow(lambda, 2)/T(3); + + c_c_30 = fcn_is_zero(c_30)?T(0):-c_pi*c_30*pow(lambda, 3)/T(2); + c_c_32 = fcn_is_zero(c_32)?T(0):-c_pi*c_32*pow(lambda, 3)/T(2); + c_c_34 = fcn_is_zero(c_34)?T(0):-c_pi*c_34*pow(lambda, 3)/T(2); + + c_c_41 = fcn_is_zero(c_41)?T(0):-T(2)*c_pi*c_41*pow(lambda, 4)/T(5); + c_c_43 = fcn_is_zero(c_43)?T(0):-T(2)*c_pi*c_43*pow(lambda, 4)/T(5); + c_c_45 = fcn_is_zero(c_45)?T(0):-T(2)*c_pi*c_45*pow(lambda, 4)/T(5); + + c_c_50 = fcn_is_zero(c_50)?T(0):-c_pi*c_50*pow(lambda, 5)/T(3); + c_c_52 = fcn_is_zero(c_52)?T(0):-c_pi*c_52*pow(lambda, 5)/T(3); + c_c_54 = fcn_is_zero(c_54)?T(0):-c_pi*c_54*pow(lambda, 5)/T(3); + c_c_56 = fcn_is_zero(c_56)?T(0):-c_pi*c_56*pow(lambda, 5)/T(3); + + g2_inner = (inner_aper_ang < epsilon_abs())?T(0):pow(rad_2_rangs(inner_aper_ang), 2); + g2_outer = (outer_aper_ang < epsilon_abs())?T(2)*grid.g2_max():pow(rad_2_rangs(outer_aper_ang), 2); + + tp_inc_a = max(T(0), min(T(1), tp_inc_a)); + set_tp_inc_sigma(tp_inc_sigma); + tp_inc_beta = max(T(0), tp_inc_beta); + tp_inc_npts = max(1, tp_inc_npts); + + spt_inc_a = max(T(0), min(T(1), spt_inc_a)); + set_spt_inc_sigma(spt_inc_sigma); + spt_inc_beta = max(T(0), spt_inc_beta); + spt_inc_rad_npts = max(1, spt_inc_rad_npts); + spt_inc_azm_npts = max(1, spt_inc_azm_npts); + + T gmaxs = T(3.5)*spt_inc_sigma; + g2_maxs = gmaxs*gmaxs; + T dgs = gmaxs/static_cast(spt_inc_rad_npts); + + dt_int32 n = (dgs(::floor(grid.dgx/dgs)+1):1; + ngxs = static_cast(::floor(n*gmaxs/grid.dgx)) + 1; + dgxs = gmaxs/ngxs; + + n = (dgs(::floor(grid.dgy/dgs)+1):1; + ngys = static_cast(::floor(n*gmaxs/grid.dgy)) + 1; + dgys = gmaxs/ngys; + } + + CGPU_EXEC + T rad_2_rangs(const T& theta) const + { + return sin(theta)/lambda; + } + + void set_tp_inc_sigma(const T& ti_sigma) + { + tp_inc_sigma = max(T(0), ti_sigma); + tp_inc_iehwgd = c_2i2*tp_inc_sigma; + } + + void set_spt_inc_sigma(const T& si_sigma) + { + spt_inc_sigma = max(T(0), si_sigma); + spt_inc_iehwgd = c_2i2*spt_inc_sigma; + spt_inc_theta_c = asin(spt_inc_iehwgd*lambda); + } + + void set_defocus(const T& c_10) + { + this->c_10 = c_10; + c_c_10 = (fcn_is_zero(c_10))?T(0):-c_pi*c_10*lambda; + } + + T get_zero_def_plane(const T& z_min, const T& z_max) const + { + switch(zero_def_typ) + { + case ezdt_first: + { + return z_min; + } + case ezdt_middle: + { + return T(0.5)*(z_min + z_max); + } + case ezdt_last: + { + return z_max; + } + default: + { + return zero_def_plane; + } + } + }; + + dt_bool is_zdt_first() const + { + return mt::is_zdt_first(zero_def_typ); + } + + dt_bool is_zdt_middle() const + { + return mt::is_zdt_first(zero_def_typ); + } + + dt_bool is_zdt_last() const + { + return mt::is_zdt_first(zero_def_typ); + } + + dt_bool is_zdt_user_def() const + { + return mt::is_zdt_first(zero_def_typ); + } + + T gxs(const dt_int32& ix) const + { + return static_cast(ix)*dgxs; + } + T gys(const dt_int32& iy) const + { + return static_cast(iy)*dgys; + } + T g2s(const dt_int32& ix, const dt_int32& iy) const + { + T gxi = gxs(ix); + T gyi = gys(iy); + + return gxi*gxi + gyi*gyi; + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T tp_inc_sigma_2() const + { + return ::square(tp_inc_sigma); + } + + CGPU_EXEC_INL + T tp_inc_beta_2() const + { + return ::square(tp_inc_beta); + } + + CGPU_EXEC_INL + T spt_inc_sigma_2() const + { + return ::square(spt_inc_sigma); + } + + CGPU_EXEC_INL + T spt_inc_beta_2() const + { + return ::square(spt_inc_beta); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + dt_bool is_phi_required() const + { + auto bb = fcn_is_nzero(m)||fcn_is_nzero(c_12)||fcn_is_nzero(c_21)||fcn_is_nzero(c_23)||fcn_is_nzero(c_32)||fcn_is_nzero(c_34); + bb = bb||fcn_is_nzero(c_41)||fcn_is_nzero(c_43)||fcn_is_nzero(c_45)||fcn_is_nzero(c_52)||fcn_is_nzero(c_54)||fcn_is_nzero(c_56); + + return bb; + } + + CGPU_EXEC_INL + T eval_m(const T& phi) const + { + return T(m)*phi; + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_10(const T& g2) const + { + return c_c_10*g2; + } + + CGPU_EXEC_INL + T eval_c_12(const T& g2, const T& phi) const + { + return c_c_12*g2*sin(T(2)*(phi-phi_12)); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_21(const T& g3, const T& phi) const + { + return c_c_21*g3*sin(phi-phi_21); + } + + CGPU_EXEC_INL + T eval_c_23(const T& g3, const T& phi) const + { + return c_c_23*g3*sin(T(3)*(phi-phi_23)); + } + + CGPU_EXEC_INL + T eval_c_21_c_23(const T& g3, const T& phi) const + { + return eval_c_21(g3, phi) + eval_c_23(g3, phi); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_30(const T& g4) const + { + return c_c_30*g4; + } + + CGPU_EXEC_INL + T eval_c_32(const T& g4, const T& phi) const + { + return c_c_32*g4*sin(T(2)*(phi-phi_32)); + } + + CGPU_EXEC_INL + T eval_c_34(const T& g4, const T& phi) const + { + return c_c_34*g4*sin(T(4)*(phi-phi_34)); + } + + CGPU_EXEC_INL + T eval_c_32_c_34(const T& g4, const T& phi) const + { + return eval_c_32(g4, phi) + eval_c_34(g4, phi); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_41(const T& g5, const T& phi) const + { + return c_c_41*g5*sin(phi-phi_41); + } + + CGPU_EXEC_INL + T eval_c_43(const T& g5, const T& phi) const + { + return c_c_43*g5*sin(T(3)*(phi-phi_43)); + } + + CGPU_EXEC_INL + T eval_c_45(const T& g5, const T& phi) const + { + return c_c_45*g5*sin(T(5)*(phi-phi_45)); + } + + CGPU_EXEC_INL + T eval_c_41_c_43_c_45(const T& g5, const T& phi) const + { + return eval_c_41(g5, phi) + eval_c_43(g5, phi) + eval_c_45(g5, phi); + } + + /***************************************************************************************/ + CGPU_EXEC_INL + T eval_c_50(const T& g6) const + { + return c_c_50*g6; + } + + CGPU_EXEC_INL + T eval_c_52(const T& g6, const T& phi) const + { + return c_c_52*g6*sin(T(2)*(phi-phi_52)); + } + + CGPU_EXEC_INL + T eval_c_54(const T& g6, const T& phi) const + { + return c_c_54*g6*sin(T(4)*(phi-phi_54)); + } + + CGPU_EXEC_INL + T eval_c_56(const T& g6, const T& phi) const + { + return c_c_56*g6*sin(T(6)*(phi-phi_56)); + } + + CGPU_EXEC_INL + T eval_c_52_c_54_c_56(const T& g6, const T& phi) const + { + return eval_c_52(g6, phi) + eval_c_54(g6, phi) + eval_c_56(g6, phi); + } + }; + } + +#endif \ No newline at end of file diff --git a/src/libblas.lib b/src/libblas.lib old mode 100644 new mode 100755 index 84a1c94b..88344bd0 Binary files a/src/libblas.lib and b/src/libblas.lib differ diff --git a/src/liblapack.lib b/src/liblapack.lib deleted file mode 100644 index 6469a10d..00000000 Binary files a/src/liblapack.lib and /dev/null differ diff --git a/src/lin_alg_def.cuh b/src/lin_alg_def.cuh deleted file mode 100644 index cf2cac90..00000000 --- a/src/lin_alg_def.cuh +++ /dev/null @@ -1,878 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef LIN_ALG_DEF_H -#define LIN_ALG_DEF_H - -#include -#include - -#include "math.cuh" - -namespace mt -{ - /************************************************************************/ - /********************************2d vector*******************************/ - /************************************************************************/ - - template - struct r2d - { - using value_type = T; - - T x; - T y; - - DEVICE_CALLABLE - inline r2d(const T &x_i = T(), const T &y_i = T()) - { - x = x_i; - y = y_i; - } - - template - DEVICE_CALLABLE - inline r2d(const r2d &r) - { - x = r.x; - y = r.y; - } - - template - friend DEVICE_CALLABLE - inline r2d operator-(const r2d r); - - DEVICE_CALLABLE - inline r2d& operator+=(const r2d r) - { - x += r.x; - y += r.y; - return *this; - } - - DEVICE_CALLABLE - inline r2d& operator-=(const r2d r) - { - x -= r.x; - y -= r.y; - return *this; - } - - DEVICE_CALLABLE - inline r2d& operator*=(const T r) - { - x *= r; - y *= r; - return *this; - } - - DEVICE_CALLABLE - inline r2d& operator/=(const T r) - { - x /= r; - y /= r; - return *this; - } - - DEVICE_CALLABLE - inline T norm() const - { - return x*x + y*y; - } - - DEVICE_CALLABLE - inline T module() const - { - return sqrt(norm()); - } - - DEVICE_CALLABLE - inline void normalized() - { - *this /= module(); - } - - template - DEVICE_CALLABLE - inline r2d apply_matrix(const TVector &Rm) - { - r2d r_o; - r_o.x = Rm[0] * x + Rm[2] * y; - r_o.y = Rm[1] * x + Rm[3] * y; - return r_o; - } - - template - DEVICE_CALLABLE - inline r2d rotate(const TVector &Rm, const r2d &p0) - { - r2d r(x, y); - r -= p0; - return (apply_matrix(Rm) + p0); - } - - }; - - template - DEVICE_CALLABLE - inline r2d operator-(const r2d r) - { - return r2d(-r.x, -r.y); - } - - template - DEVICE_CALLABLE - inline r2d operator+(const r2d &lhs, const r2d &rhs) - { - return r2d(lhs.x + rhs.x, lhs.y + rhs.y); - } - - template - DEVICE_CALLABLE - inline r2d operator+(const r2d &lhs, const X &rhs) - { - return r2d(lhs.x + rhs, lhs.y + rhs); - } - - template - DEVICE_CALLABLE - inline r2d operator+(const X &lhs, const r2d &rhs) - { - return r2d(lhs + rhs.x, lhs + rhs.y); - } - - template - DEVICE_CALLABLE - inline r2d operator-(const r2d &lhs, const r2d &rhs) - { - return r2d(lhs.x - rhs.x, lhs.y - rhs.y); - } - - template - DEVICE_CALLABLE - inline r2d operator-(const r2d &lhs, const X &rhs) - { - return r2d(lhs.x - rhs, lhs.y - rhs); - } - - template - DEVICE_CALLABLE - inline r2d operator-(const X &lhs, const r2d &rhs) - { - return r2d(lhs - rhs.x, lhs - rhs.y); - } - - template - DEVICE_CALLABLE - inline r2d operator*(const r2d &lhs, const r2d &rhs) - { - return r2d(lhs.x*rhs.x, lhs.y*rhs.y); - } - - template - DEVICE_CALLABLE - inline r2d operator*(const r2d &lhs, const X &rhs) - { - return r2d(lhs.x*rhs, lhs.y*rhs); - } - - template - DEVICE_CALLABLE - inline r2d operator*(const X &lhs, const r2d &rhs) - { - return r2d(lhs*rhs.x, lhs*rhs.y); - } - - template - DEVICE_CALLABLE - inline r2d operator/(const r2d &lhs, const X &rhs) - { - return r2d(lhs.x / rhs, lhs.y / rhs); - } - - template - DEVICE_CALLABLE - inline r2d fmin(const r2d lhs, const r2d rhs) - { - return r2d(::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y)); - } - - template - DEVICE_CALLABLE - inline r2d fmax(const r2d lhs, const r2d rhs) - { - return r2d(::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y)); - } - - template - DEVICE_CALLABLE - inline X norm(const r2d& r) - { - return r.x*r.x + r.y*r.y; - } - - template - DEVICE_CALLABLE - inline X module(const r2d& r) - { - return sqrt(norm(r)); - } - - template - DEVICE_CALLABLE - inline r2d normalized(const r2d& r) - { - return r / module(r); - } - - template - DEVICE_CALLABLE - inline X dot(const r2d &lhs, const r2d &rhs) - { - return lhs.x*rhs.x + lhs.y*rhs.y; - } - - template - DEVICE_CALLABLE - inline X angle(const r2d &lhs, const r2d &rhs) - { - return acos(dot(lhs, rhs) / (lhs.module()*rhs.module())); - } - - /************************************************************************/ - /********************************3d vector*******************************/ - /************************************************************************/ - - template - struct r3d - { - using value_type = T; - - T x; - T y; - T z; - - DEVICE_CALLABLE - r3d(const T &x_i = T(), const T &y_i = T(), const T &z_i = T()) - { - x = x_i; - y = y_i; - z = z_i; - } - - template - DEVICE_CALLABLE - r3d(const r3d &r) - { - x = r.x; - y = r.y; - z = r.z; - } - - DEVICE_CALLABLE - inline r3d& operator+=(const r3d r) - { - x += r.x; - y += r.y; - z += r.z; - return *this; - } - - DEVICE_CALLABLE - inline r3d& operator-=(const r3d r) - { - x -= r.x; - y -= r.y; - z -= r.z; - return *this; - } - - DEVICE_CALLABLE - inline r3d& operator*=(const T r) - { - x *= r; - y *= r; - z *= r; - return *this; - } - - DEVICE_CALLABLE - inline r3d& operator/=(const T r) - { - x /= r; - y /= r; - z /= r; - return *this; - } - - DEVICE_CALLABLE - inline T norm() - { - return pow(x, 2) + pow(y, 2) + pow(z, 2); - } - - DEVICE_CALLABLE - inline T module() - { - return sqrt(norm()); - } - - DEVICE_CALLABLE - inline void normalized() - { - auto rm = module(); - *this /= module(); - } - - template - DEVICE_CALLABLE - inline r3d apply_matrix(const TVector &Rm) - { - r3d r_o; - r_o.x = Rm[0] * x + Rm[3] * y + Rm[6] * z; - r_o.y = Rm[1] * x + Rm[4] * y + Rm[7] * z; - r_o.z = Rm[2] * x + Rm[5] * y + Rm[8] * z; - return r_o; - } - - template - DEVICE_CALLABLE - inline r3d rotate(const TVector &Rm, const r3d &p0) const - { - r3d r(x, y, z); - r -= p0; - return (r.apply_matrix(Rm) + p0); - } - - }; - - template - DEVICE_CALLABLE - inline r3d operator+(const r3d &lhs, const r3d &rhs) - { - return r3d(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z); - } - - template - DEVICE_CALLABLE - inline r3d operator+(const r3d &lhs, const X &rhs) - { - return r3d(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs); - } - - template - DEVICE_CALLABLE - inline r3d operator+(const X &lhs, const r3d &rhs) - { - return r3d(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z); - } - - template - DEVICE_CALLABLE - inline r3d operator-(const r3d &lhs, const r3d &rhs) - { - return r3d(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z); - } - - template - DEVICE_CALLABLE - inline r3d operator-(const r3d &lhs, const X &rhs) - { - return r3d(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs); - } - - template - DEVICE_CALLABLE - inline r3d operator-(const X &lhs, const r3d &rhs) - { - return r3d(lhs - rhs.x, lhs - rhs.y, lhs - rhs.z); - } - - template - DEVICE_CALLABLE - inline r3d operator*(const r3d &lhs, const r3d &rhs) - { - return r3d(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z); - } - - template - DEVICE_CALLABLE - inline r3d operator*(const r3d &lhs, const X &rhs) - { - return r3d(lhs.x*rhs, lhs.y*rhs, lhs.z*rhs); - } - - template - DEVICE_CALLABLE - inline r3d operator*(const X &lhs, const r3d &rhs) - { - return r3d(lhs*rhs.x, lhs*rhs.y, lhs*rhs.z); - } - - template - DEVICE_CALLABLE - inline r3d operator/(const r3d &lhs, const X &rhs) - { - return r3d(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); - } - - template - DEVICE_CALLABLE - inline r3d fmin(const r3d &lhs, const r3d &rhs) - { - return r3d(::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y), ::fmin(lhs.z, rhs.z)); - } - - template - DEVICE_CALLABLE - inline r3d fmax(const r3d &lhs, const r3d &rhs) - { - return r3d(::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y), ::fmax(lhs.z, rhs.z)); - } - - template - DEVICE_CALLABLE - inline X norm(const r3d& r) - { - return r.x*r.x + r.y*r.y + r.z*r.z; - } - - template - DEVICE_CALLABLE - inline X module(const r3d& r) - { - return sqrt(norm(r)); - } - - template - DEVICE_CALLABLE - inline r3d normalized(const r3d& r) - { - return r / r.module(); - } - - template - DEVICE_CALLABLE - inline X dot(const r3d &lhs, const r3d &rhs) - { - return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; - } - - template - DEVICE_CALLABLE - inline X angle(const r3d &lhs, const r3d &rhs) - { - return acos(dot(lhs, rhs) / (lhs.module()*rhs.module())); - } - - /************************************************************************/ - /********************************3x3 matrix******************************/ - /************************************************************************/ - - template - struct M3x3 - { - using value_type = T; - - const int m; - const int n; - const int m_size; - - std::vector data; - - DEVICE_CALLABLE - inline M3x3() : m(3), n(3), m_size(m*n) - { - data.resize(m_size); - } - - template - DEVICE_CALLABLE - inline M3x3(const TVector &v) : m(3), n(3), m_size(m*n) - { - data.resize(m_size); - - if (v.size() >= m_size) - { - std::copy(v.begin(), v.begin() + m_size, data.begin()); - } - } - - int size() const - { - return m_size; - } - - DEVICE_CALLABLE FORCE_INLINE - T& operator[](const int idx) { return data[idx]; } - - DEVICE_CALLABLE FORCE_INLINE - const T& operator[](const int idx) const { return data[idx]; } - - DEVICE_CALLABLE FORCE_INLINE - T& operator()(const int ir, const int ic) { return data[ir - 1 + m*(ic - 1)]; } - - DEVICE_CALLABLE FORCE_INLINE - const T& operator()(const int ir, const int ic) const { return data[ir - 1 + m*(ic - 1)]; } - - DEVICE_CALLABLE - inline M3x3& operator+=(const T &r) - { - for (auto ik = 0; ik < m_size; ik++) - { - data[ik] += r; - } - - return *this; - } - - DEVICE_CALLABLE - inline M3x3& operator+=(const M3x3 &r) - { - for (auto ik = 0; ik < m_size; ik++) - { - data[ik] += r.data[ik]; - } - - return *this; - } - - DEVICE_CALLABLE - inline M3x3& operator-=(const T &r) - { - for (auto ik = 0; ik < m_size; ik++) - { - data[ik] -= r; - } - - return *this; - } - - DEVICE_CALLABLE - inline M3x3& operator-=(const M3x3 &r) - { - for (auto ik = 0; ik < m_size; ik++) - { - data[ik] -= r.data[ik]; - } - - return *this; - } - - DEVICE_CALLABLE - inline M3x3& operator*=(const T &r) - { - for (auto ik = 0; ik < m_size; ik++) - { - data[ik] *= r; - } - - return *this; - } - - DEVICE_CALLABLE - inline M3x3& operator*=(const M3x3 &r) - { - T a11 = data[0] * r.data[0] + data[3] * r.data[1] + data[6] * r.data[2]; - T a21 = data[0] * r.data[3] + data[3] * r.data[4] + data[6] * r.data[5]; - T a31 = data[0] * r.data[6] + data[3] * r.data[7] + data[6] * r.data[8]; - - T a12 = data[1] * r.data[0] + data[4] * r.data[1] + data[7] * r.data[2]; - T a22 = data[1] * r.data[3] + data[4] * r.data[4] + data[7] * r.data[5]; - T a32 = data[1] * r.data[6] + data[4] * r.data[7] + data[7] * r.data[8]; - - T a13 = data[2] * r.data[0] + data[5] * r.data[1] + data[8] * r.data[2]; - T a23 = data[2] * r.data[3] + data[5] * r.data[4] + data[8] * r.data[5]; - T a33 = data[2] * r.data[6] + data[5] * r.data[7] + data[8] * r.data[8]; - - data[0] = a11; - data[1] = a21; - data[2] = a31; - - data[3] = a12; - data[4] = a22; - data[5] = a32; - - data[6] = a13; - data[7] = a23; - data[8] = a33; - - return *this; - } - - DEVICE_CALLABLE - inline M3x3& operator/=(const T r) - { - for (auto ik = 0; ik < m_size; ik++) - { - data[ik] /= r; - } - - return *this; - } - }; - - template - DEVICE_CALLABLE - inline M3x3 operator+(const M3x3 &lhs, const X &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs[ik] + rhs; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator+(const X &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs + rhs[ik]; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator+(const M3x3 &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs[ik] + rhs[ik]; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator-(const M3x3 &lhs, const X &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs[ik] - rhs; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator-(const X &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs - rhs[ik]; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator-(const M3x3 &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs[ik] - rhs[ik]; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator*(const M3x3 &lhs, const X &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs[ik] * rhs; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator*(const X &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs*rhs[ik]; - } - - return M; - } - - template - DEVICE_CALLABLE - inline r3d operator*(const M3x3 &lhs, const r3d &rhs) - { - r3d V; - - V.x = lhs[0] * rhs.x + lhs[3] * rhs.y + lhs[6] * rhs.z; - V.y = lhs[1] * rhs.x + lhs[4] * rhs.y + lhs[7] * rhs.z; - V.z = lhs[2] * rhs.x + lhs[5] * rhs.y + lhs[8] * rhs.z; - - return V; - } - - template - DEVICE_CALLABLE - inline r3d operator*(const r3d &lhs, const M3x3 &rhs) - { - r3d V; - - V.x = lhs[0] * rhs.x + lhs[1] * rhs.y + lhs[2] * rhs.z; - V.y = lhs[3] * rhs.x + lhs[4] * rhs.y + lhs[5] * rhs.z; - V.z = lhs[6] * rhs.x + lhs[7] * rhs.y + lhs[8] * rhs.z; - - return V; - } - - template - DEVICE_CALLABLE - inline M3x3 operator*(const M3x3 &lhs, const M3x3 &rhs) - { - M3x3 M; - - M[0] = lhs[0] * rhs[0] + lhs[3] * rhs[1] + lhs[6] * rhs[2]; - M[1] = lhs[0] * rhs[3] + lhs[3] * rhs[4] + lhs[6] * rhs[5]; - M[2] = lhs[0] * rhs[6] + lhs[3] * rhs[7] + lhs[6] * rhs[8]; - - M[3] = lhs[1] * rhs[0] + lhs[4] * rhs[1] + lhs[7] * rhs[2]; - M[4] = lhs[1] * rhs[3] + lhs[4] * rhs[4] + lhs[7] * rhs[5]; - M[5] = lhs[1] * rhs[6] + lhs[4] * rhs[7] + lhs[7] * rhs[8]; - - M[6] = lhs[2] * rhs[0] + lhs[5] * rhs[1] + lhs[8] * rhs[2]; - M[7] = lhs[2] * rhs[3] + lhs[5] * rhs[4] + lhs[8] * rhs[5]; - M[8] = lhs[2] * rhs[6] + lhs[5] * rhs[7] + lhs[8] * rhs[8]; - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator/(const M3x3 &lhs, const X &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs[ik] / rhs; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 operator/(const X &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = lhs / lhs[ik]; - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 fmin(const M3x3 &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = ::fmin(lhs[ik], rhs[ik]); - } - - return M; - } - - template - DEVICE_CALLABLE - inline M3x3 fmax(const M3x3 &lhs, const M3x3 &rhs) - { - M3x3 M; - - for (auto ik = 0; ik < M.size(); ik++) - { - M[ik] = ::fmax(lhs[ik], rhs[ik]); - } - - return M; - } - - template - DEVICE_CALLABLE - inline X det(const M3x3& M) - { - X d = M(1, 1)*M(2, 2)*M(3, 3) + M(1, 2)*M(2, 3)*M(3, 1) + M(1, 3)*M(2, 1)*M(3, 2); - d -= M(1, 3)*M(2, 2)*M(3, 1) + M(1, 2)*M(2, 1)*M(3, 3) + M(1, 1)*M(2, 3)*M(3, 2); - - return d; - } - - template - DEVICE_CALLABLE - inline M3x3 inv(const M3x3& M) - { - M3x3 Mo; - - Mo(1, 1) = M(2, 2)*M(3, 3) - M(2, 3)*M(3, 2); - Mo(2, 1) = M(2, 3)*M(3, 1) - M(2, 1)*M(3, 3); - Mo(3, 1) = M(2, 1)*M(3, 2) - M(2, 2)*M(3, 1); - - Mo(1, 2) = M(1, 3)*M(3, 2) - M(1, 2)*M(3, 3); - Mo(2, 2) = M(1, 1)*M(3, 3) - M(1, 3)*M(3, 1); - Mo(3, 2) = M(1, 2)*M(3, 1) - M(1, 1)*M(3, 2); - - Mo(1, 3) = M(1, 2)*M(2, 3) - M(1, 3)*M(2, 2); - Mo(3, 3) = M(1, 1)*M(2, 2) - M(1, 2)*M(2, 1); - Mo(2, 3) = M(1, 3)*M(2, 1) - M(1, 1)*M(2, 3); - - Mo /= det(M); - - return Mo; - } -} // namespace mt -#endif \ No newline at end of file diff --git a/src/macros.h b/src/macros.h new file mode 100755 index 00000000..ebee7451 --- /dev/null +++ b/src/macros.h @@ -0,0 +1,261 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +//#define __CUDACC__ + +#pragma once + +// https:// github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks, -tips, -and-idioms +#define COMMA , + +#define EVAL(...) __VA_ARGS__ + +#define PCAT2(a, ...) a ## __VA_ARGS__ +#define CAT2(a, ...) PCAT2(a, __VA_ARGS__) +#define CAT2_2(a, ...) CAT2(a, __VA_ARGS__) + +#define PCAT3(a, b, ...) a ## b ## __VA_ARGS__ +#define CAT3(a, b, ...) PCAT3(a, b, __VA_ARGS__) +#define CAT3_2(a, b, ...) CAT3(a, b, __VA_ARGS__) + +/***************************************************************************************/ +#define IIF_1(t, ...) t +#define IIF_0(t, ...) __VA_ARGS__ +#define IIF(c) PCAT2(IIF_, c) + +/***************************************************************************************/ +#define CHECK_N(x, n, ...) n +#define CHECK(...) CHECK_N(__VA_ARGS__, 0) +#define IS_1 x, 1 +#define IS_ONE(x) CHECK(CAT2(IS_, x)) + +/***************************************************************************************/ +#define REPV_1(N) N +#define REPV_2(N) REPV_1(N), N +#define REPV_3(N) REPV_2(N), N +#define REPV_4(N) REPV_3(N), N +#define REPV_5(N) REPV_4(N), N +#define REPV_6(N) REPV_5(N), N +#define REPV_7(N) REPV_6(N), N +#define REPV_8(N) REPV_7(N), N +#define REPV_9(N) REPV_8(N), N +#define REPV(V, N) CAT2(REPV_, N(V)) + +/***************************************************************************************/ +#define IDX_1D ix +#define IDX_2D ix, iy +#define IDX_3D ix, iy, iz +#define IDX_ND(DIM) CAT3(IDX_, DIM, D) + +/***************************************************************************************/ +#define IDX_CDEF_1D const dt_int32& ix +#define IDX_CDEF_2D const dt_int32& ix, const dt_int32& iy +#define IDX_CDEF_3D const dt_int32& ix, const dt_int32& iy, const dt_int32& iz +#define IDX_CDEF_ND(DIM) CAT3(IDX_CDEF_, DIM, D) + +/***************************************************************************************/ +#define F_SHAPE_1D(G) G.nx +#define F_SHAPE_2D(G) G.nx, G.ny +#define F_SHAPE_3D(G) G.nx, G.ny, G.nz +#define F_SHAPE_ND(G, DIM) F_SHAPE_##DIM##D(G) + +/***************************************************************************************/ +#define EDIM(DIM) edim_##DIM + +/***************************************************************************************/ +// macro for int definition for blas and lapack +#ifdef MATLAB_BLAS_LAPACK + #define MTL_BL_INT ptrdiff_t +#else + #define MTL_BL_INT dt_int32 +#endif + +#define PASTER(pre, x, y) pre ## _ ## x ## _ ## y +#define EVAL_PASTE(pre, x, y) PASTER(pre, x, y) +#define EVAL_2_PASTE(pre, x, y) EVAL_PASTE(pre, x, y) + +#define INC(X, K) EVAL_PASTE(INC, K, X) +#define DEC(X, K) EVAL_PASTE(DEC, K, X) + +#define INC_1_0 1 +#define INC_1_1 2 +#define INC_1_2 3 +#define INC_1_3 4 +#define INC_1_4 5 +#define INC_1_5 6 +#define INC_1_6 7 +#define INC_1_7 8 +#define INC_1_8 9 +#define INC_1_9 10 +#define INC_1_10 11 +#define INC_1_11 12 +#define INC_1_12 13 +#define INC_1_13 14 +#define INC_1_14 15 +#define INC_1_15 16 + +#define INC_2_0 2 +#define INC_2_1 3 +#define INC_2_2 4 +#define INC_2_3 5 +#define INC_2_4 6 +#define INC_2_5 7 +#define INC_2_6 8 +#define INC_2_7 9 +#define INC_2_8 10 +#define INC_2_9 11 +#define INC_2_10 12 +#define INC_2_11 13 +#define INC_2_12 14 +#define INC_2_13 15 +#define INC_2_14 16 +#define INC_2_15 17 + +#define INC_3_0 3 +#define INC_3_1 4 +#define INC_3_2 5 +#define INC_3_3 6 +#define INC_3_4 7 +#define INC_3_5 8 +#define INC_3_6 9 +#define INC_3_7 10 +#define INC_3_8 11 +#define INC_3_9 12 +#define INC_3_10 13 +#define INC_3_11 14 +#define INC_3_12 15 +#define INC_3_13 16 +#define INC_3_14 17 +#define INC_3_15 18 + +#define DEC_1_0 0 +#define DEC_1_1 0 +#define DEC_1_2 1 +#define DEC_1_3 2 +#define DEC_1_4 3 +#define DEC_1_5 4 +#define DEC_1_6 5 +#define DEC_1_7 6 +#define DEC_1_8 7 +#define DEC_1_9 8 +#define DEC_1_10 9 +#define DEC_1_11 10 +#define DEC_1_12 12 +#define DEC_1_13 13 +#define DEC_1_14 14 +#define DEC_1_15 15 + +#define DEC_2_0 0 +#define DEC_2_1 0 +#define DEC_2_2 0 +#define DEC_2_3 1 +#define DEC_2_4 2 +#define DEC_2_5 3 +#define DEC_2_6 4 +#define DEC_2_7 5 +#define DEC_2_8 6 +#define DEC_2_9 7 +#define DEC_2_10 8 +#define DEC_2_11 9 +#define DEC_2_12 10 +#define DEC_2_13 12 +#define DEC_2_14 13 +#define DEC_2_15 14 + +#define DEC_3_0 0 +#define DEC_3_1 0 +#define DEC_3_2 0 +#define DEC_3_3 0 +#define DEC_3_4 1 +#define DEC_3_5 2 +#define DEC_3_6 3 +#define DEC_3_7 4 +#define DEC_3_8 5 +#define DEC_3_9 6 +#define DEC_3_10 7 +#define DEC_3_11 8 +#define DEC_3_12 9 +#define DEC_3_13 10 +#define DEC_3_14 11 +#define DEC_3_15 12 + +#ifdef __CUDACC__ + #include + + #define CPU_EXEC __host__ + #define CPU_EXEC_INL __host__ inline + + #define GPU_EXEC __device__ + #define GPU_EXEC_INL __device__ inline + + #define CGPU_EXEC __host__ __device__ + #define CGPU_EXEC_INL __host__ __device__ inline + + #define FORCE_INLINE __forceinline__ + + #define FOR_IX_1DC(nx) for(dt_int32 ix = threadIdx.x + blockIdx.x*blockDim.x; ix < nx; ix += blockDim.x*gridDim.x) + + #define FOR_IX_2DC(nx) for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < nx; ix += blockDim.y*gridDim.y) + #define FOR_IY_2DC(ny) for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < ny; iy += blockDim.x*gridDim.x) + + #define FOR_LOOP_1DC(nx, fcn) \ + for(dt_int32 ix = threadIdx.x + blockIdx.x*blockDim.x; ix < nx; ix += blockDim.x*gridDim.x) \ + { \ + fcn; \ + } + + #define FOR_LOOP_2DC(nx, ny, fcn) \ + for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < nx; ix += blockDim.y*gridDim.y) \ + { \ + for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < ny; iy += blockDim.x*gridDim.x) \ + { \ + fcn; \ + } \ + } + + //check out for(dt_int32 iz = blockIdx.z*blockDim.z + threadIdx.z; iz < nz; iz += blockDim.z*gridDim.z) + #define FOR_LOOP_3DC(nx, ny, nz, fcn) \ + { \ + dt_int32 iz = threadIdx.z; \ + for(dt_int32 ix = blockIdx.y*blockDim.y + threadIdx.y; ix < nx; ix += blockDim.y*gridDim.y) \ + { \ + for(dt_int32 iy = blockIdx.x*blockDim.x + threadIdx.x; iy < ny; iy += blockDim.x*gridDim.x) \ + { \ + fcn; \ + } \ + } \ + } + + #define FOR_LOOP_NDC(DIM, ...) CAT3(FOR_LOOP_, DIM, DC)(__VA_ARGS__) + +#else + #define CPU_EXEC + #define CPU_EXEC_INL inline + + #define GPU_EXEC + #define GPU_EXEC_INL inline + + #define CGPU_EXEC + #define CGPU_EXEC_INL inline + + #define FORCE_INLINE inline + + #ifdef _MSC_VER + #define __restrict__ __restrict + #endif +#endif \ No newline at end of file diff --git a/src/math.cuh b/src/math.cuh deleted file mode 100644 index 8d295fb2..00000000 --- a/src/math.cuh +++ /dev/null @@ -1,636 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef MATH_H -#define MATH_H - -#include -#include - -#ifndef DEVICE_CALLABLE - #ifdef __CUDACC__ - #define DEVICE_CALLABLE __host__ __device__ - #define FORCE_INLINE __forceinline__ - #else - #define DEVICE_CALLABLE - #define FORCE_INLINE inline - #endif -#endif - -//#ifdef __CUDACC__ -// #pragma message("Cuda MATH_H") -//#else -// #pragma message("nonCuda MATH_H") -//#endif - -#ifdef __CUDACC__ - #include - #include - #include - using thrust::complex; - using thrust::norm; - using thrust::polar; - using thrust::arg; - using thrust::abs; - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_j0(const T &x) - { - return j0(x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_j1(const T &x) - { - return j1(x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_jn(const int &n, const T &x) - { - return jn(n, x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_y0(const T &x) - { - return y0(x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_y1(const T &x) - { - return y1(x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_yn(const int &n, const T &x) - { - return yn(n, x); - } - -#else - #include - #include - using std::complex; - - using std::cos; - using std::sin; - using std::tan; - using std::acos; - using std::asin; - using std::atan; - using std::atan2; - using std::cosh; - using std::sinh; - using std::tanh; - using std::acosh; - using std::asinh; - using std::atanh; - using std::norm; - using std::polar; - using std::arg; - using std::abs; - - template - inline void sincos(const T &x, T *sptr, T *cptr) - { - *sptr = std::sin(x); - *cptr = std::cos(x); - } - - template - inline T cospi(const T &x) - { - const T c_Pi = 3.141592653589793238463; - return std::cos(c_Pi*x); - } - - template - inline T sinpi(const T &x) - { - const T c_Pi = 3.141592653589793238463; - return std::sin(c_Pi*x); - } - - template - inline void sincospi(const T &x, T *sptr, T *cptr) - { - const T c_Pi = 3.141592653589793238463; - *sptr = std::sin(c_Pi*x); - *cptr = std::cos(c_Pi*x); - } - - using std::exp; - using std::exp2; - - template - inline T exp10(const T &x) - { - return std::pow(static_cast(10), x); - } - - using std::expm1; - using std::frexp; - using std::log; - using std::log2; - using std::log10; - using std::ilogb; - using std::log1p; - using std::logb; - using std::modf; - using std::pow; - using std::sqrt; - - template - inline T rsqrt(const T &x) - { - return 1.0/std::sqrt(x); - } - - using std::cbrt; - using std::hypot; - - template - inline T rhypot(const T &x, const T &y) - { - return 1.0/std::hypot(x, y); - } - - using std::erf; - using std::erfc; - using std::tgamma; - using std::lgamma; - using std::ceil; - using std::floor; - using std::trunc; - using std::round; - using std::lround; - using std::llround; - using std::rint; - using std::lrint; - using std::llrint; - - using std::remainder; - using std::copysign; - using std::fdim; - using std::fmax; - using std::fmin; - using std::fabs; - using std::fma; - using std::fmod; - - template - inline T bessel_j0(const T &x) - { - // host code - T ax, z; - T xx, y, ans, ans1, ans2; - - if((ax =fabs(x)) < 8.0) - { - y =x*x; - ans1 = 57568490574.0+y*(-13362590354.0+y*(651619640.7 - +y*(-11214424.18+y*(77392.33017+y*(-184.9052456))))); - ans2 = 57568490411.0+y*(1029532985.0+y*(9494680.718 - +y*(59272.64853+y*(267.8532712+y*1.0)))); - ans =ans1/ans2; - } - else - { - z = 8.0/ax; - y =z*z; - xx =ax-0.785398164; - ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 - +y*(-0.2073370639e-5+y*0.2093887211e-6))); - ans2 = -0.1562499995e-1+y*(0.1430488765e-3 - +y*(-0.6911147651e-5+y*(0.7621095161e-6 - -y*0.934935152e-7))); - ans =sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); - } - return ans; - } - - template - inline T bessel_j1(const T &x) - { - T ax, z; - T xx, y, ans, ans1, ans2; - - if((ax =fabs(x)) < 8.0) - { - y =x*x; - ans1 =x*(72362614232.0+y*(-7895059235.0+y*(242396853.1 - +y*(-2972611.439+y*(15704.48260+y*(-30.16036606)))))); - ans2 = 144725228442.0+y*(2300535178.0+y*(18583304.74 - +y*(99447.43394+y*(376.9991397+y*1.0)))); - ans =ans1/ans2; - } - else - { - z = 8.0/ax; - y =z*z; - xx =ax-2.356194491; - ans1 = 1.0+y*(0.183105e-2+y*(-0.3516396496e-4 - +y*(0.2457520174e-5+y*(-0.240337019e-6)))); - ans2 = 0.04687499995+y*(-0.2002690873e-3 - +y*(0.8449199096e-5+y*(-0.88228987e-6 - +y*0.105787412e-6))); - ans =sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); - if(x < 0.0) - { - ans = -ans; - } - } - return ans; - } - - template - inline T bessel_jn(const int &n, const T &x) - { - const T ACC = 40.0; - const T BIGNO = 1.0e10; - const T BIGNI = 1.0e-10; - - int j, jsum, m; - T ax, bj, bjm, bjp, sum, tox, ans; - - ax =fabs(x); - if(n == 0) - { - return( bessel_j0(ax) ); - } - if(n == 1) - { - return( bessel_j1(ax) ); - } - - if(ax == 0.0) - { - return 0.0; - } - else if(ax > (T) n) - { - tox = 2.0/ax; - bjm =bessel_j0(ax); - bj =bessel_j1(ax); - for(j = 1;j0;j--) - { - bjm =j*tox*bj-bjp; - bjp =bj; - bj =bjm; - if(fabs(bj) > BIGNO) - { - bj *= BIGNI; - bjp *= BIGNI; - ans *= BIGNI; - sum *= BIGNI; - } - if(jsum) - { - sum += bj; - } - jsum =!jsum; - if(j == n) - { - ans =bjp; - } - } - sum = 2.0*sum-bj; - ans /= sum; - } - return x < (0.0 && n%2 == 1)?-ans:ans; - } - - template - inline T bessel_y0(const T &x) - { - T z; - T xx, y, ans, ans1, ans2; - - if(x < 8.0) - { - y =x*x; - ans1 = -2957821389.0+y*(7062834065.0+y*(-512359803.6 - +y*(10879881.29+y*(-86327.92757+y*228.4622733)))); - ans2 = 40076544269.0+y*(745249964.8+y*(7189466.438 - +y*(47447.26470+y*(226.1030244+y*1.0)))); - ans = (ans1/ans2)+0.636619772*bessel_j0(x)*log(x); - } - else - { - z = 8.0/x; - y =z*z; - xx =x-0.785398164; - ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 - +y*(-0.2073370639e-5+y*0.2093887211e-6))); - ans2 = -0.1562499995e-1+y*(0.1430488765e-3 - +y*(-0.6911147651e-5+y*(0.7621095161e-6 - +y*(-0.934945152e-7)))); - ans =sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); - } - return ans; - } - - template - inline T bessel_y1(const T &x) - { - T z; - T xx, y, ans, ans1, ans2; - - if(x < 8.0) - { - y =x*x; - ans1 =x*(-0.4900604943e13+y*(0.1275274390e13 - +y*(-0.5153438139e11+y*(0.7349264551e9 - +y*(-0.4237922726e7+y*0.8511937935e4))))); - ans2 = 0.2499580570e14+y*(0.4244419664e12 - +y*(0.3733650367e10+y*(0.2245904002e8 - +y*(0.1020426050e6+y*(0.3549632885e3+y))))); - ans = (ans1/ans2)+0.636619772*(bessel_j1(x)*log(x)-1.0/x); - } - else - { - z = 8.0/x; - y =z*z; - xx =x-2.356194491; - ans1 = 1.0+y*(0.183105e-2+y*(-0.3516396496e-4 - +y*(0.2457520174e-5+y*(-0.240337019e-6)))); - ans2 = 0.04687499995+y*(-0.2002690873e-3 - +y*(0.8449199096e-5+y*(-0.88228987e-6 - +y*0.105787412e-6))); - ans =sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); - } - return ans; - } - - template - inline T bessel_yn(const int &n, const T &x) - { - int j; - T by, bym, byp, tox; - - if(n == 0) - { - return( bessel_y0(x) ); - } - if(n == 1) - { - return( bessel_y1(x) ); - } - - tox = 2.0/x; - by =bessel_y1(x); - bym =bessel_y0(x); - for(j = 1;j - DEVICE_CALLABLE FORCE_INLINE - T square(T x) - { - return x*x; - } - - //#ifndef __APPLE__ - DEVICE_CALLABLE FORCE_INLINE - double norm(const double &x) - { - return x*x; - } - - DEVICE_CALLABLE FORCE_INLINE - float norm(const float &x) - { - return x*x; - } - // #endif - - template - DEVICE_CALLABLE FORCE_INLINE - complex euler(const T &x) - { - T sptr, cptr; - sincos(x, &sptr, &cptr); - return complex(cptr, sptr); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_i0(const T &x) - { - T ax, ans; - T y; - - if((ax =fabs(x)) < 3.75) - { - y =x/3.75, y =y*y; - ans = 1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 - +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); - } - else - { - y = 3.75/ax; - ans = (exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 - +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 - +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 - +y*0.392377e-2)))))))); - } - return ans; - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_i1(const T &x) - { - T ax, ans; - T y; - - if((ax =fabs(x)) < 3.75) - { - y =x/3.75, y =y*y; - ans =ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934 - +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3)))))); - } - else - { - y = 3.75/ax; - ans = 0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1 - -y*0.420059e-2)); - ans = 0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2 - +y*(0.163801e-2+y*(-0.1031555e-1+y*ans)))); - ans *= (exp(ax)/sqrt(ax)); - } - return (x < 0.0)?-ans:ans; - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_in(const int &n, const T &x) - { - const T ACC = 40.0; - const T BIGNO = 1.0e10; - const T BIGNI = 1.0e-10; - - int j; - T bi, bim, bip, tox, ans; - - if(n == 0) - { - return( bessel_i0(x) ); - } - if(n == 1) - { - return( bessel_i1(x) ); - } - - if(x == 0.0) - { - return 0.0; - } - else - { - tox = 2.0/fabs(x); - bip =ans = 0.0; - bi = 1.0; - for(j = 2*(n+(int)sqrt(ACC*n)); j>0; j--) - { - bim =bip+j*tox*bi; - bip =bi; - bi =bim; - if(fabs(bi) > BIGNO) - { - ans *= BIGNI; - bi *= BIGNI; - bip *= BIGNI; - } - if(j == n) - { - ans =bip; - } - } - ans *= bessel_i0(x)/bi; - return (x < 0.0 && n%2 == 1)?-ans:ans; - } - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_k0(const T &x) - { - T y, ans; - - if(x <= 2.0) - { - y =x*x/4.0; - ans = (-log(x/2.0)*bessel_i0(x))+(-0.57721566+y*(0.42278420 - +y*(0.23069756+y*(0.3488590e-1+y*(0.262698e-2 - +y*(0.10750e-3+y*0.74e-5)))))); - } - else - { - y = 2.0/x; - ans = (exp(-x)/sqrt(x))*(1.25331414+y*(-0.7832358e-1 - +y*(0.2189568e-1+y*(-0.1062446e-1+y*(0.587872e-2 - +y*(-0.251540e-2+y*0.53208e-3)))))); - } - return ans; - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_k1(const T &x) - { - T y, ans; - - if(x <= 2.0) - { - y =x*x/4.0; - ans = (log(x/2.0)*bessel_i1(x))+(1.0/x)*(1.0+y*(0.15443144 - +y*(-0.67278579+y*(-0.18156897+y*(-0.1919402e-1 - +y*(-0.110404e-2+y*(-0.4686e-4))))))); - } - else - { - y = 2.0/x; - ans = (exp(-x)/sqrt(x))*(1.25331414+y*(0.23498619 - +y*(-0.3655620e-1+y*(0.1504268e-1+y*(-0.780353e-2 - +y*(0.325614e-2+y*(-0.68245e-3))))))); - } - return ans; - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_kn(const int &n, const T &x) - { - int j; - T bk, bkm, bkp, tox; - - if(n == 0) - { - return( bessel_k0(x) ); - } - if(n == 1) - { - return( bessel_k1(x) ); - } - - tox = 2.0/x; - bkm =bessel_k0(x); - bk =bessel_k1(x); - for(j = 1;j +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include + +#include "macros.h" +#include "const_enum.h" + +#ifdef __CUDACC__ + #include + #include + #include + using thrust::complex; + // using thrust::norm; + using thrust::polar; + using thrust::arg; + using thrust::abs; + + template + CGPU_EXEC_INL + T bessel_j0(const T& x) + { + return j0(x); + } + + template + CGPU_EXEC_INL + T bessel_j1(const T& x) + { + return j1(x); + } + + template + CGPU_EXEC_INL + T bessel_jn(const dt_int32& n, const T& x) + { + return jn(n, x); + } + + template + CGPU_EXEC_INL + T bessel_y0(const T& x) + { + return y0(x); + } + + template + CGPU_EXEC_INL + T bessel_y1(const T& x) + { + return y1(x); + } + + template + CGPU_EXEC_INL + T bessel_yn(const dt_int32& n, const T& x) + { + return yn(n, x); + } + + template + CGPU_EXEC_INL + T norm_2(const thrust::complex& z) + { + return thrust::norm(z); + } + + template + CGPU_EXEC_INL + T norm(const thrust::complex& z) + { + return thrust::abs(z); + } +#else + #include + #include + using std::complex; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + using std::cos; + using std::sin; + using std::tan; + using std::acos; + using std::asin; + using std::atan; + using std::atan2; + using std::cosh; + using std::sinh; + using std::tanh; + using std::acosh; + using std::asinh; + using std::atanh; + // using std::norm; + using std::polar; + using std::arg; + using std::abs; + + template + inline void sincos(const T& x, T* sptr, T* cptr) + { + *sptr = sin(x); + *cptr = cos(x); + } + + template + inline T cospi(const T& x) + { + returncos(mt::c_pi*x); + } + + template + inline T sinpi(const T& x) + { + return sin(mt::c_pi*x); + } + + template + inline void sincospi(const T& x, T* sptr, T* cptr) + { + *sptr = sin(mt::c_pi*x); + *cptr = cos(mt::c_pi*x); + } + + using std::exp; + using std::exp2; + + template + inline T exp10(const T& x) + { + return std::pow(static_cast(10), x); + } + + using std::expm1; + using std::frexp; + using std::log; + using std::log2; + using std::log10; + using std::ilogb; + using std::log1p; + using std::logb; + using std::modf; + using std::pow; + using std::sqrt; + + template + inline T rsqrt(const T& x) + { + return T(1)/std::sqrt(x); + } + + using std::cbrt; + using std::hypot; + + template + inline T rhypot(const T& x, const T& y) + { + return T(1)/std::hypot(x, y); + } + + using std::erf; + using std::erfc; + using std::tgamma; + using std::lgamma; + using std::ceil; + using std::floor; + using std::trunc; + using std::round; + using std::lround; + using std::llround; + using std::rint; + using std::lrint; + using std::llrint; + + using std::remainder; + using std::copysign; + using std::fdim; + using std::fmax; + using std::fmin; + using std::fabs; + using std::fma; + using std::fmod; + + template + inline T bessel_j0(const T& x) + { + // host code + T ax, z; + T xx, y, ans, ans1, ans2; + + if ((ax =fabs(x)) < 8.0) + { + y =x*x; + ans1 = 57568490574.0+y*(-13362590354.0+y*(651619640.7 + +y*(-11214424.18+y*(77392.33017+y*(-184.9052456))))); + ans2 = 57568490411.0+y*(1029532985.0+y*(9494680.718 + +y*(59272.64853+y*(267.8532712+y*1.0)))); + ans =ans1/ans2; + } + else + { + z = 8.0/ax; + y =z*z; + xx =ax-0.785398164; + ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 + +y*(-0.2073370639e-5+y*0.2093887211e-6))); + ans2 = -0.1562499995e-1+y*(0.1430488765e-3 + +y*(-0.6911147651e-5+y*(0.7621095161e-6 + -y*0.934935152e-7))); + ans =sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); + } + return ans; + } + + template + inline T bessel_j1(const T& x) + { + T ax, z; + T xx, y, ans, ans1, ans2; + + if ((ax =fabs(x)) < 8.0) + { + y =x*x; + ans1 =x*(72362614232.0+y*(-7895059235.0+y*(242396853.1 + +y*(-2972611.439+y*(15704.48260+y*(-30.16036606)))))); + ans2 = 144725228442.0+y*(2300535178.0+y*(18583304.74 + +y*(99447.43394+y*(376.9991397+y*1.0)))); + ans =ans1/ans2; + } + else + { + z = 8.0/ax; + y =z*z; + xx =ax-2.356194491; + ans1 = 1.0+y*(0.183105e-2+y*(-0.3516396496e-4 + +y*(0.2457520174e-5+y*(-0.240337019e-6)))); + ans2 = 0.04687499995+y*(-0.2002690873e-3 + +y*(0.8449199096e-5+y*(-0.88228987e-6 + +y*0.105787412e-6))); + ans =sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); + if (x < 0.0) + { + ans = -ans; + } + } + return ans; + } + + template + inline T bessel_jn(const dt_int32& n, const T& x) + { + const T ACC = 40.0; + const T BIGNO = 1.0e10; + const T BIGNI = 1.0e-10; + + dt_int32 j, jsum, m; + T ax, bj, bjm, bjp, sum, tox, ans; + + ax = fabs(x); + if (n == 0) + { + return( bessel_j0(ax) ); + } + if (n == 1) + { + return( bessel_j1(ax) ); + } + + if (ax == 0.0) + { + return 0.0; + } + else if (ax > (T) n) + { + tox = 2.0/ax; + bjm =bessel_j0(ax); + bj =bessel_j1(ax); + for(j = 1; j0; j--) + { + bjm = j*tox*bj-bjp; + bjp = bj; + bj = bjm; + if (fabs(bj) > BIGNO) + { + bj *= BIGNI; + bjp *= BIGNI; + ans *= BIGNI; + sum *= BIGNI; + } + if (jsum) + { + sum += bj; + } + jsum =!jsum; + if (j == n) + { + ans =bjp; + } + } + sum = 2.0*sum-bj; + ans /= sum; + } + return x < (0.0 && n%2 == 1)?-ans:ans; + } + + template + inline T bessel_y0(const T& x) + { + T z; + T xx, y, ans, ans1, ans2; + + if (x < 8.0) + { + y =x*x; + ans1 = -2957821389.0+y*(7062834065.0+y*(-512359803.6 + +y*(10879881.29+y*(-86327.92757+y*228.4622733)))); + ans2 = 40076544269.0+y*(745249964.8+y*(7189466.438 + +y*(47447.26470+y*(226.1030244+y*1.0)))); + ans = (ans1/ans2)+0.636619772*bessel_j0(x)*log(x); + } + else + { + z = 8.0/x; + y =z*z; + xx =x-0.785398164; + ans1 = 1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 + +y*(-0.2073370639e-5+y*0.2093887211e-6))); + ans2 = -0.1562499995e-1+y*(0.1430488765e-3 + +y*(-0.6911147651e-5+y*(0.7621095161e-6 + +y*(-0.934945152e-7)))); + ans =sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); + } + return ans; + } + + template + inline T bessel_y1(const T& x) + { + T z; + T xx, y, ans, ans1, ans2; + + if (x < 8.0) + { + y =x*x; + ans1 =x*(-0.4900604943e13+y*(0.1275274390e13 + +y*(-0.5153438139e11+y*(0.7349264551e9 + +y*(-0.4237922726e7+y*0.8511937935e4))))); + ans2 = 0.2499580570e14+y*(0.4244419664e12 + +y*(0.3733650367e10+y*(0.2245904002e8 + +y*(0.1020426050e6+y*(0.3549632885e3+y))))); + ans = (ans1/ans2)+0.636619772*(bessel_j1(x)*log(x)-1.0/x); + } + else + { + z = 8.0/x; + y =z*z; + xx =x-2.356194491; + ans1 = 1.0+y*(0.183105e-2+y*(-0.3516396496e-4 + +y*(0.2457520174e-5+y*(-0.240337019e-6)))); + ans2 = 0.04687499995+y*(-0.2002690873e-3 + +y*(0.8449199096e-5+y*(-0.88228987e-6 + +y*0.105787412e-6))); + ans =sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); + } + return ans; + } + + template + inline T bessel_yn(const dt_int32& n, const T& x) + { + dt_int32 j; + T by, bym, byp, tox; + + if (n == 0) + { + return( bessel_y0(x) ); + } + if (n == 1) + { + return( bessel_y1(x) ); + } + + tox = 2.0/x; + by =bessel_y1(x); + bym =bessel_y0(x); + for(j = 1; j +CGPU_EXEC_INL +T square(const T& x) +{ + return x*x; +} + +template +CGPU_EXEC_INL +T norm_2(const std::complex& z) +{ + return std::norm(z); +} + +template +CGPU_EXEC_INL +T norm(const std::complex& z) +{ + return std::abs(z); +} + +// #ifndef __APPLE__ +template +CGPU_EXEC_INL +T norm_2(const T& x) +{ + return x*x; +} + +template +CGPU_EXEC_INL +T norm(const T& x) +{ + return abs(x); +} + +// #endif + +template +CGPU_EXEC_INL +complex euler(const T& x) +{ + T sptr, cptr; + sincos(x, &sptr, &cptr); + return complex(cptr, sptr); +} + +template +CGPU_EXEC_INL +T bessel_i0(const T& x) +{ + T ax, ans; + T y; + + if ((ax =fabs(x)) < 3.75) + { + y =x/3.75, y =y*y; + ans = 1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 + +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); + } + else + { + y = 3.75/ax; + ans = (exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 + +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 + +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 + +y*0.392377e-2)))))))); + } + return ans; +} + +template +CGPU_EXEC_INL +T bessel_i1(const T& x) +{ + T ax, ans; + T y; + + if ((ax =fabs(x)) < 3.75) + { + y =x/3.75, y =y*y; + ans =ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934 + +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3)))))); + } + else + { + y = 3.75/ax; + ans = 0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1 + -y*0.420059e-2)); + ans = 0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2 + +y*(0.163801e-2+y*(-0.1031555e-1+y*ans)))); + ans *= (exp(ax)/sqrt(ax)); + } + return (x < 0.0)?-ans:ans; +} + +template +CGPU_EXEC_INL +T bessel_in(const dt_int32& n, const T& x) +{ + const T ACC = 40.0; + const T BIGNO = 1.0e10; + const T BIGNI = 1.0e-10; + + dt_int32 j; + T bi, bim, bip, tox, ans; + + if (n == 0) + { + return( bessel_i0(x) ); + } + if (n == 1) + { + return( bessel_i1(x) ); + } + + if (x == 0.0) + { + return 0.0; + } + else + { + tox = 2.0/fabs(x); + bip =ans = 0.0; + bi = 1.0; + for(j = 2*(n+(dt_int32)sqrt(ACC*n)); j>0; j--) + { + bim =bip+j*tox*bi; + bip =bi; + bi =bim; + if (fabs(bi) > BIGNO) + { + ans *= BIGNI; + bi *= BIGNI; + bip *= BIGNI; + } + if (j == n) + { + ans =bip; + } + } + ans *= bessel_i0(x)/bi; + return (x < 0.0 && n%2 == 1)?-ans:ans; + } +} + +template +CGPU_EXEC_INL +T bessel_k0(const T& x) +{ + T y, ans; + + if (x <= 2.0) + { + y =x*x/4.0; + ans = (-log(x/2.0)*bessel_i0(x))+(-0.57721566+y*(0.42278420 + +y*(0.23069756+y*(0.3488590e-1+y*(0.262698e-2 + +y*(0.10750e-3+y*0.74e-5)))))); + } + else + { + y = 2.0/x; + ans = (exp(-x)/sqrt(x))*(1.25331414+y*(-0.7832358e-1 + +y*(0.2189568e-1+y*(-0.1062446e-1+y*(0.587872e-2 + +y*(-0.251540e-2+y*0.53208e-3)))))); + } + return ans; +} + +template +CGPU_EXEC_INL +T bessel_k1(const T& x) +{ + T y, ans; + + if (x <= 2.0) + { + y =x*x/4.0; + ans = (log(x/2.0)*bessel_i1(x))+(1.0/x)*(1.0+y*(0.15443144 + +y*(-0.67278579+y*(-0.18156897+y*(-0.1919402e-1 + +y*(-0.110404e-2+y*(-0.4686e-4))))))); + } + else + { + y = 2.0/x; + ans = (exp(-x)/sqrt(x))*(1.25331414+y*(0.23498619 + +y*(-0.3655620e-1+y*(0.1504268e-1+y*(-0.780353e-2 + +y*(0.325614e-2+y*(-0.68245e-3))))))); + } + return ans; +} + +template +CGPU_EXEC_INL +T bessel_kn(const dt_int32& n, const T& x) +{ + dt_int32 j; + T bk, bkm, bkp, tox; + + if (n == 0) + { + return( bessel_k0(x) ); + } + if (n == 1) + { + return( bessel_k1(x) ); + } + + tox = 2.0/x; + bkm = bessel_k0(x); + bk = bessel_k1(x); + for(j = 1; j - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef MATLAB_MEX_H -#define MATLAB_MEX_H - -#include -#include -#include - -#include "types.cuh" -#include "traits.cuh" -#include "lin_alg_def.cuh" -#include "matlab_types.cuh" -#include "stream.cuh" -#include - -using mt::rmatrix_r; -using mt::rmatrix_c; -using mt::r3d; - -/**************************************************************************/ -template -void mx_print(const TVector &vector) -{ - for(auto i = 0; i(mxGetM(mxB)*mxGetN(mxB)); -} - -/**************************************************************************/ -template -T mx_get_scalar(const mxArray *mxB) -{ - auto data = static_cast(std::round(mxGetScalar(mxB))); - return static_cast(data); -} - -template <> -int mx_get_scalar(const mxArray *mxB) -{ - return static_cast(std::round(mxGetScalar(mxB))); -} - -template <> -double mx_get_scalar(const mxArray *mxB) -{ - return mxGetScalar(mxB); -} - -template <> -float mx_get_scalar(const mxArray *mxB) -{ - return static_cast(mxGetScalar(mxB)); -} - -/**************************************************************************/ -template -T mx_get_matrix(const mxArray *mxB){}; - -template <> -rmatrix_r mx_get_matrix(const mxArray *mxB) -{ - mt::rmatrix_r matrix; - matrix.rows = static_cast(mxGetM(mxB)); - matrix.cols = static_cast(mxGetN(mxB)); - matrix.m_size = matrix.rows*matrix.cols; - matrix.real = mxGetPr(mxB); - - return matrix; -} - -template <> -rmatrix_c mx_get_matrix(const mxArray *mxB) -{ - mt::rmatrix_c matrix; - matrix.rows = static_cast(mxGetM(mxB)); - matrix.cols = static_cast(mxGetN(mxB)); - matrix.m_size = matrix.rows*matrix.cols; - matrix.real = mxGetPr(mxB); - matrix.imag = mxGetPi(mxB); - - return matrix; -} - -/**************************************************************************/ -bool mx_field_exits(const mxArray *mxB, const int &idx, const char *field_name) -{ - const mxArray *fPtr = mxGetField(mxB, idx, field_name); - - return (fPtr!=nullptr); -} - -bool mx_field_exits(const mxArray *mxB, const char *field_name) -{ - return mx_field_exits(mxB, 0, field_name); -} - -template -T mx_get_scalar_field(const mxArray *mxB, const int &idx, const char *field_name) -{ - const mxArray *fPtr = mxGetField(mxB, idx, field_name); - - if(fPtr==nullptr) - { - return T(0); - } - else - { - return mx_get_scalar(fPtr); - } -} - -template -T mx_get_scalar_field(const mxArray *mxB, const char *field_name) -{ - return mx_get_scalar_field(mxB, 0, field_name); -} - -/**************************************************************************/ -template -T mx_get_matrix_field(const mxArray *mxB, const int &idx, const char *field_name) -{ - mxArray *mx_matrix = mxGetField(mxB, idx, field_name); - - return mx_get_matrix(mx_matrix); -} - -template -T mx_get_matrix_field(const mxArray *mxB, const char *field_name) -{ - return mx_get_matrix_field(mxB, 0, field_name); -} - - -template -r3d mx_get_r3d_field(const mxArray *mxB, const char *field_name) -{ - auto r = mx_get_matrix_field(mxB, field_name); - return r3d(r[0], r[1], r[2]); -} - -/**************************************************************************/ -template -T mx_create_matrix(const int &rows, const int &cols, mxArray *&mx_M); - -template <> -rmatrix_r mx_create_matrix(const int &rows, const int &cols, mxArray *&mx_M) -{ - mx_M = mxCreateDoubleMatrix(rows, cols, mxREAL); - - return mx_get_matrix(mx_M); -} - -template <> -rmatrix_c mx_create_matrix(const int &rows, const int &cols, mxArray *&mx_M) -{ - mx_M = mxCreateDoubleMatrix(rows, cols, mxCOMPLEX); - - return mx_get_matrix(mx_M); -} - -template -T mx_create_scalar(mxArray *&mx_M) -{ - return mx_create_matrix(1, 1, mx_M); -} - -template -T mx_create_matrix(TGrid &grid_2d, mxArray *&mx_M) -{ - return mx_create_matrix(grid_2d.ny, grid_2d.nx, mx_M); -} - -/**************************************************************************/ -template -inline T mx_create_matrix_field(mxArray *mx_struct, const int &idx, const char *field_name, const int &rows, const int &cols) -{ - mxArray *mxfield; - T rmatrix = mx_create_matrix(rows, cols, mxfield); - mxSetField(mx_struct, idx, field_name, mxfield); - return rmatrix; -} - -template -inline T mx_create_matrix_field(mxArray *mx_struct, const char *field_name, const int &rows, const int &cols) -{ - return mx_create_matrix_field(mx_struct, 0, field_name, rows, cols); -} - -template -inline T mx_create_scalar_field(mxArray *mx_struct, const int &idx, const char *field_name) -{ - return mx_create_matrix_field(mx_struct, idx, field_name, 1, 1); -} - -template -inline T mx_create_scalar_field(mxArray *mx_struct, const char *field_name) -{ - return mx_create_scalar_field(mx_struct, 0, field_name); -} - -/**************************************************************************/ -template -inline void mx_create_set_matrix_field(mxArray *mx_struct, const int &idx, -const char *field_name, const int &rows, const int &cols, TVector &field_value) -{ - mxArray *mxfield; - T matrix = mx_create_matrix(rows, cols, mxfield); - mt::Stream stream(1); - mt::copy_to_host(stream, field_value, matrix); - mxSetField(mx_struct, idx, field_name, mxfield); -} - -template -inline void mx_create_set_matrix_field(mxArray *mx_struct, const char *field_name, -const int &rows, const int &cols, TVector &field_value) -{ - mx_create_set_matrix_field(mx_struct, 0, field_name, rows, cols, field_value); -} - -template -inline void mx_create_set_scalar_field(mxArray *mx_struct, const int &idx, -const char *field_name, const double &field_value) -{ - mxArray *mxfield; - T matrix = mx_create_scalar(mxfield); - *(matrix.real) = field_value; - mxSetField(mx_struct, idx, field_name, mxfield); -} - -template -inline void mx_create_set_scalar_field(mxArray *mx_struct, const char *field_name, -const double &field_value) -{ - mx_create_set_scalar_field(mx_struct, 0, field_name, field_value); -} - -/**************************************************************************/ -namespace mt -{ - System_Configuration read_system_conf(const mxArray *mx_input) - { - System_Configuration system_conf; - - if(mxIsStruct(mx_input) && mx_field_exits(mx_input, "precision")) - { - system_conf.device = mx_get_scalar_field(mx_input, "device"); - system_conf.precision = mx_get_scalar_field(mx_input, "precision"); - system_conf.cpu_ncores = 1; - //system_conf.cpu_ncores = mx_get_scalar_field(mx_input, "cpu_ncores"); - system_conf.cpu_nthread = mx_get_scalar_field(mx_input, "cpu_nthread"); - system_conf.gpu_device = mx_get_scalar_field(mx_input, "gpu_device"); - system_conf.gpu_nstream = 0; - //system_conf.gpu_nstream = mx_get_scalar_field(mx_input, "gpu_nstream"); - system_conf.active = true; - } - else - { - system_conf.cpu_nthread = 4; - system_conf.active = false; - } - system_conf.validate_parameters(); - system_conf.set_device(); - - return system_conf; - } -} - -#endif \ No newline at end of file diff --git a/src/matlab_mex.h b/src/matlab_mex.h new file mode 100755 index 00000000..e2f482c9 --- /dev/null +++ b/src/matlab_mex.h @@ -0,0 +1,1708 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include +#include + +#include "const_enum.h" +#include "type_traits_gen.h" +#include "math_mt.h" +#include "memcpy.cuh" +#include "r_2d.h" +#include "r_3d.h" +#include "vctr_cpu.h" +#include "vctr_gpu.h" +#include "system_config.h" + +#include + +template +mt::enable_if_real +mex_print(T* ptr, dt_int32 n) +{ + for(auto ik = 0; ik +mt::enable_if_real +mex_print(const mt::pVctr_cpu_64& vector) +{ + for(auto ik = 0; ik +mt::enable_if_cmplx +mex_print(const mt::pVctr_cpu_64& vector) +{ + for(auto ik = 0; ik 0)?static_cast(dim[0]):0; +} + +CPU_EXEC_INL +dt_uint32 mex_get_s1(const mxArray* mxA) +{ + auto n_dim = mxGetNumberOfDimensions(mxA); + auto dim = mxGetDimensions(mxA); + + return (n_dim>1)?static_cast(dim[1]):0; +} + +CPU_EXEC_INL +dt_uint32 mex_get_s2(const mxArray* mxA) +{ + auto n_dim = mxGetNumberOfDimensions(mxA); + auto dim = mxGetDimensions(mxA); + + return (n_dim>2)?static_cast(dim[2]):0; +} + +CPU_EXEC_INL +dt_uint32 mex_get_s3(const mxArray* mxA) +{ + auto n_dim = mxGetNumberOfDimensions(mxA); + auto dim = mxGetDimensions(mxA); + + return (n_dim>3)?static_cast(dim[3]):0; +} + +CPU_EXEC_INL +dt_shape mex_get_mx_shape(const mxArray* mxA) +{ + auto n_dim = min(mwSize(4), mxGetNumberOfDimensions(mxA)); + auto dim = mxGetDimensions(mxA); + + dt_shape shape{1, 1, 1, 1}; + + for (auto ik = 0; ik mex_get_mx_shape_uint64(const mxArray* mxA) +{ + auto n_dim = min(mwSize(4), mxGetNumberOfDimensions(mxA)); + auto dim = mxGetDimensions(mxA); + + dt_shape_st shape{1, 1, 1, 1}; + + for (auto ik = 0; ik +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return mt::pVctr_cpu_64(); +} + +/***************************************************************************************/ +/************************************ get real data ************************************/ +/***************************************************************************************/ +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetInt8s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetUint8s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetInt16s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetUint16s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetInt32s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetUint32s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetInt64s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetUint64s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetSingles(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetDoubles(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +/***************************************************************************************/ +/********************************** get complex data ***********************************/ +/***************************************************************************************/ +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexInt8s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexUint8s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexInt16s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexUint16s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexInt32s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexUint32s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexInt64s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexUint64s(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexSingles(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +template <> +mt::pVctr_cpu_64 mex_get_pvctr(const mxArray* mxA) +{ + return {reinterpret_cast(mxGetComplexDoubles(mxA)), mex_get_mx_shape_uint64(mxA)}; +} + +/***************************************************************************************/ +/*********************************** read data type ************************************/ +/***************************************************************************************/ +eData_Typ mex_get_data_type(const mxArray* mxA) +{ + auto category = mxGetClassID(mxA); + + if (mxIsComplex(mxA)) + { + switch (category) + { + case mxINT8_CLASS: + { + return edt_cint8; + } + case mxUINT8_CLASS: + { + return edt_cuint8; + } + case mxINT16_CLASS: + { + return edt_cint16; + } + case mxUINT16_CLASS: + { + return edt_cuint16; + } + case mxINT32_CLASS: + { + return edt_cint32; + } + case mxUINT32_CLASS: + { + return edt_cuint32; + } + case mxINT64_CLASS: + { + return edt_cint64; + } + case mxUINT64_CLASS: + { + return edt_cuint64; + } + case mxSINGLE_CLASS: + { + return edt_cfloat32; + } + case mxDOUBLE_CLASS: + { + return edt_cfloat64; + } + } + } + else + { + switch (category) + { + case mxLOGICAL_CLASS: + { + return edt_bool; + } + case mxINT8_CLASS: + { + return edt_int8; + } + case mxUINT8_CLASS: + { + return edt_uint8; + } + case mxINT16_CLASS: + { + return edt_int16; + } + case mxUINT16_CLASS: + { + return edt_uint16; + } + case mxINT32_CLASS: + { + return edt_int32; + } + case mxUINT32_CLASS: + { + return edt_uint32; + } + case mxINT64_CLASS: + { + return edt_int64; + } + case mxUINT64_CLASS: + { + return edt_uint64; + } + case mxSINGLE_CLASS: + { + return edt_float32; + } + case mxDOUBLE_CLASS: + { + return edt_float64; + } + } + } + + return edt_none; +} + +eData_Typ mex_get_data_type_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_data_type(mxGetField(mxA, idx, field_name)); + + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return edt_none; + } +} + +eData_Typ mex_get_data_type_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_data_type_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +/********************** Vector: template for reading matlab data ***********************/ +/***************************************************************************************/ +template +mt::Vctr_cpu mex_get_vctr(const mxArray* mxA) +{ + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_bool: + { + return mex_get_pvctr(mxA); + } + case edt_int8: + { + return mex_get_pvctr(mxA); + } + case edt_uint8: + { + return mex_get_pvctr(mxA); + } + case edt_int16: + { + return mex_get_pvctr(mxA); + } + case edt_uint16: + { + return mex_get_pvctr(mxA); + } + case edt_int32: + { + return mex_get_pvctr(mxA); + } + case edt_uint32: + { + return mex_get_pvctr(mxA); + } + case edt_int64: + { + return mex_get_pvctr(mxA); + } + case edt_uint64: + { + return mex_get_pvctr(mxA); + } + case edt_float32: + { + return mex_get_pvctr(mxA); + } + case edt_float64: + { + return mex_get_pvctr(mxA); + } + } + + return mt::Vctr_cpu(); +} + +template +mt::Vctr_r_2d_cpu mex_get_vctr_r_2d(const mxArray* mxA) +{ + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_bool: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + } + + return mt::Vctr_cpu(); +} + +template +mt::Vctr_r_3d_cpu mex_get_vctr_r_3d(const mxArray* mxA) +{ + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_bool: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint8: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint16: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_int64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_uint64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float32: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + case edt_float64: + { + auto ptr = mex_get_pvctr(mxA); + return {ptr.data(), ptr.s0()}; + } + } + + return mt::Vctr_cpu(); +} + +/***************************************************************************************/ +/********************************** get dimensions *************************************/ +/***************************************************************************************/ +mt::Vctr_cpu mex_get_vctr_shape(const mxArray* mxA) +{ + return mex_get_vctr(mxA); +} + +dt_shape mex_get_shape(const mxArray* mxA) +{ + auto dim = mex_get_vctr(mxA); // nx, ny, nz + auto n_dim = min(4, dim.size_32()); + + dt_shape shape{1, 1, 1, 1}; + + for (auto ik = 0; ik(std::round(mxGetScalar(mxA))); + return data > 0; +} + +/***************************************************************************************/ +/*********************************** get enumeration ***********************************/ +/***************************************************************************************/ +template +T mex_get_enum(const mxArray* mxA) +{ + auto data = static_cast(std::round(mxGetScalar(mxA))); + return static_cast(data); +} + +/***************************************************************************************/ +/************************************ get number ***************************************/ +/***************************************************************************************/ +template +T mex_get_num(const mxArray* mxA) +{ + auto data = static_cast(std::round(mxGetScalar(mxA))); + return static_cast(data); +} + +template <> +dt_int32 mex_get_num(const mxArray* mxA) +{ + return static_cast(std::round(mxGetScalar(mxA))); +} + +template <> +dt_float32 mex_get_num(const mxArray* mxA) +{ + return static_cast(mxGetScalar(mxA)); +} + +template <> +dt_float64 mex_get_num(const mxArray* mxA) +{ + return mxGetScalar(mxA); +} + +dt_cfloat64 mex_get_cmplx_num(const mxArray* mxA) +{ + auto data_type = mex_get_data_type(mxA); + + switch (data_type) + { + case edt_cint8: + { + auto r = mxGetComplexInt8s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint8: + { + auto r = mxGetComplexUint8s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cint16: + { + auto r = mxGetComplexInt16s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint16: + { + auto r = mxGetComplexUint16s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cint32: + { + auto r = mxGetComplexInt32s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint32: + { + auto r = mxGetComplexUint32s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cint64: + { + auto r = mxGetComplexInt64s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cuint64: + { + auto r = mxGetComplexUint64s(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cfloat32: + { + auto r = mxGetComplexSingles(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + case edt_cfloat64: + { + auto r = mxGetComplexDoubles(mxA); + return {dt_float64(r[0].real), dt_float64(r[0].imag)}; + } + default: + { + return {mxGetScalar(mxA), dt_float64(0)}; + } + } + + return {dt_float64(0), dt_float64(0)}; +} + +template <> +dt_cfloat32 mex_get_num(const mxArray* mxA) +{ + auto num = mex_get_cmplx_num(mxA); + + return {dt_float32(num.real()), dt_float32(num.imag())}; +} + +template <> +dt_cfloat64 mex_get_num(const mxArray* mxA) +{ + auto num = mex_get_cmplx_num(mxA); + + return {num.real(), num.imag()}; +} + +/***************************************************************************************/ +/******************************** get r_2d/r_3d data ***********************************/ +/***************************************************************************************/ +template +mt::R_2d mex_get_r_2d(const mxArray* mxA, mt::R_2d r_0 = mt::R_2d(0, 0)) +{ + if (mxA!=nullptr) + { + auto pvctr = mex_get_vctr(mxA); + return (pvctr.size()>=2)?mt::R_2d(pvctr.data()):r_0; + } + else + { + return r_0; + } +} + +template +mt::R_3d mex_get_r_3d(const mxArray* mxA, mt::R_3d r_0 = mt::R_3d(0, 0, 0)) +{ + if (mxA!=nullptr) + { + auto vctr = mex_get_vctr(mxA); + return (vctr.size()>=3)?mt::R_3d(vctr.data()):r_0; + } + else + { + return r_0; + } +} + +/***************************************************************************************/ +/******************************** get repeat r_2d/r_3d ********************************/ +/***************************************************************************************/ +template +mt::R_2d mex_get_r_2d_rep(const mxArray* mxA) +{ + const auto vctr = mex_get_vctr(mxA); + const auto n_vctr = vctr.size_32(); + + if (n_vctr<1) + return {1, 1}; + else if (n_vctr<2) + return {vctr[0], vctr[0]}; + else + return {vctr[0], vctr[1]}; +} + +template +mt::R_3d mex_get_r_3d_rep(const mxArray* mxA) +{ + const auto vctr = mex_get_vctr(mxA); + const auto n_vctr = vctr.size_32(); + + if (n_vctr<1) + return {1, 1}; + else if (n_vctr<2) + return {vctr[0], vctr[0], vctr[0]}; + else if (n_vctr<3) + return {vctr[0], vctr[1], vctr[1]}; + else + return {vctr[0], vctr[1], vctr[2]}; +} + +/***************************************************************************************/ +/*********************************** get box size **************************************/ +/***************************************************************************************/ +template +mt::R_3d mex_get_r_3d_bs(const mxArray* mxA, mt::R_3d f) +{ + return mex_get_r_3d_rep(mxA)*f; +} + +template +mt::R_3d mex_get_r_3d_bs(const mxArray* mxA, mt::Vctr_cpu& f) +{ + return mex_get_r_3d_bs(mxA, mt::R_3d(f.m_data, f.size_32())); +} + +template +mt::R_3d mex_get_r_3d_bs(const mxArray* mxA, const dt_shape_st& shape) +{ + return mex_get_r_3d_bs(mxA, mt::R_3d(shape[1], shape[0], shape[2])); +} + +/***************************************************************************************/ +/************************************ get r center *************************************/ +/***************************************************************************************/ +template +mt::R_3d mex_get_r_3d_r_c(const mxArray* mxA, mt::R_3d r_c_0 = mt::R_3d(0, 0, 0)) +{ + const auto vctr = mex_get_vctr(mxA); + const dt_int32 n_vctr = vctr.size_32(); + mt::R_3d r = r_c_0; + + if (n_vctr<2) + r = mt::R_3d(vctr[0], vctr[0], vctr[0]); + else if (n_vctr<3) + r = mt::R_3d(vctr[0], vctr[1], vctr[1]); + else if (n_vctr<3) + r = mt::R_3d(vctr[0], vctr[1], vctr[2]); + + return r; +} + +/***************************************************************************************/ +/********************************** get data by field **********************************/ +/***************************************************************************************/ +template +mt::pVctr_cpu_64 mex_get_pvctr_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_pvctr(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_pvctr(nullptr); + } +} + +template +mt::pVctr_cpu_64 mex_get_pvctr_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_pvctr_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +template +mt::Vctr_cpu mex_get_vctr_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_vctr(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_vctr(nullptr); + } +} + +template +mt::Vctr_cpu mex_get_vctr_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_pvctr_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +template +mt::Vctr_r_2d_cpu mex_get_vctr_r_2d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_vctr_r_2d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_vctr_r_2d(nullptr); + } +} + +template +mt::Vctr_r_2d_cpu mex_get_vctr_r_2d_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_vctr_r_2d_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +template +mt::Vctr_r_3d_cpu mex_get_vctr_r_3d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_vctr_r_3d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_vctr_r_3d(nullptr); + } +} + +template +mt::Vctr_r_3d_cpu mex_get_vctr_r_3d_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_vctr_r_3d_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +dt_bool mex_get_bool_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, idx, field_name)) + { + return mex_get_bool(mxGetField(mxA, idx, field_name)); + } + else + { + return false; + } +} + +dt_bool mex_get_bool_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_bool_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +template +T mex_get_enum_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, idx, field_name)) + { + return mex_get_enum(mxGetField(mxA, idx, field_name)); + } + else + { + return T(0); + } +} + +template +T mex_get_enum_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_enum_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +template +T mex_get_num_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, idx, field_name)) + { + return mex_get_num(mxGetField(mxA, idx, field_name)); + } + else + { + return T(0); + } +} + +template +T mex_get_num_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_num_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +template +mt::R_2d mex_get_r_2d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name, mt::R_2d r_d = mt::R_2d(0, 0)) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_2d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_2d(nullptr); + } +} + +template +mt::R_2d mex_get_r_2d_from_field(const mxArray* mxA, const char *field_name, mt::R_2d r_d = mt::R_2d(0, 0)) +{ + return mex_get_r_2d_from_field(mxA, 0, field_name, r_d); +} + +/***************************************************************************************/ +template +mt::R_3d mex_get_r_3d_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name, mt::R_3d r_d = mt::R_3d(0, 0, 0)) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_3d(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_3d(nullptr); + } +} + +template +mt::R_3d mex_get_r_3d_from_field(const mxArray* mxA, const char *field_name, mt::R_3d r_d = mt::R_3d(0, 0, 0)) +{ + return mex_get_r_3d_from_field(mxA, 0, field_name, r_d); +} + +/***************************************************************************************/ +template +mt::R_2d mex_get_r_2d_rep_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_2d_rep(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_2d_rep(nullptr); + } +} + +template +mt::R_2d mex_get_r_2d_rep_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_r_2d_rep_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +template +mt::R_3d mex_get_r_3d_rep_from_field(const mxArray* mxA, const dt_int32& idx, const char *field_name) +{ + if (mex_field_exist(mxA, field_name)) + { + return mex_get_r_3d_rep(mxGetField(mxA, idx, field_name)); + } + else + { + mexPrintf("Field name '%s' do not exist\n", field_name); + return mex_get_r_3d_rep(nullptr); + } +} + +template +mt::R_3d mex_get_r_3d_rep_from_field(const mxArray* mxA, const char *field_name) +{ + return mex_get_r_3d_rep_from_field(mxA, 0, field_name); +} + +/***************************************************************************************/ +/************************ template for creation of matlab data *************************/ +/***************************************************************************************/ +template +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + return mt::pVctr_cpu_64(mex_data); +} + +/***************************************************************************************/ +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT8_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT8_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT16_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT16_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT32_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT32_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT64_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT64_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxSINGLE_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxDOUBLE_CLASS, mxREAL); + + return mex_get_pvctr(mex_data); +} + +/***************************************************************************************/ +/******************************* create complex data ***********************************/ +/***************************************************************************************/ +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT8_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT8_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT16_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT16_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT32_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT32_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxINT64_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxUINT64_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxSINGLE_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template <> +mt::pVctr_cpu_64 mex_create_pVctr(dt_shape_64 shape, mxArray*& mex_data) +{ + mex_data = mxCreateNumericArray(shape.dim(), shape.data(), mxDOUBLE_CLASS, mxCOMPLEX); + + return mex_get_pvctr(mex_data); +} + +template +mt::pVctr_cpu_64 mex_create_num(mxArray*& mex_data) +{ + return mex_create_pVctr({1, 1}, mex_data); +} + +/***************************************************************************************/ +/**************************** create number/r_2d/r_3d data *****************************/ +/***************************************************************************************/ +template +mt::pVctr_cpu_64 mex_create_r_2d(mxArray*& mex_data) +{ + return mex_create_pVctr({2, 1}, mex_data); +} + +template +mt::pVctr_cpu_64 mex_create_r_3d(mxArray*& mex_data) +{ + return mex_create_pVctr({3, 1}, mex_data); +} + +/***************************************************************************************/ +template +mt::enable_if_number> +mex_create_set_pVctr(mxArray*& mex_data, const mt::pVctr_cpu_64& vctr) +{ + auto pdata = mex_create_pVctr(vctr.shape(), mex_data); + mt::memcpy_cpu_cpu(pdata.data(), vctr.data(), vctr.size()); + + return pdata; +} + +template +mt::enable_if_r_2d> +mex_create_set_pVctr(mxArray*& mex_data, const mt::pVctr_cpu_64& vctr) +{ + auto pdata = mex_create_pVctr({vctr.size(), 2}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr.data(), vctr.size()); + + return pdata; +} + +template +mt::enable_if_r_3d> +mex_create_set_pVctr(mxArray*& mex_data, const mt::pVctr_cpu_64& vctr) +{ + auto pdata = mex_create_pVctr({vctr.size(), 3}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr.data(), vctr.size()); + + return pdata; +} + +template +mt::pVctr_cpu_64 mex_create_set_pVctr(mxArray*& mex_data, const mt::Vctr_r_2d& vctr_r_2d) +{ + auto pdata = mex_create_pVctr({vctr_r_2d.size(), 2}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr_r_2d.data(), vctr_r_2d.size()); + + return pdata; +} + +template +mt::pVctr_cpu_64 mex_create_set_pVctr(mxArray*& mex_data, const mt::Vctr_r_3d& vctr_r_3d) +{ + auto pdata = mex_create_pVctr({vctr_r_3d.size(), 3}, mex_data); + mt::memcpy_pos_cpu_cpu(pdata.data(), vctr_r_3d.data(), vctr_r_3d.size()); + + return pdata; +} + +template +mt::pVctr_cpu_64 mex_create_set_num(mxArray*& mex_data, const U& val) +{ + auto pval = mex_create_num(mex_data); + pval[0] = T(val); + + return pval; +} + +/***************************************************************************************/ +template +mt::pVctr_cpu_64 mex_create_pVctr_field(dt_shape_64 shape, mxArray*& mex_data, const dt_int32& idx, const char *field_name) +{ + mxArray* mxfield = nullptr; + auto pfield = mex_create_pVctr(shape, mxfield); + mxSetField(mex_data, idx, field_name, mxfield); + + return pfield; +} + +template +mt::pVctr_cpu_64 mex_create_pVctr_field(dt_shape_64 shape, mxArray*& mex_data, const char *field_name) +{ + return mex_create_pVctr_field(shape, mex_data, 0, field_name); +} + +template +mt::pVctr_cpu_64 mex_create_num_field(mxArray*& mex_data, const dt_int32& idx, const char *field_name) +{ + return mex_create_pVctr_field({1, 1}, mex_data, 0, field_name); +} + +template +mt::pVctr_cpu_64 mex_create_num_field(mxArray*& mex_data, const char *field_name) +{ + return mex_create_num_field(mex_data, 0, field_name); +} + +/***************************************************************************************/ +template +mt::pVctr_cpu_64 mex_create_set_pVctr_field(mxArray*& mex_data, const dt_int32& idx, const char *field_name, const mt::pVctr_cpu_64& field_value) +{ + auto pdata = mex_create_pVctr_field(field_value.shape(), mex_data, idx, field_name); + mt::memcpy_cpu_cpu(pdata.data(), field_value.data(), field_value.size()); + + return pdata; +} + +template +mt::pVctr_cpu_64 mex_create_set_pVctr_field(mxArray*& mex_data, const char *field_name, const mt::pVctr_cpu_64& field_value) +{ + return mex_create_set_pVctr_field(mex_data, 0, field_name, field_value); +} + +template +mt::pVctr_cpu_64 mex_create_set_num_field(mxArray*& mex_data, const dt_int32& idx, const char *field_name, const U& field_value) +{ + auto pdata = mex_create_num_field(mex_data, idx, field_name); + pdata[0] = field_value; + + return pdata; +} + +template +mt::pVctr_cpu_64 mex_create_set_num_field(mxArray*& mex_data, const char *field_name, const U& field_value) +{ + return mex_create_set_num_field(mex_data, 0, field_name, field_value); +} + +/***************************************************************************************/ +/********************************** run mexFunction ************************************/ +/***************************************************************************************/ +#define MEX_RUN_FCN_INT(FCN, idx) \ +{ \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + } \ + } \ +} + +#define MEX_RUN_FCN_FLOAT(FCN, idx) \ +{ \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxSINGLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxDOUBLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + default: \ + { \ + mexPrintf("Error: Input data must be floating point\n"); \ + } \ + break; \ + } \ + } \ +} + +#define MEX_RUN_FCN_FLOAT_OUT(FCN, idx) \ +{ \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxSINGLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + default: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + } \ + } \ +} + +#define MEX_RUN_FCN_REAL(FCN, idx) \ +{ \ + if (mxIsNumeric(prhs[idx])) \ + { \ + auto category = mxGetClassID(prhs[idx]); \ + \ + switch (category) \ + { \ + case mxINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT8_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT16_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT32_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxUINT64_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxSINGLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + case mxDOUBLE_CLASS: \ + { \ + FCN(nlhs, plhs, nrhs, prhs); \ + } \ + break; \ + } \ + } \ +} + + +/***************************************************************************************/ +/**************************** mex system configuration *********************************/ +/***************************************************************************************/ +dt_bool mex_is_system_config(const mxArray* mxA) +{ + return mxIsStruct(mxA) && mex_field_exist(mxA, "device") && mex_field_exist(mxA, "precision"); +} + +mt::System_Config mex_read_system_config(const mxArray* mex_in) +{ + mt::System_Config system_config; + + if (mex_is_system_config(mex_in)) + { + system_config.device = mex_get_num_from_field(mex_in, "device"); + system_config.precision = mex_get_num_from_field(mex_in, "precision"); + // system_config.cpu_n_proc = 1; + system_config.cpu_n_proc = mex_get_num_from_field(mex_in, "cpu_n_proc"); + system_config.cpu_n_thread = mex_get_num_from_field(mex_in, "cpu_n_thread"); + + auto gpu_device = mex_get_pvctr_from_field(mex_in, "gpu_device"); + system_config.gpu_device.assign(gpu_device.begin(), gpu_device.end()); + system_config.gpu_n_stream = 1; + // system_config.gpu_n_stream = mex_get_num_from_field(mex_in, "gpu_n_stream"); + system_config.idx_0 = 1; + + system_config.set_dep_var(); + } + else + { + system_config.cpu_n_thread = 1; + system_config.idx_0 = 0; + } + + return system_config; +} + +mt::System_Config mex_read_set_system_config(const mxArray* mex_in) +{ + auto system_config = mex_read_system_config(mex_in); + + if (system_config.is_gpu()) + { + system_config.set_gpu(); + } + + return system_config; +} + +/***************************************************************************************/ +/*************** this option set the output type using the in data ******************/ +/***************************************************************************************/ +#define MEX_RUN_FCN_INT_SYS_CONF_IN_TYP(FCN, idx_0) \ +{ \ + auto bb_system_config = mex_is_system_config(prhs[0]); \ + auto idx = (bb_system_config)?idx_0+1:idx_0; \ + MEX_RUN_FCN_INT(FCN, idx); \ +} + +#define MEX_RUN_FCN_FLOAT_SYS_CONF_IN_TYP(FCN, idx_0) \ +{ \ + auto bb_system_config = mex_is_system_config(prhs[0]); \ + auto idx = (bb_system_config)?idx_0+1:idx_0; \ + MEX_RUN_FCN_FLOAT(FCN, idx); \ +} + +#define MEX_RUN_FCN_REAL_SYS_CONF_IN_TYP(FCN, idx_0) \ +{ \ + auto bb_system_config = mex_is_system_config(prhs[0]); \ + auto idx = (bb_system_config)?idx_0+1:idx_0; \ + MEX_RUN_FCN_REAL(FCN, idx); \ +} + +/***************************************************************************************/ +/************ this option set the output type using system configuration ***************/ +/***************************************************************************************/ +#define MEX_RUN_FCN_DEV(system_config, FCN, T) \ +if (system_config.is_cpu()) \ +{ \ + FCNsystem_config, (nlhs, plhs, nrhs, prhs); \ +} \ +else if (system_config.is_gpu()) \ +{ \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ +} + +#ifdef __CUDACC__ +#define MEX_RUN_FCN_FLOAT_SYS_CONF(FCN, idx_0) \ +{ \ + auto system_config = mex_read_set_system_config(prhs[idx_0]); \ + \ + if (system_config.is_float32_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float64_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float32_gpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float64_gpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ +} +#else +#define MEX_RUN_FCN_FLOAT_SYS_CONF(FCN, idx_0) \ +{ \ + auto system_config = mex_read_set_system_config(prhs[idx_0]); \ + \ + if (system_config.is_float32_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ + else if (system_config.is_float64_cpu()) \ + { \ + FCN(system_config, nlhs, plhs, nrhs, prhs); \ + } \ +} +#endif \ No newline at end of file diff --git a/src/matlab_multem_io.cuh b/src/matlab_multem_io.cuh new file mode 100755 index 00000000..06921d6f --- /dev/null +++ b/src/matlab_multem_io.cuh @@ -0,0 +1,356 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include +#include + +#include "types_mt.cuh" +#include "type_traits_gen.h" +#include "r_2d.h" +#include "r_3d.h" +#include "rot_in_parm.hpp" +#include "atomic_vib.hpp" +#include "beam_pos_2d.hpp" +#include "scan_pat.hpp" +#include "spec_slic_in_parm.hpp" +#include "lens.cuh" +#include "particles.cuh" + +#include +#include "matlab_mex.h" + +/************************ read beam positions *************************/ +template +void mex_read_beam_pos(const mxArray* mex_array, mt::Beam_Pos_2d& beam_pos) +{ + auto pbeam_pos = mex_get_pvctr_from_field(mex_array, "beam_pos"); + beam_pos.set_in_data(pbeam_pos); +} + +/************************ read user define wave ************************/ +template +void mex_read_user_define_wave(const mxArray* mex_array, mt::Vctr_cpu& psi) +{ + auto ppsi = mex_get_pvctr_from_field(mex_array, "iw_psi"); + psi.assign(ppsi); +} + +/*********************** read specimen thickness ***********************/ +template +void mex_read_spec_thick(const mxArray* mex_array, mt::Vctr_cpu& thick) +{ + auto pthick = mex_get_pvctr_from_field(mex_array, "thick"); + thick.assign(pthick); +} + +/************************** read output area ***************************/ +void mex_read_output_area(const mxArray* mex_array, mt::iThread_Rect_2d& output_area) +{ + const auto ip_0 = mex_get_vctr_from_field(mex_array, "output_area_ip_0"); + const auto ip_e = mex_get_vctr_from_field(mex_array, "output_area_ip_e"); + + output_area.ix_0 = static_cast(ip_0[0])-1; + output_area.iy_0 = static_cast(ip_0[1])-1; + output_area.ix_e = static_cast(ip_e[0])-1; + output_area.iy_e = static_cast(ip_e[1])-1; +} + +/********************** atomic vibration model ************************/ +void mex_read_atomic_vib(const mxArray* mex_array, mt::Atomic_Vib& atomic_vib) +{ + atomic_vib.model = mex_get_enum_from_field(mex_array, "atomic_vib_mod"); + atomic_vib.coh_contrib = mex_get_bool_from_field(mex_array, "atomic_vib_coh_contrib"); + atomic_vib.sgl_conf = mex_get_bool_from_field(mex_array, "atomic_vib_sgl_conf"); + atomic_vib.nconf = mex_get_num_from_field(mex_array, "atomic_vib_nconf"); + atomic_vib.dim = mex_get_r_3d_from_field(mex_array, "atomic_vib_dim", mt::R_3d(1, 1, 0)); + atomic_vib.seed = mex_get_num_from_field(mex_array, "atomic_vib_seed"); + + atomic_vib.set_dep_var(); +} + +/****************************** read atoms *****************************/ +template +void mex_read_atoms(const mxArray* mex_array, mt::R_3d bs, dt_bool pbc_xy, dt_bool b_statistic, mt::Ptc_Atom& atoms) +{ + auto patoms = mex_get_pvctr_from_field(mex_array, "spec_atoms"); + + atoms.set_ptc(patoms, bs, pbc_xy, b_statistic); +} + +//template +//void mex_read_atoms(const mxArray* mex_array, T bs_x, T bs_y, T bs_z, T sli_thick, mt::Ptc_Atom& atoms) +//{ +// auto patoms = mex_get_pvctr_from_field(mex_array, "spec_atoms"); +// +// auto ct_na = mex_get_num_from_field(mex_array, "spec_cryst_na"); +// auto ct_nb = mex_get_num_from_field(mex_array, "spec_cryst_nb"); +// auto ct_nc = mex_get_num_from_field(mex_array, "spec_cryst_nc"); +// auto ct_a = mex_get_num_from_field(mex_array, "spec_cryst_a"); +// auto ct_b = mex_get_num_from_field(mex_array, "spec_cryst_b"); +// auto ct_c = mex_get_num_from_field(mex_array, "spec_cryst_c"); +// auto ct_x0 = mex_get_num_from_field(mex_array, "spec_cryst_x0"); +// auto ct_y0 = mex_get_num_from_field(mex_array, "spec_cryst_y0"); +// +// auto mex_spec_amorp = mxGetField(mex_array, 0, "spec_amorp"); +// mt::Vctr_Spec_Lay_Info spec_lay_info(mxGetN(mex_spec_amorp)); +// for(auto ik = 0; ik < spec_lay_info.size(); ik++) +// { +// spec_lay_info[ik].z_0 = mex_get_num_from_field(mex_spec_amorp, ik, "z_0"); +// spec_lay_info[ik].z_e = mex_get_num_from_field(mex_spec_amorp, ik, "z_e"); +// spec_lay_info[ik].sli_thick = mex_get_num_from_field(mex_spec_amorp, ik, "sli_thick"); +// } +// +// atoms.set_xtl_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); +// atoms.set_amorphous_parameters(spec_lay_info); +// atoms.set_ptc(patoms, bs, sli_thick); +//} + +/*********************** read rotation parameters *********************/ +template +void mex_read_rot_in_parm(const mxArray* mex_array, mt::Rot_In_Parm& rot_in_parm) +{ + rot_in_parm.theta = mex_get_num_from_field(mex_array, "spec_rot_theta")*mt::c_deg_2_rad; + rot_in_parm.u_0 = mex_get_r_3d_from_field(mex_array, "spec_rot_u_0", mt::R_3d(0, 0, 1)); + rot_in_parm.ctr_type = mex_get_enum_from_field(mex_array, "spec_rot_ctr_typ"); + rot_in_parm.ctr_p = mex_get_r_3d_from_field(mex_array, "spec_rot_ctr_p", mt::R_3d(0, 0, 0)); + + rot_in_parm.set_dep_var(); +} + +/*************************** specimen slicing *************************/ +template +void mex_read_spec_sli_in_parm(const mxArray* mex_array, mt::Vctr_Spec_Slic_In_Parm& spec_slic_in_parm) +{ + auto mex_spec_slic = mxGetField(mex_array, 0, "spec_slic"); + + spec_slic_in_parm.resize(mex_get_s0(mex_spec_slic)); + for(auto ik = 0; ik < spec_slic_in_parm.size(); ik++) + { + spec_slic_in_parm[ik].typ = mex_get_enum_from_field(mex_spec_slic, ik, "typ"); + spec_slic_in_parm[ik].sli_thick = mex_get_num_from_field(mex_spec_slic, ik, "sli_thick"); + spec_slic_in_parm[ik].sel_typ = mex_get_enum_from_field(mex_spec_slic, ik, "sel_typ"); + spec_slic_in_parm[ik].sel_tag = mex_get_num_from_field(mex_spec_slic, ik, "sel_tag"); + spec_slic_in_parm[ik].sel_Z = mex_get_num_from_field(mex_spec_slic, ik, "sel_Z"); + spec_slic_in_parm[ik].sel_z_lim = mex_get_r_2d_from_field(mex_spec_slic, ik, "sel_z_lim"); + auto pz_plns = mex_get_pvctr_from_field(mex_array, ik, "z_plns"); + spec_slic_in_parm[ik].z_plns.assign(pz_plns); + } +} + +/************************ read condenser lens *************************/ +template +void mex_read_cond_lens(const mxArray* mex_array, mt::Lens& cond_lens) +{ + cond_lens.m = mex_get_num_from_field(mex_array, "cond_lens_m"); // momentum of the vortex + cond_lens.c_10 = mex_get_num_from_field(mex_array, "cond_lens_c_10"); // defocus (Angstrom) + cond_lens.c_12 = mex_get_num_from_field(mex_array, "cond_lens_c_12"); // 2-fold astigmatism (Angstrom) + cond_lens.phi_12 = mex_get_num_from_field(mex_array, "cond_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) + + cond_lens.c_21 = mex_get_num_from_field(mex_array, "cond_lens_c_21"); // Axial coma (Angstrom) + cond_lens.phi_21 = mex_get_num_from_field(mex_array, "cond_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) + cond_lens.c_23 = mex_get_num_from_field(mex_array, "cond_lens_c_23"); // 3-fold astigmatism (Angstrom) + cond_lens.phi_23 = mex_get_num_from_field(mex_array, "cond_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) + + cond_lens.c_30 = mex_get_num_from_field(mex_array, "cond_lens_c_30")*mt::c_mm_2_angs; // 3rd order spherical aberration (mm-->Angstrom) + cond_lens.c_32 = mex_get_num_from_field(mex_array, "cond_lens_c_32"); // Axial star aberration (Angstrom) + cond_lens.phi_32 = mex_get_num_from_field(mex_array, "cond_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) + cond_lens.c_34 = mex_get_num_from_field(mex_array, "cond_lens_c_34"); // 4-fold astigmatism (Angstrom) + cond_lens.phi_34 = mex_get_num_from_field(mex_array, "cond_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) + + cond_lens.c_41 = mex_get_num_from_field(mex_array, "cond_lens_c_41"); // 4th order axial coma (Angstrom) + cond_lens.phi_41 = mex_get_num_from_field(mex_array, "cond_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) + cond_lens.c_43 = mex_get_num_from_field(mex_array, "cond_lens_c_43"); // 3-lobe aberration (Angstrom) + cond_lens.phi_43 = mex_get_num_from_field(mex_array, "cond_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) + cond_lens.c_45 = mex_get_num_from_field(mex_array, "cond_lens_c_45"); // 5-fold astigmatism (Angstrom) + cond_lens.phi_45 = mex_get_num_from_field(mex_array, "cond_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) + + cond_lens.c_50 = mex_get_num_from_field(mex_array, "cond_lens_c_50")*mt::c_mm_2_angs; // 5th order spherical aberration (mm-->Angstrom) + cond_lens.c_52 = mex_get_num_from_field(mex_array, "cond_lens_c_52"); // 5th order axial star aberration (Angstrom) + cond_lens.phi_52 = mex_get_num_from_field(mex_array, "cond_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) + cond_lens.c_54 = mex_get_num_from_field(mex_array, "cond_lens_c_54"); // 5th order rosette aberration (Angstrom) + cond_lens.phi_54 = mex_get_num_from_field(mex_array, "cond_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) + cond_lens.c_56 = mex_get_num_from_field(mex_array, "cond_lens_c_56"); // 6-fold astigmatism (Angstrom) + cond_lens.phi_56 = mex_get_num_from_field(mex_array, "cond_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) + + cond_lens.inner_aper_ang = mex_get_num_from_field(mex_array, "cond_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) + cond_lens.outer_aper_ang = mex_get_num_from_field(mex_array, "cond_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) + + /********************* defocus spread function ********************/ + cond_lens.tp_inc_a = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + cond_lens.tp_inc_sigma = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.tp_inc_beta = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.tp_inc_npts = mex_get_num_from_field(mex_array, "cond_lens_tp_inc_npts"); // number of integration points + + /***************** source size broadening function *****************/ + cond_lens.spt_inc_a = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + cond_lens.spt_inc_sigma = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.spt_inc_beta = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + cond_lens.spt_inc_rad_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_rad_npts"); // number of radial integration points + cond_lens.spt_inc_azm_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_azm_npts"); // number of azimuth integration points + + /********************* zero defocus reference ********************/ /********************* zero defocus reference ********************/ + cond_lens.zero_def_typ = mex_get_enum_from_field(mex_array, "cond_lens_zero_def_typ"); // Zero defocus type + cond_lens.zero_def_plane = mex_get_num_from_field(mex_array, "cond_lens_zero_def_plane"); // Zero defocus position +} + +/************************* read objective lens ************************/ +template +void mex_read_obj_lens(const mxArray* mex_array, mt::Lens& obj_lens) +{ + obj_lens.m = mex_get_num_from_field(mex_array, "obj_lens_m"); // momentum of the vortex + obj_lens.c_10 = mex_get_num_from_field(mex_array, "obj_lens_c_10"); // defocus (Angstrom) + obj_lens.c_12 = mex_get_num_from_field(mex_array, "obj_lens_c_12"); // 2-fold astigmatism (Angstrom) + obj_lens.phi_12 = mex_get_num_from_field(mex_array, "obj_lens_phi_12")*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) + + obj_lens.c_21 = mex_get_num_from_field(mex_array, "obj_lens_c_21"); // Axial coma (Angstrom) + obj_lens.phi_21 = mex_get_num_from_field(mex_array, "obj_lens_phi_21")*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) + obj_lens.c_23 = mex_get_num_from_field(mex_array, "obj_lens_c_23"); // 3-fold astigmatism (Angstrom) + obj_lens.phi_23 = mex_get_num_from_field(mex_array, "obj_lens_phi_23")*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) + + obj_lens.c_30 = mex_get_num_from_field(mex_array, "obj_lens_c_30")*mt::c_mm_2_angs; // 3rd order spherical aberration (mm-->Angstrom) + obj_lens.c_32 = mex_get_num_from_field(mex_array, "obj_lens_c_32"); // Axial star aberration (Angstrom) + obj_lens.phi_32 = mex_get_num_from_field(mex_array, "obj_lens_phi_32")*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) + obj_lens.c_34 = mex_get_num_from_field(mex_array, "obj_lens_c_34"); // 4-fold astigmatism (Angstrom) + obj_lens.phi_34 = mex_get_num_from_field(mex_array, "obj_lens_phi_34")*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) + + obj_lens.c_41 = mex_get_num_from_field(mex_array, "obj_lens_c_41"); // 4th order axial coma (Angstrom) + obj_lens.phi_41 = mex_get_num_from_field(mex_array, "obj_lens_phi_41")*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) + obj_lens.c_43 = mex_get_num_from_field(mex_array, "obj_lens_c_43"); // 3-lobe aberration (Angstrom) + obj_lens.phi_43 = mex_get_num_from_field(mex_array, "obj_lens_phi_43")*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) + obj_lens.c_45 = mex_get_num_from_field(mex_array, "obj_lens_c_45"); // 5-fold astigmatism (Angstrom) + obj_lens.phi_45 = mex_get_num_from_field(mex_array, "obj_lens_phi_45")*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) + + obj_lens.c_50 = mex_get_num_from_field(mex_array, "obj_lens_c_50")*mt::c_mm_2_angs; // 5th order spherical aberration (mm-->Angstrom) + obj_lens.c_52 = mex_get_num_from_field(mex_array, "obj_lens_c_52"); // 5th order axial star aberration (Angstrom) + obj_lens.phi_52 = mex_get_num_from_field(mex_array, "obj_lens_phi_52")*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) + obj_lens.c_54 = mex_get_num_from_field(mex_array, "obj_lens_c_54"); // 5th order rosette aberration (Angstrom) + obj_lens.phi_54 = mex_get_num_from_field(mex_array, "obj_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration(degrees-->rad) + obj_lens.c_56 = mex_get_num_from_field(mex_array, "obj_lens_c_56"); // 6-fold astigmatism (Angstrom) + obj_lens.phi_56 = mex_get_num_from_field(mex_array, "obj_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) + + obj_lens.inner_aper_ang = mex_get_num_from_field(mex_array, "obj_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) + obj_lens.outer_aper_ang = mex_get_num_from_field(mex_array, "obj_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) + + /********************* defocus spread function ********************/ + obj_lens.tp_inc_a = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + obj_lens.tp_inc_sigma = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.tp_inc_beta = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.tp_inc_npts = mex_get_num_from_field(mex_array, "obj_lens_tp_inc_npts"); // number of integration points + + /********************* source spread function *********************/ + obj_lens.spt_inc_a = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_a"); // Height proportion of a normalized Gaussian [0, 1] + obj_lens.spt_inc_sigma = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_sigma"); // standard deviation of the source spread function for the Gaussian component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.spt_inc_beta = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_beta"); // standard deviation of the source spread function for the exponential component: For parallel ilumination(Å^-1);otherwise (Å) + obj_lens.spt_inc_rad_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_rad_npts"); // number of radial integration points + obj_lens.spt_inc_azm_npts = mex_get_num_from_field(mex_array, "cond_lens_spt_inc_azm_npts"); // number of azimuth integration points + + /********************* zero defocus reference ********************/ + obj_lens.zero_def_typ = mex_get_num_from_field(mex_array, "obj_lens_zero_def_typ"); // Zero defocus type + obj_lens.zero_def_plane = mex_get_num_from_field(mex_array, "obj_lens_zero_def_plane"); // Zero defocus position +} + +/*************************** read scanning ****************************/ +template +void mex_read_scan_pat(const mxArray* mex_array, mt::Scan_Pat& scan_pat) +{ + scan_pat.typ = mex_get_enum_from_field(mex_array, "scan_pat_typ"); + scan_pat.pbc = mex_get_bool_from_field(mex_array, "scan_pat_pbc"); + scan_pat.spxs = mex_get_bool_from_field(mex_array, "scan_pat_spxs"); + scan_pat.nsp = mex_get_r_2d_rep_from_field(mex_array, "scan_pat_nsp"); + scan_pat.r_0 = mex_get_r_2d_from_field(mex_array, "scan_pat_r_0"); + scan_pat.r_e = mex_get_r_2d_from_field(mex_array, "scan_pat_r_e"); + + if (scan_pat.is_scan_pat_user_def()) + { + scan_pat.r = mex_get_vctr_r_2d_from_field(mex_array, "scan_pat_r"); + } + + scan_pat.set_dep_var(); +} + +/***************************** read detector ***************************/ +template +void mex_read_detector(const mxArray* mex_array, T E_0, mt::Detector& detector) +{ + T lambda = mt::fcn_lambda(E_0); + mxArray* mex_detector = mxGetField(mex_array, 0, "detector"); + detector.type = mex_get_enum_from_field(mex_detector, "type"); + + switch (detector.type) + { + case mt::edt_circular: + { + mex_detector = mxGetField(mex_detector, 0, "cir"); + dt_int32 ndetector = mex_get_MxN(mex_detector); + if (ndetector > 0) + { + detector.resize(ndetector); + for(auto i = 0; i < detector.size(); i++) + { + auto inner_ang = mex_get_num_from_field(mex_detector, i, "inner_ang")*mt::c_mrad_2_rad; + detector.g_inner[i] = sin(inner_ang)/lambda; + auto outer_ang = mex_get_num_from_field(mex_detector, i, "outer_ang")*mt::c_mrad_2_rad; + detector.g_outer[i] = sin(outer_ang)/lambda; + } + } + } + break; + case mt::edt_radial: + { + mex_detector = mxGetField(mex_detector, 0, "radial"); + dt_int32 ndetector = mxGetN(mex_detector); + if (ndetector > 0) + { + detector.resize(ndetector); + for(auto i = 0; i < detector.size(); i++) + { + // auto x = mex_get_pvctr_from_field(mex_detector, i, "x"); + // mt::assign(x, detector.x[i]); + // mt::fcn_scale(detector.x[i], 1.0/lambda); + + auto fx = mex_get_pvctr_from_field(mex_detector, i, "fx"); + mt::assign(fx, detector.fx[i]); + } + } + } + break; + case mt::edt_matrix: + { + mex_detector = mxGetField(mex_detector, 0, "matrix"); + dt_int32 ndetector = mxGetN(mex_detector); + if (ndetector > 0) + { + detector.resize(ndetector); + for(auto i = 0; i < detector.size(); i++) + { + // auto R = mex_get_pvctr_from_field(mex_detector, i, "x"); + // mt::assign(R, detector.R[i]); + // mt::fcn_scale(detector.R[i], 1.0/lambda); + // mt::fcn_fftsft_2d(grid_2d, detector.R[i]); + + auto fR = mex_get_pvctr_from_field(mex_detector, i, "fR"); + mt::assign(fR, detector.fR[i]); + } + } + } + break; + } +} \ No newline at end of file diff --git a/src/matlab_types.cuh b/src/matlab_types.cuh deleted file mode 100644 index 28c241d0..00000000 --- a/src/matlab_types.cuh +++ /dev/null @@ -1,567 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef MATLAB_TYPES_H -#define MATLAB_TYPES_H - -#include -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "cpu_fcns.hpp" - -namespace mt -{ - template - struct complex_s - { - public: - complex_s(): m_real(nullptr), m_imag(nullptr){} - - template - inline complex_s& operator = (const complex & z) - { - *m_real = z.real(); - *m_imag = z.imag(); - return *this; - } - - inline void operator()(T &real, T &imag) - { - m_real = ℜ - m_imag = &imag; - } - - template - inline operator complex() const - { - return complex(*m_real, *m_imag); - } - - inline void real(const T &re){ *m_real = re; } - - inline void imag(const T &im){ *m_imag = im; } - - inline T real() const { return *m_real; } - - inline T imag() const { return *m_imag; } - - template - inline complex_s& operator+= (const complex &z) - { - real(real()+z.real()); - imag(imag()+z.imag()); - return *this; - } - - private: - T *m_real; - T *m_imag; - }; - - template - std::ostream& operator<<(std::ostream& out, const complex_s& z){ - return out << "("<< z.real() << ", " << z.imag() <<")"; - } - - /*********************pointer to double matrix*****************/ - struct rmatrix_r - { - public: - using value_type = double; - using size_type = std::size_t; - static const eDevice device = e_host; - - int m_size; - int rows; - int cols; - double *real; - double *imag; - rmatrix_r(): m_size(0), rows(0), cols(0), real(nullptr), imag(nullptr){} - - double& operator[](const int i){ return real[i]; } - const double& operator[](const int i) const { return real[i]; } - host_vector::iterator begin() const { return real; }; - host_vector::iterator end() const { return (real + m_size); }; - - size_type size() const - { - return m_size; - } - - bool empty() const - { - return size()==0; - } - - void resize(const size_type &new_size) - { - m_size = static_cast(new_size); - delete [] real; - real = new double [new_size]; - } - - void clear() - { - m_size = 0; - rows = 0; - cols = 0; - delete [] real; - real = nullptr; - } - - template - void assign(TInput_Iterator first, TInput_Iterator last) - { - if(real!= nullptr) - { - thrust::copy(first, last, real); - } - } - - template - T get(const int &i) const - { - return T(real[i]); - } - - template - typename std::enable_if::value, void>::type - set(const int &i, const T &z) - { - real[i] = z.real(); - } - - template - typename std::enable_if::value, void>::type - set(const int &i, const T &z) - { - real[i] = z; - } - - void swap(const int &i, const int &j) - { - thrust::swap(real[i], real[j]); - } - }; - - /*********************pointer to complex matrix****************/ - struct rmatrix_c - { - public: - using value_type = complex; - using size_type = std::size_t; - static const eDevice device = e_host; - - int m_size; - int rows; - int cols; - double *real; - double *imag; - - rmatrix_c(): m_size(0), rows(0), cols(0), real(nullptr), imag(nullptr){} - - complex operator[](const int i) const - { - return complex(real[i], imag[i]); - } - - size_type size() const - { - return m_size; - } - - bool empty() const - { - return size()==0; - } - - void resize(const size_type &new_size) - { - m_size = static_cast(new_size); - delete [] real; - real = new double [new_size]; - delete [] imag; - imag = new double [new_size]; - } - - void clear() - { - m_size = 0; - rows = 0; - cols = 0; - delete [] real; - real = nullptr; - delete [] imag; - imag = nullptr; - } - - template - typename std::enable_if::value, T>::type - get(const int &i) const - { - return T(real[i], imag[i]); - } - - template - typename std::enable_if::value, T>::type - get(const int &i) const - { - return T(real[i]); - } - - template - typename std::enable_if::value, void>::type - set(const int &i, const T &z) - { - real[i] = z.real(); - imag[i] = z.imag(); - } - - template - typename std::enable_if::value, void>::type - set(const int &i, const T &z) - { - real[i] = z; - } - - void swap(const int &i, const int &j) - { - thrust::swap(real[i], real[j]); - thrust::swap(imag[i], imag[j]); - } - }; - - /***********************Matlab traits**************************/ - template - struct is_rmatrix_r: std::integral_constant::value> {}; - - template - struct is_rmatrix_c: std::integral_constant::value> {}; - - template - struct is_rmatrix: std::integral_constant::value || is_rmatrix_c::value> {}; - - template - struct is_rmatrix_and_rmatrix: std::integral_constant::value && is_rmatrix::value> {}; - - template - struct is_rmatrix_and_host_vector: std::integral_constant::value && is_host_vector::value> {}; - - template - struct is_rmatrix_and_device_vector: std::integral_constant::value && is_device_vector::value> {}; - - template - struct is_host_vector_and_rmatrix: std::integral_constant::value && is_rmatrix::value> {}; - - template - struct is_device_vector_and_rmatrix: std::integral_constant::value && is_rmatrix::value> {}; - - template - using enable_if_rmatrix_r = typename std::enable_if::value, U>::type; - - template - using enable_if_rmatrix_c = typename std::enable_if::value, U>::type; - - template - using enable_if_rmatrix = typename std::enable_if::value, U>::type; - - template - using enable_if_rmatrix_and_rmatrix = typename std::enable_if::value, U>::type; - - template - using enable_if_rmatrix_and_host_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_rmatrix_and_device_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_host_vector_and_rmatrix = typename std::enable_if::value, U>::type; - - template - using enable_if_device_vector_and_rmatrix = typename std::enable_if::value, U>::type; - - /***********************Matlab functions**************************/ - - template - enable_if_rmatrix_and_host_vector - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - using value_type = Value_type; - - M_o.resize(M_i.size()); - - for(auto ixy = 0; ixy < M_o.size(); ixy++) - { - M_o[ixy] = M_i.template get(ixy); - } - } - - template - enable_if_rmatrix_and_device_vector - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - Vector, e_host> M_h; - M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; - - assign(M_i, *M_i_h); - M_o.assign(M_i_h->begin(), M_i_h->end()); - } - - template - typename std::enable_if::value && is_complex>::value, void>::type - assign_real(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) - { - for(auto ixy = 0; ixy < M_o.size(); ixy++) - { - M_o[ixy] = M_i[ixy].real(); - } - } - - template - enable_if_rmatrix - fill(Stream &stream, TVector &M_io, Value_type value_i) - { - auto thr_fill = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - M_io.set(ixy, value_i); - } - }; - - stream.set_n_act_stream(M_io.size()); - stream.set_grid(1, M_io.size()); - stream.exec(thr_fill); - } - - template - enable_if_rmatrix_and_rmatrix - scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_scale = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto z = w_i*M_i.template get(ixy); - M_o.set(ixy, z); - }; - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_scale); - } - - template - enable_if_rmatrix - scale(Stream &stream, Value_type w_i, TVector &M_io) - { - scale(stream, w_i, M_io, M_io); - } - - template - enable_if_rmatrix_and_rmatrix - square(Stream &stream, TVector_1 &M_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_square = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto z = ::norm(M_i.template get(ixy)); - M_o.set(ixy, z); - } - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_square); - } - - template - enable_if_rmatrix_and_rmatrix - square_scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_o) - { - using value_type = Value_type; - auto thr_square_scale = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto z = w_i*::norm(M_i.template get(ixy)); - M_o.set(ixy, z); - } - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_square_scale); - } - - template - enable_if_rmatrix - fft1_shift(TGrid &grid_1d, TVector &M_io) - { - for(auto ix = 0; ix < grid_1d.nxh; ix++) - { - int ix_shift = grid_1d.iRx_shift(ix); - M_io.swap(ix, ix_shift); - } - } - - template - enable_if_rmatrix - fft2_shift(Stream &stream, TGrid &grid_2d, TVector &M_io) - { - auto krn_fft2_shift = [](const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_io) - { - int ixy = grid_2d.ind_col(ix, iy); - int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); - M_io.swap(ixy, ixy_shift); - - ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); - ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); - M_io.swap(ixy, ixy_shift); - }; - - auto thr_fft2_shift = [&](const Range_2d &range) - { - host_detail::matrix_iter(range, krn_fft2_shift, grid_2d, M_io); - }; - - stream.set_n_act_stream(grid_2d.nxh); - stream.set_grid(grid_2d.nxh, grid_2d.nyh); - stream.exec(thr_fft2_shift); - } - - template - enable_if_rmatrix_r> - sum(Stream &stream, TVector &M_i) - { - using value_type = Value_type; - - value_type sum_total = 0; - auto thr_sum = [&](const Range_2d &range) - { - auto sum_partial = thrust::reduce(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e); - - stream.stream_mutex.lock(); - sum_total += sum_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(1, M_i.size()); - stream.exec(thr_sum); - - return sum_total; - } - - template - enable_if_rmatrix_r> - mean(Stream &stream, TVector &M_i) - { - return sum(stream, M_i)/M_i.size(); - } - - /***************************************************************************/ - /***************************************************************************/ - template - enable_if_host_vector_and_rmatrix - copy_to_host(Stream &stream, TVector_i &M_i, - TVector_o &M_o, TVector_i *M_i_h = nullptr) - { - auto thr_copy_to_host = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - M_o.set(ixy, M_i[ixy]); - } - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_copy_to_host); - } - - template - enable_if_host_vector_and_rmatrix - add_scale_to_host(Stream &stream, Value_type w_i, - TVector_i &M_i, TVector_o &M_o, Vector, e_host> *M_i_h = nullptr) - { - using value_type = Value_type; - auto thr_add_scale_to_host = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto z = M_o.template get(ixy) + value_type(w_i*M_i[ixy]); - M_o.set(ixy, z); - }; - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_add_scale_to_host); - } - - template - enable_if_host_vector_and_rmatrix - add_scale_square_to_host(Stream &stream, Value_type w_i, - TVector_i &M_i, TVector_o &M_o, Vector, e_host> *M_i_h = nullptr) - { - auto thr_add_scale_square_to_host = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto z = M_o.template get>(ixy) + w_i*thrust::norm(M_i[ixy]); - M_o.set(ixy, z); - }; - }; - - stream.set_n_act_stream(M_o.size()); - stream.set_grid(1, M_o.size()); - stream.exec(thr_add_scale_square_to_host); - } - - template - enable_if_host_vector_and_rmatrix - add_scale_m2psi_psi_to_host(Stream &stream, Value_type w_i, - TVector_c_i &psi_i, TVector_r_o &m2psi_o, TVector_c_o &psi_o, Vector, e_host> *psi_i_h = nullptr) - { - using T_r = Value_type; - using T_c = Value_type; - auto thr_add_scale_m2psi_psi_to_host = [&](const Range_2d &range) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto z1 = m2psi_o.template get(ixy) + T_r(w_i)*thrust::norm(psi_i[ixy]); - auto z2 = psi_o.template get(ixy) + T_c(w_i)*T_c(psi_i[ixy]); - m2psi_o.set(ixy, z1); - psi_o.set(ixy, z2); - } - }; - - stream.set_n_act_stream(psi_o.size()); - stream.set_grid(1, psi_o.size()); - stream.exec(thr_add_scale_m2psi_psi_to_host); - } -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/memcpy.cuh b/src/memcpy.cuh new file mode 100755 index 00000000..1aacac58 --- /dev/null +++ b/src/memcpy.cuh @@ -0,0 +1,342 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is destroy software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MEMCPY_H + #define MEMCPY_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "const_enum.h" + #include "math_mt.h" + #include "type_traits_gen.h" + + #ifdef __CUDACC__ + #include + #include + #endif + + /* gpu data cast */ + namespace mt + { + namespace gpu_detail + { + #ifdef __CUDACC__ + template + __global__ void fcn_data_typ_cast(Td* data_dst, Ts* data_src, dt_int32 n_data) + { + FOR_IX_1DC(n_data) + { + data_dst[ix] = Td(data_src[ix]); + } + } + + template + __global__ void fcn_real_gpu_gpu(Td* data_dst, Ts* data_src, dt_int32 n_data) + { + FOR_IX_1DC(n_data) + { + data_dst[ix] = Td(data_src[ix].real()); + } + } + + template + __global__ void fcn_imag_gpu_gpu(Td* data_dst, Ts* data_src, dt_int32 n_data) + { + FOR_IX_1DC(n_data) + { + data_dst[ix] = Td(data_src[ix].imag()); + } + } + #endif + } + } + + /* data copy */ + namespace mt + { + /******************************* (dst, src): cpu -> cpu ********************************/ + template + void memcpy_cpu_cpu(Td* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + pcpu_dst[ik] = Td(pcpu_src[ik]); + } + } + + #ifdef __CUDACC__ + /******************************* (dst, src): gpu -> cpu ********************************/ + template + enable_if_same_decay + memcpy_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + cudaMemcpy(pcpu_dst, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + } + + template + enable_if_diff_decay + memcpy_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + if (pcpu_jk == nullptr) + { + Ts* pcpu_t = new Ts[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_cpu_cpu(pcpu_dst, pcpu_t, n_size); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_cpu_cpu(pcpu_dst, pcpu_jk, n_size); + } + } + + /******************************* (dst, src): gpu -> gpu ********************************/ + // (dst, src): gpu -> gpu + template + enable_if_same_decay + memcpy_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + auto size_bytes = n_size*dt_uint64(sizeof(Td)); + cudaMemcpy(pgpu_dst, pgpu_src, size_bytes, cudaMemcpyDeviceToDevice); + } + + template + enable_if_diff_decay + memcpy_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + // dt_int32 numSMs; + // cudaDeviceGetAttribute(&numSMs, cudaDevAttrMultiProcessorCount, devId); + + auto grid = fcn_cdg_1d(n_size); + grid.x = min(128, grid.x); + + gpu_detail::fcn_data_typ_cast<<>>(pgpu_dst, pgpu_src, dt_int32(n_size)); + } + + /******************************* (dst, src): cpu -> gpu ********************************/ + template + enable_if_same_decay + memcpy_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + cudaMemcpy(pgpu_dst, pcpu_src, size_bytes, cudaMemcpyHostToDevice); + } + + template + enable_if_diff_decay + memcpy_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + const auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + if (pcpu_jk == nullptr) + { + Td* pcpu_t = new Td[n_size]; + memcpy_cpu_cpu(pcpu_t, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_cpu_cpu(pcpu_jk, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + + #endif + + } + + /* complex real data copy */ + namespace mt + { + // (dst, src): cpu -> cpu + template + enable_if_cmplx + memcpy_real_cpu_cpu(Td* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pcpu_src) + return; + + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + pcpu_dst[ik] = Td(pcpu_src[ik].real()); + } + } + + #ifdef __CUDACC__ + // (dst, src): gpu -> cpu + template + enable_if_cmplx + memcpy_real_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pgpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + if (pcpu_jk == nullptr) + { + Ts* pcpu_t = new Ts[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_real_cpu_cpu(pcpu_dst, pcpu_t, n_size); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_real_cpu_cpu(pcpu_dst, pcpu_jk, n_size); + } + } + + // (dst, src): gpu -> gpu + template + enable_if_cmplx + memcpy_real_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pgpu_src) + return; + + auto grid = fcn_cdg_1d(n_size); + grid.x = min(128, grid.x); + + gpu_detail::fcn_real_gpu_gpu<<>>(pgpu_dst, pgpu_src, dt_int32(n_size)); + } + + // (dst, src): cpu -> gpu + template + enable_if_cmplx + memcpy_real_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pcpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + if (pcpu_jk == nullptr) + { + Td* pcpu_t = new Td[n_size]; + memcpy_real_cpu_cpu(pcpu_t, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_real_cpu_cpu(pcpu_jk, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + + #endif + + } + + /* complex imag data copy */ + namespace mt + { + // (dst, src): cpu -> cpu + template + enable_if_cmplx + memcpy_imag_cpu_cpu(Td* pcpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pcpu_src) + return; + + for (dt_uint64 ik = 0; ik < n_size; ik++) + { + pcpu_dst[ik] = Td(pcpu_src[ik].imag()); + } + } + + #ifdef __CUDACC__ + // (dst, src): gpu -> cpu + template + enable_if_cmplx + memcpy_imag_gpu_cpu(Td* pcpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Ts* pcpu_jk = nullptr) + { + if ((void*)pcpu_dst == (void*)pgpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Ts)); + + if (pcpu_jk == nullptr) + { + Ts* pcpu_t = new Ts[n_size]; + cudaMemcpy(pcpu_t, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_imag_cpu_cpu(pcpu_dst, pcpu_t, n_size); + delete[] pcpu_t; + } + else + { + cudaMemcpy(pcpu_jk, pgpu_src, size_bytes, cudaMemcpyDeviceToHost); + memcpy_imag_cpu_cpu(pcpu_dst, pcpu_jk, n_size); + } + } + + // (dst, src): gpu -> gpu + template + enable_if_cmplx + memcpy_imag_gpu_gpu(Td* pgpu_dst, const Ts* pgpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pgpu_src) + return; + + auto grid = fcn_cdg_1d(n_size); + grid.x = min(128, grid.x); + + gpu_detail::fcn_imag_gpu_gpu<<>>(pgpu_dst, pgpu_src, dt_int32(n_size)); + } + + // (dst, src): cpu -> gpu + template + enable_if_cmplx + memcpy_imag_cpu_gpu(Td* pgpu_dst, const Ts* pcpu_src, dt_uint64 n_size, Td* pcpu_jk = nullptr) + { + if ((void*)pgpu_dst == (void*)pcpu_src) + return; + + auto size_bytes = n_size*dt_uint64(sizeof(Td)); + + if (pcpu_jk == nullptr) + { + Td* pcpu_t = new Td[n_size]; + memcpy_imag_cpu_cpu(pcpu_t, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_t, size_bytes, cudaMemcpyHostToDevice); + delete[] pcpu_t; + } + else + { + memcpy_imag_cpu_cpu(pcpu_jk, pcpu_src, n_size); + cudaMemcpy(pgpu_dst, pcpu_jk, size_bytes, cudaMemcpyHostToDevice); + } + } + + #endif + + } + +#endif \ No newline at end of file diff --git a/src/memory_info.cuh b/src/memory_info.cuh deleted file mode 100644 index 7d7df074..00000000 --- a/src/memory_info.cuh +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef MEMORY_INFO_H -#define MEMORY_INFO_H - -#ifdef _WIN32 - #include -#else - #include - #ifdef __APPLE__ - #include - #include - #include - #include - #else - #include - #include - #endif -#endif -#include - -#include -#include -#include - -#include "types.cuh" - -#include -#include - -namespace mt -{ - bool is_gpu_available(); - - template - void memory_info(double &total, double &free); - - template <> - inline - void memory_info(double &total, double &free) - { -#if defined(_WIN32) - MEMORYSTATUSEX status; - status.dwLength = sizeof(status); - GlobalMemoryStatusEx(&status); - free = static_cast(status.ullAvailPhys)/(1048576.0); - total = static_cast(status.ullTotalPhys)/(1048576.0); -#elif defined(__APPLE__) - int mib[2]; - mib[0] = CTL_HW; - mib[1] = HW_MEMSIZE; - uint64_t physicalMem = 0; - size_t returnSize = sizeof(physicalMem); - sysctl(mib, 2, &physicalMem, &returnSize, NULL, 0); - total = returnSize/(1048576.0); - - task_t targetTask = mach_task_self(); - struct task_basic_info ti; - mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT; - task_info(targetTask, TASK_BASIC_INFO_64, (task_info_t) &ti, &count); - free = ti.resident_size/(1048576.0); - -#else // linux - struct sysinfo memInfo; - sysinfo (&memInfo); - long long totalPhysMem = memInfo.totalram; - totalPhysMem *= memInfo.mem_unit; - long long physMemFree = memInfo.freeram; - physMemFree *= memInfo.mem_unit; - free = static_cast(physMemFree)/(1048576.0); // check if division by 1MB = 1048576 is necessary - total = static_cast(totalPhysMem)/(1048576.0); // check if division by 1MB = 1048576 is necessary -#endif - } - - template <> - inline - void memory_info(double &total, double &free) - { - free = total = 0; - size_t free_t, total_t; - if(cudaSuccess == cudaMemGetInfo(&free_t, &total_t)) - { - free = static_cast(free_t)/(1048576.0); - total = static_cast(total_t)/(1048576.0); - } - } - - template - double get_free_memory(){ return 0; } - - template <> - inline - double get_free_memory() - { - double total, free; - memory_info(total, free); - return free; - } - - template <> - inline - double get_free_memory() - { - double total, free; - memory_info(total, free); - return free; - } - - inline - void get_device_properties(std::vector &device_properties) - { - device_properties.clear(); - - if (!is_gpu_available()) - { - return; - } - - int device_count = 0; - cudaGetDeviceCount(&device_count); - - device_properties.resize(device_count); - for (auto idev = 0; idev < device_count; idev++) - { - cudaDeviceProp cuda_device_prop; - cudaGetDeviceProperties(&cuda_device_prop, idev); - - device_properties[idev].id = idev; - device_properties[idev].name = cuda_device_prop.name; - device_properties[idev].compute_capability = 10*cuda_device_prop.major+cuda_device_prop.minor; - memory_info(device_properties[idev].total_memory_size, device_properties[idev].free_memory_size); - } - - //auto compare_fn = [](const Device_Properties &a, const Device_Properties &b)->bool - //{ - // return a.compute_capability > b.compute_capability; - //}; - //std::sort(device_properties.begin(), device_properties.end(), compare_fn); - } - - inline - void get_host_properties(Host_Properties &host_properties) - { -#ifdef _WIN32 - SYSTEM_INFO siSysInfo; - GetSystemInfo(&siSysInfo); - host_properties.nprocessors = siSysInfo.dwNumberOfProcessors; -#elif __APPLE__ - int count = 0; - size_t count_len = sizeof(count); - sysctlbyname("hw.logicalcpu", &count, &count_len, NULL, 0); - host_properties.nprocessors = count; -#else - host_properties.nprocessors = sysconf(_SC_NPROCESSORS_ONLN); -#endif - host_properties.nthreads = std::thread::hardware_concurrency(); - memory_info(host_properties.total_memory_size, host_properties.free_memory_size); - } - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/microscope_effects.cuh b/src/microscope_effects.cuh old mode 100644 new mode 100755 index cf1caa2a..3cad79eb --- a/src/microscope_effects.cuh +++ b/src/microscope_effects.cuh @@ -1,216 +1,194 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef MICROSCOPE_EFFECTS_H -#define MICROSCOPE_EFFECTS_H - -#include "math.cuh" -#include "types.cuh" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" -#include "cgpu_fcns.cuh" -#include "quadrature.hpp" - -namespace mt -{ - template - class Microscope_Effects - { - public: - using T_r = T; - using T_c = complex; - - Microscope_Effects(): input_multislice(nullptr), stream(nullptr), fft_2d(nullptr){} - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i, FFT *fft2_i) - { - input_multislice = input_multislice_i; - stream = stream_i; - fft_2d = fft2_i; - - psi.resize(input_multislice->grid_2d.nxy()); - - if((input_multislice->illumination_model == eIM_Coherent)||(input_multislice->illumination_model == eIM_Partial_Coherent)) - { - return; - } - - // Load quadratures - obj_lens_temporal_spatial_quadratures(input_multislice->obj_lens, qt, qs); - } - - void operator()(Vector &fpsi, Vector &m2psi_tot) - { - switch(input_multislice->illumination_model) - { - case eIM_Coherent: - { - CTF_TEM(input_multislice->temporal_spatial_incoh, fpsi, psi); - mt::square(*stream, psi, m2psi_tot); - } - break; - case eIM_Partial_Coherent: - { - PCTF_LI_WPO_TEM(input_multislice->temporal_spatial_incoh, fpsi, psi); - mt::square(*stream, psi, m2psi_tot); - } - break; - case eIM_Trans_Cross_Coef: - { - - } - break; - case eIM_Full_Integration: - { - num_int_TEM(input_multislice->temporal_spatial_incoh, fpsi, m2psi_tot); - } - break; - } - } - - template - void operator()(TOutput_multislice &output_multislice) - { - Vector psi(input_multislice->iw_psi.begin(), input_multislice->iw_psi.end()); - mt::fft2_shift(*stream, input_multislice->grid_2d, psi); - fft_2d->forward(psi); - mt::scale(*stream, input_multislice->grid_2d.inxy(), psi); - Vector m2psi_tot(input_multislice->grid_2d.nxy()); - this->operator()(psi, m2psi_tot); - mt::fft2_shift(*stream, input_multislice->grid_2d, m2psi_tot); - - mt::copy_to_host(output_multislice.stream, m2psi_tot, output_multislice.m2psi_tot[0]); - } - - template - void apply_ctf(TOutput_multislice &output_multislice) - { - Vector psi(input_multislice->iw_psi.begin(), input_multislice->iw_psi.end()); - - mt::fft2_shift(*stream, input_multislice->grid_2d, psi); - fft_2d->forward(psi); - mt::scale(*stream, input_multislice->grid_2d.inxy(), psi); - if (input_multislice->is_illu_mod_coherent()) - { - CTF_TEM(input_multislice->temporal_spatial_incoh, psi, psi); - } - else - { - PCTF_LI_WPO_TEM(input_multislice->temporal_spatial_incoh, psi, psi); - } - mt::fft2_shift(*stream, input_multislice->grid_2d, psi); - - mt::copy_to_host(output_multislice.stream, psi, output_multislice.psi_coh[0]); - } - - private: - void CTF_TEM(const eTemporal_Spatial_Incoh &temporal_spatial_incoh, Vector &fpsi, Vector &psi) - { - mt::apply_CTF(*stream, input_multislice->grid_2d, input_multislice->obj_lens, 0, 0, fpsi, psi); - fft_2d->inverse(psi); - } - - void PCTF_LI_WPO_TEM(const eTemporal_Spatial_Incoh &temporal_spatial_incoh, Vector &fpsi, Vector &psi) - { - T_r ti_sigma = input_multislice->obj_lens.ti_sigma; - T_r si_sigma = input_multislice->obj_lens.si_sigma; - - switch(temporal_spatial_incoh) - { - case eTSI_Temporal: // Temporal - { - input_multislice->obj_lens.set_si_sigma(0); - } - break; - case eTSI_Spatial: // Spatial - { - input_multislice->obj_lens.set_ti_sigma(0); - } - break; - } - - mt::apply_PCTF(*stream, input_multislice->grid_2d, input_multislice->obj_lens, fpsi, psi); - fft_2d->inverse(psi); - - input_multislice->obj_lens.set_ti_sigma(ti_sigma); - input_multislice->obj_lens.set_si_sigma(si_sigma); - } - - void num_int_TEM(const eTemporal_Spatial_Incoh &temporal_spatial_incoh, Vector &fpsi, Vector &m2psi_tot) - { - T_r c_10_0 = input_multislice->obj_lens.c_10; - - fill(*stream, m2psi_tot, 0.0); - switch(temporal_spatial_incoh) - { - case 1: // Temporal and Spatial - { - for(auto i = 0; iobj_lens.ti_iehwgd*qt.x[j]+c_10_0; - input_multislice->obj_lens.set_defocus(c_10); - - mt::apply_CTF(*stream, input_multislice->grid_2d, input_multislice->obj_lens, qs.x[i], qs.y[i], fpsi, psi); - fft_2d->inverse(psi); - mt::add_scale_square(*stream, qs.w[i]*qt.w[j], psi, m2psi_tot); - } - } - } - break; - case 2: // Temporal - { - for(auto j = 0; jobj_lens.ti_iehwgd*qt.x[j]+c_10_0; - input_multislice->obj_lens.set_defocus(c_10); - - mt::apply_CTF(*stream, input_multislice->grid_2d, input_multislice->obj_lens, 0.0, 0.0, fpsi, psi); - fft_2d->inverse(psi); - mt::add_scale_square(*stream, qt.w[j], psi, m2psi_tot); - } - } - break; - case 3: // Spatial - { - for(auto i = 0; igrid_2d, input_multislice->obj_lens, qs.x[i], qs.y[i], fpsi, psi); - fft_2d->inverse(psi); - mt::add_scale_square(*stream, qs.w[i], psi, m2psi_tot); - } - } - } - - input_multislice->obj_lens.set_defocus(c_10_0); - } - - Input_Multislice *input_multislice; - Stream *stream; - FFT *fft_2d; - - Vector psi; - - Q1 qt; - Q2 qs; - }; - -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MICROSCOPE_EFFECTS_H +#define MICROSCOPE_EFFECTS_H + +#include "math_mt.h" +#include "types.cuh" +#include "fcns_cpu.h" +#include "fcns_gpu.h" +#include "fcns_gpu.h" +#include "quad_data.cuh" + +namespace mt +{ + template + class Microscope_Effects + { + public: + using T_r = T; + using T_c = complex; + + Microscope_Effects(): multem_in_parm(nullptr), stream(nullptr), fft_2d(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + multem_in_parm = multem_in_parm_i; + stream = stream_i; + fft_2d = fft2_i; + + psi.resize(multem_in_parm->grid_2d.size()); + + if ((multem_in_parm->illum_mod == eim_coherent)||(multem_in_parm->illum_mod == eim_partial_coherent)) + { + return; + } + + // Load quadratures + obj_lens_temporal_spatial_quadratures(multem_in_parm->obj_lens, qt, qs); + } + + void operator()(Vctr& fpsi, Vctr& m2psi_tot) + { + switch(multem_in_parm->illum_mod) + { + case eim_coherent: + { + CTF_TEM(multem_in_parm->illum_inc, fpsi, m2psi_tot); + } + break; + case eim_partial_coherent: + { + PCTF_LI_WPO_TEM(multem_in_parm->illum_inc, fpsi, m2psi_tot); + } + break; + case eim_trans_cross_coef: + { + + } + break; + case eim_full_integration: + { + num_int_TEM(multem_in_parm->illum_inc, fpsi, m2psi_tot); + } + break; + } + } + + template + void operator()(TOutput_multislice &output_multem) + { + Vctr psi(multem_in_parm->iw_psi.begin(), multem_in_parm->iw_psi.end()); + mt::fcn_fftsft_2d(*stream, multem_in_parm->grid_2d, psi); + fft_2d->forward(psi); + mt::fcn_scale(*stream, multem_in_parm->grid_2d.isize_r(), psi); + + Vctr m2psi_tot(multem_in_parm->grid_2d.size()); + this->operator()(psi, m2psi_tot); + mt::cpy_to_host(output_multem.stream, m2psi_tot, output_multem.m2psi_tot[0]); + } + + private: + void CTF_TEM(const eIllum_Inc &illum_inc, Vctr& fpsi, Vctr& m2psi_tot) + { + mt::fcn_apply_ctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, 0, 0, fpsi, psi); + fft_2d->inverse(psi); + mt::square(*stream, psi, m2psi_tot); + } + + void PCTF_LI_WPO_TEM(const eIllum_Inc &illum_inc, Vctr& fpsi, Vctr& m2psi_tot) + { + T_r tp_inc_sigma = multem_in_parm->obj_lens.tp_inc_sigma; + T_r spt_inc_sigma = multem_in_parm->obj_lens.spt_inc_sigma; + + switch(illum_inc) + { + case eii_temporal: // Temporal + { + multem_in_parm->obj_lens.set_spt_inc_sigma(0); + } + break; + case etst_spatial: // Spatial + { + multem_in_parm->obj_lens.set_tp_inc_sigma(0); + } + break; + } + + mt::fcn_apply_pctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, fpsi, psi); + fft_2d->inverse(psi); + mt::square(*stream, psi, m2psi_tot); + + multem_in_parm->obj_lens.set_tp_inc_sigma(tp_inc_sigma); + multem_in_parm->obj_lens.set_spt_inc_sigma(spt_inc_sigma); + } + + void num_int_TEM(const eIllum_Inc &illum_inc, Vctr& fpsi, Vctr& m2psi_tot) + { + T_r c_10_0 = multem_in_parm->obj_lens.c_10; + + fill(*stream, m2psi_tot, 0.0); + switch(illum_inc) + { + case 1: // Temporal and Spatial + { + for(auto i = 0; iobj_lens.tp_inc_iehwgd*qt.x[j]+c_10_0; + multem_in_parm->obj_lens.set_defocus(c_10); + + mt::fcn_apply_ctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, qs.x[i], qs.y[i], fpsi, psi); + fft_2d->inverse(psi); + mt::add_scale_norm_2(*stream, qs.w[i]*qt.w[j], psi, m2psi_tot); + } + } + } + break; + case 2: // Temporal + { + for(auto j = 0; jobj_lens.tp_inc_iehwgd*qt.x[j]+c_10_0; + multem_in_parm->obj_lens.set_defocus(c_10); + + mt::fcn_apply_ctf(*stream, multem_in_parm->grid_2d, multem_in_parm->obj_lens, 0.0, 0.0, fpsi, psi); + fft_2d->inverse(psi); + mt::add_scale_norm_2(*stream, qt.w[j], psi, m2psi_tot); + } + } + break; + case 3: // Spatial + { + for(auto i = 0; igrid_2d, multem_in_parm->obj_lens, qs.x[i], qs.y[i], fpsi, psi); + fft_2d->inverse(psi); + mt::add_scale_norm_2(*stream, qs.w[i], psi, m2psi_tot); + } + } + } + + multem_in_parm->obj_lens.set_defocus(c_10_0); + } + + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + + Vctr psi; + + Quad_Coef_1d qt; + Quad_Coef_2d qs; + }; + +} + #endif \ No newline at end of file diff --git a/src/multem_in_parm.cuh b/src/multem_in_parm.cuh new file mode 100755 index 00000000..c746eede --- /dev/null +++ b/src/multem_in_parm.cuh @@ -0,0 +1,1016 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef MULTEM_IN_PARM_H + #define MULTEM_IN_PARM_H + + #include + + #include "math_mt.h" + #include "types_mt.cuh" + #include "particles.cuh" + #include "atomic_vib.hpp" + #include "rot_in_parm.hpp" + #include "spec_slic_in_parm.hpp" + #include "beam_pos_2d.hpp" + #include "scan_pat.hpp" + #include "lens.cuh" + #include "system_config.h" + #include "cgpu_vctr.cuh" + + /* multem */ + namespace mt + { + dt_bool is_gpu_avbl(); + + dt_int32 gpu_n_avbl(); + + template + class EELS; + + /**************************** Input multem *****************************/ + template + struct Spec_Slic; + + template + class Multem_In_Parm + { + public: + using value_type = T; + + System_Config system_config; // System information + + eElec_Spec_Interact_Mod elec_spec_interact_mod; // eesim_multislice = 1, eesim_phase_object = 2, eesim_weak_phase_object = 3 + eAtomic_Pot_Parm_Typ atomic_pot_parm_typ; // potential type: 1: doyle(0-4), 2: Peng(0-4), 3: peng(0-12), 4: Kirkland(0-12), 5:Weickenmeier(0-12) adn 6: Lobato(0-12) + + Atomic_Vib atomic_vib; // phonon parameters + + Ptc_Atom atoms; // atoms + dt_bool is_xtl; // is a crystalline specimen? + + Rot_In_Parm rot_in_parm; // specimen rotation parameters + + Vctr_Spec_Slic_In_Parm spec_slic_in_parm; // specimen slicing input parameters + + eSim_Thick_Typ thick_type; // estt_whole_spec = 1, estt_through_thick = 2, estt_through_slices = 3 + Vctr_cpu thick; // Array of thicknesses + + Grid_2d grid_2d; // grid information + + iThread_Rect_2d output_area; // Output region information + + eEM_Sim_Typ em_sim_typ; // 11: STEM, 12: ISTEM, 21: cbed, 22: cbei, 31: ED, 32: hrtem, 41: ped, 42: hci, ... 51: EW Fourier, 52: EW real + + eIncident_Wave_Typ iw_type; // 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto + Vctr_cpu> iw_psi; // user define incident wave + + Beam_Pos_2d beam_pos_2d; // in beam positions + + T E_0; // Acceleration volatage in KeV + T lambda; // lambda + T theta; // incident tilt (in spherical coordinates) (rad) + T phi; // incident tilt (in spherical coordinates) (rad) + + eIllum_Mod illum_mod; // 1: coherent mode, 2: Partial coherente mode, 2: transmission cross coefficient, 2: full integration + eIllum_Inc illum_inc; // 1: Spatial and temporal, 2: Temporal, 3: Spatial + + Lens cond_lens; // Condenser lens + Lens obj_lens; // Objective lens + + Scan_Pat scanning; // Scan_Pat + + Detector detector; // STEM Detectors + + EELS eels_fr; // EELS + + eOperation_Mode operation_mode; // eOM_Normal = 1, eOM_Advanced = 2 + dt_bool slice_storage; // true, false + dt_bool reverse_multislice; // reverse multislice (true, false) + dt_int32 mul_sign; // tem_simulation sign + + T Vrl; // atomic potential cut-off + dt_int32 nR; // number of d_grid_blk points + + dt_int32 nrot; // Total number of rotations + + eLens_Var_Typ cdl_var_type; // eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 + Vctr_cpu cdl_var; // Array of thicknesses + + Beam_Pos_2d beam_pos; // beam positions + + dt_int32 islice; + dt_bool dp_Shift; // Shift diffraction pattern + + Multem_In_Parm(): system_config(), elec_spec_interact_mod(eesim_multislice), + atomic_pot_parm_typ(eappt_lobato_0_12), atomic_vib(), atoms(), rot_in_parm(), spec_slic_in_parm(), + thick_type(estt_whole_spec), thick(), grid_2d(), output_area(), output_area(), + iw_type(), iw_psi(), beam_pos_2d(), illum_mod(eim_partial_coherent), illum_inc(eii_temporal_spatial), em_sim_typ(eemst_ewrs), + operation_mode(eOM_Normal), slice_storage(false), reverse_multislice(false), + mul_sign(1), E_0(300), lambda(0), theta(0), phi(0), nrot(1), Vrl(c_vr_min), nR(c_nR), iw_type(eiwt_plane_wave), + is_xtl(false), islice(0), dp_Shift(false) {}; + + Multem_In_Parm(const Multem_In_Parm& multem_in_parm) + { + assign(multem_in_parm); + } + + template + void assign(TIn_Multislice &multem_in_parm) + { + system_config = multem_in_parm.system_config; + + elec_spec_interact_mod = multem_in_parm.elec_spec_interact_mod; + atomic_pot_parm_typ = multem_in_parm.atomic_pot_parm_typ; + + operation_mode = multem_in_parm.operation_mode; + slice_storage = multem_in_parm.slice_storage; + reverse_multislice = multem_in_parm.reverse_multislice; + mul_sign = multem_in_parm.mul_sign; + Vrl = multem_in_parm.Vrl; + nR = multem_in_parm.nR; + + atomic_vib = multem_in_parm.atomic_vib; + + atoms = multem_in_parm.atoms; + is_xtl = multem_in_parm.is_xtl; + + rot_in_parm = multem_in_parm.rot_in_parm; + + thick_type = multem_in_parm.thick_type; + thick = multem_in_parm.thick; + + spec_slic_typ = multem_in_parm.spec_slic_typ; + + grid_2d = multem_in_parm.grid_2d; + + em_sim_typ = multem_in_parm.em_sim_typ; + + iw_type = multem_in_parm.iw_type; + iw_psi = multem_in_parm.iw_psi; + + beam_pos_2d = multem_in_parm.beam_pos_2d; + + E_0 = multem_in_parm.E_0; + theta = multem_in_parm.theta; + phi = multem_in_parm.phi; + nrot = multem_in_parm.nrot; + + illum_mod = multem_in_parm.illum_mod; + illum_inc = multem_in_parm.illum_inc; + + cond_lens = multem_in_parm.cond_lens; + obj_lens = multem_in_parm.obj_lens; + + scanning = multem_in_parm.scanning; + detector = multem_in_parm.detector; + + eels_fr = multem_in_parm.eels_fr; + + cdl_var_type = multem_in_parm.cdl_var_type; + cdl_var = multem_in_parm.cdl_var; + + beam_pos = multem_in_parm.beam_pos; + + islice = multem_in_parm.islice; + dp_Shift = multem_in_parm.dp_Shift; + } + + template + Multem_In_Parm& operator=(const TIn_Multislice &multem_in_parm) + { + assign(multem_in_parm); + return *this; + } + + void set_dep_var() + { + atomic_vib.set_dep_var(); + + rot_in_parm.set_dep_var(); + + islice = max(0, islice); + + if (fcn_is_zero(Vrl)) + { + Vrl = c_vr_min; + } + + if (fcn_is_zero(nR)) + { + nR = c_nR; + } + + dp_Shift = (is_PED())?true:false; + + /************************ incident beam ****************************/ + if ((is_plane_wave()) || (is_scanning() && !scanning.is_scan_pat_user_def())) + { + beam_pos_2d.resize(1); + } + + beam_pos = beam_pos_2d; + + /************************** Scanning *******************************/ + if (is_scanning()) + { + if (scanning.is_scan_pat_user_def()) + { + scanning.R = beam_pos_2d.p; + } + } + else + { + scanning.set_default(); + } + + scanning.set_grid(); + + /***************************************************************************************/ + lambda = fcn_lambda(E_0); + + // multislice sign + mul_sign = (reverse_multislice)?-1:1; + + theta = set_incident_angle(theta); + nrot = max(1, nrot); + if (!is_PED_HCTEM()) + { + nrot = 1; + } + + if (is_EELS_EFTEM()) + { + atomic_vib.coh_contrib = false; + elec_spec_interact_mod = mt::eesim_multislice; + illum_mod = eim_coherent; + + auto coll_angle_max = fcn_rangs_2_rad(E_0, 2*grid_2d.g_max()); + auto coll_angle = (fcn_is_zero(eels_fr.coll_angle)||(eels_fr.coll_angle<0))?coll_angle_max:eels_fr.coll_angle; + eels_fr.set_coll_angle(coll_angle); + + if (is_EFTEMRS()) + { + obj_lens.inner_aper_ang = 0; + obj_lens.outer_aper_ang = eels_fr.coll_angle; + obj_lens.set_in_data(E_0, grid_2d); + } + } + + if (is_EWFS_EWRS()) + { + atomic_vib.coh_contrib = true; + illum_mod = eim_coherent; + } + + // It will be changed when you include spatial incoherences (beta) + if (is_CBED_CBEI() && !is_illu_mod_full_integration()) + { + illum_mod = eim_coherent; + } + + slice_storage = is_slice_storage(); + + if (!is_multislice()) + { + islice = 0; + spec_slic_typ = esst_plns_proj; + if (is_sim_through_slices()) + { + thick_type = estt_through_thick; + } + slice_storage = slice_storage || !is_sim_whole_spec(); + } + + if (is_spec_slic_by_dz_sub() && is_sim_through_thick()) + { + thick_type = estt_whole_spec; + } + + if (!is_spec_slic_by_dz_sub()) + { + atomic_vib.dim_z = false; + } + + if (is_spec_rot_active()) + { + thick_type = estt_whole_spec; + // get geometric center + if (rot_in_parm.is_geometric_center()) + { + rot_in_parm.center_p = R_3d(atoms.x_mean, atoms.y_mean, atoms.z_mean); + } + // rotate atoms + rotate_atoms(atoms, rot_in_parm.theta, rot_in_parm.u0, rot_in_parm.center_p); + // get statistic + atoms.get_statistic(); + // reset theta + rot_in_parm.theta = 0; + } + + // match slicing with the require thickness + Spec_Slic slicing; + slicing.match_thickness(spec_slic_typ, atoms, thick_type, thick); + + // remove atoms outside the thickness range + T ee_z = 0.1; + T z_e = thick.back() + ee_z; + + if (atoms.z_max > z_e) + { + T z_0 = atoms.z_min - ee_z; + remove_atoms_outside_z_range(atoms, z_0, z_e); + // get statistic + atoms.get_statistic(); + } + + /************* verify lenses parameters **************/ + + if (fcn_is_zero(cond_lens.spt_inc_sigma)) + { + illum_inc = eii_temporal; + } + + if (!is_illu_mod_full_integration()) + { + cond_lens.spt_inc_rad_npts = 1; + cond_lens.spt_inc_azm_npts = 1; + cond_lens.tp_inc_npts = 1; + + obj_lens.spt_inc_rad_npts = 1; + obj_lens.spt_inc_azm_npts = 1; + obj_lens.tp_inc_npts = 1; + } + + if (is_incoh_temporal()) + { + cond_lens.spt_inc_rad_npts = 1; + cond_lens.spt_inc_azm_npts = 1; + + obj_lens.spt_inc_rad_npts = 1; + obj_lens.spt_inc_azm_npts = 1; + } + else if (is_incoh_spatial()) + { + cond_lens.tp_inc_npts = 1; + obj_lens.tp_inc_npts = 1; + } + + // set condenser lens parameters + cond_lens.set_in_data(E_0, grid_2d); + if (atoms.empty()) + { + cond_lens.zero_def_plane = 0; + } + else + { + cond_lens.zero_def_plane = cond_lens.get_zero_def_plane(atoms.z_min, atoms.z_max); + } + + cond_lens.zero_def_typ = ezdt_user_def; + + // set objetive lens parameters + obj_lens.set_in_data(E_0, grid_2d); + + // validate output area + validate_output_area(); + } + + /***************************************************************************************/ + void set_reverse_multislice(dt_bool rm) + { + reverse_multislice = rm; + mul_sign = (reverse_multislice)?-1:1; + } + + /***************************************************************************************/ + inline + dt_int32 number_pn_conf() + { + return atomic_vib.number_conf(); + } + + dt_int32 number_of_beams() + { + return (is_scanning())?scanning.size():beam_pos.size(); + } + + dt_bool is_multi_beam() + { + return number_of_beams() > 1; + } + + Vctr, edev_cpu> extract_beam_pos(dt_int32 idx, dt_int32 n_idx) + { + dt_int32 n_beams_tot = number_of_beams(); + dt_int32 n_beams = (n_beams_tot+n_idx-1)/n_idx; + + dt_int32 ix_0 = idx*n_beams; + dt_int32 ix_e = min(ix_0+n_beams, n_beams_tot); + + auto it_0 = (is_scanning())?scanning.R.begin():beam_pos.p.begin(); + return Vctr, edev_cpu>(it_0+ix_0, it_0+ix_e); + } + + void validate_output_area() + { + if ((is_STEM() || is_STEM_EELS())) + { + if (scanning.is_scan_pat_user_def()) + { + output_area.ix_0 = 0; + output_area.ix_e = scanning.R.size(); + + output_area.iy_0 = 0; + output_area.iy_e = 1; + } + else + { + output_area.ix_0 = 0; + output_area.ix_e = scanning.nx; + + output_area.iy_0 = 0; + output_area.iy_e = scanning.ny; + } + } + else + { + if (output_area.ix_0==output_area.ix_e) + { + output_area.ix_0 = 0; + output_area.ix_e = grid_2d.nx; + } + + if (output_area.iy_0==output_area.iy_e) + { + output_area.iy_0 = 0; + output_area.iy_e = grid_2d.ny; + } + + output_area.set_ind_asc_order(); + output_area.apply_bound_ix(0, grid_2d.nx); + output_area.apply_bound_iy(0, grid_2d.ny); + } + + output_area.ind_0 = 0; + output_area.ind_e = output_area.size(); + } + + void set_iscan_beam_position() + { + // beam_pos_2d.resize(beam_pos_2d_i.size()); + // for(auto is = 0; is < beam_pos_2d_i.size(); is++) + // { + // auto idx = beam_pos_2d_i.idx[is]; + // beam_pos_2d[is] = R_2d(scanning.x[idx], scanning.y[idx]); + // } + } + + /***************************************************************************************/ + dt_bool is_spec_rot_active() const + { + return rot_in_parm.is_rot_active(); + } + + /***************************************************************************************/ + T Rx_exp_factor() + { + return 0; + // return grid_2d.factor_2pi_rx_ctr(beam_x); + } + + T Ry_exp_factor() + { + return 0; + // return grid_2d.factor_2pi_ry_ctr(beam_y); + } + + T set_incident_angle(const T& theta) const + { + T n = ::round(sin(theta)/(lambda*grid_2d.dg_min())); + return (fcn_is_zero(theta))?0:asin(n*lambda*grid_2d.dg_min()); + } + + T get_phonon_rot_weight() const + { + return 1.0/static_cast(number_pn_conf()*nrot); + } + + void set_phi(const dt_int32& irot) + { + phi = (irot == 0)?0.0:(c_2pi*static_cast(irot))/static_cast(nrot); + } + + inline + T get_propagator_factor(const T& z) const + { + return (-mul_sign*c_pi*lambda*z); + } + + T Vr_factor() const + { + return (mul_sign*fcn_transf_exp_factor(E_0, theta)); + } + + T gx_0() const + { + return sin(theta)*cos(phi)/lambda; + } + + T gy_0() const + { + return sin(theta)*sin(phi)/lambda; + } + + R_2d gu_0() const + { + return R_2d(gx_0(), gy_0()); + } + + void set_eels_fr_atom(const dt_int32& iatoms, const Ptc_Atom& atoms) + { + eels_fr.x = grid_2d.factor_2pi_rx_ctr(atoms.x[iatoms]); + eels_fr.y = grid_2d.factor_2pi_ry_ctr(atoms.y[iatoms]); + eels_fr.occ = atoms.occ[iatoms]; + } + + /***************************************************************************************/ + dt_bool is_multislice() const + { + return mt::is_multislice(elec_spec_interact_mod); + } + + dt_bool is_phase_object() const + { + return mt::is_phase_object(elec_spec_interact_mod); + } + + dt_bool is_weak_phase_object() const + { + return mt::is_weak_phase_object(elec_spec_interact_mod); + } + + /***************************************************************************************/ + + dt_bool is_avm_still_atom() const + { + return atomic_vib.is_avm_still_atom(); + } + + dt_bool is_avm_absorptive_pot() const + { + return atomic_vib.is_avm_absorptive_pot(); + } + + dt_bool is_avm_frozen_phonon() const + { + return atomic_vib.is_avm_frozen_phonon(); + } + + dt_bool is_avm_frozen_phonon_sgl_conf() const + { + return atomic_vib.is_avm_frozen_phonon_sgl_conf(); + } + + /***************************************************************************************/ + dt_bool is_sim_whole_spec() const + { + return mt::is_sim_whole_spec(thick_type); + } + + dt_bool is_sim_through_slices() const + { + return mt::is_sim_through_slices(thick_type); + } + + dt_bool is_sim_through_thick() const + { + return mt::is_sim_through_thick(thick_type); + } + + /***************************************************************************************/ + dt_bool is_spec_slic_by_plns_proj() const + { + return mt::is_spec_slic_by_plns_proj(elec_spec_interact_mod, spec_slic_typ); + } + + dt_bool is_spec_slic_by_dz_proj() const + { + return mt::is_spec_slic_by_dz_proj(elec_spec_interact_mod, spec_slic_typ); + } + + dt_bool is_spec_slic_by_dz_sub() const + { + return mt::is_spec_slic_by_dz_sub(elec_spec_interact_mod, spec_slic_typ); + } + + dt_bool is_spec_slic_by_dz_sub_whole_spec() const + { + return mt::is_spec_slic_by_dz_sub_whole_spec(elec_spec_interact_mod, spec_slic_typ, thick_type); + } + + /***************************************************************************************/ + dt_bool is_plane_wave() const + { + return mt::is_plane_wave(iw_type); + } + + dt_bool is_convergent_wave() const + { + return mt::is_convergent_wave(iw_type); + } + + dt_bool is_user_define_wave() const + { + return mt::is_user_define_wave(iw_type); + } + + /***************************************************************************************/ + dt_bool is_STEM() const + { + return mt::is_STEM(em_sim_typ); + } + + dt_bool is_ISTEM() const + { + return mt::is_ISTEM(em_sim_typ); + } + + dt_bool is_CBED() const + { + return mt::is_CBED(em_sim_typ); + } + + dt_bool is_CBEI() const + { + return mt::is_CBEI(em_sim_typ); + } + + dt_bool is_ED() const + { + return mt::is_ED(em_sim_typ); + } + + dt_bool is_HRTEM() const + { + return mt::is_HRTEM(em_sim_typ); + } + + dt_bool is_PED() const + { + return mt::is_PED(em_sim_typ); + } + + dt_bool is_HCTEM() const + { + return mt::is_HCTEM(em_sim_typ); + } + + dt_bool is_EWFS() const + { + return mt::is_EWFS(em_sim_typ); + } + + dt_bool is_EWRS() const + { + return mt::is_EWRS(em_sim_typ); + } + + dt_bool is_EWFS_SC() const + { + return mt::is_EWFS_SC(em_sim_typ, atomic_vib.model, atomic_vib.sgl_conf); + } + + dt_bool is_EWRS_SC() const + { + return mt::is_EWRS_SC(em_sim_typ, atomic_vib.model, atomic_vib.sgl_conf); + } + + dt_bool is_STEM_EELS() const + { + return mt::is_STEM_EELS(em_sim_typ); + } + + dt_bool is_ISTEM_EELS() const + { + return mt::is_ISTEM_EELS(em_sim_typ); + } + + dt_bool is_STEM_ISTEM_EELS() const + { + return mt::is_STEM_ISTEM_EELS(em_sim_typ); + } + + dt_bool is_EFTEMFS() const + { + return mt::is_EFTEMFS(em_sim_typ); + } + + dt_bool is_EFTEMRS() const + { + return mt::is_EFTEMRS(em_sim_typ); + } + + dt_bool is_EFTEM() const + { + return mt::is_EFTEM(em_sim_typ); + } + + dt_bool is_IWFS() const + { + return mt::is_IWFS(em_sim_typ); + } + + dt_bool is_IWRS() const + { + return mt::is_IWRS(em_sim_typ); + } + + dt_bool is_PPFS() const + { + return mt::is_PPFS(em_sim_typ); + } + + dt_bool is_PPRS() const + { + return mt::is_PPRS(em_sim_typ); + } + + dt_bool is_TFFS() const + { + return mt::is_TFFS(em_sim_typ); + } + + dt_bool is_TFRS() const + { + return mt::is_TFRS(em_sim_typ); + } + + dt_bool is_PropFS() const + { + return mt::is_PropFS(em_sim_typ); + } + + dt_bool is_PropRS() const + { + return mt::is_PropRS(em_sim_typ); + } + + dt_bool is_STEM_ISTEM() const + { + return mt::is_STEM_ISTEM(em_sim_typ); + } + + dt_bool is_CBED_CBEI() const + { + return mt::is_CBED_CBEI(em_sim_typ); + } + + dt_bool is_ED_HRTEM() const + { + return mt::is_ED_HRTEM(em_sim_typ); + } + + dt_bool is_PED_HCTEM() const + { + return mt::is_PED_HCTEM(em_sim_typ); + } + + dt_bool is_EWFS_EWRS() const + { + return mt::is_EWFS_EWRS(em_sim_typ); + } + + dt_bool is_EWFS_EWRS_SC() const + { + return mt::is_EWFS_EWRS_SC(em_sim_typ, atomic_vib.model, atomic_vib.sgl_conf); + } + + dt_bool is_EELS_EFTEM() const + { + return mt::is_EELS_EFTEM(em_sim_typ); + } + + dt_bool is_IWFS_IWRS() const + { + return mt::is_IWFS_IWRS(em_sim_typ); + } + + dt_bool is_PPFS_PPRS() const + { + return mt::is_PPFS_PPRS(em_sim_typ); + } + + dt_bool is_TFFS_TFRS() const + { + return mt::is_TFFS_TFRS(em_sim_typ); + } + + dt_bool is_PropFS_PropRS() const + { + return mt::is_PropFS_PropRS(em_sim_typ); + } + + dt_bool is_grid_FS() const + { + return mt::is_grid_FS(em_sim_typ); + } + + dt_bool is_grid_RS() const + { + return mt::is_grid_RS(em_sim_typ); + } + + dt_bool is_simulation_type_FS() const + { + return mt::is_simulation_type_FS(em_sim_typ); + } + + dt_bool is_simulation_type_RS() const + { + return mt::is_simulation_type_RS(em_sim_typ); + } + + dt_bool is_specimen_required() const + { + return mt::is_specimen_required(em_sim_typ); + } + + dt_bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS() const + { + return mt::is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS(em_sim_typ); + } + + dt_bool is_CBED_ED_EWFS_PED() const + { + return mt::is_CBED_ED_EWFS_PED(em_sim_typ); + } + + dt_bool is_obj_lens_temp_spat() const + { + return mt::is_obj_lens_temp_spat(em_sim_typ); + } + + dt_bool is_cond_lens_temp_spat() const + { + return mt::is_cond_lens_temp_spat(em_sim_typ); + } + + eSpace get_simulation_space() const + { + return mt::get_simulation_space(em_sim_typ); + } + + dt_bool is_scanning() const + { + return mt::is_scanning(em_sim_typ); + } + + /***************************************************************************************/ + void set_incident_wave_type(eIncident_Wave_Typ iw_type_i) + { + iw_type = mt::validate_incident_wave_type(em_sim_typ, iw_type_i); + } + + /***************************************************************************************/ + dt_bool is_illu_mod_coherent() const + { + return illum_mod == eim_coherent; + } + + dt_bool is_illu_mod_partial_coherent() const + { + return illum_mod == eim_partial_coherent; + } + + dt_bool is_illu_mod_trans_cross_coef() const + { + return illum_mod == eim_trans_cross_coef; + } + + dt_bool is_illu_mod_full_integration() const + { + return illum_mod == eim_full_integration; + } + + /***************************************************************************************/ + dt_bool is_incoh_temporal_spatial() const + { + return illum_inc == eii_temporal_spatial; + } + + dt_bool is_incoh_temporal() const + { + return illum_inc == eii_temporal; + } + + dt_bool is_incoh_spatial() const + { + return illum_inc == etst_spatial; + } + + /***************************************************************************************/ + dt_bool is_detector_circular() const + { + return detector.is_detector_circular(); + } + + dt_bool is_detector_radial() const + { + return detector.is_detector_radial(); + } + + dt_bool is_detector_matrix() const + { + return detector.is_detector_matrix(); + } + + /***************************************************************************************/ + dt_bool is_slice_storage() const + { + dt_bool slice_storage = is_PED_HCTEM() || is_EELS_EFTEM(); + slice_storage = slice_storage || is_ISTEM() || (is_STEM() && !atomic_vib.coh_contrib); + slice_storage = slice_storage || (is_CBED_CBEI() && is_illu_mod_full_integration()); + + return slice_storage; + } + + dt_bool is_operation_mode_normal() const + { + return operation_mode == eOM_Normal; + } + + dt_bool is_operation_mode_advanced() const + { + return operation_mode == eOM_Advanced; + } + + /***************************************************************************************/ + dt_bool is_lvt_off() const + { + return cdl_var == eLVT_off; + } + + dt_bool is_lvt_m() const + { + return cdl_var == eLVT_m; + } + + dt_bool is_lvt_Cs3() const + { + return cdl_var == eLVT_Cs3; + } + + dt_bool is_lvt_Cs5() const + { + return cdl_var == eLVT_Cs5; + } + + dt_bool is_lvt_mfa2() const + { + return cdl_var == eLVT_mfa2; + } + + dt_bool is_lvt_afa2() const + { + return cdl_var == eLVT_afa2; + } + + dt_bool is_lvt_mfa3() const + { + return cdl_var == eLVT_mfa3; + } + + dt_bool is_lvt_afa3() const + { + return cdl_var == eLVT_afa3; + } + + dt_bool is_lvt_inner_aper_ang() const + { + return cdl_var == eLVT_inner_aper_ang; + } + + dt_bool is_lvt_outer_aper_ang() const + { + return cdl_var == eLVT_outer_aper_ang; + } + + }; + } + +#endif \ No newline at end of file diff --git a/src/mx_2x2.h b/src/mx_2x2.h new file mode 100755 index 00000000..6c7540ae --- /dev/null +++ b/src/mx_2x2.h @@ -0,0 +1,162 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "r_2d.h" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +namespace mt +{ + /* 2x2 matrix */ + template + class Mx_2x2 + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + Mx_2x2(); + + /* constructor */ + CGPU_EXEC + Mx_2x2(const T& c_11, const T& c_21, const T& c_12, const T& c_22); + + /* converting constructor */ + template + CGPU_EXEC + Mx_2x2(const U& c_11, const U& c_21, const U& c_12, const U& c_22); + + /* Copy constructor */ + CGPU_EXEC + Mx_2x2(const Mx_2x2& mx); + + /* Move constructor */ + template + CGPU_EXEC + Mx_2x2(Mx_2x2&& mx); + + /* converting copy constructor */ + template + CGPU_EXEC + Mx_2x2(const Mx_2x2& mx); + + template > + CGPU_EXEC + Mx_2x2(U* v); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Mx_2x2& operator=(const Mx_2x2& mx); + + /* Move assignment operator */ + CGPU_EXEC + Mx_2x2& operator=(Mx_2x2&& mx); + + /* converting assignment operator */ + template + CGPU_EXEC + Mx_2x2& operator=(const Mx_2x2& mx); + + /******************* Compound assignment operators *******************/ + template + CGPU_EXEC + Mx_2x2& operator+=(const Mx_2x2& mx); + + template + CGPU_EXEC + Mx_2x2& operator+=(const U& mx); + + template + CGPU_EXEC + Mx_2x2& operator-=(const Mx_2x2& mx); + + template + CGPU_EXEC + Mx_2x2& operator-=(const U& mx); + + template + CGPU_EXEC + Mx_2x2& operator*=(const Mx_2x2& mx); + + template + CGPU_EXEC + Mx_2x2& operator*=(const U& mx); + + template + CGPU_EXEC + Mx_2x2& operator/=(const Mx_2x2& mx); + + template + CGPU_EXEC + Mx_2x2& operator/=(const U& mx); + + /************************** Other operators **************************/ + dt_int32 size() const; + + CGPU_EXEC_INL + T& operator[](const dt_int32 idx); + + CGPU_EXEC_INL + const T& operator[](const dt_int32 idx) const; + + CGPU_EXEC_INL + T& operator()(const dt_int32 ir, const dt_int32 ic); + + CGPU_EXEC_INL + const T& operator()(const dt_int32 ir, const dt_int32 ic) const; + + + CGPU_EXEC + dt_bool fcn_is_zero() const; + + CGPU_EXEC + dt_bool is_nzero() const; + + CGPU_EXEC + dt_bool is_id_mx() const; + + CGPU_EXEC + T min() const; + + CGPU_EXEC + T max() const; + + CGPU_EXEC + T det() const; + + CGPU_EXEC + Mx_2x2 inv() const; + + private: + T m_data[4]; + }; +} + +#include "detail/mx_2x2.inl" \ No newline at end of file diff --git a/src/mx_3x3.h b/src/mx_3x3.h new file mode 100755 index 00000000..7dbdf9de --- /dev/null +++ b/src/mx_3x3.h @@ -0,0 +1,164 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "r_3d.h" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +namespace mt +{ + /* 3x3 matrix */ + template + class Mx_3x3 + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + Mx_3x3(); + + /* constructor */ + CGPU_EXEC + Mx_3x3(const T& c_11, const T& c_21, const T& c_31, const T& c_12, + const T& c_22, const T& c_32, const T& c_13, const T& c_23, const T& c_33); + + /* converting constructor */ + template + CGPU_EXEC + Mx_3x3(const U& c_11, const U& c_21, const U& c_31, const U& c_12, + const U& c_22, const U& c_32, const U& c_13, const U& c_23, const U& c_33); + + + /* Copy constructor */ + CGPU_EXEC + Mx_3x3(const Mx_3x3& mx); + + /* Move constructor */ + template + CGPU_EXEC + Mx_3x3(Mx_3x3&& mx); + + /* converting copy constructor */ + template + CGPU_EXEC + Mx_3x3(const Mx_3x3& mx); + + template > + CGPU_EXEC + Mx_3x3(U* v); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Mx_3x3& operator=(const Mx_3x3& mx); + + /* Move assignment operator */ + CGPU_EXEC + Mx_3x3& operator=(Mx_3x3&& mx); + + /* converting assignment operator */ + template + CGPU_EXEC + Mx_3x3& operator=(const Mx_3x3& mx); + + /******************* Compound assignment operators *******************/ + template + CGPU_EXEC + Mx_3x3& operator+=(const Mx_3x3& mx); + + template + CGPU_EXEC + Mx_3x3& operator+=(const U& mx); + + template + CGPU_EXEC + Mx_3x3& operator-=(const Mx_3x3& mx); + + template + CGPU_EXEC + Mx_3x3& operator-=(const U& mx); + + template + CGPU_EXEC + Mx_3x3& operator*=(const Mx_3x3& mx); + + template + CGPU_EXEC + Mx_3x3& operator*=(const U& mx); + + template + CGPU_EXEC + Mx_3x3& operator/=(const Mx_3x3& mx); + + template + CGPU_EXEC + Mx_3x3& operator/=(const U& mx); + + /************************** Other operators **************************/ + dt_int32 size() const; + + CGPU_EXEC_INL + T& operator[](const dt_int32 idx); + + CGPU_EXEC_INL + const T& operator[](const dt_int32 idx) const; + + CGPU_EXEC_INL + T& operator()(const dt_int32 ir, const dt_int32 ic); + + CGPU_EXEC_INL + const T& operator()(const dt_int32 ir, const dt_int32 ic) const; + + CGPU_EXEC + dt_bool fcn_is_zero() const; + + CGPU_EXEC + dt_bool is_nzero() const; + + CGPU_EXEC + dt_bool is_id_mx() const; + + CGPU_EXEC + T min() const; + + CGPU_EXEC + T max() const; + + CGPU_EXEC + T det() const; + + CGPU_EXEC + Mx_3x3 inv() const; + + private: + T m_data[9]; + }; +} + +#include "detail/mx_3x3.inl" \ No newline at end of file diff --git a/src/output_multislice.hpp b/src/output_multislice.hpp deleted file mode 100644 index 93c94048..00000000 --- a/src/output_multislice.hpp +++ /dev/null @@ -1,1358 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef OUTPUT_MULTISLICE_H -#define OUTPUT_MULTISLICE_H - -#include -#include - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "matlab_types.cuh" -#include "atomic_data_mt.hpp" -#include "input_multislice.cuh" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" - -namespace mt -{ - inline - bool is_ot_image_tot_coh(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_image_tot_coh; - } - - inline - bool is_ot_image_tot(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_image_tot; - } - - inline - bool is_ot_m2psi_tot_coh(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_m2psi_tot_coh; - } - - inline - bool is_ot_m2psi_tot(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_m2psi_tot; - } - - inline - bool is_ot_m2psi_tot_psi_coh(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_m2psi_tot_psi_coh; - } - - inline - bool is_ot_psi_coh(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_psi_coh; - } - - inline - bool is_ot_psi_0(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_psi_0; - } - - inline - bool is_ot_V(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_V; - } - - inline - bool is_ot_trans(const eTEM_Output_Type &output_type) - { - return output_type == mt::eTEMOT_trans; - } - - /**************************************************************************************/ - template - class Output_Multislice : public Input_Multislice - { - public: - using T_r = T; - using T_c = complex; - - using TVector_hr = host_vector; - using TVector_hc = host_vector>; - - using TVector_dr = device_vector; - using TVector_dc = device_vector>; - - Output_Multislice() : Input_Multislice(), output_type(eTEMOT_m2psi_tot), - ndetector(0), nx(0), ny(0), dx(0), dy(0), dr(0), n_thk(0), n_thk_d(0) {} - - template - void assign(TOutput_Multislice &output_multislice) - { - assign_input_multislice(output_multislice); - - output_type = output_multislice.output_type; - ndetector = output_multislice.ndetector; - nx = output_multislice.nx; - ny = output_multislice.ny; - dx = output_multislice.dx; - dy = output_multislice.dy; - dr = output_multislice.dr; - - x = output_multislice.x; - y = output_multislice.y; - r = output_multislice.r; - - image_tot.resize(output_multislice.image_tot.size()); - for (auto ithk = 0; ithk < output_multislice.image_tot.size(); ithk++) - { - image_tot[ithk].image.resize(output_multislice.image_tot[ithk].image.size()); - for (auto idet = 0; idet < output_multislice.image_tot[ithk].image.size(); idet++) - { - image_tot[ithk].image[idet] = output_multislice.image_tot[ithk].image[idet]; - } - } - - image_coh.resize(output_multislice.image_coh.size()); - for (auto ithk = 0; ithk < output_multislice.image_coh.size(); ithk++) - { - image_coh[ithk].image.resize(output_multislice.image_coh[ithk].image.size()); - for (auto idet = 0; idet < output_multislice.image_coh[ithk].image.size(); idet++) - { - image_coh[ithk].image[idet] = output_multislice.image_coh[ithk].image[idet]; - } - } - - m2psi_tot.resize(output_multislice.m2psi_tot.size()); - for (auto ithk = 0; ithk < output_multislice.m2psi_tot.size(); ithk++) - { - m2psi_tot[ithk] = output_multislice.m2psi_tot[ithk]; - } - - m2psi_coh.resize(output_multislice.m2psi_coh.size()); - for (auto ithk = 0; ithk < output_multislice.m2psi_coh.size(); ithk++) - { - m2psi_coh[ithk] = output_multislice.m2psi_coh[ithk]; - } - - psi_coh.resize(output_multislice.psi_coh.size()); - for (auto ithk = 0; ithk < output_multislice.psi_coh.size(); ithk++) - { - psi_coh[ithk] = output_multislice.psi_coh[ithk]; - } - - V.resize(output_multislice.V.size()); - for (auto ithk = 0; ithk < output_multislice.V.size(); ithk++) - { - V[ithk] = output_multislice.V[ithk]; - } - - trans.resize(output_multislice.trans.size()); - for (auto ithk = 0; ithk < output_multislice.trans.size(); ithk++) - { - trans[ithk] = output_multislice.trans[ithk]; - } - - psi_0.resize(output_multislice.psi_0.size()); - for (auto ithk = 0; ithk < output_multislice.psi_0.size(); ithk++) - { - psi_0[ithk] = output_multislice.psi_0[ithk]; - } - } - - template - Output_Multislice& operator=(TOutput_Multislice &output_multislice) - { - assign(output_multislice); - return *this; - } - - void clear() - { - output_type = eTEMOT_m2psi_tot; - ndetector = 0; - nx = 0; - ny = 0; - dx = 0; - dy = 0; - dr = 0; - - n_thk = 0; - n_thk_d = 0; - - x.clear(); - x.shrink_to_fit(); - - y.clear(); - y.shrink_to_fit(); - - r.clear(); - r.shrink_to_fit(); - - image_tot.clear(); - image_tot.shrink_to_fit(); - - image_coh.clear(); - image_coh.shrink_to_fit(); - - m2psi_tot.clear(); - m2psi_tot.shrink_to_fit(); - - m2psi_coh.clear(); - m2psi_coh.shrink_to_fit(); - - psi_coh.clear(); - psi_coh.shrink_to_fit(); - - /*******************************************/ - psi_zh.clear(); - psi_zh.shrink_to_fit(); - - m2psi_zh.clear(); - m2psi_zh.shrink_to_fit(); - - thk_gpu.clear(); - thk_gpu.shrink_to_fit(); - - m2psi_tot_d.clear(); - m2psi_tot_d.shrink_to_fit(); - - m2psi_coh_d.clear(); - m2psi_coh_d.shrink_to_fit(); - - psi_coh_d.clear(); - psi_coh_d.shrink_to_fit(); - - /*******************************************/ - V.clear(); - V.shrink_to_fit(); - - trans.clear(); - trans.shrink_to_fit(); - - psi_0.clear(); - psi_0.shrink_to_fit(); - } - - void clean_temporal() - { - psi_zh.clear(); - //psi_zh.shrink_to_fit(); - - m2psi_zh.clear(); - //m2psi_zh.shrink_to_fit(); - - switch (output_type) - { - case eTEMOT_image_tot_coh: - { - for (auto ithk = 0; ithk < n_thk; ithk++) - { - psi_coh[ithk].clear(); - //psi_coh[ithk].shrink_to_fit(); - - thk_gpu[ithk] = false; - - if(ithk - void set_input_data(TInput_Multislice *input_multislice) - { - clear(); - - stream.resize(1); - - assign_input_multislice(*input_multislice); - - // set required number of thickness - n_thk = this->thick.size(); - n_thk_d = 0; - - thk_gpu.resize(n_thk); - std::fill(thk_gpu.begin(), thk_gpu.end(), false); - - // check selected device - auto bb_is_device = this->system_conf.is_device(); - - // get available gpu free memory - double free_memory_mb = get_free_memory() - 10; - int nxy_r = this->output_area.nxy(); - int nxy_g = this->grid_2d.nxy(); - - if(bb_is_device) - { - psi_zh.resize(nxy_g); - m2psi_zh.resize(nxy_g); - } - - ndetector = (this->is_EELS()) ? 1 : this->detector.size(); - - set_output_grid(); - - set_output_type(); - - switch (output_type) - { - case eTEMOT_image_tot_coh: - { - image_tot.resize(n_thk); - image_coh.resize(n_thk); - psi_coh.resize(n_thk); - - n_thk_d = (bb_is_device)?cal_n_thk_a(free_memory_mb, nxy_g):0; - n_thk_d = min(n_thk_d, n_thk); - - psi_coh_d.resize(n_thk_d); - - for (auto ithk = 0; ithk < n_thk; ithk++) - { - image_tot[ithk].image.resize(ndetector); - image_coh[ithk].image.resize(ndetector); - - for (auto idet = 0; idet < ndetector; idet++) - { - image_tot[ithk].image[idet].resize(nxy()); - image_coh[ithk].image[idet].resize(nxy()); - } - - psi_coh[ithk].resize(nxy_g); - - if(ithk(free_memory_mb, nxy_r+nxy_g):0; - n_thk_d = min(n_thk_d, n_thk); - - m2psi_tot_d.resize(n_thk_d); - m2psi_coh_d.resize(n_thk_d); - psi_coh_d.resize(n_thk_d); - - for (auto ithk = 0; ithk < n_thk; ithk++) - { - m2psi_tot[ithk].resize(nxy_r); - m2psi_coh[ithk].resize(nxy_r); - psi_coh[ithk].resize(nxy_g); - - if(ithk(free_memory_mb, nxy_r):0; - n_thk_d = min(n_thk_d, n_thk); - - m2psi_tot_d.resize(n_thk_d); - - for (auto ithk = 0; ithk < n_thk; ithk++) - { - m2psi_tot[ithk].resize(nxy_r); - - if(ithk(free_memory_mb, nxy_r+2*nxy_g):0; - n_thk_d = min(n_thk_d, n_thk); - - m2psi_tot_d.resize(n_thk_d); - psi_coh_d.resize(n_thk_d); - - for (auto ithk = 0; ithk < n_thk; ithk++) - { - m2psi_tot[ithk].resize(nxy_r); - psi_coh[ithk].resize(nxy_g); - - if(ithk(free_memory_mb, nxy_g):0; - n_thk_d = min(n_thk_d, n_thk); - - psi_coh_d.resize(n_thk_d); - - for (auto ithk = 0; ithk < n_thk; ithk++) - { - psi_coh[ithk].resize(nxy_g); - - if(ithkthick.size(); ithk++) - { - for (auto idet = 0; idet < image_tot[ithk].image.size(); idet++) - { - mt::fill(stream, image_tot[ithk].image[idet], T_r(0)); - mt::fill(stream, image_coh[ithk].image[idet], T_r(0)); - } - mt::fill(stream, psi_coh[ithk], T_c(0)); - - if(ithkthick.size(); ithk++) - { - for (auto idet = 0; idet < image_tot[ithk].image.size(); idet++) - { - mt::fill(stream, image_tot[ithk].image[idet], T_r(0)); - } - } - } - break; - case eTEMOT_m2psi_tot_coh: - { - for (auto ithk = 0; ithk < this->thick.size(); ithk++) - { - mt::fill(stream, m2psi_tot[ithk], T_r(0)); - mt::fill(stream, m2psi_coh[ithk], T_r(0)); - mt::fill(stream, psi_coh[ithk], T_c(0)); - - if(ithkthick.size(); ithk++) - { - mt::fill(stream, m2psi_tot[ithk], T_r(0)); - - if(ithkthick.size(); ithk++) - { - mt::fill(stream, m2psi_tot[ithk], T_r(0)); - mt::fill(stream, psi_coh[ithk], T_c(0)); - - if(ithkthick.size(); ithk++) - { - mt::fill(stream, psi_coh[ithk], T_c(0)); - - if(ithkthick.size(); ithk++) - { - mt::fill(stream, psi_0[ithk], T_c(0)); - } - } - break; - case eTEMOT_V: - { - for (auto ithk = 0; ithk < this->thick.size(); ithk++) - { - mt::fill(stream, V[ithk], T_r(0)); - } - } - break; - case eTEMOT_trans: - { - for (auto ithk = 0; ithk < this->thick.size(); ithk++) - { - mt::fill(stream, trans[ithk], T_c(0)); - } - } - break; - } - } - - void init_psi_coh() - { - for (auto ithk = 0; ithk < this->thick.size(); ithk++) - { - if(ithk - void add_scale_psi_coh(int ithk, T_c w, TVector &phi) - { - if(thk_gpu[ithk]) - { - thrust::transform(thrust::device, phi.begin(), phi.end(), psi_coh_d[ithk].begin(), psi_coh_d[ithk].begin(), functor::add_scale(w)); - } - else - { - mt::add_scale_to_host(stream, w, phi, psi_coh[ithk], &psi_zh); - } - } - - template - void add_scale_shift_psi_coh(int ithk, T_c w, TVector &phi) - { - if(thk_gpu[ithk]) - { - mt::add_scale_shift_2d(this->grid_2d, w, phi, psi_coh_d[ithk], &psi_zh); - } - else - { - mt::add_scale_shift_2d(this->grid_2d, w, phi, psi_coh[ithk], &psi_zh); - } - } - - template - void add_scale_crop_shift_psi_coh(int ithk, T_c w, TVector &phi) - { - if(thk_gpu[ithk]) - { - mt::add_scale_crop_shift_2d(this->grid_2d, w, phi, this->output_area, psi_coh_d[ithk], &psi_zh); - } - else - { - mt::add_scale_crop_shift_2d(this->grid_2d, w, phi, this->output_area, psi_coh[ithk], &psi_zh); - } - } - - template - void add_scale_crop_shift_m2psi_coh_from_psi(int ithk, T_r w, TVector &phi) - { - if(thk_gpu[ithk]) - { - mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_coh_d[ithk], &psi_zh); - } - else - { - mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_coh[ithk], &psi_zh); - } - } - - template - void add_scale_crop_shift_m2psi_coh_from_m2psi(int ithk, T_r w, TVector &m2phi) - { - if(thk_gpu[ithk]) - { - mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_coh_d[ithk], &m2psi_zh); - } - else - { - mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_coh[ithk], &m2psi_zh); - } - } - - template - void add_scale_crop_shift_m2psi_tot_from_psi(int ithk, T_r w, TVector phi) - { - if(thk_gpu[ithk]) - { - mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_tot_d[ithk], &psi_zh); - } - else - { - mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_tot[ithk], &psi_zh); - } - } - - template - void add_scale_crop_shift_m2psi_tot_from_m2psi(int ithk, T_r w, TVector &m2phi) - { - if(thk_gpu[ithk]) - { - mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_tot_d[ithk], &m2psi_zh); - } - else - { - mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_tot[ithk], &m2psi_zh); - } - } - - /***************************************************************************/ - template - void set_psi_coh(int ithk, TVector &phi) - { - if(thk_gpu[ithk]) - { - thrust::copy(phi.begin(), phi.end(), psi_coh_d[ithk].begin()); - } - else - { - thrust::copy(phi.begin(), phi.end(), psi_coh[ithk].begin()); - } - } - - template - void set_shift_psi_coh(int ithk, TVector &phi) - { - if(thk_gpu[ithk]) - { - mt::assign_shift_2d(this->grid_2d, phi, psi_coh_d[ithk], &psi_zh); - } - else - { - mt::assign_shift_2d(this->grid_2d, phi, psi_coh[ithk], &psi_zh); - } - } - - template - void set_crop_shift_psi_coh(int ithk, TVector &phi) - { - if(thk_gpu[ithk]) - { - mt::assign_crop_shift_2d(this->grid_2d, phi, this->output_area, psi_coh_d[ithk], &psi_zh); - } - else - { - mt::assign_crop_shift_2d(this->grid_2d, phi, this->output_area, psi_coh[ithk], &psi_zh); - } - } - - template - void set_crop_shift_m2psi_coh(int ithk, TVector &m2phi) - { - if(thk_gpu[ithk]) - { - mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_coh_d[ithk], &m2psi_zh); - } - else - { - mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_coh[ithk], &m2psi_zh); - } - } - - template - void set_crop_shift_m2psi_tot(int ithk, TVector &m2phi) - { - if(thk_gpu[ithk]) - { - mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_tot_d[ithk], &m2psi_zh); - } - else - { - mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_tot[ithk], &m2psi_zh); - } - } - - /***************************************************************************/ - template - void from_psi_coh_2_phi(int ithk, TVector &phi) - { - if(thk_gpu[ithk]) - { - thrust::copy(psi_coh_d[ithk].begin(), psi_coh_d[ithk].end(), phi.begin()); - } - else - { - thrust::copy(psi_coh[ithk].begin(), psi_coh[ithk].end(), phi.begin()); - } - } - - template - void from_m2psi_coh_2_m2phi(int ithk, TVector &m2phi) - { - if(thk_gpu[ithk]) - { - thrust::copy(m2psi_coh_d[ithk].begin(), m2psi_coh_d[ithk].end(), m2phi.begin()); - } - else - { - thrust::copy(m2psi_coh[ithk].begin(), m2psi_coh[ithk].end(), m2phi.begin()); - } - } - - template - void from_m2psi_tot_2_m2phi(int ithk, TVector &m2phi) - { - if(thk_gpu[ithk]) - { - thrust::copy(m2psi_tot_d[ithk].begin(), m2psi_tot_d[ithk].end(), m2phi.begin()); - } - else - { - thrust::copy(m2psi_tot[ithk].begin(), m2psi_tot[ithk].end(), m2phi.begin()); - } - } - - void gather() - { - const int n_thk = this->thick.size(); - - switch (output_type) - { - case eTEMOT_m2psi_tot_coh: - { - for (auto ithk = 0; ithk < n_thk; ithk++) - { - if(ithkgrid_2d, psi_0[ithk]); - } - } - break; - case eTEMOT_V: - { - for (auto ithk = 0; ithk < n_thk; ithk++) - { - mt::fft2_shift(stream, this->grid_2d, V[ithk]); - } - } - break; - case eTEMOT_trans: - { - for (auto ithk = 0; ithk < n_thk; ithk++) - { - mt::fft2_shift(stream, this->grid_2d, trans[ithk]); - } - } - break; - } - } - - int nxy() const { return nx*ny; } - - /**************************************************************************************/ - inline - bool is_ot_image_tot_coh() const - { - return mt::is_ot_image_tot_coh(output_type); - } - - inline - bool is_ot_image_tot() const - { - return mt::is_ot_image_tot(output_type); - } - - inline - bool is_ot_m2psi_tot_coh() const - { - return mt::is_ot_m2psi_tot_coh(output_type); - } - - inline - bool is_ot_m2psi_tot() const - { - return mt::is_ot_m2psi_tot(output_type); - } - - inline - bool is_ot_m2psi_tot_psi_coh() const - { - return mt::is_ot_m2psi_tot_psi_coh(output_type); - } - - inline - bool is_ot_psi_coh() const - { - return mt::is_ot_psi_coh(output_type); - } - - inline - bool is_ot_psi_0() const - { - return mt::is_ot_psi_0(output_type); - } - - inline - bool is_ot_V() const - { - return mt::is_ot_V(output_type); - } - - inline - bool is_ot_trans() const - { - return mt::is_ot_trans(output_type); - } - - host_vector extract_data(ePhonon_Model_Output fp_ctr, eShow_CData show_data, int ithk, int idet = 0) - { - host_vector data(nxy()); - - switch (output_type) - { - case eTEMOT_image_tot_coh: - { - data = (fp_ctr == eFMO_Total) ? image_tot[ithk].image[idet] : image_coh[ithk].image[idet]; - } - break; - case eTEMOT_image_tot: - { - data = image_tot[ithk].image[idet]; - } - break; - case eTEMOT_m2psi_tot_coh: - { - data = (fp_ctr == eFMO_Total) ? m2psi_tot[ithk] : m2psi_coh[ithk]; - } - break; - case eTEMOT_m2psi_tot: - { - data = m2psi_tot[ithk]; - } - break; - case eTEMOT_m2psi_tot_psi_coh: - { - if (fp_ctr == eFMO_Total) - { - data = m2psi_tot[ithk]; - } - else - { - from_complex_to_real(show_data, psi_coh[ithk], data); - } - } - break; - case eTEMOT_psi_coh: - { - from_complex_to_real(show_data, psi_coh[ithk], data); - } - break; - case eTEMOT_psi_0: - { - from_complex_to_real(show_data, psi_0[ithk], data); - } - break; - case eTEMOT_V: - { - data = V[ithk]; - } - break; - case eTEMOT_trans: - { - from_complex_to_real(show_data, trans[ithk], data); - } - break; - } - - return data; - } - - eTEM_Output_Type output_type; - - int ndetector; - int nx; - int ny; - T_r dx; - T_r dy; - T_r dr; - - host_vector x; - host_vector y; - host_vector r; - - host_vector> image_tot; - host_vector> image_coh; - - host_vector m2psi_tot; - host_vector m2psi_coh; - host_vector psi_coh; - host_vector V; - host_vector trans; - host_vector psi_0; - - std::vector thk_gpu; - host_vector m2psi_tot_d; - host_vector m2psi_coh_d; - host_vector psi_coh_d; - - Stream stream; - private: - Vector psi_zh; - Vector m2psi_zh; - - int n_thk; - int n_thk_d; - - template - int cal_n_thk_a(double memory, int nxy) - { - return static_cast(floor(memory/mt::sizeMb(nxy))); - } - - void set_output_grid() - { - if (this->is_STEM() || this->is_EELS()) - { - nx = this->scanning.nx; - ny = this->scanning.ny; - - dx = this->scanning.dRx; - dy = this->scanning.dRy; - - x = this->scanning.x; - y = this->scanning.y; - r = this->scanning.r; - } - else - { - nx = this->output_area.nx(); - ny = this->output_area.ny(); - - const bool is_RS = this->is_grid_RS(); - dx = (is_RS)?this->grid_2d.dRx:this->grid_2d.dgx; - dy = (is_RS)?this->grid_2d.dRy:this->grid_2d.dgy; - - x.resize(nx); - y.resize(ny); - - for (auto ix = this->output_area.ix_0; ix < this->output_area.ix_e; ix++) - { - int ix_s = ix-this->output_area.ix_0; - x[ix_s] = (is_RS)?this->grid_2d.Rx(ix):this->grid_2d.gx(ix); - } - - for (auto iy = this->output_area.iy_0; iy < this->output_area.iy_e; iy++) - { - int iy_s = iy-this->output_area.iy_0; - y[iy_s] = (is_RS)?this->grid_2d.Ry(iy):this->grid_2d.gy(iy); - } - } - } - - // 1:(image_tot, image_coh); 2:(image_tot); 3:(m2psi_tot, m2psi_coh); 4:(m2psi_tot); - // 5:(m2psi_tot, psi_coh); 6:(psi_coh); 7:(psi_0); 8:(V); 9:(trans) - void set_output_type() - { - if (this->is_STEM() || this->is_EELS()) - { - output_type = (this->pn_coh_contrib) ? eTEMOT_image_tot_coh : eTEMOT_image_tot; - } - else if (this->is_ISTEM() || this->is_CBED_CBEI() || this->is_PED_HCTEM() || - this->is_ED_HRTEM() || this->is_EFTEM()) - { - output_type = (this->pn_coh_contrib) ? eTEMOT_m2psi_tot_coh : eTEMOT_m2psi_tot; - } - else if (this->is_EWFS_EWRS()) - { - output_type = (this->is_EWFS_EWRS_SC()) ? eTEMOT_psi_coh : eTEMOT_m2psi_tot_psi_coh; - } - else if (this->is_PropFS_PropRS()) - { - output_type = eTEMOT_psi_coh; - } - else if (this->is_IWFS_IWRS()) - { - output_type = eTEMOT_psi_0; - } - else if (this->is_PPFS_PPRS()) - { - output_type = eTEMOT_V; - } - else if (this->is_TFFS_TFRS()) - { - output_type = eTEMOT_trans; - } - } - - template - void assign_input_multislice(TInput_Multislice &input_multislice) - { - this->system_conf = input_multislice.system_conf; - - this->interaction_model = input_multislice.interaction_model; - this->potential_type = input_multislice.potential_type; - - this->operation_mode = input_multislice.operation_mode; - this->slice_storage = input_multislice.slice_storage; - this->reverse_multislice = input_multislice.reverse_multislice; - this->mul_sign = input_multislice.mul_sign; - this->Vrl = input_multislice.Vrl; - this->nR = input_multislice.nR; - - this->pn_model = input_multislice.pn_model; - this->pn_coh_contrib = input_multislice.pn_coh_contrib; - this->pn_dim = input_multislice.pn_dim; - this->fp_dist = input_multislice.fp_dist; - this->pn_seed = input_multislice.pn_seed; - this->pn_single_conf = input_multislice.pn_single_conf; - this->pn_nconf = input_multislice.pn_nconf; - - this->atoms = input_multislice.atoms; - this->is_crystal = input_multislice.is_crystal; - - this->spec_rot_theta = input_multislice.spec_rot_theta; - this->spec_rot_u0 = input_multislice.spec_rot_u0; - this->spec_rot_center_type = input_multislice.spec_rot_center_type; - this->spec_rot_center_p = input_multislice.spec_rot_center_p; - - this->thick_type = input_multislice.thick_type; - this->thick = input_multislice.thick; - - this->potential_slicing = input_multislice.potential_slicing; - - this->grid_2d = input_multislice.grid_2d; - this->output_area = input_multislice.output_area; - - this->simulation_type = input_multislice.simulation_type; - - this->iw_type = input_multislice.iw_type; - this->iw_psi = input_multislice.iw_psi; - this->iw_x = input_multislice.iw_x; - this->iw_y = input_multislice.iw_y; - - this->E_0 = input_multislice.E_0; - this->theta = input_multislice.theta; - this->phi = input_multislice.phi; - this->nrot = input_multislice.nrot; - - this->illumination_model = input_multislice.illumination_model; - this->temporal_spatial_incoh = input_multislice.temporal_spatial_incoh; - - this->cond_lens = input_multislice.cond_lens; - this->obj_lens = input_multislice.obj_lens; - - this->scanning = input_multislice.scanning; - this->detector = input_multislice.detector; - - this->eels_fr = input_multislice.eels_fr; - - this->cdl_var_type = input_multislice.cdl_var_type; - this->cdl_var = input_multislice.cdl_var; - - this->iscan = input_multislice.iscan; - this->beam_x = input_multislice.beam_x; - this->beam_y = input_multislice.beam_y; - - this->islice = input_multislice.islice; - this->dp_Shift = input_multislice.dp_Shift; - } - }; - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/output_tomography.hpp b/src/output_tomography.hpp deleted file mode 100644 index b5a514ac..00000000 --- a/src/output_tomography.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef OUTPUT_TOMOGRAPHY_H -#define OUTPUT_TOMOGRAPHY_H - -#include "types.cuh" -#include "traits.cuh" -#include "atomic_data_mt.hpp" -#include "input_tomography.cuh" - -namespace mt -{ - template - class Output_Tomography: public Input_Tomography> - { - public: - using T_r = Value_type; - static const bool is_vector = !is_rmatrix_r::value; - - template - void set_input_data(TInput_Tomography *input_tomography_i) - { - set_input_tomography(input_tomography_i); - if(is_vector) - { - // temp.resize(input_tomography_i->atoms.size()); - // chi2.resize(input_tomography_i->atoms.size()); - - Z.resize(input_tomography_i->atoms.size()); - x.resize(input_tomography_i->atoms.size()); - y.resize(input_tomography_i->atoms.size()); - z.resize(input_tomography_i->atoms.size()); - } - } - - TVector_r temp; - TVector_r chi2; - TVector_r Z; - TVector_r x; - TVector_r y; - TVector_r z; - private: - template - void set_input_tomography(TInput_Tomography *input_tomography) - { - this->precision = input_tomography->precision; - this->device = input_tomography->device; - this->cpu_nthread = input_tomography->cpu_nthread; - this->gpu_device = input_tomography->gpu_device; - this->gpu_nstream = input_tomography->gpu_nstream; - - - this->spec_rot_u0 = input_tomography->spec_rot_u0; - this->spec_rot_center_p = input_tomography->spec_rot_center_p; - - this->grid_2d = input_tomography->grid_2d; - - temp.clear(); - chi2.clear(); - } - }; - - using Output_Tomography_Matlab = Output_Tomography; - - template - using Output_Tomography_Vector = Output_Tomography>; - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/particle_fcns.hpp b/src/particle_fcns.hpp new file mode 100755 index 00000000..27ce44d0 --- /dev/null +++ b/src/particle_fcns.hpp @@ -0,0 +1,381 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PARTICLE_FCNS_H + #define PARTICLE_FCNS_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + + #include "macros.h" + #include "math_mt.h" + #include "type_traits_gen.h" + #include "r_2d.h" + #include "r_3d.h" + #include "vctr_cpu.h" + + namespace mt + { + // calculate the mean position using xy cordinates and it frequency + template + enable_if_vctr_cpu_r_2d>> + fcn_xy_2_xyc(TVctr& vr_2d, Value_type_r radius) + { + using T = Value_type_r; + using ST = Size_type; + + const ST n_vr_2d = vr_2d.size(); + + const T r2_max = ::square(radius); + + Vctr_r_3d_cpu vr_3d; + vr_3d.reserve(n_vr_2d); + + std::vector bb(n_vr_2d, true); + + for(ST ip = 0; ip < n_vr_2d; ip++) + { + if (bb[ip]) + { + const auto r_i = vr_2d[ip]; + + ST ic = 0; + R_2d p_m = 0; + + for(ST ip_s = 0; ip_s < n_vr_2d; ip_s++) + { + if (bb[ip_s]) + { + if (norm_2(vr_2d[ip_s]-r_i) < r2_max) + { + p_m += vr_2d[ip_s]; + bb[ip_s] = false; + ic++; + } + } + } + p_m /= T(ic); + + vr_3d.push_back(R_3d(p_m.x, p_m.y, T(ic))); + } + } + + return vr_3d; + } + + // replace xy positions by its mean positions using a xy reference + template + enable_if_vctr_cpu_r_2d + fcn_xy_2_xym(const TVctr& vr_2d_r, Value_type_r radius, TVctr& vr_2d_io) + { + using T = Value_type_r; + using ST = Size_type; + + const ST n_vr_2d = vr_2d_io.size(); + const ST n_vr_2d_r = vr_2d_r.size(); + //const ST n_vr_2d_r = min(vr_2d_r.size(), n_vr_2d); + + const T r2_max = ::square(radius); + + std::vector bb(n_vr_2d, true); + std::vector ind_s(n_vr_2d, ST(0)); + + for(ST ip = 0; ip < n_vr_2d_r; ip++) + { + const auto r_c = vr_2d_r[ip]; + + ST ic = 0; + R_2d p_m = 0; + + for(ST ip_s = 0; ip_s < n_vr_2d; ip_s++) + { + if (bb[ip_s]) + { + if (norm_2(vr_2d_io[ip_s]-r_c) < r2_max) + { + p_m += vr_2d_io[ip_s]; + bb[ip_s] = false; + ind_s[ic] = ip_s; + ic++; + } + } + } + p_m /= T(ic); + + for(ST ip_s = 0; ip_s < ic; ip_s++) + { + vr_2d_io[ind_s[ip_s]] = p_m; + } + } + } + + // match one to one xy positions: vr_2d_r: array of R_2d and vr_2d: array of R_2d + template + enable_if_vctr_cpu_r_2d + fcn_xy_match_one_2_one(const TVctr& vr_2d_r, TVctr& vr_2d, Vctr_cpu& ind_match) + { + if (vr_2d_r.size() != vr_2d.size()) + return; + + using T = Value_type; + using U = Value_type_r; + using ST = Size_type; + + const ST n_vr_2d = vr_2d.size(); + + using typ_ind_d2 = std::tuple; + + std::vector data(n_vr_2d, std::make_tuple(ST(), ST(), U(), T())); + + // find minimum distance for each reference position + for(ST ip = 0; ip < n_vr_2d; ip++) + { + const auto r_c = vr_2d_r[ip]; + + ST ip_s_min = 0; + U d2_s_min = norm_2(vr_2d[ip_s_min]-r_c); + + for(ST ip_s = 1; ip_s < n_vr_2d; ip_s++) + { + auto d2_ip = norm_2(vr_2d[ip_s]-r_c); + + if (d2_ip < d2_s_min) + { + d2_s_min = d2_ip; + ip_s_min =ip_s; + } + } + + data[ip] = std::make_tuple(ip, ip_s_min, d2_s_min, vr_2d[ip_s_min]); + } + + // sort by distance + std::sort(data.begin(), data.end(), [](const typ_ind_d2 &a, const typ_ind_d2 &b) + { return (std::get<1>(a) < std::get<1>(b)) || + ((std::get<1>(a) == std::get<1>(b)) && (std::get<2>(a) < std::get<2>(b))); + }); + + // std::sort(data.begin(), data.end(), [](const typ_ind_d2 &a, const typ_ind_d2 &b){ return std::get<2>(a) < std::get<2>(b); }); + + // get unique indices + auto last = std::unique(data.begin(), data.end(), [](const typ_ind_d2 &a, const typ_ind_d2 &b){ return std::get<1>(a) == std::get<1>(b); }); + ST n_uniq = std::distance(data.begin(), last); + ST n_left = n_vr_2d - n_uniq; + + // return if there is not duplicate indices + if (n_left==0) + { + for(ST ip = 0; ip < n_vr_2d; ip++) + { + ind_match[std::get<0>(data[ip])] = std::get<1>(data[ip]); + vr_2d[std::get<0>(data[ip])] = std::get<3>(data[ip]); + } + + return; + } + + // select unique matches + std::vector bb_r(n_vr_2d, true); + std::vector bb(n_vr_2d, true); + + for(ST ip = 0; ip < n_uniq; ip++) + { + bb_r[std::get<0>(data[ip])] = false; + bb[std::get<1>(data[ip])] = false; + } + + // get duplicated indices + std::vector ind_r; + ind_r.reserve(n_left); + + std::vector ind; + ind.reserve(n_left); + + for(ST ip = 0; ip < n_vr_2d; ip++) + { + if (bb_r[ip]) + ind_r.push_back(ip); + + if (bb[ip]) + ind.push_back(ip); + } + + // match duplicate indices + for(ST ip = 0; ip < n_left; ip++) + { + const auto r_c = vr_2d_r[ind_r[ip]]; + + // initial index have to be calculated for each iteration + ST ip_s_g_min = 0; + + for(ST ip_s = 0; ip_s < n_left; ip_s++) + { + if (bb[ind[ip_s]]) + { + ip_s_g_min = ind[ip_s]; + break; + } + } + + U d2 = norm_2(vr_2d[ip_s_g_min]-r_c); + + for(ST ip_s = 1; ip_s < n_left; ip_s++) + { + auto ip_s_g = ind[ip_s]; + + if (bb[ip_s_g]) + { + auto d2_ip = norm_2(vr_2d[ip_s_g]-r_c); + + if (d2_ip < d2) + { + d2 = d2_ip; + ip_s_g_min =ip_s_g; + } + } + } + + bb[ip_s_g_min] = false; + data[n_uniq + ip] = std::make_tuple(ind_r[ip], ip_s_g_min, d2, vr_2d[ip_s_g_min]); + } + + for(ST ip = 0; ip < n_vr_2d; ip++) + { + ind_match[std::get<0>(data[ip])] = std::get<1>(data[ip]); + vr_2d[std::get<0>(data[ip])] = std::get<3>(data[ip]); + } + } + + /***************************************************************************************/ + // radial distribution function + template + enable_if_vctr_cpu_r_nd_and_vctr_cpu + fcn_rdf(TVctr_r_nd& vr_nd, Value_type r_max, dt_int32 nr, TVctr& r_o, TVctr& rdf_o) + { + using T = Value_type; + using ST = Size_type; + + const T dr = r_max/T(nr); + + for(ST ir = 0; ir < nr; ir++) + { + r_o[ir] = ir*dr; + rdf_o[ir] = T(0); + } + + const auto r2_max = ::square(r_max); + + const ST n_vr_nd = vr_nd.size(); + for(ST ixy = 0; ixy < n_vr_nd; ixy++) + { + const auto r_i = vr_nd[ixy]; + for(ST ixy_s = 0; ixy_s < n_vr_nd; ixy_s++) + { + auto d2 = norm_2(vr_nd[ixy_s]-r_i); + if ((d2 < r2_max) && (ixy != ixy_s)) + { + const auto ir = static_cast(::floor(::sqrt(d2)/dr)); + rdf_o[ir] += 1; + } + } + } + if (typeid(Value_type) == typeid(R_2d)) + { + for(auto ir = 1; ir < nr; ir++) + { + rdf_o[ir] = rdf_o[ir]/(c_pi*r_o[ir]*dr); + } + } + else if (typeid(Value_type) == typeid(R_3d)) + { + for(auto ir = 1; ir < nr; ir++) + { + rdf_o[ir] = rdf_o[ir]/(T(4)*c_pi*::square(r_o[ir])*dr); + } + } + } + + /***************************************************************************************/ + template + enable_if_vctr_cpu_r_nd, Size_type, Size_type>> + fcn_vctr_r_nd_dist(const TVctr& vr_nd, TFcn fcn) + { + using T = Value_type_r; + using ST = Size_type; + + const ST n_vr_nd = vr_nd.size(); + + if (n_vr_nd == 1) + { + return std::make_tuple(T(0), ST(0), ST(0)); + } + + ST idx_0 = 0; + ST idx_e = 1; + T d2_op = norm_2(vr_nd[0]-vr_nd[1]); + + for(ST ixy = 0; ixy < n_vr_nd; ixy++) + { + const auto r_i = vr_nd[ixy]; + //for (ST ixy_s = 0; ixy_s < n_vr_nd; ixy_s++) // check out this line because it can be optmize by + for(ST ixy_s = ixy+1; ixy_s < n_vr_nd; ixy_s++) + { + auto d2 = norm_2(vr_nd[ixy_s]-r_i); + if ((ixy != ixy_s) && fcn(d2, d2_op)) + { + idx_0 = ixy; + idx_e = ixy_s; + d2_op = d2; + } + } + } + + return std::make_tuple(::sqrt(d2_op), idx_0, idx_e); + } + + template + enable_if_vctr_cpu_r_nd> + fcn_min_dist(const TVctr& vr_nd) + { + using T = Value_type_r; + + auto dist_t = fcn_vctr_r_nd_dist(vr_nd, std::less()); + + return std::get<0>(dist_t); + } + + template + enable_if_vctr_cpu_r_nd> + fcn_max_dist(const TVctr& vr_nd) + { + using T = Value_type_r; + + auto dist_t = fcn_vctr_r_nd_dist(vr_nd, std::greater()); + + return std::get<0>(dist_t); + } + } + +#endif \ No newline at end of file diff --git a/src/particles.h b/src/particles.h new file mode 100755 index 00000000..f9803ff1 --- /dev/null +++ b/src/particles.h @@ -0,0 +1,2246 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include + +#include "macros.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "mx_2x2.h" +#include "mx_3x3.h" +#include "cgpu_vctr.cuh" +#include "fcns_cpu.h" +#ifdef __CUDACC__ + #include "fcns_gpu.h" +#endif +#include "grid.h" +#include "range.cuh" +#include "fcns_elem.cuh" + +#include + +/***************************************************************************************/ +namespace mt +{ + namespace ptc_detail + { + template + void set_ptc_pbc_xy(const PTC_i& ptc_i, const dt_bool& pbc_xy, const dt_bool& b_statistic, PTC_o& ptc_o) + { + using T = typename PTC_o::value_type; + + ptc_o.bs = ptc_i.bs; + + if (ptc_i.size()==0) + return; + + if (!pbc_xy) + { + ptc_o = ptc_i; + } + else + { + auto bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < ptc_i.size(); ia++) + { + auto bb_x = fcn_chk_bound(ptc_i.x[ia], T(0), bs_e.x); + auto bb_y = fcn_chk_bound(ptc_i.y[ia], T(0), bs_e.y); + + if (bb_x && bb_y) + { + ptc_o.push_back(ptc_i.get(ia)); + } + } + + ptc_o.shrink_to_fit(); + } + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + template + void set_ptc_pbc_xy(const pVctr_cpu_64& p_ptc, const dt_int64& icol, const R_D& bs, const dt_bool& pbc_xy, const dt_bool& b_statistic, PTC_o& ptc_o) + { + using T = typename PTC_o::value_type; + using Ptc_s = typename PTC_o::Ptc_s; + + ptc_o.bs = bs; + + if (p_ptc.empty()) + return; + + auto s_0 = p_ptc.s0(); + auto s_1 = p_ptc.s1(); + + if (!pbc_xy) + { + for(dt_int64 ia = 0; ia < s_0; ia++) + { + ptc_o.push_back(Ptc_s(p_ptc.data(), s_0, s_1, ia, icol)); + } + } + else + { + auto bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < s_0; ia++) + { + auto ptc_s = Ptc_s(p_ptc.data(), s_0, s_1, ia, icol); + auto bb_x = fcn_chk_bound(ptc_s.x, T(0), bs_e.x); + auto bb_y = fcn_chk_bound(ptc_s.y, T(0), bs_e.y); + + if (bb_x && bb_y) + { + ptc_o.push_back(ptc_s); + } + } + } + + ptc_o.shrink_to_fit(); + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + /***************************************************************************************/ + /*********************************** macros 2d/3d **************************************/ + /***************************************************************************************/ + #define CASE_SORT(N) case N: { thrust::sort(first, last, mt::cgpu_fctr::less_soa()); } break; + + #define ZIPITER_0_2D this->x, this->y + #define ZIPITER_0_3D this->x, this->y, this->z + + #define ZIPITER_0(DIM) ZIPITER_0_##DIM##D + #define ZIPITER_1(DIM) ZIPITER_0(DIM), this->c_1 + #define ZIPITER_2(DIM) ZIPITER_1(DIM), this->c_2 + #define ZIPITER_3(DIM) ZIPITER_2(DIM), this->c_3 + #define ZIPITER_4(DIM) ZIPITER_3(DIM), this->c_4 + #define ZIPITER_5(DIM) ZIPITER_4(DIM), this->c_5 + #define ZIPITER_6(DIM) ZIPITER_5(DIM), this->c_6 + #define ZIPITER_7(DIM) ZIPITER_6(DIM), this->c_7 + #define ZIPITER_8(DIM) ZIPITER_7(DIM), this->c_8 + #define ZIPITER_9(DIM) ZIPITER_8(DIM), this->c_9 + + #define SWITCH_0_2D(macro) macro(0) macro(1) + #define SWITCH_1_2D(macro) SWITCH_0_2D(macro) macro(2) + #define SWITCH_2_2D(macro) SWITCH_1_2D(macro) macro(3) + #define SWITCH_3_2D(macro) SWITCH_2_2D(macro) macro(4) + #define SWITCH_4_2D(macro) SWITCH_3_2D(macro) macro(5) + #define SWITCH_5_2D(macro) SWITCH_4_2D(macro) macro(6) + #define SWITCH_6_2D(macro) SWITCH_5_2D(macro) macro(7) + #define SWITCH_7_2D(macro) SWITCH_6_2D(macro) macro(8) + #define SWITCH_8_2D(macro) SWITCH_7_2D(macro) macro(9) + #define SWITCH_9_2D(macro) SWITCH_8_2D(macro) macro(10) + + #define SWITCH_0_3D(macro) macro(0) macro(1) macro(2) + #define SWITCH_1_3D(macro) SWITCH_0_3D(macro) macro(3) + #define SWITCH_2_3D(macro) SWITCH_1_3D(macro) macro(4) + #define SWITCH_3_3D(macro) SWITCH_2_3D(macro) macro(5) + #define SWITCH_4_3D(macro) SWITCH_3_3D(macro) macro(6) + #define SWITCH_5_3D(macro) SWITCH_4_3D(macro) macro(7) + #define SWITCH_6_3D(macro) SWITCH_5_3D(macro) macro(8) + #define SWITCH_7_3D(macro) SWITCH_6_3D(macro) macro(9) + #define SWITCH_8_3D(macro) SWITCH_7_3D(macro) macro(10) + #define SWITCH_9_3D(macro) SWITCH_8_3D(macro) macro(11) + + #define FCN_SORT_BY_IDX(DIM, N) \ + virtual void sort_by_idx(const dt_int32& idx) \ + { \ + auto first = fcn_mkzipiter_begin(ZIPITER_##N(DIM)); \ + auto last = fcn_mkzipiter_end(ZIPITER_##N(DIM)); \ + \ + switch(idx) \ + { \ + SWITCH_##N##_##DIM##D(CASE_SORT) \ + } \ + } + + #define CD_PASTE(pre, x, y) pre ## _ ## x ## d ## _ ## y + #define CD_EVAL_PASTE(pre, x, y) CD_PASTE(pre, x, y) + #define CD_EVAL_2_PASTE(pre, x, y) CD_EVAL_PASTE(pre, x, y) + + #define CD_PTC_S_N(DIM, N) CD_EVAL_PASTE(Ptc_s, DIM, N) + #define CD_PTC_S_NB(DIM, N) CD_EVAL_2_PASTE(Ptc_s, DIM, DEC(N, 1)) + + #define CD_PTC_N(DIM, N) CD_EVAL_PASTE(Ptc, DIM, N) + #define CD_PTC_NB(DIM, N) CD_EVAL_2_PASTE(Ptc, DIM, DEC(N, 1)) + + #define N_DIM(N, DIM) EVAL_2_PASTE(INC, DEC(DIM, 1), N) + + /***************************************************************************************/ + #define C_PTC_S_COEF_DIM_N(DIM, N) \ + template \ + class CD_PTC_S_N(DIM, N): public CD_PTC_S_NB(DIM, N) \ + { \ + public: \ + T c_##N; \ + \ + CD_PTC_S_N(DIM, N)(): CD_PTC_S_NB(DIM, N)(), c_##N(0) {} \ + \ + /* constructor by initializer list */ \ + template \ + CD_PTC_S_N(DIM, N)(const dt_init_list& list): CD_PTC_S_NB(DIM, N)(list) \ + { \ + auto ptr = list.begin(); \ + \ + c_##N = T(ptr[N_DIM(N, DIM)]); \ + } \ + \ + /* constructor by base class */ \ + template \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_NB(DIM, N)& base, const T& c_##N): CD_PTC_S_NB(DIM, N)(base) \ + { \ + this->c_##N = T(c_##N); \ + } \ + \ + /* constructor by pointer */ \ + template \ + CD_PTC_S_N(DIM, N)(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): CD_PTC_S_NB(DIM, N)(v, n_r, n_c, idx, icol) \ + { \ + const auto ip = icol*n_r + idx; \ + c_##N = (n_c>N_DIM(N, DIM))?T(v[ip + N_DIM(N, DIM)*n_r]):T(1); \ + } \ + \ + /* copy constructor */ \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + *this = ptc_s; \ + } \ + \ + /* converting constructor */ \ + template \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + *this = ptc_s; \ + } \ + \ + /******************************** assignment operators *********************************/ \ + /* copy assignment operator */ \ + CD_PTC_S_N(DIM, N)& operator=(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + if (this != &ptc_s) \ + { \ + CD_PTC_S_NB(DIM, N)::operator=(ptc_s); \ + \ + c_##N = ptc_s.c_##N; \ + } \ + \ + return *this; \ + } \ + \ + /* converting assignment operator */ \ + template \ + CD_PTC_S_N(DIM, N)& operator=(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + assign(ptc_s); \ + \ + return *this; \ + } \ + \ + template \ + void assign(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + if ((void*)this != (void*)&ptc_s) \ + { \ + CD_PTC_S_NB(DIM, N)::assign(ptc_s); \ + \ + c_##N = T(ptc_s.c_##N); \ + } \ + } \ + } + + /***************************************************************************************/ + #define C_PTC_COEF_DIM_N(DIM, N) \ + template \ + class CD_PTC_N(DIM, N): public CD_PTC_NB(DIM, N) \ + { \ + public: \ + using value_type = T; \ + using size_type = dt_int64; \ + \ + using Ptc_s = CD_PTC_S_N(DIM, N); \ + \ + mutable Vctr_cpu c_##N; \ + \ + R_2d c_##N##_lim; \ + \ + /************************************* constructors ************************************/ \ + CD_PTC_N(DIM, N)(): CD_PTC_NB(DIM, N)(), c_##N##_lim(){} \ + \ + template \ + CD_PTC_N(DIM, N)(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_##DIM##d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); \ + } \ + \ + /* copy constructor */ \ + CD_PTC_N(DIM, N)(const CD_PTC_N(DIM, N)& ptc) \ + { \ + *this = ptc; \ + } \ + \ + /* converting constructor */ \ + template \ + CD_PTC_N(DIM, N)(const CD_PTC_N(DIM, N)& ptc) \ + { \ + *this = ptc; \ + } \ + \ + /******************************** assignment operators *********************************/ \ + /* copy assignment operator */ \ + CD_PTC_N(DIM, N)& operator=(const CD_PTC_N(DIM, N)& ptc) \ + { \ + assign(ptc); \ + \ + return *this; \ + } \ + \ + /* converting assignment operator */ \ + template \ + CD_PTC_N(DIM, N)& operator=(const CD_PTC_N(DIM, N)& ptc) \ + { \ + assign(ptc); \ + \ + return *this; \ + } \ + \ + template \ + void assign(const CD_PTC_N(DIM, N)& ptc) \ + { \ + if ((void*)this != (void*)&ptc) \ + { \ + CD_PTC_NB(DIM, N)::assign(ptc); \ + \ + c_##N = ptc.c_##N; \ + \ + c_##N##_lim = ptc.c_##N##_lim; \ + } \ + } \ + \ + /***************************************************************************************/ \ + virtual size_type cols() const \ + { \ + return INC(N, DIM); \ + } \ + \ + void clear() \ + { \ + CD_PTC_NB(DIM, N)::clear(); \ + \ + c_##N.clear(); \ + \ + c_##N##_lim = 0; \ + } \ + \ + void resize(size_type new_size) \ + { \ + new_size = max(size_type(0), new_size); \ + \ + CD_PTC_NB(DIM, N)::resize(new_size); \ + \ + c_##N.resize(new_size); \ + } \ + \ + void reserve(size_type new_size) \ + { \ + new_size = max(size_type(0), new_size); \ + \ + CD_PTC_NB(DIM, N)::reserve(new_size); \ + \ + c_##N.reserve(new_size); \ + } \ + \ + void shrink_to_fit() \ + { \ + CD_PTC_NB(DIM, N)::shrink_to_fit(); \ + \ + c_##N.shrink_to_fit(); \ + } \ + \ + void push_back(const Ptc_s& ptc_s) \ + { \ + CD_PTC_NB(DIM, N)::push_back(ptc_s); \ + \ + c_##N.push_back(ptc_s.c_##N); \ + } \ + \ + Ptc_s get(const size_type& ia) const \ + { \ + return {CD_PTC_NB(DIM, N)::get(ia), c_##N[ia]}; \ + } \ + \ + void set(const size_type& ia, const Ptc_s& ptc_s) \ + { \ + CD_PTC_NB(DIM, N)::set(ia, ptc_s); \ + \ + c_##N[ia] = ptc_s.c_##N; \ + } \ + \ + template \ + void set_ptc(const CD_PTC_N(DIM, N)& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + clear(); \ + reserve(ptc.size()); \ + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); \ + } \ + \ + template \ + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_##DIM##d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + clear(); \ + reserve(ptc.size()); \ + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); \ + } \ + \ + /* copy data to pointer */ \ + template \ + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=INC(N, DIM)) const \ + { \ + if (is_0>is_e) \ + { \ + std::swap(is_0, is_e); \ + } \ + \ + auto n_data = min(n_ptc, this->size()); \ + auto is = CD_PTC_NB(DIM, N)::cpy_to_ptr(ptc, n_ptc, is_0, is_e); \ + \ + if (fcn_chk_bound(N_DIM(N, DIM), is_0, is_e)) \ + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), c_##N.data(), n_data); \ + \ + return is; \ + } \ + \ + /* get statistic */ \ + virtual void get_statistic() \ + { \ + if (this->empty()) \ + { \ + return; \ + } \ + \ + CD_PTC_NB(DIM, N)::get_statistic(); \ + \ + fcn_minmax_element(c_##N, c_##N##_lim.x, c_##N##_lim.y); \ + } \ + \ + /* sort by idx */ \ + FCN_SORT_BY_IDX(DIM, N); \ + } + }; +} + +/***************************************************************************************/ +/******************************** position particle ************************************/ +/***************************************************************************************/ + +/* derived class Ptc_s_2d_0 */ +namespace mt +{ + template + using Ptc_s_2d_0 = Ptc_s_xd_0; + + template + using Ptc_R_2d = Ptc_R_xd; +} + +/* template specialization 2d*/ +namespace mt +{ + template + class Ptc_s_xd_0: public Ptc_s_xd_0 + { + public: + T y; + + Ptc_s_xd_0(): Ptc_s_xd_0(), y(0) {} + + Ptc_s_xd_0(const T& x, const T& y): Ptc_s_xd_0(x), y(y){} + + template + Ptc_s_xd_0(const U& x, const U& y): Ptc_s_xd_0(x), y(y){} + + /* constructor by initializer list */ + template + Ptc_s_xd_0(const dt_init_list& list): Ptc_s_xd_0(list) + { + auto ptr = list.begin(); + + y = T(ptr[1]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): Ptc_s_xd_0(v, n_r, n_c, idx, icol) + { + const auto ip = icol*n_r + idx; + + y = (n_c>1)?T(v[ip + 1*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + Ptc_s_xd_0::operator=(ptc); + + y = ptc.y; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + Ptc_s_xd_0::operator=(ptc); + + y = T(ptc.y); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + CGPU_EXEC + void set_pos(const R_2d& r) + { + this->x = r.x; + y = r.y; + } + + CGPU_EXEC + R_2d get_pos() const + { + return {this->x, y}; + } + }; +} + +/* template specialization 2d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_2d_0; + + R_2d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + + R_2d x_lim; + R_2d y_lim; + + R_2d r_mean; // mean position + R_2d r_std; // standard deviation + R_2d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(): bs(), x_lim(), y_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 2; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + y.clear(); + + x_lim = 0; + y_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + y.push_back(ptc_s.y); + } + + template + void set_bs(const R_2d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + y[ia] = ptc_s.y; + } + + R_2d get_pos(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + void set_pos(const size_type& ia, const R_2d& r) + { + x[ia] = r.x; + y[ia] = r.y; + } + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=2) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(1); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y); + auto last = fcn_mkzipiter_end(this->x, this->y); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = ::fabs(r.x); + r.y = ::fabs(r.y); + + r.x = ::fmin(r.x, ::fabs(r.x-bs.x)); + r.y = ::fmin(r.y, ::fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_2d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia, const T& x, const T& y) const + { + return mt::norm_2(get_pos(ia) - R_2d(x, y)); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia, const T& x, const T& y) const + { + return ::sqrt(this->norm_2(ia, x, y)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_2d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_2d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void apply_ltf(const Mx_2x2& mx, const R_2d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + void rotate(const T& theta, const R_2d& p) + { + mt::fcn_ptc_pos_rotate(theta, p, *this); + } + }; +} + +/* fcns 2d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_2d& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + fcn_minmax_element(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + + ptc.sz = R_2d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_R_2d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_R_2d& ptc) + { + const R_2d r_sft = (bs-ptc.sz)/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_R_2d& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_R_2d& ptc) + { + const auto Rm = fcn_rot_mx_2d(theta); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } +} + + + +/* derived class Ptc_s_3d_0 */ +namespace mt +{ + template + using Ptc_s_3d_0 = Ptc_s_xd_0; + + template + using Ptc_R_3d = Ptc_R_xd; +} + +/* template specialization 3d*/ +namespace mt +{ + template + class Ptc_s_xd_0: public Ptc_s_xd_0 + { + public: + T z; + + Ptc_s_xd_0(): Ptc_s_xd_0(), z(0) {} + + Ptc_s_xd_0(const T& x, const T& y, const T& z): Ptc_s_xd_0(x, y), z(z){} + + template + Ptc_s_xd_0(const U& x, const U& y, const U& z): Ptc_s_xd_0(x, y), z(z){} + + /* constructor by initializer list */ + template + Ptc_s_xd_0(const dt_init_list& list): Ptc_s_xd_0(list) + { + auto ptr = list.begin(); + + z = T(ptr[2]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): Ptc_s_xd_0(v, n_r, n_c, idx, icol) + { + const auto ip = icol*n_r + idx; + + z = (n_c>1)?T(v[ip + 2*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + Ptc_s_xd_0::operator=(ptc); + + z = ptc.z; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + Ptc_s_xd_0::operator=(ptc); + + z = T(ptc.z); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + CGPU_EXEC + void set_pos(const R_3d& r) + { + this->x = r.x; + this->y = r.y; + z = r.z; + } + + CGPU_EXEC + R_3d get_pos() const + { + return {this->x, this->y, z}; + } + }; +} + +/* template specialization 3d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_3d_0; + + R_3d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + mutable Vctr_cpu z; + + R_2d x_lim; // x limits + R_2d y_lim; // y limits + R_2d z_lim; // z limits + + R_3d r_mean; // mean position + R_3d r_std; // standard deviation + R_3d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(): bs(), x_lim(), y_lim(), z_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + z = ptc.z; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + z_lim = ptc.z_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 3; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + y.clear(); + z.clear(); + + x_lim = 0; + y_lim = 0; + z_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + z.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + z.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + z.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + y.push_back(ptc_s.y); + z.push_back(ptc_s.z); + } + + template + void set_bs(const R_3d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + y[ia] = ptc_s.y; + z[ia] = ptc_s.z; + } + + R_3d get_pos(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + void set_pos(const size_type& ia, const R_3d& r) + { + x[ia] = r.x; + y[ia] = r.y; + z[ia] = r.z; + } + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=3) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), z.data(), n_data); // z-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(1); + } + + // sort by z + void sort_by_z() + { + sort_by_idx(2); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(this->x, this->y, this->z); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + r.z = fabs(r.z); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + r.z = ::fmin(r.z, fabs(r.y-bs.z)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_3d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia, const T& x, const T& y, const T& z) const + { + return mt::norm_2(get_pos(ia) - R_3d(x, y, z)); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia, const T& x, const T& y, const T& z) const + { + return ::sqrt(this->norm_2(ia, x, y, z)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_3d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_3d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter_xy(const R_2d& bs) + { + fcn_ptc_pos_recenter_xy(bs, *this); + } + + void recenter_xy() + { + cn_ptc_pos_recenter_xy({bs.x, bs.y}, *this); + } + + void apply_ltf(const Mx_2x2& mx, const R_3d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + void rotate(const T& theta, const R_3d& u_0, const R_3d& p) + { + mt::fcn_ptc_pos_rotate(theta, u_0, p, *this); + } + }; +} + +/* fcns 3d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_3d& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + fcn_minmax_element(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + fcn_minmax_element(ptc.z, ptc.z_lim.x, ptc.z_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + fcn_mean_std(ptc.z, ptc.r_mean.z, ptc.r_std.z); + + ptc.sz = R_3d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x, ptc.z_lim.y - ptc.z_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_3d& r_sft, Ptc_R_3d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + ptc.z[ia] += r_sft.z; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_R_3d& ptc) + { + const R_3d r_sft = (bs-ptc.sz)/T(2) - R_3d(ptc.x_lim.x, ptc.y_lim.x, ptc.z_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_R_3d& ptc) + { + const R_2d r_sft = (bs-R_2d(ptc.sz.x, ptc.sz.y))/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift({r_sft.x, r_sft.y, T(0)}, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_R_3d& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_R_3d& ptc) + { + const auto Rm = fcn_rot_mx_3d(theta, u_0); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } +} + + +/********************************* atomic particles ************************************/ +namespace mt +{ + /******************************* forward declarations **********************************/ + template + class Ptc_Atom; + + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& atoms); +} + +namespace mt +{ + template + class Ptc_s_Atom: public Ptc_s_3d_0 + { + public: + dt_int32 Z; + dt_float32 sigma; + dt_float32 occ; + dt_int32 tag; + dt_int32 charge; + + Ptc_s_Atom():Z(0), Ptc_s_3d_0(), sigma(0), occ(0), tag(0), charge(0) {}; + + Ptc_s_Atom(const dt_int32& Z, const T& x, const T& y, const T& z, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge): + Z(Z), Ptc_s_3d_0(x, y, z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + Ptc_s_Atom(const dt_int32& Z, const R_3d& r, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge): + Z(Z), Ptc_s_3d_0(r.x, r.y, r.z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + /* constructor by pointer */ + template + Ptc_s_Atom(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + Z = dt_int32(v[ip + 0*n_r]); // atomic number + this->x = (n_c>1)?T(v[ip + 1*n_r]):T(0); // x-position + this->y = (n_c>2)?T(v[ip + 2*n_r]):T(0); // y-position + this->z = (n_c>3)?T(v[ip + 3*n_r]):T(0); // z-position + + sigma = (n_c>4)?dt_float32(v[ip + 4*n_r]):c_dflt_rms3d; // standard deviation + occ = (n_c>5)?dt_float32(v[ip + 5*n_r]):c_dflt_occ; // occupancy + tag = (n_c>6)?dt_int32(v[ip + 6*n_r]):c_dflt_tag; // tag + charge = (n_c>7)?dt_int32(v[ip + 7*n_r]):c_dflt_charge; // charge + } + + /* copy constructor */ + Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /* converting constructor */ + template + Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s) + { + if (this != &ptc_s) + { + Z = ptc_s.Z; + this->x = ptc_s.x; + this->y = ptc_s.y; + this->z = ptc_s.z; + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + + return *this; + } + + /* converting assignment operator */ + template + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s) + { + assign(ptc_s); + + return *this; + } + + template + void assign(const Ptc_s_Atom& ptc_s) + { + if ((void*)this != (void*)&ptc_s) + { + Z = ptc_s.Z; + this->x = T(ptc_s.x); + this->y = T(ptc_s.y); + this->z = T(ptc_s.z); + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + } + }; +} + +namespace mt +{ + template + class Ptc_Atom: public Ptc_R_3d + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_Atom; + + mutable Vctr_cpu Z; // atomic number + mutable Vctr_cpu sigma; // 3d root fcn_mean squared displacement (rmsd) + mutable Vctr_cpu occ; // occupancy + mutable Vctr_cpu tag; // tag + mutable Vctr_cpu charge; // charge + + dt_int32 cols_used; // number of used columns + + R_2d Z_lim; + R_2d sigma_lim; + R_2d occ_lim; + R_2d tag_lim; + R_2d charge_lim; + + /************************************* constructors ************************************/ + Ptc_Atom(): Ptc_R_3d(), cols_used(4), Z_lim(), sigma_lim(), occ_lim(), tag_lim(), charge_lim() {} + + template + Ptc_Atom(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* assignment operator */ + Ptc_Atom& operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_Atom& operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_Atom& ptc) + { + if ((void*)this != (void*)&ptc) + { + cols_used = ptc.cols_used; + + Z = ptc.Z; + + Ptc_R_3d::assign(ptc); + + sigma = ptc.sigma; + occ = ptc.occ; + tag = ptc.tag; + charge = ptc.charge; + + Z_lim = ptc.Z_lim; + sigma_lim = ptc.sigma_lim; + occ_lim = ptc.occ_lim; + tag_lim = ptc.tag_lim; + charge_lim = ptc.charge_lim; + } + } + + /***************************************************************************************/ + virtual size_type cols() const + { + return 8; + } + + void clear() + { + cols_used = 4; + + Z.clear(); + + Ptc_R_3d::clear(); + + sigma.clear(); + occ.clear(); + tag.clear(); + charge.clear(); + + Z_lim = 0; + sigma_lim = 0; + occ_lim = 0; + tag_lim = 0; + charge_lim = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.resize(new_size); + + Ptc_R_3d::resize(new_size); + + if (cols_used>4) + sigma.resize(new_size); + + if (cols_used>5) + occ.resize(new_size); + + if (cols_used>6) + tag.resize(new_size); + + if (cols_used>7) + charge.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.reserve(new_size); + + Ptc_R_3d::reserve(new_size); + + if (cols_used>4) + sigma.reserve(new_size); + + if (cols_used>5) + occ.reserve(new_size); + + if (cols_used>6) + tag.reserve(new_size); + + if (cols_used>7) + charge.reserve(new_size); + } + + void shrink_to_fit() + { + Z.shrink_to_fit(); + + Ptc_R_3d::shrink_to_fit(); + + sigma.shrink_to_fit(); + occ.shrink_to_fit(); + tag.shrink_to_fit(); + charge.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + Z.push_back(ptc_s.Z); // atomic number + + Ptc_R_3d::push_back(ptc_s); // xyz + + if (cols_used>4) + sigma.push_back(ptc_s.sigma); // standard deviation + + if (cols_used>5) + occ.push_back(ptc_s.occ); // occupancy + + if (cols_used>6) + tag.push_back(abs(ptc_s.tag)); // tag + + if (cols_used>7) + charge.push_back(ptc_s.charge); // charge + } + + dt_float32 get_sigma(const size_type& ia) const + { + return (cols_used>4)?sigma[ia]:c_dflt_rms3d; // standard deviation + } + + dt_float32 get_occ(const size_type& ia) const + { + return (cols_used>5)?occ[ia]:c_dflt_occ; // occupancy + } + + dt_int32 get_tag(const size_type& ia) const + { + return (cols_used>6)?tag[ia]:c_dflt_tag; // tag + } + + dt_int32 get_charge(const size_type& ia) const + { + return (cols_used>7)?charge[ia]:c_dflt_charge; // charge + } + + Ptc_s get(const size_type& ia) const + { + return {Z[ia], this->x[ia], this->y[ia], this->z[ia], get_sigma(ia), get_occ(ia), get_tag(ia), get_charge(ia)}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + Z[ia] = ptc_s.Z; // atomic number + + Ptc_R_3d::set(ia, ptc_s); // xyz + + if (cols_used>4) // standard deviation + sigma[ia] = ptc_s.sigma; + + if (cols_used>5) // occupancy + occ[ia] = ptc_s.occ; + + if (cols_used>6) // tag + tag[ia] = ptc_s.tag; + + if (cols_used>7) // charge + charge[ia] = ptc_s.charge; + } + + template + void set_ptc(const Ptc_Atom& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + cols_used = ptc.cols_used; + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + cols_used = ptc.s1_32(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, 0, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=8) + { + is_e = min(is_e, cols_used); + + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, this->size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), Z.data(), n_data); // atomic number + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->x.data(), n_data); // x-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->y.data(), n_data); // y-position + + if (fcn_chk_bound(3, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->z.data(), n_data); // z-position + + if (fcn_chk_bound(4, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), sigma.data(), n_data); // standard deviation + + if (fcn_chk_bound(5, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), occ.data(), n_data); // occupancy + + if (fcn_chk_bound(6, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), tag.data(), n_data); // tag + + if (fcn_chk_bound(7, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), charge.data(), n_data); // charge + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(1); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(2); + } + + // sort by z + void sort_by_z() + { + sort_by_idx(3); + } + + // sort by idx + void sort_by_idx(const dt_int32 idx = 3) + { + if (cols_used==4) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z); + + switch(idx) + { + SWITCH_1_3D(CASE_SORT) + } + } + else if (cols_used==5) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma); + + switch(idx) + { + SWITCH_2_3D(CASE_SORT) + } + } + else if (cols_used==6) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ); + + switch(idx) + { + SWITCH_3_3D(CASE_SORT) + } + } + else if (cols_used==7) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag); + + switch(idx) + { + SWITCH_4_3D(CASE_SORT) + } + } + else if (cols_used==8) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + + switch(idx) + { + SWITCH_5_3D(CASE_SORT) + } + } + } + + + /***************************************************************************************/ + virtual void get_statistic() + { + if (this->empty()) + { + return; + } + + mt::fcn_minmax_element(Z, Z_lim.x, Z_lim.y); + + Ptc_R_3d::get_statistic(); + + sigma_lim.x = c_dflt_rms3d; + sigma_lim.y = c_dflt_rms3d; + if (cols_used>4) + mt::fcn_minmax_element(sigma, sigma_lim.x, sigma_lim.y); + + occ_lim.x = c_dflt_occ; + occ_lim.y = c_dflt_occ; + if (cols_used>5) + mt::fcn_minmax_element(occ, occ_lim.x, occ_lim.y); + + tag_lim.x = c_dflt_tag; + tag_lim.y = c_dflt_tag; + if (cols_used>6) + mt::fcn_minmax_element(tag, tag_lim.x, tag_lim.y); + + charge_lim.x = c_dflt_charge; + charge_lim.y = c_dflt_charge; + if (cols_used>7) + mt::fcn_minmax_element(tag, charge_lim.x, charge_lim.y); + + this->bs.z = ::fmax(this->sz.z, this->bs.z); + } + + // max z value within a tag + void minmax_z_by_region(const T& tag_v, T& z_min, T& z_max) + { + z_min = 1e20; + z_max = -1e20; + for(auto iz = 0; iz < this->size(); iz++) + { + if (tag[iz]==tag_v) + { + z_max = ::fmax(z_max, this->z[iz]); + z_min = ::fmin(z_min, this->z[iz]); + } + } + } + + void remove_ptc_out_z_range(const T& z_0, const T& z_e) + { + mt::remove_ptc_out_z_range(z_0, z_e, *this); + } + }; +} + +namespace mt +{ + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& ptc) + { + dt_int32 ia_z = 0; + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + if (fcn_chk_bound(ptc.z[ia], z_0, z_e)) + { + ptc.Z[ia_z] = ptc.Z[ia]; + ptc.x[ia_z] = ptc.x[ia]; + ptc.y[ia_z] = ptc.y[ia]; + ptc.z[ia_z] = ptc.z[ia]; + + if (ptc.cols_used>4) + ptc.sigma[ia_z] = ptc.sigma[ia]; + + if (ptc.cols_used>5) + ptc.occ[ia_z] = ptc.occ[ia]; + + if (ptc.cols_used>6) + ptc.tag[ia_z] = ptc.tag[ia]; + + if (ptc.cols_used>7) + ptc.charge[ia_z] = ptc.charge[ia]; + + ia_z++; + } + } + + ptc.resize(ia_z); + ptc.shrink_to_fit(); + } + +} + +/* forward declarations */ +namespace mt +{ + /* 1d */ + template + void fcn_ptc_pos_statistic(Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_shift(const R_1d& r_sft, Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_recenter(const R_1d& bs, Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const T& mx, const R_1d& p, Ptc_R_1d& ptc); + + /* 2d */ + template + void fcn_ptc_pos_statistic(Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_R_2d& ptc); + + /* 3d */ + template + void fcn_ptc_pos_statistic(Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_shift(const R_3d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_R_3d& ptc); +} + +/* derived class 2d */ +namespace mt +{ + /***************************************************************************************/ + /************************************ pos 2d/c1 ****************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 1); // Ptc_s_2d_1 + C_PTC_COEF_DIM_N(2, 1); // Ptc_2d_1 + + /***************************************************************************************/ + /*********************************** pos 2d/c1/c2 **************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 2); // Ptc_s_2d_2 + C_PTC_COEF_DIM_N(2, 2); // Ptc_2d_2 + + /***************************************************************************************/ + /*********************************** pos 2d/c1/c2/c3 ***********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 3); // Ptc_s_2d_3 + C_PTC_COEF_DIM_N(2, 3); // Ptc_2d_3 + + /***************************************************************************************/ + /********************************* pos 2d/c1/c2/c3/c4 **********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 4); // Ptc_s_2d_4 + C_PTC_COEF_DIM_N(2, 4); // Ptc_2d_4 + + /***************************************************************************************/ + /******************************** pos 2d/c1/c2/c3/c4/c5 ********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 5); // Ptc_s_2d_5 + C_PTC_COEF_DIM_N(2, 5); // Ptc_2d_5 + +} + +/* derived class 3d */ +namespace mt +{ + /***************************************************************************************/ + /************************************** pos 3d/c1 **************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 1); // Ptc_s_3d_1 + C_PTC_COEF_DIM_N(3, 1); // Ptc_3d_1 + + /***************************************************************************************/ + /************************************* pos 3d/c1/c2 ************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 2); // Ptc_s_3d_2 + C_PTC_COEF_DIM_N(3, 2); // Ptc_3d_2 + + /***************************************************************************************/ + /*********************************** pos 3d/c1/c2/c3 ***********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 3); // Ptc_s_3d_3 + C_PTC_COEF_DIM_N(3, 3); // Ptc_3d_3 + + /***************************************************************************************/ + /********************************** pos 3d/c1/c2/c3/c4 *********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 4); // Ptc_s_3d_4 + C_PTC_COEF_DIM_N(3, 4); // Ptc_3d_4 + + /***************************************************************************************/ + /******************************** pos 3d/c1/c2/c3/c4/c5 ********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 5); // Ptc_s_3d_5 + C_PTC_COEF_DIM_N(3, 5); // Ptc_3d_5 +} diff --git a/src/particles.inl b/src/particles.inl new file mode 100755 index 00000000..64e33abb --- /dev/null +++ b/src/particles.inl @@ -0,0 +1,3390 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include + +#include "macros.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "mx_2x2.h" +#include "mx_3x3.h" +#include "cgpu_vctr.cuh" +#include "fcns_cpu.h" +#ifdef __CUDACC__ + #include "fcns_gpu.h" +#endif +#include "grid.h" +#include "range.cuh" +#include "fcns_elem.cuh" + +#include + +/***************************************************************************************/ +/************************************* fcn particle ************************************/ +/***************************************************************************************/ +namespace mt +{ + template class Ptc_s_fcn_xd; + + /* Gauss */ + template + using Ptc_s_Gauss_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_3d = Ptc_s_fcn_xd; + + /* Exp */ + template + using Ptc_s_Exp_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_3d = Ptc_s_fcn_xd; + + /* Fermi */ + template + using Ptc_s_Fermi_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_3d = Ptc_s_fcn_xd; + + /* Butwth */ + template + using Ptc_s_Butwth_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_3d = Ptc_s_fcn_xd; + + /* Hann */ + template + using Ptc_s_Hann_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_3d = Ptc_s_fcn_xd; +} + +/***************************************************************************************/ +/********************************* gaussian particle ***********************************/ +/***************************************************************************************/ +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Gauss_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max) + { + set_in_data(r, a, sigma, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, sigma, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, sigma); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, sigma, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + + }; +} + +/***************************************************************************************/ +/******************************** exponential particle *********************************/ +/***************************************************************************************/ +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Exp_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max) + { + set_in_data(r, a, beta, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, beta, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, beta); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, beta, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; +} + +/***************************************************************************************/ +/*********************************** fermi particle ************************************/ +/***************************************************************************************/ +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Fermi_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max) + { + set_in_data(r, a, alpha, radius, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, alpha, radius, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, alpha, radius); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, alpha, radius, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; +} + +/***************************************************************************************/ +/******************************* butterworth particle **********************************/ +/***************************************************************************************/ +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Butwth_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max) + { + set_in_data(r, a, n, radius, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, n, radius, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, n, radius); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, n, radius, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; +} + +/***************************************************************************************/ +/*********************************** hann particle *************************************/ +/***************************************************************************************/ +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Hann_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(): Fcn_Elem(), Fcn_Cos_Tap(), Range(), r(), r_max_2(0) {} + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max) + { + set_in_data(r, a, l, r_tap, r_max); + } + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, l, r_tap, r_max, grid); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc) + { + if (this != &ptc) + { + Fcn_Elem::operator=(ptc); + Fcn_Cos_Tap::operator=(ptc); + Range::operator=(ptc); + + r = ptc.r; + r_max_2 = ptc.r_max_2; + } + + return *this; + } + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max) + { + Fcn_Elem::set_in_data(a, l); + Fcn_Cos_Tap::set_in_data(::square(r_tap), ::square(r_max)); + this->r = r; + r_max_2 = ::square(r_max); + } + + void set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid) + { + set_in_data(r, a, l, r_tap, r_max); + + Range::set_in_data(r, r_max, grid); + } + + CGPU_EXEC + void clear() + { + Fcn_Elem::clear(); + Fcn_Cos_Tap::clear(); + Range::clear(); + + r = T(0); + r_max_2 = T(0); + } + + CGPU_EXEC + T eval_r2(const T& r2) const + { + return Fcn_Elem::eval_r2(r2)*Fcn_Cos_Tap::eval_r(r2); + } + }; +} + +/***************************************************************************************/ +namespace mt +{ + namespace ptc_detail + { + template + void set_ptc_pbc_xy(const PTC_i& ptc_i, const dt_bool& pbc_xy, const dt_bool& b_statistic, PTC_o& ptc_o) + { + using T = typename PTC_o::value_type; + + ptc_o.bs = ptc_i.bs; + + if (ptc_i.size()==0) + return; + + if (!pbc_xy) + { + ptc_o = ptc_i; + } + else + { + auto bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < ptc_i.size(); ia++) + { + auto bb_x = fcn_chk_bound(ptc_i.x[ia], T(0), bs_e.x); + auto bb_y = fcn_chk_bound(ptc_i.y[ia], T(0), bs_e.y); + + if (bb_x && bb_y) + { + ptc_o.push_back(ptc_i.get(ia)); + } + } + + ptc_o.shrink_to_fit(); + } + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + template + void set_ptc_pbc_xy(const pVctr_cpu_64& p_ptc, const dt_int64& icol, const R_D& bs, const dt_bool& pbc_xy, const dt_bool& b_statistic, PTC_o& ptc_o) + { + using T = typename PTC_o::value_type; + using Ptc_s = typename PTC_o::Ptc_s; + + ptc_o.bs = bs; + + if (p_ptc.empty()) + return; + + auto s_0 = p_ptc.s0(); + auto s_1 = p_ptc.s1(); + + if (!pbc_xy) + { + for(dt_int64 ia = 0; ia < s_0; ia++) + { + ptc_o.push_back(Ptc_s(p_ptc.data(), s_0, s_1, ia, icol)); + } + } + else + { + auto bs_e = ptc_o.bs - c_dflt_pos_ee; + + for(dt_int64 ia = 0; ia < s_0; ia++) + { + auto ptc_s = Ptc_s(p_ptc.data(), s_0, s_1, ia, icol); + auto bb_x = fcn_chk_bound(ptc_s.x, T(0), bs_e.x); + auto bb_y = fcn_chk_bound(ptc_s.y, T(0), bs_e.y); + + if (bb_x && bb_y) + { + ptc_o.push_back(ptc_s); + } + } + } + + ptc_o.shrink_to_fit(); + + if (b_statistic) + { + ptc_o.get_statistic(); + } + } + + /***************************************************************************************/ + /*********************************** macros 2d/3d **************************************/ + /***************************************************************************************/ + #define CASE_SORT(N) case N: { thrust::sort(first, last, mt::cgpu_fctr::less_soa()); } break; + + #define ZIPITER_0_2D this->x, this->y + #define ZIPITER_0_3D this->x, this->y, this->z + + #define ZIPITER_0(DIM) ZIPITER_0_##DIM##D + #define ZIPITER_1(DIM) ZIPITER_0(DIM), this->c_1 + #define ZIPITER_2(DIM) ZIPITER_1(DIM), this->c_2 + #define ZIPITER_3(DIM) ZIPITER_2(DIM), this->c_3 + #define ZIPITER_4(DIM) ZIPITER_3(DIM), this->c_4 + #define ZIPITER_5(DIM) ZIPITER_4(DIM), this->c_5 + #define ZIPITER_6(DIM) ZIPITER_5(DIM), this->c_6 + #define ZIPITER_7(DIM) ZIPITER_6(DIM), this->c_7 + #define ZIPITER_8(DIM) ZIPITER_7(DIM), this->c_8 + #define ZIPITER_9(DIM) ZIPITER_8(DIM), this->c_9 + + #define SWITCH_0_2D(macro) macro(0) macro(1) + #define SWITCH_1_2D(macro) SWITCH_0_2D(macro) macro(2) + #define SWITCH_2_2D(macro) SWITCH_1_2D(macro) macro(3) + #define SWITCH_3_2D(macro) SWITCH_2_2D(macro) macro(4) + #define SWITCH_4_2D(macro) SWITCH_3_2D(macro) macro(5) + #define SWITCH_5_2D(macro) SWITCH_4_2D(macro) macro(6) + #define SWITCH_6_2D(macro) SWITCH_5_2D(macro) macro(7) + #define SWITCH_7_2D(macro) SWITCH_6_2D(macro) macro(8) + #define SWITCH_8_2D(macro) SWITCH_7_2D(macro) macro(9) + #define SWITCH_9_2D(macro) SWITCH_8_2D(macro) macro(10) + + #define SWITCH_0_3D(macro) macro(0) macro(1) macro(2) + #define SWITCH_1_3D(macro) SWITCH_0_3D(macro) macro(3) + #define SWITCH_2_3D(macro) SWITCH_1_3D(macro) macro(4) + #define SWITCH_3_3D(macro) SWITCH_2_3D(macro) macro(5) + #define SWITCH_4_3D(macro) SWITCH_3_3D(macro) macro(6) + #define SWITCH_5_3D(macro) SWITCH_4_3D(macro) macro(7) + #define SWITCH_6_3D(macro) SWITCH_5_3D(macro) macro(8) + #define SWITCH_7_3D(macro) SWITCH_6_3D(macro) macro(9) + #define SWITCH_8_3D(macro) SWITCH_7_3D(macro) macro(10) + #define SWITCH_9_3D(macro) SWITCH_8_3D(macro) macro(11) + + #define FCN_SORT_BY_IDX(DIM, N) \ + virtual void sort_by_idx(const dt_int32& idx) \ + { \ + auto first = fcn_mkzipiter_begin(ZIPITER_##N(DIM)); \ + auto last = fcn_mkzipiter_end(ZIPITER_##N(DIM)); \ + \ + switch(idx) \ + { \ + SWITCH_##N##_##DIM##D(CASE_SORT) \ + } \ + } + + #define CD_PASTE(pre, x, y) pre ## _ ## x ## d ## _ ## y + #define CD_EVAL_PASTE(pre, x, y) CD_PASTE(pre, x, y) + #define CD_EVAL_2_PASTE(pre, x, y) CD_EVAL_PASTE(pre, x, y) + + #define CD_PTC_S_N(DIM, N) CD_EVAL_PASTE(Ptc_s, DIM, N) + #define CD_PTC_S_NB(DIM, N) CD_EVAL_2_PASTE(Ptc_s, DIM, DEC(N, 1)) + + #define CD_PTC_N(DIM, N) CD_EVAL_PASTE(Ptc, DIM, N) + #define CD_PTC_NB(DIM, N) CD_EVAL_2_PASTE(Ptc, DIM, DEC(N, 1)) + + #define N_DIM(N, DIM) EVAL_2_PASTE(INC, DEC(DIM, 1), N) + + /***************************************************************************************/ + #define C_PTC_S_COEF_DIM_N(DIM, N) \ + template \ + class CD_PTC_S_N(DIM, N): public CD_PTC_S_NB(DIM, N) \ + { \ + public: \ + T c_##N; \ + \ + CD_PTC_S_N(DIM, N)(): CD_PTC_S_NB(DIM, N)(), c_##N(0) {} \ + \ + /* constructor by initializer list */ \ + template \ + CD_PTC_S_N(DIM, N)(const dt_init_list& list): CD_PTC_S_NB(DIM, N)(list) \ + { \ + auto ptr = list.begin(); \ + \ + c_##N = T(ptr[N_DIM(N, DIM)]); \ + } \ + \ + /* constructor by base class */ \ + template \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_NB(DIM, N)& base, const T& c_##N): CD_PTC_S_NB(DIM, N)(base) \ + { \ + this->c_##N = T(c_##N); \ + } \ + \ + /* constructor by pointer */ \ + template \ + CD_PTC_S_N(DIM, N)(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): CD_PTC_S_NB(DIM, N)(v, n_r, n_c, idx, icol) \ + { \ + const auto ip = icol*n_r + idx; \ + c_##N = (n_c>N_DIM(N, DIM))?T(v[ip + N_DIM(N, DIM)*n_r]):T(1); \ + } \ + \ + /* copy constructor */ \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + *this = ptc_s; \ + } \ + \ + /* converting constructor */ \ + template \ + CD_PTC_S_N(DIM, N)(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + *this = ptc_s; \ + } \ + \ + /******************************** assignment operators *********************************/ \ + /* copy assignment operator */ \ + CD_PTC_S_N(DIM, N)& operator=(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + if (this != &ptc_s) \ + { \ + CD_PTC_S_NB(DIM, N)::operator=(ptc_s); \ + \ + c_##N = ptc_s.c_##N; \ + } \ + \ + return *this; \ + } \ + \ + /* converting assignment operator */ \ + template \ + CD_PTC_S_N(DIM, N)& operator=(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + assign(ptc_s); \ + \ + return *this; \ + } \ + \ + template \ + void assign(const CD_PTC_S_N(DIM, N)& ptc_s) \ + { \ + if ((void*)this != (void*)&ptc_s) \ + { \ + CD_PTC_S_NB(DIM, N)::assign(ptc_s); \ + \ + c_##N = T(ptc_s.c_##N); \ + } \ + } \ + } + + /***************************************************************************************/ + #define C_PTC_COEF_DIM_N(DIM, N) \ + template \ + class CD_PTC_N(DIM, N): public CD_PTC_NB(DIM, N) \ + { \ + public: \ + using value_type = T; \ + using size_type = dt_int64; \ + \ + using Ptc_s = CD_PTC_S_N(DIM, N); \ + \ + mutable Vctr_cpu c_##N; \ + \ + R_2d c_##N##_lim; \ + \ + /************************************* constructors ************************************/ \ + CD_PTC_N(DIM, N)(): CD_PTC_NB(DIM, N)(), c_##N##_lim(){} \ + \ + template \ + CD_PTC_N(DIM, N)(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_##DIM##d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); \ + } \ + \ + /* copy constructor */ \ + CD_PTC_N(DIM, N)(const CD_PTC_N(DIM, N)& ptc) \ + { \ + *this = ptc; \ + } \ + \ + /* converting constructor */ \ + template \ + CD_PTC_N(DIM, N)(const CD_PTC_N(DIM, N)& ptc) \ + { \ + *this = ptc; \ + } \ + \ + /******************************** assignment operators *********************************/ \ + /* copy assignment operator */ \ + CD_PTC_N(DIM, N)& operator=(const CD_PTC_N(DIM, N)& ptc) \ + { \ + assign(ptc); \ + \ + return *this; \ + } \ + \ + /* converting assignment operator */ \ + template \ + CD_PTC_N(DIM, N)& operator=(const CD_PTC_N(DIM, N)& ptc) \ + { \ + assign(ptc); \ + \ + return *this; \ + } \ + \ + template \ + void assign(const CD_PTC_N(DIM, N)& ptc) \ + { \ + if ((void*)this != (void*)&ptc) \ + { \ + CD_PTC_NB(DIM, N)::assign(ptc); \ + \ + c_##N = ptc.c_##N; \ + \ + c_##N##_lim = ptc.c_##N##_lim; \ + } \ + } \ + \ + /***************************************************************************************/ \ + virtual size_type cols() const \ + { \ + return INC(N, DIM); \ + } \ + \ + void clear() \ + { \ + CD_PTC_NB(DIM, N)::clear(); \ + \ + c_##N.clear(); \ + \ + c_##N##_lim = 0; \ + } \ + \ + void resize(size_type new_size) \ + { \ + new_size = max(size_type(0), new_size); \ + \ + CD_PTC_NB(DIM, N)::resize(new_size); \ + \ + c_##N.resize(new_size); \ + } \ + \ + void reserve(size_type new_size) \ + { \ + new_size = max(size_type(0), new_size); \ + \ + CD_PTC_NB(DIM, N)::reserve(new_size); \ + \ + c_##N.reserve(new_size); \ + } \ + \ + void shrink_to_fit() \ + { \ + CD_PTC_NB(DIM, N)::shrink_to_fit(); \ + \ + c_##N.shrink_to_fit(); \ + } \ + \ + void push_back(const Ptc_s& ptc_s) \ + { \ + CD_PTC_NB(DIM, N)::push_back(ptc_s); \ + \ + c_##N.push_back(ptc_s.c_##N); \ + } \ + \ + Ptc_s get(const size_type& ia) const \ + { \ + return {CD_PTC_NB(DIM, N)::get(ia), c_##N[ia]}; \ + } \ + \ + void set(const size_type& ia, const Ptc_s& ptc_s) \ + { \ + CD_PTC_NB(DIM, N)::set(ia, ptc_s); \ + \ + c_##N[ia] = ptc_s.c_##N; \ + } \ + \ + template \ + void set_ptc(const CD_PTC_N(DIM, N)& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + clear(); \ + reserve(ptc.size()); \ + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); \ + } \ + \ + template \ + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_##DIM##d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) \ + { \ + clear(); \ + reserve(ptc.size()); \ + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); \ + } \ + \ + /* copy data to pointer */ \ + template \ + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=INC(N, DIM)) const \ + { \ + if (is_0>is_e) \ + { \ + std::swap(is_0, is_e); \ + } \ + \ + auto n_data = min(n_ptc, this->size()); \ + auto is = CD_PTC_NB(DIM, N)::cpy_to_ptr(ptc, n_ptc, is_0, is_e); \ + \ + if (fcn_chk_bound(N_DIM(N, DIM), is_0, is_e)) \ + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), c_##N.data(), n_data); \ + \ + return is; \ + } \ + \ + /* get statistic */ \ + virtual void get_statistic() \ + { \ + if (this->empty()) \ + { \ + return; \ + } \ + \ + CD_PTC_NB(DIM, N)::get_statistic(); \ + \ + fcn_minmax_element(c_##N, c_##N##_lim.x, c_##N##_lim.y); \ + } \ + \ + /* sort by idx */ \ + FCN_SORT_BY_IDX(DIM, N); \ + } + }; +} + +/***************************************************************************************/ +/******************************** position particle ************************************/ +/***************************************************************************************/ +/* template definition */ +namespace mt +{ + template class Ptc_s_xd_0; + + template class Ptc_R_xd; +} + +/* derived class Ptc_s_1d_0 */ +namespace mt +{ + template + using Ptc_s_1d_0 = Ptc_s_xd_0; + + template + using Ptc_R_1d = Ptc_R_xd; +} + +/* template specialization 1d*/ +namespace mt +{ + template + class Ptc_s_xd_0 + { + public: + using value_type = T; + + T x; + + /************************************* constructors ************************************/ + Ptc_s_xd_0(): x(0) {} + + Ptc_s_xd_0(const T& x): x(x){} + + template + Ptc_s_xd_0(const U& x): x(x){} + + /* constructor by initializer list */ + template + Ptc_s_xd_0(const dt_init_list& list) + { + auto ptr = list.begin(); + + x = T(ptr[0]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + x = (n_c>0)?T(v[ip + 0*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + x = ptc.x; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + x = T(ptc.x); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /***************************************************************************************/ + CGPU_EXEC + void clear() + { + x = T(0); + } + + CGPU_EXEC + void set_pos(const T& r) + { + x = r; + } + + CGPU_EXEC + T get_pos() const + { + return x; + } + }; +} + + +/* template specialization 1d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_1d_0; + + R_1d bs; // box size + + mutable Vctr_cpu x; + + R_2d x_lim; + + R_1d r_mean; // mean position + R_1d r_std; // standard deviation + R_1d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(): bs(), x_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_x, b_statistic); + } + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + + x_lim = ptc.x_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 1; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + + x_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + } + + template + void set_bs(const R_2d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return x[ia]; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + } + + R_1d get_pos(const size_type& ia) const + { + return x[ia]; + } + + void set_pos(const size_type& ia, const R_1d& r) + { + x[ia] = r; + } + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_x = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_x, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_x, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=1) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = std::begin(this->x); + auto last = std::end(this->x); + + switch(idx) + { + case 0: + { + thrust::sort(x, last, mt::cgpu_fctr::less()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_x(const size_type& ia, const R_1d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r = fabs(r); + + r = ::fmin(r, fabs(r-bs)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_1d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r = fabs(r); + + r = ::fmin(r, fabs(r-bs)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_1d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_x(const size_type& ia, const R_1d& r_0) const + { + return ::sqrt(this->norm_2_pbc_x(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_1d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_1d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_1d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void apply_ltf(const T mx, const R_1d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + }; +} + + +/* fcns 1d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_1d& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean, ptc.r_std); + + ptc.sz = ptc.x_lim.y - ptc.x_lim.x; + } + + template + void fcn_ptc_pos_shift(const R_1d& r_sft, Ptc_R_1d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_1d& bs, Ptc_R_1d& ptc) + { + const R_1d r_sft = (bs-ptc.sz)/T(2) - ptc.x_lim.x; + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const T& mx, const R_1d& p, Ptc_R_1d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r; + } + + fcn_ptc_pos_statistic(ptc); + } +} + +/* derived class Ptc_s_2d_0 */ +namespace mt +{ + template + using Ptc_s_2d_0 = Ptc_s_xd_0; + + template + using Ptc_R_2d = Ptc_R_xd; +} + +/* template specialization 2d*/ +namespace mt +{ + template + class Ptc_s_xd_0: public Ptc_s_xd_0 + { + public: + T y; + + Ptc_s_xd_0(): Ptc_s_xd_0(), y(0) {} + + Ptc_s_xd_0(const T& x, const T& y): Ptc_s_xd_0(x), y(y){} + + template + Ptc_s_xd_0(const U& x, const U& y): Ptc_s_xd_0(x), y(y){} + + /* constructor by initializer list */ + template + Ptc_s_xd_0(const dt_init_list& list): Ptc_s_xd_0(list) + { + auto ptr = list.begin(); + + y = T(ptr[1]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): Ptc_s_xd_0(v, n_r, n_c, idx, icol) + { + const auto ip = icol*n_r + idx; + + y = (n_c>1)?T(v[ip + 1*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + Ptc_s_xd_0::operator=(ptc); + + y = ptc.y; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + Ptc_s_xd_0::operator=(ptc); + + y = T(ptc.y); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + CGPU_EXEC + void set_pos(const R_2d& r) + { + this->x = r.x; + y = r.y; + } + + CGPU_EXEC + R_2d get_pos() const + { + return {this->x, y}; + } + }; +} + +/* template specialization 2d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_2d_0; + + R_2d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + + R_2d x_lim; + R_2d y_lim; + + R_2d r_mean; // mean position + R_2d r_std; // standard deviation + R_2d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(): bs(), x_lim(), y_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 2; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + y.clear(); + + x_lim = 0; + y_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + y.push_back(ptc_s.y); + } + + template + void set_bs(const R_2d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + y[ia] = ptc_s.y; + } + + R_2d get_pos(const size_type& ia) const + { + return {x[ia], y[ia]}; + } + + void set_pos(const size_type& ia, const R_2d& r) + { + x[ia] = r.x; + y[ia] = r.y; + } + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=2) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(1); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y); + auto last = fcn_mkzipiter_end(this->x, this->y); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = ::fabs(r.x); + r.y = ::fabs(r.y); + + r.x = ::fmin(r.x, ::fabs(r.x-bs.x)); + r.y = ::fmin(r.y, ::fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_2d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_2d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia, const T& x, const T& y) const + { + return mt::norm_2(get_pos(ia) - R_2d(x, y)); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_2d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia, const T& x, const T& y) const + { + return ::sqrt(this->norm_2(ia, x, y)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_2d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_2d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void apply_ltf(const Mx_2x2& mx, const R_2d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + void rotate(const T& theta, const R_2d& p) + { + mt::fcn_ptc_pos_rotate(theta, p, *this); + } + }; +} + + +/* fcns 2d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_2d& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + fcn_minmax_element(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + + ptc.sz = R_2d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_R_2d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_R_2d& ptc) + { + const R_2d r_sft = (bs-ptc.sz)/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_R_2d& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_R_2d& ptc) + { + const auto Rm = fcn_rot_mx_2d(theta); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } +} + +/* derived class Ptc_s_3d_0 */ +namespace mt +{ + template + using Ptc_s_3d_0 = Ptc_s_xd_0; + + template + using Ptc_R_3d = Ptc_R_xd; +} + +/* template specialization 3d*/ +namespace mt +{ + template + class Ptc_s_xd_0: public Ptc_s_xd_0 + { + public: + T z; + + Ptc_s_xd_0(): Ptc_s_xd_0(), z(0) {} + + Ptc_s_xd_0(const T& x, const T& y, const T& z): Ptc_s_xd_0(x, y), z(z){} + + template + Ptc_s_xd_0(const U& x, const U& y, const U& z): Ptc_s_xd_0(x, y), z(z){} + + /* constructor by initializer list */ + template + Ptc_s_xd_0(const dt_init_list& list): Ptc_s_xd_0(list) + { + auto ptr = list.begin(); + + z = T(ptr[2]); + } + + /* constructor by pointer */ + template + Ptc_s_xd_0(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0): Ptc_s_xd_0(v, n_r, n_c, idx, icol) + { + const auto ip = icol*n_r + idx; + + z = (n_c>1)?T(v[ip + 2*n_r]):T(0); + } + + /* copy constructor */ + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + CGPU_EXEC + Ptc_s_xd_0(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + if (this != &ptc) + { + Ptc_s_xd_0::operator=(ptc); + + z = ptc.z; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Ptc_s_xd_0& operator=(const Ptc_s_xd_0& ptc) + { + Ptc_s_xd_0::operator=(ptc); + + z = T(ptc.z); + + return *this; + } + + template + CGPU_EXEC + void assign(const Ptc_s_xd_0& ptc) + { + *this = ptc; + } + + CGPU_EXEC + void set_pos(const R_3d& r) + { + this->x = r.x; + this->y = r.y; + z = r.z; + } + + CGPU_EXEC + R_3d get_pos() const + { + return {this->x, this->y, z}; + } + }; +} + +/* template specialization 3d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_3d_0; + + R_3d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + mutable Vctr_cpu z; + + R_2d x_lim; // x limits + R_2d y_lim; // y limits + R_2d z_lim; // z limits + + R_3d r_mean; // mean position + R_3d r_std; // standard deviation + R_3d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(): bs(), x_lim(), y_lim(), z_lim(), r_mean(), r_std(), sz() {} + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, icol, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_R_xd& ptc) + { + if ((void*)this != (void*)&ptc) + { + bs = ptc.bs; + + x = ptc.x; + y = ptc.y; + z = ptc.z; + + x_lim = ptc.x_lim; + y_lim = ptc.y_lim; + z_lim = ptc.z_lim; + + r_mean = ptc.r_mean; + r_std = ptc.r_std; + sz = ptc.sz; + } + } + + /***************************************************************************************/ + dt_shape_st shape() const + { + return {size(), cols(), 1, 1}; + } + + size_type size() const + { + return x.size(); + } + + dt_int32 size_32() const + { + return static_cast(x.size()); + } + + virtual size_type cols() const + { + return 3; + } + + dt_bool empty() const + { + return size() == 0; + } + + void clear() + { + bs = 0; + + x.clear(); + y.clear(); + z.clear(); + + x_lim = 0; + y_lim = 0; + z_lim = 0; + + r_mean = 0; + r_std = 0; + sz = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.resize(new_size); + y.resize(new_size); + z.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + x.reserve(new_size); + y.reserve(new_size); + z.reserve(new_size); + } + + void shrink_to_fit() + { + x.shrink_to_fit(); + y.shrink_to_fit(); + z.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + x.push_back(ptc_s.x); + y.push_back(ptc_s.y); + z.push_back(ptc_s.z); + } + + template + void set_bs(const R_3d& bs) + { + this->bs = bs; + } + + Ptc_s get(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + x[ia] = ptc_s.x; + y[ia] = ptc_s.y; + z[ia] = ptc_s.z; + } + + R_3d get_pos(const size_type& ia) const + { + return {x[ia], y[ia], z[ia]}; + } + + void set_pos(const size_type& ia, const R_3d& r) + { + x[ia] = r.x; + y[ia] = r.y; + z[ia] = r.z; + } + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, icol, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=3) const + { + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), x.data(), n_data); // x-position + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), y.data(), n_data); // y-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), z.data(), n_data); // z-position + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(0); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(1); + } + + // sort by z + void sort_by_z() + { + sort_by_idx(2); + } + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx) + { + auto first = fcn_mkzipiter_begin(this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(this->x, this->y, this->z); + + switch(idx) + { + case 0: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<0>()); + } + break; + case 1: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<1>()); + } + break; + case 2: + { + thrust::sort(first, last, mt::cgpu_fctr::less_soa<2>()); + } + break; + } + } + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + + return mt::norm_2(r); + } + + T norm_2_pbc(const size_type& ia, const R_3d& r_0) const + { + auto r = get_pos(ia) - r_0; + + r.x = fabs(r.x); + r.y = fabs(r.y); + r.z = fabs(r.z); + + r.x = ::fmin(r.x, fabs(r.x-bs.x)); + r.y = ::fmin(r.y, fabs(r.y-bs.y)); + r.z = ::fmin(r.z, fabs(r.y-bs.z)); + + return mt::norm_2(r); + } + + T norm_2(const size_type& ia, const R_3d& r_0) const + { + return mt::norm_2(get_pos(ia) - r_0); + } + + T norm_2(const size_type& ia, const T& x, const T& y, const T& z) const + { + return mt::norm_2(get_pos(ia) - R_3d(x, y, z)); + } + + T norm_2(const size_type& ia_0, const size_type& ia_e) const + { + return mt::norm_2(get_pos(ia_0) - get_pos(ia_e)); + } + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc_xy(ia, r_0)); + } + + T norm_pbc(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2_pbc(ia, r_0)); + } + + T norm(const size_type& ia, const R_3d& r_0) const + { + return ::sqrt(this->norm_2(ia, r_0)); + } + + T norm(const size_type& ia, const T& x, const T& y, const T& z) const + { + return ::sqrt(this->norm_2(ia, x, y, z)); + } + + T norm(const size_type& ia_0, const size_type& ia_e) const + { + return ::sqrt(this->norm_2(ia_0, ia_e)); + } + + /***************************************************************************************/ + virtual void get_statistic() + { + fcn_ptc_pos_statistic(*this); + } + + void shift(const R_3d& r_sft) + { + mt::fcn_ptc_pos_shift(r_sft, *this); + } + + void recenter(const R_3d& bs) + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter() + { + mt::fcn_ptc_pos_recenter(bs, *this); + } + + void recenter_xy(const R_2d& bs) + { + fcn_ptc_pos_recenter_xy(bs, *this); + } + + void recenter_xy() + { + cn_ptc_pos_recenter_xy({bs.x, bs.y}, *this); + } + + void apply_ltf(const Mx_2x2& mx, const R_3d& p) + { + fcn_ptc_pos_apply_ltf(mx, p, *this); + } + + void rotate(const T& theta, const R_3d& u_0, const R_3d& p) + { + mt::fcn_ptc_pos_rotate(theta, u_0, p, *this); + } + }; +} + + +/* fcns 3d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_3d& ptc) + { + if (ptc.empty()) + { + return; + } + + fcn_minmax_element(ptc.x, ptc.x_lim.x, ptc.x_lim.y); + fcn_minmax_element(ptc.y, ptc.y_lim.x, ptc.y_lim.y); + fcn_minmax_element(ptc.z, ptc.z_lim.x, ptc.z_lim.y); + + fcn_mean_std(ptc.x, ptc.r_mean.x, ptc.r_std.x); + fcn_mean_std(ptc.y, ptc.r_mean.y, ptc.r_std.y); + fcn_mean_std(ptc.z, ptc.r_mean.z, ptc.r_std.z); + + ptc.sz = R_3d(ptc.x_lim.y - ptc.x_lim.x, ptc.y_lim.y - ptc.y_lim.x, ptc.z_lim.y - ptc.z_lim.x); + } + + template + void fcn_ptc_pos_shift(const R_3d& r_sft, Ptc_R_3d& ptc) + { + for(auto ia = 0; ia < ptc.size(); ia++) + { + ptc.x[ia] += r_sft.x; + ptc.y[ia] += r_sft.y; + ptc.z[ia] += r_sft.z; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_R_3d& ptc) + { + const R_3d r_sft = (bs-ptc.sz)/T(2) - R_3d(ptc.x_lim.x, ptc.y_lim.x, ptc.z_lim.x); + + fcn_ptc_pos_shift(r_sft, ptc); + } + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_R_3d& ptc) + { + const R_2d r_sft = (bs-R_2d(ptc.sz.x, ptc.sz.y))/T(2) - R_2d(ptc.x_lim.x, ptc.y_lim.x); + + fcn_ptc_pos_shift({r_sft.x, r_sft.y, T(0)}, ptc); + } + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_R_3d& ptc) + { + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + auto r = mx*ptc.get_pos(ia) + p; + + ptc.x[ia] = r.x; + ptc.y[ia] = r.y; + } + + fcn_ptc_pos_statistic(ptc); + } + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_R_3d& ptc) + { + const auto Rm = fcn_rot_mx_3d(theta, u_0); + const auto p_sft = p - Rm*p; + + fcn_ptc_pos_apply_ltf(Rm, p_sft, ptc); + } +} + + +/********************************* atomic particles ************************************/ +namespace mt +{ + /******************************* forward declarations **********************************/ + template + class Ptc_Atom; + + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& atoms); +} + +namespace mt +{ + template + class Ptc_s_Atom: public Ptc_s_3d_0 + { + public: + dt_int32 Z; + dt_float32 sigma; + dt_float32 occ; + dt_int32 tag; + dt_int32 charge; + + Ptc_s_Atom():Z(0), Ptc_s_3d_0(), sigma(0), occ(0), tag(0), charge(0) {}; + + Ptc_s_Atom(const dt_int32& Z, const T& x, const T& y, const T& z, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge): + Z(Z), Ptc_s_3d_0(x, y, z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + Ptc_s_Atom(const dt_int32& Z, const R_3d& r, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge): + Z(Z), Ptc_s_3d_0(r.x, r.y, r.z), sigma(sigma), occ(occ), tag(tag), charge(charge) {}; + + /* constructor by pointer */ + template + Ptc_s_Atom(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0) + { + const auto ip = icol*n_r + idx; + + Z = dt_int32(v[ip + 0*n_r]); // atomic number + this->x = (n_c>1)?T(v[ip + 1*n_r]):T(0); // x-position + this->y = (n_c>2)?T(v[ip + 2*n_r]):T(0); // y-position + this->z = (n_c>3)?T(v[ip + 3*n_r]):T(0); // z-position + + sigma = (n_c>4)?dt_float32(v[ip + 4*n_r]):c_dflt_rms3d; // standard deviation + occ = (n_c>5)?dt_float32(v[ip + 5*n_r]):c_dflt_occ; // occupancy + tag = (n_c>6)?dt_int32(v[ip + 6*n_r]):c_dflt_tag; // tag + charge = (n_c>7)?dt_int32(v[ip + 7*n_r]):c_dflt_charge; // charge + } + + /* copy constructor */ + Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /* converting constructor */ + template + Ptc_s_Atom(const Ptc_s_Atom& ptc_s) + { + *this = ptc_s; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s) + { + if (this != &ptc_s) + { + Z = ptc_s.Z; + this->x = ptc_s.x; + this->y = ptc_s.y; + this->z = ptc_s.z; + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + + return *this; + } + + /* converting assignment operator */ + template + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s) + { + assign(ptc_s); + + return *this; + } + + template + void assign(const Ptc_s_Atom& ptc_s) + { + if ((void*)this != (void*)&ptc_s) + { + Z = ptc_s.Z; + this->x = T(ptc_s.x); + this->y = T(ptc_s.y); + this->z = T(ptc_s.z); + sigma = ptc_s.sigma; + occ = ptc_s.occ; + tag = ptc_s.tag; + charge = ptc_s.charge; + } + } + }; +} + +namespace mt +{ + template + class Ptc_Atom: public Ptc_R_3d + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_Atom; + + mutable Vctr_cpu Z; // atomic number + mutable Vctr_cpu sigma; // 3d root fcn_mean squared displacement (rmsd) + mutable Vctr_cpu occ; // occupancy + mutable Vctr_cpu tag; // tag + mutable Vctr_cpu charge; // charge + + dt_int32 cols_used; // number of used columns + + R_2d Z_lim; + R_2d sigma_lim; + R_2d occ_lim; + R_2d tag_lim; + R_2d charge_lim; + + /************************************* constructors ************************************/ + Ptc_Atom(): Ptc_R_3d(), cols_used(4), Z_lim(), sigma_lim(), occ_lim(), tag_lim(), charge_lim() {} + + template + Ptc_Atom(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + set_ptc(ptc, bs, pbc_xy, b_statistic); + } + + /* copy constructor */ + Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /* converting constructor */ + template + Ptc_Atom(const Ptc_Atom& ptc) + { + *this = ptc; + } + + /******************************** assignment operators *********************************/ + /* assignment operator */ + Ptc_Atom& operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + /* converting assignment operator */ + template + Ptc_Atom& operator=(const Ptc_Atom& ptc) + { + assign(ptc); + + return *this; + } + + template + void assign(const Ptc_Atom& ptc) + { + if ((void*)this != (void*)&ptc) + { + cols_used = ptc.cols_used; + + Z = ptc.Z; + + Ptc_R_3d::assign(ptc); + + sigma = ptc.sigma; + occ = ptc.occ; + tag = ptc.tag; + charge = ptc.charge; + + Z_lim = ptc.Z_lim; + sigma_lim = ptc.sigma_lim; + occ_lim = ptc.occ_lim; + tag_lim = ptc.tag_lim; + charge_lim = ptc.charge_lim; + } + } + + /***************************************************************************************/ + virtual size_type cols() const + { + return 8; + } + + void clear() + { + cols_used = 4; + + Z.clear(); + + Ptc_R_3d::clear(); + + sigma.clear(); + occ.clear(); + tag.clear(); + charge.clear(); + + Z_lim = 0; + sigma_lim = 0; + occ_lim = 0; + tag_lim = 0; + charge_lim = 0; + } + + void resize(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.resize(new_size); + + Ptc_R_3d::resize(new_size); + + if (cols_used>4) + sigma.resize(new_size); + + if (cols_used>5) + occ.resize(new_size); + + if (cols_used>6) + tag.resize(new_size); + + if (cols_used>7) + charge.resize(new_size); + } + + void reserve(size_type new_size) + { + new_size = max(size_type(0), new_size); + + Z.reserve(new_size); + + Ptc_R_3d::reserve(new_size); + + if (cols_used>4) + sigma.reserve(new_size); + + if (cols_used>5) + occ.reserve(new_size); + + if (cols_used>6) + tag.reserve(new_size); + + if (cols_used>7) + charge.reserve(new_size); + } + + void shrink_to_fit() + { + Z.shrink_to_fit(); + + Ptc_R_3d::shrink_to_fit(); + + sigma.shrink_to_fit(); + occ.shrink_to_fit(); + tag.shrink_to_fit(); + charge.shrink_to_fit(); + } + + void push_back(const Ptc_s& ptc_s) + { + Z.push_back(ptc_s.Z); // atomic number + + Ptc_R_3d::push_back(ptc_s); // xyz + + if (cols_used>4) + sigma.push_back(ptc_s.sigma); // standard deviation + + if (cols_used>5) + occ.push_back(ptc_s.occ); // occupancy + + if (cols_used>6) + tag.push_back(abs(ptc_s.tag)); // tag + + if (cols_used>7) + charge.push_back(ptc_s.charge); // charge + } + + dt_float32 get_sigma(const size_type& ia) const + { + return (cols_used>4)?sigma[ia]:c_dflt_rms3d; // standard deviation + } + + dt_float32 get_occ(const size_type& ia) const + { + return (cols_used>5)?occ[ia]:c_dflt_occ; // occupancy + } + + dt_int32 get_tag(const size_type& ia) const + { + return (cols_used>6)?tag[ia]:c_dflt_tag; // tag + } + + dt_int32 get_charge(const size_type& ia) const + { + return (cols_used>7)?charge[ia]:c_dflt_charge; // charge + } + + Ptc_s get(const size_type& ia) const + { + return {Z[ia], this->x[ia], this->y[ia], this->z[ia], get_sigma(ia), get_occ(ia), get_tag(ia), get_charge(ia)}; + } + + void set(const size_type& ia, const Ptc_s& ptc_s) + { + Z[ia] = ptc_s.Z; // atomic number + + Ptc_R_3d::set(ia, ptc_s); // xyz + + if (cols_used>4) // standard deviation + sigma[ia] = ptc_s.sigma; + + if (cols_used>5) // occupancy + occ[ia] = ptc_s.occ; + + if (cols_used>6) // tag + tag[ia] = ptc_s.tag; + + if (cols_used>7) // charge + charge[ia] = ptc_s.charge; + } + + template + void set_ptc(const Ptc_Atom& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + cols_used = ptc.cols_used; + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, pbc_xy, b_statistic, *this); + } + + template + void set_ptc(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true) + { + clear(); + cols_used = ptc.s1_32(); + reserve(ptc.size()); + + mt::ptc_detail::set_ptc_pbc_xy(ptc, 0, bs, pbc_xy, b_statistic, *this); + } + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=8) + { + is_e = min(is_e, cols_used); + + if (is_0>is_e) + { + std::swap(is_0, is_e); + } + + auto n_data = min(n_ptc, this->size()); + dt_int32 is = 0; + + if (fcn_chk_bound(0, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), Z.data(), n_data); // atomic number + + if (fcn_chk_bound(1, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->x.data(), n_data); // x-position + + if (fcn_chk_bound(2, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->y.data(), n_data); // y-position + + if (fcn_chk_bound(3, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), this->z.data(), n_data); // z-position + + if (fcn_chk_bound(4, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), sigma.data(), n_data); // standard deviation + + if (fcn_chk_bound(5, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), occ.data(), n_data); // occupancy + + if (fcn_chk_bound(6, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), tag.data(), n_data); // tag + + if (fcn_chk_bound(7, is_0, is_e)) + memcpy_cpu_cpu(&(ptc[(is++)*n_ptc]), charge.data(), n_data); // charge + + return is; + } + + // sort by x + void sort_by_x() + { + sort_by_idx(1); + } + + // sort by y + void sort_by_y() + { + sort_by_idx(2); + } + + // sort by z + void sort_by_z() + { + sort_by_idx(3); + } + + // sort by idx + void sort_by_idx(const dt_int32 idx = 3) + { + if (cols_used==4) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z); + + switch(idx) + { + SWITCH_1_3D(CASE_SORT) + } + } + else if (cols_used==5) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma); + + switch(idx) + { + SWITCH_2_3D(CASE_SORT) + } + } + else if (cols_used==6) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ); + + switch(idx) + { + SWITCH_3_3D(CASE_SORT) + } + } + else if (cols_used==7) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag); + + switch(idx) + { + SWITCH_4_3D(CASE_SORT) + } + } + else if (cols_used==8) + { + auto first = fcn_mkzipiter_begin(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + auto last = fcn_mkzipiter_end(Z, this->x, this->y, this->z, sigma, occ, tag, charge); + + switch(idx) + { + SWITCH_5_3D(CASE_SORT) + } + } + } + + + /***************************************************************************************/ + virtual void get_statistic() + { + if (this->empty()) + { + return; + } + + mt::fcn_minmax_element(Z, Z_lim.x, Z_lim.y); + + Ptc_R_3d::get_statistic(); + + sigma_lim.x = c_dflt_rms3d; + sigma_lim.y = c_dflt_rms3d; + if (cols_used>4) + mt::fcn_minmax_element(sigma, sigma_lim.x, sigma_lim.y); + + occ_lim.x = c_dflt_occ; + occ_lim.y = c_dflt_occ; + if (cols_used>5) + mt::fcn_minmax_element(occ, occ_lim.x, occ_lim.y); + + tag_lim.x = c_dflt_tag; + tag_lim.y = c_dflt_tag; + if (cols_used>6) + mt::fcn_minmax_element(tag, tag_lim.x, tag_lim.y); + + charge_lim.x = c_dflt_charge; + charge_lim.y = c_dflt_charge; + if (cols_used>7) + mt::fcn_minmax_element(tag, charge_lim.x, charge_lim.y); + + this->bs.z = ::fmax(this->sz.z, this->bs.z); + } + + // max z value within a tag + void minmax_z_by_region(const T& tag_v, T& z_min, T& z_max) + { + z_min = 1e20; + z_max = -1e20; + for(auto iz = 0; iz < this->size(); iz++) + { + if (tag[iz]==tag_v) + { + z_max = ::fmax(z_max, this->z[iz]); + z_min = ::fmin(z_min, this->z[iz]); + } + } + } + + void remove_ptc_out_z_range(const T& z_0, const T& z_e) + { + mt::remove_ptc_out_z_range(z_0, z_e, *this); + } + }; +} + +namespace mt +{ + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& ptc) + { + dt_int32 ia_z = 0; + for(dt_int64 ia = 0; ia < ptc.size(); ia++) + { + if (fcn_chk_bound(ptc.z[ia], z_0, z_e)) + { + ptc.Z[ia_z] = ptc.Z[ia]; + ptc.x[ia_z] = ptc.x[ia]; + ptc.y[ia_z] = ptc.y[ia]; + ptc.z[ia_z] = ptc.z[ia]; + + if (ptc.cols_used>4) + ptc.sigma[ia_z] = ptc.sigma[ia]; + + if (ptc.cols_used>5) + ptc.occ[ia_z] = ptc.occ[ia]; + + if (ptc.cols_used>6) + ptc.tag[ia_z] = ptc.tag[ia]; + + if (ptc.cols_used>7) + ptc.charge[ia_z] = ptc.charge[ia]; + + ia_z++; + } + } + + ptc.resize(ia_z); + ptc.shrink_to_fit(); + } + +} + +/* forward declarations */ +namespace mt +{ + /* 1d */ + template + void fcn_ptc_pos_statistic(Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_shift(const R_1d& r_sft, Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_recenter(const R_1d& bs, Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const T& mx, const R_1d& p, Ptc_R_1d& ptc); + + /* 2d */ + template + void fcn_ptc_pos_statistic(Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_R_2d& ptc); + + /* 3d */ + template + void fcn_ptc_pos_statistic(Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_shift(const R_3d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_R_3d& ptc); +} + +/* derived class 2d */ +namespace mt +{ + /***************************************************************************************/ + /************************************ pos 2d/c1 ****************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 1); // Ptc_s_2d_1 + C_PTC_COEF_DIM_N(2, 1); // Ptc_2d_1 + + /***************************************************************************************/ + /*********************************** pos 2d/c1/c2 **************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 2); // Ptc_s_2d_2 + C_PTC_COEF_DIM_N(2, 2); // Ptc_2d_2 + + /***************************************************************************************/ + /*********************************** pos 2d/c1/c2/c3 ***********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 3); // Ptc_s_2d_3 + C_PTC_COEF_DIM_N(2, 3); // Ptc_2d_3 + + /***************************************************************************************/ + /********************************* pos 2d/c1/c2/c3/c4 **********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 4); // Ptc_s_2d_4 + C_PTC_COEF_DIM_N(2, 4); // Ptc_2d_4 + + /***************************************************************************************/ + /******************************** pos 2d/c1/c2/c3/c4/c5 ********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(2, 5); // Ptc_s_2d_5 + C_PTC_COEF_DIM_N(2, 5); // Ptc_2d_5 + +} + +/* derived class 3d */ +namespace mt +{ + /***************************************************************************************/ + /************************************** pos 3d/c1 **************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 1); // Ptc_s_3d_1 + C_PTC_COEF_DIM_N(3, 1); // Ptc_3d_1 + + /***************************************************************************************/ + /************************************* pos 3d/c1/c2 ************************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 2); // Ptc_s_3d_2 + C_PTC_COEF_DIM_N(3, 2); // Ptc_3d_2 + + /***************************************************************************************/ + /*********************************** pos 3d/c1/c2/c3 ***********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 3); // Ptc_s_3d_3 + C_PTC_COEF_DIM_N(3, 3); // Ptc_3d_3 + + /***************************************************************************************/ + /********************************** pos 3d/c1/c2/c3/c4 *********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 4); // Ptc_s_3d_4 + C_PTC_COEF_DIM_N(3, 4); // Ptc_3d_4 + + /***************************************************************************************/ + /******************************** pos 3d/c1/c2/c3/c4/c5 ********************************/ + /***************************************************************************************/ + C_PTC_S_COEF_DIM_N(3, 5); // Ptc_s_3d_5 + C_PTC_COEF_DIM_N(3, 5); // Ptc_3d_5 +} diff --git a/src/peak_finding.cuh b/src/peak_finding.cuh old mode 100644 new mode 100755 index 5f24fcae..2d11e745 --- a/src/peak_finding.cuh +++ b/src/peak_finding.cuh @@ -1,1888 +1,1891 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef PEAK_FINDING_H -#define PEAK_FINDING_H - -#include -#include - -#include -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "fft.cuh" -#include "stream.cuh" -#include "lapack.hpp" -#include "box_occ.hpp" -#include "cgpu_classes.cuh" -#include "image_functions.cuh" - -namespace mt -{ - template - class Peak_Finding - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - using size_type = std::size_t; - - Peak_Finding(): sigma(1.0), thres(0.5), niter(10), d_error(1e-3), - image_mean(0), image_std(1), radius_n(6*sigma), ref_mean(500), ref_std(80){}; - - Peak_Finding(Grid_2d &grid_i, TVector_r &image_i, T sigma_i, T thres_i, int niter_i) - { - operator()(grid_i, image_i, sigma_i, thres_i, niter_i); - } - - void cleanup() - { - fft_2d.cleanup(); - } - - void operator()(Grid_2d &grid_i, TVector_r &image_i, T sigma_i, T thres_i, int niter_i) - { - grid_2d = grid_i; - sigma = sigma_i; - thres = thres_i; - niter = niter_i; - d_error = 1e-4; - - ref_mean = 500; - ref_std = 80; - radius_n = 6*sigma; - - stream.resize(4); - fft_2d.create_plan_2d(grid_2d.ny, grid_2d.nx, stream.size()); - - // image_mean and image_std are defined here - image = scale_input_image(stream, image_i); - } - - void find() - { - // denoise im - int nkr_w = max(1, static_cast(floor(sigma/2+0.5))); - int nkr_m = max(1, static_cast(floor(sigma/3+0.5))); - image_den = ftr_poiss_dnois_2d(stream, grid_2d, image, nkr_w, nkr_m); - - // get peak signal to noise ratio - auto PSNR = get_PSNR(stream, image, image_den); - - // deconvolute input image - auto image_dcon = image; - Gauss_Dcv_2d gauss_dcv_2d(&stream, &fft_2d, grid_2d); - gauss_dcv_2d(sigma, PSNR, image_dcon); - - thrust::for_each(image_dcon.begin(), image_dcon.end(), [&](T &v){ v = (v<0)?0:v; }); - - // get background - int nkr = static_cast(round(5.0*sigma/grid_2d.dR_min())); - auto image_thr = morp_g_open(stream, grid_2d.ny, grid_2d.nx, image_dcon, nkr); - - Gauss_Cv_2d gauss_cv_2d(&stream, &fft_2d, grid_2d); - gauss_cv_2d(sigma, image_thr); - - // background substraction - thrust::transform(image_dcon.begin(), image_dcon.end(), image_thr.begin(), - image_thr.begin(), [](const T &a, const T&b){ return ::fmax(a-b, T(0)); }); - - // fast peak finding - fast_peak_finding(stream, image_thr, x, y); - - // deleting close neighbors - neigh.delete_points(x, y, grid_2d); - - // set output data - A.resize(x.size()); - std::fill(A.begin(), A.end(), T(0)); - - A_min.resize(x.size()); - std::fill(A_min.begin(), A_min.end(), T(0)); - - A_max.resize(x.size()); - std::fill(A_max.begin(), A_max.end(), T(0)); - - S.resize(x.size()); - std::fill(S.begin(), S.end(), T(0)); - - S_min.resize(x.size()); - std::fill(S_min.begin(), S_min.end(), T(0)); - - S_max.resize(x.size()); - std::fill(S_max.begin(), S_max.end(), T(0)); - - bg = 0; - - int ibor = max(10, grid_2d.ceil_dR_min(3*sigma)); - range_ct.ix_0 = ibor; - range_ct.ix_e = grid_2d.nx-ibor; - range_ct.iy_0 = ibor; - range_ct.iy_e = grid_2d.ny-ibor; - } - - void fit() - { - // get neighbors - neigh(stream, x, y, radius_n); - - // get image mask - mask = get_mask(stream, neigh, x, y); - - // set bg values - T bg_min, bg_max; - set_init_bg_values(stream, mask, image_den, x, y, bg, bg_min, bg_max); - - // set A values - set_init_A_values(stream, image_den, neigh, x, y, A, A_min, A_max, bg); - - // get first approximations - S = fit_b_0(stream, mask, image, x, y, A, sigma, bg, 15, d_error); - A = fit_a_0(stream, mask, image, x, y, A, A_min, A_max, S, bg); - - for (auto ipk = 0; ipk < x.size(); ipk++) - { - S_min[ipk] = ::fmax(0.5*grid_2d.dR_min(), 0.25*S[ipk]); - S_max[ipk] = ::fmin(0.9*neigh.d_min(ipk), 1.5*S[ipk]); - } - - // regions.set(stream, grid_2d, image, neigh, x, y, 1, 1); - // for (auto it = 0; it < 1; it++) - // { - // fit_a_b_0(stream, regions, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); - // } - - // regions.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); - // for (auto it = 0; it < 3; it++) - // { - // fit_a_b_0(stream, regions, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); - // } - // bg = fit_c_0(stream, image, x, y, A, S, bg, bg_min, bg_max); - - // for (auto it = 0; it < 3; it++) - // { - // regions.set(stream, grid_2d, image, neigh, x, y, 1, 0.4); - // fit_x_y_0(stream, regions, x, y, A, S, bg, 10, d_error); - // } - - // regions.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); - // fit_a_b_0(stream, regions, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); - // fit_a_b_x_y_0(stream, regions, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); - // for (auto it = 0; it < 3; it++) - // { - // regions.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); - // fit_a_b_x_y_0(stream, regions, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); - // } - // neigh(stream, x, y, radius_n); - // regions.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); - // fit_a_b_x_y(stream, regions, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); - // fit_a_b_x_y_0(stream, regions, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); - } - - void get_data(TVector_r &x_o, TVector_r &y_o, TVector_r &A_o, TVector_r &S_o, T &bg_o) - { - int npeaks = x.size(); - - x_o.resize(npeaks); - y_o.resize(npeaks); - A_o.resize(npeaks); - S_o.resize(npeaks); - - T sf = ref_std/image_std; - for(auto idx=0; idx &grid_2d, TVector_r &Im_s, T x, T y) - { - TVector_r v = Ixy; - - T R2_max = pow(R_max, 2); - - r2d p(x, y); - auto range = grid_2d.index_range(p, R_max); - int iv = 0; - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T r2 = grid_2d.R2(ix, iy, p.x, p.y); - if (r2 < R2_max) - { - v[iv++] -= Im_s[grid_2d.ind_col(ix, iy)]/Ixy_sc; - } - } - } - return v; - } - - TVector_r sft_Ixy(Grid_2d &grid_2d, TVector_r &Im_s, T x, T y, T a, T s) - { - TVector_r v = sub_region_to_Ixy(grid_2d, Im_s, x*Rxy_sc+Rx_sf, y*Rxy_sc+Ry_sf); - - T alpha = 0.5/pow(s, 2); - T r2_l = pow(4.0*s, 2); - for(auto im = 0; im < v.size(); im++) - { - T rx = Rx[im]-x; - T ry = Ry[im]-y; - T r2 = rx*rx+ry*ry; - if(r2 &grid_2d, TVector_r &Im_s, TVector_r &x, TVector_r &y, TVector_r &A, TVector_r &S) - { - TVector_r v = sub_region_to_Ixy(grid_2d, Im_s, x[0]*Rxy_sc+Rx_sf, y[0]*Rxy_sc+Ry_sf); - - for(auto ip = 0; ip < x.size(); ip++) - { - T a = A[ip]; - T b = S[ip]; - T alpha = 0.5/pow(b, 2); - T r2_l = pow(4.0*b, 2); - for(auto im = 0; im < v.size(); im++) - { - T rx = Rx[im]-x[ip]; - T ry = Ry[im]-y[ip]; - T r2 = rx*rx+ry*ry; - if(r2 sft_x_y(T x, T y) const - { - x = sft_Rx(x); - y = sft_Ry(y); - return r2d(x, y); - } - }; - - struct Regions - { - public: - using size_type = std::size_t; - - int m_max; - int n_max; - Regions():m_max(1), n_max(1){} - - size_type size() const - { - return reg.size(); - } - - void set(Stream &stream, const Grid_2d &grid_i, TVector_r &Im_i, - Neigh_2d &neigh, TVector_r &x, TVector_r &y, int iradius=1, T ff=0.5) - { - grid_2d = grid_i; - reg.resize(x.size()); - T R_min = 3.1*grid_2d.dR_min(); - - auto sel_radius = [&neigh, R_min, ff](int ipk, int iradius)->T - { - T radius = 0; - switch (iradius) - { - case 1: - radius = ::fmax(R_min, ff*neigh.d_min(ipk)); - break; - case 2: - radius = neigh.d_max(ipk) + ff*neigh.d_min(ipk); - break; - } - return radius; - }; - - auto thr_select_cir_reg = [&](const Range_2d &range) - { - for (auto ipk = range.ixy_0; ipk < range.ixy_e; ipk++) - { - r2d p(x[ipk], y[ipk]); - T radius = sel_radius(ipk, iradius); - reg[ipk] = select_cir_reg(Im_i, p, radius); - } - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_select_cir_reg); - - T d_max = 0; - n_max = 1; - for (auto ipk = 0; ipk < x.size(); ipk++) - { - T radius = sel_radius(ipk, iradius); - d_max = max(d_max, radius); - n_max = max(n_max, neigh.size(ipk)); - } - d_max += 3*grid_i.dR_min(); - m_max = static_cast(std::round(c_Pi*pow(d_max, 2)/pow(grid_i.dR_min(), 2))); - } - - Region& operator[](const int i){ return reg[i]; } - - const Region& operator[](const int i) const { return reg[i]; } - private: - vector reg; - Grid_2d grid_2d; - - Region select_cir_reg(TVector_r &Im, r2d p, T radius) - { - T R_max = radius; - T R2_max = pow(R_max, 2); - - auto range = grid_2d.index_range(p, R_max); - - Region region; - region.clear(); - region.reserve(range.ixy_e); - - // select circular region - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T r2_d = grid_2d.R2(ix, iy, p.x, p.y); - int ixy = grid_2d.ind_col(ix, iy); - if (r2_d < R2_max) - { - region.Rx.push_back(grid_2d.Rx(ix)); - region.Ry.push_back(grid_2d.Ry(iy)); - region.R2.push_back(r2_d); - region.Ixy.push_back(Im[ixy]); - } - } - } - - region.R_max = R_max; - region.Rx_sf = p.x; - region.Ry_sf = p.y; - region.Rxy_sc = R_max; - - // really important that Ixy_mean is zero if not - // we have to change our reference system to fit the parameters - region.Ixy_sf = 0; - region.Ixy_sc = sqrt(variance(region.Ixy)); - // shift and scale - int m = region.Ixy.size(); - for (auto ixy = 0; ixy < m; ixy++) - { - region.Rx[ixy] = (region.Rx[ixy]-region.Rx_sf)/region.Rxy_sc; - region.Ry[ixy] = (region.Ry[ixy]-region.Ry_sf)/region.Rxy_sc; - region.R2[ixy] = region.R2[ixy]/pow(region.Rxy_sc, 2); - region.Ixy[ixy] = (region.Ixy[ixy]-region.Ixy_sf)/region.Ixy_sc; - } - - region.shrink_to_fit(); - return region; - } - }; - - TVector_r scale_input_image(Stream &stream, TVector_r &image_i) - { - mean_var(stream, image_i, image_mean, image_std); - image_std = sqrt(image_std); - - auto thr_scale = [=](const Range_2d &range, TVector_r &image_i, TVector_r &image_o) - { - for (auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - T v = image_i[ixy]; - v = (v-image_mean)/image_std; - v = v*ref_std + ref_mean; - image_o[ixy] = ::fmax(v, 4); - } - }; - - TVector_r image_o(image_i.size()); - stream.set_n_act_stream(grid_2d.nx); - stream.set_grid(grid_2d.nx, grid_2d.ny); - stream.exec(thr_scale, image_i, image_o); - - return image_o; - } - - void fast_peak_finding(Stream &stream, TVector_r &image, TVector_r &x, TVector_r &y) - { - auto Im_minmax = std::minmax_element(image.begin(), image.end()); - - T thres_n = *(Im_minmax.first) + thres*(*(Im_minmax.second)-*(Im_minmax.first)); - - image = thresholding(stream, image, thres_n); - - // local maximum - auto krn_maximum = [thres_n](const int &ix, const int &iy, Grid_2d &grid_2d, TVector_r &Im, r2d &peak)->bool - { - auto v = Im[grid_2d.ind_col(ix, iy)]; - peak = r2d(grid_2d.Rx(ix), grid_2d.Ry(iy)); - - if(v <= thres_n) - { - return false; - } - - T v1 = Im[grid_2d.ind_col(ix-1, iy-1)]; - T v2 = Im[grid_2d.ind_col(ix, iy-1)]; - T v3 = Im[grid_2d.ind_col(ix+1, iy-1)]; - - T v4 = Im[grid_2d.ind_col(ix-1, iy)]; - T v6 = Im[grid_2d.ind_col(ix+1, iy)]; - - T v7 = Im[grid_2d.ind_col(ix-1, iy+1)]; - T v8 = Im[grid_2d.ind_col(ix, iy+1)]; - T v9 = Im[grid_2d.ind_col(ix+1, iy+1)]; - - T v_s = v1+v2+v3+v4+v+v6+v7+v8+v9; - - T x1 = grid_2d.Rx(ix-1); - T x2 = grid_2d.Rx(ix); - T x3 = grid_2d.Rx(ix+1); - - T y1 = grid_2d.Ry(iy-1); - T y2 = grid_2d.Ry(iy); - T y3 = grid_2d.Ry(iy+1); - - T x = v1*x1 + v2*x2 + v3*x3 + v4*x1 + v*x2 + v6*x3 + v7*x1 + v8*x2 + v9*x3; - T y = v1*y1 + v2*y2 + v3*y3 + v4*y1 + v*y2 + v6*y3 + v7*y1 + v8*y2 + v9*y3; - peak = r2d(x, y)/v_s; - - return (v1<=v) && (v2<=v) && (v3<=v) && (v4<=v) && (v6<=v) && (v7<=v) && (v8<=v) && (v9<=v); - }; - - auto npeaks_m = static_cast(ceil(grid_2d.lx*grid_2d.ly/(c_Pi*sigma*sigma))); - - x.reserve(2*npeaks_m); - y.reserve(2*npeaks_m); - - // get local peaks - auto thr_peaks = [&](const Range_2d &range, Grid_2d &grid_2d, TVector_r &image, TVector_r &x_o, TVector_r &y_o) - { - TVector_r x; - x.reserve(npeaks_m); - - TVector_r y; - y.reserve(npeaks_m); - - auto ix_0 = 1 + range.ix_0; - auto ix_e = 1 + range.ix_e; - auto iy_0 = 1 + range.iy_0; - auto iy_e = 1 + range.iy_e; - - for(auto ix = ix_0; ix < ix_e; ix++) - { - for(auto iy = iy_0; iy < iy_e; iy++) - { - r2d peak; - if(krn_maximum(ix, iy, grid_2d, image, peak)) - { - x.push_back(peak.x); - y.push_back(peak.y); - } - } - } - - stream.stream_mutex.lock(); - x_o.insert(x_o.end(), x.begin(), x.end()); - y_o.insert(y_o.end(), y.begin(), y.end()); - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(grid_2d.nx-2); - stream.set_grid(grid_2d.nx-2, grid_2d.ny-2); - stream.exec(thr_peaks, grid_2d, image, x, y); - - x.shrink_to_fit(); - y.shrink_to_fit(); - } - - void set_init_bg_values(Stream &stream, vector &mask, TVector_r &image, - TVector_r &x, TVector_r &y, T &bg, T &bg_min, T &bg_max) - { - T R_max = 2.5*grid_2d.dR_min(); - T peak_min = image[grid_2d.ixy(x[0], y[0])]; - - auto get_mean_peak = [](const r2d &p, const T &R_max, const Grid_2d &grid_2d, const TVector_r &image)->T - { - T R2_max = pow(R_max, 2); - auto range = grid_2d.index_range(p, R_max); - T Ixy_mean = 0; - int n_Ixy_mean = 0; - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2_d = grid_2d.R2(ix, iy, p.x, p.y); - if (R2_d < R2_max) - { - Ixy_mean += image[grid_2d.ind_col(ix, iy)]; - n_Ixy_mean++; - } - } - } - Ixy_mean /= n_Ixy_mean; - return Ixy_mean; - }; - - auto thr_min_peak = [&](const Range_2d &range, Grid_2d &grid_2d, vector &mask, TVector_r &image, - TVector_r &x, TVector_r &y, T &peak_min) - { - T peak_min_t = 100*image[grid_2d.ixy(x[0], y[0])]; - for(auto ipk=range.ixy_0; ipk p(x[ipk], y[ipk]); - if (mask[grid_2d.ixy(p.x, p.y)]) - { - peak_min_t = ::fmin(peak_min_t, get_mean_peak(p, R_max, grid_2d, image)); - } - } - stream.stream_mutex.lock(); - peak_min = ::fmin(peak_min, peak_min_t); - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_min_peak, grid_2d, mask, image, x, y, peak_min); - - // mean bellow thr - T I_min = 0; - T I_mean = 0; - T I_std = 0; - T I_low = 0; - for(auto it=0; it<2; it++) - { - I_min = peak_min; - T I_sum = 0; - T I_sum_ee = 0; - T I_sum2 = 0; - T I_sum2_ee = 0; - int I_c = 0; - for (auto ix = range_ct.ix_0; ix < range_ct.ix_e; ix++) - { - for (auto iy = range_ct.iy_0; iy < range_ct.iy_e; iy++) - { - T v = image[grid_2d.ind_col(ix, iy)]; - if ((v < peak_min) && (I_low < v)) - { - host_device_detail::kh_sum(I_sum, v, I_sum_ee); - host_device_detail::kh_sum(I_sum2, v*v, I_sum2_ee); - I_min = ::fmin(I_min, v); - I_c++; - } - } - } - I_mean = I_sum/I_c; - I_std = sqrt(fabs(I_sum2/I_c-I_mean*I_mean)); - peak_min = I_mean; - I_low = I_mean-3*I_std; - } - bg = ::fmax(0, I_mean - I_std); - // bg_o = (0-image_mean)*sf + ref_mean; - bg_min = ::fmax(I_mean-4*I_std, I_min-0.5*I_std); - bg_max = I_mean+0.5*I_std; - } - - void set_init_A_values(Stream &stream, TVector_r &image, Neigh_2d &neigh, - TVector_r &x, TVector_r &y, TVector_r &A, TVector_r &A_min, TVector_r &A_max, T Bg) - { - auto thr_A_values = [Bg](const Range_2d &range, Grid_2d &grid_2d, TVector_r &image, - Neigh_2d &neigh, TVector_r &x, TVector_r &y, TVector_r &A, TVector_r &A_min, TVector_r &A_max) - { - auto get_A_values = [](const r2d &p, const T &R_max, const Grid_2d &grid_2d, - const TVector_r &image, T &A, T &A_min, T &A_max) - { - T R2_max = pow(R_max, 2); - T R2_peak_max = pow(1.75*grid_2d.dR_min(), 2); - - auto range = grid_2d.index_range(p, R_max); - - T Ixy_min = image[grid_2d.ixy(p.x, p.y)]; - - T Ixy_peak = 0; - int Ixy_peak_c = 0; - - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2_d = grid_2d.R2(ix, iy, p.x, p.y); - if (R2_d < R2_max) - { - T v = image[grid_2d.ind_col(ix, iy)]; - Ixy_min = (v p(x[ipk], y[ipk]); - T R_max = neigh.d_min(ipk); - get_A_values(p, R_max, grid_2d, image, A[ipk], A_min[ipk], A_max[ipk]); - A[ipk] -= Bg; - } - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_A_values, grid_2d, image, neigh, x, y, A, A_min, A_max); - } - - vector get_mask(Stream &stream, TVector_r &x, TVector_r &y, TVector_r &S) - { - vector image(grid_2d.nxy(), false); - - auto set_area = [](const r2d &p, const T &R_max, const Grid_2d &grid_2d, vector &image) - { - T R2_max = pow(R_max, 2); - auto range = grid_2d.index_range(p, R_max); - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2_d = grid_2d.R2(ix, iy, p.x, p.y); - if (R2_d < R2_max) - { - image[grid_2d.ind_col(ix, iy)] = true; - } - } - } - }; - - auto thr_area = [&](const Range_2d &range, Grid_2d &grid_2d, TVector_r &x, TVector_r &y, TVector_r &S, vector &image) - { - for (auto ipk = range.ixy_0; ipk < range.ixy_e; ipk++) - { - r2d p(x[ipk], y[ipk]); - T R_max = 3.5*S[ipk]; - set_area(p, R_max, grid_2d, image); - } - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_area, grid_2d, x, y, S, image); - - return image; - } - - vector get_mask(Stream &stream, Neigh_2d &neigh, TVector_r &x, TVector_r &y) - { - vector image(grid_2d.nxy(), false); - - auto set_area = [](const r2d &p, const T &R_max, const Grid_2d &grid_2d, vector &image) - { - T R2_max = pow(R_max, 2); - auto range = grid_2d.index_range(p, R_max); - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T R2_d = grid_2d.R2(ix, iy, p.x, p.y); - if (R2_d < R2_max) - { - image[grid_2d.ind_col(ix, iy)] = true; - } - } - } - }; - - auto thr_area = [&](const Range_2d &range, Grid_2d &grid_2d, Neigh_2d &neigh, TVector_r &x, TVector_r &y, vector &image) - { - for(auto ipk=range.ixy_0; ipk p(x[ipk], y[ipk]); - T R_max = neigh.d_min(ipk); - set_area(p, R_max, grid_2d, image); - } - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_area, grid_2d, neigh, x, y, image); - - // left - for (auto ix = 0; ix < range_ct.ix_0; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - image[grid_2d.ind_col(ix, iy)] = false; - } - } - - // right - for (auto ix = range_ct.ix_e; ix < grid_2d.nx; ix++) - { - for (auto iy = 0; iy < grid_2d.ny; iy++) - { - image[grid_2d.ind_col(ix, iy)] = false; - } - } - - // top - for (auto ix = 0; ix < grid_2d.nx; ix++) - { - for (auto iy = 0; iy < range_ct.iy_0; iy++) - { - image[grid_2d.ind_col(ix, iy)] = false; - } - } - - // bottom - for (auto ix = 0; ix < grid_2d.nx; ix++) - { - for (auto iy = range_ct.iy_e; iy < grid_2d.ny; iy++) - { - image[grid_2d.ind_col(ix, iy)] = false; - } - } - - return image; - } - - void set_mask_and_scale(Stream &stream, vector &mask, - TVector_r &image, TVector_r &image_m, T &image_m_sc) - { - image_m.resize(image.size()); - T image_sum = 0; - T image2_sum = 0; - int c_image_sum = 0; - - // mask image - auto thr_mask = [&](const Range_2d &range, TVector_r &image, - TVector_r &image_m, int &c_image_sum, T &image_sum, T &image2_sum) - { - // set mask and get mean and std - T im_sum = 0; - T im_sum_ee = 0; - T im2_sum = 0; - T im2_sum_ee = 0; - int c_sum = 0; - for (auto ixy = range.ixy_0; ixy &mask, TVector_r &image) - { - for (auto ixy = range.ixy_0; ixy &stream, TVector_r &image, TVector_r &image_m, T &image_m_sc) - { - image_m.resize(image.size()); - - image_m_sc = sqrt(variance(stream, image)); - - auto thr_sft_scale = [image_m_sc](const Range_2d &range, TVector_r &image, TVector_r &image_m) - { - for (auto ixy = range.ixy_0; ixysig_u))?s_mean:S[ipk]; - } - } - - TVector_r gauss_sp(Stream &stream, TVector_r &x, TVector_r &y, - TVector_r &A, TVector_r &S, T Bg) - { - auto thr_gauss_sp = [&stream](const Grid_2d &grid_2d, TVector_r &x, TVector_r &y, TVector_r &A, TVector_r &S, T Bg) - { - int m = grid_2d.nxy(); - TVector_r Ixy(m, Bg); - - auto thr_gauss_sup = [&](const Range_2d &range, TVector_r &x, TVector_r &y, TVector_r &A, TVector_r &S) - { - auto gaussian = [](r2d p, T a, T b, T R_max, const Grid_2d &grid_2d, TVector_r &Ixy) - { - T R2_max = pow(R_max, 2); - T c_alpha = 0.5/pow(b, 2); - auto range = grid_2d.index_range(p, R_max); - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T r2 = grid_2d.R2(ix, iy, p.x, p.y); - if (r2 < R2_max) - { - Ixy[grid_2d.ind_col(ix, iy)] += a*exp(-c_alpha*r2); - } - } - } - }; - - TVector_r Ixy_p(m, T(0)); - for (auto ip = range.ixy_0; ip < range.ixy_e; ip++) - { - r2d p(x[ip], y[ip]); - T a = A[ip]; - T b = S[ip]; - T R_max = 4.0*b; - gaussian(p, a, b, R_max, grid_2d, Ixy_p); - } - - stream.stream_mutex.lock(); - for (auto ixy = 0; ixy < m; ixy++) - { - Ixy[ixy] += Ixy_p[ixy]; - } - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_gauss_sup, x, y, A, S); - return Ixy; - }; - - return thr_gauss_sp(grid_2d, x, y, A, S, Bg); - }; - - TVector_r fit_b_0(Stream &stream, vector &mask, TVector_r &image, - TVector_r x, TVector_r y, TVector_r A, T S, T Bg, int niter, T d_error) - { - // mask and scaling - TVector_r Ixy; - T Ixy_sc; - set_mask_and_scale(stream, mask, image, Ixy, Ixy_sc); - - const T factor = 2; - T Rxy_sc = grid_2d.lx_ly_max()/factor; - - Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.lx/Rxy_sc, grid_2d.ly/Rxy_sc); - - // scaling - for (auto ip = 0; ip &grid_2d, vector &mask, TVector_r &Ixy, - TVector_r &x, TVector_r &y, TVector_r &A, T &b, T b_min, T b_max, int niter, T d_error) - { - auto dgaussian = [&mask](r2d p, T a, T b, T R_max, const Grid_2d &grid_2d, TVector_r &J, TVector_r &d_Ixy) - { - T R2_max = pow(R_max, 2); - T c_alpha = 0.5/pow(b, 2); - T c_a = a/pow(b, 3); - auto range = grid_2d.index_range(p, R_max); - - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T r2 = grid_2d.R2(ix, iy, p.x, p.y); - int ixy = grid_2d.ind_col(ix, iy); - if ((r2 < R2_max) && mask[ixy]) - { - T f = exp(-c_alpha*r2); - J[ixy] += c_a*r2*f; - d_Ixy[ixy] += a*f; - } - } - } - }; - - auto solve_d_b = [&mask](TVector_r &J, TVector_r &d_Ixy)->T - { - T sxx = 0; - T sxx_ee = 0; - T sxy = 0; - T sxy_ee = 0; - for (auto ixy = 0; ixy < d_Ixy.size(); ixy++) - { - if (mask[ixy]) - { - T x = J[ixy]; - T y = d_Ixy[ixy]; - - host_device_detail::kh_sum(sxx, x*x, sxx_ee); - host_device_detail::kh_sum(sxy, x*y, sxy_ee); - } - } - - return sxy/sxx; - }; - - int m = Ixy.size(); - TVector_r d_Ixy(m); - TVector_r J(m); - for (auto iter = 0; iter p(x[ip], y[ip]); - T a = A[ip]; - T R_max = 4.0*b; - dgaussian(p, a, b, R_max, grid_2d, J_p, d_Ixy_p); - } - stream.stream_mutex.lock(); - for (auto ixy = 0; ixy < m; ixy++) - { - J[ixy] += J_p[ixy]; - d_Ixy[ixy] -= d_Ixy_p[ixy]; - } - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_gauss_sup); - - T d_b = solve_d_b(J, d_Ixy); - - b += d_b; - - b = min(max(b_min, b), b_max); - - if (fabs(d_b/b) &stream, vector &mask, TVector_r &image, - TVector_r x, TVector_r y, TVector_r A, TVector_r &A_min, TVector_r &A_max, TVector_r S, T Bg) - { - // mask and scaling - TVector_r Ixy; - T Ixy_sc; - set_mask_and_scale(stream, mask, image, Ixy, Ixy_sc); - - const T factor = 2; - T Rxy_sc = grid_2d.lx_ly_max()/factor; - - Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.lx/Rxy_sc, grid_2d.ly/Rxy_sc); - - // scaling - for (auto ip = 0; ip &grid_2d, vector &mask, TVector_r &Ixy, - TVector_r &x, TVector_r &y, TVector_r &A, TVector_r &S) - { - auto dgaussian = [&mask](r2d p, T a, T b, T R_max, const Grid_2d &grid_2d, TVector_r &J) - { - T R2_max = pow(R_max, 2); - T c_alpha = 0.5/pow(b, 2); - auto range = grid_2d.index_range(p, R_max); - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T r2 = grid_2d.R2(ix, iy, p.x, p.y); - int ixy = grid_2d.ind_col(ix, iy); - if ((r2 < R2_max) && mask[ixy]) - { - J[ixy] += a*exp(-c_alpha*r2); - } - } - } - }; - - int m = Ixy.size(); - TVector_r J(m, T(0)); - auto thr_gauss_sup = [&](const Range_2d &range) - { - TVector_r J_p(m, T(0)); - for (auto ip = range.ixy_0; ip < range.ixy_e; ip++) - { - r2d p(x[ip], y[ip]); - T a = A[ip]; - T b = S[ip]; - T R_max = 4.0*b; - dgaussian(p, a, b, R_max, grid_2d, J_p); - } - - stream.stream_mutex.lock(); - for (auto ixy = 0; ixy < m; ixy++) - { - J[ixy] += J_p[ixy]; - } - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_gauss_sup); - - T sxy = 0; - T sxy_ee = 0; - T sxx = 0; - T sxx_ee = 0; - for (auto ixy = 0; ixy < Ixy.size(); ixy++) - { - if (mask[ixy]) - { - host_device_detail::kh_sum(sxy, Ixy[ixy]*J[ixy], sxy_ee); - host_device_detail::kh_sum(sxx, J[ixy]*J[ixy], sxx_ee); - } - } - return sxy/sxx; - }; - - T alpha = get_a(grid_s, mask, Ixy, x, y, A, S); - for (auto ip = 0; ip < x.size(); ip++) - { - T a = A[ip]*alpha*Ixy_sc + Bg; - if((aA_max[ip])) - { - a = A[ip]*Ixy_sc + Bg; - } - A[ip] = a-Bg; - } - return A; - }; - - T fit_c_0(Stream &stream, TVector_r &image, TVector_r x, TVector_r y, - TVector_r A, TVector_r S, T Bg, T Bg_min, T Bg_max) - { - // mask and scaling - TVector_r Ixy; - T Ixy_sc; - scale(stream, image, Ixy, Ixy_sc); - - const T factor = 2; - T Rxy_sc = grid_2d.lx_ly_max()/factor; - - Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.lx/Rxy_sc, grid_2d.ly/Rxy_sc); - - // scaling - for (auto ip = 0; ip &grid_2d, vector &mask, TVector_r &Ixy, - TVector_r &x, TVector_r &y, TVector_r &A, TVector_r &S) - { - auto dgaussian = [](const r2d &p, const T &a, const T &b, const T &R_max, const Grid_2d &grid_2d, TVector_r &J) - { - T R2_max = pow(R_max, 2); - T c_alpha = 0.5/pow(b, 2); - auto range = grid_2d.index_range(p, R_max); - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T r2 = grid_2d.R2(ix, iy, p.x, p.y); - if (r2 < R2_max) - { - J[grid_2d.ind_col(ix, iy)] += a*exp(-c_alpha*r2); - } - } - } - }; - - int m = Ixy.size(); - TVector_r d_Ixy = Ixy; - auto thr_gauss_sup = [&](const Range_2d &range) - { - TVector_r d_Ixy_p(m, T(0)); - for (auto ip = range.ixy_0; ip < range.ixy_e; ip++) - { - r2d p(x[ip], y[ip]); - T a = A[ip]; - T b = S[ip]; - T R_max = 4.0*b; - dgaussian(p, a, b, R_max, grid_2d, d_Ixy_p); - } - - stream.stream_mutex.lock(); - for (auto ixy = 0; ixy < m; ixy++) - { - d_Ixy[ixy] -= d_Ixy_p[ixy]; - } - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(x.size()); - stream.set_grid(x.size(), 1); - stream.exec(thr_gauss_sup); - - T sxy = 0; - T sxy_ee = 0; - int sxx = 0; - for (auto ix = range_ct.ix_0; ix < range_ct.ix_e; ix++) - { - for (auto iy = range_ct.iy_0; iy < range_ct.iy_e; iy++) - { - int ixy = grid_2d.ind_col(ix, iy); - host_device_detail::kh_sum(sxy, d_Ixy[ixy], sxy_ee); - sxx++; - } - } - return sxy/sxx; - }; - - T c = get_c(grid_s, mask, Ixy, x, y, A, S); - c = ((cc_max))?c_0:c_0+(1.0/2.0)*(c-c_0); - return c*Ixy_sc; - }; - - void fit_a_b_0(Stream &stream, Regions ®ions, TVector_r &x, TVector_r &y, - TVector_r &A, TVector_r &A_min, TVector_r &A_max, TVector_r &S, TVector_r &S_min, - TVector_r &S_max, T Bg, int niter, T d_error) - { - auto image_s = gauss_sp(stream, x, y, A, S, Bg); - - auto thr_fit_a_b_0 = [&](const Range_2d &range) - { - int m_max = regions.m_max; - int n_max = 2; - - TVector_r Ja(m_max); - TVector_r Jb(m_max); - TVector_r d_Ixy(m_max); - - auto solve_a_b = [](int m, TVector_r &Ja, TVector_r &Jb, - TVector_r &d_Ixy, T lambda, T &d_a, T &d_b, T &g_m, T &rho_f) - { - T sx1x1 = 0; - T sx2x2 = 0; - T sx1x2 = 0; - T sx1y = 0; - T sx2y = 0; - for (auto ixy = 0; ixy < m; ixy++) - { - T x1 = Ja[ixy]; - T x2 = Jb[ixy]; - T y = d_Ixy[ixy]; - - sx1x1 += x1*x1; - sx2x2 += x2*x2; - sx1x2 += x1*x2; - sx1y += x1*y; - sx2y += x2*y; - } - T D_a = lambda*(sx1x1 > 1e-10)?sx1x1:1; - T D_b = lambda*(sx2x2 > 1e-10)?sx2x2:1; - - sx1x1 += D_a; - sx2x2 += D_b; - - T det = sx1x1*sx2x2 - sx1x2*sx1x2; - d_a = (sx2x2*sx1y - sx1x2*sx2y)/det; - d_b = (sx1x1*sx2y - sx1x2*sx1y)/det; - - g_m = ::fmax(fabs(sx1y), fabs(sx2y)); - rho_f = d_a*(D_a*d_a + sx1y) + d_b*(D_b*d_b + sx2y); - }; - - auto get_chi2 = [](TVector_r &R2, TVector_r &Ixy, T a, T b)->T - { - T c_alpha = 0.5/pow(b, 2); - T chi2 = 0; - T chi2_ee = 0; - for (auto im = 0; im < R2.size(); im++) - { - T v = Ixy[im]-a*exp(-c_alpha*R2[im]); - host_device_detail::kh_sum(chi2, v*v, chi2_ee); - } - return chi2; - }; - - for(auto ipk=range.ixy_0; ipk0) - { - a = a_t; - b = b_t; - - // a = ((aa_max))?a_0:a; - // b = ((bb_max))?b_0:b; - - a = min(max(a, a_min), a_max); - b = min(max(b, b_min), b_max); - - chi2 = get_chi2(R2, Ixy, a, b); - } - - lambda = (rho>1e-3)?(::fmax(lambda/lambda_f, 1e-7)):(::fmin(lambda*lambda_f, 1e+7)); - - // a = min(max(a, a_min), a_max); - // b = min(max(b, b_min), b_max); - - // if (fabs(d_b/b) &stream, Regions ®ions, TVector_r &x, TVector_r &y, - TVector_r &A, TVector_r &S, T Bg, int niter, T d_error) - { - auto image_s = gauss_sp(stream, x, y, A, S, Bg); - - auto thr_fit_x_y_0 = [&](const Range_2d &range) - { - int m_max = regions.m_max; - int n_max = 2; - - TVector_r Jx(m_max); - TVector_r Jy(m_max); - TVector_r d_Ixy(m_max); - - auto solve_x_y = [](int m, TVector_r &Jx, TVector_r &Jy, TVector_r &d_Ixy, T &d_x, T &d_y) - { - T sx1x1 = 0; - T sx2x2 = 0; - T sx1x2 = 0; - T sx1y = 0; - T sx2y = 0; - for (auto ixy = 0; ixy < m; ixy++) - { - T x1 = Jx[ixy]; - T x2 = Jy[ixy]; - T y = d_Ixy[ixy]; - - sx1x1 += x1*x1; - sx2x2 += x2*x2; - sx1x2 += x1*x2; - sx1y += x1*y; - sx2y += x2*y; - } - sx1x1 *= 1.001; - sx2x2 *= 1.001; - - T det = sx1x1*sx2x2 - sx1x2*sx1x2; - d_x = (sx2x2*sx1y - sx1x2*sx2y)/det; - d_y = (sx1x1*sx2y - sx1x2*sx1y)/det; - }; - - for(auto ipk=range.ixy_0; ipk p(x_0, y_0); - r2d p_0 = p; - r2d p_min(p.x-dxy, p.y-dxy); - r2d p_max(p.x+dxy, p.y+dxy); - - int m = Ixy.size(); - int n = 2; - - TVector_r d_abxy(n); - for (auto iter = 0; iter(d_x, d_y); - - T ff = 0.5; - p.x = ((p.xp_max.x))?p_0.x:p_0.x+ff*(p.x-p_0.x); - p.y = ((p.yp_max.y))?p_0.y:p_0.y+ff*(p.y-p_0.y); - - T d_xy = sqrt(d_x*d_x+d_y*d_y); - if (d_xy &stream, Regions ®ions, TVector_r &x, TVector_r &y, - TVector_r &A, TVector_r &A_min, TVector_r &A_max, TVector_r &S, TVector_r &S_min, - TVector_r &S_max, T Bg, int niter, T d_error) - { - auto image_s = gauss_sp(stream, x, y, A, S, Bg); - - auto thr_fit_a_b_x_y_0 = [&](const Range_2d &range) - { - lapack::FLSF flsf; - - int m_max = regions.m_max; - int n_max = 4; - - TVector_r M(m_max*n_max); - TVector_r d_Ixy(m_max); - - for(auto ipk=range.ixy_0; ipk p(x_0, y_0); - r2d p_0 = p; - r2d p_min(p.x-dxy, p.y-dxy); - r2d p_max(p.x+dxy, p.y+dxy); - - int m = Ixy.size(); - int n = 4; - - TVector_r d_abxy(n); - for (auto iter = 0; iter(d_abxy[2], d_abxy[3]); - - T ff = 0.75; - a = ((aa_max))?a_0:a_0+ff*(a-a_0); - b = ((bb_max))?b_0:b_0+ff*(b-b_0); - p.x = ((p.xp_max.x))?p_0.x:p_0.x+ff*(p.x-p_0.x); - p.y = ((p.yp_max.y))?p_0.y:p_0.y+ff*(p.y-p_0.y); - - if (fabs(d_abxy[1]/b) &stream, Regions ®ions, TVector_r &x_i, TVector_r &y_i, - TVector_r &A_i, TVector_r &A_min, TVector_r &A_max, TVector_r &S_i, TVector_r &S_min, - TVector_r &S_max, T Bg, int niter, T d_error) - { - auto image_s = gauss_sp(stream, x, y, A, S, Bg); - - int m_max = regions.m_max; - int n_max = 4*regions.n_max; - - auto thr_fit_a_b_x_y = [&](const Range_2d &range) - { - TVector_r d_beta(n_max); - TVector_r beta(n_max); - TVector_r beta_0(n_max); - TVector_r beta_min(n_max); - TVector_r beta_max(n_max); - - lapack::FLSF flsf; - - auto dgaussian = [](int n, TVector_r &beta, TVector_r &Rx, TVector_r &Ry, TVector_r &J, TVector_r &d_Ixy) - { - int m = Rx.size(); - int npn = n/4; - for (auto ip = 0; ip < npn; ip++) - { - int idx_p = 4*ip; - - r2d p(beta[idx_p+0], beta[idx_p+1]); - T a = beta[idx_p+2]; - T b = beta[idx_p+3]; - T r2_lim = pow(4*b, 2); - T c_alpha = 0.5/pow(b, 2); - T c_b = a/pow(b, 3); - T c_xy = a/pow(b, 2); - for (auto im = 0; im < m; im++) - { - T rx = Rx[im]-p.x; - T ry = Ry[im]-p.y; - T r2 = rx*rx + ry*ry; - if (r2 < r2_lim) - { - T f = exp(-c_alpha*r2); - J[(idx_p + 0)*m + im] = c_xy*rx*f; - J[(idx_p + 1)*m + im] = c_xy*ry*f; - J[(idx_p + 2)*m + im] = f; - J[(idx_p + 3)*m + im] = c_b*r2*f; - d_Ixy[im] -= a*f; - } - } - } - }; - - auto x = x_i; - auto y = y_i; - auto A = A_i; - auto S = S_i; - for (auto ipk = range.ixy_0; ipk < range.ixy_e; ipk++) - { - TVector_r &Rx = regions[ipk].Rx; - TVector_r &Ry = regions[ipk].Ry; - - TVector_r xn = neigh.select(ipk, x, regions[ipk].Rx_sf, regions[ipk].Rxy_sc); - TVector_r yn = neigh.select(ipk, y, regions[ipk].Ry_sf, regions[ipk].Rxy_sc); - TVector_r An = neigh.select(ipk, A, 0, regions[ipk].Ixy_sc); - TVector_r Sn = neigh.select(ipk, S, 0, regions[ipk].Rxy_sc); - - TVector_r Ixy = regions[ipk].sft_Ixy(grid_2d, image_s, xn, yn, An, Sn); - - for (auto ipn = 0; ipn < xn.size(); ipn++) - { - int idx_p = 4*ipn; - - beta_0[idx_p + 0] = xn[ipn]; - beta_0[idx_p + 1] = yn[ipn]; - beta_0[idx_p + 2] = An[ipn]; - beta_0[idx_p + 3] = Sn[ipn]; - - T dxy = ::fmax(1.1*grid_2d.dR_min()/regions[ipk].Rxy_sc, 0.25*Sn[ipn]); - r2d p(xn[ipn], yn[ipn]); - - beta_min[idx_p + 0] = p.x-dxy; - beta_min[idx_p + 1] = p.y-dxy; - beta_min[idx_p + 2] = (A_min[ipn]-Bg)/regions[ipk].Ixy_sc; - beta_min[idx_p + 3] = S_min[ipn]/regions[ipk].Rxy_sc; - - beta_max[idx_p + 0] = p.x+dxy; - beta_max[idx_p + 1] = p.y+dxy; - beta_max[idx_p + 2] = (A_max[ipn]-Bg)/regions[ipk].Ixy_sc; - beta_max[idx_p + 3] = S_max[ipn]/regions[ipk].Rxy_sc; - } - - beta = beta_0; - - int m = Rx.size(); - int n = 4*xn.size(); - - for (auto iter = 0; iter < niter; iter++) - { - TVector_r J(m*n, 0); - TVector_r d_Ixy = Ixy; - - dgaussian(n, beta, Rx, Ry, J, d_Ixy); - - flsf(m, n, J.data(), d_Ixy.data(), d_beta.data()); - - thrust::transform(beta.begin(), beta.end(), d_beta.begin(), beta.begin(), thrust::plus()); - - for (auto ip = 0; ip < n; ip++) - { - beta[ip] = ((beta[ip]beta_max[ip]))?beta_0[ip]:beta[ip]; - } - - if (fabs(d_beta[3]/beta[3]) stream; - FFT fft_2d; - - Grid_2d grid_2d; - TVector_r image; - TVector_r image_den; - vector mask; - - T sigma; - T thres; - T d_error; - int niter; - - T ref_mean; - T ref_std; - T image_mean; - T image_std; - - T radius_n; - Neigh_2d neigh; - Regions regions; - Range_2d range_ct; - - TVector_r x; - TVector_r y; - TVector_r A; - TVector_r S; - T bg; - - TVector_r A_min; - TVector_r A_max; - TVector_r S_min; - TVector_r S_max; - }; - -} // namespace mt +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PEAK_FINDING_H + #define PEAK_FINDING_H + + #include + #include + + #include + #include "math_mt.h" + #include "types.cuh" + #include "type_traits_gen.h" + #include "cgpu_fft.cuh" + #include "cgpu_stream.cuh" + #include "lapack.hpp" + #include "box_occ.hpp" + #include "cgpu_classes.cuh" + #include "cpu_fcns_image.hpp" + + namespace mt + { + template + class Peak_Finding + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using size_type = dt_uint64; + + Peak_Finding(): sigma(1.0), thres(0.5), niter(10), d_error(1e-3), + image_mean(0), image_std(1), radius_n(6*sigma), ref_mean(500), ref_std(80) {}; + + Peak_Finding(Grid_2d& grid_i, TVctr_r &image_i, T sigma_i, T thres_i, dt_int32 niter_i) + { + operator()(grid_i, image_i, sigma_i, thres_i, niter_i); + } + + void cleanup() + { + fft_2d.cleanup(); + } + + void operator()(Grid_2d& grid_i, TVctr_r &image_i, T sigma_i, T thres_i, dt_int32 niter_i) + { + grid_2d = grid_i; + sigma = sigma_i; + thres = thres_i; + niter = niter_i; + d_error = 1e-4; + + ref_mean = 500; + ref_std = 80; + radius_n = 6*sigma; + + stream.resize(4); + fft_2d.create_plan_2d(grid_2d.ny, grid_2d.nx, stream.size()); + + // image_mean and image_std are defined here + image = scale_in_image(stream, image_i); + } + + void find() + { + // denoise im + dt_int32 nkr_w = max(1, static_cast(::floor(sigma/2+0.5))); + dt_int32 nkr_m = max(1, static_cast(::floor(sigma/3+0.5))); + image_den = fltr_poiss_nois_2d(stream, grid_2d, image, nkr_w, nkr_m); + + // get peak signal to noise ratio + auto PSNR = fcn_get_psnr(stream, image, image_den); + + // deconvolute in image + auto image_dcon = image; + Gauss_Dcv_2d gauss_dcv_2d(&stream, &fft_2d, grid_2d); + gauss_dcv_2d(sigma, PSNR, image_dcon); + + thrust::for_each(image_dcon.begin(), image_dcon.end(), [&](T& v){ v = (v<0)?0:v; }); + + // get background + dt_int32 nkr = static_cast(::round(5.0*sigma/grid_2d.dR_min())); + auto image_thr = fcn_morp_op_open(stream, grid_2d.ny, grid_2d.nx, image_dcon, nkr); + + Gauss_Cv_2d gauss_cv_2d(&stream, &fft_2d, grid_2d); + gauss_cv_2d(sigma, image_thr); + + // background substraction + thrust::transform(image_dcon.begin(), image_dcon.end(), image_thr.begin(), + image_thr.begin(), [](const T& a, const T&b){ return ::fmax(a-b, T(0)); }); + + // fast peak finding + fast_peak_finding(stream, image_thr, x, y); + + // deleting close neighbors + neigh.delete_points(x, y, grid_2d); + + // set output data + A.resize(x.size()); + std::fill(A.begin(), A.end(), T(0)); + + A_min.resize(x.size()); + std::fill(A_min.begin(), A_min.end(), T(0)); + + A_max.resize(x.size()); + std::fill(A_max.begin(), A_max.end(), T(0)); + + S.resize(x.size()); + std::fill(S.begin(), S.end(), T(0)); + + S_min.resize(x.size()); + std::fill(S_min.begin(), S_min.end(), T(0)); + + S_max.resize(x.size()); + std::fill(S_max.begin(), S_max.end(), T(0)); + + bg = 0; + + dt_int32 ibor = max(10, grid_2d.r_2_ir_cds_dr_min(3*sigma)); + range_ct.ix_0 = ibor; + range_ct.ix_e = grid_2d.nx-ibor; + range_ct.iy_0 = ibor; + range_ct.iy_e = grid_2d.ny-ibor; + } + + void fit() + { + // get neighbors + neigh(stream, x, y, radius_n); + + // get image mask + mask = get_mask(stream, neigh, x, y); + + // set bg values + T bg_min, bg_max; + set_init_bg_values(stream, mask, image_den, x, y, bg, bg_min, bg_max); + + // set A values + set_init_A_values(stream, image_den, neigh, x, y, A, A_min, A_max, bg); + + // get first approximations + S = fit_b_0(stream, mask, image, x, y, A, sigma, bg, 15, d_error); + A = fit_a_0(stream, mask, image, x, y, A, A_min, A_max, S, bg); + + for(auto ipk = 0; ipk < x.size(); ipk++) + { + S_min[ipk] = ::fmax(0.5*grid_2d.dR_min(), 0.25*S[ipk]); + S_max[ipk] = ::fmin(0.9*neigh.d_min(ipk), 1.5*S[ipk]); + } + + region.set(stream, grid_2d, image, neigh, x, y, 1, 1); + for(auto it = 0; it < 1; it++) + { + fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + } + + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // for(auto it = 0; it < 3; it++) + // { + // fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + // } + // bg = fit_c_0(stream, image, x, y, A, S, bg, bg_min, bg_max); + + for(auto it = 0; it < niter; it++) + { + region.set(stream, grid_2d, image, neigh, x, y, 1, 0.4); + fit_x_y_0(stream, region, x, y, A, S, bg, 10, d_error); + + region.set(stream, grid_2d, image, neigh, x, y, 1, 1); + fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + } + + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // fit_a_b_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // fit_a_b_x_y_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // for(auto it = 0; it < 3; it++) + // { + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // fit_a_b_x_y_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // } + // neigh(stream, x, y, radius_n); + // region.set(stream, grid_2d, image, neigh, x, y, 1, 1.0); + // fit_a_b_x_y(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 10, d_error); + // fit_a_b_x_y_0(stream, region, x, y, A, A_min, A_max, S, S_min, S_max, bg, 20, d_error); + } + + void get_data(TVctr_r &x_o, TVctr_r &y_o, TVctr_r &A_o, TVctr_r &S_o, T& bg_o) + { + dt_int32 npeaks = x.size(); + + x_o.resize(npeaks); + y_o.resize(npeaks); + A_o.resize(npeaks); + S_o.resize(npeaks); + + T sf = ref_std/image_std; + for(auto idx=0; idx& grid_2d, TVctr_r &Im_s, T x, T y) + { + TVctr_r v = Ixy; + + T R2_max = pow(R_max, 2); + + R_2d p(x, y); + auto range = grid_2d.region_ind(p, R_max); + dt_int32 iv = 0; + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + v[iv++] -= Im_s[grid_2d.sub_2_ind(ix, iy)]/Ixy_sc; + } + } + } + return v; + } + + TVctr_r sft_Ixy(Grid_2d& grid_2d, TVctr_r &Im_s, T x, T y, T a, T s) + { + TVctr_r v = sub_region_to_Ixy(grid_2d, Im_s, x*Rxy_sc+Rx_sf, y*Rxy_sc+Ry_sf); + + T alpha = 0.5/pow(s, 2); + T r2_l = pow(4.0*s, 2); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x; + T ry = Ry[im]-y; + T r2 = rx*rx+ry*ry; + if (r2& grid_2d, TVctr_r &Im_s, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + TVctr_r v = sub_region_to_Ixy(grid_2d, Im_s, x[0]*Rxy_sc+Rx_sf, y[0]*Rxy_sc+Ry_sf); + + for(auto ip = 0; ip < x.size(); ip++) + { + T a = A[ip]; + T b = S[ip]; + T alpha = 0.5/pow(b, 2); + T r2_l = pow(4.0*b, 2); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x[ip]; + T ry = Ry[im]-y[ip]; + T r2 = rx*rx+ry*ry; + if (r2 sft_x_y(T x, T y) const + { + x = sft_Rx(x); + y = sft_Ry(y); + return R_2d(x, y); + } + }; + + struct Regions + { + public: + using size_type = dt_uint64; + + dt_int32 m_max; + dt_int32 n_max; + Regions():m_max(1), n_max(1) {} + + size_type size() const + { + return reg.size(); + } + + void set(Stream& stream, const Grid_2d& grid_i, TVctr_r &Im_i, + Neigh_2d& neigh, TVctr_r &x, TVctr_r &y, dt_int32 iradius=1, T ff=0.5) + { + grid_2d = grid_i; + reg.resize(x.size()); + T R_min = 3.1*grid_2d.dR_min(); + + auto sel_radius = [&neigh, R_min, ff](dt_int32 ipk, dt_int32 iradius)->T + { + T radius = 0; + switch (iradius) + { + case 1: + radius = ::fmax(R_min, ff*neigh.d_min(ipk)); + break; + case 2: + radius = neigh.d_max(ipk) + ff*neigh.d_min(ipk); + break; + } + return radius; + }; + + auto thr_select_cir_reg = [&](const iThread_Rect_2d& range) + { + for(auto ipk = range.ind_0; ipk < range.ind_e; ipk++) + { + R_2d p(x[ipk], y[ipk]); + T radius = sel_radius(ipk, iradius); + reg[ipk] = select_cir_reg(Im_i, p, radius); + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_select_cir_reg); + + T d_max = 0; + n_max = 1; + for(auto ipk = 0; ipk < x.size(); ipk++) + { + T radius = sel_radius(ipk, iradius); + d_max = max(d_max, radius); + n_max = max(n_max, neigh.size(ipk)); + } + d_max += 3*grid_i.dR_min(); + m_max = static_cast(std::round(c_pi*pow(d_max, 2)/pow(grid_i.dR_min(), 2))); + } + + Region_Rad_2d& operator[](const dt_int32 i){ return reg[i]; } + + const Region_Rad_2d& operator[](const dt_int32 i) const { return reg[i]; } + private: + vector reg; + Grid_2d grid_2d; + + Region_Rad_2d select_cir_reg(TVctr_r &Im, R_2d p, T radius) + { + T R_max = radius; + T R2_max = pow(R_max, 2); + + auto range = grid_2d.region_ind(p, R_max); + + Region_Rad_2d region; + region.clear(); + region.reserve(range.ind_e); + + // select circular region + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2_d = grid_2d.r2(ix, iy, p.x, p.y); + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + if (r2_d < R2_max) + { + region.Rx.push_back(grid_2d.rx(ix)); + region.Ry.push_back(grid_2d.ry(iy)); + region.R2.push_back(r2_d); + region.Ixy.push_back(Im[ixy]); + } + } + } + + region.R_max = R_max; + region.Rx_sf = p.x; + region.Ry_sf = p.y; + region.Rxy_sc = R_max; + + // really important that Ixy_mean is zero if not + // we have to change our reference system to fit the parameters + region.Ixy_sf = 0; + region.Ixy_sc = sqrt(fcn_variance(region.Ixy)); + // shift and fcn_scale + dt_int32 m = region.Ixy.size(); + for(auto ixy = 0; ixy < m; ixy++) + { + region.Rx[ixy] = (region.Rx[ixy]-region.Rx_sf)/region.Rxy_sc; + region.Ry[ixy] = (region.Ry[ixy]-region.Ry_sf)/region.Rxy_sc; + region.R2[ixy] = region.R2[ixy]/pow(region.Rxy_sc, 2); + region.Ixy[ixy] = (region.Ixy[ixy]-region.Ixy_sf)/region.Ixy_sc; + } + + region.shrink_to_fit(); + return region; + } + }; + + TVctr_r scale_in_image(Stream& stream, TVctr_r &image_i) + { + fcn_mean_var(stream, image_i, image_mean, image_std); + image_std = sqrt(image_std); + + auto thr_scale = [=](const iThread_Rect_2d& range, TVctr_r &image_i, TVctr_r &image_o) + { + for(auto ixy = range.ind_0; ixy < range.ind_e; ixy++) + { + T v = image_i[ixy]; + v = (v-image_mean)/image_std; + v = v*ref_std + ref_mean; + image_o[ixy] = ::fmax(v, 4); + } + }; + + TVctr_r image_o(image_i.size()); + stream.set_n_stream_act(grid_2d.nx); + stream.set_grid(grid_2d.nx, grid_2d.ny); + stream.exec(thr_scale, image_i, image_o); + + return image_o; + } + + void fast_peak_finding(Stream& stream, TVctr_r &image, TVctr_r &x, TVctr_r &y) + { + auto Im_minmax = fcn_minmax_element(image.begin(), image.end()); + + T thres_n = *(Im_minmax.first) + thres*(*(Im_minmax.second)-*(Im_minmax.first)); + + image = fcn_threshold_max(stream, image, thres_n); + + // local maximum + auto krn_maximum = [thres_n](const dt_int32& ix, const dt_int32& iy, Grid_2d& grid_2d, TVctr_r &Im, R_2d& peak)->dt_bool + { + auto v = Im[grid_2d.sub_2_ind(ix, iy)]; + peak = R_2d(grid_2d.rx(ix), grid_2d.ry(iy)); + + if (v <= thres_n) + { + return false; + } + + T v1 = Im[grid_2d.sub_2_ind(ix-1, iy-1)]; + T v2 = Im[grid_2d.sub_2_ind(ix, iy-1)]; + T v3 = Im[grid_2d.sub_2_ind(ix+1, iy-1)]; + + T v4 = Im[grid_2d.sub_2_ind(ix-1, iy)]; + T v6 = Im[grid_2d.sub_2_ind(ix+1, iy)]; + + T v7 = Im[grid_2d.sub_2_ind(ix-1, iy+1)]; + T v8 = Im[grid_2d.sub_2_ind(ix, iy+1)]; + T v9 = Im[grid_2d.sub_2_ind(ix+1, iy+1)]; + + T v_s = v1+v2+v3+v4+v+v6+v7+v8+v9; + + T x1 = grid_2d.rx(ix-1); + T x2 = grid_2d.rx(ix); + T x3 = grid_2d.rx(ix+1); + + T y1 = grid_2d.ry(iy-1); + T y2 = grid_2d.ry(iy); + T y3 = grid_2d.ry(iy+1); + + T x = v1*x1 + v2*x2 + v3*x3 + v4*x1 + v*x2 + v6*x3 + v7*x1 + v8*x2 + v9*x3; + T y = v1*y1 + v2*y2 + v3*y3 + v4*y1 + v*y2 + v6*y3 + v7*y1 + v8*y2 + v9*y3; + peak = R_2d(x, y)/v_s; + + return (v1<=v) && (v2<=v) && (v3<=v) && (v4<=v) && (v6<=v) && (v7<=v) && (v8<=v) && (v9<=v); + }; + + auto npeaks_m = static_cast(::ceil(grid_2d.bs_x*grid_2d.bs_y/(c_pi*sigma*sigma))); + + x.reserve(2*npeaks_m); + y.reserve(2*npeaks_m); + + // get local peaks + auto thr_peaks = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, TVctr_r &image, TVctr_r &x_o, TVctr_r &y_o) + { + TVctr_r x; + x.reserve(npeaks_m); + + TVctr_r y; + y.reserve(npeaks_m); + + auto ix_0 = 1 + range.ix_0; + auto ix_e = 1 + range.ix_e; + auto iy_0 = 1 + range.iy_0; + auto iy_e = 1 + range.iy_e; + + for(auto ix = ix_0; ix < ix_e; ix++) + { + for(auto iy = iy_0; iy < iy_e; iy++) + { + R_2d peak; + if (krn_maximum(ix, iy, grid_2d, image, peak)) + { + x.push_back(peak.x); + y.push_back(peak.y); + } + } + } + + stream.stream_mutex.lock(); + x_o.insert(x_o.end(), x.begin(), x.end()); + y_o.insert(y_o.end(), y.begin(), y.end()); + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(grid_2d.nx-2); + stream.set_grid(grid_2d.nx-2, grid_2d.ny-2); + stream.exec(thr_peaks, grid_2d, image, x, y); + + x.shrink_to_fit(); + y.shrink_to_fit(); + } + + void set_init_bg_values(Stream& stream, vector& mask, TVctr_r &image, + TVctr_r &x, TVctr_r &y, T& bg, T& bg_min, T& bg_max) + { + T R_max = 2.5*grid_2d.dR_min(); + T peak_min = image[grid_2d.rv_2_ir_bfds(x[0], y[0])]; + + auto get_mean_peak = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, const TVctr_r &image)->T + { + T R2_max = pow(R_max, 2); + auto range = grid_2d.region_ind(p, R_max); + T Ixy_mean = 0; + dt_int32 n_Ixy_mean = 0; + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + Ixy_mean += image[grid_2d.sub_2_ind(ix, iy)]; + n_Ixy_mean++; + } + } + } + Ixy_mean /= n_Ixy_mean; + return Ixy_mean; + }; + + auto thr_min_peak = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, vector& mask, TVctr_r &image, + TVctr_r &x, TVctr_r &y, T& peak_min) + { + T peak_min_t = 100*image[grid_2d.rv_2_ir_bfds(x[0], y[0])]; + for(auto ipk=range.ind_0; ipk p(x[ipk], y[ipk]); + if (mask[grid_2d.rv_2_ir_bfds(p.x, p.y)]) + { + peak_min_t = ::fmin(peak_min_t, get_mean_peak(p, R_max, grid_2d, image)); + } + } + stream.stream_mutex.lock(); + peak_min = ::fmin(peak_min, peak_min_t); + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_min_peak, grid_2d, mask, image, x, y, peak_min); + + // fcn_mean bellow thr + T I_min = 0; + T I_mean = 0; + T I_std = 0; + T I_low = 0; + for(auto it=0; it<2; it++) + { + I_min = peak_min; + T I_sum = 0; + T I_sum_ee = 0; + T I_sum2 = 0; + T I_sum2_ee = 0; + dt_int32 I_c = 0; + for(auto ix = range_ct.ix_0; ix < range_ct.ix_e; ix++) + { + for(auto iy = range_ct.iy_0; iy < range_ct.iy_e; iy++) + { + T v = image[grid_2d.sub_2_ind(ix, iy)]; + if ((v < peak_min) && (I_low < v)) + { + fcn_kh_sum(I_sum, v, I_sum_ee); + fcn_kh_sum(I_sum2, v*v, I_sum2_ee); + I_min = ::fmin(I_min, v); + I_c++; + } + } + } + I_mean = I_sum/I_c; + I_std = sqrt(fabs(I_sum2/I_c-I_mean*I_mean)); + peak_min = I_mean; + I_low = I_mean-3*I_std; + } + bg = ::fmax(0, I_mean - I_std); + // bg_o = (0-image_mean)*sf + ref_mean; + bg_min = ::fmax(I_mean-4*I_std, I_min-0.5*I_std); + bg_max = I_mean+0.5*I_std; + } + + void set_init_A_values(Stream& stream, TVctr_r &image, Neigh_2d& neigh, + TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max, T Bg) + { + auto thr_A_values = [Bg](const iThread_Rect_2d& range, Grid_2d& grid_2d, TVctr_r &image, + Neigh_2d& neigh, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max) + { + auto get_A_values = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, + const TVctr_r &image, T& A, T& A_min, T& A_max) + { + T R2_max = pow(R_max, 2); + T R2_peak_max = pow(1.75*grid_2d.dR_min(), 2); + + auto range = grid_2d.region_ind(p, R_max); + + T Ixy_min = image[grid_2d.rv_2_ir_bfds(p.x, p.y)]; + + T Ixy_peak = 0; + dt_int32 Ixy_peak_c = 0; + + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + T v = image[grid_2d.sub_2_ind(ix, iy)]; + Ixy_min = (v p(x[ipk], y[ipk]); + T R_max = neigh.d_min(ipk); + get_A_values(p, R_max, grid_2d, image, A[ipk], A_min[ipk], A_max[ipk]); + A[ipk] -= Bg; + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_A_values, grid_2d, image, neigh, x, y, A, A_min, A_max); + } + + vector get_mask(Stream& stream, TVctr_r &x, TVctr_r &y, TVctr_r &S) + { + vector image(grid_2d.size(), false); + + auto set_area = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, vector& image) + { + T R2_max = pow(R_max, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + image[grid_2d.sub_2_ind(ix, iy)] = true; + } + } + } + }; + + auto thr_area = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, TVctr_r &x, TVctr_r &y, TVctr_r &S, vector& image) + { + for(auto ipk = range.ind_0; ipk < range.ind_e; ipk++) + { + R_2d p(x[ipk], y[ipk]); + T R_max = 3.5*S[ipk]; + set_area(p, R_max, grid_2d, image); + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_area, grid_2d, x, y, S, image); + + return image; + } + + vector get_mask(Stream& stream, Neigh_2d& neigh, TVctr_r &x, TVctr_r &y) + { + vector image(grid_2d.size(), false); + + auto set_area = [](const R_2d& p, const T& R_max, const Grid_2d& grid_2d, vector& image) + { + T R2_max = pow(R_max, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T R2_d = grid_2d.r2(ix, iy, p.x, p.y); + if (R2_d < R2_max) + { + image[grid_2d.sub_2_ind(ix, iy)] = true; + } + } + } + }; + + auto thr_area = [&](const iThread_Rect_2d& range, Grid_2d& grid_2d, Neigh_2d& neigh, TVctr_r &x, TVctr_r &y, vector& image) + { + for(auto ipk=range.ind_0; ipk p(x[ipk], y[ipk]); + T R_max = neigh.d_min(ipk); + set_area(p, R_max, grid_2d, image); + } + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_area, grid_2d, neigh, x, y, image); + + // left + for(auto ix = 0; ix < range_ct.ix_0; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + // right + for(auto ix = range_ct.ix_e; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < grid_2d.ny; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + // top + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = 0; iy < range_ct.iy_0; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + // bottom + for(auto ix = 0; ix < grid_2d.nx; ix++) + { + for(auto iy = range_ct.iy_e; iy < grid_2d.ny; iy++) + { + image[grid_2d.sub_2_ind(ix, iy)] = false; + } + } + + return image; + } + + void set_mask_and_scale(Stream& stream, vector& mask, + TVctr_r &image, TVctr_r &image_m, T& image_m_sc) + { + image_m.resize(image.size()); + T image_sum = 0; + T image2_sum = 0; + dt_int32 c_image_sum = 0; + + // mask image + auto thr_mask = [&](const iThread_Rect_2d& range, TVctr_r &image, + TVctr_r &image_m, dt_int32& c_image_sum, T& image_sum, T& image2_sum) + { + // set mask and get fcn_mean and std + T im_sum = 0; + T im_sum_ee = 0; + T im2_sum = 0; + T im2_sum_ee = 0; + dt_int32 c_sum = 0; + for(auto ixy = range.ind_0; ixy& mask, TVctr_r &image) + { + for(auto ixy = range.ind_0; ixy& stream, TVctr_r &image, TVctr_r &image_m, T& image_m_sc) + { + image_m.resize(image.size()); + + image_m_sc = sqrt(fcn_variance(stream, image)); + + auto thr_sft_scale = [image_m_sc](const iThread_Rect_2d& range, TVctr_r &image, TVctr_r &image_m) + { + for(auto ixy = range.ind_0; ixysig_u))?s_mean:S[ipk]; + } + } + + TVctr_r gauss_sp(Stream& stream, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &S, T Bg) + { + auto thr_gauss_sp = [&stream](const Grid_2d& grid_2d, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S, T Bg) + { + dt_int32 m = grid_2d.size(); + TVctr_r Ixy(m, Bg); + + auto thr_gauss_sup = [&](const iThread_Rect_2d& range, TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + auto gaussian = [](R_2d p, T a, T b, T R_max, const Grid_2d& grid_2d, TVctr_r &Ixy) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + Ixy[grid_2d.sub_2_ind(ix, iy)] += a*exp(-c_alpha*r2); + } + } + } + }; + + TVctr_r Ixy_p(m, T(0)); + for(auto ip = range.ind_0; ip < range.ind_e; ip++) + { + R_2d p(x[ip], y[ip]); + T a = A[ip]; + T b = S[ip]; + T R_max = 4.0*b; + gaussian(p, a, b, R_max, grid_2d, Ixy_p); + } + + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + Ixy[ixy] += Ixy_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup, x, y, A, S); + return Ixy; + }; + + return thr_gauss_sp(grid_2d, x, y, A, S, Bg); + }; + + TVctr_r fit_b_0(Stream& stream, vector& mask, TVctr_r &image, + TVctr_r x, TVctr_r y, TVctr_r A, T S, T Bg, dt_int32 niter, T d_error) + { + // mask and scaling + TVctr_r Ixy; + T Ixy_sc; + set_mask_and_scale(stream, mask, image, Ixy, Ixy_sc); + + const T factor = 2; + T Rxy_sc = grid_2d.bs_max()/factor; + + Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.bs_x/Rxy_sc, grid_2d.bs_y/Rxy_sc); + + // scaling + for(auto ip = 0; ip& grid_2d, vector& mask, TVctr_r &Ixy, + TVctr_r &x, TVctr_r &y, TVctr_r &A, T& b, T b_min, T b_max, dt_int32 niter, T d_error) + { + auto dgaussian = [&mask](R_2d p, T a, T b, T R_max, const Grid_2d& grid_2d, TVctr_r &J, TVctr_r &d_Ixy) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + T c_a = a/pow(b, 3); + auto range = grid_2d.region_ind(p, R_max); + + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + if ((r2 < R2_max) && mask[ixy]) + { + T f = exp(-c_alpha*r2); + J[ixy] += c_a*r2*f; + d_Ixy[ixy] += a*f; + } + } + } + }; + + auto solve_d_b = [&mask](TVctr_r &J, TVctr_r &d_Ixy)->T + { + T sxx = 0; + T sxx_ee = 0; + T sxy = 0; + T sxy_ee = 0; + for(auto ixy = 0; ixy < d_Ixy.size(); ixy++) + { + if (mask[ixy]) + { + T x = J[ixy]; + T y = d_Ixy[ixy]; + + fcn_kh_sum(sxx, x*x, sxx_ee); + fcn_kh_sum(sxy, x*y, sxy_ee); + } + } + + return sxy/sxx; + }; + + dt_int32 m = Ixy.size(); + TVctr_r d_Ixy(m); + TVctr_r J(m); + for(auto iter = 0; iter p(x[ip], y[ip]); + T a = A[ip]; + T R_max = 4.0*b; + dgaussian(p, a, b, R_max, grid_2d, J_p, d_Ixy_p); + } + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + J[ixy] += J_p[ixy]; + d_Ixy[ixy] -= d_Ixy_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup); + + T d_b = solve_d_b(J, d_Ixy); + + b += d_b; + + b = min(max(b_min, b), b_max); + + if (fabs(d_b/b)& stream, vector& mask, TVctr_r &image, + TVctr_r x, TVctr_r y, TVctr_r A, TVctr_r &A_min, TVctr_r &A_max, TVctr_r S, T Bg) + { + // mask and scaling + TVctr_r Ixy; + T Ixy_sc; + set_mask_and_scale(stream, mask, image, Ixy, Ixy_sc); + + const T factor = 2; + T Rxy_sc = grid_2d.bs_max()/factor; + + Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.bs_x/Rxy_sc, grid_2d.bs_y/Rxy_sc); + + // scaling + for(auto ip = 0; ip& grid_2d, vector& mask, TVctr_r &Ixy, + TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + auto dgaussian = [&mask](R_2d p, T a, T b, T R_max, const Grid_2d& grid_2d, TVctr_r &J) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + if ((r2 < R2_max) && mask[ixy]) + { + J[ixy] += a*exp(-c_alpha*r2); + } + } + } + }; + + dt_int32 m = Ixy.size(); + TVctr_r J(m, T(0)); + auto thr_gauss_sup = [&](const iThread_Rect_2d& range) + { + TVctr_r J_p(m, T(0)); + for(auto ip = range.ind_0; ip < range.ind_e; ip++) + { + R_2d p(x[ip], y[ip]); + T a = A[ip]; + T b = S[ip]; + T R_max = 4.0*b; + dgaussian(p, a, b, R_max, grid_2d, J_p); + } + + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + J[ixy] += J_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup); + + T sxy = 0; + T sxy_ee = 0; + T sxx = 0; + T sxx_ee = 0; + for(auto ixy = 0; ixy < Ixy.size(); ixy++) + { + if (mask[ixy]) + { + fcn_kh_sum(sxy, Ixy[ixy]*J[ixy], sxy_ee); + fcn_kh_sum(sxx, J[ixy]*J[ixy], sxx_ee); + } + } + return sxy/sxx; + }; + + T alpha = get_a(grid_s, mask, Ixy, x, y, A, S); + for(auto ip = 0; ip < x.size(); ip++) + { + T a = A[ip]*alpha*Ixy_sc + Bg; + if ((aA_max[ip])) + { + a = A[ip]*Ixy_sc + Bg; + } + A[ip] = a-Bg; + } + return A; + }; + + T fit_c_0(Stream& stream, TVctr_r &image, TVctr_r x, TVctr_r y, + TVctr_r A, TVctr_r S, T Bg, T Bg_min, T Bg_max) + { + // mask and scaling + TVctr_r Ixy; + T Ixy_sc; + fcn_scale(stream, image, Ixy, Ixy_sc); + + const T factor = 2; + T Rxy_sc = grid_2d.bs_max()/factor; + + Grid_2d grid_s(grid_2d.nx, grid_2d.ny, grid_2d.bs_x/Rxy_sc, grid_2d.bs_y/Rxy_sc); + + // scaling + for(auto ip = 0; ip& grid_2d, vector& mask, TVctr_r &Ixy, + TVctr_r &x, TVctr_r &y, TVctr_r &A, TVctr_r &S) + { + auto dgaussian = [](const R_2d& p, const T& a, const T& b, const T& R_max, const Grid_2d& grid_2d, TVctr_r &J) + { + T R2_max = pow(R_max, 2); + T c_alpha = 0.5/pow(b, 2); + auto range = grid_2d.region_ind(p, R_max); + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + J[grid_2d.sub_2_ind(ix, iy)] += a*exp(-c_alpha*r2); + } + } + } + }; + + dt_int32 m = Ixy.size(); + TVctr_r d_Ixy = Ixy; + auto thr_gauss_sup = [&](const iThread_Rect_2d& range) + { + TVctr_r d_Ixy_p(m, T(0)); + for(auto ip = range.ind_0; ip < range.ind_e; ip++) + { + R_2d p(x[ip], y[ip]); + T a = A[ip]; + T b = S[ip]; + T R_max = 4.0*b; + dgaussian(p, a, b, R_max, grid_2d, d_Ixy_p); + } + + stream.stream_mutex.lock(); + for(auto ixy = 0; ixy < m; ixy++) + { + d_Ixy[ixy] -= d_Ixy_p[ixy]; + } + stream.stream_mutex.unlock(); + }; + + stream.set_n_stream_act(x.size()); + stream.set_grid(x.size(), 1); + stream.exec(thr_gauss_sup); + + T sxy = 0; + T sxy_ee = 0; + dt_int32 sxx = 0; + for(auto ix = range_ct.ix_0; ix < range_ct.ix_e; ix++) + { + for(auto iy = range_ct.iy_0; iy < range_ct.iy_e; iy++) + { + dt_int32 ixy = grid_2d.sub_2_ind(ix, iy); + fcn_kh_sum(sxy, d_Ixy[ixy], sxy_ee); + sxx++; + } + } + return sxy/sxx; + }; + + T c = get_c(grid_s, mask, Ixy, x, y, A, S); + c = ((cc_max))?c_0:c_0+(1.0/2.0)*(c-c_0); + return c*Ixy_sc; + }; + + void fit_a_b_0(Stream& stream, Regions ®ion, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max, TVctr_r &S, TVctr_r &S_min, + TVctr_r &S_max, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + auto thr_fit_a_b_0 = [&](const iThread_Rect_2d& range) + { + dt_int32 m_max = region.m_max; + dt_int32 n_max = 2; + + TVctr_r Ja(m_max); + TVctr_r Jb(m_max); + TVctr_r d_Ixy(m_max); + + auto solve_a_b = [](dt_int32 m, TVctr_r &Ja, TVctr_r &Jb, + TVctr_r &d_Ixy, T lambda, T& d_a, T& d_b, T& g_m, T& rho_f) + { + T sx1x1 = 0; + T sx2x2 = 0; + T sx1x2 = 0; + T sx1y = 0; + T sx2y = 0; + for(auto ixy = 0; ixy < m; ixy++) + { + T x1 = Ja[ixy]; + T x2 = Jb[ixy]; + T y = d_Ixy[ixy]; + + sx1x1 += x1*x1; + sx2x2 += x2*x2; + sx1x2 += x1*x2; + sx1y += x1*y; + sx2y += x2*y; + } + T D_a = lambda*(sx1x1 > 1e-10)?sx1x1:1; + T D_b = lambda*(sx2x2 > 1e-10)?sx2x2:1; + + sx1x1 += D_a; + sx2x2 += D_b; + + T det = sx1x1*sx2x2 - sx1x2*sx1x2; + d_a = (sx2x2*sx1y - sx1x2*sx2y)/det; + d_b = (sx1x1*sx2y - sx1x2*sx1y)/det; + + g_m = ::fmax(fabs(sx1y), fabs(sx2y)); + rho_f = d_a*(D_a*d_a + sx1y) + d_b*(D_b*d_b + sx2y); + }; + + auto get_chi2 = [](TVctr_r &R2, TVctr_r &Ixy, T a, T b)->T + { + T c_alpha = 0.5/pow(b, 2); + T chi2 = 0; + T chi2_ee = 0; + for(auto im = 0; im < R2.size(); im++) + { + T v = Ixy[im]-a*exp(-c_alpha*R2[im]); + fcn_kh_sum(chi2, v*v, chi2_ee); + } + return chi2; + }; + + for(auto ipk=range.ind_0; ipk0) + { + a = a_t; + b = b_t; + + // a = ((a < a_min)||(a>a_max))?a_0:a; + // b = ((bb_max))?b_0:b; + + a = min(max(a, a_min), a_max); + b = min(max(b, b_min), b_max); + + chi2 = get_chi2(R2, Ixy, a, b); + } + + lambda = (rho>1e-3)?(::fmax(lambda/lambda_f, 1e-7)):(::fmin(lambda*lambda_f, 1e+7)); + + // a = min(max(a, a_min), a_max); + // b = min(max(b, b_min), b_max); + + // if (fabs(d_b/b)& stream, Regions ®ion, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &S, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + auto thr_fit_x_y_0 = [&](const iThread_Rect_2d& range) + { + dt_int32 m_max = region.m_max; + dt_int32 n_max = 2; + + TVctr_r Jx(m_max); + TVctr_r Jy(m_max); + TVctr_r d_Ixy(m_max); + + auto solve_x_y = [](dt_int32 m, TVctr_r &Jx, TVctr_r &Jy, TVctr_r &d_Ixy, T& d_x, T& d_y) + { + T sx1x1 = 0; + T sx2x2 = 0; + T sx1x2 = 0; + T sx1y = 0; + T sx2y = 0; + for(auto ixy = 0; ixy < m; ixy++) + { + T x1 = Jx[ixy]; + T x2 = Jy[ixy]; + T y = d_Ixy[ixy]; + + sx1x1 += x1*x1; + sx2x2 += x2*x2; + sx1x2 += x1*x2; + sx1y += x1*y; + sx2y += x2*y; + } + sx1x1 *= 1.001; + sx2x2 *= 1.001; + + T det = sx1x1*sx2x2 - sx1x2*sx1x2; + d_x = (sx2x2*sx1y - sx1x2*sx2y)/det; + d_y = (sx1x1*sx2y - sx1x2*sx1y)/det; + }; + + for(auto ipk=range.ind_0; ipk p(x_0, y_0); + R_2d p_0 = p; + R_2d p_min(p.x-dxy, p.y-dxy); + R_2d p_max(p.x+dxy, p.y+dxy); + + dt_int32 m = Ixy.size(); + dt_int32 n = 2; + + TVctr_r d_abxy(n); + for(auto iter = 0; iter(d_x, d_y); + + T ff = 0.5; + p.x = ((p.xp_max.x))?p_0.x:p_0.x+ff*(p.x-p_0.x); + p.y = ((p.yp_max.y))?p_0.y:p_0.y+ff*(p.y-p_0.y); + + T d_xy = sqrt(d_x*d_x+d_y*d_y); + if (d_xy& stream, Regions ®ion, TVctr_r &x, TVctr_r &y, + TVctr_r &A, TVctr_r &A_min, TVctr_r &A_max, TVctr_r &S, TVctr_r &S_min, + TVctr_r &S_max, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + auto thr_fit_a_b_x_y_0 = [&](const iThread_Rect_2d& range) + { + lapack::LSF_1 fls_1; + + dt_int32 m_max = region.m_max; + dt_int32 n_max = 4; + + TVctr_r M(m_max*n_max); + TVctr_r d_Ixy(m_max); + + for(auto ipk=range.ind_0; ipk p(x_0, y_0); + R_2d p_0 = p; + R_2d p_min(p.x-dxy, p.y-dxy); + R_2d p_max(p.x+dxy, p.y+dxy); + + dt_int32 m = Ixy.size(); + dt_int32 n = 4; + + TVctr_r d_abxy(n); + for(auto iter = 0; iter(d_abxy[2], d_abxy[3]); + + T ff = 0.75; + a = ((a < a_min)||(a>a_max))?a_0:a_0+ff*(a-a_0); + b = ((bb_max))?b_0:b_0+ff*(b-b_0); + p.x = ((p.xp_max.x))?p_0.x:p_0.x+ff*(p.x-p_0.x); + p.y = ((p.yp_max.y))?p_0.y:p_0.y+ff*(p.y-p_0.y); + + if (fabs(d_abxy[1]/b)& stream, Regions ®ion, TVctr_r &x_i, TVctr_r &y_i, + TVctr_r &A_i, TVctr_r &A_min, TVctr_r &A_max, TVctr_r &S_i, TVctr_r &S_min, + TVctr_r &S_max, T Bg, dt_int32 niter, T d_error) + { + auto image_s = gauss_sp(stream, x, y, A, S, Bg); + + dt_int32 m_max = region.m_max; + dt_int32 n_max = 4*region.n_max; + + auto thr_fit_a_b_x_y = [&](const iThread_Rect_2d& range) + { + TVctr_r d_beta(n_max); + TVctr_r beta(n_max); + TVctr_r beta_0(n_max); + TVctr_r beta_min(n_max); + TVctr_r beta_max(n_max); + + lapack::LSF_1 fls_1; + + auto dgaussian = [](dt_int32 n, TVctr_r &beta, TVctr_r &Rx, TVctr_r &Ry, TVctr_r &J, TVctr_r &d_Ixy) + { + dt_int32 m = Rx.size(); + dt_int32 npn = n/4; + for(auto ip = 0; ip < npn; ip++) + { + dt_int32 idx_p = 4*ip; + + R_2d p(beta[idx_p+0], beta[idx_p+1]); + T a = beta[idx_p+2]; + T b = beta[idx_p+3]; + T r2_lim = pow(4*b, 2); + T c_alpha = 0.5/pow(b, 2); + T c_b = a/pow(b, 3); + T c_xy = a/pow(b, 2); + for(auto im = 0; im < m; im++) + { + T rx = Rx[im]-p.x; + T ry = Ry[im]-p.y; + T r2 = rx*rx + ry*ry; + if (r2 < r2_lim) + { + T f = exp(-c_alpha*r2); + J[(idx_p + 0)*m + im] = c_xy*rx*f; + J[(idx_p + 1)*m + im] = c_xy*ry*f; + J[(idx_p + 2)*m + im] = f; + J[(idx_p + 3)*m + im] = c_b*r2*f; + d_Ixy[im] -= a*f; + } + } + } + }; + + auto x = x_i; + auto y = y_i; + auto A = A_i; + auto S = S_i; + for(auto ipk = range.ind_0; ipk < range.ind_e; ipk++) + { + TVctr_r &Rx = region[ipk].Rx; + TVctr_r &Ry = region[ipk].Ry; + + TVctr_r xn = neigh.select(ipk, x, region[ipk].Rx_sf, region[ipk].Rxy_sc); + TVctr_r yn = neigh.select(ipk, y, region[ipk].Ry_sf, region[ipk].Rxy_sc); + TVctr_r An = neigh.select(ipk, A, 0, region[ipk].Ixy_sc); + TVctr_r Sn = neigh.select(ipk, S, 0, region[ipk].Rxy_sc); + + TVctr_r Ixy = region[ipk].sft_Ixy(grid_2d, image_s, xn, yn, An, Sn); + + for(auto ipn = 0; ipn < xn.size(); ipn++) + { + dt_int32 idx_p = 4*ipn; + + beta_0[idx_p + 0] = xn[ipn]; + beta_0[idx_p + 1] = yn[ipn]; + beta_0[idx_p + 2] = An[ipn]; + beta_0[idx_p + 3] = Sn[ipn]; + + T dxy = ::fmax(1.1*grid_2d.dR_min()/region[ipk].Rxy_sc, 0.25*Sn[ipn]); + R_2d p(xn[ipn], yn[ipn]); + + beta_min[idx_p + 0] = p.x-dxy; + beta_min[idx_p + 1] = p.y-dxy; + beta_min[idx_p + 2] = (A_min[ipn]-Bg)/region[ipk].Ixy_sc; + beta_min[idx_p + 3] = S_min[ipn]/region[ipk].Rxy_sc; + + beta_max[idx_p + 0] = p.x+dxy; + beta_max[idx_p + 1] = p.y+dxy; + beta_max[idx_p + 2] = (A_max[ipn]-Bg)/region[ipk].Ixy_sc; + beta_max[idx_p + 3] = S_max[ipn]/region[ipk].Rxy_sc; + } + + beta = beta_0; + + dt_int32 m = Rx.size(); + dt_int32 n = 4*xn.size(); + + for(auto iter = 0; iter < niter; iter++) + { + TVctr_r J(m*n, 0); + TVctr_r d_Ixy = Ixy; + + dgaussian(n, beta, Rx, Ry, J, d_Ixy); + + fls_1(m, n, J.data(), d_Ixy.data(), d_beta.data()); + + thrust::transform(beta.begin(), beta.end(), d_beta.begin(), beta.begin(), thrust::plus()); + + for(auto ip = 0; ip < n; ip++) + { + beta[ip] = ((beta[ip]beta_max[ip]))?beta_0[ip]:beta[ip]; + } + + if (fabs(d_beta[3]/beta[3]) stream; + FFT fft_2d; + + Grid_2d grid_2d; + TVctr_r image; + TVctr_r image_den; + vector mask; + + T sigma; + T thres; + T d_error; + dt_int32 niter; + + T ref_mean; + T ref_std; + T image_mean; + T image_std; + + T radius_n; + Neigh_2d neigh; + Regions region; + iThread_Rect_2d range_ct; + + TVctr_r x; + TVctr_r y; + TVctr_r A; + TVctr_r S; + T bg; + + TVctr_r A_min; + TVctr_r A_max; + TVctr_r S_min; + TVctr_r S_max; + }; + + } #endif \ No newline at end of file diff --git a/src/pn_fact.hpp b/src/pn_fact.hpp new file mode 100755 index 00000000..b2db5761 --- /dev/null +++ b/src/pn_fact.hpp @@ -0,0 +1,149 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PN_FACT_H + #define PN_FACT_H + + #include + #include + + #include "macros.h" + #include "const_enum.h" + + namespace mt + { + /***************************************************************************************/ + /******************** factorization of a number in small prime number ******************/ + // factorization: 2^a × 3^b × 5^c × 7^d, where a>1 + // https:// docs.nvidia.com/cuda/cufft/index.html + + struct PN_Fact + { + public: + PN_Fact() + { + load_prime_numbers(); + } + + dt_int32 operator()(dt_int64 n, eDat_Sel_Typ dst = edst_closest) + { + auto p_idx = std::min_element(pnv.begin(), pnv.end(), [n](dt_int64 p0, dt_int64 pe){ return std::abs(n-p0) < std::abs(n-pe); }); + + auto pn = static_cast(*p_idx); + + switch(dst) + { + case edst_less_than: + { + if (pn>=n) + { + pn = static_cast(*(p_idx-1)); + } + } + break; + case edst_eless_than: + { + if (pn>n) + { + pn = static_cast(*(p_idx-1)); + } + } + break; + case edst_greater_than: + { + if (pn<=n) + { + pn = static_cast(*(p_idx+1)); + } + } + break; + case edst_egreater_than: + { + if (pn(*(p_idx+1)); + } + } + break; + } + return pn; + } + + private: + std::vector pnv; + + void load_prime_numbers() + { + dt_int64 b_2 = 2; + dt_int64 b_3 = 3; + dt_int64 b_5 = 5; + dt_int64 b_7 = 7; + + dt_int32 e_2_m = 16; + dt_int32 e_3_m = 7; + dt_int32 e_5_m = 5; + dt_int32 e_7_m = 4; + + dt_int64 pn_0 = std::pow(b_2, 5); + dt_int64 pn_e = static_cast(std::pow(b_2, e_2_m)); + + // reserve enough space + pnv.reserve((e_2_m+1)*(e_3_m + 1)*(e_5_m + 1)*(e_7_m + 1)); + + // fill in first numbers + for(auto ie=1; ie<6; ie++) + { + auto p = static_cast(std::pow(b_2, ie)); + pnv.push_back(p); + } + + // calculate the other numbers + for(auto ip7=0; ip7<=e_7_m; ip7++) + { + auto p7 = static_cast(std::pow(b_7, ip7)); + + for(auto ip5=0; ip5<=e_5_m; ip5++) + { + auto p5 = static_cast(std::pow(b_5, ip5)); + + for(auto ip3=0; ip3<=e_3_m; ip3++) + { + auto p3 = static_cast(std::pow(b_3, ip3)); + + for(auto ip2=1; ip2<=e_2_m; ip2++) + { + auto p2 = static_cast(std::pow(b_2, ip2)); + + auto p = p7*p5*p3*p2; + + if ((pn_0 - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef PROJECTED_POTENTIAL_H -#define PROJECTED_POTENTIAL_H - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "quadrature.hpp" -#include "input_multislice.cuh" -#include "output_multislice.hpp" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" -#include "cgpu_fcns.cuh" -#include "spec.hpp" - -namespace mt -{ - template - class Projected_Potential: public Spec{ - public: - using size_type = std::size_t; - - static const eDevice device = dev; - - Projected_Potential(): stream(nullptr), n_atoms_s(512){} - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i) - { - Spec::set_input_data(input_multislice_i); - stream = stream_i; - - Quadrature quadrature; - quadrature(0, c_nqz, qz); // 0: int_-1^1 y(x) dx - TanhSinh quadrature - - atom_type.resize(c_nAtomsTypes); - for(auto iatom_type = 0; iatom_type::atom_type[iatom_type]); - } - - n_atoms_s = (device==e_host)?(stream->size()):512; - - int nv = max(this->input_multislice->grid_2d.nx_dRx(this->atoms.l_x_int), this->input_multislice->grid_2d.ny_dRy(this->atoms.l_y_int)); - - stream_data.resize(n_atoms_s); - - for(auto i = 0; iinput_multislice->is_subslicing()) - { - stream_data.c0[i].resize(c_nR); - stream_data.c1[i].resize(c_nR); - stream_data.c2[i].resize(c_nR); - stream_data.c3[i].resize(c_nR); - } - } - - atom_Vp_h.resize(n_atoms_s); - atom_Vp.resize(n_atoms_s); - - V_0.resize(this->input_multislice->grid_2d.nxy()); - } - - /************************Host************************/ - template - enable_if_dev_host - operator()(const T &z_0, const T &z_e, const int &iatom_0, const int &iatom_e, Vector &V) - { - auto eval_cubic_poly = [](Stream &stream, Grid_2d &grid_2d, - Vector, e_host> &atom, Vector &M_o) - { - if(stream.n_act_stream<= 0) - { - return; - } - - for(auto istream = 0; istream < stream.n_act_stream-1; istream++) - { - stream[istream] = std::thread(std::bind(host_detail::eval_cubic_poly, std::ref(stream), std::ref(grid_2d), std::ref(atom[istream]), std::ref(M_o))); - } - - host_detail::eval_cubic_poly(stream, grid_2d, atom[stream.n_act_stream-1], M_o); - - stream.synchronize(); - }; - - mt::fill(*stream, V, T(0)); - - int iatoms = iatom_0; - while (iatoms <= iatom_e) - { - stream->set_n_act_stream(iatom_e-iatoms+1); - set_atom_Vp(z_0, z_e, iatoms, stream->n_act_stream, atom_Vp); - //get_cubic_poly_coef_Vz(*stream, atom_Vp); - eval_cubic_poly(*stream, this->input_multislice->grid_2d, atom_Vp, V); - iatoms += stream->n_act_stream; - } - - stream->synchronize(); - } - - /***********************Device***********************/ - #ifdef __CUDACC__ - template - enable_if_dev_device - operator()(const T &z_0, const T &z_e, const int &iatom_0, const int &iatom_e, Vector &V) - { - auto get_eval_cubic_poly_gridBT = [](int natoms)->Grid_BT - { - Grid_BT grid_bt; - grid_bt.Blk = dim3(natoms, 1, 1); - grid_bt.Thr = dim3(c_thrnxny, c_thrnxny, 1); - - return grid_bt; - }; - - mt::fill(*stream, V, T(0)); - - int iatoms = iatom_0; - while (iatoms <= iatom_e) - { - int n_atoms = min(n_atoms_s, iatom_e-iatoms+1); - set_atom_Vp(z_0, z_e, iatoms, n_atoms, atom_Vp); - //get_cubic_poly_coef_Vz(*stream, atom_Vp_h); - - auto grid_bt = get_eval_cubic_poly_gridBT(n_atoms); - device_detail::eval_cubic_poly<<>>(this->input_multislice->grid_2d, atom_Vp, V); - - iatoms += n_atoms; - } - } - #endif - - void operator()(const int &islice_0, const int &islice_e, Vector &V) - { - if((islice_0<0) || (islice_e>=this->slicing.slice.size())) - { - mt::fill(*stream, V, 0.0); - return; - } - this->operator()(this->slicing.slice[islice_0].z_0, this->slicing.slice[islice_e].z_e, - this->slicing.slice[islice_0].iatom_0, this->slicing.slice[islice_e].iatom_e, V); - } - - void operator()(const int &islice_0, const int &islice_e) - { - this->operator()(islice_0, islice_e, V_0); - } - - void operator()(const int &islice, Vector &V) - { - this->operator()(islice, islice, V); - } - - void operator()(const int &islice) - { - this->operator()(islice, islice, V_0); - } - - template - void operator()(const int &islice, TOutput_multislice &output_multislice) - { - this->operator()(islice, islice, V_0); - mt::copy_to_host(output_multislice.stream, V_0, output_multislice.V[0]); - } - - Vector V_0; - Stream *stream; - private: - int n_atoms_s; - - struct Stream_Data - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = e_host; - - size_type size() const - { - return iv.size(); - } - - void resize(const size_type &new_size) - { - iv.resize(new_size); - v.resize(new_size); - c0.resize(new_size); - c1.resize(new_size); - c2.resize(new_size); - c3.resize(new_size); - } - - Vector, e_host> iv; - Vector, e_host> v; - Vector, e_host> c0; // zero coefficient - Vector, e_host> c1; // first coefficient - Vector, e_host> c2; // second coefficient - Vector, e_host> c3; // third coefficient - }; - - void set_atom_Vp(const T &z_0, const T &z_e, int iatoms, int n_atoms, Vector, dev> &atom_Vp) - { - for(auto istream = 0; istream < n_atoms; istream++) - { - auto iZ = (this->atoms.Z[iatoms] % 1000)-1; - auto charge = this->atoms.charge[iatoms]; - int icharge = atom_type[iZ].charge_to_idx(charge); - auto &coef = atom_type[iZ].coef[icharge]; - - atom_Vp_h[istream].charge = charge; - atom_Vp_h[istream].x = this->atoms.x[iatoms]; - atom_Vp_h[istream].y = this->atoms.y[iatoms]; - atom_Vp_h[istream].occ = this->atoms.occ[iatoms]; - atom_Vp_h[istream].R2_min = coef.R2_min(); - atom_Vp_h[istream].R2_max = coef.R2_max(); - atom_Vp_h[istream].R2 = raw_pointer_cast(coef.R2.data()); - atom_Vp_h[istream].set_ix0_ixn(this->input_multislice->grid_2d, coef.R_max); - atom_Vp_h[istream].set_iy0_iyn(this->input_multislice->grid_2d, coef.R_max); - atom_Vp_h[istream].R2_tap = coef.R2_tap(); - atom_Vp_h[istream].tap_cf = coef.tap_cf; - - if(device==e_host) - { - atom_Vp_h[istream].iv = raw_pointer_cast(stream_data.iv[istream].data()); - atom_Vp_h[istream].v = raw_pointer_cast(stream_data.v[istream].data()); - } - - if(this->input_multislice->is_subslicing()) - { - atom_Vp_h[istream].z0h = 0.5*(z_0 - this->atoms.z[iatoms]); - atom_Vp_h[istream].zeh = 0.5*(z_e - this->atoms.z[iatoms]); - atom_Vp_h[istream].split = (atom_Vp_h[istream].z0h<0) && (0 &stream, Vector, e_host> &atom_Vp) - { - if(this->input_multislice->is_subslicing()) - { - mt::linear_Vz(stream, this->input_multislice->potential_type, qz, atom_Vp); - mt::cubic_poly_coef(stream, atom_Vp); - } - } - - Q1 qz; - Vector, e_host> atom_type; // Atom types - - Stream_Data stream_data; - Vector, e_host> atom_Vp_h; - Vector, dev> atom_Vp; - }; - -} // namespace mt +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PROJECTED_POTENTIAL_H +#define PROJECTED_POTENTIAL_H + +#include "math_mt.h" +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "quad_data.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" +#include "fcns_cpu.h" +#include "fcns_gpu.h" +#include "fcns_gpu.h" +#include "spec.hpp" + +namespace mt + + template + class Projected_Potential: public Spec{ + public: + using size_type = dt_uint64; + + static const eDev device = Dev; + + Projected_Potential(): stream(nullptr), n_atoms_s(512) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i) + { + Spec::set_in_data(multem_in_parm_i); + stream = stream_i; + + Quad_Data quad_data; + quad_data(0, c_nqz, qz); // 0: int_-1^1 y(x) dx - tanh_sinh quad_data + + atom_type.resize(c_n_atom_typ); + for(auto iatom_type = 0; iatom_type::atom_type[iatom_type]); + } + + n_atoms_s = (device==edev_cpu)?(stream->size()):256; + + dt_int32 nv = max(this->multem_in_parm->grid_2d.rx_2_irx_cd(this->atoms.bs_x_int), this->multem_in_parm->grid_2d.ry_2_iry_cd(this->atoms.bs_y_int)); + + stream_data.resize(n_atoms_s); + + for(auto i = 0; imultem_in_parm->is_spec_slic_by_dz_sub()) + { + stream_data.c0[i].resize(c_nR); + stream_data.c1[i].resize(c_nR); + stream_data.c2[i].resize(c_nR); + stream_data.c3[i].resize(c_nR); + } + } + + atom_Vp_h.resize(n_atoms_s); + atom_Vp.resize(n_atoms_s); + + V_0.resize(this->multem_in_parm->grid_2d.size()); + } + + /***************************************** cpu *****************************************/ + template + enable_if_edev_cpu + operator()(const T& z_0, const T& z_e, const dt_int32& iatom_0, const dt_int32& iatom_e, Vctr& V) + { + auto fcn_eval_poly3 = [](Stream& stream, Grid_2d& grid_2d, + Vctr, edev_cpu>& atom, Vctr& mx_o) + { + if (stream.n_stream_act<= 0) + { + return; + } + + for(auto istm = 0; istm < stream.n_stream_act-1; istm++) + { + stream[istm] = std::thread(std::bind(cpu_detail::fcn_eval_poly3, std::ref(stream), std::ref(grid_2d), std::ref(atom[istm]), std::ref(mx_o))); + } + + cpu_detail::fcn_eval_poly3(stream, grid_2d, atom[stream.n_stream_act-1], mx_o); + + stream.synchronize(); + }; + + mt::fill(*stream, V, T(0)); + + dt_int32 iatoms = iatom_0; + while (iatoms <= iatom_e) + { + stream->set_n_stream_act(iatom_e-iatoms+1); + set_atom_Vp(z_0, z_e, iatoms, stream->n_stream_act, atom_Vp); + // get_cubic_poly_coef_Vz(*stream, atom_Vp); + fcn_eval_poly3(*stream, this->multem_in_parm->grid_2d, atom_Vp, V); + iatoms += stream->n_stream_act; + } + + stream->synchronize(); + } + + /*************************************** device ****************************************/ + #ifdef __CUDACC__ + template + enable_if_edev_gpu + operator()(const T& z_0, const T& z_e, const dt_int32& iatom_0, const dt_int32& iatom_e, Vctr& V) + { + auto get_eval_cubic_poly_gridBT = [](dt_int32 natoms)->D_Grid_Blk + { + D_Grid_Blk d_grid_blk; + d_grid_blk.grid = dim3(natoms, 1, 1); + d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y, 1); + + return d_grid_blk; + }; + + mt::fill(*stream, V, T(0)); + + dt_int32 iatoms = iatom_0; + while (iatoms <= iatom_e) + { + dt_int32 n_atoms = min(n_atoms_s, iatom_e-iatoms+1); + set_atom_Vp(z_0, z_e, iatoms, n_atoms, atom_Vp); + // get_cubic_poly_coef_Vz(*stream, atom_Vp_h); + + auto d_grid_blk = get_eval_cubic_poly_gridBT(n_atoms); + gpu_detail::fcn_eval_poly3<<>>(this->multem_in_parm->grid_2d, atom_Vp, V); + + iatoms += n_atoms; + } + } + #endif + + void operator()(const dt_int32& islice_0, const dt_int32& islice_e, Vctr& V) + { + if ((islice_0<0) || (islice_e>=this->slicing.slice.size())) + { + mt::fill(*stream, V, 0.0); + return; + } + this->operator()(this->slicing.slice[islice_0].z_0, this->slicing.slice[islice_e].z_e, + this->slicing.slice[islice_0].iatom_0, this->slicing.slice[islice_e].iatom_e, V); + } + + void operator()(const dt_int32& islice_0, const dt_int32& islice_e) + { + this->operator()(islice_0, islice_e, V_0); + } + + void operator()(const dt_int32& islice, Vctr& V) + { + this->operator()(islice, islice, V); + } + + void operator()(const dt_int32& islice) + { + this->operator()(islice, islice, V_0); + } + + template + void operator()(const dt_int32& islice, TOutput_multislice &output_multem) + { + this->operator()(islice, islice, V_0); + mt::cpy_to_host(output_multem.stream, V_0, output_multem.V[0]); + } + + Vctr V_0; + Stream *stream; + private: + dt_int32 n_atoms_s; + + struct Stream_Data + { + using value_type = T; + using size_type = dt_uint64; + + static const eDev device = edev_cpu; + + size_type size() const + { + return iv.size(); + } + + void resize(const size_type& new_size) + { + iv.resize(new_size); + v.resize(new_size); + c0.resize(new_size); + c1.resize(new_size); + c2.resize(new_size); + c3.resize(new_size); + } + + Vctr, edev_cpu> iv; + Vctr, edev_cpu> v; + Vctr, edev_cpu> c0; // zero coefficient + Vctr, edev_cpu> c1; // first coefficient + Vctr, edev_cpu> c2; // second coefficient + Vctr, edev_cpu> c3; // third coefficient + }; + + void set_atom_Vp(const T& z_0, const T& z_e, dt_int32 iatoms, dt_int32 n_atoms, Vctr, Dev>& atom_Vp) + { + for(auto istm = 0; istm < n_atoms; istm++) + { + auto iZ = this->atoms.Z[iatoms]-1; + auto charge = this->atoms.charge[iatoms]; + dt_int32 icharge = atom_type[iZ].charge_to_ind(charge); + auto &coef = atom_type[iZ].coef[icharge]; + + atom_Vp_h[istm].charge = charge; + atom_Vp_h[istm].x = this->atoms.x[iatoms]; + atom_Vp_h[istm].y = this->atoms.y[iatoms]; + atom_Vp_h[istm].occ = this->atoms.occ[iatoms]; + atom_Vp_h[istm].R2_min = coef.R2_min(); + atom_Vp_h[istm].R2_max = coef.R2_max(); + atom_Vp_h[istm].R2 = raw_pointer_cast(coef.R2.data()); + atom_Vp_h[istm].set_ix0_ixn(this->multem_in_parm->grid_2d, coef.R_max); + atom_Vp_h[istm].set_iy0_iyn(this->multem_in_parm->grid_2d, coef.R_max); + atom_Vp_h[istm].R2_tap = coef.R2_tap(); + atom_Vp_h[istm].coef_tap = coef.coef_tap; + + if (device==edev_cpu) + { + atom_Vp_h[istm].iv = raw_pointer_cast(stream_data.iv[istm].data()); + atom_Vp_h[istm].v = raw_pointer_cast(stream_data.v[istm].data()); + } + + if (this->multem_in_parm->is_spec_slic_by_dz_sub()) + { + atom_Vp_h[istm].z0h = 0.5*(z_0 - this->atoms.z[iatoms]); + atom_Vp_h[istm].zeh = 0.5*(z_e - this->atoms.z[iatoms]); + atom_Vp_h[istm].split = (atom_Vp_h[istm].z0h<0) && (0& stream, Vctr, edev_cpu>& atom_Vp) + { + if (this->multem_in_parm->is_spec_slic_by_dz_sub()) + { + mt::linear_Vz(stream, this->multem_in_parm->atomic_pot_parm_typ, qz, atom_Vp); + mt::fcn_vd_2_coef_poly3(stream, atom_Vp); + } + } + + Quad_Coef_1d qz; + Vctr, edev_cpu> atom_type; // Atom types + + Stream_Data stream_data; + Vctr, edev_cpu> atom_Vp_h; + Vctr, Dev> atom_Vp; + }; + +} #endif \ No newline at end of file diff --git a/src/propagator.cuh b/src/propagator.cuh old mode 100644 new mode 100755 index 7b9ccf62..acbdec7a --- a/src/propagator.cuh +++ b/src/propagator.cuh @@ -1,114 +1,113 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef PROPAGATOR_H -#define PROPAGATOR_H - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "fft.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" -#include "cgpu_fcns.cuh" - -namespace mt -{ - template - class Propagator{ - public: - using T_r = T; - using T_c = complex; - - static const eDevice device = dev; - - Propagator(): input_multislice(nullptr), stream(nullptr), fft_2d(nullptr){} - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i, FFT *fft2_i) - { - input_multislice = input_multislice_i; - stream = stream_i; - fft_2d = fft2_i; - } - - void operator()(const eSpace &space_out, T_r gxu, T_r gyu, - T_r z, Vector &psi_i, Vector &psi_o) - { - if(isZero(z)) - { - if(input_multislice->grid_2d.bwl) - { - fft_2d->forward(psi_i, psi_o); - mt::bandwidth_limit(*stream, input_multislice->grid_2d, psi_o); - - if(space_out == eS_Real) - { - fft_2d->inverse(psi_o); - } - } - else - { - if(space_out == eS_Reciprocal) - { - fft_2d->forward(psi_i, psi_o); - mt::scale(*stream, input_multislice->grid_2d.inxy(), psi_o); - } - } - } - else - { - fft_2d->forward(psi_i, psi_o); - - mt::propagate(*stream, input_multislice->grid_2d, input_multislice->get_propagator_factor(z), gxu, gyu, psi_o, psi_o); - - if(space_out == eS_Real) - { - fft_2d->inverse(psi_o, psi_o); - } - } - } - - void operator()(const eSpace &space_out, T_r gxu, T_r gyu, - T_r z, Vector &psi_io) - { - this->operator()(space_out, gxu, gyu, z, psi_io, psi_io); - } - - template - void operator()(const eSpace &space_out, T_r gxu, T_r gyu, - T_r z, TOutput_multislice &output_multislice) - { - Vector psi(input_multislice->iw_psi.begin(), input_multislice->iw_psi.end()); - mt::fft2_shift(*stream, input_multislice->grid_2d, psi); - this->operator()(space_out, gxu, gyu, z, psi); - mt::fft2_shift(*stream, input_multislice->grid_2d, psi); - mt::copy_to_host(output_multislice.stream, psi, output_multislice.psi_coh[0]); - } - - private: - Input_Multislice *input_multislice; - Stream *stream; - FFT *fft_2d; - }; - -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef PROPAGATOR_H +#define PROPAGATOR_H + +#include "math_mt.h" +#include "types.cuh" +#include "type_traits_gen.h" +#include "cgpu_stream.cuh" +#include "cgpu_fft.cuh" +#include "in_classes.cuh" +#include "output_multem.hpp" +#include "fcns_cpu.h" +#include "fcns_gpu.h" +#include "fcns_gpu.h" + +namespace mt +{ + template + class Propagator{ + public: + using T_r = T; + using T_c = complex; + + static const eDev device = Dev; + + Propagator(): multem_in_parm(nullptr), stream(nullptr), fft_2d(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + multem_in_parm = multem_in_parm_i; + stream = stream_i; + fft_2d = fft2_i; + } + + void operator()(const eSpace &space_out, T_r gxu, T_r gyu, + T_r z, Vctr& psi_i, Vctr& psi_o) + { + if (fcn_is_zero(z)) + { + if (multem_in_parm->grid_2d.bwl) + { + fft_2d->forward(psi_i, psi_o); + mt::fcn_fermi_aperture(*stream, multem_in_parm->grid_2d, psi_o); + + if (space_out == esp_real) + { + fft_2d->inverse(psi_o); + } + } + else + { + if (space_out == esp_fourier) + { + fft_2d->forward(psi_i, psi_o); + mt::fcn_scale(*stream, multem_in_parm->grid_2d.isize_r(), psi_o); + } + } + } + else + { + fft_2d->forward(psi_i, psi_o); + + mt::fcn_propagate(*stream, multem_in_parm->grid_2d, multem_in_parm->get_propagator_factor(z), gxu, gyu, psi_o, psi_o); + + if (space_out == esp_real) + { + fft_2d->inverse(psi_o, psi_o); + } + } + } + + void operator()(const eSpace &space_out, T_r gxu, T_r gyu, + T_r z, Vctr& psi_io) + { + this->operator()(space_out, gxu, gyu, z, psi_io, psi_io); + } + + template + void operator()(const eSpace &space_out, T_r gxu, T_r gyu, + T_r z, TOutput_multislice &output_multem) + { + Vctr psi(multem_in_parm->iw_psi.begin(), multem_in_parm->iw_psi.end()); + mt::fcn_fftsft_2d(*stream, multem_in_parm->grid_2d, psi); + this->operator()(space_out, gxu, gyu, z, psi); + mt::cpy_to_host(output_multem.stream, psi, output_multem.psi_coh[0]); + } + + private: + Multem_In_Parm *multem_in_parm; + Stream *stream; + FFT *fft_2d; + }; + +} + #endif \ No newline at end of file diff --git a/src/ptc_atom.h b/src/ptc_atom.h new file mode 100755 index 00000000..c90a37e6 --- /dev/null +++ b/src/ptc_atom.h @@ -0,0 +1,197 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "r_3d.h" +#include "pvctr.h" +#include "vctr_cpu.h" +#include "fcns_cpu.h" +#include "fcns_cgpu_gen.h" +#include "ptc_r_3d.h" + +/* template definition */ +namespace mt +{ + template class Ptc_s_Atom; + + template class Ptc_Atom; +} + +/* template Ptc_s_Atom */ +namespace mt +{ + template + class Ptc_s_Atom: public Ptc_3d_0 + { + public: + dt_int32 Z; + dt_float32 sigma; + dt_float32 occ; + dt_int32 tag; + dt_int32 charge; + + Ptc_s_Atom():Z(0), Ptc_s_3d_0(), sigma(0), occ(0), tag(0), charge(0) {}; + + Ptc_s_Atom(const dt_int32& Z, const T& x, const T& y, const T& z, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge); + + Ptc_s_Atom(const dt_int32& Z, const R_3d& r, + dt_float32 sigma=c_dflt_rms3d, dt_float32 occ=c_dflt_occ, dt_int32 tag=c_dflt_tag, dt_int32 charge=c_dflt_charge); + + /* constructor by pointer */ + template + Ptc_s_Atom(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0); + + /* copy constructor */ + Ptc_s_Atom(const Ptc_s_Atom& ptc_s); + + /* converting constructor */ + template + Ptc_s_Atom(const Ptc_s_Atom& ptc_s); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s); + + /* converting assignment operator */ + template + Ptc_s_Atom& operator=(const Ptc_s_Atom& ptc_s); + + template + void assign(const Ptc_s_Atom& ptc_s); + }; +} + +/* template Ptc_Atom */ +namespace mt +{ + template + class Ptc_Atom: public Ptc_R_3d + { + public: + using value_type = T; + using size_type = dt_int64; + + using Ptc_s = Ptc_s_Atom; + + mutable Vctr_cpu Z; // atomic number + mutable Vctr_cpu sigma; // 3d root fcn_mean squared displacement (rmsd) + mutable Vctr_cpu occ; // occupancy + mutable Vctr_cpu tag; // tag + mutable Vctr_cpu charge; // charge + + dt_int32 cols_used; // number of used columns + + R_2d Z_lim; + R_2d sigma_lim; + R_2d occ_lim; + R_2d tag_lim; + R_2d charge_lim; + + /************************************* constructors ************************************/ + Ptc_Atom(); + + template + Ptc_Atom(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + /* copy constructor */ + Ptc_Atom(const Ptc_Atom& ptc); + + /* converting constructor */ + template + Ptc_Atom(const Ptc_Atom& ptc); + + /******************************** assignment operators *********************************/ + /* assignment operator */ + Ptc_Atom& operator=(const Ptc_Atom& ptc); + + /* converting assignment operator */ + template + Ptc_Atom& operator=(const Ptc_Atom& ptc); + + template + void assign(const Ptc_Atom& ptc); + + /***************************************************************************************/ + virtual size_type cols() const; + + void clear(); + + void resize(size_type new_size); + + void reserve(size_type new_size); + + void shrink_to_fit(); + + void push_back(const Ptc_s& ptc_s); + + dt_float32 get_sigma(const size_type& ia) const; + + dt_float32 get_occ(const size_type& ia) const; + + dt_int32 get_tag(const size_type& ia) const; + + dt_int32 get_charge(const size_type& ia) const; + + Ptc_s get(const size_type& ia) const; + + void set(const size_type& ia, const Ptc_s& ptc_s); + + template + void set_ptc(const Ptc_Atom& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + template + void set_ptc(const pVctr_cpu_64& ptc, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=8); + + // sort by x + void sort_by_x(); + + // sort by y + void sort_by_y(); + + // sort by z + void sort_by_z(); + + // sort by idx + void sort_by_idx(const dt_int32 idx = 3); + + /***************************************************************************************/ + virtual void get_statistic(); + + // max z value within a tag + void minmax_z_by_region(const T& tag_v, T& z_min, T& z_max); + + void remove_ptc_out_z_range(const T& z_0, const T& z_e); + }; +} + +/* fcns */ +namespace mt +{ + template + void remove_ptc_out_z_range(const T& z_0, const T& z_e, Ptc_Atom& ptc); +} + +#include "detail/ptc_atom.inl" \ No newline at end of file diff --git a/src/ptc_butwth.h b/src/ptc_butwth.h new file mode 100755 index 00000000..0b6d78ba --- /dev/null +++ b/src/ptc_butwth.h @@ -0,0 +1,103 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" +#include "range_1d.h" +#include "range_2d.h" +#include "range_3d.h" + +#include "fcn_butwth.h" +#include "fcn_cos_tap.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Butwth_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Butwth_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid); + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc); + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max); + + void set_in_data(const R_xd& r, const T& a, const dt_int32& n, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T eval_r2(const T& r2) const; + }; +} + + +#include "detail/ptc_butwth.inl" \ No newline at end of file diff --git a/src/ptc_exp.h b/src/ptc_exp.h new file mode 100755 index 00000000..d63d4c2c --- /dev/null +++ b/src/ptc_exp.h @@ -0,0 +1,102 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" +#include "range_1d.h" +#include "range_2d.h" +#include "range_3d.h" + +#include "fcn_exp.h" +#include "fcn_cos_tap.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Exp_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Exp_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid); + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc); + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max); + + void set_in_data(const R_xd& r, const T& a, const T& beta, const T& r_tap, const T& r_max, const Grid_xd& grid); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T eval_r2(const T& r2) const; + }; +} + +#include "detail/ptc_exp.inl" \ No newline at end of file diff --git a/src/ptc_fermi.h b/src/ptc_fermi.h new file mode 100755 index 00000000..1b71bcfd --- /dev/null +++ b/src/ptc_fermi.h @@ -0,0 +1,103 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" +#include "range_1d.h" +#include "range_2d.h" +#include "range_3d.h" + +#include "fcn_fermi.h" +#include "fcn_cos_tap.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Fermi_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Fermi_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid); + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc); + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max); + + void set_in_data(const R_xd& r, const T& a, const T& alpha, const T& radius, const T& r_tap, const T& r_max, const Grid_xd& grid); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T eval_r2(const T& r2) const; + }; +} + + +#include "detail/ptc_fermi.inl" \ No newline at end of file diff --git a/src/ptc_gauss.h b/src/ptc_gauss.h new file mode 100755 index 00000000..cdde8945 --- /dev/null +++ b/src/ptc_gauss.h @@ -0,0 +1,103 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" +#include "range_1d.h" +#include "range_2d.h" +#include "range_3d.h" + +#include "fcn_gauss.h" +#include "fcn_cos_tap.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Gauss_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Gauss_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid); + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc); + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max); + + void set_in_data(const R_xd& r, const T& a, const T& sigma, const T& r_tap, const T& r_max, const Grid_xd& grid); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T eval_r2(const T& r2) const; + + }; +} + +#include "detail/ptc_gauss.inl" \ No newline at end of file diff --git a/src/ptc_hann.h b/src/ptc_hann.h new file mode 100755 index 00000000..dbb561f4 --- /dev/null +++ b/src/ptc_hann.h @@ -0,0 +1,102 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "grid_1d.h" +#include "grid_2d.h" +#include "grid_3d.h" +#include "range_1d.h" +#include "range_2d.h" +#include "range_3d.h" + +#include "fcn_hann.h" +#include "fcn_cos_tap.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_ELEM_DEC + #define PTC_ELEM_DEC + template class Ptc_s_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_s_Hann_xd = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_1d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_2d = Ptc_s_fcn_xd; + + template + using Ptc_s_Hann_3d = Ptc_s_fcn_xd; +} + +namespace mt +{ + template + class Ptc_s_fcn_xd: public Fcn_Elem, public Fcn_Cos_Tap, public Range + { + public: + using value_type = T; + + R_xd r; + T r_max_2; + + /************************************* constructors ************************************/ + CGPU_EXEC + Ptc_s_fcn_xd(); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max); + + Ptc_s_fcn_xd(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid); + + /* copy constructor */ + CGPU_EXEC + Ptc_s_fcn_xd(const Ptc_s_fcn_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Ptc_s_fcn_xd& operator=(const Ptc_s_fcn_xd& ptc); + + CGPU_EXEC + void assign(const Ptc_s_fcn_xd& ptc); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max); + + void set_in_data(const R_xd& r, const T& a, const T& l, const T& r_tap, const T& r_max, const Grid_xd& grid); + + CGPU_EXEC + void clear(); + + CGPU_EXEC + T eval_r2(const T& r2) const; + }; +} + +#include "detail/ptc_hann.inl" \ No newline at end of file diff --git a/src/ptc_r_1d.h b/src/ptc_r_1d.h new file mode 100755 index 00000000..7f552938 --- /dev/null +++ b/src/ptc_r_1d.h @@ -0,0 +1,188 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "pvctr.h" +#include "vctr_cpu.h" +#include "fcns_cpu.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_R_DX_DEC + #define PTC_R_DX_DEC + template class Ptc_R_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_R_1d = Ptc_R_xd; +} + +/* template specialization 1d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + R_1d bs; // box size + + mutable Vctr_cpu x; + + R_2d x_lim; + + R_1d r_mean; // mean position + R_1d r_std; // standard deviation + R_1d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(); + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x = false, dt_bool b_statistic = true); + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc); + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc); + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc); + + template + void assign(const Ptc_R_xd& ptc); + + /***************************************************************************************/ + dt_shape_st shape() const; + + size_type size() const; + + dt_int32 size_32() const; + + virtual size_type cols() const; + + dt_bool empty() const; + + void clear(); + + void resize(size_type new_size); + + void reserve(size_type new_size); + + void shrink_to_fit(); + + void push_back(const R_1d& r); + + template + void set_bs(const R_2d& bs); + + R_1d get(const size_type& ia) const; + + void set(const size_type& ia, const R_1d& r); + + R_1d get_pos(const size_type& ia) const; + + void set_pos(const size_type& ia, const R_1d& r); + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_x = false, dt_bool b_statistic = true); + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_1d& bs, dt_bool pbc_x = false, dt_bool b_statistic = true); + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=1) const; + + // sort by x + void sort_by_x(); + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx); + + /***************************************************************************************/ + T norm_2_pbc_x(const size_type& ia, const R_1d& r_0) const; + + T norm_2_pbc(const size_type& ia, const R_1d& r_0) const; + + T norm_2(const size_type& ia, const R_1d& r_0) const; + + T norm_2(const size_type& ia_0, const size_type& ia_e) const; + + /***************************************************************************************/ + T norm_pbc_x(const size_type& ia, const R_1d& r_0) const; + + T norm_pbc(const size_type& ia, const R_1d& r_0) const; + + T norm(const size_type& ia, const R_2d& r_0) const; + + T norm(const size_type& ia_0, const size_type& ia_e) const; + + /***************************************************************************************/ + virtual void get_statistic(); + + void shift(const R_1d& r_sft); + + void recenter(const R_1d& bs); + + void recenter(); + + void apply_ltf(const T mx, const R_1d& p); + }; +} + +/* fcns */ +namespace mt +{ + template + void set_ptc_pbc_x(const Ptc_R_1d& ptc_i, const dt_bool& pbc_x, const dt_bool& b_statistic, Ptc_R_1d& ptc_o); + + template + void set_ptc_pbc_x(const pVctr_cpu_64& pvctr, const dt_int64& icol, const R_1d& bs, const dt_bool& pbc_x, const dt_bool& b_statistic, Ptc_R_1d& ptc_o); + + template + void fcn_ptc_pos_statistic(Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_shift(const R_1d& r_sft, Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_recenter(const R_1d& bs, Ptc_R_1d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const T& mx, const R_1d& p, Ptc_R_1d& ptc); +} + +#include "detail/ptc_r_1d.inl" \ No newline at end of file diff --git a/src/ptc_r_2d.h b/src/ptc_r_2d.h new file mode 100755 index 00000000..113e70b6 --- /dev/null +++ b/src/ptc_r_2d.h @@ -0,0 +1,197 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "r_2d.h" +#include "pvctr.h" +#include "vctr_cpu.h" +#include "fcns_cpu.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_R_DX_DEC + #define PTC_R_DX_DEC + template class Ptc_R_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_R_2d = Ptc_R_xd; +} + +/* template specialization 2d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + R_2d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + + R_2d x_lim; + R_2d y_lim; + + R_2d r_mean; // mean position + R_2d r_std; // standard deviation + R_2d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(); + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc); + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc); + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc); + + template + void assign(const Ptc_R_xd& ptc); + + /***************************************************************************************/ + dt_shape_st shape() const; + + size_type size() const; + + dt_int32 size_32() const; + + virtual size_type cols() const; + + dt_bool empty() const; + + void clear(); + + void resize(size_type new_size); + + void reserve(size_type new_size); + + void shrink_to_fit(); + + void push_back(const R_2d& r); + + template + void set_bs(const R_2d& bs); + + R_2d get(const size_type& ia) const; + + void set(const size_type& ia, const R_2d& r); + + R_2d get_pos(const size_type& ia) const; + + void set_pos(const size_type& ia, const R_2d& r); + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_2d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=2) const; + + // sort by x + void sort_by_x(); + + // sort by y + void sort_by_y(); + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx); + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_2d& r_0) const; + + T norm_2_pbc(const size_type& ia, const R_2d& r_0) const; + + T norm_2(const size_type& ia, const R_2d& r_0) const; + + T norm_2(const size_type& ia, const T& x, const T& y) const; + + T norm_2(const size_type& ia_0, const size_type& ia_e) const; + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_2d& r_0) const; + + T norm_pbc(const size_type& ia, const R_2d& r_0) const; + + T norm(const size_type& ia, const R_2d& r_0) const; + + T norm(const size_type& ia, const T& x, const T& y) const; + + T norm(const size_type& ia_0, const size_type& ia_e) const; + + /***************************************************************************************/ + virtual void get_statistic(); + + void shift(const R_2d& r_sft); + + void recenter(const R_2d& bs); + + void recenter(); + + void apply_ltf(const Mx_2x2& mx, const R_2d& p); + + void rotate(const T& theta, const R_2d& p); + }; +} + +/* fcns 2d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_shift(const R_2d& r_sft, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_recenter(const R_2d& bs, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_2x2& mx, const R_2d& p, Ptc_R_2d& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_2d& p, Ptc_R_2d& ptc); +} + +#include "detail/ptc_r_2d.inl" \ No newline at end of file diff --git a/src/ptc_r_3d.h b/src/ptc_r_3d.h new file mode 100755 index 00000000..8c270366 --- /dev/null +++ b/src/ptc_r_3d.h @@ -0,0 +1,209 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "macros.h" +#include "math_mt.h" +#include "r_3d.h" +#include "pvctr.h" +#include "vctr_cpu.h" +#include "fcns_cpu.h" + +/* template definition */ +namespace mt +{ +#ifndef PTC_R_DX_DEC + #define PTC_R_DX_DEC + template class Ptc_R_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Ptc_R_3d = Ptc_R_xd; +} + +/* template specialization 3d */ +namespace mt +{ + template + class Ptc_R_xd + { + public: + using value_type = T; + using size_type = dt_int64; + + R_3d bs; // box size + + mutable Vctr_cpu x; + mutable Vctr_cpu y; + mutable Vctr_cpu z; + + R_2d x_lim; // x limits + R_2d y_lim; // y limits + R_2d z_lim; // z limits + + R_3d r_mean; // mean position + R_3d r_std; // standard deviation + R_3d sz; // size + + /************************************* constructors ************************************/ + Ptc_R_xd(); + + template + Ptc_R_xd(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + /* copy constructor */ + Ptc_R_xd(const Ptc_R_xd& ptc); + + /* converting constructor */ + template + Ptc_R_xd(const Ptc_R_xd& ptc); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Ptc_R_xd& operator=(const Ptc_R_xd& ptc); + + /* converting assignment operator */ + template + Ptc_R_xd& operator=(const Ptc_R_xd& ptc); + + template + void assign(const Ptc_R_xd& ptc); + + /***************************************************************************************/ + dt_shape_st shape() const; + + size_type size() const; + + dt_int32 size_32() const; + + virtual size_type cols() const; + + dt_bool empty() const; + + void clear(); + + void resize(size_type new_size); + + void reserve(size_type new_size); + + void shrink_to_fit(); + + void push_back(const R_3d& r); + + template + void set_bs(const R_3d& bs); + + R_3d get(const size_type& ia) const; + + void set(const size_type& ia, const R_3d& r); + + R_3d get_pos(const size_type& ia) const; + + void set_pos(const size_type& ia, const R_3d& r); + + template + void set_ptc(const Ptc_R_xd& ptc, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + template + void set_ptc(const pVctr_cpu_64& ptc, const dt_int64& icol, const R_3d& bs, dt_bool pbc_xy = false, dt_bool b_statistic = true); + + /* copy data to pointer */ + template + dt_int32 cpy_to_ptr(U *ptc, size_type n_ptc, dt_int32 is_0=0, dt_int32 is_e=3) const; + + // sort by x + void sort_by_x(); + + // sort by y + void sort_by_y(); + + // sort by z + void sort_by_z(); + + // sort by idx + virtual void sort_by_idx(const dt_int32& idx); + + /***************************************************************************************/ + T norm_2_pbc_xy(const size_type& ia, const R_3d& r_0) const; + + T norm_2_pbc(const size_type& ia, const R_3d& r_0) const; + + T norm_2(const size_type& ia, const R_3d& r_0) const; + + T norm_2(const size_type& ia, const T& x, const T& y, const T& z) const; + + T norm_2(const size_type& ia_0, const size_type& ia_e) const; + + /***************************************************************************************/ + T norm_pbc_xy(const size_type& ia, const R_3d& r_0) const; + + T norm_pbc(const size_type& ia, const R_3d& r_0) const; + + T norm(const size_type& ia, const R_3d& r_0) const; + + T norm(const size_type& ia, const T& x, const T& y, const T& z) const; + + T norm(const size_type& ia_0, const size_type& ia_e) const; + + /***************************************************************************************/ + virtual void get_statistic(); + + void shift(const R_3d& r_sft); + + void recenter(const R_3d& bs); + + void recenter(); + + void recenter_xy(const R_2d& bs); + + void recenter_xy(); + + void apply_ltf(const Mx_3x3& mx, const R_3d& p); + + void rotate(const T& theta, const R_3d& u_0, const R_3d& p); + }; +} + +/* fcns 3d */ +namespace mt +{ + template + void fcn_ptc_pos_statistic(Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_shift(const R_3d& r_sft, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_recenter(const R_3d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_recenter_xy(const R_2d& bs, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_apply_ltf(const Mx_3x3& mx, const R_3d& p, Ptc_R_3d& ptc); + + template + void fcn_ptc_pos_rotate(const T& theta, const R_3d& u_0, const R_3d& p, Ptc_R_3d& ptc); +} + +#include "detail/ptc_r_3d.inl" \ No newline at end of file diff --git a/src/pvctr.h b/src/pvctr.h new file mode 100755 index 00000000..f07e2778 --- /dev/null +++ b/src/pvctr.h @@ -0,0 +1,372 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is destroy software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include + +#include "macros.h" +#include "const_enum.h" +#include "type_traits_gen.h" +#include "igrid_1d.h" +#include "igrid_2d.h" +#include "igrid_3d.h" + +#ifdef __CUDACC__ + #include + #include +#endif + +/* macro definition grid-block */ +namespace mt +{ +#define FCNS_DEF_GPU_GRID_BLK_VCTR \ + dim3 d_blk_size(); \ + \ + dim3 d_grid_size(const dim3 d_grid_max = dim3(128, 1, 1)); \ + \ + /***************************************************************************************/ \ + dim3 d_blk_1d(); \ + \ + dim3 d_grid_1d(const dim3 d_grid_max = dim3(128, 1, 1)); \ + \ + D_Grid_Blk d_grid_blk_1d(const dim3 d_grid_max = dim3(128, 1, 1)); \ + \ + /***************************************************************************************/ \ + dim3 d_grid_1d_h(const dim3 d_grid_max = dim3(128, 1, 1)); \ + \ + D_Grid_Blk d_grid_blk_1d_h(const dim3 d_grid_max = dim3(128, 1, 1)); \ + \ + /***************************************************************************************/ \ + dim3 d_blk_2d(); \ + \ + /***************************************************************************************/ \ + dim3 d_grid_2d(const dim3 d_grid_max = dim3(64, 64, 0)); \ + \ + D_Grid_Blk d_grid_blk_2d(const dim3 d_grid_max = dim3(64, 64, 1)); \ + \ + /***************************************************************************************/ \ + dim3 d_grid_2d_h(const dim3 d_grid_max = dim3(64, 64, 1)); \ + \ + D_Grid_Blk d_grid_blk_2d_h(const dim3 d_grid_max = dim3(64, 64, 1)); \ + \ + /***************************************************************************************/ \ + dim3 d_blk_3d(); \ + \ + /***************************************************************************************/ \ + dim3 d_grid_3d(const dim3 d_grid_max = dim3(64, 64, 64)); \ + \ + D_Grid_Blk d_grid_blk_3d(const dim3 d_grid_max = dim3(64, 64, 64)); \ + \ + /***************************************************************************************/ \ + dim3 d_grid_3d_h(const dim3 d_grid_max = dim3(64, 64, 64)); \ + \ + D_Grid_Blk d_grid_blk_h(const dim3 d_grid_max = dim3(64, 64, 64)) +} + +/* vector forward declaration */ +namespace mt +{ +#ifndef VCTR_DEC + #define VCTR_DEC + template class Vctr; + + template class pVctr; +#endif +} + +/* derived class */ +namespace mt +{ + template + using pVctr_32 = pVctr; + + template + using pVctr_64 = pVctr; + + template + using pVctr_cpu_32 = pVctr; + + template + using pVctr_cpu_64 = pVctr; + + template + using pVctr_gpu_32 = pVctr; + + template + using pVctr_gpu_64 = pVctr; +} + +/* vector pointer */ +namespace mt +{ + template + class pVctr + { + public: + using value_type = T; + using size_type = ST; + static const eDev device = Dev; + + T* m_data; + ST m_s0; + ST m_s1; + ST m_s2; + ST m_s3; + ST m_size; + + ST m_pitch_s1; + ST m_pitch_s2; + ST m_pitch_s3; + + /************************************* constructors ************************************/ + CGPU_EXEC + pVctr(); + + CPU_EXEC + pVctr(T* data, dt_shape_64 shape); + + CGPU_EXEC + pVctr(T* data, ST s0); + + CGPU_EXEC + pVctr(T* data, ST s0, ST s1); + + CGPU_EXEC + pVctr(T* data, ST s0, ST s1, ST s2); + + CGPU_EXEC + pVctr(T* data, ST s0, ST s1, ST s2, ST s3); + + /************************** constructors *****************************/ + /* copy constructor */ + CGPU_EXEC + pVctr(const pVctr& pvctr); + + /* Move constructor */ + CGPU_EXEC + pVctr(pVctr&& pvctr); + + /* Converting constructor */ + template + CPU_EXEC + explicit pVctr(const pVctr& pvctr); + + /* constructor from Vctr */ + CPU_EXEC + explicit pVctr(const Vctr& vctr); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pVctr& operator=(const pVctr& pvctr); + + /* Move assignment operator */ + CGPU_EXEC + pVctr& operator=(pVctr&& pvctr); + + /* Converting assignment operator */ + template + CPU_EXEC + pVctr& operator=(const pVctr& pvctr); + + /* Assignment operator: Vctr -> pVctr */ + CPU_EXEC + pVctr& operator=(const Vctr& vctr); + + /**************** user define conversion operators *******************/ + pVctr ptr_32() const; + + pVctr ptr_64() const; + + operator pVctr>() const; + + CGPU_EXEC + ST s0() const; + + CGPU_EXEC + ST s1() const; + + CGPU_EXEC + ST s2() const; + + CGPU_EXEC + ST s3() const; + + CGPU_EXEC + dt_int32 s0_32() const; + + CGPU_EXEC + dt_int32 s1_32() const; + + CGPU_EXEC + dt_int32 s2_32() const; + + CGPU_EXEC + dt_int32 s3_32() const; + + CGPU_EXEC + dt_int64 s0_64() const; + + CGPU_EXEC + dt_int64 s1_64() const; + + CGPU_EXEC + dt_int64 s2_64() const; + + CGPU_EXEC + dt_int64 s3_64() const; + + CGPU_EXEC + ST s0h() const; + + CGPU_EXEC + ST s1h() const; + + CGPU_EXEC + ST s2h() const; + + CGPU_EXEC + ST s3h() const; + + dt_shape_st shape() const; + + dt_shape_st shape_2d_trs() const; + + CGPU_EXEC + ST shape_size() const; + + CGPU_EXEC + ST pitch_s1() const; + + CGPU_EXEC + ST pitch_s2() const; + + CGPU_EXEC + ST pitch_s3() const; + + CGPU_EXEC + ST size() const; + + CGPU_EXEC + dt_int32 size_32() const; + + CGPU_EXEC + dt_int64 size_64() const; + + iGrid_1d igrid_1d() const; + + iGrid_2d igrid_2d() const; + + iGrid_3d igrid_3d() const; + + iGrid_1d_64 igrid_1d_64() const; + + iGrid_2d_64 igrid_2d_64() const; + + iGrid_3d_64 igrid_3d_64() const; + + CGPU_EXEC + dt_bool empty() const; + + CGPU_EXEC + dt_bool is_1d() const; + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0) const; + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0, const ST& ix_1) const; + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0, const ST& ix_1, const ST& ix_2) const; + + CGPU_EXEC + ST sub_2_ind(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) const; + + CGPU_EXEC + T& operator[](const ST& iy); + + CGPU_EXEC + const T& operator[](const ST& iy) const; + + CGPU_EXEC + T& operator()(const ST& iy); + + CGPU_EXEC + const T& operator()(const ST& iy) const; + + CGPU_EXEC + T& operator()(const ST& ix_0, const ST& ix_1); + + CGPU_EXEC + const T& operator()(const ST& ix_0, const ST& ix_1) const ; + + CGPU_EXEC + T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2); + + CGPU_EXEC + const T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2) const; + + CGPU_EXEC + T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3); + + CGPU_EXEC + const T& operator()(const ST& ix_0, const ST& ix_1, const ST& ix_2, const ST& ix_3) const; + + CGPU_EXEC + T* begin(); + + CGPU_EXEC + const T* begin() const; + + CGPU_EXEC + T* end(); + + CGPU_EXEC + const T* end() const; + + CGPU_EXEC + T* data(); + + CGPU_EXEC + const T* data() const; + + template + U data_cast(); + + template + const U data_cast() const; + + CGPU_EXEC + T front() const; + + CGPU_EXEC + T back() const; + + #ifdef __CUDACC__ + FCNS_DEF_GPU_GRID_BLK_VCTR; + #endif + + private: + CGPU_EXEC + void set_picth(); + }; +} + +#include "detail/pvctr.inl" \ No newline at end of file diff --git a/src/quad_coef_1d.h b/src/quad_coef_1d.h new file mode 100755 index 00000000..4b30f231 --- /dev/null +++ b/src/quad_coef_1d.h @@ -0,0 +1,161 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "vctr_cpu.h" +#include "vctr_gpu.h" + +/* template definition */ +namespace mt +{ + template class pQuad_Coef_1d; + + template class Quad_Coef_1d; +} + +/* derived class pQuad_Coef_1d */ +namespace mt +{ + template + using pQuad_Coef_1d_cpu = pQuad_Coef_1d; + + template + using pQuad_Coef_1d_gpu = pQuad_Coef_1d; +} + +/* derived class Quad_Coef_1d */ +namespace mt +{ + template + using Quad_Coef_1d_cpu = Quad_Coef_1d; + + template + using Quad_Coef_1d_gpu = Quad_Coef_1d; +} + +/* class pQuad_Coef_1d */ +namespace mt +{ + template + class pQuad_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ x; + T* __restrict__ w; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pQuad_Coef_1d(); + + CGPU_EXEC + pQuad_Coef_1d(T* x, T* w, const size_type& size); + + /* copy constructor */ + CGPU_EXEC + pQuad_Coef_1d(const pQuad_Coef_1d& pcoef_quad_1d); + + /* constructor from Quad_Coef_1d */ + explicit pQuad_Coef_1d(const Quad_Coef_1d& coef_quad_1d); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pQuad_Coef_1d& operator=(const pQuad_Coef_1d& pcoef_quad_1d); + + /* Assignment operator: Quad_Coef_1d -> pQuad_Coef_1d */ + CPU_EXEC + pQuad_Coef_1d& operator=(const Quad_Coef_1d& coef_quad_1d); + + size_type size() const; + }; +} + +/* class Quad_Coef_1d */ +namespace mt +{ + template + class Quad_Coef_1d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr x; + mutable Vctr w; + + /************************************* constructors ************************************/ + Quad_Coef_1d() = default; + + Quad_Coef_1d(const Vctr_cpu& x, const Vctr_cpu& w); + + Quad_Coef_1d(const dt_init_list_f64& x, const dt_init_list_f64& w); + + Quad_Coef_1d(const size_type& new_size); + + Quad_Coef_1d(const size_type& new_size, const T& value); + + /* copy constructor */ + Quad_Coef_1d(const Quad_Coef_1d& coef_quad_1d); + + /* converting constructor */ + template + Quad_Coef_1d(const Quad_Coef_1d& coef_quad_1d); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Quad_Coef_1d& operator=(const Quad_Coef_1d& coef_quad_1d); + + /* converting assignment operator */ + template + Quad_Coef_1d& operator=(const Quad_Coef_1d& coef_quad_1d); + + template + void assign(const Quad_Coef_1d& coef_quad_1d); + + /**************** user define conversion operators *******************/ + pQuad_Coef_1d ptr() const; + + /* user define conversion for pointer Vctr */ + operator pQuad_Coef_1d() const; + + void fill(const T& val_x, const T& val_w); + + size_type size() const; + + void clear(); + + void reserve(const size_type& new_size); + + void resize(const size_type& new_size); + + void resize(const size_type& new_size, const T& value); + + void shrink_to_fit(); + }; +} + +#include "detail/quad_coef_1d.inl" \ No newline at end of file diff --git a/src/quad_coef_2d.h b/src/quad_coef_2d.h new file mode 100755 index 00000000..cf885921 --- /dev/null +++ b/src/quad_coef_2d.h @@ -0,0 +1,163 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ +#pragma once + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "vctr_cpu.h" +#include "vctr_gpu.h" + +/* template definition */ +namespace mt +{ + template class pQuad_Coef_2d; + + template class Quad_Coef_2d; +} + +/* derived class pQuad_Coef_1d */ +namespace mt +{ + template + using pQuad_Coef_2d_cpu = pQuad_Coef_2d; + + template + using pQuad_Coef_2d_gpu = pQuad_Coef_2d; +} + +/* derived class Quad_Coef_1d */ +namespace mt +{ + template + using Quad_Coef_2d_cpu = Quad_Coef_2d; + + template + using Quad_Coef_2d_gpu = Quad_Coef_2d; +} + +/* class pQuad_Coef_2d */ +namespace mt +{ + template + class pQuad_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + T* __restrict__ x; + T* __restrict__ y; + T* __restrict__ w; + size_type m_size; + + /************************************* constructors ************************************/ + CGPU_EXEC + pQuad_Coef_2d(); + + CGPU_EXEC + pQuad_Coef_2d(T* x, T* y, T* w, const size_type& size); + + /* copy constructor */ + CGPU_EXEC + pQuad_Coef_2d(const pQuad_Coef_2d& pcoef_quad_2d); + + /* constructor from Quad_Coef_2d */ + explicit pQuad_Coef_2d(const Quad_Coef_2d& coef_quad_2d); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + pQuad_Coef_2d& operator=(const pQuad_Coef_2d& pcoef_quad_2d); + + /* Assignment operator: Quad_Coef_2d -> pQuad_Coef_2d */ + CPU_EXEC + pQuad_Coef_2d& operator=(Quad_Coef_2d& coef_quad_2d); + + size_type size() const; + }; +} + +/* class Quad_Coef_2d */ +namespace mt +{ + template + class Quad_Coef_2d + { + public: + using value_type = T; + using size_type = dt_int32; + static const eDev device = Dev; + + mutable Vctr x; + mutable Vctr y; + mutable Vctr w; + + /************************************* constructors ************************************/ + Quad_Coef_2d() = default; + + Quad_Coef_2d(const Vctr_cpu& x, const Vctr_cpu& y, const Vctr_cpu& w); + + Quad_Coef_2d(const dt_init_list_f64& x, const dt_init_list_f64& y, const dt_init_list_f64& w); + + Quad_Coef_2d(const size_type& new_size); + + Quad_Coef_2d(const size_type& new_size, const T& value); + + /* copy constructor */ + Quad_Coef_2d(const Quad_Coef_2d& coef_quad_2d); + + /* converting constructor */ + template + Quad_Coef_2d(const Quad_Coef_2d& coef_quad_2d); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Quad_Coef_2d& operator=(const Quad_Coef_2d& coef_quad_2d); + + /* converting assignment operator */ + template + Quad_Coef_2d& operator=(const Quad_Coef_2d& coef_quad_2d); + + template + void assign(const Quad_Coef_2d& coef_quad_2d); + + /**************** user define conversion operators *******************/ + pQuad_Coef_2d ptr() const; + + /* user define conversion for pointer Vctr */ + operator pQuad_Coef_2d() const; + + void fill(const T& val_x, const T& val_y, const T& val_w); + + size_type size() const; + + void clear(); + + void reserve(const size_type& new_size); + + void resize(const size_type& new_size); + + void resize(const size_type& new_size, const T& value); + + void shrink_to_fit(); + }; +} + +#include "detail/quad_coef_2d.inl" \ No newline at end of file diff --git a/src/quad_data.h b/src/quad_data.h new file mode 100755 index 00000000..0ce27a26 --- /dev/null +++ b/src/quad_data.h @@ -0,0 +1,131 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "quad_coef_1d.h" +#include "quad_coef_2d.h" + +/* template definition */ +namespace mt +{ + template class Quad_Data_T; +} + +/* derived class */ +namespace mt +{ + using Quad_Data = Quad_Data_T; +} + +namespace mt +{ + template + class Quad_Data_T + { + public: + using value_type = T; + using size_type = dt_int32; + + Quad_Data_T() = default; + + template + Quad_Data_T(const eQuad_Typ& quad_typ, const dt_int32& n_quad, Quad_Coef_1d& quad, T alpha = 0, T beta = 0, T a = 0, T b = 1); + + template + void operator()(const eQuad_Typ& quad_typ, const dt_int32& n_quad, Quad_Coef_1d& quad, T alpha=0, T beta=0, T a=0, T b=1); + + private: + // 1: int_-1^1 f(x) dx + void nw_tanh_sinh_int_n1_p1(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw); + + // 2: int_0^infty f(x) dx + void nw_exp_sinh_int_0_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw); + + // 3: int_0^infty f(x)exp(-x) dx + void nw_exp_exp_int_0_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw); + + // 4: int_-infty^infty f(x) dx + void nw_sinh_sinh_int_ninfty_pinfty(const dt_int32& nx, const T& x_min, const T& x_max, T* px, T* pw); + + //1. Ooura, T. & Mori, M. A robust double exponential formula for Fourier-type integrals. J. Comput. Appl. Math. 112, 229–241 (1999). + // 5: int_0^infty f(x)sin(wx) dx + void nw_fourier_sin_int_0_pinfty(const dt_int32& nx, const T& ta, T* px, T* pw); + + // 6: int_0^infty f(x)Cos(wx) dx + void nw_fourier_cos_int_0_pinfty(const dt_int32& nx, const T& ta, T* px, T* pw); + + // 7: int_-1^1 f(x) dx + void nw_gauss_legendre_int_n1_p1(const dt_int32& nx, T* px, T* pw); + + // 8: int_-infty^infty f(x) x^0 Exp[-x^2] dx + void nw_gauss_hermite_x0_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw); + + // 9: int_-infty^infty f(x) |x|^1 Exp[-x^2] dx + void nw_gauss_hermite_x1_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw); + + // 9: int_-infty^infty f(x) |x|^2 Exp[-x^2] dx + void nw_gauss_hermite_x2_int_ninfty_pinfty(const dt_int32& nx, T* px, T* pw); + + // 11: int_0^infty f(x) x^0 Exp[-x] dx + void nw_gauss_laguerre_x0_int_0_pinfty(const dt_int32& nx, T* px, T* pw); + + // 12: int_0^infty f(x) x^1 Exp[-x] dx + void nw_gauss_laguerre_x1_int_0_pinfty(const dt_int32& nx, T* px, T* pw); + + // 13: int_0^infty f(x) x^2 Exp[-x] dx + void nw_gauss_laguerre_x2_int_0_pinfty(const dt_int32& nx, T* px, T* pw); + + // 14: int_0^infty f(x) Exp[-x]/Sqrt[x] dx + void nw_gauss_laguerre_xi2_int_0_pinfty(const dt_int32& nx, T* px, T* pw); + + /***************************************************************************************/ + // in, dt_int32 KIND, the rule. + // 1, legendre, (a, b) 1.0 + // 2, chebyshev, (a, b) ((b-x)*(x-a))^(-0.5) + // 3, gegenbauer, (a, b) ((b-x)*(x-a))^alpha + // 4, jacobi, (a, b) (b-x)^alpha*(x-a)^beta + // 5, generalized laguerre, (a, inf) (x-a)^alpha*exp(-b*(x-a)) + // 6, generalized hermite, (-inf, inf) |x-a|^alpha*exp(-b*(x-a)^2) + // 7, exponential, (a, b) |x-(a+b)/2.0|^alpha + // 8, rational, (a, inf) (x-a)^alpha*(x+b)^beta + + void cgqf(dt_int32 kind, dt_int32 nt, T alpha, T beta, T a, T b, T t[], T wts[]); + + void cdgqf(dt_int32 kind, dt_int32 nt, T alpha, T beta, T t[], T wts[]); + + T class_matrix(dt_int32 kind, dt_int32 m, T alpha, T beta, T aj[], T bj[]); + + void imtqlx(dt_int32 n, T d[], T e[], T z[]); + + void parchk(dt_int32 kind, dt_int32 m, T alpha, T beta); + + void scqf(dt_int32 nt, T t[], dt_int32 mlt[], T wts[], dt_int32 nwts, dt_int32 ndx[], + T swts[], T st[], dt_int32 kind, T alpha, T beta, T a, T b); + + void sgqf(dt_int32 nt, T aj[], T bj[], T zemu, T t[], T wts[]); + + T r8_epsilon(); + + T r8_huge(); + + T r8_sign(T x); + }; +} + +#include "detail/quad_data.inl" \ No newline at end of file diff --git a/src/quadrature.hpp b/src/quadrature.hpp deleted file mode 100644 index 22696cbc..00000000 --- a/src/quadrature.hpp +++ /dev/null @@ -1,2629 +0,0 @@ -/* - * This file is part of Multem. - * Copyright 2020 Ivan Lobato - * - * Multem is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Multem is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Multem. If not, see . - */ - -#ifndef QUADRATURE_H -#define QUADRATURE_H - -#ifdef _MSC_VER -#pragma once -#endif // _MSC_VER - -#include "types.cuh" -#include "traits.cuh" - -namespace mt -{ - class Quadrature{ - public: - template - void operator()(int Quad_Type, int nQuad, TQ1 &Q, double alpha=0, double beta=0, double a=0, double b=1) - { - using value_type = Value_type; - - if (nQuad <= 1) - { - Q.resize(1); - Q.x[0] = 0; - Q.w[0] = 1; - return; - } - - value_type x_min, x_max, r_max = 225; - double tai = 4.0; - - cQ.resize(nQuad); - - switch(Quad_Type) - { - case 0: // 0: int_-1^1 f(x) dx - x_min = -1.0+Epsilon::eps; - x_max = 1.0-Epsilon::eps; - nw_TanhSinh(cQ, x_min, x_max); - break; - case 1: // 1: int_0^infty f(x) dx - x_min = Epsilon::eps; - x_max = r_max; - nw_ExpSinh(cQ, x_min, x_max); - break; - case 2: // 2: int_0^infty f(x)exp(-x) dx - x_min = Epsilon::eps; - x_max = r_max; - nw_ExpExp(cQ, x_min, x_max); - break; - case 3: // 3: int_-infty^infty f(x) dx - x_min = -r_max; - x_max = r_max; - nw_SinhSinh(cQ, x_min, x_max); - break; - case 4: // 4: int_0^infty f(x)sin(wx) dx - nw_Fourier_Sin(cQ, tai); // tai = 2.6 - break; - case 5: // 5: int_0^infty f(x)Cos(wx) dx - nw_Fourier_Cos(cQ, tai); // tai = 2.6 - break; - case 6: // 6: int_-1^1 f(x) dx - nw_Gauss_Legendre_int_n1_p1(cQ); - break; - case 7: // 7: int_-infty^infty f(x) x^0 Exp[-x^2] dx - nw_Gauss_Hermite_x0_int_ninfty_pinfty(cQ); - break; - case 8: // 8: int_-infty^infty f(x) |x|^1 Exp[-x^2] dx - nw_Gauss_Hermite_x1_int_ninfty_pinfty(cQ); - break; - case 9: // 9: int_-infty^infty f(x) |x|^2 Exp[-x^2] dx - nw_Gauss_Hermite_x2_int_ninfty_pinfty(cQ); - break; - case 10: // 10: int_0^infty f(x) x^0 Exp[-x] dx - nw_Gauss_Laguerre_x0_int_0_pinfty(cQ); - break; - case 11: // 11: int_0^infty f(x) x^1 Exp[-x] dx - nw_Gauss_Laguerre_x1_int_0_pinfty(cQ); - break; - case 12: // 12: int_0^infty f(x) x^2 Exp[-x] dx - nw_Gauss_Laguerre_x2_int_0_pinfty(cQ); - break; - case 13: // 12: int_0^infty f(x) Exp[-x]/Sqrt[x] dx - nw_Gauss_Laguerre_xi2_int_0_pinfty(cQ); - break; - case 21: // 1, Legendre, (a,b) 1.0 - cgqf(cQ.size(), 1, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - case 22: // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - cgqf(cQ.size(), 2, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - case 23: // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - cgqf(cQ.size(), 3, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - case 24: // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - cgqf(cQ.size(), 4, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - case 25: // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - cgqf(cQ.size(), 5, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - case 26: // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - cgqf(cQ.size(), 6, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - case 27: // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - cgqf(cQ.size(), 7, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - case 28: // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - cgqf(cQ.size(), 8, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - break; - } - - Q.assign(cQ); - } - - private: - // 0: int_-1^1 f(x) dx - void nw_TanhSinh(Q1 &cQ, const double &x_min, const double &x_max) - { - auto Aprox = [](double x)->double{ return asinh(atanh(x)/c_i2Pi); }; - double tmin = Aprox(x_min); - double tmax = Aprox(x_max); - - double ti, tti, xi, wi; - double h = (tmax-tmin)/(cQ.size()-1); - - for(auto i = 0; i < cQ.size(); i++) - { - ti = tmin + i*h; - tti = c_i2Pi*sinh(ti); - xi = tanh(tti); - wi = h*c_i2Pi*cosh(ti)/pow(cosh(tti), 2); - cQ.x[i] = xi; - cQ.w[i] = wi; - } - } - - // 1: int_0^infty f(x) dx - void nw_ExpSinh(Q1 &cQ, const double &x_min, const double &x_max) - { - auto getLimit = [](double x)->double{ return asinh(log(x)/c_i2Pi); }; - double t_min = getLimit(x_min); - double t_max = getLimit(x_max); - int N = cQ.size(); - double h = (t_max-t_min)/(N-1); - double f = 0.5; - - for(auto ik = 0; ik < N; ik++) - { - auto t_ik = t_min + ik*h; - auto x_i = exp(c_i2Pi*sinh(t_ik)); - auto w_i = f*h*c_i2Pi*cosh(t_ik)*x_i; - cQ.x[ik] = x_i; - cQ.w[ik] = w_i; - f = (ik==N-1)?0.5:1.0; - } - } - - // 2: int_0^infty f(x)exp(-x) dx - void nw_ExpExp(Q1 &cQ, const double &x_min, const double &x_max) - { - auto getLimit = [](double x, double t, int n)->double - { - auto t_s = log(x); - for (auto ik = 0; ik < n; ik++) - { - auto exp_t = exp(-t); - t = t - (t - exp_t - t_s)/(1.0 + exp_t); - } - return t; - }; - - double t_min = -log(-log(x_min)); - t_min = getLimit(x_min, t_min, 5); - double t_max = log(x_max); - t_max = getLimit(x_max, t_max, 5); - - int N = cQ.size(); - double h = (t_max-t_min)/(N-1); - double f = 0.5; - - for(auto ik = 0; ik < N; ik++) - { - auto t_ik = t_min + ik*h; - auto exp_t_ik = exp(-t_ik); - auto x_i = exp(t_ik-exp_t_ik); - auto w_i = f*h*x_i*(1.0+exp_t_ik); - cQ.x[ik] = x_i; - cQ.w[ik] = w_i; - f = (ik==N-1)?0.5:1.0; - } - } - - // 3: int_-infty^infty f(x) dx - void nw_SinhSinh(Q1 &cQ, const double &x_min, const double &x_max) - { - auto getLimit = [](double x)->double{ return asinh(asin(x)/c_i2Pi); }; - double tmin = getLimit(x_min); - double tmax = getLimit(x_max); - - double ti, tti, xi, wi; - double h = (tmax-tmin)/(cQ.size()-1); - - for(auto i = 0; i < cQ.size(); i++) - { - ti = tmin + i*h; - tti = c_i2Pi*sinh(ti); - xi = sinh(tti); - wi = h*c_i2Pi*cosh(ti)*cosh(tti); - cQ.x[i] = xi; - cQ.w[i] = wi; - } - } - - // 4: int_0^infty f(x)sin(wx) dx - void nw_Fourier_Sin(Q1 &cQ, const double &ta) - { - double M, h, k, xi, wi; - double ti, ut, phi, dphi; - - h = 2.0*ta/cQ.size(); - M = c_Pi/h; k = 6; - - for(auto i = 0; i < cQ.size(); i++) - { - ti = -ta + (i+1)*h; - if(ti == 0 ) - { - phi = 1.0/k; dphi = 0.5; - xi = M*phi; - wi = c_Pi*dphi*sin(M*phi); - } - else - { - ut = 1.0-exp(-k*sinh(ti)); - phi = ti/ut; - dphi = (1.0+(1.0+k*ti*cosh(ti))*(ut-1))/(ut*ut); - xi = M*phi; - wi = c_Pi*dphi*sin(M*phi); - } - cQ.x[i] = xi; - cQ.w[i] = wi; - } - } - - // 5: int_0^infty f(x)Cos(wx) dx - void nw_Fourier_Cos(Q1 &cQ, const double &ta) - { - double M, h, k, xi, wi; - double ti, ut, phi, dphi; - - h = 2.0*ta/cQ.size(); - M = c_Pi/h; k = 6.0; - - for(auto i = 0; i < cQ.size(); i++) - { - ti = -ta + (i+0.5)*h; - if(ti == 0 ) - { - phi = 1.0/k; - dphi = 0.5; - xi = M*phi; - wi = c_Pi*dphi*cos(M*phi); - } - else - { - ut = 1.0-exp(-k*sinh(ti)); - phi = ti/ut; - dphi = (1.0+(1.0+k*ti*cosh(ti))*(ut-1))/(ut*ut); - xi = M*phi; - wi = c_Pi*dphi*cos(M*phi); - } - cQ.x[i] = xi; - cQ.w[i] = wi; - } - } - - // 6: int_-1^1 f(x) dx - void nw_Gauss_Legendre_int_n1_p1(Q1 &cQ) - { - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - int n_quad = cQ.size(); - int kind = 1; - double alpha = 0; - double beta = 0; - double a = -1.0; - double b = 1.0; - - cgqf(n_quad, kind, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - } - - // 7: int_-infty^infty f(x) x^0 Exp[-x^2] dx - void nw_Gauss_Hermite_x0_int_ninfty_pinfty(Q1 &cQ) - { - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - int n_quad = cQ.size(); - int kind = 6; - double alpha = 0; - double beta = 0; - double a = 0.0; - double b = 1.0; - - cgqf(n_quad, kind, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - } - - // 8: int_-infty^infty f(x) |x|^1 Exp[-x^2] dx - void nw_Gauss_Hermite_x1_int_ninfty_pinfty(Q1 &cQ) - { - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - int n_quad = cQ.size(); - int kind = 6; - double alpha = 1; - double beta = 0; - double a = 0.0; - double b = 1.0; - - cgqf(n_quad, kind, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - } - - // 9: int_-infty^infty f(x) |x|^2 Exp[-x^2] dx - void nw_Gauss_Hermite_x2_int_ninfty_pinfty(Q1 &cQ) - { - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - int n_quad = cQ.size(); - int kind = 6; - double alpha = 2; - double beta = 0; - double a = 0.0; - double b = 1.0; - - cgqf(n_quad, kind, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - } - - // 10: int_0^infty f(x) x^0 Exp[-x] dx - void nw_Gauss_Laguerre_x0_int_0_pinfty(Q1 &cQ) - { - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - int n_quad = cQ.size(); - int kind = 5; - double alpha = 0; - double beta = 0; - double a = 0.0; - double b = 1.0; - - cgqf(n_quad, kind, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - } - - // 11: int_0^infty f(x) x^1 Exp[-x] dx - void nw_Gauss_Laguerre_x1_int_0_pinfty(Q1 &cQ) - { - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - int n_quad = cQ.size(); - int kind = 5; - double alpha = 1; - double beta = 0; - double a = 0.0; - double b = 1.0; - - cgqf(n_quad, kind, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - } - - // 12: int_0^infty f(x) x^2 Exp[-x] dx - void nw_Gauss_Laguerre_x2_int_0_pinfty(Q1 &cQ) - { - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - int n_quad = cQ.size(); - int kind = 5; - double alpha = 2; - double beta = 0; - double a = 0.0; - double b = 1.0; - - cgqf(n_quad, kind, alpha, beta, a, b, cQ.x.data(), cQ.w.data()); - } - - // 13: int_0^infty f(x) Exp[-x]/Sqrt[x] dx - void nw_Gauss_Laguerre_xi2_int_0_pinfty(Q1 &cQ) - { - switch(cQ.size()) - { - case 2: - cQ.x[0] = 2.7525512860841095e-1; cQ.w[0] = 1.6098281800110257e0; - cQ.x[1] = 2.7247448713915890e0; cQ.w[1] = 1.6262567089449035e-1; - break; - case 4: - cQ.x[0] = 1.4530352150331709e-1; cQ.w[0] = 1.3222940251164826e0; - cQ.x[1] = 1.3390972881263614e0; cQ.w[1] = 4.1560465162978376e-1; - cQ.x[2] = 3.9269635013582872e0; cQ.w[2] = 3.4155966014826951e-2; - cQ.x[3] = 8.5886356890120343e0; cQ.w[3] = 3.9920814442273524e-4; - break; - case 8: - cQ.x[0] = 7.4791882596818270e-2; cQ.w[0] = 1.0158589580332275e0; - cQ.x[1] = 6.7724908764928915e-1; cQ.w[1] = 5.6129491705706735e-1; - cQ.x[2] = 1.9051136350314284e0; cQ.w[2] = 1.6762008279797166e-1; - cQ.x[3] = 3.8094763614849071e0; cQ.w[3] = 2.5760623071019947e-2; - cQ.x[4] = 6.4831454286271704e0; cQ.w[4] = 1.8645680172483611e-3; - cQ.x[5] = 1.0093323675221343e1; cQ.w[5] = 5.4237201850757630e-5; - cQ.x[6] = 1.4972627088426393e1; cQ.w[6] = 4.6419616897304213e-7; - cQ.x[7] = 2.1984272840962651e1; cQ.w[7] = 5.3096149480223645e-10; - break; - case 16: - cQ.x[0] = 3.7962914575313455e-2; cQ.w[0] = 7.5047670518560479e-1; - cQ.x[1] = 3.4220015601094768e-1; cQ.w[1] = 5.5491628460505980e-1; - cQ.x[2] = 9.5355315539086550e-1; cQ.w[2] = 3.0253946815328497e-1; - cQ.x[3] = 1.8779315076960743e0; cQ.w[3] = 1.2091626191182523e-1; - cQ.x[4] = 3.1246010507021443e0; cQ.w[4] = 3.5106857663146861e-2; - cQ.x[5] = 4.7067267076675872e0; cQ.w[5] = 7.3097806533088562e-3; - cQ.x[6] = 6.6422151797414440e0; cQ.w[6] = 1.0725367310559441e-3; - cQ.x[7] = 8.9550013377233902e0; cQ.w[7] = 1.0833168123639965e-4; - cQ.x[8] = 1.1677033673975957e1; cQ.w[8] = 7.3011702591247521e-6; - cQ.x[9] = 1.4851431341801250e1; cQ.w[9] = 3.1483355850911881e-7; - cQ.x[10] = 1.8537743178606694e1; cQ.w[10] = 8.1976643295417932e-9; - cQ.x[11] = 2.2821300693525208e1; cQ.w[11] = 1.1866582926793277e-10; - cQ.x[12] = 2.7831438211328676e1; cQ.w[12] = 8.4300204226528951e-13; - cQ.x[13] = 3.3781970488226166e1; cQ.w[13] = 2.3946880341856973e-15; - cQ.x[14] = 4.1081666525491202e1; cQ.w[14] = 1.8463473073036584e-18; - cQ.x[15] = 5.0777223877537080e1; cQ.w[15] = 1.4621352854768325e-22; - break; - case 24: - cQ.x[0] = 2.5437996585689359e-2; cQ.w[0] = 6.2200206075592616e-1; - cQ.x[1] = 2.2910231649262433e-1; cQ.w[1] = 5.0792308532951820e-1; - cQ.x[2] = 6.3729027873266879e-1; cQ.w[2] = 3.3840894389128221e-1; - cQ.x[3] = 1.2517406323627464e0; cQ.w[3] = 1.8364459415857036e-1; - cQ.x[4] = 2.0751129098523806e0; cQ.w[4] = 8.0959353969207698e-2; - cQ.x[5] = 3.1110524551477130e0; cQ.w[5] = 2.8889923149962199e-2; - cQ.x[6] = 4.3642830769353062e0; cQ.w[6] = 8.3060098239551049e-3; - cQ.x[7] = 5.8407332713236080e0; cQ.w[7] = 1.9127846396388306e-3; - cQ.x[8] = 7.5477046800234544e0; cQ.w[8] = 3.5030086360234566e-4; - cQ.x[9] = 9.4940953300264876e0; cQ.w[9] = 5.0571980554969778e-5; - cQ.x[10] = 1.1690695926056073e1; cQ.w[10] = 5.6945173834696962e-6; - cQ.x[11] = 1.4150586187285759e1; cQ.w[11] = 4.9373179873395010e-7; - cQ.x[12] = 1.6889671928527108e1; cQ.w[12] = 3.2450282717915397e-8; - cQ.x[13] = 1.9927425875242462e1; cQ.w[13] = 1.5860934990330765e-9; - cQ.x[14] = 2.3287932824879917e1; cQ.w[14] = 5.6305930756763382e-11; - cQ.x[15] = 2.7001406056472356e1; cQ.w[15] = 1.4093865163091778e-12; - cQ.x[16] = 3.1106464709046565e1; cQ.w[16] = 2.3951797309583587e-14; - cQ.x[17] = 3.5653703516328212e1; cQ.w[17] = 2.6303192453168170e-16; - cQ.x[18] = 4.0711598185543107e1; cQ.w[18] = 1.7460319202373353e-18; - cQ.x[19] = 4.6376979557540133e1; cQ.w[19] = 6.3767746470102769e-21; - cQ.x[20] = 5.2795432527283630e1; cQ.w[20] = 1.1129154937804570e-23; - cQ.x[21] = 6.0206666963057223e1; cQ.w[21] = 7.3700721603013398e-27; - cQ.x[22] = 6.9068601975304369e1; cQ.w[22] = 1.1969225386627757e-30; - cQ.x[23] = 8.0556280819950406e1; cQ.w[23] = 1.5871103023654473e-35; - break; - case 32: - cQ.x[0] = 1.9127510968446856e-2; cQ.w[0] = 5.4275484988260796e-1; - cQ.x[1] = 1.7221572414539558e-1; cQ.w[1] = 4.6598957212535609e-1; - cQ.x[2] = 4.7875647727748885e-1; cQ.w[2] = 3.4337168469816740e-1; - cQ.x[3] = 9.3948321450073428e-1; cQ.w[3] = 2.1699669861237368e-1; - cQ.x[4] = 1.5555082314789380e0; cQ.w[4] = 1.1747996392819887e-1; - cQ.x[5] = 2.3283376682103970e0; cQ.w[5] = 5.4406257907377837e-2; - cQ.x[6] = 3.2598922564569419e0; cQ.w[6] = 2.1512081019758274e-2; - cQ.x[7] = 4.3525345293301410e0; cQ.w[7] = 7.2451739570689175e-3; - cQ.x[8] = 5.6091034574961513e0; cQ.w[8] = 2.0726581990151553e-3; - cQ.x[9] = 7.0329577982838936e0; cQ.w[9] = 5.0196739702612497e-4; - cQ.x[10] = 8.6280298574059291e0; cQ.w[10] = 1.0251858271572549e-4; - cQ.x[11] = 1.0398891905552624e1; cQ.w[11] = 1.7576998461700718e-5; - cQ.x[12] = 1.2350838217714770e1; cQ.w[12] = 2.5166805020623692e-6; - cQ.x[13] = 1.4489986690780274e1; cQ.w[13] = 2.9910658734544941e-7; - cQ.x[14] = 1.6823405362953694e1; cQ.w[14] = 2.9302506329522187e-8; - cQ.x[15] = 1.9359271087268714e1; cQ.w[15] = 2.3472334846430987e-9; - cQ.x[16] = 2.2107070382206007e1; cQ.w[16] = 1.5230434500290903e-10; - cQ.x[17] = 2.5077856544198053e1; cQ.w[17] = 7.9183555338954479e-12; - cQ.x[18] = 2.8284583194970531e1; cQ.w[18] = 3.2566814614194407e-13; - cQ.x[19] = 3.1742543790616606e1; cQ.w[19] = 1.0437247453181695e-14; - cQ.x[20] = 3.5469961396173283e1; cQ.w[20] = 2.5601867826448761e-16; - cQ.x[21] = 3.9488797123368127e1; cQ.w[21] = 4.7037694213516382e-18; - cQ.x[22] = 4.3825886369903902e1; cQ.w[22] = 6.3045091330075628e-20; - cQ.x[23] = 4.8514583867416048e1; cQ.w[23] = 5.9657255685597023e-22; - cQ.x[24] = 5.3597231826148512e1; cQ.w[24] = 3.8234137666012857e-24; - cQ.x[25] = 5.9129027934391951e1; cQ.w[25] = 1.5723595577851821e-26; - cQ.x[26] = 6.5184426376135782e1; cQ.w[26] = 3.8582071909299337e-29; - cQ.x[27] = 7.1868499359551422e1; cQ.w[27] = 5.0993217982259985e-32; - cQ.x[28] = 7.9339086528823201e1; cQ.w[28] = 3.1147812492595276e-35; - cQ.x[29] = 8.7856119943133525e1; cQ.w[29] = 6.8422760225114810e-39; - cQ.x[30] = 9.7916716426062762e1; cQ.w[30] = 3.3594959802163184e-43; - cQ.x[31] = 1.1079926894707576e2; cQ.w[31] = 1.1088644990767160e-48; - break; - case 40: - cQ.x[0] = 1.5325663331507189e-2; cQ.w[0] = 4.8767170761442366e-1; - cQ.x[1] = 1.3796600174102882e-1; cQ.w[1] = 4.3154989254866095e-1; - cQ.x[2] = 3.8343384139288653e-1; cQ.w[2] = 3.3787593855180386e-1; - cQ.x[3] = 7.5210508353159711e-1; cQ.w[3] = 2.3396146760859843e-1; - cQ.x[4] = 1.2445475511131953e0; cQ.w[4] = 1.4320149538368678e-1; - cQ.x[5] = 1.8615258453171583e0; cQ.w[5] = 7.7417199829675957e-2; - cQ.x[6] = 2.6040079765974233e0; cQ.w[6] = 3.6931502308855776e-2; - cQ.x[7] = 3.4731739113527927e0; cQ.w[7] = 1.5528078810799283e-2; - cQ.x[8] = 4.4704262206423379e0; cQ.w[8] = 5.7463950661794487e-3; - cQ.x[9] = 5.5974030703416056e0; cQ.w[9] = 1.8686353739223537e-3; - cQ.x[10] = 6.8559938552704945e0; cQ.w[10] = 5.3295577338670161e-4; - cQ.x[11] = 8.2483578563697614e0; cQ.w[11] = 1.3303482483630581e-4; - cQ.x[12] = 9.7769463941849785e0; cQ.w[12] = 2.8992888382259350e-5; - cQ.x[13] = 1.1444529069317641e1; cQ.w[13] = 5.5014492548024867e-6; - cQ.x[14] = 1.3254224828602629e1; cQ.w[14] = 9.0610711317226041e-7; - cQ.x[15] = 1.5209538784718065e1; cQ.w[15] = 1.2908925900239279e-7; - cQ.x[16] = 1.7314405960671086e1; cQ.w[16] = 1.5845846578300512e-8; - cQ.x[17] = 1.9573243448531832e1; cQ.w[17] = 1.6686111852173423e-9; - cQ.x[18] = 2.1991012891259404e1; cQ.w[18] = 1.4999439829316549e-10; - cQ.x[19] = 2.4573295756577260e1; cQ.w[19] = 1.1446559437004013e-11; - cQ.x[20] = 2.7326384629341011e1; cQ.w[20] = 7.3696996403182414e-13; - cQ.x[21] = 3.0257394787336121e1; cQ.w[21] = 3.9750416693969613e-14; - cQ.x[22] = 3.3374401770413884e1; cQ.w[22] = 1.7818922081332433e-15; - cQ.x[23] = 3.6686612696144794e1; cQ.w[23] = 6.5783240287291484e-17; - cQ.x[24] = 4.0204582016183319e1; cQ.w[24] = 1.9793057979240198e-18; - cQ.x[25] = 4.3940486724615585e1; cQ.w[25] = 4.7956805512357826e-20; - cQ.x[26] = 4.7908482506508098e1; cQ.w[26] = 9.2269421491078646e-22; - cQ.x[27] = 5.2125172273284642e1; cQ.w[27] = 1.3868239639057759e-23; - cQ.x[28] = 5.6610234272577454e1; cQ.w[28] = 1.5970374396346345e-25; - cQ.x[29] = 6.1387282639433491e1; cQ.w[29] = 1.3766914087267507e-27; - cQ.x[30] = 6.6485076698107068e1; cQ.w[30] = 8.6356346860439419e-30; - cQ.x[31] = 7.1939271994415582e1; cQ.w[31] = 3.8059812200638324e-32; - cQ.x[32] = 7.7795048292119587e1; cQ.w[32] = 1.1274385558954499e-34; - cQ.x[33] = 8.4111230042098140e1; cQ.w[33] = 2.1190293856555058e-37; - cQ.x[34] = 9.0967109281657703e1; cQ.w[34] = 2.3384153996394935e-40; - cQ.x[35] = 9.8474564473065897e1; cQ.w[35] = 1.3584866032309069e-43; - cQ.x[36] = 1.0680170504629888e2; cQ.w[36] = 3.5284114086777935e-47; - cQ.x[37] = 1.1622557258080335e2; cQ.w[37] = 3.1343129875498926e-51; - cQ.x[38] = 1.2727662323235295e2; cQ.w[38] = 5.7648218162351852e-52; - cQ.x[39] = 1.4132130003237776e2; cQ.w[39] = 5.6256581525587782e-50; - break; - case 48: - cQ.x[0] = 1.2784572337116694e-2; cQ.w[0] = 4.4654004699506952e-1; - cQ.x[1] = 1.1508148358837804e-1; cQ.w[1] = 4.0322602695846852e-1; - cQ.x[2] = 3.1978387827943194e-1; cQ.w[2] = 3.2875926119699403e-1; - cQ.x[3] = 6.2710953585675593e-1; cQ.w[3] = 2.4196623372503065e-1; - cQ.x[4] = 1.0373867221540579e0; cQ.w[4] = 1.6070790016128415e-1; - cQ.x[5] = 1.5510561307962492e0; cQ.w[5] = 9.6279813462180107e-2; - cQ.x[6] = 2.1686735147948251e0; cQ.w[6] = 5.2000680542488898e-2; - cQ.x[7] = 2.8909130466944233e0; cQ.w[7] = 2.5302750225600317e-2; - cQ.x[8] = 3.7185714571096889e0; cQ.w[8] = 1.1083262578877953e-2; - cQ.x[9] = 4.6525730143474026e0; cQ.w[9] = 4.3662639521934365e-3; - cQ.x[10] = 5.6939754224427003e0; cQ.w[10] = 1.5453916433633038e-3; - cQ.x[11] = 6.8439767318335151e0; cQ.w[11] = 4.9083618546105323e-4; - cQ.x[12] = 8.1039233766453468e0; cQ.w[12] = 1.3970864889083082e-4; - cQ.x[13] = 9.4753194758919079e0; cQ.w[13] = 3.5583611836440579e-5; - cQ.x[14] = 1.0959837563734646e1; cQ.w[14] = 8.0964663575545199e-6; - cQ.x[15] = 1.2559330947448595e1; cQ.w[15] = 1.6427089095665616e-6; - cQ.x[16] = 1.4275847932399555e1; cQ.w[16] = 2.9659388100100142e-7; - cQ.x[17] = 1.6111648203063945e1; cQ.w[17] = 4.7547324295148571e-8; - cQ.x[18] = 1.8069221710408724e1; cQ.w[18] = 6.7511694622554086e-9; - cQ.x[19] = 2.0151310492061653e1; cQ.w[19] = 8.4671875670220449e-10; - cQ.x[20] = 2.2360933946965237e1; cQ.w[20] = 9.3520207719701412e-11; - cQ.x[21] = 2.4701418206395586e1; cQ.w[21] = 9.0666067491677764e-12; - cQ.x[22] = 2.7176430396128092e1; cQ.w[22] = 7.6873634497532554e-13; - cQ.x[23] = 2.9790018780757460e1; cQ.w[23] = 5.6775347903386773e-14; - cQ.x[24] = 3.2546660035349492e1; cQ.w[24] = 3.6363382609864670e-15; - cQ.x[25] = 3.5451315222092618e1; cQ.w[25] = 2.0098102983149713e-16; - cQ.x[26] = 3.8509496489187991e1; cQ.w[26] = 9.5336623423732135e-18; - cQ.x[27] = 4.1727347097011937e1; cQ.w[27] = 3.8577586536742773e-19; - cQ.x[28] = 4.5111738172331784e1; cQ.w[28] = 1.3225902352962134e-20; - cQ.x[29] = 4.8670386683149351e1; cQ.w[29] = 3.8125203773751006e-22; - cQ.x[30] = 5.2412000646782474e1; cQ.w[30] = 9.1612021970998299e-24; - cQ.x[31] = 5.6346459734243123e1; cQ.w[31] = 1.8171931294097668e-25; - cQ.x[32] = 6.0485042530508732e1; cQ.w[32] = 2.9424831099483641e-27; - cQ.x[33] = 6.4840716257286064e1; cQ.w[33] = 3.8399414135897572e-29; - cQ.x[34] = 6.9428511589042573e1; cQ.w[34] = 3.9790937885390546e-31; - cQ.x[35] = 7.4266015688703556e1; cQ.w[35] = 3.2177464158769137e-33; - cQ.x[36] = 7.9374033184791669e1; cQ.w[36] = 1.9893600118442518e-35; - cQ.x[37] = 8.4777491893280191e1; cQ.w[37] = 9.1748033317163899e-38; - cQ.x[38] = 9.0506715916613337e1; cQ.w[38] = 3.0635979294223916e-40; - cQ.x[39] = 9.6599269661943114e1; cQ.w[39] = 7.1378771235620131e-43; - cQ.x[40] = 1.0310272648925973e2; cQ.w[40] = 1.1074129639565051e-45; - cQ.x[41] = 1.1007901167333772e2; cQ.w[41] = 1.0766445013940194e-48; - cQ.x[42] = 1.1761159733441177e2; cQ.w[42] = 6.0445878630042245e-52; - cQ.x[43] = 1.2581828912230779e2; cQ.w[43] = 1.7467465671838054e-55; - cQ.x[44] = 1.3487618875613396e2; cQ.w[44] = 2.1867649475035571e-59; - cQ.x[45] = 1.4507736943128927e2; cQ.w[45] = 8.9374048433626366e-64; - cQ.x[46] = 1.5698162310364024e2; cQ.w[46] = 6.9616827754363648e-69; - cQ.x[47] = 1.7203286674516623e2; cQ.w[47] = 7.3843030686139940e-50; - break; - case 56: - cQ.x[0] = 1.0966296964922414e-2; cQ.w[0] = 4.1431861461592488e-1; - cQ.x[1] = 9.8709503981500921e-2; cQ.w[1] = 3.7958824335151592e-1; - cQ.x[2] = 2.7426441281900728e-1; cQ.w[2] = 3.1859560878006560e-1; - cQ.x[3] = 5.3776830760580984e-1; cQ.w[3] = 2.4493804875366549e-1; - cQ.x[4] = 8.8942785389626524e-1; cQ.w[4] = 1.7245385388352993e-1; - cQ.x[5] = 1.3295199945387192e0; cQ.w[5] = 1.1116552769641440e-1; - cQ.x[6] = 1.8583931587330957e0; cQ.w[6] = 6.5583934984821083e-2; - cQ.x[7] = 2.4764687971240665e0; cQ.w[7] = 3.5397526052325080e-2; - cQ.x[8] = 3.1842432594503771e0; cQ.w[8] = 1.7469565741779008e-2; - cQ.x[9] = 3.9822900352751187e0; cQ.w[9] = 7.8791146628173459e-3; - cQ.x[10] = 4.8712623827436266e0; cQ.w[10] = 3.2454637275858797e-3; - cQ.x[11] = 5.8518963752570206e0; cQ.w[11] = 1.2200069198095973e-3; - cQ.x[12] = 6.9250144015294926e0; cQ.w[12] = 4.1819509658049854e-4; - cQ.x[13] = 8.0915291608577938e0; cQ.w[13] = 1.3059682676732009e-4; - cQ.x[14] = 9.3524482027415579e0; cQ.w[14] = 3.7118324819779832e-5; - cQ.x[15] = 1.0708879068458080e1; cQ.w[15] = 9.5910914884881867e-6; - cQ.x[16] = 1.2162035102064631e1; cQ.w[16] = 2.2503384827035532e-6; - cQ.x[17] = 1.3713242009881661e1; cQ.w[17] = 4.7880157280422767e-7; - cQ.x[18] = 1.5363945261179596e1; cQ.w[18] = 9.2250198493335919e-8; - cQ.x[19] = 1.7115718439020667e1; cQ.w[19] = 1.6069558346408703e-8; - cQ.x[20] = 1.8970272669583436e1; cQ.w[20] = 2.5265449989883177e-9; - cQ.x[21] = 2.0929467281561854e1; cQ.w[21] = 3.5787741726578897e-10; - cQ.x[22] = 2.2995321875320932e1; cQ.w[22] = 4.5577902726623018e-11; - cQ.x[23] = 2.5170030015603701e1; cQ.w[23] = 5.2076385947795911e-12; - cQ.x[24] = 2.7455974803255672e1; cQ.w[24] = 5.3255665746212511e-13; - cQ.x[25] = 2.9855746632650704e1; cQ.w[25] = 4.8619672412277693e-14; - cQ.x[26] = 3.2372163504856039e1; cQ.w[26] = 3.9515202575705826e-15; - cQ.x[27] = 3.5008294345466858e1; cQ.w[27] = 2.8503559634838643e-16; - cQ.x[28] = 3.7767485874979349e1; cQ.w[28] = 1.8187535954103432e-17; - cQ.x[29] = 4.0653393704581200e1; cQ.w[29] = 1.0228519632208071e-18; - cQ.x[30] = 4.3670018489449905e1; cQ.w[30] = 5.0500039302829468e-20; - cQ.x[31] = 4.6821748176145590e1; cQ.w[31] = 2.1793149108595921e-21; - cQ.x[32] = 5.0113407645739421e1; cQ.w[32] = 8.1812395526908028e-23; - cQ.x[33] = 5.3550317401224539e1; cQ.w[33] = 2.6576488518963704e-24; - cQ.x[34] = 5.7138363406574332e1; cQ.w[34] = 7.4271309204470600e-26; - cQ.x[35] = 6.0884080798556528e1; cQ.w[35] = 1.7740931536888198e-27; - cQ.x[36] = 6.4794755023535346e1; cQ.w[36] = 3.5960724740047246e-29; - cQ.x[37] = 6.8878545092128855e1; cQ.w[37] = 6.1357429171822799e-31; - cQ.x[38] = 7.3144635233014682e1; cQ.w[38] = 8.7325878464563983e-33; - cQ.x[39] = 7.7603423474903333e1; cQ.w[39] = 1.0260913087634106e-34; - cQ.x[40] = 8.2266758923044609e1; cQ.w[40] = 9.8379556343138002e-37; - cQ.x[41] = 8.7148244251462459e1; cQ.w[41] = 7.5937692877807736e-39; - cQ.x[42] = 9.2263627069792685e1; cQ.w[42] = 4.6460504504603365e-41; - cQ.x[43] = 9.7631314803869374e1; cQ.w[43] = 2.2125228051355289e-43; - cQ.x[44] = 1.0327306509488168e2; cQ.w[44] = 8.0267804054671947e-46; - cQ.x[45] = 1.0921493206709584e2; cQ.w[45] = 2.1621413990444480e-48; - cQ.x[46] = 1.1548859679336965e2; cQ.w[46] = 4.1913798221383726e-51; - cQ.x[47] = 1.2213329501416645e2; cQ.w[47] = 5.6258187814957665e-54; - cQ.x[48] = 1.2919871245898944e2; cQ.w[48] = 4.9791444365660730e-57; - cQ.x[49] = 1.3674952821727593e2; cQ.w[49] = 2.7270187769624205e-60; - cQ.x[50] = 1.4487294472877377e2; cQ.w[50] = 8.4854893562244169e-64; - cQ.x[51] = 1.5369207574377554e2; cQ.w[51] = 1.3300105642340421e-67; - cQ.x[52] = 1.6339209491703519e2; cQ.w[52] = 8.7671924329217860e-72; - cQ.x[53] = 1.7427858611626866e2; cQ.w[53] = 1.8070041919711762e-76; - cQ.x[54] = 1.8693771869007120e2; cQ.w[54] = 1.0229121536329777e-48; - cQ.x[55] = 2.0288303763687224e2; cQ.w[55] = 7.4032472491198754e-53; - break; - case 64: - cQ.x[0] = 9.6008293650696286e-3; cQ.w[0] = 3.8819522372817551e-1; - cQ.x[1] = 8.6416074005085619e-2; cQ.w[1] = 3.5954616781559853e-1; - cQ.x[2] = 2.4009251326551299e-1; cQ.w[2] = 3.0842087059670877e-1; - cQ.x[3] = 4.7072219845762405e-1; cQ.w[3] = 2.4500654632827139e-1; - cQ.x[4] = 7.7844358612953627e-1; cQ.w[4] = 1.8021735675289784e-1; - cQ.x[5] = 1.1634419969552807e0; cQ.w[5] = 1.2272144200898013e-1; - cQ.x[6] = 1.6259502332928078e0; cQ.w[6] = 7.7347909621273805e-2; - cQ.x[7] = 2.1662493604094500e0; cQ.w[7] = 4.5108620335648845e-2; - cQ.x[8] = 2.7846696577606368e0; cQ.w[8] = 2.4333837728938679e-2; - cQ.x[9] = 3.4815917481914229e0; cQ.w[9] = 1.2137724813851775e-2; - cQ.x[10] = 4.2574479145349120e0; cQ.w[10] = 5.5956788032115785e-3; - cQ.x[11] = 5.1127236148341415e0; cQ.w[11] = 2.3831276289143345e-3; - cQ.x[12] = 6.0479592093454125e0; cQ.w[12] = 9.3710307561682273e-4; - cQ.x[13] = 7.0637519146269628e0; cQ.w[13] = 3.4002817652561882e-4; - cQ.x[14] = 8.1607580024185598e0; cQ.w[14] = 1.1377487520080482e-4; - cQ.x[15] = 9.3396952637232506e0; cQ.w[15] = 3.5080971696187810e-5; - cQ.x[16] = 1.0601345761568931e1; cQ.w[16] = 9.9598490651819740e-6; - cQ.x[17] = 1.1946558899421827e1; cQ.w[17] = 2.6014940064763985e-6; - cQ.x[18] = 1.3376254836226536e1; cQ.w[18] = 6.2457459723578062e-7; - cQ.x[19] = 1.4891428283653888e1; cQ.w[19] = 1.3769162244308700e-7; - cQ.x[20] = 1.6493152726464029e1; cQ.w[20] = 2.7843814305870358e-8; - cQ.x[21] = 1.8182585113077513e1; cQ.w[21] = 5.1587944588527896e-9; - cQ.x[22] = 1.9960971070661513e1; cQ.w[22] = 8.7463733196968069e-10; - cQ.x[23] = 2.1829650707488929e1; cQ.w[23] = 1.3551560975549108e-10; - cQ.x[24] = 2.3790065075269629e1; cQ.w[24] = 1.9160633017471715e-11; - cQ.x[25] = 2.5843763375899103e1; cQ.w[25] = 2.4684289732011134e-12; - cQ.x[26] = 2.7992411011009711e1; cQ.w[26] = 2.8926946423808331e-13; - cQ.x[27] = 3.0237798589328330e1; cQ.w[27] = 3.0780994607070916e-14; - cQ.x[28] = 3.2581852026749626e1; cQ.w[28] = 2.9684476750277130e-15; - cQ.x[29] = 3.5026643897992604e1; cQ.w[29] = 2.5890963186787431e-16; - cQ.x[30] = 3.7574406227691570e1; cQ.w[30] = 2.0378664608465850e-17; - cQ.x[31] = 4.0227544944021652e1; cQ.w[31] = 1.4440214633856584e-18; - cQ.x[32] = 4.2988656261067658e1; cQ.w[32] = 9.1880153546594432e-20; - cQ.x[33] = 4.5860545309175844e1; cQ.w[33] = 5.2349151678696223e-21; - cQ.x[34] = 4.8846247398170421e1; cQ.w[34] = 2.6627357180671792e-22; - cQ.x[35] = 5.1949052380103696e1; cQ.w[35] = 1.2051968064012909e-23; - cQ.x[36] = 5.5172532680822943e1; cQ.w[36] = 4.8368069192953299e-25; - cQ.x[37] = 5.8520575699338077e1; cQ.w[37] = 1.7145660967538707e-26; - cQ.x[38] = 6.1997421439210377e1; cQ.w[38] = 5.3458472401161465e-28; - cQ.x[39] = 6.5607706448472386e1; cQ.w[39] = 1.4593090013536809e-29; - cQ.x[40] = 6.9356515419807817e1; cQ.w[40] = 3.4702060405641224e-31; - cQ.x[41] = 7.3249442163003752e1; cQ.w[41] = 7.1487577917588421e-33; - cQ.x[42] = 7.7292662138289202e1; cQ.w[42] = 1.2679827052732978e-34; - cQ.x[43] = 8.1493019376821402e1; cQ.w[43] = 1.9233416135935014e-36; - cQ.x[44] = 8.5858131478224402e1; cQ.w[44] = 2.4761711159527361e-38; - cQ.x[45] = 9.0396517560549849e1; cQ.w[45] = 2.6829949635287387e-40; - cQ.x[46] = 9.5117755689162181e1; cQ.w[46] = 2.4235590682611838e-42; - cQ.x[47] = 1.0003267864790140e2; cQ.w[47] = 1.8056080277573288e-44; - cQ.x[48] = 1.0515362028215433e2; cQ.w[48] = 1.0960434057957593e-46; - cQ.x[49] = 1.1049472958850639e2; cQ.w[49] = 5.3454875034721357e-49; - cQ.x[50] = 1.1607237715014811e2; cQ.w[50] = 2.0609725041113895e-51; - cQ.x[51] = 1.2190568994074218e2; cQ.w[51] = 6.1641547666785974e-54; - cQ.x[52] = 1.2801726858944196e2; cQ.w[52] = 1.3986145848103912e-56; - cQ.x[53] = 1.3443417070003274e2; cQ.w[53] = 2.3439570024259610e-59; - cQ.x[54] = 1.4118929376119792e2; cQ.w[54] = 2.8089345154809745e-62; - cQ.x[55] = 1.4832337939847587e2; cQ.w[55] = 2.3123103281927504e-65; - cQ.x[56] = 1.5588802451891946e2; cQ.w[56] = 1.2428488323660627e-68; - cQ.x[57] = 1.6395040789497031e2; cQ.w[57] = 4.0831715944879700e-72; - cQ.x[58] = 1.7260112638093499e2; cQ.w[58] = 7.5024317376094500e-76; - cQ.x[59] = 1.8196813220934213e2; cQ.w[59] = 6.8024601738732743e-80; - cQ.x[60] = 1.9224396472236875e2; cQ.w[60] = 2.5224989666770768e-84; - cQ.x[61] = 2.0374654228943264e2; cQ.w[61] = 9.5158011667265254e-49; - cQ.x[62] = 2.1708611403654403e2; cQ.w[62] = 5.3192427849433605e-52; - cQ.x[63] = 2.3383975178282573e2; cQ.w[63] = 2.9535559171937292e-66; - break; - case 72: - cQ.x[0] = 8.5377530337449248e-3; cQ.w[0] = 3.6646133805754739e-1; - cQ.x[1] = 7.6845831749819249e-2; cQ.w[1] = 3.4230533863506727e-1; - cQ.x[2] = 2.1349429706226695e-1; cQ.w[2] = 2.9865564028363514e-1; - cQ.x[3] = 4.1854784885205123e-1; cQ.w[3] = 2.4337240372556322e-1; - cQ.x[4] = 6.9210374777076850e-1; cQ.w[4] = 1.8521384480327197e-1; - cQ.x[5] = 1.0342920697248060e0; cQ.w[5] = 1.3161967742383411e-1; - cQ.x[6] = 1.4452760476859431e0; cQ.w[6] = 8.7325860377519644e-2; - cQ.x[7] = 1.9252525030070945e0; cQ.w[7] = 5.4082218044787982e-2; - cQ.x[8] = 2.4744523690138993e0; cQ.w[8] = 3.1257614600552892e-2; - cQ.x[9] = 3.0931413102677093e0; cQ.w[9] = 1.6855126430119594e-2; - cQ.x[10] = 3.7816204415611087e0; cQ.w[10] = 8.4772081114631611e-3; - cQ.x[11] = 4.5402271514220959e0; cQ.w[11] = 3.9753232176891744e-3; - cQ.x[12] = 5.3693360356771178e0; cQ.w[12] = 1.7375161592345435e-3; - cQ.x[13] = 6.2693599474670913e0; cQ.w[13] = 7.0752789404236957e-4; - cQ.x[14] = 7.2407511710366363e0; cQ.w[14] = 2.6830022946769146e-4; - cQ.x[15] = 8.2840027276389276e0; cQ.w[15] = 9.4699597895333223e-5; - cQ.x[16] = 9.3996498230328796e0; cQ.w[16] = 3.1095207369238697e-5; - cQ.x[17] = 1.0588271447314284e1; cQ.w[17] = 9.4930705560516880e-6; - cQ.x[18] = 1.1850492139239455e1; cQ.w[18] = 2.6928856004713719e-6; - cQ.x[19] = 1.3186983928793866e1; cQ.w[19] = 7.0931074479099719e-7; - cQ.x[20] = 1.4598468473558433e1; cQ.w[20] = 1.7336070598064455e-7; - cQ.x[21] = 1.6085719406466767e1; cQ.w[21] = 3.9284921495770124e-8; - cQ.x[22] = 1.7649564914868501e1; cQ.w[22] = 8.2471566241554238e-9; - cQ.x[23] = 1.9290890573464524e1; cQ.w[23] = 1.6025182143590107e-9; - cQ.x[24] = 2.1010642456716749e1; cQ.w[24] = 2.8794742979351125e-10; - cQ.x[25] = 2.2809830559825846e1; cQ.w[25] = 4.7796759804694583e-11; - cQ.x[26] = 2.4689532561396773e1; cQ.w[26] = 7.3213811680310381e-12; - cQ.x[27] = 2.6650897965571812e1; cQ.w[27] = 1.0337134692368372e-12; - cQ.x[28] = 2.8695152666822676e1; cQ.w[28] = 1.3436626222686719e-13; - cQ.x[29] = 3.0823603986900308e1; cQ.w[29] = 1.6058255460718379e-14; - cQ.x[30] = 3.3037646240818195e1; cQ.w[30] = 1.7620660009112015e-15; - cQ.x[31] = 3.5338766897405687e1; cQ.w[31] = 1.7726340324641576e-16; - cQ.x[32] = 3.7728553410174551e1; cQ.w[32] = 1.6323127659605682e-17; - cQ.x[33] = 4.0208700806318587e1; cQ.w[33] = 1.3735451099194697e-18; - cQ.x[34] = 4.2781020136014409e1; cQ.w[34] = 1.0542790113729066e-19; - cQ.x[35] = 4.5447447901312514e1; cQ.w[35] = 7.3672431203789817e-21; - cQ.x[36] = 4.8210056604429630e1; cQ.w[36] = 4.6773118965550795e-22; - cQ.x[37] = 5.1071066579968236e1; cQ.w[37] = 2.6919741928296506e-23; - cQ.x[38] = 5.4032859305501852e1; cQ.w[38] = 1.4012014167408308e-24; - cQ.x[39] = 5.7097992421357986e1; cQ.w[39] = 6.5793246486772861e-26; - cQ.x[40] = 6.0269216734953006e1; cQ.w[40] = 2.7792387816429709e-27; - cQ.x[41] = 6.3549495539818125e1; cQ.w[41] = 1.0530654909535471e-28; - cQ.x[42] = 6.6942026647284918e1; cQ.w[42] = 3.5677140725415228e-30; - cQ.x[43] = 7.0450267613328067e1; cQ.w[43] = 1.0770556703499718e-31; - cQ.x[44] = 7.4077964749136873e1; cQ.w[44] = 2.8865806752335222e-33; - cQ.x[45] = 7.7829186638083087e1; cQ.w[45] = 6.8402497184153889e-35; - cQ.x[46] = 8.1708363052613987e1; cQ.w[46] = 1.4268974543918404e-36; - cQ.x[47] = 8.5720330384148150e1; cQ.w[47] = 2.6077204118485067e-38; - cQ.x[48] = 8.9870384983719634e1; cQ.w[48] = 4.1533050523669125e-40; - cQ.x[49] = 9.4164346183819770e1; cQ.w[49] = 5.7316992987700021e-42; - cQ.x[50] = 9.8608631264982208e1; cQ.w[50] = 6.8102796020749233e-44; - cQ.x[51] = 1.0321034529045834e2; cQ.w[51] = 6.9179617811502756e-46; - cQ.x[52] = 1.0797738962609581e2; cQ.w[52] = 5.9610219491215519e-48; - cQ.x[53] = 1.1291859418950553e2; cQ.w[53] = 4.3190839650906910e-50; - cQ.x[54] = 1.1804388018177253e2; cQ.w[54] = 2.6056833265450411e-52; - cQ.x[55] = 1.2336446247428126e2; cQ.w[55] = 1.2944535536043246e-54; - cQ.x[56] = 1.2889310430876951e2; cQ.w[56] = 5.2287531735186084e-57; - cQ.x[57] = 1.3464444208967572e2; cQ.w[57] = 1.6926455724514031e-59; - cQ.x[58] = 1.4063540573754781e2; cQ.w[58] = 4.3183461553903832e-62; - cQ.x[59] = 1.4688577190557120e2; cQ.w[59] = 8.5145486452100040e-65; - cQ.x[60] = 1.5341890608220506e2; cQ.w[60] = 1.2678660729891205e-67; - cQ.x[61] = 1.6026278017056644e2; cQ.w[61] = 1.3869468532834784e-70; - cQ.x[62] = 1.6745140389442310e2; cQ.w[62] = 1.0778332837412283e-73; - cQ.x[63] = 1.7502689981511292e2; cQ.w[63] = 5.7084939874269743e-77; - cQ.x[64] = 1.8304262155336948e2; cQ.w[64] = 1.9550707098857624e-80; - cQ.x[65] = 1.9156804971323859e2; cQ.w[65] = 4.0440344494888973e-84; - cQ.x[66] = 2.0069691105825289e2; cQ.w[66] = 4.6082741548145242e-88; - cQ.x[67] = 2.1056162324265798e2; cQ.w[67] = 2.5411102164420924e-92; - cQ.x[68] = 2.2136152670104394e2; cQ.w[68] = 5.5818464378910382e-97; - cQ.x[69] = 2.3342593022383359e2; cQ.w[69] = 3.8018252344681360e-50; - cQ.x[70] = 2.4738731475402643e2; cQ.w[70] = 2.0795745925390798e-53; - cQ.x[71] = 2.6488137073545847e2; cQ.w[71] = 5.9029492520141047e-68; - break; - case 80: - cQ.x[0] = 7.6866318444038650e-3; cQ.w[0] = 3.4801121234964061e-1; - cQ.x[1] = 6.9184104726922287e-2; cQ.w[1] = 3.2728554809172511e-1; - cQ.x[2] = 1.9220262418784241e-1; cQ.w[2] = 2.8945683894699143e-1; - cQ.x[3] = 3.7678938735594810e-1; cQ.w[3] = 2.4073751764332210e-1; - cQ.x[4] = 6.2301531452046157e-1; cQ.w[4] = 1.8826779554366350e-1; - cQ.x[5] = 9.3097519935847685e-1; cQ.w[5] = 1.3843298565975990e-1; - cQ.x[6] = 1.3007879104323092e0; cQ.w[6] = 9.5693623713172557e-2; - cQ.x[7] = 1.7325966449946741e0; cQ.w[7] = 6.2179086370712325e-2; - cQ.x[8] = 2.2265692364173354e0; cQ.w[8] = 3.7970908655009312e-2; - cQ.x[9] = 2.7828985168491514e0; cQ.w[9] = 2.1788109306695115e-2; - cQ.x[10] = 3.4018027370152287e0; cQ.w[10] = 1.1745069517438239e-2; - cQ.x[11] = 4.0835260453933245e0; cQ.w[11] = 5.9463917421429804e-3; - cQ.x[12] = 4.8283390293501774e0; cQ.w[12] = 2.8268077494244823e-3; - cQ.x[13] = 5.6365393211929032e0; cQ.w[13] = 1.2614066531994309e-3; - cQ.x[14] = 6.5084522724931878e0; cQ.w[14] = 5.2818895724163281e-4; - cQ.x[15] = 7.4444317004794741e0; cQ.w[15] = 2.0746547336341577e-4; - cQ.x[16] = 8.4448607107699771e0; cQ.w[16] = 7.6411540013651783e-5; - cQ.x[17] = 9.5101526012431861e0; cQ.w[17] = 2.6378489263127714e-5; - cQ.x[18] = 1.0640751852419332e1; cQ.w[18] = 8.5315214346510367e-6; - cQ.x[19] = 1.1837135210363891e1; cQ.w[19] = 2.5839402017229379e-6; - cQ.x[20] = 1.3099812868831478e1; cQ.w[20] = 7.3248237980755977e-7; - cQ.x[21] = 1.4429329758155656e1; cQ.w[21] = 1.9423835172306337e-7; - cQ.x[22] = 1.5826266949269123e1; cQ.w[22] = 4.8155353038663436e-8; - cQ.x[23] = 1.7291243182222957e1; cQ.w[23] = 1.1154712143820550e-8; - cQ.x[24] = 1.8824916529679155e1; cQ.w[24] = 2.4126359656654055e-9; - cQ.x[25] = 2.0427986207095807e1; cQ.w[25] = 4.8690306206928333e-10; - cQ.x[26] = 2.2101194542730669e1; cQ.w[26] = 9.1619835022640038e-11; - cQ.x[27] = 2.3845329122181760e1; cQ.w[27] = 1.6061727543126440e-11; - cQ.x[28] = 2.5661225123992617e1; cQ.w[28] = 2.6211365629406585e-12; - cQ.x[29] = 2.7549767864910021e1; cQ.w[29] = 3.9783127491115241e-13; - cQ.x[30] = 2.9511895575734651e1; cQ.w[30] = 5.6106664386726106e-14; - cQ.x[31] = 3.1548602431399443e1; cQ.w[31] = 7.3452477074096906e-15; - cQ.x[32] = 3.3660941862004724e1; cQ.w[32] = 8.9170156740924202e-16; - cQ.x[33] = 3.5850030175103469e1; cQ.w[33] = 1.0027003519531224e-16; - cQ.x[34] = 3.8117050523647834e1; cQ.w[34] = 1.0431576805686864e-17; - cQ.x[35] = 4.0463257258780339e1; cQ.w[35] = 1.0027987156316190e-18; - cQ.x[36] = 4.2889980712201399e1; cQ.w[36] = 8.8958541452840810e-20; - cQ.x[37] = 4.5398632459316878e1; cQ.w[37] = 7.2721294867218350e-21; - cQ.x[38] = 4.7990711121944935e1; cQ.w[38] = 5.4700089499572571e-22; - cQ.x[39] = 5.0667808778260416e1; cQ.w[39] = 3.7798889589128719e-23; - cQ.x[40] = 5.3431618058147838e1; cQ.w[40] = 2.3955393929296669e-24; - cQ.x[41] = 5.6283940014554144e1; cQ.w[41] = 1.3898975276677134e-25; - cQ.x[42] = 5.9226692876193983e1; cQ.w[42] = 7.3686649638685550e-27; - cQ.x[43] = 6.2261921804579421e1; cQ.w[43] = 3.5623617964926723e-28; - cQ.x[44] = 6.5391809799470289e1; cQ.w[44] = 1.5670671394405450e-29; - cQ.x[45] = 6.8618689922287050e1; cQ.w[45] = 6.2579202126857896e-31; - cQ.x[46] = 7.1945059037830997e1; cQ.w[46] = 2.2630134382743232e-32; - cQ.x[47] = 7.5373593312139102e1; cQ.w[47] = 7.3910051432137950e-34; - cQ.x[48] = 7.8907165750162510e1; cQ.w[48] = 2.1738965407946768e-35; - cQ.x[49] = 8.2548866113398157e1; cQ.w[49] = 5.7406301865352811e-37; - cQ.x[50] = 8.6302023627490826e1; cQ.w[50] = 1.3565280389341554e-38; - cQ.x[51] = 9.0170232976927819e1; cQ.w[51] = 2.8582178093556767e-40; - cQ.x[52] = 9.4157384193266820e1; cQ.w[52] = 5.3491017715110987e-42; - cQ.x[53] = 9.8267697181550113e1; cQ.w[53] = 8.8545200956130098e-44; - cQ.x[54] = 1.0250576180568381e2; cQ.w[54] = 1.2905303360994193e-45; - cQ.x[55] = 1.0687658467989708e2; cQ.w[55] = 1.6479024314408629e-47; - cQ.x[56] = 1.1138564410689640e2; cQ.w[56] = 1.8335510486003441e-49; - cQ.x[57] = 1.1603895498763616e2; cQ.w[57] = 1.7670959327066303e-51; - cQ.x[58] = 1.2084314603612786e2; cQ.w[58] = 1.4654679930191558e-53; - cQ.x[59] = 1.2580555231319460e2; cQ.w[59] = 1.0382012259739465e-55; - cQ.x[60] = 1.3093432701495951e2; cQ.w[60] = 6.2325264712640765e-58; - cQ.x[61] = 1.3623857771756320e2; cQ.w[61] = 3.1419744937690600e-60; - cQ.x[62] = 1.4172853404292507e2; cQ.w[62] = 1.3167216299744360e-62; - cQ.x[63] = 1.4741575620660480e2; cQ.w[63] = 4.5348612513885167e-65; - cQ.x[64] = 1.5331339750560076e2; cQ.w[64] = 1.2669383082047862e-67; - cQ.x[65] = 1.5943653908891510e2; cQ.w[65] = 2.8286860158479256e-70; - cQ.x[66] = 1.6580262329068657e2; cQ.w[66] = 4.9608576653838684e-73; - cQ.x[67] = 1.7243202402097285e2; cQ.w[67] = 6.6976362308197039e-76; - cQ.x[68] = 1.7934881203693207e2; cQ.w[68] = 6.7974784724244015e-79; - cQ.x[69] = 1.8658180447952091e2; cQ.w[69] = 5.0405265141181345e-82; - cQ.x[70] = 1.9416604151140286e2; cQ.w[70] = 2.6380873260356514e-85; - cQ.x[71] = 2.0214492732686698e2; cQ.w[71] = 9.3369329897351393e-89; - cQ.x[72] = 2.1057344821155215e2; cQ.w[72] = 2.1169241731154879e-92; - cQ.x[73] = 2.1952322632251781e2; cQ.w[73] = 2.8655194931946936e-96; - cQ.x[74] = 2.2909090256827742e2; cQ.w[74] = 2.1061692586895640e-100; - cQ.x[75] = 2.3941305411072180e2; cQ.w[75] = 7.6547423878179816e-105; - cQ.x[76] = 2.5069535780481856e2; cQ.w[76] = 4.5949033294697062e-51; - cQ.x[77] = 2.6327773413988054e2; cQ.w[77] = 6.4123032211485360e-55; - cQ.x[78] = 2.7781337017790295e2; cQ.w[78] = 2.6355344341971242e-68; - cQ.x[79] = 2.9599252372507157e2; cQ.w[79] = 4.2626228488835649e-81; - break; - case 88: - cQ.x[0] = 6.9898229051547411e-3; cQ.w[0] = 3.3209344438409325e-1; - cQ.x[1] = 6.2911728289785692e-2; cQ.w[1] = 3.1405674898440063e-1; - cQ.x[2] = 1.7477326359221082e-1; cQ.w[2] = 2.8086402575909276e-1; - cQ.x[3] = 3.4260990879552213e-1; cQ.w[3] = 2.3752476979765092e-1; - cQ.x[4] = 5.6647496129652395e-1; cQ.w[4] = 1.8994306166644856e-1; - cQ.x[5] = 8.4643962917804553e-1; cQ.w[5] = 1.4361800366234363e-1; - cQ.x[6] = 1.1825931561845759e0; cQ.w[6] = 1.0266599963917014e-1; - cQ.x[7] = 1.5750429789323641e0; cQ.w[7] = 6.9379346479544336e-2; - cQ.x[8] = 2.0239149170256255e0; cQ.w[8] = 4.4316467105237175e-2; - cQ.x[9] = 2.5293533968962740e0; cQ.w[9] = 2.6752780145097017e-2; - cQ.x[10] = 3.0915217103368590e0; cQ.w[10] = 1.5260575426000781e-2; - cQ.x[11] = 3.7106023088564040e0; cQ.w[11] = 8.2241712678339878e-3; - cQ.x[12] = 4.3867971351580078e0; cQ.w[12] = 4.1864435774652050e-3; - cQ.x[13] = 5.1203279932168699e0; cQ.w[13] = 2.0124922623294288e-3; - cQ.x[14] = 5.9114369586294842e0; cQ.w[14] = 9.1338594776452588e-4; - cQ.x[15] = 6.7603868311109156e0; cQ.w[15] = 3.9128377994473102e-4; - cQ.x[16] = 7.6674616312393195e0; cQ.w[16] = 1.5816991465628900e-4; - cQ.x[17] = 8.6329671437874178e0; cQ.w[17] = 6.0313998121755884e-5; - cQ.x[18] = 9.6572315102419724e0; cQ.w[18] = 2.1688652721856188e-5; - cQ.x[19] = 1.0740605873397186e1; cQ.w[19] = 7.3521662189359001e-6; - cQ.x[20] = 1.1883465077219540e1; cQ.w[20] = 2.3485735170662032e-6; - cQ.x[21] = 1.3086208425523377e1; cQ.w[21] = 7.0668575490339494e-7; - cQ.x[22] = 1.4349260503372554e1; cQ.w[22] = 2.0021570985018051e-7; - cQ.x[23] = 1.5673072065538298e1; cQ.w[23] = 5.3385656195939403e-8; - cQ.x[24] = 1.7058120996802116e1; cQ.w[24] = 1.3390564636227622e-8; - cQ.x[25] = 1.8504913349401250e1; cQ.w[25] = 3.1579273648368550e-9; - cQ.x[26] = 2.0013984463479417e1; cQ.w[26] = 6.9984639734477468e-10; - cQ.x[27] = 2.1585900177035253e1; cQ.w[27] = 1.4566522851312418e-10; - cQ.x[28] = 2.3221258132563997e1; cQ.w[28] = 2.8457916194634976e-11; - cQ.x[29] = 2.4920689188374744e1; cQ.w[29] = 5.2152057446839083e-12; - cQ.x[30] = 2.6684858943448156e1; cQ.w[30] = 8.9592785232829909e-13; - cQ.x[31] = 2.8514469385691634e1; cQ.w[31] = 1.4417973875868243e-13; - cQ.x[32] = 3.0410260674566840e1; cQ.w[32] = 2.1719253795631441e-14; - cQ.x[33] = 3.2373013070326923e1; cQ.w[33] = 3.0602546728763147e-15; - cQ.x[34] = 3.4403549023529919e1; cQ.w[34] = 4.0298283180374064e-16; - cQ.x[35] = 3.6502735440116345e1; cQ.w[35] = 4.9551512528428224e-17; - cQ.x[36] = 3.8671486139183441e1; cQ.w[36] = 5.6842543746643022e-18; - cQ.x[37] = 4.0910764522691699e1; cQ.w[37] = 6.0774264422552206e-19; - cQ.x[38] = 4.3221586478743604e1; cQ.w[38] = 6.0500123323576681e-20; - cQ.x[39] = 4.5605023542830377e1; cQ.w[39] = 5.6016998994982451e-21; - cQ.x[40] = 4.8062206344609867e1; cQ.w[40] = 4.8186081446164731e-22; - cQ.x[41] = 5.0594328371429292e1; cQ.w[41] = 3.8463215773862006e-23; - cQ.x[42] = 5.3202650084026280e1; cQ.w[42] = 2.8454232488178569e-24; - cQ.x[43] = 5.5888503424734049e1; cQ.w[43] = 1.9482724641523455e-25; - cQ.x[44] = 5.8653296764206622e1; cQ.w[44] = 1.2329494549301778e-26; - cQ.x[45] = 6.1498520339319444e1; cQ.w[45] = 7.2009452095564265e-28; - cQ.x[46] = 6.4425752242674225e1; cQ.w[46] = 3.8752556618667624e-29; - cQ.x[47] = 6.7436665033270514e1; cQ.w[47] = 1.9184700627092652e-30; - cQ.x[48] = 7.0533033048677930e1; cQ.w[48] = 8.7214115374171135e-32; - cQ.x[49] = 7.3716740511795214e1; cQ.w[49] = 3.6339711712303267e-33; - cQ.x[50] = 7.6989790540440737e1; cQ.w[50] = 1.3850762473413167e-34; - cQ.x[51] = 8.0354315186114501e1; cQ.w[51] = 4.8188380976506615e-36; - cQ.x[52] = 8.3812586649969540e1; cQ.w[52] = 1.5268836098287974e-37; - cQ.x[53] = 8.7367029850170202e1; cQ.w[53] = 4.3955893390762546e-39; - cQ.x[54] = 9.1020236546461036e1; cQ.w[54] = 1.1467178326064145e-40; - cQ.x[55] = 9.4774981266282465e1; cQ.w[55] = 2.7034989251018274e-42; - cQ.x[56] = 9.8634239323895773e1; cQ.w[56] = 5.7430338090994212e-44; - cQ.x[57] = 1.0260120728198211e2; cQ.w[57] = 1.0957767689227991e-45; - cQ.x[58] = 1.0667932627700808e2; cQ.w[58] = 1.8714704533178499e-47; - cQ.x[59] = 1.1087230871918132e2; cQ.w[59] = 2.8505049132116738e-49; - cQ.x[60] = 1.1518416899019180e2; cQ.w[60] = 3.8566146717396706e-51; - cQ.x[61] = 1.1961925890402067e2; cQ.w[61] = 4.6148622579363381e-53; - cQ.x[62] = 1.2418230887717554e2; cQ.w[62] = 4.8611462511088885e-55; - cQ.x[63] = 1.2887847598742982e2; cQ.w[63] = 4.4845808683072384e-57; - cQ.x[64] = 1.3371340040194700e2; cQ.w[64] = 3.6030988117615386e-59; - cQ.x[65] = 1.3869327205088259e2; cQ.w[65] = 2.5057229445134590e-61; - cQ.x[66] = 1.4382490994553306e2; cQ.w[66] = 1.4981434219579486e-63; - cQ.x[67] = 1.4911585724002039e2; cQ.w[67] = 7.6434036433722766e-66; - cQ.x[68] = 1.5457449608379523e2; cQ.w[68] = 3.3000635664912984e-68; - cQ.x[69] = 1.6021018761433266e2; cQ.w[69] = 1.1946162455653543e-70; - cQ.x[70] = 1.6603344425357073e2; cQ.w[70] = 3.5882216086453966e-73; - cQ.x[71] = 1.7205614404012268e2; cQ.w[71] = 8.8381795575894759e-76; - cQ.x[72] = 1.7829180043052003e2; cQ.w[72] = 1.7614304684723708e-78; - cQ.x[73] = 1.8475590644174345e2; cQ.w[73] = 2.7972091009100451e-81; - cQ.x[74] = 1.9146638017638173e2; cQ.w[74] = 3.4772790784565961e-84; - cQ.x[75] = 1.9844415134556974e2; cQ.w[75] = 3.3145008476708899e-87; - cQ.x[76] = 2.0571394830191976e2; cQ.w[76] = 2.3639811252252232e-90; - cQ.x[77] = 2.1330537759040182e2; cQ.w[77] = 1.2252220679209011e-93; - cQ.x[78] = 2.2125444306253341e2; cQ.w[78] = 4.4534409258766820e-97; - cQ.x[79] = 2.2960574884915661e2; cQ.w[79] = 1.0863817141918454e-100; - cQ.x[80] = 2.3841581114398289e2; cQ.w[80] = 1.6822680293726604e-104; - cQ.x[81] = 2.4775826014248507e2; cQ.w[81] = 1.5380603201854840e-108; - cQ.x[82] = 2.5773247037077271e2; cQ.w[82] = 7.5305256625793262e-113; - cQ.x[83] = 2.6847892170878440e2; cQ.w[83] = 1.7204742760900275e-117; - cQ.x[84] = 2.8020923651927812e2; cQ.w[84] = 2.4712355922645459e-52; - cQ.x[85] = 2.9327329106785954e2; cQ.w[85] = 2.0946397303280510e-50; - cQ.x[86] = 3.0834369296097073e2; cQ.w[86] = 9.0428276327931568e-65; - cQ.x[87] = 3.2716185523285862e2; cQ.w[87] = 1.9175767652062620e-79; - break; - case 96: - cQ.x[0] = 6.4088479693086173e-3; cQ.w[0] = 3.1817720207314518e-1; - cQ.x[1] = 5.7682192384603139e-2; cQ.w[1] = 3.0229450239014958e-1; - cQ.x[2] = 1.6024254224241131e-1; cQ.w[2] = 2.7286429856942241e-1; - cQ.x[3] = 3.1411723962617867e-1; cQ.w[3] = 2.3399502554972005e-1; - cQ.x[4] = 5.1934734780450853e-1; cQ.w[4] = 1.9063041737616373e-1; - cQ.x[5] = 7.7598771160231075e-1; cQ.w[5] = 1.4752978061991784e-1; - cQ.x[6] = 1.0841070382287637e0; cQ.w[6] = 1.0845245228344696e-1; - cQ.x[7] = 1.4437879988503862e0; cQ.w[7] = 7.5724332195484464e-2; - cQ.x[8] = 1.8551273512731066e0; cQ.w[8] = 5.0214141133917932e-2; - cQ.x[9] = 2.3182360841752035e0; cQ.w[9] = 3.1620089370995634e-2; - cQ.x[10] = 2.8332395834139107e0; cQ.w[10] = 1.8905681570520517e-2; - cQ.x[11] = 3.4002778210128949e0; cQ.w[11] = 1.0731321018794248e-2; - cQ.x[12] = 4.0195055675263257e0; cQ.w[12] = 5.7820073860565274e-3; - cQ.x[13] = 4.6910926285685173e0; cQ.w[13] = 2.9566179089772504e-3; - cQ.x[14] = 5.4152241063968240e0; cQ.w[14] = 1.4345733126805138e-3; - cQ.x[15] = 6.1921006875403740e0; cQ.w[15] = 6.6035034249772304e-4; - cQ.x[16] = 7.0219389575791665e0; cQ.w[16] = 2.8830782856393540e-4; - cQ.x[17] = 7.9049717442979328e0; cQ.w[17] = 1.1936254041747660e-4; - cQ.x[18] = 8.8414484905679871e0; cQ.w[18] = 4.6849104586421198e-5; - cQ.x[19] = 9.8316356584491658e0; cQ.w[19] = 1.7427730160295739e-5; - cQ.x[20] = 1.0875817166154111e1; cQ.w[20] = 6.1427630640308088e-6; - cQ.x[21] = 1.1974294859679961e1; cQ.w[21] = 2.0508762851384060e-6; - cQ.x[22] = 1.3127389021089503e1; cQ.w[22] = 6.4837954271472021e-7; - cQ.x[23] = 1.4335438915616705e1; cQ.w[23] = 1.9403784928607733e-7; - cQ.x[24] = 1.5598803379982271e1; cQ.w[24] = 5.4948470407217337e-8; - cQ.x[25] = 1.6917861454535469e1; cQ.w[25] = 1.4718810972300389e-8; - cQ.x[26] = 1.8293013062091624e1; cQ.w[26] = 3.7279041518397285e-9; - cQ.x[27] = 1.9724679736612835e1; cQ.w[27] = 8.9237873517832415e-10; - cQ.x[28] = 2.1213305405186056e1; cQ.w[28] = 2.0180598524189019e-10; - cQ.x[29] = 2.2759357227090996e1; cQ.w[29] = 4.3094025836606105e-11; - cQ.x[30] = 2.4363326494124491e1; cQ.w[30] = 8.6853173406217016e-12; - cQ.x[31] = 2.6025729596762688e1; cQ.w[31] = 1.6512638032485222e-12; - cQ.x[32] = 2.7747109061202697e1; cQ.w[32] = 2.9598835329453310e-13; - cQ.x[33] = 2.9528034662837436e1; cQ.w[33] = 4.9993510953075103e-14; - cQ.x[34] = 3.1369104622288073e1; cQ.w[34] = 7.9519688037928626e-15; - cQ.x[35] = 3.3270946890755629e1; cQ.w[35] = 1.1903810906669537e-15; - cQ.x[36] = 3.5234220532166221e1; cQ.w[36] = 1.6759557500075327e-16; - cQ.x[37] = 3.7259617210383481e1; cQ.w[37] = 2.2177113226367451e-17; - cQ.x[38] = 3.9347862790659313e1; cQ.w[38] = 2.7561280628581385e-18; - cQ.x[39] = 4.1499719065504354e1; cQ.w[39] = 3.2145199936756972e-19; - cQ.x[40] = 4.3715985616298953e1; cQ.w[40] = 3.5156800159203487e-20; - cQ.x[41] = 4.5997501823253394e1; cQ.w[41] = 3.6025990545465830e-21; - cQ.x[42] = 4.8345149037785020e1; cQ.w[42] = 3.4558483324761214e-22; - cQ.x[43] = 5.0759852933036353e1; cQ.w[43] = 3.1004532672815943e-23; - cQ.x[44] = 5.3242586050143369e1; cQ.w[44] = 2.5990033771037196e-24; - cQ.x[45] = 5.5794370560013523e1; cQ.w[45] = 2.0335626660738988e-25; - cQ.x[46] = 5.8416281262832383e1; cQ.w[46] = 1.4835853103395276e-26; - cQ.x[47] = 6.1109448850337470e1; cQ.w[47] = 1.0080516345867198e-27; - cQ.x[48] = 6.3875063459139563e1; cQ.w[48] = 6.3716760141675274e-29; - cQ.x[49] = 6.6714378547108836e1; cQ.w[49] = 3.7418231588440592e-30; - cQ.x[50] = 6.9628715129163805e1; cQ.w[50] = 2.0389207136140223e-31; - cQ.x[51] = 7.2619466413811364e1; cQ.w[51] = 1.0294436657754091e-32; - cQ.x[52] = 7.5688102887614222e1; cQ.w[52] = 4.8089946872814419e-34; - cQ.x[53] = 7.8836177901563518e1; cQ.w[53] = 2.0753148425343429e-35; - cQ.x[54] = 8.2065333821298500e1; cQ.w[54] = 8.2600326269673452e-37; - cQ.x[55] = 8.5377308812473848e1; cQ.w[55] = 3.0268879909029589e-38; - cQ.x[56] = 8.8773944343613222e1; cQ.w[56] = 1.0193701477126852e-39; - cQ.x[57] = 9.2257193501856653e1; cQ.w[57] = 3.1487953377266536e-41; - cQ.x[58] = 9.5829130232545822e1; cQ.w[58] = 8.9030283898555212e-43; - cQ.x[59] = 9.9491959632139456e1; cQ.w[59] = 2.2991067830207375e-44; - cQ.x[60] = 1.0324802944619364e2; cQ.w[60] = 5.4099632013102152e-46; - cQ.x[61] = 1.0709984295093964e2; cQ.w[61] = 1.1570760541533550e-47; - cQ.x[62] = 1.1105007342943756e2; cQ.w[62] = 2.2434027937343383e-49; - cQ.x[63] = 1.1510158049277213e2; cQ.w[63] = 3.9318356145233163e-51; - cQ.x[64] = 1.1925742854508090e2; cQ.w[64] = 6.2101615333023767e-53; - cQ.x[65] = 1.2352090775068523e2; cQ.w[65] = 8.8106771041998731e-55; - cQ.x[66] = 1.2789555793525788e2; cQ.w[66] = 1.1188872437683772e-56; - cQ.x[67] = 1.3238519594478634e2; cQ.w[67] = 1.2670287078247711e-58; - cQ.x[68] = 1.3699394710135137e2; cQ.w[68] = 1.2741754871478997e-60; - cQ.x[69] = 1.4172628154048866e2; cQ.w[69] = 1.1328848065466888e-62; - cQ.x[70] = 1.4658705640065854e2; cQ.w[70] = 8.8625846243039034e-65; - cQ.x[71] = 1.5158156507410060e2; cQ.w[71] = 6.0683384585205647e-67; - cQ.x[72] = 1.5671559503799880e2; cQ.w[72] = 3.6159126920762266e-69; - cQ.x[73] = 1.6199549619039953e2; cQ.w[73] = 1.8632314937659433e-71; - cQ.x[74] = 1.6742826215197814e2; cQ.w[74] = 8.2452068773611101e-74; - cQ.x[75] = 1.7302162771302658e2; cQ.w[75] = 3.1094858299677929e-76; - cQ.x[76] = 1.7878418657827880e2; cQ.w[76] = 9.9088925545678630e-79; - cQ.x[77] = 1.8472553489864371e2; cQ.w[77] = 2.6428813129457523e-81; - cQ.x[78] = 1.9085644794111835e2; cQ.w[78] = 5.8372225441875102e-84; - cQ.x[79] = 1.9718909988484638e2; cQ.w[79] = 1.0548005520682382e-86; - cQ.x[80] = 2.0373734053112526e2; cQ.w[80] = 1.5381913402837248e-89; - cQ.x[81] = 2.1051704829955498e2; cQ.w[81] = 1.7819545894948543e-92; - cQ.x[82] = 2.1754658727070438e2; cQ.w[82] = 1.6104009725265265e-95; - cQ.x[83] = 2.2484740894787622e2; cQ.w[83] = 1.1114881452557864e-98; - cQ.x[84] = 2.3244485984497173e2; cQ.w[84] = 5.7137871484250277e-102; - cQ.x[85] = 2.4036928938394857e2; cQ.w[85] = 2.1230825957651528e-105; - cQ.x[86] = 2.4865760911996251e2; cQ.w[86] = 5.4979966939612256e-109; - cQ.x[87] = 2.5735555421768465e2; cQ.w[87] = 9.4850943127338216e-113; - cQ.x[88] = 2.6652108371132283e2; cQ.w[88] = 1.0296088521328023e-116; - cQ.x[89] = 2.7622972228180378e2; cQ.w[89] = 6.4585972823499812e-121; - cQ.x[90] = 2.8658342409205652e2; cQ.w[90] = 1.7529595043807457e-117; - cQ.x[91] = 2.9772635225359436e2; cQ.w[91] = 3.1105665306320562e-130; - cQ.x[92] = 3.0987574005931242e2; cQ.w[92] = 2.5102657022454895e-50; - cQ.x[93] = 3.2339085777326039e2; cQ.w[93] = 1.1598746411740026e-54; - cQ.x[94] = 3.3896263242081578e2; cQ.w[94] = 1.8735722301688603e-68; - cQ.x[95] = 3.5838071121369978e2; cQ.w[95] = 3.6413912508706140e-80; - break; - case 104: - cQ.x[0] = 5.9170399902629313e-3; cQ.w[0] = 3.0587540675027521e-1; - cQ.x[1] = 5.3255375119357608e-2; cQ.w[1] = 2.9174971091826186e-1; - cQ.x[2] = 1.4794279594504654e-1; cQ.w[2] = 2.6542237352386527e-1; - cQ.x[3] = 2.9000081703620763e-1; cQ.w[3] = 2.3031197872444814e-1; - cQ.x[4] = 4.7946174387139034e-1; cQ.w[4] = 1.9060462767137745e-1; - cQ.x[5] = 7.1636871330281893e-1; cQ.w[5] = 1.5044217126994679e-1; - cQ.x[6] = 1.0007757476986113e0; cQ.w[6] = 1.1324045142276644e-1; - cQ.x[7] = 1.3327478229276096e0; cQ.w[7] = 8.1283295752663497e-2; - cQ.x[8] = 1.7123609503940247e0; cQ.w[8] = 5.5633427651614899e-2; - cQ.x[9] = 2.1397022733730653e0; cQ.w[9] = 3.6305080311286526e-2; - cQ.x[10] = 2.6148701779441033e0; cQ.w[10] = 2.2586734959646651e-2; - cQ.x[11] = 3.1379744188649923e0; cQ.w[11] = 1.3395115370766690e-2; - cQ.x[12] = 3.7091362607801872e0; cQ.w[12] = 7.5717088395729501e-3; - cQ.x[13] = 4.3284886352066046e0; cQ.w[13] = 4.0788547539583762e-3; - cQ.x[14] = 4.9961763137950506e0; cQ.w[14] = 2.0937112294538550e-3; - cQ.x[15] = 5.7123560984218524e0; cQ.w[15] = 1.0239096611160486e-3; - cQ.x[16] = 6.4771970287254551e0; cQ.w[16] = 4.7697940575163359e-4; - cQ.x[17] = 7.2908806077665737e0; cQ.w[17] = 2.1161778351897556e-4; - cQ.x[18] = 8.1536010465584800e0; cQ.w[18] = 8.9399513582116538e-5; - cQ.x[19] = 9.0655655282866201e0; cQ.w[19] = 3.5954968465819779e-5; - cQ.x[20] = 1.0026994493114549e1; cQ.w[20] = 1.3763471639247608e-5; - cQ.x[21] = 1.1038121944556697e1; cQ.w[21] = 5.0135007842022910e-6; - cQ.x[22] = 1.2099195778488418e1; cQ.w[22] = 1.7373642266442212e-6; - cQ.x[23] = 1.3210478135960773e1; cQ.w[23] = 5.7261651269671511e-7; - cQ.x[24] = 1.4372245781092441e1; cQ.w[24] = 1.7944867221251103e-7; - cQ.x[25] = 1.5584790505424801e1; cQ.w[25] = 5.3455660388561925e-8; - cQ.x[26] = 1.6848419560249673e1; cQ.w[26] = 1.5131821405551822e-8; - cQ.x[27] = 1.8163456118553402e1; cQ.w[27] = 4.0690485475645235e-9; - cQ.x[28] = 1.9530239768367304e1; cQ.w[28] = 1.0390864670042617e-9; - cQ.x[29] = 2.0949127039474128e1; cQ.w[29] = 2.5189139018781987e-10; - cQ.x[30] = 2.2420491965594827e1; cQ.w[30] = 5.7944986530631928e-11; - cQ.x[31] = 2.3944726684371185e1; cQ.w[31] = 1.2644148134587503e-11; - cQ.x[32] = 2.5522242077669684e1; cQ.w[32] = 2.6161135978115952e-12; - cQ.x[33] = 2.7153468454962594e1; cQ.w[33] = 5.1301572545741211e-13; - cQ.x[34] = 2.8838856282796113e1; cQ.w[34] = 9.5305252540215033e-14; - cQ.x[35] = 3.0578876963635225e1; cQ.w[35] = 1.6765288843561763e-14; - cQ.x[36] = 3.2374023667684009e1; cQ.w[36] = 2.7912570841914264e-15; - cQ.x[37] = 3.4224812221621939e1; cQ.w[37] = 4.3960232489011666e-16; - cQ.x[38] = 3.6131782058575501e1; cQ.w[38] = 6.5457287737442617e-17; - cQ.x[39] = 3.8095497234064709e1; cQ.w[39] = 9.2097916367430484e-18; - cQ.x[40] = 4.0116547513131397e1; cQ.w[40] = 1.2237146175390552e-18; - cQ.x[41] = 4.2195549534376423e1; cQ.w[41] = 1.5345540324461345e-19; - cQ.x[42] = 4.4333148057213359e1; cQ.w[42] = 1.8150011522883905e-20; - cQ.x[43] = 4.6530017299294814e1; cQ.w[43] = 2.0233572060917363e-21; - cQ.x[44] = 4.8786862371793691e1; cQ.w[44] = 2.1245357575136396e-22; - cQ.x[45] = 5.1104420821036147e1; cQ.w[45] = 2.0995790452740547e-23; - cQ.x[46] = 5.3483464285898315e1; cQ.w[46] = 1.9513862776804163e-24; - cQ.x[47] = 5.5924800281409502e1; cQ.w[47] = 1.7043065745685083e-25; - cQ.x[48] = 5.8429274120167462e1; cQ.w[48] = 1.3975904770003455e-26; - cQ.x[49] = 6.0997770984486184e1; cQ.w[49] = 1.0751199957435543e-27; - cQ.x[50] = 6.3631218163686521e1; cQ.w[50] = 7.7513543786225607e-29; - cQ.x[51] = 6.6330587472631968e1; cQ.w[51] = 5.2326478018346559e-30; - cQ.x[52] = 6.9096897869537813e1; cQ.w[52] = 3.3040599143163473e-31; - cQ.x[53] = 7.1931218293279340e1; cQ.w[53] = 1.9493708377000895e-32; - cQ.x[54] = 7.4834670742938227e1; cQ.w[54] = 1.0734353038941787e-33; - cQ.x[55] = 7.7808433625208567e1; cQ.w[55] = 5.5103919609823204e-35; - cQ.x[56] = 8.0853745398597933e1; cQ.w[56] = 2.6337753192506890e-36; - cQ.x[57] = 8.3971908547179854e1; cQ.w[57] = 1.1705805971768911e-37; - cQ.x[58] = 8.7164293921072095e1; cQ.w[58] = 4.8312277173311803e-39; - cQ.x[59] = 9.0432345485938809e1; cQ.w[59] = 1.8489404848533130e-40; - cQ.x[60] = 9.3777585529775213e1; cQ.w[60] = 6.5514799851540860e-42; - cQ.x[61] = 9.7201620382189983e1; cQ.w[61] = 2.1459149564917285e-43; - cQ.x[62] = 1.0070614670954704e2; cQ.w[62] = 6.4864747764771309e-45; - cQ.x[63] = 1.0429295845890204e2; cQ.w[63] = 1.8061451197301461e-46; - cQ.x[64] = 1.0796395453496108e2; cQ.w[64] = 4.6240601087164368e-48; - cQ.x[65] = 1.1172114730766026e2; cQ.w[65] = 1.0863042774855916e-49; - cQ.x[66] = 1.1556667206386112e2; cQ.w[66] = 2.3367590047772692e-51; - cQ.x[67] = 1.1950279753563604e2; cQ.w[67] = 4.5923018372463456e-53; - cQ.x[68] = 1.2353193766037873e2; cQ.w[68] = 8.2254183241711378e-55; - cQ.x[69] = 1.2765666475539859e2; cQ.w[69] = 1.3393229733255628e-56; - cQ.x[70] = 1.3187972432286344e2; cQ.w[70] = 1.9770897715441433e-58; - cQ.x[71] = 1.3620405174137066e2; cQ.w[71] = 2.6382340385810416e-60; - cQ.x[72] = 1.4063279114988850e2; cQ.w[72] = 3.1724019756972273e-62; - cQ.x[73] = 1.4516931689069355e2; cQ.w[73] = 3.4260518574631090e-64; - cQ.x[74] = 1.4981725795333762e2; cQ.w[74] = 3.3110336284062607e-66; - cQ.x[75] = 1.5458052595568164e2; cQ.w[75] = 2.8523873910804969e-68; - cQ.x[76] = 1.5946334731603723e2; cQ.w[76] = 2.1812446026410382e-70; - cQ.x[77] = 1.6447030041968208e2; cQ.w[77] = 1.4739245558990479e-72; - cQ.x[78] = 1.6960635877321616e2; cQ.w[78] = 8.7573978000268771e-75; - cQ.x[79] = 1.7487694138470448e2; cQ.w[79] = 4.5505714966004102e-77; - cQ.x[80] = 1.8028797192464818e2; cQ.w[80] = 2.0558561295409975e-79; - cQ.x[81] = 1.8584594863812376e2; cQ.w[81] = 8.0232998204915563e-82; - cQ.x[82] = 1.9155802752806165e2; cQ.w[82] = 2.6857246723649169e-84; - cQ.x[83] = 1.9743212206533502e2; cQ.w[83] = 7.6508024905351989e-87; - cQ.x[84] = 2.0347702367824598e2; cQ.w[84] = 1.8386578992442195e-89; - cQ.x[85] = 2.0970254864305275e2; cQ.w[85] = 3.6915967746713164e-92; - cQ.x[86] = 2.1611971890494698e2; cQ.w[86] = 6.1249132399226474e-95; - cQ.x[87] = 2.2274098706028915e2; cQ.w[87] = 8.2946217677700358e-98; - cQ.x[88] = 2.2958051962428511e2; cQ.w[88] = 9.0408055705882247e-101; - cQ.x[89] = 2.3665455843056904e2; cQ.w[89] = 7.8044833919279015e-104; - cQ.x[90] = 2.4398188860512600e2; cQ.w[90] = 5.2375692667980381e-107; - cQ.x[91] = 2.5158445479007743e2; cQ.w[91] = 2.6738203410490589e-110; - cQ.x[92] = 2.5948818823677792e2; cQ.w[92] = 1.0120749135417976e-113; - cQ.x[93] = 2.6772414159918294e2; cQ.w[93] = 2.7544888677231600e-117; - cQ.x[94] = 2.7633008621234766e2; cQ.w[94] = 5.1929686996596160e-121; - cQ.x[95] = 2.8535282906339674e2; cQ.w[95] = 6.4755792717472659e-125; - cQ.x[96] = 2.9485169696486133e2; cQ.w[96] = 5.0218621637969880e-129; - cQ.x[97] = 3.0490401093647767e2; cQ.w[97] = 1.9758139579198723e-133; - cQ.x[98] = 3.1561417142961915e2; cQ.w[98] = 2.6170200395803803e-134; - cQ.x[99] = 3.2712983445040887e2; cQ.w[99] = 2.0394890255436422e-51; - cQ.x[100] = 3.3967355383586156e2; cQ.w[100] = 1.9410589620744451e-56; - cQ.x[101] = 3.5361350610111344e2; cQ.w[101] = 1.9061593758307076e-70; - cQ.x[102] = 3.6965798176808293e2; cQ.w[102] = 9.4662691701560053e-80; - cQ.x[103] = 3.8964232774217858e2; cQ.w[103] = 1.1104725813752798e-82; - break; - case 112: - cQ.x[0] = 5.4953341803301609e-3; cQ.w[0] = 2.9489826922398073e-1; - cQ.x[1] = 4.9459621920962637e-2; cQ.w[1] = 2.8222796178145113e-1; - cQ.x[2] = 1.3739680892391444e-1; cQ.w[2] = 2.5849487746587741e-1; - cQ.x[3] = 2.6932412751335894e-1; cQ.w[3] = 2.2657942282144552e-1; - cQ.x[4] = 4.4526744940170549e-1; cQ.w[4] = 1.9006161252137982e-1; - cQ.x[5] = 6.6526131362871422e-1; cQ.w[5] = 1.5256636998998856e-1; - cQ.x[6] = 9.2934896392688816e-1; cQ.w[6] = 1.1719118584424322e-1; - cQ.x[7] = 1.2375823956108998e0; cQ.w[7] = 8.6135126997093899e-2; - cQ.x[8] = 1.5900224121141247e0; cQ.w[8] = 6.0574317417714514e-2; - cQ.x[9] = 1.9867386913212612e0; cQ.w[9] = 4.0755803971739961e-2; - cQ.x[10] = 2.4278098618726480e0; cQ.w[10] = 2.6233066082736348e-2; - cQ.x[11] = 2.9133235896433742e0; cQ.w[11] = 1.6152112426163087e-2; - cQ.x[12] = 3.4433766746287615e0; cQ.w[12] = 9.5123620147754134e-3; - cQ.x[13] = 4.0180751584974267e0; cQ.w[13] = 5.3577229622045945e-3; - cQ.x[14] = 4.6375344431040623e0; cQ.w[14] = 2.8857253991993310e-3; - cQ.x[15] = 5.3018794202864780e0; cQ.w[15] = 1.4861359153491582e-3; - cQ.x[16] = 6.0112446133054996e0; cQ.w[16] = 7.3169919995809469e-4; - cQ.x[17] = 6.7657743303222200e0; cQ.w[17] = 3.4436155411986205e-4; - cQ.x[18] = 7.5656228303450516e0; cQ.w[18] = 1.5489520162150497e-4; - cQ.x[19] = 8.4109545021192616e0; cQ.w[19] = 6.6578086192592747e-5; - cQ.x[20] = 9.3019440564744304e0; cQ.w[20] = 2.7341291782963178e-5; - cQ.x[21] = 1.0238776732690826e1; cQ.w[21] = 1.0725583190203260e-5; - cQ.x[22] = 1.1221648519494320e1; cQ.w[22] = 4.0183900973494323e-6; - cQ.x[23] = 1.2250766391341530e1; cQ.w[23] = 1.4375499392088491e-6; - cQ.x[24] = 1.3326348560712631e1; cQ.w[24] = 4.9095191796603443e-7; - cQ.x[25] = 1.4448624747189284e1; cQ.w[25] = 1.6002973367034795e-7; - cQ.x[26] = 1.5617836464159565e1; cQ.w[26] = 4.9774112595986853e-8; - cQ.x[27] = 1.6834237324061373e1; cQ.w[27] = 1.4768543773235768e-8; - cQ.x[28] = 1.8098093363150867e1; cQ.w[28] = 4.1791497540829771e-9; - cQ.x[29] = 1.9409683386863716e1; cQ.w[29] = 1.1275442160204611e-9; - cQ.x[30] = 2.0769299336924940e1; cQ.w[30] = 2.8996675589492684e-10; - cQ.x[31] = 2.2177246681458568e1; cQ.w[31] = 7.1055803679543191e-11; - cQ.x[32] = 2.3633844829452103e1; cQ.w[32] = 1.6586292637190786e-11; - cQ.x[33] = 2.5139427571043608e1; cQ.w[33] = 3.6868289748704489e-12; - cQ.x[34] = 2.6694343545222255e1; cQ.w[34] = 7.8011677084046385e-13; - cQ.x[35] = 2.8298956736667379e1; cQ.w[35] = 1.5707664005052362e-13; - cQ.x[36] = 2.9953647003597728e1; cQ.w[36] = 3.0084617930185426e-14; - cQ.x[37] = 3.1658810638663093e1; cQ.w[37] = 5.4788162867425923e-15; - cQ.x[38] = 3.3414860965086388e1; cQ.w[38] = 9.4832975673093346e-16; - cQ.x[39] = 3.5222228970457193e1; cQ.w[39] = 1.5594657436863047e-16; - cQ.x[40] = 3.7081363980789887e1; cQ.w[40] = 2.4352390869127641e-17; - cQ.x[41] = 3.8992734377692841e1; cQ.w[41] = 3.6095571137034836e-18; - cQ.x[42] = 4.0956828361752369e1; cQ.w[42] = 5.0757642386344912e-19; - cQ.x[43] = 4.2974154765518962e1; cQ.w[43] = 6.7680555851412924e-20; - cQ.x[44] = 4.5045243919797104e1; cQ.w[44] = 8.5528682924618337e-21; - cQ.x[45] = 4.7170648577287264e1; cQ.w[45] = 1.0237779829567897e-21; - cQ.x[46] = 4.9350944898013731e1; cQ.w[46] = 1.1601029671831009e-22; - cQ.x[47] = 5.1586733501399526e1; cQ.w[47] = 1.2437241818417510e-23; - cQ.x[48] = 5.3878640590325199e1; cQ.w[48] = 1.2607163390079573e-24; - cQ.x[49] = 5.6227319153038116e1; cQ.w[49] = 1.2075186187234281e-25; - cQ.x[50] = 5.8633450249370054e1; cQ.w[50] = 1.0920906578859209e-26; - cQ.x[51] = 6.1097744388381858e1; cQ.w[51] = 9.3197543545708300e-28; - cQ.x[52] = 6.3620943005294023e1; cQ.w[52] = 7.4991199467470311e-29; - cQ.x[53] = 6.6203820046392479e1; cQ.w[53] = 5.6851415515118275e-30; - cQ.x[54] = 6.8847183671532207e1; cQ.w[54] = 4.0573989053601805e-31; - cQ.x[55] = 7.1551878084912556e1; cQ.w[55] = 2.7237314698332196e-32; - cQ.x[56] = 7.4318785505984439e1; cQ.w[56] = 1.7183408111964119e-33; - cQ.x[57] = 7.7148828293691083e1; cQ.w[57] = 1.0178497763141794e-34; - cQ.x[58] = 8.0042971238764368e1; cQ.w[58] = 5.6554871509106191e-36; - cQ.x[59] = 8.3002224040525493e1; cQ.w[59] = 2.9446351279717004e-37; - cQ.x[60] = 8.6027643986604472e1; cQ.w[60] = 1.4351943180018244e-38; - cQ.x[61] = 8.9120338856236006e1; cQ.w[61] = 6.5407638433990210e-40; - cQ.x[62] = 9.2281470070355184e1; cQ.w[62] = 2.7840843888220453e-41; - cQ.x[63] = 9.5512256114659083e1; cQ.w[63] = 1.1054661469676639e-42; - cQ.x[64] = 9.8813976265183997e1; cQ.w[64] = 4.0894445809546643e-44; - cQ.x[65] = 1.0218797464984955e2; cQ.w[65] = 1.4075301928520080e-45; - cQ.x[66] = 1.0563566468393243e2; cQ.w[66] = 4.5010556553905317e-47; - cQ.x[67] = 1.0915853392266498e2; cQ.w[67] = 1.3353375262485678e-48; - cQ.x[68] = 1.1275814938024115e2; cQ.w[68] = 3.6695275610607160e-50; - cQ.x[69] = 1.1643616337161760e2; cQ.w[69] = 9.3251810053654335e-52; - cQ.x[70] = 1.2019431994181835e2; cQ.w[70] = 2.1876527359441781e-53; - cQ.x[71] = 1.2403446195723057e2; cQ.w[71] = 4.7290816436201351e-55; - cQ.x[72] = 1.2795853894491414e2; cQ.w[72] = 9.4017744393225470e-57; - cQ.x[73] = 1.3196861577960725e2; cQ.w[73] = 1.7154770732070957e-58; - cQ.x[74] = 1.3606688233435014e2; cQ.w[74] = 2.8665242731015198e-60; - cQ.x[75] = 1.4025566423003982e2; cQ.w[75] = 4.3763989573541065e-62; - cQ.x[76] = 1.4453743484248376e2; cQ.w[76] = 6.0897571742385102e-64; - cQ.x[77] = 1.4891482875354178e2; cQ.w[77] = 7.7031170730276684e-66; - cQ.x[78] = 1.5339065686687570e2; cQ.w[78] = 8.8328749793303574e-68; - cQ.x[79] = 1.5796792345012664e2; cQ.w[79] = 9.1539586505379100e-70; - cQ.x[80] = 1.6264984541588618e2; cQ.w[80] = 8.5466832132929860e-72; - cQ.x[81] = 1.6743987421605101e2; cQ.w[81] = 7.1643610696800221e-74; - cQ.x[82] = 1.7234172080122024e2; cQ.w[82] = 5.3721243887414992e-76; - cQ.x[83] = 1.7735938419287581e2; cQ.w[83] = 3.5890274005464772e-78; - cQ.x[84] = 1.8249718433670430e2; cQ.w[84] = 2.1271822587291959e-80; - cQ.x[85] = 1.8775980005795738e2; cQ.w[85] = 1.1132951771397071e-82; - cQ.x[86] = 1.9315231313418438e2; cQ.w[86] = 5.1191820200621500e-85; - cQ.x[87] = 1.9868025975060599e2; cQ.w[87] = 2.0567744853280919e-87; - cQ.x[88] = 2.0434969092759117e2; cQ.w[88] = 7.1772526649596168e-90; - cQ.x[89] = 2.1016724393431546e2; cQ.w[89] = 2.1609888032718971e-92; - cQ.x[90] = 2.1614022726467649e2; cQ.w[90] = 5.5733711965802891e-95; - cQ.x[91] = 2.2227672250383794e2; cQ.w[91] = 1.2214353570041591e-97; - cQ.x[92] = 2.2858570743324025e2; cQ.w[92] = 2.2544498870469226e-100; - cQ.x[93] = 2.3507720612202630e2; cQ.w[93] = 3.4698364983238705e-103; - cQ.x[94] = 2.4176247370399097e2; cQ.w[94] = 4.4037992320193089e-106; - cQ.x[95] = 2.4865422630218547e2; cQ.w[95] = 4.5511410854658978e-109; - cQ.x[96] = 2.5576693054575381e2; cQ.w[96] = 3.7753744367507348e-112; - cQ.x[97] = 2.6311717297716247e2; cQ.w[97] = 2.4729177063662401e-115; - cQ.x[98] = 2.7072413844178640e2; cQ.w[98] = 1.2549250228724467e-118; - cQ.x[99] = 2.7861024009039942e2; cQ.w[99] = 4.8255791873729851e-122; - cQ.x[100] = 2.8680196505406753e2; cQ.w[100] = 1.3697149157065236e-125; - cQ.x[101] = 2.9533103485728541e2; cQ.w[101] = 2.7803242111394275e-129; - cQ.x[102] = 3.0423603893997241e2; cQ.w[102] = 5.7192111543195200e-133; - cQ.x[103] = 3.1356480447692787e2; cQ.w[103] = 2.7224139503928083e-135; - cQ.x[104] = 3.2337796045230511e2; cQ.w[104] = 1.4985049959339292e-124; - cQ.x[105] = 3.3375453828748506e2; cQ.w[105] = 2.4300435849929846e-132; - cQ.x[106] = 3.4480126780658105e2; cQ.w[106] = 1.2259326780033627e-133; - cQ.x[107] = 3.5666913087724963e2; cQ.w[107] = 2.4281860924963857e-51; - cQ.x[108] = 3.6958574691724203e2; cQ.w[108] = 1.3766733748904064e-55; - cQ.x[109] = 3.8392777037966436e2; cQ.w[109] = 5.9376811746370755e-69; - cQ.x[110] = 4.0042001600670709e2; cQ.w[110] = 2.6857350954106024e-82; - cQ.x[111] = 4.2094130637188611e2; cQ.w[111] = 2.9834955778444689e-81; - break; - case 120: - cQ.x[0] = 5.1297391669498222e-3; cQ.w[0] = 2.8502395317547204e-1; - cQ.x[1] = 4.6168965558965583e-2; cQ.w[1] = 2.7357523293518048e-1; - cQ.x[2] = 1.2825442268012189e-1; cQ.w[2] = 2.5203716182373969e-1; - cQ.x[3] = 2.5140012578184619e-1; cQ.w[3] = 2.2286337164152000e-1; - cQ.x[4] = 4.1562711419913549e-1; cQ.w[4] = 1.8914288655924106e-1; - cQ.x[5] = 6.2096347114179658e-1; cQ.w[5] = 1.5406584277742807e-1; - cQ.x[6] = 8.6744435015264118e-1; cQ.w[6] = 1.2044049267022821e-1; - cQ.x[7] = 1.1551120082929025e0; cQ.w[7] = 9.0358744219355181e-2; - cQ.x[8] = 1.4840158461306763e0; cQ.w[8] = 6.5054591666537773e-2; - cQ.x[9] = 1.8542124546240439e0; cQ.w[9] = 4.4943958036852311e-2; - cQ.x[10] = 2.2657656690067761e0; cQ.w[10] = 2.9793575056951512e-2; - cQ.x[11] = 2.7187466298012132e0; cQ.w[11] = 1.8949643702576734e-2; - cQ.x[12] = 3.2132338511001456e0; cQ.w[12] = 1.1563055121878621e-2; - cQ.x[13] = 3.7493132962773567e0; cQ.w[13] = 6.7686183318686482e-3; - cQ.x[14] = 4.3270784613050146e0; cQ.w[14] = 3.8005184078890596e-3; - cQ.x[15] = 4.9466304658754044e0; cQ.w[15] = 2.0467143746931182e-3; - cQ.x[16] = 5.6080781525446617e0; cQ.w[16] = 1.0570513354181031e-3; - cQ.x[17] = 6.3115381941373083e0; cQ.w[17] = 5.2349052163887461e-4; - cQ.x[18] = 7.0571352096725975e0; cQ.w[18] = 2.4856586787767428e-4; - cQ.x[19] = 7.8450018890970696e0; cQ.w[19] = 1.1314532553553562e-4; - cQ.x[20] = 8.6752791271324176e0; cQ.w[20] = 4.9366594298931427e-5; - cQ.x[21] = 9.5481161665738945e0; cQ.w[21] = 2.0642700128290312e-5; - cQ.x[22] = 1.0463670751402208e1; cQ.w[22] = 8.2711958203927816e-6; - cQ.x[23] = 1.1422109290101294e1; cQ.w[23] = 3.1751663936728944e-6; - cQ.x[24] = 1.2423607029605695e1; cQ.w[24] = 1.1675760027782005e-6; - cQ.x[25] = 1.3468348240334714e1; cQ.w[25] = 4.1119185727034140e-7; - cQ.x[26] = 1.4556526412806197e1; cQ.w[26] = 1.3866304189070192e-7; - cQ.x[27] = 1.5688344466361026e1; cQ.w[27] = 4.4765756397348091e-8; - cQ.x[28] = 1.6864014970570331e1; cQ.w[28] = 1.3832734889608059e-8; - cQ.x[29] = 1.8083760379941373e1; cQ.w[29] = 4.0902585285705370e-9; - cQ.x[30] = 1.9347813282585301e1; cQ.w[30] = 1.1571064421471916e-9; - cQ.x[31] = 2.0656416663560776e1; cQ.w[31] = 3.1309092427946476e-10; - cQ.x[32] = 2.2009824183662284e1; cQ.w[32] = 8.1008838545649928e-11; - cQ.x[33] = 2.3408300474481054e1; cQ.w[33] = 2.0037543940941961e-11; - cQ.x[34] = 2.4852121450630391e1; cQ.w[34] = 4.7368238655988873e-12; - cQ.x[35] = 2.6341574640096350e1; cQ.w[35] = 1.0698826247166949e-12; - cQ.x[36] = 2.7876959533749559e1; cQ.w[36] = 2.3081364934421758e-13; - cQ.x[37] = 2.9458587955135198e1; cQ.w[37] = 4.7547562946209405e-14; - cQ.x[38] = 3.1086784451746349e1; cQ.w[38] = 9.3496621251942795e-15; - cQ.x[39] = 3.2761886709081786e1; cQ.w[39] = 1.7543580097101897e-15; - cQ.x[40] = 3.4484245988893703e1; cQ.w[40] = 3.1400971154418774e-16; - cQ.x[41] = 3.6254227593144597e1; cQ.w[41] = 5.3593522678761522e-17; - cQ.x[42] = 3.8072211355316697e1; cQ.w[42] = 8.7188945766817631e-18; - cQ.x[43] = 3.9938592160852983e1; cQ.w[43] = 1.3515106234226978e-18; - cQ.x[44] = 4.1853780498657202e1; cQ.w[44] = 1.9953021921306626e-19; - cQ.x[45] = 4.3818203045742856e1; cQ.w[45] = 2.8044282474471764e-20; - cQ.x[46] = 4.5832303287299388e1; cQ.w[46] = 3.7508906971614997e-21; - cQ.x[47] = 4.7896542174639558e1; cQ.w[47] = 4.7717681635147569e-22; - cQ.x[48] = 5.0011398823707265e1; cQ.w[48] = 5.7712738310619112e-23; - cQ.x[49] = 5.2177371257062108e1; cQ.w[49] = 6.6327836836945849e-24; - cQ.x[50] = 5.4394977192518312e1; cQ.w[50] = 7.2398182117815891e-25; - cQ.x[51] = 5.6664754881904218e1; cQ.w[51] = 7.5012587727931265e-26; - cQ.x[52] = 5.8987264003727612e1; cQ.w[52] = 7.3734885029706274e-27; - cQ.x[53] = 6.1363086613885492e1; cQ.w[53] = 6.8721443844602975e-28; - cQ.x[54] = 6.3792828158948708e1; cQ.w[54] = 6.0691779183687126e-29; - cQ.x[55] = 6.6277118556987132e1; cQ.w[55] = 5.0759007367076133e-30; - cQ.x[56] = 6.8816613351385211e1; cQ.w[56] = 4.0175221438220706e-31; - cQ.x[57] = 7.1411994943637213e1; cQ.w[57] = 3.0072530813297540e-32; - cQ.x[58] = 7.4063973911713684e1; cQ.w[58] = 2.1273584216828318e-33; - cQ.x[59] = 7.6773290421263832e1; cQ.w[59] = 1.4211829797498313e-34; - cQ.x[60] = 7.9540715737672631e1; cQ.w[60] = 8.9590957177462511e-36; - cQ.x[61] = 8.2367053847837527e1; cQ.w[61] = 5.3251918761543396e-37; - cQ.x[62] = 8.5253143201480774e1; cQ.w[62] = 2.9819503451853612e-38; - cQ.x[63] = 8.8199858582884791e1; cQ.w[63] = 1.5717412988204925e-39; - cQ.x[64] = 9.1208113125147039e1; cQ.w[64] = 7.7908008505381426e-41; - cQ.x[65] = 9.4278860480418384e1; cQ.w[65] = 3.6281971412784443e-42; - cQ.x[66] = 9.7413097161138711e1; cQ.w[66] = 1.5859015177178711e-43; - cQ.x[67] = 1.0061186506904395e2; cQ.w[67] = 6.4996104375459879e-45; - cQ.x[68] = 1.0387625423072283e2; cQ.w[68] = 2.4948970341280962e-46; - cQ.x[69] = 1.0720740576078862e2; cQ.w[69] = 8.9593901038397884e-48; - cQ.x[70] = 1.1060651507634780e2; cQ.w[70] = 3.0064061869829462e-49; - cQ.x[71] = 1.1407483538944766e2; cQ.w[71] = 9.4149529210783543e-51; - cQ.x[72] = 1.1761368150763627e2; cQ.w[72] = 2.7480284196099378e-52; - cQ.x[73] = 1.2122443397674619e2; cQ.w[73] = 7.4655144872656008e-54; - cQ.x[74] = 1.2490854360461544e2; cQ.w[74] = 1.8849778633354656e-55; - cQ.x[75] = 1.2866753640979513e2; cQ.w[75] = 4.4167295028366118e-57; - cQ.x[76] = 1.3250301904550293e2; cQ.w[76] = 9.5884544111130115e-59; - cQ.x[77] = 1.3641668475632833e2; cQ.w[77] = 1.9253846157160579e-60; - cQ.x[78] = 1.4041031993368383e2; cQ.w[78] = 3.5697275921210464e-62; - cQ.x[79] = 1.4448581134597201e2; cQ.w[79] = 6.0993788510648131e-64; - cQ.x[80] = 1.4864515413120591e2; cQ.w[80] = 9.5853191608176058e-66; - cQ.x[81] = 1.5289046065375615e2; cQ.w[81] = 1.3825627736640795e-67; - cQ.x[82] = 1.5722397034346682e2; cQ.w[82] = 1.8262174400320119e-69; - cQ.x[83] = 1.6164806065516658e2; cQ.w[83] = 2.2038494574755515e-71; - cQ.x[84] = 1.6616525931033000e2; cQ.w[84] = 2.4237108166704223e-73; - cQ.x[85] = 1.7077825801123656e2; cQ.w[85] = 2.4226238499885409e-75; - cQ.x[86] = 1.7548992785259882e2; cQ.w[86] = 2.1946080740100573e-77; - cQ.x[87] = 1.8030333669777762e2; cQ.w[87] = 1.7962565586872283e-79; - cQ.x[88] = 1.8522176883828634e2; cQ.w[88] = 1.3240410388018822e-81; - cQ.x[89] = 1.9024874731879046e2; cQ.w[89] = 8.7585968525902169e-84; - cQ.x[90] = 1.9538805938846759e2; cQ.w[90] = 5.1800274294960421e-86; - cQ.x[91] = 2.0064378563766165e2; cQ.w[91] = 2.7279222749641292e-88; - cQ.x[92] = 2.0602033350188195e2; cQ.w[92] = 1.2735953172719079e-90; - cQ.x[93] = 2.1152247597090631e2; cQ.w[93] = 5.2465045442237418e-93; - cQ.x[94] = 2.1715539653923255e2; cQ.w[94] = 1.8971890062657397e-95; - cQ.x[95] = 2.2292474168927554e2; cQ.w[95] = 5.9884763458065071e-98; - cQ.x[96] = 2.2883668252968495e2; cQ.w[96] = 1.6399282759538974e-100; - cQ.x[97] = 2.3489798764468268e2; cQ.w[97] = 3.8700481929789787e-103; - cQ.x[98] = 2.4111610978413709e2; cQ.w[98] = 7.8122606315689856e-106; - cQ.x[99] = 2.4749928979224946e2; cQ.w[99] = 1.3379893855632987e-108; - cQ.x[100] = 2.5405668221374821e2; cQ.w[100] = 1.9266285323004829e-111; - cQ.x[101] = 2.6079850844627440e2; cQ.w[101] = 2.3089140588011642e-114; - cQ.x[102] = 2.6773624530027240e2; cQ.w[102] = 2.2768662844496908e-117; - cQ.x[103] = 2.7488285964960641e2; cQ.w[103] = 1.8239060669490364e-120; - cQ.x[104] = 2.8225310392367891e2; cQ.w[104] = 1.1696325620584706e-123; - cQ.x[105] = 2.8986389317085953e2; cQ.w[105] = 5.9089203696565755e-127; - cQ.x[106] = 2.9773479340583953e2; cQ.w[106] = 2.3982393520466646e-130; - cQ.x[107] = 3.0588866478394910e2; cQ.w[107] = 1.3336608988109749e-133; - cQ.x[108] = 3.1435252503773286e2; cQ.w[108] = 1.8554662333955921e-131; - cQ.x[109] = 3.2315873437660234e2; cQ.w[109] = 5.6745552433723977e-133; - cQ.x[110] = 3.3234666364534706e2; cQ.w[110] = 6.4148023503115847e-132; - cQ.x[111] = 3.4196511464296833e2; cQ.w[111] = 1.7690546779468858e-132; - cQ.x[112] = 3.5207596053730912e2; cQ.w[112] = 2.3559424075535023e-133; - cQ.x[113] = 3.6275986709694166e2; cQ.w[113] = 7.0346860953952109e-133; - cQ.x[114] = 3.7412578995211861e2; cQ.w[114] = 8.2581860285237120e-132; - cQ.x[115] = 3.8632788878085670e2; cQ.w[115] = 3.8298599230421540e-49; - cQ.x[116] = 3.9959862252409562e2; cQ.w[116] = 8.6830434227075531e-52; - cQ.x[117] = 4.1432274380983757e2; cQ.w[117] = 7.8569306274869450e-66; - cQ.x[118] = 4.3124084763817151e2; cQ.w[118] = 1.0876766815421296e-79; - cQ.x[119] = 4.5227326181239169e2; cQ.w[119] = 1.7576416430685541e-80; - break; - case 128: - cQ.x[0] = 4.8097546269833893e-3; cQ.w[0] = 2.7607937255104182e-1; - cQ.x[1] = 4.3288873981462912e-2; cQ.w[1] = 2.6566783614880718e-1; - cQ.x[2] = 1.2025288615546319e-1; cQ.w[2] = 2.4600646227023164e-1; - cQ.x[3] = 2.3571334284486281e-1; cQ.w[3] = 2.1920556026860463e-1; - cQ.x[4] = 3.8968758351746751e-1; cQ.w[4] = 1.8795185561410056e-1; - cQ.x[5] = 5.8219874974842322e-1; cQ.w[5] = 1.5506780698139096e-1; - cQ.x[6] = 8.1327580437858389e-1; cQ.w[6] = 1.2310171404959776e-1; - cQ.x[7] = 1.0829535555341720e0; cQ.w[7] = 9.4028368962612467e-2; - cQ.x[8] = 1.3912726855559166e0; cQ.w[8] = 6.9101651733143485e-2; - cQ.x[9] = 1.7382797848958800e0; cQ.w[9] = 4.8857640815463552e-2; - cQ.x[10] = 2.1240273910504205e0; cQ.w[10] = 3.3232907130961684e-2; - cQ.x[11] = 2.5485740326082378e0; cQ.w[11] = 2.1745560021797622e-2; - cQ.x[12] = 3.0119842785032310e0; cQ.w[12] = 1.3687095820753643e-2; - cQ.x[13] = 3.5143287925730293e0; cQ.w[13] = 8.2862847528073521e-3; - cQ.x[14] = 4.0556843935355590e0; cQ.w[14] = 4.8248404263837572e-3; - cQ.x[15] = 4.6361341205079486e0; cQ.w[15] = 2.7017467389205526e-3; - cQ.x[16] = 5.2557673042044822e0; cQ.w[16] = 1.4548097345670083e-3; - cQ.x[17] = 5.9146796439632562e0; cQ.w[17] = 7.5322752691836494e-4; - cQ.x[18] = 6.6129732907647177e0; cQ.w[18] = 3.7493875811399589e-4; - cQ.x[19] = 7.3507569364194338e0; cQ.w[19] = 1.7941616616270753e-4; - cQ.x[20] = 8.1281459091173179e0; cQ.w[20] = 8.2523935092697431e-5; - cQ.x[21] = 8.9452622755461916e0; cQ.w[21] = 3.6480646490280587e-5; - cQ.x[22] = 9.8022349498040578e0; cQ.w[22] = 1.5497209992155702e-5; - cQ.x[23] = 1.0699199809346890e1; cQ.w[23] = 6.3254880868062279e-6; - cQ.x[24] = 1.1636299818232177e1; cQ.w[24] = 2.4804025381841617e-6; - cQ.x[25] = 1.2613685157937996e1; cQ.w[25] = 9.3427092817735856e-7; - cQ.x[26] = 1.3631513366058145e1; cQ.w[26] = 3.3796972810877498e-7; - cQ.x[27] = 1.4689949483195887e1; cQ.w[27] = 1.1739931842906987e-7; - cQ.x[28] = 1.5789166208402366e1; cQ.w[28] = 3.9152666460117425e-8; - cQ.x[29] = 1.6929344063530748e1; cQ.w[29] = 1.2533919800530000e-8; - cQ.x[30] = 1.8110671566903898e1; cQ.w[30] = 3.8508855814103435e-9; - cQ.x[31] = 1.9333345416721943e1; cQ.w[31] = 1.1352650067802054e-9; - cQ.x[32] = 2.0597570684666645e1; cQ.w[32] = 3.2107610902767967e-10; - cQ.x[33] = 2.1903561020192286e1; cQ.w[33] = 8.7096417230648332e-11; - cQ.x[34] = 2.3251538866027899e1; cQ.w[34] = 2.2655716245890225e-11; - cQ.x[35] = 2.4641735685453456e1; cQ.w[35] = 5.6498933794313194e-12; - cQ.x[36] = 2.6074392201953201e1; cQ.w[36] = 1.3504651749637866e-12; - cQ.x[37] = 2.7549758651893053e1; cQ.w[37] = 3.0931346162094001e-13; - cQ.x[38] = 2.9068095050916087e1; cQ.w[38] = 6.7869387110402112e-14; - cQ.x[39] = 3.0629671474800940e1; cQ.w[39] = 1.4262371047812445e-14; - cQ.x[40] = 3.2234768355582876e1; cQ.w[40] = 2.8696621621608344e-15; - cQ.x[41] = 3.3883676793796597e1; cQ.w[41] = 5.5266882811584044e-16; - cQ.x[42] = 3.5576698887764130e1; cQ.w[42] = 1.0185057527135605e-16; - cQ.x[43] = 3.7314148080920709e1; cQ.w[43] = 1.7955213298120343e-17; - cQ.x[44] = 3.9096349528247114e1; cQ.w[44] = 3.0269510335107605e-18; - cQ.x[45] = 4.0923640482958862e1; cQ.w[45] = 4.8782259058116175e-19; - cQ.x[46] = 4.2796370704691817e1; cQ.w[46] = 7.5129177544606858e-20; - cQ.x[47] = 4.4714902890520744e1; cQ.w[47] = 1.1053212066329750e-20; - cQ.x[48] = 4.6679613130253012e1; cQ.w[48] = 1.5528826688231492e-21; - cQ.x[49] = 4.8690891387554891e1; cQ.w[49] = 2.0825248019667178e-22; - cQ.x[50] = 5.0749142008593753e1; cQ.w[50] = 2.6648208774549398e-23; - cQ.x[51] = 5.2854784260017013e1; cQ.w[51] = 3.2523000556521267e-24; - cQ.x[52] = 5.5008252898239286e1; cQ.w[52] = 3.7841616175987121e-25; - cQ.x[53] = 5.7209998772174173e1; cQ.w[53] = 4.1957539145536696e-26; - cQ.x[54] = 5.9460489461728161e1; cQ.w[54] = 4.4310753939163665e-27; - cQ.x[55] = 6.1760209954572964e1; cQ.w[55] = 4.4550960738061500e-28; - cQ.x[56] = 6.4109663363931410e1; cQ.w[56] = 4.2622210868369363e-29; - cQ.x[57] = 6.6509371690352848e1; cQ.w[57] = 3.8781073546455843e-30; - cQ.x[58] = 6.8959876630719803e1; cQ.w[58] = 3.3540852993298416e-31; - cQ.x[59] = 7.1461740438021006e1; cQ.w[59] = 2.7558487347346862e-32; - cQ.x[60] = 7.4015546835750457e1; cQ.w[60] = 2.1498637246741931e-33; - cQ.x[61] = 7.6621901991151567e1; cQ.w[61] = 1.5913963136894115e-34; - cQ.x[62] = 7.9281435551924119e1; cQ.w[62] = 1.1170819746689115e-35; - cQ.x[63] = 8.1994801751454565e1; cQ.w[63] = 7.4310093282819445e-37; - cQ.x[64] = 8.4762680588122938e1; cQ.w[64] = 4.6813625515950693e-38; - cQ.x[65] = 8.7585779084788683e1; cQ.w[65] = 2.7909522621573202e-39; - cQ.x[66] = 9.0464832635170634e1; cQ.w[66] = 1.5735113668960615e-40; - cQ.x[67] = 9.3400606444521639e1; cQ.w[67] = 8.3828847876304648e-42; - cQ.x[68] = 9.6393897072765977e1; cQ.w[68] = 4.2167560748751703e-43; - cQ.x[69] = 9.9445534089129095e1; cQ.w[69] = 2.0010861658834713e-44; - cQ.x[70] = 1.0255638184825758e2; cQ.w[70] = 8.9512017753845699e-46; - cQ.x[71] = 1.0572734139891817e2; cQ.w[71] = 3.7708148208752655e-47; - cQ.x[72] = 1.0895935253759580e2; cQ.w[72] = 1.4945851640195755e-48; - cQ.x[73] = 1.1225339602070313e2; cQ.w[73] = 5.5681807795587594e-50; - cQ.x[74] = 1.1561049595069244e2; cQ.w[74] = 1.9479151853826422e-51; - cQ.x[75] = 1.1903172235315340e2; cQ.w[75] = 6.3918683903792039e-53; - cQ.x[76] = 1.2251819396402152e2; cQ.w[76] = 1.9651813087431218e-54; - cQ.x[77] = 1.2607108124835155e2; cQ.w[77] = 5.6544197387738892e-56; - cQ.x[78] = 1.2969160967477476e2; cQ.w[78] = 1.5207362927895532e-57; - cQ.x[79] = 1.3338106327281588e2; cQ.w[79] = 3.8180775856184579e-59; - cQ.x[80] = 1.3714078850376025e2; cQ.w[80] = 8.9367191262601894e-61; - cQ.x[81] = 1.4097219847981490e2; cQ.w[81] = 1.9473442897375391e-62; - cQ.x[82] = 1.4487677757099489e2; cQ.w[82] = 3.9445422891662265e-64; - cQ.x[83] = 1.4885608644460317e2; cQ.w[83] = 7.4159150213626314e-66; - cQ.x[84] = 1.5291176758849769e2; cQ.w[84] = 1.2919234936181112e-67; - cQ.x[85] = 1.5704555137672418e2; cQ.w[85] = 2.0819221394737772e-69; - cQ.x[86] = 1.6125926274474058e2; cQ.w[86] = 3.0978378698037742e-71; - cQ.x[87] = 1.6555482855162421e2; cQ.w[87] = 4.2480171859192708e-73; - cQ.x[88] = 1.6993428571864366e2; cQ.w[88] = 5.3575541752687071e-75; - cQ.x[89] = 1.7439979024777800e2; cQ.w[89] = 6.2010829537374423e-77; - cQ.x[90] = 1.7895362724065057e2; cQ.w[90] = 6.5720579636670588e-79; - cQ.x[91] = 1.8359822205850647e2; cQ.w[91] = 6.3623825304174234e-81; - cQ.x[92] = 1.8833615278804584e2; cQ.w[92] = 5.6118813553226041e-83; - cQ.x[93] = 1.9317016420706524e2; cQ.w[93] = 4.4976052330512204e-85; - cQ.x[94] = 1.9810318347914946e2; cQ.w[94] = 3.2656789300649514e-87; - cQ.x[95] = 2.0313833784961355e2; cQ.w[95] = 2.1415773771514337e-89; - cQ.x[96] = 2.0827897466747490e2; cQ.w[96] = 1.2642009038210272e-91; - cQ.x[97] = 2.1352868412296766e2; cQ.w[97] = 6.6937523730388343e-94; - cQ.x[98] = 2.1889132517029559e2; cQ.w[98] = 3.1668515385882014e-96; - cQ.x[99] = 2.2437105520529297e2; cQ.w[99] = 1.3331988108895188e-98; - cQ.x[100] = 2.2997236419317798e2; cQ.w[100] = 4.9720167074631327e-101; - cQ.x[101] = 2.3570011410033001e2; cQ.w[101] = 1.6347801791277616e-103; - cQ.x[102] = 2.4155958468639006e2; cQ.w[102] = 4.7134964221305137e-106; - cQ.x[103] = 2.4755652697313934e2; cQ.w[103] = 1.1851002424541479e-108; - cQ.x[104] = 2.5369722604409365e2; cQ.w[104] = 2.5820543464647026e-111; - cQ.x[105] = 2.5998857527081546e2; cQ.w[105] = 4.8417253805291566e-114; - cQ.x[106] = 2.6643816464709542e2; cQ.w[106] = 7.7550688581883223e-117; - cQ.x[107] = 2.7305438669552003e2; cQ.w[107] = 1.0522110136923271e-119; - cQ.x[108] = 2.7984656447262174e2; cQ.w[108] = 1.1982172530332628e-122; - cQ.x[109] = 2.8682510765704206e2; cQ.w[109] = 1.1333834975480497e-125; - cQ.x[110] = 2.9400170473751538e2; cQ.w[110] = 8.8091250671314200e-129; - cQ.x[111] = 3.0138956219582173e2; cQ.w[111] = 5.1031266854191002e-132; - cQ.x[112] = 3.0900370572897370e2; cQ.w[112] = 3.7889105113753785e-134; - cQ.x[113] = 3.1686136465414833e2; cQ.w[113] = 1.6614242788060531e-135; - cQ.x[114] = 3.2498246980378542e2; cQ.w[114] = 3.3159273335592529e-133; - cQ.x[115] = 3.3339030932831591e2; cQ.w[115] = 6.6730040001944718e-134; - cQ.x[116] = 3.4211240916012430e2; cQ.w[116] = 1.2949575356743615e-133; - cQ.x[117] = 3.5118174138517492e2; cQ.w[117] = 9.1532484444758395e-133; - cQ.x[118] = 3.6063842559961562e2; cQ.w[118] = 1.9549729552902828e-134; - cQ.x[119] = 3.7053219762567725e2; cQ.w[119] = 8.0781662197334676e-122; - cQ.x[120] = 3.8092612308026272e2; cQ.w[120] = 3.7898513479231859e-137; - cQ.x[121] = 3.9190243416377710e2; cQ.w[121] = 1.0948592196247296e-132; - cQ.x[122] = 4.0357221976913419e2; cQ.w[122] = 3.6495237116054534e-50; - cQ.x[123] = 4.1609268503849895e2; cQ.w[123] = 7.9553417261007054e-54; - cQ.x[124] = 4.2970092632479113e2; cQ.w[124] = 5.8160707456163802e-67; - cQ.x[125] = 4.4478945491488902e2; cQ.w[125] = 1.6308626485034593e-79; - cQ.x[126] = 4.6211398112631172e2; cQ.w[126] = 8.1797036981379553e-83; - cQ.x[127] = 4.8363457770593729e2; cQ.w[127] = 4.4300469125827045e-82; - break; - } - } - - /******************************************************************************/ - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - - double r8_epsilon() - // Purpose: - // - // R8_EPSILON returns the R8 roundoff unit. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // Reference: - // - // Discussion: - // - // The roundoff unit is a number R which is a power of 2 with the - // property that, to the precision of the computer's arithmetic, - // 1 < 1 + R - // but - // 1 = ( 1 + R / 2 ) - // - // Parameters: - // - // Output, double R8_EPSILON, the R8 round-off unit. - { - const double value = 2.220446049250313E-016; - - return value; - } - - double r8_huge() - // Purpose: - // - // R8_HUGE returns a "huge" R8. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Discussion: - // - // The value returned by this function is NOT required to be the - // maximum representable R8. This value varies from machine to machine, - // from compiler to compiler, and may cause problems when being printed. - // We simply want a "very large" but non-infinite number. - // - // Parameters: - // - // Output, double R8_HUGE, a "huge" R8 value. - { - double value; - - value = 1.0E+30; - - return value; - } - - double r8_sign(double x) - // Purpose: - // - // R8_SIGN returns the sign of an R8. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Parameters: - // - // Input, double X, the number whose sign is desired. - // Output, double R8_SIGN, the sign of X. - { - double value; - - if (x < 0.0) - { - value = -1.0; - } - else - { - value = 1.0; - } - return value; - } - - void cgqf(int nt, int kind, double alpha, double beta, double a, double b, - double t[], double wts[]) - // Purpose: - // - // CGQF computes knots and weights of a Gauss quadrature formula. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Discussion: - // - // The user may specify the interval (A,B). - // Only simple knots are produced. - // Use routine EIQFS to evaluate this quadrature formula. - // - // Reference: - // - // Sylvan Elhay, Jaroslav Kautsky, - // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of - // Interpolatory Quadrature, - // ACM Transactions on Mathematical Software, - // Volume 13, Number 4, December 1987, pages 399-415. - // - // Parameters: - // - // Input, int NT, the number of knots. - // - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev Type 1, (a,b) ((b-x)*(x-a))^-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,+oo) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-oo,+oo) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,+oo) (x-a)^alpha*(x+b)^beta - // 9, Chebyshev Type 2, (a,b) ((b-x)*(x-a))^(+0.5) - // - // Input, double ALPHA, the value of Alpha, if needed. - // Input, double BETA, the value of Beta, if needed. - // Input, double A, B, the interval endpoints, or other parameters. - // - // Output, double T[NT], the knots. - // Output, double WTS[NT], the weights. - { - int i; - int *mlt; - int *ndx; - // Compute the Gauss quadrature formula for default values of A and B. - cdgqf(nt, kind, alpha, beta, t, wts); - - // Prepare to scale the quadrature formula to other weight function with valid A and B. - mlt = new int[nt]; - for (i = 0; i < nt; i++) - { - mlt[i] = 1; - } - ndx = new int[nt]; - for (i = 0; i < nt; i++) - { - ndx[i] = i + 1; - } - scqf(nt, t, mlt, wts, nt, ndx, wts, t, kind, alpha, beta, a, b); - - delete[] mlt; - delete[] ndx; - - return; - } - - void cdgqf(int nt, int kind, double alpha, double beta, double t[], - double wts[]) - // Purpose: - // - // CDGQF computes a Gauss quadrature formula with default A, B and simple knots. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Discussion: - // - // This routine computes all the knots and weights of a Gauss quadrature - // formula with a classical weight function with default values for A and B, - // and only simple knots. - // There are no moments checks and no printing is done. - // Use routine EIQFS to evaluate a quadrature computed by CGQFS. - // - // Reference: - // - // Sylvan Elhay, Jaroslav Kautsky, - // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of - // Interpolatory Quadrature, - // ACM Transactions on Mathematical Software, - // Volume 13, Number 4, December 1987, pages 399-415. - // - // Parameters: - // - // Input, int NT, the number of knots. - // - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - // - // Input, double ALPHA, the value of Alpha, if needed. - // Input, double BETA, the value of Beta, if needed. - // Output, double T[NT], the knots. - // Output, double WTS[NT], the weights. - { - double *aj; - double *bj; - double zemu; - - parchk(kind, 2 * nt, alpha, beta); - // Get the Jacobi matrix and zero-th moment. - aj = new double[nt]; - bj = new double[nt]; - - zemu = class_matrix(kind, nt, alpha, beta, aj, bj); - // Compute the knots and weights. - sgqf(nt, aj, bj, zemu, t, wts); - - delete[] aj; - delete[] bj; - - return; - } - - double class_matrix(int kind, int m, double alpha, double beta, double aj[], - double bj[]) - // Purpose: - // - // CLASS_MATRIX computes the Jacobi matrix for a quadrature rule. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Discussion: - // - // This routine computes the diagonal AJ and sub-diagonal BJ - // elements of the order M tridiagonal symmetric Jacobi matrix - // associated with the polynomials orthogonal with respect to - // the weight function specified by KIND. - // - // For weight functions 1-7, M elements are defined in BJ even - // though only M-1 are needed. For weight function 8, BJ(M) is - // set to zero. - // - // The zero-th moment of the weight function is returned in ZEMU. - // - // Reference: - // - // Sylvan Elhay, Jaroslav Kautsky, - // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of - // Interpolatory Quadrature, - // ACM Transactions on Mathematical Software, - // Volume 13, Number 4, December 1987, pages 399-415. - // - // Parameters: - // - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - // - // Input, int M, the order of the Jacobi matrix. - // Input, double ALPHA, the value of Alpha, if needed. - // Input, double BETA, the value of Beta, if needed. - // Output, double AJ[M], BJ[M], the diagonal and subdiagonal - // of the Jacobi matrix. - // Output, double CLASS_MATRIX, the zero-th moment. - { - double a2b2; - double ab; - double aba; - double abi; - double abj; - double abti; - double apone; - int i; - double pi = 3.14159265358979323846264338327950; - double temp; - double temp2; - double zemu; - - temp = r8_epsilon(); - - parchk(kind, 2 * m - 1, alpha, beta); - - temp2 = 0.5; - - if (500.0 * temp < fabs(pow(tgamma(temp2), 2) - pi)) - { - //cout << "\n"; - //cout << "CLASS_MATRIX - Fatal error!\n"; - //cout << " Gamma function does not match machine parameters.\n"; - //exit(1); - } - - if (kind == 1) - { - ab = 0.0; - - zemu = 2.0 / (ab + 1.0); - - for (i = 0; i < m; i++) - { - aj[i] = 0.0; - } - - for (i = 1; i <= m; i++) - { - abi = i + ab * (i % 2); - abj = 2 * i + ab; - bj[i - 1] = sqrt(abi * abi / (abj * abj - 1.0)); - } - } - else if (kind == 2) - { - zemu = pi; - - for (i = 0; i < m; i++) - { - aj[i] = 0.0; - } - - bj[0] = sqrt(0.5); - for (i = 1; i < m; i++) - { - bj[i] = 0.5; - } - } - else if (kind == 3) - { - ab = alpha * 2.0; - zemu = pow(2.0, ab + 1.0) * pow(tgamma(alpha + 1.0), 2) - / tgamma(ab + 2.0); - - for (i = 0; i < m; i++) - { - aj[i] = 0.0; - } - - bj[0] = sqrt(1.0 / (2.0 * alpha + 3.0)); - for (i = 2; i <= m; i++) - { - bj[i - 1] = sqrt(i * (i + ab) / (4.0 * pow(i + alpha, 2) - 1.0)); - } - } - else if (kind == 4) - { - ab = alpha + beta; - abi = 2.0 + ab; - zemu = pow(2.0, ab + 1.0) * tgamma(alpha + 1.0) - * tgamma(beta + 1.0) / tgamma(abi); - aj[0] = (beta - alpha) / abi; - bj[0] = sqrt(4.0 * (1.0 + alpha) * (1.0 + beta) - / ((abi + 1.0) * abi * abi)); - a2b2 = beta * beta - alpha * alpha; - - for (i = 2; i <= m; i++) - { - abi = 2.0 * i + ab; - aj[i - 1] = a2b2 / ((abi - 2.0) * abi); - abi = abi * abi; - bj[i - 1] = sqrt(4.0 * i * (i + alpha) * (i + beta) * (i + ab) - / ((abi - 1.0) * abi)); - } - } - else if (kind == 5) - { - zemu = tgamma(alpha + 1.0); - - for (i = 1; i <= m; i++) - { - aj[i - 1] = 2.0 * i - 1.0 + alpha; - bj[i - 1] = sqrt(i * (i + alpha)); - } - } - else if (kind == 6) - { - zemu = tgamma((alpha + 1.0) / 2.0); - - for (i = 0; i < m; i++) - { - aj[i] = 0.0; - } - - for (i = 1; i <= m; i++) - { - bj[i - 1] = sqrt((i + alpha * (i % 2)) / 2.0); - } - } - else if (kind == 7) - { - ab = alpha; - zemu = 2.0 / (ab + 1.0); - - for (i = 0; i < m; i++) - { - aj[i] = 0.0; - } - - for (i = 1; i <= m; i++) - { - abi = i + ab * (i % 2); - abj = 2 * i + ab; - bj[i - 1] = sqrt(abi * abi / (abj * abj - 1.0)); - } - } - else if (kind == 8) - { - ab = alpha + beta; - zemu = tgamma(alpha + 1.0) * tgamma(-(ab + 1.0)) - / tgamma(-beta); - apone = alpha + 1.0; - aba = ab * apone; - aj[0] = -apone / (ab + 2.0); - bj[0] = -aj[0] * (beta + 1.0) / (ab + 2.0) / (ab + 3.0); - for (i = 2; i <= m; i++) - { - abti = ab + 2.0 * i; - aj[i - 1] = aba + 2.0 * (ab + i) * (i - 1); - aj[i - 1] = -aj[i - 1] / abti / (abti - 2.0); - } - - for (i = 2; i <= m - 1; i++) - { - abti = ab + 2.0 * i; - bj[i - 1] = i * (alpha + i) / (abti - 1.0) * (beta + i) - / (abti * abti) * (ab + i) / (abti + 1.0); - } - bj[m - 1] = 0.0; - for (i = 0; i < m; i++) - { - bj[i] = sqrt(bj[i]); - } - } - - return zemu; - } - - void imtqlx(int n, double d[], double e[], double z[]) - // Purpose: - // - // IMTQLX diagonalizes a symmetric tridiagonal matrix. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Discussion: - // - // This routine is a slightly modified version of the EISPACK routine to - // perform the implicit QL algorithm on a symmetric tridiagonal matrix. - // - // The authors thank the authors of EISPACK for permission to use this - // routine. - // - // It has been modified to produce the product Q' * Z, where Z is an input - // vector and Q is the orthogonal matrix diagonalizing the input matrix. - // The changes consist (essentialy) of applying the orthogonal transformations - // directly to Z as they are generated. - // - // Reference: - // - // Sylvan Elhay, Jaroslav Kautsky, - // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of - // Interpolatory Quadrature, - // ACM Transactions on Mathematical Software, - // Volume 13, Number 4, December 1987, pages 399-415. - // - // Roger Martin, James Wilkinson, - // The Implicit QL Algorithm, - // Numerische Mathematik, - // Volume 12, Number 5, December 1968, pages 377-383. - // - // Parameters: - // - // Input, int N, the order of the matrix. - // - // Input/output, double D(N), the diagonal entries of the matrix. - // On output, the information in D has been overwritten. - // - // Input/output, double E(N), the subdiagonal entries of the - // matrix, in entries E(1) through E(N-1). On output, the information in - // E has been overwritten. - // - // Input/output, double Z(N). On input, a vector. On output, - // the value of Q' * Z, where Q is the matrix that diagonalizes the - // input symmetric tridiagonal matrix. - { - double b; - double c; - double f; - double g; - int i; - int ii; - int itn = 30; - int j; - int k; - int l; - int m; - int mml; - double p; - double prec; - double r; - double s; - - prec = r8_epsilon(); - - if (n == 1) - { - return; - } - - e[n - 1] = 0.0; - - for (l = 1; l <= n; l++) - { - j = 0; - for (; ; ) - { - for (m = l; m <= n; m++) - { - if (m == n) - { - break; - } - - if (fabs(e[m - 1]) <= prec * (fabs(d[m - 1]) + fabs(d[m]))) - { - break; - } - } - p = d[l - 1]; - if (m == l) - { - break; - } - if (itn <= j) - { - //cout << "\n"; - //cout << "IMTQLX - Fatal error!\n"; - //cout << " Iteration limit exceeded\n"; - //exit(1); - } - - j = j + 1; - g = (d[l] - p) / (2.0 * e[l - 1]); - r = sqrt(g * g + 1.0); - g = d[m - 1] - p + e[l - 1] / (g + fabs(r) * r8_sign(g)); - s = 1.0; - c = 1.0; - p = 0.0; - mml = m - l; - - for (ii = 1; ii <= mml; ii++) - { - i = m - ii; - f = s * e[i - 1]; - b = c * e[i - 1]; - - if (fabs(g) <= fabs(f)) - { - c = g / f; - r = sqrt(c * c + 1.0); - e[i] = f * r; - s = 1.0 / r; - c = c * s; - } - else - { - s = f / g; - r = sqrt(s * s + 1.0); - e[i] = g * r; - c = 1.0 / r; - s = s * c; - } - g = d[i] - p; - r = (d[i - 1] - g) * s + 2.0 * c * b; - p = s * r; - d[i] = g + p; - g = c * r - b; - f = z[i]; - z[i] = s * z[i - 1] + c * f; - z[i - 1] = c * z[i - 1] - s * f; - } - d[l - 1] = d[l - 1] - p; - e[l - 1] = g; - e[m - 1] = 0.0; - } - } - // - // Sorting. - // - for (ii = 2; ii <= m; ii++) - { - i = ii - 1; - k = i; - p = d[i - 1]; - - for (j = ii; j <= n; j++) - { - if (d[j - 1] < p) - { - k = j; - p = d[j - 1]; - } - } - - if (k != i) - { - d[k - 1] = d[i - 1]; - d[i - 1] = p; - p = z[i - 1]; - z[i - 1] = z[k - 1]; - z[k - 1] = p; - } - } - return; - } - - void parchk(int kind, int m, double alpha, double beta) - // Purpose: - // - // PARCHK checks parameters ALPHA and BETA for classical weight functions. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Reference: - // - // Sylvan Elhay, Jaroslav Kautsky, - // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of - // Interpolatory Quadrature, - // ACM Transactions on Mathematical Software, - // Volume 13, Number 4, December 1987, pages 399-415. - // - // Parameters: - // - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta - // - // Input, int M, the order of the highest moment to - // be calculated. This value is only needed when KIND = 8. - // - // Input, double ALPHA, BETA, the parameters, if required - // by the value of KIND. - { - double tmp; - - if (kind <= 0) - { - //cout << "\n"; - //cout << "PARCHK - Fatal error!\n"; - //cout << " KIND <= 0.\n"; - //exit(1); - } - - // Check ALPHA for Gegenbauer, Jacobi, Laguerre, Hermite, Exponential. - if (3 <= kind && alpha <= -1.0) - { - //cout << "\n"; - //cout << "PARCHK - Fatal error!\n"; - //cout << " 3 <= KIND and ALPHA <= -1.\n"; - //exit(1); - } - - // Check BETA for Jacobi. - if (kind == 4 && beta <= -1.0) - { - //cout << "\n"; - //cout << "PARCHK - Fatal error!\n"; - //cout << " KIND == 4 and BETA <= -1.0.\n"; - //exit(1); - } - - // Check ALPHA and BETA for rational. - if (kind == 8) - { - tmp = alpha + beta + m + 1.0; - if (0.0 <= tmp || tmp <= beta) - { - //cout << "\n"; - //cout << "PARCHK - Fatal error!\n"; - //cout << " KIND == 8 but condition on ALPHA and BETA fails.\n"; - //exit(1); - } - } - return; - } - - void scqf(int nt, double t[], int mlt[], double wts[], int nwts, int ndx[], - double swts[], double st[], int kind, double alpha, double beta, double a, double b) - // Purpose: - // - // SCQF scales a quadrature formula to a nonstandard interval. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Discussion: - // - // The arrays WTS and SWTS may coincide. - // The arrays T and ST may coincide. - // - // Reference: - // - // Sylvan Elhay, Jaroslav Kautsky, - // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of - // Interpolatory Quadrature, - // ACM Transactions on Mathematical Software, - // Volume 13, Number 4, December 1987, pages 399-415. - // - // Parameters: - // - // Input, int NT, the number of knots. - // Input, double T[NT], the original knots. - // Input, int MLT[NT], the multiplicity of the knots. - // Input, double WTS[NWTS], the weights. - // Input, int NWTS, the number of weights. - // Input, int NDX[NT], used to index the array WTS. - // For more details see the comments in CAWIQ. - // - // Output, double SWTS[NWTS], the scaled weights. - // Output, double ST[NT], the scaled knots. - // - // Input, int KIND, the rule. - // 1, Legendre, (a,b) 1.0 - // 2, Chebyshev Type 1, (a,b) ((b-x)*(x-a))^(-0.5) - // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha - // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta - // 5, Generalized Laguerre, (a,+oo) (x-a)^alpha*exp(-b*(x-a)) - // 6, Generalized Hermite, (-oo,+oo) |x-a|^alpha*exp(-b*(x-a)^2) - // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha - // 8, Rational, (a,+oo) (x-a)^alpha*(x+b)^beta - // 9, Chebyshev Type 2, (a,b) ((b-x)*(x-a))^(+0.5) - // - // Input, double ALPHA, the value of Alpha, if needed. - // Input, double BETA, the value of Beta, if needed. - // Input, double A, B, the interval endpoints. - { - double al; - double be; - int i; - int k; - int l; - double p; - double shft; - double slp; - double temp; - double tmp; - - temp = r8_epsilon(); - - parchk(kind, 1, alpha, beta); - - if (kind == 1) - { - al = 0.0; - be = 0.0; - if (fabs(b - a) <= temp) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " |B - A| too small.\n"; - //exit(1); - } - shft = (a + b) / 2.0; - slp = (b - a) / 2.0; - } - else if (kind == 2) - { - al = -0.5; - be = -0.5; - if (fabs(b - a) <= temp) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " |B - A| too small.\n"; - //exit(1); - } - shft = (a + b) / 2.0; - slp = (b - a) / 2.0; - } - else if (kind == 3) - { - al = alpha; - be = alpha; - if (fabs(b - a) <= temp) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " |B - A| too small.\n"; - //exit(1); - } - shft = (a + b) / 2.0; - slp = (b - a) / 2.0; - } - else if (kind == 4) - { - al = alpha; - be = beta; - - if (fabs(b - a) <= temp) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " |B - A| too small.\n"; - //exit(1); - } - shft = (a + b) / 2.0; - slp = (b - a) / 2.0; - } - else if (kind == 5) - { - if (b <= 0.0) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " B <= 0\n"; - //exit(1); - } - shft = a; - slp = 1.0 / b; - al = alpha; - be = 0.0; - } - else if (kind == 6) - { - if (b <= 0.0) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " B <= 0.\n"; - //exit(1); - } - shft = a; - slp = 1.0 / sqrt(b); - al = alpha; - be = 0.0; - } - else if (kind == 7) - { - al = alpha; - be = 0.0; - if (fabs(b - a) <= temp) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " |B - A| too small.\n"; - //exit(1); - } - shft = (a + b) / 2.0; - slp = (b - a) / 2.0; - } - else if (kind == 8) - { - if (a + b <= 0.0) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " A + B <= 0.\n"; - //exit(1); - } - shft = a; - slp = a + b; - al = alpha; - be = beta; - } - else if (kind == 9) - { - al = 0.5; - be = 0.5; - if (fabs(b - a) <= temp) - { - //cout << "\n"; - //cout << "SCQF - Fatal error!\n"; - //cout << " |B - A| too small.\n"; - //exit(1); - } - shft = (a + b) / 2.0; - slp = (b - a) / 2.0; - } - - p = pow(slp, al + be + 1.0); - - for (k = 0; k < nt; k++) - { - st[k] = shft + slp * t[k]; - l = abs(ndx[k]); - - if (l != 0) - { - tmp = p; - for (i = l - 1; i <= l - 1 + mlt[k] - 1; i++) - { - swts[i] = wts[i] * tmp; - tmp = tmp * slp; - } - } - } - return; - } - - void sgqf(int nt, double aj[], double bj[], double zemu, double t[], double wts[]) - // Purpose: - // - // SGQF computes knots and weights of a Gauss Quadrature formula. - // - // Author: - // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. - // C++ version by John Burkardt. - // - // Licensing: - // - // This code is distributed under the GNU LGPL license. - // - // Discussion: - // - // This routine computes all the knots and weights of a Gauss quadrature - // formula with simple knots from the Jacobi matrix and the zero-th - // moment of the weight function, using the Golub-Welsch technique. - // - // Reference: - // - // Sylvan Elhay, Jaroslav Kautsky, - // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of - // Interpolatory Quadrature, - // ACM Transactions on Mathematical Software, - // Volume 13, Number 4, December 1987, pages 399-415. - // - // Parameters: - // - // Input, int NT, the number of knots. - // - // Input, double AJ[NT], the diagonal of the Jacobi matrix. - // - // Input/output, double BJ[NT], the subdiagonal of the Jacobi - // matrix, in entries 1 through NT-1. On output, BJ has been overwritten. - // - // Input, double ZEMU, the zero-th moment of the weight function. - // - // Output, double T[NT], the knots. - // - // Output, double WTS[NT], the weights. - { - int i; - - // Exit if the zero-th moment is not positive. - if (zemu <= 0.0) - { - //cout << "\n"; - //cout << "SGQF - Fatal error!\n"; - //cout << " ZEMU <= 0.\n"; - //exit(1); - } - - // Set up vectors for IMTQLX. - for (i = 0; i < nt; i++) - { - t[i] = aj[i]; - } - wts[0] = sqrt(zemu); - for (i = 1; i < nt; i++) - { - wts[i] = 0.0; - } - - // Diagonalize the Jacobi matrix. - imtqlx(nt, t, bj, wts); - - for (i = 0; i < nt; i++) - { - wts[i] = wts[i] * wts[i]; - } - - return; - } - - Q1 cQ; - }; - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/r_2d.h b/src/r_2d.h new file mode 100755 index 00000000..5f7c0093 --- /dev/null +++ b/src/r_2d.h @@ -0,0 +1,224 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#pragma once + +#include +#include + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "fcns_cgpu_gen.h" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +/* R_2d */ +namespace mt +{ + template + using R_2d = R_xtd; + + template + class R_xtd + { + public: + using value_type = T; + + T x; + T y; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + R_xtd(); + + /* constructor by initializer list */ + template + CPU_EXEC + R_xtd(const dt_init_list& list); + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0); + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v); + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int32& n_v); + + /* constructor a R_2d with an x */ + CGPU_EXEC + R_xtd(const T& x); + + /* converting constructor: R_2d with an x */ + template + CGPU_EXEC + R_xtd(const U& x); + + /* constructor a R_2d from its x and y parts */ + CGPU_EXEC + R_xtd(const T& x, const T& y); + + /* converting constructor: R_2d from its x and y parts. */ + template + CGPU_EXEC + R_xtd(const U& x, const U& y); + + /* Copy constructor */ + CGPU_EXEC + R_xtd(const R_xtd& r); + + /* Move constructor */ + CGPU_EXEC + R_xtd(R_xtd&& r); + + /* converting copy constructor */ + template + CGPU_EXEC + R_xtd(const R_xtd& r); + + /******************************** assignment operators *********************************/ + /* Assign x and set y to 0 */ + CGPU_EXEC + R_xtd& operator=(const T& x); + + /* Convert and assign x and set y to 0 */ + template + CGPU_EXEC + R_xtd& operator=(const U& x); + + /* copy assignment operator */ + CGPU_EXEC + R_xtd& operator=(const R_xtd& r); + + /* Move assignment operator */ + CGPU_EXEC + R_xtd& operator=(R_xtd&& r); + + /* converting assignment operator */ + template + CGPU_EXEC + R_xtd& operator=(const R_xtd& r); + +#ifdef __CUDACC__ + /* Assignment operator from thrust::complex */ + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r); + + /* converting assignment operator from thrust::complex */ + template + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r); +#endif + + /* Assignment operator from std::complex */ + CPU_EXEC + R_xtd& operator=(const std::complex& r); + + /* converting assignment operator from std::complex */ + template + CPU_EXEC + R_xtd& operator=(const std::complex& r); + + /******************* Compound assignment operators *******************/ + template + CGPU_EXEC + R_xtd& operator+=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator+=(const U& r); + + template + CGPU_EXEC + R_xtd& operator-=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator-=(const U& r); + + template + CGPU_EXEC + R_xtd& operator*=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator*=(const U& r); + + template + CGPU_EXEC + R_xtd& operator/=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator/=(const U& r); + + /************************** Other operators **************************/ + CGPU_EXEC + dt_bool fcn_is_zero() const; + + CGPU_EXEC + dt_bool is_nzero() const; + + CGPU_EXEC + dt_bool is_one() const; + + CGPU_EXEC + R_xtd floor() const; + + CGPU_EXEC + R_xtd ceil() const; + + CGPU_EXEC + R_xtd round() const; + + CGPU_EXEC + T min() const; + + CGPU_EXEC + T max() const; + + CGPU_EXEC + T norm_2() const; + + CGPU_EXEC + T norm() const; + + CGPU_EXEC + void normalize(); + + CGPU_EXEC + void fill(const T& v); + + CGPU_EXEC + void assign_nzero(const R_xtd& r); + }; +} + +#include "detail/r_2d.inl" diff --git a/src/r_3d.h b/src/r_3d.h new file mode 100755 index 00000000..1bf21a38 --- /dev/null +++ b/src/r_3d.h @@ -0,0 +1,242 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#pragma once + +#include +#include + +#include "const_enum.h" +#include "math_mt.h" +#include "type_traits_gen.h" +#include "fcns_cgpu_gen.h" +#include "r_2d.h" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +/* R_3d */ +namespace mt +{ + template + using R_3d = R_xtd; + + template + class R_xtd + { + public: + using value_type = T; + + T x; + T y; + T z; + + /************************************* constructors ************************************/ + /* Default constructor */ + CGPU_EXEC + R_xtd(); + + /* converting constructor by initializer list */ + template + CPU_EXEC + R_xtd(const dt_init_list& list); + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int64& n_r, const dt_int64& n_c, const dt_int64& idx, dt_int64 icol=0); + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v); + + /* constructor by pointer */ + template > + CPU_EXEC + R_xtd(U* v, const dt_int32& n_v); + + /* constructor a R_3d with an x part */ + CGPU_EXEC + R_xtd(const T& x); + + /* converting constructor: R_3d with an x part */ + template + CGPU_EXEC + R_xtd(const U& x); + + /* constructor a R_3d from its x and y parts */ + CGPU_EXEC + R_xtd(const T& x, const T& y); + + /* converting constructor: R_3d from its x and y parts */ + template + CGPU_EXEC + R_xtd(const U& x, const U& y); + + /* constructor a R_3d from its x, y and z parts */ + CGPU_EXEC + R_xtd(const T& x, const T& y, const T& z); + + /* converting constructor: R_3d from its x, y and z parts */ + template + CGPU_EXEC + R_xtd(const U& x, const U& y, const U& z); + + /* copy constructor */ + CGPU_EXEC + R_xtd(const R_xtd& r); + + /* Move constructor */ + CGPU_EXEC + R_xtd(R_xtd&& r); + + /* converting copy constructor */ + template + CGPU_EXEC + R_xtd(const R_xtd& r); + + /******************************** assignment operators *********************************/ + /* Assign x and set y to 0 */ + CGPU_EXEC + R_xtd& operator=(const T& x); + + /* Convert and assign x and set y to 0 */ + template + CGPU_EXEC + R_xtd& operator=(const U& x); + + /* copy assignment operator */ + CGPU_EXEC + R_xtd& operator=(const R_xtd& r); + + /* Move assignment operator */ + CGPU_EXEC + R_xtd& operator=(R_xtd&& r); + + /* converting assignment operator */ + template + CGPU_EXEC + R_xtd& operator=(const R_xtd& r); + + /* Assignment operator from R_2d */ + CGPU_EXEC + R_xtd& operator=(const R_2d& r); + + /* converting assignment operator from R_2d */ + template + CGPU_EXEC + R_xtd& operator=(const R_2d& r); + +#ifdef __CUDACC__ + /* Assignment operator from thrust::complex */ + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r); + + /* converting assignment operator from thrust::complex */ + template + CGPU_EXEC + R_xtd& operator=(const thrust::complex& r); +#endif + + /* Assignment operator from std::complex */ + CPU_EXEC + R_xtd& operator=(const std::complex& r); + + /* converting assignment operator from std::complex */ + template + CPU_EXEC + R_xtd& operator=(const std::complex& r); + + /******************* Compound assignment operators *******************/ + + template + CGPU_EXEC + R_xtd& operator+=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator+=(const U& r); + + template + CGPU_EXEC + R_xtd& operator-=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator-=(const U& r); + + template + CGPU_EXEC + R_xtd& operator*=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator*=(const U& r); + + template + CGPU_EXEC + R_xtd& operator/=(const R_xtd& r); + + template + CGPU_EXEC + R_xtd& operator/=(const U& r); + + /************************** Other operators **************************/ + CGPU_EXEC + dt_bool fcn_is_zero() const; + + CGPU_EXEC + dt_bool is_nzero() const; + + CGPU_EXEC + dt_bool is_one() const; + + CGPU_EXEC + R_2d floor() const; + + CGPU_EXEC + R_2d ceil() const; + + CGPU_EXEC + R_2d round() const; + + CGPU_EXEC + T min() const; + + CGPU_EXEC + T max() const; + + CGPU_EXEC + T norm_2() const; + + CGPU_EXEC + T norm() const; + + CGPU_EXEC + void normalize(); + + CGPU_EXEC + void fill(const T& v); + }; +} + +#include "detail/r_3d.inl" \ No newline at end of file diff --git a/src/range_1d.h b/src/range_1d.h new file mode 100755 index 00000000..3960cd4a --- /dev/null +++ b/src/range_1d.h @@ -0,0 +1,98 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" + +#include "grid_1d.h" + +/* template definition */ +namespace mt +{ + template class Range_xd; + + template + using Range = Range_xd; +} + +/* derived class */ +namespace mt +{ + template + using Range_1d_st = Range_xd; + + using Range_1d = Range_xd; + + using Range_1d_64 = Range_xd; +} + +/* template specialization 1d */ +namespace mt +{ + template + class Range_xd + { + public: + using size_type = ST; + + ST ix_0; // initial x index + ST nx; // x points + + /************************************* constructors ************************************/ + CGPU_EXEC + Range_xd(); + + Range_xd(const ST& ix_0, const ST& nx); + + /* copy constructor */ + CGPU_EXEC + Range_xd(const Range_xd& range); + + /* converting constructor */ + template + CGPU_EXEC + Range_xd(const Range_xd& range); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Range_xd& operator=(const Range_xd& range); + + /* converting assignment operator */ + template + CGPU_EXEC + Range_xd& operator=(const Range_xd& range); + + template + CGPU_EXEC + void assign(const Range_xd& range); + + /***************************************************************************************/ + template + void set_in_data(const SU& ix_0, const SU& nx); + + template + void set_in_data(const T& r, const T& r_max, const Grid_1d& grid); + + CGPU_EXEC + void clear(); + }; +} + +#include "detail/range_1d.inl" \ No newline at end of file diff --git a/src/range_2d.h b/src/range_2d.h new file mode 100755 index 00000000..b5110169 --- /dev/null +++ b/src/range_2d.h @@ -0,0 +1,90 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "r_2d.h" +#include "grid_2d.h" + +#include "range_1d.h" + +/* derived class */ +namespace mt +{ + template + using Range_2d_st = Range_xd; + + using Range_2d = Range_xd; + + using Range_2d_64 = Range_xd; +} + +/* template specialization 2d */ +namespace mt +{ + template + class Range_xd: public Range_xd + { + public: + using size_type = ST; + + ST iy_0; // initial y index + ST ny; // y points + + /************************************* constructors ************************************/ + CGPU_EXEC + Range_xd(); + + Range_xd(const ST& ix_0, const ST& nx, const ST& iy_0, const ST& ny); + + /* copy constructor */ + CGPU_EXEC + Range_xd(const Range_xd& range); + + /* converting constructor */ + template + CGPU_EXEC + Range_xd(const Range_xd& range); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Range_xd& operator=(const Range_xd& range); + + /* converting assignment operator */ + template + CGPU_EXEC + Range_xd& operator=(const Range_xd& range); + + template + CGPU_EXEC + void assign(const Range_xd& range); + + /***************************************************************************************/ + template + void set_in_data(const SU& ix_0, const SU& nx, const SU& iy_0, const SU& ny); + + template + void set_in_data(const R_2d& r, const T& r_max, const Grid_2d& grid); + + CGPU_EXEC + void clear(); + }; +} + +#include "detail/range_2d.inl" \ No newline at end of file diff --git a/src/range_3d.h b/src/range_3d.h new file mode 100755 index 00000000..54c806ca --- /dev/null +++ b/src/range_3d.h @@ -0,0 +1,90 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "r_3d.h" +#include "grid_3d.h" + +#include "range_2d.h" + +/* derived class */ +namespace mt +{ + template + using Range_3d_st = Range_xd; + + using Range_3d = Range_xd; + + using Range_3d_64 = Range_xd; +} + +/* template specialization 3d */ +namespace mt +{ + template + class Range_xd: public Range_xd + { + public: + using size_type = ST; + + ST iz_0; // initial z index + ST nz; // z points + + /************************************* constructors ************************************/ + CGPU_EXEC + Range_xd(); + + Range_xd(const ST& ix_0, const ST& nx, const ST& iy_0, const ST& ny, const ST& iz_0, const ST& nz); + + /* copy constructor */ + CGPU_EXEC + Range_xd(const Range_xd& range); + + /* converting constructor */ + template + CGPU_EXEC + Range_xd(const Range_xd& range); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Range_xd& operator=(const Range_xd& range); + + /* converting assignment operator */ + template + CGPU_EXEC + Range_xd& operator=(const Range_xd& range); + + template + CGPU_EXEC + void assign(const Range_xd& range); + + /***************************************************************************************/ + template + void set_in_data(const SU& ix_0, const SU& nx, const SU& iy_0, const SU& ny, const SU& iz_0, const SU& nz); + + template + void set_in_data(const R_3d& r, const T& r_max, const Grid_3d& grid); + + CGPU_EXEC + void clear(); + }; +} + +#include "detail/range_3d.inl" \ No newline at end of file diff --git a/src/region.cuh b/src/region.cuh new file mode 100755 index 00000000..c82ce51e --- /dev/null +++ b/src/region.cuh @@ -0,0 +1,938 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef REGION_H + #define REGION_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "math_mt.h" + #include "const_enum.h" + #include "fcns_cgpu_gen.h" + #include "r_2d.h" + #include "r_3d.h" + + /***************************************************************************************/ + /********************** iRegion_Rect template forward declaration **********************/ + /***************************************************************************************/ + namespace mt + { + template class Region_Rect_xd; + + template + using iRegion_Rect_xd = Region_Rect_xd; + + /* 1d */ + template + using Region_Rect_1d = Region_Rect_xd; + + using iRegion_Rect_1d = Region_Rect_xd; + + using iRegion_Rect_1d_64 = Region_Rect_xd; + + /* 2d */ + template + using Region_Rect_2d = Region_Rect_xd; + + using iRegion_Rect_2d = Region_Rect_xd; + + using iRegion_Rect_2d_64 = Region_Rect_xd; + + /* 3d */ + template + using Region_Rect_3d = Region_Rect_xd; + + using iRegion_Rect_3d = Region_Rect_xd; + + using iRegion_Rect_3d_64 = Region_Rect_xd; + } + + /* template specialization 1d */ + namespace mt + { + template + class Region_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T rx_0; // initial x position + T rx_e; // final x position + + /************************************* constructors ************************************/ + CGPU_EXEC + Region_Rect_xd(): rx_0(0), rx_e(0) {} + + Region_Rect_xd(const T& rx_0, const T& rx_e) + { + set_in_data(rx_0, rx_e); + } + + template + Region_Rect_xd(U *data, const size_type& n_data) + { + rx_0 = (n_data>0)?data[0]:T(0); + rx_e = (n_data>1)?data[1]:T(0); + } + + /* copy constructor */ + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /* converting constructor */ + template + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + rx_0 = region.rx_0; + rx_e = region.rx_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + rx_0 = T(region.rx_0); + rx_e = T(region.rx_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Region_Rect_xd& region) + { + *this = region; + } + + /***************************************************************************************/ + template + void set_in_data(const U& rx_0, const U& rx_e) + { + this->rx_0 = rx_0; + this->rx_e = rx_e; + } + + CGPU_EXEC + void clear() + { + rx_0 = T(0); + rx_e = T(0); + } + + CGPU_EXEC + T bs_x() const + { + return fcn_max(rx_e-rx_0, T(0)); + } + + CGPU_EXEC + T bs() const + { + return bs_x(); + } + + CGPU_EXEC + T bs_x_h() const + { + return bs_x()/T(2); + } + + CGPU_EXEC + T bs_h() const + { + return bs_x_h(); + } + + CGPU_EXEC + T rx_c() const + { + return (rx_e+rx_0)/T(2); + } + + CGPU_EXEC + T r_c() const + { + return rx_c(); + } + + CGPU_EXEC + T radius_x() const + { + return bs_x_h(); + } + + CGPU_EXEC + T radius() const + { + return radius_x(); + } + + CGPU_EXEC + T radius_x_p(const T& p) const + { + return (T(1)-p)*radius_x(); + } + + CGPU_EXEC + T radius_p(const T& p) const + { + return radius_x_p(p); + } + + void sft_region(const T& bs, const T& dr) + { + rx_0 = fcn_set_bound(rx_0 + dr, T(0), bs); + rx_e = fcn_set_bound(rx_e + dr, T(0), bs); + } + + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_x(const T& x) const + { + return fcn_chk_bound(x, rx_0, rx_e); + } + + CGPU_EXEC + dt_bool chk_bound(const T& r) const + { + return chk_bound_x(r); + } + + CGPU_EXEC + dt_bool chk_bound_x_eps(const T& x) const + { + return fcn_chk_bound_eps(x, rx_0, rx_e); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const T& r) const + { + return chk_bound_x_eps(r); + } + + template > + CGPU_EXEC + T sub_2_ind(const T& ix) const + { + return ix-rx_0; + } + }; + } + + /* template specialization 2d */ + namespace mt + { + template + class Region_Rect_xd: public Region_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T ry_0; // initial y position + T ry_e; // final y position + + /************************************* constructors ************************************/ + CGPU_EXEC + Region_Rect_xd(): Region_Rect_xd(), ry_0(0), ry_e(0) {} + + Region_Rect_xd(const T& rx_0, const T& rx_e, const T& ry_0, const T& ry_e) + { + set_in_data(rx_0, rx_e, ry_0, ry_e); + } + + template + Region_Rect_xd(U *data, const size_type& n_data) + { + Region_Rect_xd(data, n_data); + + ry_0 = (n_data>2)?data[2]:T(0); + ry_e = (n_data>3)?data[3]:T(0); + } + + /* copy constructor */ + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /* converting constructor */ + template + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + ry_0 = region.ry_0; + ry_e = region.ry_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + ry_0 = T(region.ry_0); + ry_e = T(region.ry_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Region_Rect_xd& region) + { + *this = region; + } + + /***************************************************************************************/ + template + void set_in_data(const U& rx_0, const U& rx_e, const U& ry_0, const U& ry_e) + { + Region_Rect_xd::set_in_data(rx_0, rx_e); + + this->ry_0 = ry_0; + this->ry_e = ry_e; + } + + CGPU_EXEC + void clear() + { + Region_Rect_xd::clear(); + + ry_0 = T(0); + ry_e = T(0); + } + + CGPU_EXEC + T bs_y() const + { + return fcn_max(ry_e-ry_0, T(0)); + } + + CGPU_EXEC + R_2d bs() const + { + return {this->bs_x(), bs_y()}; + } + + CGPU_EXEC + T bs_y_h() const + { + return bs_y()/T(2); + } + + CGPU_EXEC + R_2d bs_h() const + { + return {this->bs_x_h(), bs_y_h()}; + } + + CGPU_EXEC + T ry_c() const + { + return (ry_e+ry_0)/T(2); + } + + CGPU_EXEC + R_2d r_c() const + { + return {this->rx_c(), ry_c()}; + } + + CGPU_EXEC + T radius_y() const + { + return bs_y_h(); + } + + CGPU_EXEC + R_2d radius() const + { + return {this->radius_x(), radius_y()}; + } + + CGPU_EXEC + T radius_y_p(const T& p) const + { + return (T(1)-p)*radius_y(); + } + + CGPU_EXEC + R_2d radius_p(const T& p) const + { + return {this->radius_x_p(p), radius_y_p(p)}; + } + + void sft_region(const R_2d& bs, const R_2d& dr) + { + Region_Rect_xd::sft_region(bs.x, dr.x); + + ry_0 = fcn_set_bound(ry_0 + dr.y, T(0), bs.y); + ry_e = fcn_set_bound(ry_e + dr.y, T(0), bs.y); + } + + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_y(const T& y) const + { + return fcn_chk_bound(y, ry_0, ry_e); + } + + CGPU_EXEC + dt_bool chk_bound(const R_2d& r) const + { + return this->chk_bound_x(r.x) && chk_bound_y(r.y); + } + + CGPU_EXEC + dt_bool chk_bound(const T& rx, const T& ry)const + { + return this->chk_bound_x(rx) && chk_bound_y(ry); + } + + CGPU_EXEC + dt_bool chk_bound_y_eps(const T& y) const + { + return fcn_chk_bound_eps(y, ry_0, ry_e); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const R_2d& r) const + { + return this->chk_bound_x_eps(r.x) && chk_bound_y_eps(r.y); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const T& rx, const T& ry)const + { + return this->chk_bound_x_eps(rx) && chk_bound_y_eps(ry); + } + + template > + CGPU_EXEC + T sub_2_ind(const T& ix, const T& iy) const + { + return (iy-ry_0) + (ix-this->rx_0)*bs_y(); + } + }; + } + + /* template specialization 3d */ + namespace mt + { + template + class Region_Rect_xd: public Region_Rect_xd + { + public: + using value_type = T; + using size_type = dt_int32; + + T rz_0; // initial z position + T rz_e; // final z position + + /************************************* constructors ************************************/ + CGPU_EXEC + Region_Rect_xd(): Region_Rect_xd(), rz_0(0), rz_e(0) {} + + Region_Rect_xd(const T& rx_0, const T& rx_e, const T& ry_0, const T& ry_e, const T& rz_0, const T& rz_e) + { + set_in_data(rx_0, rx_e, ry_0, ry_e, rz_0, rz_e); + } + + template + Region_Rect_xd(U *data, const size_type& n_data) + { + Region_Rect_xd(data, n_data); + + rz_0 = (n_data>4)?data[4]:T(0); + rz_e = (n_data>5)?data[5]:T(0); + } + + /* copy constructor */ + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /* converting constructor */ + template + CGPU_EXEC + Region_Rect_xd(const Region_Rect_xd& region) + { + *this = region; + } + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + rz_0 = region.rz_0; + rz_e = region.rz_e; + } + + return *this; + } + + /* converting assignment operator */ + template + CGPU_EXEC + Region_Rect_xd& operator=(const Region_Rect_xd& region) + { + if (this != ®ion) + { + Region_Rect_xd::operator=(region); + + rz_0 = T(region.rz_0); + rz_e = T(region.rz_e); + } + + return *this; + } + + template + CGPU_EXEC + void assign(const Region_Rect_xd& region) + { + *this = region; + } + + /***************************************************************************************/ + template + void set_in_data(const U& rx_0, const U& rx_e, const U& ry_0, const U& ry_e, const U& rz_0, const U& rz_e) + { + Region_Rect_xd::set_in_data(rx_0, rx_e, ry_0, ry_e); + + this->rz_0 = rz_0; + this->rz_e = rz_e; + } + + CGPU_EXEC + void clear() + { + Region_Rect_xd::clear(); + + rz_0 = T(0); + rz_e = T(0); + } + + CGPU_EXEC + T bs_z() const + { + return fcn_max(rz_e-rz_0, T(0)); + } + + CGPU_EXEC + R_3d bs() const + { + return {this->bs_x(), this->bs_y(), bs_z()}; + } + + CGPU_EXEC + T bs_z_h() const + { + return bs_z()/T(2); + } + + CGPU_EXEC + R_3d bs_h() const + { + return {this->bs_x_h(), this->bs_y_h(), bs_z_h()}; + } + + CGPU_EXEC + T rz_c() const + { + return (rz_e+rz_0)/T(2); + } + + CGPU_EXEC + R_3d r_c() const + { + return {this->rx_c(), this->ry_c(), rz_c()}; + } + + CGPU_EXEC + T radius_z() const + { + return bs_z_h(); + } + + CGPU_EXEC + R_3d radius() const + { + return {this->radius_x(), this->radius_y(), radius_z()}; + } + + CGPU_EXEC + T radius_z_p(const T& p) const + { + return (T(1)-p)*radius_z(); + } + + CGPU_EXEC + R_3d radius_p(const T& p) const + { + return {this->radius_x_p(p), this->radius_y_p(p), radius_z_p(p)}; + } + + void sft_region(const R_3d& bs, const R_3d& dr) + { + Region_Rect_xd::sft_region({bs.x, bs.y}, {dr.x, dr.y}); + + rz_0 = fcn_set_bound(rz_0 + dr.z, T(0), bs.z); + rz_e = fcn_set_bound(rz_e + dr.z, T(0), bs.z); + } + + /***************************************************************************************/ + CGPU_EXEC + dt_bool chk_bound_z(const T& z) const + { + return fcn_chk_bound(z, rz_0, rz_e); + } + + CGPU_EXEC + dt_bool chk_bound(const R_3d& r) const + { + return this->chk_bound_x(r.x) && this->chk_bound_y(r.y) && chk_bound_z(r.z); + } + + CGPU_EXEC + dt_bool chk_bound(const T& rx, const T& ry, const T& rz)const + { + return this->chk_bound_x(rx) && this->chk_bound_y(ry) && chk_bound_z(rz); + } + + CGPU_EXEC + dt_bool chk_bound_z_eps(const T& z) const + { + return fcn_chk_bound_eps(z, rz_0, rz_e); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const R_3d& r) const + { + return this->chk_bound_x_eps(r.x) && this->chk_bound_y_eps(r.y) && chk_bound_z_eps(r.z); + } + + CGPU_EXEC + dt_bool chk_bound_eps(const T& rx, const T& ry, const T& rz)const + { + return this->chk_bound_x_eps(rx) && this->chk_bound_y_eps(ry) && chk_bound_z_eps(rz); + } + + template > + CGPU_EXEC + T sub_2_ind(const T& ix, const T& iy, const T& iz) const + { + return (iy-this->ry_0) + (ix-this->rx_0)*this->bs_y() + (iz-rz_0)*this->bs_y()*this->bs_x(); + } + }; + } + + /***************************************************************************************/ + /* symmetric region */ + namespace mt + { + /* + template + struct Region_Rad_1d + { + public: + using T = class TVctr::value_type; + using size_type = dt_uint64; + + TVctr Rx; + TVctr R2; + TVctr Ixy; + + T R_max; + T Rx_sf; + + T Ixy_sf; + T Ixy_sc; + T Ixy_sum; + + Region_Rad_1d(): Rx_sf(0), Ixy_sf(0), Ixy_sc(1), Ixy_sum(0) + { + } + + size_type size() const + { + return Ixy.size(); + } + + void clear() + { + Rx.clear(); + R2.clear(); + Ixy.clear(); + } + + void reserve(const size_type& new_size) + { + Rx.reserve(new_size); + R2.reserve(new_size); + Ixy.reserve(new_size); + } + + void shrink_to_fit() + { + Rx.shrink_to_fit(); + R2.shrink_to_fit(); + Ixy.shrink_to_fit(); + } + + TVctr sft_Ixy(T bg) + { + TVctr Ixy_s; + Ixy_s.reserve(Ixy.size()); + + for(auto ixy=0; ixy + struct Region_Rad_2d + { + public: + using T = class TVctr::value_type; + using size_type = dt_uint64; + + TVctr Rx; + TVctr Ry; + TVctr R2; + TVctr Ixy; + + T R_max; + T Rx_sf; + T Ry_sf; + T Rxy_sc; + + T Ixy_sf; + T Ixy_sc; + T Ixy_sum; + + Region_Rad_2d(): Rx_sf(0), Ry_sf(0), Rxy_sc(1), + Ixy_sf(0), Ixy_sc(1), Ixy_sum(0) {} + + size_type size() const + { + return Ixy.size(); + } + + void clear() + { + Rx.clear(); + Ry.clear(); + R2.clear(); + Ixy.clear(); + } + + void reserve(const size_type& new_size) + { + Rx.reserve(new_size); + Ry.reserve(new_size); + R2.reserve(new_size); + Ixy.reserve(new_size); + } + + void shrink_to_fit() + { + Rx.shrink_to_fit(); + Ry.shrink_to_fit(); + R2.shrink_to_fit(); + Ixy.shrink_to_fit(); + } + + TVctr sft_Ixy(T bg) + { + TVctr Ixy_s; + Ixy_s.reserve(Ixy.size()); + + for(auto ixy=0; ixy& grid_2d, TVctr& Im_s, T x, T y) + { + TVctr v = Ixy; + + T R2_max = ::square(R_max); + + R_2d p(x, y); + auto range = grid_2d.ithread(p, R_max); + dt_int32 iv = 0; + for(auto ix = range.ix_0; ix < range.ix_e; ix++) + { + for(auto iy = range.iy_0; iy < range.iy_e; iy++) + { + T r2 = grid_2d.r2(ix, iy, p.x, p.y); + if (r2 < R2_max) + { + v[iv++] -= Im_s[grid_2d.sub_2_ind(ix, iy)]/Ixy_sc; + } + } + } + + return v; + } + + TVctr sft_Ixy(Grid_2d& grid_2d, TVctr& Im_s, T x, T y, T a, T s) + { + TVctr v = sub_region_to_Ixy(grid_2d, Im_s, x*Rxy_sc+Rx_sf, y*Rxy_sc+Ry_sf); + + T alpha = T(0.5)/::square(s); + T r2_l = ::square(T(4)*s); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x; + T ry = Ry[im]-y; + T r2 = rx*rx+ry*ry; + if (r2& grid_2d, TVctr& Im_s, TVctr& x, TVctr& y, TVctr& A, TVctr& S) + { + TVctr v = sub_region_to_Ixy(grid_2d, Im_s, x[0]*Rxy_sc+Rx_sf, y[0]*Rxy_sc+Ry_sf); + + for(auto ip = 0; ip < x.size(); ip++) + { + T a = A[ip]; + T b = S[ip]; + T alpha = 0.5/pow(b, 2); + T r2_l = pow(4.0*b, 2); + for(auto im = 0; im < v.size(); im++) + { + T rx = Rx[im]-x[ip]; + T ry = Ry[im]-y[ip]; + T r2 = rx*rx+ry*ry; + if (r2 sft_x_y(T x, T y) const + { + x = sft_Rx(x); + y = sft_Ry(y); + return R_2d(x, y); + } + + // not including R2 + void sf_sc() + { + KS Ixy_sum_t = 0; + for(auto ixy = 0; ixy < Ixy.size(); ixy++) + { + Rx[ixy] = (Rx[ixy] - Rx_sf)/Rxy_sc; + Ry[ixy] = (Ry[ixy] - Ry_sf)/Rxy_sc; + T Iv = Ixy[ixy]/Ixy_sc; + Ixy[ixy] = Iv; + Ixy_sum_t += Iv; + } + Ixy_sum = Ixy_sum_t; + } + }; + */ + + } + +#endif \ No newline at end of file diff --git a/src/rnd_1d_cpu.h b/src/rnd_1d_cpu.h new file mode 100755 index 00000000..f8c5b24b --- /dev/null +++ b/src/rnd_1d_cpu.h @@ -0,0 +1,106 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "rnd_cpu.h" +#include "stream_cpu.h" + +/* template definition */ +namespace mt +{ +#ifndef RND_XD_DEC + #define RND_XD_DEC + template class Rnd_xd; +#endif +} + +/* derived class */ +namespace mt +{ + /* uniform distribution */ + template + using Rndu_1d_cpu = Rnd_xd; + + /* normal distribution */ + template + using Rndn_1d_cpu = Rnd_xd; + + /* poisson distribution */ + template + using Rndp_1d_cpu = Rnd_xd; +} + +/* template specialization 1d distribution */ +namespace mt +{ + template + class Rnd_xd: public Gen_seed + { + public: + using value_type = T; + + static const eDev device = edev_cpu; + + T m_sc; // scaling + T m_sft; // shift + + Rnd_xd(dt_uint64 seed=300183, dt_int32 n_iter=1); + + void set_in_data(const dt_uint64& seed, const T& sc, const T& sft, dt_int32 n_iter=1); + + void set_seed(dt_uint64 seed, dt_int32 n_iter=1); + + void set_sc_sft(const T& sc, const T& sft); + + T operator()(); + + T operator()(const T& sc); + + T operator()(const T& sc, const T& sft); + + private: + Rnd_Dist rnd; + }; +} + +/* fcns */ +namespace mt +{ + // add uniform noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_unif_nois(TVctr_i& mx_i, Value_type sc, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream = nullptr); + + // add gaussian noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_gauss_nois(TVctr_i& mx_i, Value_type sigma, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream = nullptr); + + + // add poisson noise + template + enable_if_vctr_cpu_and_vctr_cpu + fcn_add_poiss_nois(TVctr_i& mx_i, double sc_i, dt_uint64 seed_i, TVctr_o& mx_o, Stream_cpu* pstream = nullptr); + + //// add Poisson noise + //template + //TVctr add_poiss_nois_by_SNR(Stream& stream, TVctr& Im_i, Value_type SNR_i, Value_type& scl_o); +} + +#include "detail/rnd_1d_cpu.inl" \ No newline at end of file diff --git a/src/rnd_2d_cpu.h b/src/rnd_2d_cpu.h new file mode 100755 index 00000000..dc071f53 --- /dev/null +++ b/src/rnd_2d_cpu.h @@ -0,0 +1,90 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "rnd_cpu.h" +#include "stream_cpu.h" + +/* template definition */ +namespace mt +{ +#ifndef RND_XD_DEC + #define RND_XD_DEC + template class Rnd_xd; +#endif +} + +/* derived class */ +namespace mt +{ + /* uniform distribution */ + template + using Rndu_2d_cpu = Rnd_xd; + + /* normal distribution */ + template + using Rndn_2d_cpu = Rnd_xd; + + /* poisson distribution */ + template + using Rndp_2d_cpu = Rnd_xd; +} + +/* 2d distribution */ +namespace mt +{ + template + class Rnd_xd: public Gen_seed + { + public: + using value_type = T; + + static const eDev device = edev_cpu; + + R_2d m_sc; // scaling + R_2d m_sft; // shift + R_2d m_b_dim; // active dimensions + + Rnd_xd(dt_uint64 seed=300183, dt_int32 n_iter=1); + + void set_in_data(const dt_uint64& seed, const R_2d& sc, const R_2d& sft, dt_int32 n_iter=1); + + void set_seed(dt_uint64 seed, dt_int32 n_iter=1); + + void set_sc_sft(const R_2d& sc, const R_2d& sft); + + void set_act_dim(const R_2d& b_dim); + + R_2d operator()(); + + R_2d operator()(const R_2d& sc); + + R_2d operator()(const R_2d& sc, const R_2d& sft); + + private: + R_2d gen_rnd(const R_2d& sc); + + R_2d gen_rnd(const R_2d& sc, const R_2d& sft); + + Rnd_Dist rnd_x; + Rnd_Dist rnd_y; + }; +} + +#include "detail/rnd_2d_cpu.inl" \ No newline at end of file diff --git a/src/rnd_3d_cpu.h b/src/rnd_3d_cpu.h new file mode 100755 index 00000000..2faf7b4d --- /dev/null +++ b/src/rnd_3d_cpu.h @@ -0,0 +1,91 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "rnd_cpu.h" +#include "stream_cpu.h" + +/* template definition */ +namespace mt +{ +#ifndef RND_XD_DEC + #define RND_XD_DEC + template class Rnd_xd; +#endif +} + +/* derived class */ +namespace mt +{ + /* uniform distribution */ + template + using Rndu_3d_cpu = Rnd_xd; + + /* normal distribution */ + template + using Rndn_3d_cpu = Rnd_xd; + + /* poisson distribution */ + template + using Rndp_3d_cpu = Rnd_xd; +} + +/* 3d distribution */ +namespace mt +{ + template + class Rnd_xd: public Gen_seed + { + public: + using value_type = T; + + static const eDev device = edev_cpu; + + R_3d m_sc; // scaling + R_3d m_sft; // shift + R_3d m_b_dim; // active dimensions + + Rnd_xd(dt_uint64 seed=300183, dt_int32 n_iter=1); + + void set_in_data(const dt_uint64& seed, const R_3d& sc, const R_3d& sft, dt_int32 n_iter=1); + + void set_seed(dt_uint64 seed, dt_int32 n_iter=1); + + void set_sc_sft(const R_3d& sc, const R_3d& sft); + + void set_act_dim(const R_3d& b_dim); + + R_3d operator()(); + + R_3d operator()(const R_3d& sc); + + R_3d operator()(const R_3d& sc, const R_3d& sft); + + private: + R_3d gen_rnd(const R_3d& sc); + + R_3d gen_rnd(const R_3d& sc, const R_3d& sft); + + Rnd_Dist rnd_x; + Rnd_Dist rnd_y; + Rnd_Dist rnd_z; + }; +} + +#include "detail/rnd_3d_cpu.inl" \ No newline at end of file diff --git a/src/rnd_cpu.h b/src/rnd_cpu.h new file mode 100755 index 00000000..0cb8a685 --- /dev/null +++ b/src/rnd_cpu.h @@ -0,0 +1,120 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include + +#include "const_enum.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" +#include "vctr_cpu.h" + +/* template definition */ +namespace mt +{ + template class Rnd_Dist; +} + +/* derived class */ +namespace mt +{ + template + using Dist_type = typename std::conditional, + typename std::conditional, \ + typename std::conditional, T>::type>::type>::type; +} + +/* class template random distribution */ +namespace mt +{ + template + class Rnd_Dist + { + public: + using value_type = T; + + void set_seed(const dt_uint64& seed); + + void reset_rnd(); + + T operator()(const T& x); + + T operator()(const T& x, const T& sft); + private: + std::mt19937_64 gen; + Dist_type rnd; + }; +} + +/* template specialization random distribution Poisson */ +namespace mt +{ + template + class Rnd_Dist + { + public: + using value_type = T; + + void set_seed(const dt_uint64& seed); + + void reset_rnd(); + + T operator()(const T& x); + + T operator()(const T& x, const T& sft); + + private: + std::mt19937_64 gen; + Dist_type rnd; + }; +} + +/* class generation seed */ +namespace mt +{ + class Gen_seed + { + public: + dt_uint64 m_seed; // seed + + Gen_seed(dt_uint64 seed=300183); + + dt_uint64 seed_1d(dt_uint64 seed, dt_int32 n_iter=1); + + R_2d seed_2d(dt_uint64 seed, dt_int32 n_iter=1); + + R_3d seed_3d(dt_uint64 seed, dt_int32 n_iter=1); + + dt_uint64 operator()(); + + Vctr_uint64_cpu operator()(const dt_int32& n_spl); + + private: + void set_seed(const dt_uint64& seed); + + /* generate seed by iteration */ + dt_uint64 iseed(const dt_int32& n_iter); + + std::mt19937_64 gen_u; + std::uniform_int_distribution rnd_u; + }; +} + +#include "detail/rnd_cpu.inl" \ No newline at end of file diff --git a/src/rot_in_parm.hpp b/src/rot_in_parm.hpp new file mode 100755 index 00000000..f819b2d0 --- /dev/null +++ b/src/rot_in_parm.hpp @@ -0,0 +1,100 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef ROT_IN_PARM_H + #define ROT_IN_PARM_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "r_3d.h" + + namespace mt + { + /*********************** rotation parameters *************************/ + template + class Rot_In_Parm + { + public: + T theta; // angle + R_3d u_0; // unitary vector + eRot_Ctr_Typ ctr_type; // erct_geometric_ctr, erct_user_def + R_3d ctr_p; // rotation point + + Rot_In_Parm(): theta(0), u_0(0, 0, 1), ctr_type(erct_geometric_ctr), ctr_p(1, 0, 0) {} + + template + void assign(Rot_In_Parm& rot_in_parm) + { + if (this != &rot_in_parm) + { + theta = rot_in_parm.theta; + u_0 = rot_in_parm.u_0; + ctr_type = rot_in_parm.ctr_type; + ctr_p = rot_in_parm.ctr_p; + } + } + + void set_in_data(const T& theta, const R_3d& u_0, const eRot_Ctr_Typ& ctr_type, const R_3d& ctr_p) + { + this->theta = theta; + this->u_0 = u_0; + this->ctr_type = ctr_type; + this->ctr_p = ctr_p; + + set_dep_var(); + } + + void set_dep_var() + { + u_0.normalize(); + } + + template + Rot_In_Parm& operator=(Rot_In_Parm& rot_in_parm) + { + assign(rot_in_parm); + return *this; + } + + dt_bool is_rot_ctr_none() const + { + return mt::is_rot_ctr_none(center_type); + } + + dt_bool is_rot_ctr_geometric_ctr() const + { + return mt::is_rot_ctr_geometric_ctr(center_type); + } + + dt_bool is_rot_ctr_user_def() const + { + return mt::is_rot_ctr_user_def(center_type); + } + + dt_bool is_rot_active() const + { + return fcn_is_nzero(theta); + } + }; + } + +#endif \ No newline at end of file diff --git a/src/scan_pat.hpp b/src/scan_pat.hpp new file mode 100755 index 00000000..b3084ba9 --- /dev/null +++ b/src/scan_pat.hpp @@ -0,0 +1,237 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SCAN_PAT_H + #define SCAN_PAT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include "const_enum.h" + #include "math_mt.h" + #include "fcns_cgpu_gen.h" + #include "r_2d.h" + #include "cgpu_vctr.cuh" + + namespace mt + { + /************************* scanning pattern **************************/ + template + struct Scan_Pat + { + public: + using value_type = T; + using size_type = dt_int32; + + eScan_Pat_Typ typ; // 1: Line, 2: Area, 3: User_Define + dt_bool pbc; // periodic boundary conditions + dt_bool spxs; // square pixel size + R_2d nsp; // number of sampling points + R_2d r_0; // initial scanning position + R_2d r_e; // final scanning position + Vctr_r_2d_cpu r; // user define positions + + Scan_Pat(): typ(espt_line), pbc(false), spxs(true), nsp(0, 0), + r_0(0, 0), r_e(0, 0), dr(0, 0){}; + + template + void assign(Scan_Pat& scan) + { + if (this != &scan) + { + typ = scan.typ; + pbc = scan.pbc; + spxs = scan.spxs; + nsp = scan.nsp; + r_0 = scan.r_0; + r_e = scan.r_e; + + dr = scan.dr; + r = scan.r; + } + } + + void set_in_data(const eScan_Pat_Typ& typ, const dt_bool& pbc, const dt_bool& spxs, + const R_2d& nsp, const R_2d& r_0, const R_2d& r_e, const Vctr_r_2d_cpu& r) + { + this->typ = typ; + this->pbc = pbc; + this->spxs = spxs; + this->nsp = nsp; + this->r_0 = r_0; + this->r_e = r_e; + this->r = r; + + set_dep_var(); + } + + void set_dep_var() + { + if ((nsp.x <= 0) || (nsp.y <= 0)) + { + clear(); + return; + } + + if (is_scan_pat_line()) + { + set_grid_scan_pat_line(); + } + else if (is_scan_pat_area()) + { + set_grid_scan_pat_area(); + } + else if (is_scan_pat_user_def()) + { + nsp.x = r.size(); + nsp.y = nsp.x; + } + } + + template + Scan_Pat& operator=(Scan_Pat& scan) + { + assign(scan); + return *this; + } + + size_type size() const + { + return nsp.x*nsp.y; + } + + void clear() + { + typ = espt_line; + pbc = false; + spxs = true; + nsp.x = 0; + nsp.y = 0; + r_0 = 0; + r_e = 0; + r.clear_shrink_to_fit(); + dr = 0; + } + + R_2d operator()(const dt_int32& ind) const + { + if (is_scan_pat_user_def()) + { + return r_ud[ind]; + } + else + { + const dt_int32 ix = ind/nsp.y; + const dt_int32 iy = ind - ix*nsp.y; + + return (r_0 + R_2d(ix, iy)*dr); + } + } + + Vctr_cpu rx_vctr() const + { + Vctr_cpu x; + x.reserve(nsp.x); + if (is_scan_pat_user_def()) + { + for(auto ix = 0; ix ry_vctr() const + { + Vctr_cpu y; + y.reserve(nsp.y); + if (is_scan_pat_user_def()) + { + for(auto iy = 0; iy dr; // pixel size + + void set_grid_scan_pat_line() + { + const auto r_u = r_e-r_0; + dr = r_u/((pbc)?nsp:(nsp-1)); + } + + void set_grid_scan_pat_area() + { + const auto r_u = r_e-r_0; + dr = r_u/((pbc)?nsp:(nsp-1)); + + if (spxs) + { + if (fabs(r_u.x)>fabs(r_u.y)) + { + dr.y = std::copysign(dr.x, r_u.y); + nsp.y = fcn_cfloor(r_u.y/dr.y+Epsilon::rel+0.5); + nsp.y += (pbc)?0:1; + } + else + { + dr.x = std::copysign(dr.y, r_u.x); + nsp.x = fcn_cfloor(r_u.x/dr.x+Epsilon::rel+0.5); + nsp.x += (pbc)?0:1; + } + } + } + + }; + } + +#endif \ No newline at end of file diff --git a/src/shape_t.h b/src/shape_t.h new file mode 100755 index 00000000..59f98b2a --- /dev/null +++ b/src/shape_t.h @@ -0,0 +1,92 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include + +#include "macros.h" + +/* template definition */ +template class dt_shape_st; + + +/* derived class */ +using dt_shape = dt_shape_st; + +using dt_shape_64 = dt_shape_st; + + +template +class dt_shape_st +{ +public: + /************************************* constructors ************************************/ + dt_shape_st(); + + template + dt_shape_st(const U& s0); + + template + dt_shape_st(const U& s0, const V& s1); + + template + dt_shape_st(const U& s0, const V& s1, const X& s2); + + template + dt_shape_st(const U& s0, const V& s1, const X& s2, const Y& s3); + + /* copy constructor */ + dt_shape_st(const dt_shape_st& shape); + + /* converting constructor */ + template + dt_shape_st(const dt_shape_st& shape); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + dt_shape_st& operator=(const dt_shape_st& shape); + + /* converting assignment operator */ + template + dt_shape_st& operator=(const dt_shape_st& shape); + + T& operator[](const int32_t& iy); + + const T& operator[](const int32_t& iy) const; + + T* data(); + + const T* data() const; + + T size(); + + T shape_size(); + + void swap(const int32_t& ind_0, const int32_t& ind_e); + + T dim() const; + + T m_data[4]; + +private: + const int32_t dim_max; +}; + +#include "detail/shape_t.inl" \ No newline at end of file diff --git a/src/slicing.hpp b/src/slicing.hpp deleted file mode 100644 index b7b2b4df..00000000 --- a/src/slicing.hpp +++ /dev/null @@ -1,436 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef SLICING_H -#define SLICING_H - -#include "math.cuh" -#include "types.cuh" -#include "atomic_data_mt.hpp" -#include "cpu_fcns.hpp" - -namespace mt -{ - template - class Input_Multislice; - - template - struct Slicing - { - public: - using value_type = T; - using size_type = std::size_t; - using TVector_r = Vector; - using TVector_i = Vector; - - Slicing(): m_input_multislice(nullptr), m_atoms_r(nullptr), m_atoms(nullptr), z_eps(1e-3){} - - void set_input_data(Input_Multislice *input_multislice, Atom_Data *atoms_r, Atom_Data *atoms=nullptr) - { - m_input_multislice = input_multislice; - - m_atoms_r = atoms_r; - m_atoms = (atoms==nullptr)?atoms_r:atoms; - - z_plane = get_z_plane(m_input_multislice->potential_slicing, *m_atoms_r); - } - - void match_thickness(ePotential_Slicing pot_sli, Atom_Data &atoms, - eThick_Type thick_type, TVector_r &thick) - { - if(thick_type == eTT_Whole_Spec) - { - thick.resize(1); - thick[0] = atoms.z_max; - return; - } - - auto z_plane = get_z_plane(pot_sli, atoms); - - if(thick_type == eTT_Through_Slices) - { - z_plane = get_z_slice(pot_sli, z_plane, atoms); - } - - match_vectors(z_plane.begin(), z_plane.end(), thick, 0.25*atoms.dz); - } - - T dz(int islice_0, int islice_e) - { - return (islice_epotential_slicing, z_plane, *m_atoms); - - thick = get_thick(m_input_multislice, m_z_slice, *m_atoms_r); - - slice = get_slicing(m_input_multislice, m_z_slice, thick, *m_atoms); - } - - TVector_r z_plane; - Vector, e_host> slice; - Vector, e_host> thick; - - private: - const T z_eps; - - Input_Multislice *m_input_multislice; - - Atom_Data *m_atoms_r; - Atom_Data *m_atoms; - - TVector_r m_z_slice; - Identify_Planes identify_planes; - - // get spacing - T get_spacing(size_type ix, TVector_r &x, T dz=0.5) - { - if(x.size()==1) - { - return dz; - } - - ix = (ix <= 0)?1:min(ix, x.size()-1); - return (x.size()>1)?x[ix]-x[ix-1]:0.0; - } - - // Identify planes: Require that the atoms to be sorted along z - TVector_r get_z_plane(ePotential_Slicing pot_sli, Atom_Data &atoms) - { - TVector_r z_plane; - - if(atoms.size() == 0) - { - return z_plane; - } - - atoms.validate_amorphous_parameters(); - - const int region_ct = 0; - - // select z values of the crystal region - TVector_r z_ct; - z_ct.reserve(atoms.size()); - - for(auto iz=0; iz zt2(z_plane.begin(), z_plane.end()); - auto bb_ali = !atoms.amorp_lay_info.empty(); - if(bb_ali && (fabs(atoms.z_min-z_plane.front())>z_eps)) - { - T dz_b = get_spacing(1, z_plane); - auto amorp = atoms.amorp_lay_info.front(); - auto z_plane_top = identify_planes(amorp.z_0, amorp.z_e-dz_b, amorp.dz); - z_plane.insert(z_plane.begin(), z_plane_top.begin(), z_plane_top.end()); - } - - if(bb_ali && (fabs(z_plane.back()-atoms.z_max)>z_eps)) - { - T dz_b = get_spacing(z_plane.size()-1, z_plane); - auto amorp = atoms.amorp_lay_info.back(); - auto z_plane_bottom = identify_planes(amorp.z_0+dz_b, amorp.z_e, amorp.dz); - z_plane.insert(z_plane.end(), z_plane_bottom.begin(), z_plane_bottom.end()); - } - - // unique vector - unique_vector(z_plane); - - return z_plane; - } - - // get z slicing - TVector_r get_z_slice(ePotential_Slicing pot_sli, TVector_r &z_plane, Atom_Data &atoms) - { - TVector_r z_slice; - - if((pot_sli!=ePS_dz_Sub) && (z_plane.size() == 1)) - { - z_slice.resize(2); - z_slice[0] = atoms.z_int_min; - z_slice[1] = atoms.z_int_max; - z_slice.shrink_to_fit(); - - return z_slice; - } - - TVector_r z_plane_sli = z_plane; - - z_slice.resize(z_plane_sli.size()+1); - z_slice[0] = z_plane_sli[0]-0.5*get_spacing(0, z_plane_sli, atoms.dz); - for(auto iz=1; iz, e_host> get_thick(Input_Multislice *input_multislice, - TVector_r &z_slice, Atom_Data &atoms) - { - const auto thick_type = input_multislice->thick_type; - - auto get_islice = [thick_type](TVector_r &z_slice, const T &z)->int - { - if(thick_type==eTT_Through_Slices) - { - for(auto i = 0; i::rel) - { - return i; - } - } - return 0; - } - else - { - for(auto i = 0; iis_subslicing_whole_spec(); - - Vector, e_host> thick(input_multislice->thick.size()); - for(auto ik = 0; ikthick[ik]; - auto islice = (b_sws)?(z_slice.size()-2):get_islice(z_slice, thick[ik].z); - thick[ik].islice = islice; - - auto iatom_e = fd_by_z(atoms.z, z_slice[islice+1], false); - thick[ik].iatom_e = iatom_e; - - thick[ik].z_zero_def_plane = input_multislice->obj_lens.get_zero_defocus_plane(atoms.z[0], atoms.z[iatom_e]); - if(input_multislice->is_through_slices()) - { - thick[ik].z_back_prop = 0; - } - else - { - // I need to recheck this part, the average should be replace by the plane - thick[ik].z_back_prop = thick[ik].z_zero_def_plane - 0.5*(z_slice[islice]+z_slice[islice+1]); - if(fabs(thick[ik].z_back_prop)::rel) - { - thick[ik].z_back_prop = 0; - } - } - } - - if(!input_multislice->is_multislice()) - { - for(auto ithick = 0; ithick, e_host> get_slicing(Input_Multislice *input_multislice, - TVector_r &z_slice, Vector, e_host> &thick, Atom_Data &atoms) - { - if(!input_multislice->is_multislice()) - { - Vector, e_host> slice(thick.size()); - for(auto islice = 0; islice, e_host> slice(z_slice.size()-1); - for(auto islice = 0; islicepotential_slicing) - { - case ePS_Planes: - { - slice[islice].z_int_0 = slice[islice].z_0; - slice[islice].z_int_e = slice[islice].z_e; - Inc_Borders = false; - } - break; - case ePS_dz_Proj: - { - slice[islice].z_int_0 = slice[islice].z_0; - slice[islice].z_int_e = slice[islice].z_e; - Inc_Borders = false; - } - break; - case ePS_dz_Sub: - { - T z_m = slice[islice].z_m(); - - slice[islice].z_int_0 = ::fmin(z_m - atoms.R_int_max, slice[islice].z_0); - slice[islice].z_int_e = ::fmax(z_m + atoms.R_int_max, slice[islice].z_e); - Inc_Borders = true; - } - break; - } - - fd_by_z(atoms.z, slice[islice].z_int_0, slice[islice].z_int_e, slice[islice].iatom_0, slice[islice].iatom_e, Inc_Borders); - - slice[islice].ithk = -1; - } - - //set thickness index - for(auto ithk = 0; ithk::rel:z_e; - - if(z_e::rel):z_0; - z_e = (Inc_Borders)?(z_e+Epsilon::rel):z_e; - - if((z_0>z_e)||(z.back() iz_e)||(z[iz_e] < z_0)||(z_e < z[iz_0])) - { - iz_0 = 1; - iz_e = 0; - } - } - }; - -} // namespace mt - -#endif diff --git a/src/space_group.hpp b/src/space_group.hpp new file mode 100755 index 00000000..caaaeede --- /dev/null +++ b/src/space_group.hpp @@ -0,0 +1,596 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPACE_GROUP_H + #define SPACE_GROUP_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "r_2d.h" + #include "r_3d.h" + #include "mx_2x2.h" + #include "mx_3x3.h" + #include "cgpu_vctr.cuh" + #include "types.cuh" + #include "particles.cuh" + + namespace mt + { + + template + struct Symm_Oper + { + Vctr_r_3d tr_g; + Vctr_Mx_3x3 M; + Vctr_r_3d tr; + + Symm_Oper(const Vctr_std>& tr_g, const Vctr_std>& M, const Vctr_std>& tr): + tr_g(tr_g), M(M), tr(tr) {} + + //Symm_Oper(const dt_init_list_r_3d_f64& tr_g, const dt_init_list_mx_3x3_f64& M, const dt_init_list_r_3d_f64& tr): + //tr_g(tr_g), M(M), tr(tr) {} + }; + + template + class Space_Group{ + public: + Space_Group(): ee(1e-4) {}; + + Space_Group(Ptc_Atom& asym_uc, dt_int32 sg=1): Space_Group() + { + ptc_atom = operator()(asym_uc, sg); + } + + operator Ptc_Atom() const + { + return ptc_atom; + } + + Ptc_Atom operator()(Ptc_Atom& asym_uc, dt_int32 sg=1) + { + auto sym = load_symm_oper(sg); + + const dt_int32 n_asym_uc = asym_uc.size(); + + const dt_int32 n_M = sym.M.size(); + const dt_int32 n_tr_g = sym.tr_g.size(); + + Ptc_Atom base; + base.reserve(n_M*n_tr_g*n_asym_uc); + base.cols_used = asym_uc.cols_used; + + for(auto i_tr=0; i_tr ptc_atom; + + T ee; + + dt_bool exist(Ptc_Atom& base, const R_3d& r) + { + const auto ee_2 = ee*ee; + for(auto i_b=0; i_b load_symm_oper(const dt_int32& sg) + { + switch(sg) + { + case 1: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}}}; + case 2: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 3: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 4: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 5: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 6: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 7: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 8: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 9: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 10: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 11: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 12: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 13: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 14: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 15: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 16: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 17: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 18: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 19: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 20: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 21: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 22: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 23: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 24: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 25: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 26: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 27: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 28: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 29: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 30: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 31: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 32: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 33: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 34: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 35: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 36: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 37: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 38: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 39: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 40: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 41: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 42: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 43: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 44: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 45: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 46: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 47: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 48: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 49: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 50: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 51: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 52: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}}}; + case 53: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 54: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 55: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 56: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 57: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}}}; + case 58: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 59: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}}}; + case 60: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 61: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 62: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 63: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 64: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 65: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 66: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 67: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 68: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 69: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 70: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {3.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 1.0/4.0}}}; + case 71: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 72: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 73: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 74: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 75: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 76: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 3.0/4.0}}}; + case 77: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 78: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/4.0}}}; + case 79: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 80: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}}}; + case 81: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 82: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 83: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 84: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 85: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}}}; + case 86: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 87: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 88: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 89: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 90: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 91: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/4.0}}}; + case 92: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 93: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 94: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 95: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/4.0}, {0.0, 0.0, 3.0/4.0}}}; + case 96: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}}}; + case 97: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 98: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 99: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 100: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 101: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 102: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 103: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 104: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 105: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 106: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 107: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 108: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 109: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}}}; + case 110: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 0.0, 1.0/4.0}}}; + case 111: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 112: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 113: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 114: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 115: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 116: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 117: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 118: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 119: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 120: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 121: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 122: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}, {1.0/2.0, 0.0, 3.0/4.0}}}; + case 123: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 124: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 125: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 126: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 127: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 128: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 129: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 130: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 131: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 132: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 133: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 134: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 135: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 136: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 137: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 138: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 139: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 140: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 141: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}}}; + case 142: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 143: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 144: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}}}; + case 145: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}}}; + case 146: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 147: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 148: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 149: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 150: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 151: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}}}; + case 152: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}}}; + case 153: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}}}; + case 154: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}}}; + case 155: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 156: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 157: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 158: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 159: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 160: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 161: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 162: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 163: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 164: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 165: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 166: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 167: + return {{{0.0, 0.0, 0.0}, {2/3, 1.0/3.0, 1.0/3.0}, {1.0/3.0, 2/3, 2/3}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 168: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 169: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 1.0/6.0}}}; + case 170: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 5.0/6.0}}}; + case 171: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}}}; + case 172: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}}}; + case 173: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 174: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 175: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 176: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 177: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 178: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/6.0}}}; + case 179: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 5.0/6.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 1.0/6.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 5.0/6.0}}}; + case 180: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}}}; + case 181: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}, {0.0, 0.0, 1.0/3.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 2/3}}}; + case 182: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 183: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 184: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 185: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 186: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 187: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 188: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 189: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 190: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 191: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 192: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 193: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 194: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 0.0, 1.0/2.0}}}; + case 195: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 196: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 197: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 198: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 199: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 200: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 201: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}}; + case 202: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 203: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {3.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 0.0}}}; + case 204: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 205: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 206: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}}}; + case 207: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 208: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 209: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 210: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 211: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 212: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + case 213: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 214: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 215: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 216: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 217: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 218: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 219: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 220: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}}}; + case 221: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 222: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {0.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 223: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 224: + return {{{0.0, 0.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}}}; + case 225: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 226: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 227: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}}}; + case 228: + return {{{0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/2.0, 1.0/4.0}, {1.0/2.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 0.0}, {0.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {1.0/4.0, 0.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 0.0}, {1.0/4.0, 0.0, 3.0/4.0}, {0.0, 3.0/4.0, 1.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/4.0, 1.0/2.0, 3.0/4.0}, {1.0/2.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {3.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 0.0}, {0.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}, {3.0/4.0, 0.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 0.0}, {3.0/4.0, 0.0, 1.0/4.0}, {0.0, 1.0/4.0, 3.0/4.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}}; + case 229: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}; + case 230: + return {{{0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 1.0/2.0}}, {{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, {0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 1.0/4.0}, {1.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 3.0/4.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {0.0, 0.0, 0.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {0.0, 1.0/2.0, 1.0/2.0}, {0.0, 0.0, 0.0}, {0.0, 1.0/2.0, 1.0/2.0}, {1.0/2.0, 1.0/2.0, 0.0}, {1.0/2.0, 0.0, 1.0/2.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {1.0/4.0, 3.0/4.0, 3.0/4.0}, {3.0/4.0, 3.0/4.0, 1.0/4.0}, {3.0/4.0, 1.0/4.0, 3.0/4.0}, {1.0/4.0, 1.0/4.0, 1.0/4.0}}}; + } + return {{}, {}, {}}; + } + }; + } +#endif diff --git a/src/spec.hpp b/src/spec.hpp old mode 100644 new mode 100755 index 19b291fa..b0c341b8 --- a/src/spec.hpp +++ b/src/spec.hpp @@ -1,151 +1,150 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef SPECIMEN_H -#define SPECIMEN_H - -#include "math.cuh" -#include "types.cuh" -#include "lin_alg_def.cuh" -#include "cgpu_rand.cuh" -#include "atomic_data.hpp" -#include "atomic_data_mt.hpp" -#include "input_multislice.cuh" -#include "cgpu_fcns.cuh" -#include "cpu_fcns.hpp" -#include "slicing.hpp" - -namespace mt -{ - template - class Spec - { - public: - using T_r = T; - using size_type = std::size_t; - - Spec(): input_multislice(nullptr){} - - void set_input_data(Input_Multislice *input_multislice_i) - { - input_multislice = input_multislice_i; - - /***************************************************************************/ - Atomic_Data atomic_data(input_multislice->potential_type); - - atom_type.resize(c_nAtomsTypes); - for(auto i = 0; iVrl, input_multislice->nR, input_multislice->grid_2d.dR_min(), atom_type[i]); - } - - /***************************************************************************/ - atoms_u.set_atoms(input_multislice->atoms, input_multislice->grid_2d.pbc_xy, &atom_type); - atoms_u.sort_by_z(); - - /***************************************************************************/ - slicing.set_input_data(input_multislice, &atoms_u, &atoms); - - /***************************************************************************/ - if((input_multislice->is_phase_object()) || (atoms_u.s_z_int < 2.0*input_multislice->grid_2d.dz) || ((slicing.z_plane.size() == 1) && input_multislice->is_slicing_by_planes())) - { - input_multislice->grid_2d.dz = atoms_u.s_z_int; - input_multislice->interaction_model = eESIM_Phase_Object; - input_multislice->islice = 0; - input_multislice->pn_dim.z = false; - if(input_multislice->is_through_slices()) - { - input_multislice->thick_type = eTT_Through_Thick; - } - input_multislice->slice_storage = input_multislice->slice_storage || !input_multislice->is_whole_spec(); - atoms_u.dz = input_multislice->grid_2d.dz; - } - - atoms.set_atoms(atoms_u, false, &atom_type); - // This is needed for memory preallocation in Transmission function - slicing.calculate(); - } - - /* Move atoms (cgpu_rand distribution will be included in the future) */ - void move_atoms(const int &fp_iconf) - { - // set phonon configuration - if(input_multislice->is_frozen_phonon()) - { - rand.seed(input_multislice->pn_seed, fp_iconf); - rand.set_activation(input_multislice->pn_dim.x, input_multislice->pn_dim.y, input_multislice->pn_dim.z); - } - - // move atoms - for(int iatoms = 0; iatomsis_frozen_phonon()) - { - auto sigma_x = atoms_u.sigma[iatoms]; - auto sigma_y = atoms_u.sigma[iatoms]; - auto sigma_z = atoms_u.sigma[iatoms]; - r += rand(sigma_x, sigma_y, sigma_z); - } - - atoms.x[iatoms] = r.x; - atoms.y[iatoms] = r.y; - atoms.z[iatoms] = r.z; - atoms.sigma[iatoms] = atoms_u.sigma[iatoms]; - atoms.occ[iatoms] = atoms_u.occ[iatoms]; - atoms.region[iatoms] = atoms_u.region[iatoms]; - atoms.charge[iatoms] = atoms_u.charge[iatoms]; - } - - if(input_multislice->pn_dim.z) - { - atoms.sort_by_z(); - } - - // get atom information - atoms.get_statistic(&atom_type); - - // slicing procedure - slicing.calculate(); - } - - T dz(const int &islice) - { - return slicing.dz(islice)/cos(input_multislice->theta); - } - - T dz_m(const int &islice_0, const int &islice_e) - { - return slicing.dz_m(islice_0, islice_e)/cos(input_multislice->theta); - } - - Input_Multislice *input_multislice; - - Atom_Data atoms; // displaced atoms - Slicing slicing; // slicing procedure - Vector, e_host> atom_type; // Atom types - private: - Randn_3d rand; - Atom_Data atoms_u; - }; - -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPEC_H +#define SPEC_H + +#include "math_mt.h" +#include "types.cuh" +#include "cgpu_rand.cuh" +#include "atomic_data_mt.cuh" +#include "particles.cuh" +#include "in_classes.cuh" +#include "fcns_gpu.h" +#include "fcns_cpu.h" +#include "spec_slic.hpp" + +namespace mt +{ + template + class Spec + { + public: + using T_r = T; + using size_type = dt_uint64; + + Spec(): multem_in_parm(nullptr) {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i) + { + multem_in_parm = multem_in_parm_i; + + /***************************************************************************************/ + Atomic_Data atomic_data_mt(multem_in_parm->atomic_pot_parm_typ); + + atom_type.resize(c_n_atom_typ); + for(auto i = 0; i < atom_type.size(); i++) + { + atomic_data_mt.To_atom_type_CPU(i+1, multem_in_parm->Vrl, multem_in_parm->nR, multem_in_parm->grid_2d.dR_min(), atom_type[i]); + } + + /***************************************************************************************/ + atoms_u.set_ptc(multem_in_parm->atoms, multem_in_parm->grid_2d.pbc_xy, &atom_type); + atoms_u.sort_by_z(); + + /***************************************************************************************/ + slicing.set_in_data(multem_in_parm, &atoms_u, &atoms); + + /***************************************************************************************/ + if ((atoms_u.s_z_int < 2.0*multem_in_parm->grid_2d.sli_thick) || ((slicing.z_plane.size() == 1) && multem_in_parm->is_spec_slic_by_plns_proj())) + { + multem_in_parm->grid_2d.sli_thick = atoms_u.s_z_int; + multem_in_parm->elec_spec_interact_mod = eesim_phase_object; + multem_in_parm->islice = 0; + multem_in_parm->atomic_vib.dim_z = false; + if (multem_in_parm->is_sim_through_slices()) + { + multem_in_parm->thick_type = estt_through_thick; + } + multem_in_parm->slice_storage = multem_in_parm->slice_storage || !multem_in_parm->is_sim_whole_spec(); + atoms_u.sli_thick = multem_in_parm->grid_2d.sli_thick; + } + + atoms.set_ptc(atoms_u, false, &atom_type); + // This is needed for memory preallocation in Transmission function + slicing.calculate(); + } + + /* Move atoms (random distribution will be included in the future) */ + void move_atoms(const dt_int32& fp_iconf) + { + // set atomic_vib configuration + if (multem_in_parm->is_avm_frozen_phonon()) + { + rand.seed(multem_in_parm->atomic_vib.seed, fp_iconf); + rand.set_act_dim(multem_in_parm->atomic_vib.dim_x, multem_in_parm->atomic_vib.dim_y, multem_in_parm->atomic_vib.dim_z); + } + + // move atoms + for(dt_int32 iatoms = 0; iatomsis_avm_frozen_phonon()) + { + auto sigma_x = atoms_u.sigma[iatoms]; + auto sigma_y = atoms_u.sigma[iatoms]; + auto sigma_z = atoms_u.sigma[iatoms]; + r += rand(sigma_x, sigma_y, sigma_z); + } + + atoms.x[iatoms] = r.x; + atoms.y[iatoms] = r.y; + atoms.z[iatoms] = r.z; + atoms.sigma[iatoms] = atoms_u.sigma[iatoms]; + atoms.occ[iatoms] = atoms_u.occ[iatoms]; + atoms.tag[iatoms] = atoms_u.tag[iatoms]; + atoms.charge[iatoms] = atoms_u.charge[iatoms]; + } + + if (multem_in_parm->atomic_vib.dim_z) + { + atoms.sort_by_z(); + } + + // get atom information + atoms.get_statistic(&atom_type); + + // slicing procedure + slicing.calculate(); + } + + T sli_thick(const dt_int32& islice) + { + return slicing.sli_thick(islice)/cos(multem_in_parm->theta); + } + + T dz_m(const dt_int32& islice_0, const dt_int32& islice_e) + { + return slicing.dz_m(islice_0, islice_e)/cos(multem_in_parm->theta); + } + + Multem_In_Parm *multem_in_parm; + + Ptc_Atom atoms; // displaced atoms + Spec_Slic slicing; // slicing procedure + Vctr, edev_cpu> atom_type; // Atom types + private: + Rndn_3d rand; + Ptc_Atom atoms_u; + }; + +} + #endif \ No newline at end of file diff --git a/src/spec_slic.hpp b/src/spec_slic.hpp new file mode 100755 index 00000000..aa361e0b --- /dev/null +++ b/src/spec_slic.hpp @@ -0,0 +1,704 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPEC_SLIC_H + #define SPEC_SLIC_H + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "kahan_sum.h" + #include "r_2d.h" + #include "types_mt.cuh" + #include "fcns_cgpu_gen.h" + #include "particles.cuh" + #include "fcns_cpu.h" + #include "cgpu_vctr.cuh" + #include "spec_slic_in_parm.hpp" + + namespace mt + { + + /*************************** identify planes *************************/ + class Ident_Pla + { + public: + using T = dt_float64; + + Ident_Pla(): dv(0.1) {} + + // identify planes: require v to be sorted + template + Vctr_cpu operator()(pVctr_cpu_32& v, T v_min=0, T v_max=0) + { + if (v.size()==0) + { + return Vctr_cpu(); + } + + if (v_min >= v_max) + { + v_min = T(v.front()); + v_max = T(v.back()); + } + + // calculate hist and correct it + auto v_hist = hist(v, dv, v_min, v_max); + + if (v_hist.size()==1) + { + return Vctr_cpu({fcn_mean(v)}); + } + + // calculate layer limits + Vctr_cpu v_lim; + v_lim.reserve(v_hist.size()+1); + + for(auto iv = 0; iv < v_hist.size()-1; iv++) + { + if ((v_hist[iv]>0) && (v_hist[iv+1]==0)) + { + v_lim.push_back(v_min + T(iv+1)*dv); + } + } + v_hist.clear_shrink_to_fit(); // free v_hist + + v_lim.push_back(v_max+dv); + v_lim.shrink_to_fit(); + + // calculate planes + Vctr_cpu v_pln; + v_pln.reserve(v_lim.size()); + + KS v_s = 0; + dt_int32 v_c = 1; + dt_int32 ip = 0; + for(auto iv = 0; iv < v.size(); iv++) + { + const auto v_ih = v[iv]; + + if (!fcn_chk_bound_eps(v_ih, v_min, v_max)) + { + continue; + } + + if (v_ih + Vctr_cpu operator()(U v_min, U v_max, U dv, eMatch_Bdr match_bdr=emb_minmax) + { + if (fcn_is_equal(v_min, v_max)) + { + return Vctr_cpu({U(0.5)*(v_min+v_max)}); + } + + if (v_min >= v_max) + { + return Vctr_cpu(); + } + + const auto v_l = T(v_max-v_min); + + const dt_int32 nv = max(0, fcn_cceil(v_l/T(dv)))+1; + + // calculate planes + Vctr_cpu v_pln; + v_pln.reserve(nv); + + switch (match_bdr) + { + case emb_min: + { + for(auto iv=0; iv=0; iv--) + { + v_pln.push_back(v_max - U(iv)*dv); + } + } + break; + case emb_minmax: + { + const auto dv_b = dv + 0.5*(v_l-(nv-1)*dv); + + v_pln.push_back(v_min); + for(auto iv=1; iv + Vctr_cpu hist(pVctr_cpu_32& v, const T& dv, const T& v_min, const T& v_max) + { + const auto v_l = ::fmax(v_max-v_min, dv); + + const auto n_bins = fcn_cceil(v_l/dv); + + auto fcn_v_r = [v_min, dv](const dt_int32& ik, T& v_r_0, T& v_r_e) + { + v_r_0 = v_min + T(ik-1)*dv; + v_r_e = v_r_0 + dv; + }; + + Vctr_cpu v_hist(n_bins, 0); + + // get histogram + for(auto iv = 0; iv< v.size(); iv++) + { + T v_r_0, v_r_e; + const auto v_id = T(v[iv]); + auto ih = fcn_cfloor((v_id-v_min)/dv); + + fcn_v_r(ih-1, v_r_0, v_r_e); + + if (v_id= 0; ik--) + { + fcn_v_r(ik-1, v_r_0, v_r_e); + if (fcn_chk_bound(v_id, v_r_0, v_r_e)) + { + ih = ik-1; + break; + } + } + } + else if (v_id>v_r_e) + { + for(auto ik = ih; ik < n_bins; ik++) + { + fcn_v_r(ik, v_r_0, v_r_e); + if (fcn_chk_bound(v_id, v_r_0, v_r_e)) + { + ih = ik; + break; + } + } + } + ih = fcn_set_bound(ih, 0, n_bins-1); + + v_hist[ih]++; + } + + return v_hist; + } + }; + + /************************* slice thickness ***************************/ + template + class Out_Slic + { + public: + Out_Slic(): z_pln(0), z_lim(0, 0), z_int_lim(0, 0), + iatom_lim(0, 0), ithk(-1) {} + + R_2d z_pln; // z-position + R_2d z_lim; // z-position limit + R_2d z_int_lim; // z-int-position limit + R_2d iatom_lim; // index to z-position limit + dt_int32 ithk; // thick index + + T sli_thick() const { return ::fabs(z_lim.y-z_lim.x); } + }; + + template + class Spec_Slic + { + public: + using value_type = T; + using size_type = dt_uint64; + + Vctr_cpu z_plns; + Vctr_cpu> slice; + Vctr_cpu> thick; + + Spec_Slic(): patoms_r(nullptr), patoms(nullptr), z_eps(1e-3) {} + + void set_in_data(const Vctr_cpu& in_slic, Ptc_Atom* patoms_r=nullptr, Ptc_Atom* patoms=nullptr) + { + patoms_r = patoms_r; + if (fcn_is_null_ptr(patoms)) + { + patoms = patoms_r; + } + + z_plns = get_z_plns(in_slic, patoms_r); + } + + Vctr_cpu get_z_plns(const Vctr_cpu& in_slic, Ptc_Atom* patoms) + { + // get planes + Vctr_cpu> z_pln_s(in_slic.size()); + + for(auto ir=0; ir> z_pln(in_slic.size()); + + for(auto ir=0; ir& patoms, + //eSim_Thick_Typ thick_type, Vctr_cpu &thick) + //{ + // if (thick_type == estt_whole_spec) + // { + // thick.resize(1); + // thick[0] = patoms->z_max; + // return; + // } + + // auto z_plns = get_z_plane(spec_slic_typ, patoms); + + // if (thick_type == estt_through_slices) + // { + // z_plns = get_z_slice(spec_slic_typ, z_plns, patoms); + // } + + // fcn_match_vctr(z_plns.begin(), z_plns.end(), thick, 0.25*patoms->sli_thick); + //} + + //T sli_thick(dt_int32 islice_0, dt_int32 islice_e) + //{ + // return (islice_espec_slic_typ, z_plns, *patoms); + + // thick = get_thick(m_multem_in_parm, m_z_slice, *patoms_r); + + // slice = get_slicing(m_multem_in_parm, m_z_slice, thick, *patoms); + //} + + private: + const T z_eps; + + Ptc_Atom* patoms_r; + Ptc_Atom* patoms; + + Vctr_cpu m_z_slice; + Ident_Pla ident_pln; + + // get z positions by tag + Vctr_cpu get_z_pos_by_tag(Ptc_Atom* patoms, const dt_int32& tag) + { + Vctr_cpu z; + z.reserve(patoms->size()); + + for(auto iz = 0; izsize(); iz++) + { + if (patoms->get_tag(iz)==tag) + { + z.push_back(patoms->z[iz]); + } + } + z.shrink_to_fit(); + std::sort(z.begin(), z.end()); + + return z; + } + + // get z positions by z range and atomic number + Vctr_cpu get_z_pos_by_rng(Ptc_Atom* patoms, const dt_int32& Z, const R_2d& z_lim) + { + Vctr_cpu z; + z.reserve(patoms->size()); + + if Z<=0 + { + for(auto iz = 0; izsize(); iz++) + { + if (fcn_chk_bound_eps(patoms->z[iz], z_lim.x, z_lim.y)) + { + z.push_back(patoms->z[iz]); + } + } + } + else + { + for(auto iz = 0; izsize(); iz++) + { + if ((patoms->Z[iz]==Z) && fcn_chk_bound_eps(patoms->z[iz], z_lim.x, z_lim.y)) + { + z.push_back(patoms->z[iz]); + } + } + } + + z.shrink_to_fit(); + std::sort(z.begin(), z.end()); + + return z; + } + + // identify planes: atoms have to be sorted along z + Vctr_cpu get_z_plns(const Spec_Slic_In_Parm& in_slic, Ptc_Atom* patoms) + { + if (patoms->size() == 0) + { + return Vctr_cpu(); + } + + // get z planes + if (in_slic.is_spec_slic_by_user_def()) + { + return in_slic.z_plns; + } + else + { + Vctr_cpu z; + + if (in_slic.is_spec_slic_sel_typ_by_tag()) + { + z = get_z_pos_by_tag(patoms, in_slic.sel_tag); + } + else if (in_slic.is_spec_slic_sel_typ_by_z()) + { + z = get_z_pos_by_rng(patoms, in_slic.sel_Z, in_slic.sel_z_lim); + } + + if (in_slic.is_spec_slic_by_planes()) + { + return ident_pln(z); + } + else + { + return ident_pln(z_ct_min, z_ct_max, in_slic.sli_thick); + } + } + + return Vctr_cpu(); + } + + + //// get spacing + //T get_spacing(size_type ix, Vctr_cpu &x, T sli_thick=0.5) + //{ + // if (x.size()==1) + // { + // return sli_thick; + // } + + // ix = (ix <= 0)?1:min(ix, x.size()-1); + // return (x.size()>1)?x[ix]-x[ix-1]:0.0; + //} + + //// get z slicing + //Vctr_cpu get_z_slice(eSpec_Slic_Typ spec_slic_typ, Vctr_cpu &z_plns, Ptc_Atom& patoms) + //{ + // Vctr_cpu z_slice; + + // if ((spec_slic_typ!=esst_dz_sub) && (z_plns.size() == 1)) + // { + // z_slice.resize(2); + // z_slice[0] = patoms->z_int_min; + // z_slice[1] = patoms->z_int_max; + // z_slice.shrink_to_fit(); + + // return z_slice; + // } + + // Vctr_cpu z_plane_sli = z_plns; + + // z_slice.resize(z_plane_sli.size()+1); + // z_slice[0] = z_plane_sli[0]-0.5*get_spacing(0, z_plane_sli, patoms->sli_thick); + // for(auto iz=1; izsli_thick); + + // if (spec_slic_typ==esst_dz_sub) + // { + // T dz_b = get_spacing(1, z_plane_sli, patoms->sli_thick); + // if (patoms->z_int_minsli_thick); + // auto z_slice_top = ident_pln(patoms->z_int_min, z_slice.front()-dz_b, dz_s); + // z_slice.insert(z_slice.begin(), z_slice_top.begin(), z_slice_top.end()); + // } + // else + // { + // z_slice[0] = patoms->z_int_min; + // } + + // dz_b = get_spacing(z_plane_sli.size()-1, z_plane_sli, patoms->sli_thick); + // if (z_slice.back()+dz_bz_int_max) + // { + // T dz_s = get_spacing(z_plane_sli.size()-2, z_plane_sli, patoms->sli_thick); + // auto z_slice_bottom = ident_pln(z_slice.back()+dz_b, patoms->z_int_max, dz_s); + // z_slice.insert(z_slice.end(), z_slice_bottom.begin(), z_slice_bottom.end()); + // } + // else + // { + // z_slice[z_slice.size()-1] = patoms->z_int_max; + // } + // } + + // z_slice.shrink_to_fit(); + + // return z_slice; + //} + + //// get thick + //Vctr, edev_cpu> get_thick(Multem_In_Parm *multem_in_parm, + //Vctr_cpu &z_slice, Ptc_Atom& patoms) + //{ + // const auto thick_type = multem_in_parm->thick_type; + + // auto get_islice = [thick_type](Vctr_cpu &z_slice, const T& z)->dt_int32 + // { + // if (thick_type==estt_through_slices) + // { + // for(auto i = 0; i::rel) + // { + // return i; + // } + // } + // return 0; + // } + // else + // { + // for(auto i = 0; iis_spec_slic_by_dz_sub_whole_spec(); + + // Vctr, edev_cpu> thick(multem_in_parm->thick.size()); + // for(auto ik = 0; ikthick[ik]; + // auto islice = (b_sws)?(z_slice.size()-2):get_islice(z_slice, thick[ik].z); + // thick[ik].islice = islice; + + // auto iatom_e = fd_by_z(patoms->z, z_slice[islice+1], false); + // thick[ik].iatom_e = iatom_e; + + // thick[ik].z_zero_def_plane = multem_in_parm->obj_lens.get_zero_def_plane(patoms->z[0], patoms->z[iatom_e]); + // if (multem_in_parm->is_sim_through_slices()) + // { + // thick[ik].z_back_prop = 0; + // } + // else + // { + // // I need to recheck this part, the average should be replace by the plane + // thick[ik].z_back_prop = thick[ik].z_zero_def_plane - 0.5*(z_slice[islice]+z_slice[islice+1]); + // if (fabs(thick[ik].z_back_prop)::rel) + // { + // thick[ik].z_back_prop = 0; + // } + // } + // } + + // if (!multem_in_parm->is_multislice()) + // { + // for(auto ithick = 0; ithick, edev_cpu> get_slicing(Multem_In_Parm *multem_in_parm, + //Vctr_cpu &z_slice, Vctr, edev_cpu>& thick, Ptc_Atom& patoms) + //{ + // if (!multem_in_parm->is_multislice()) + // { + // Vctr, edev_cpu> slice(thick.size()); + // for(auto islice = 0; islicez_int_min:thick[islice-1].z; + // slice[islice].z_e = (thick.size() == 1)?patoms->z_int_max:thick[islice].z; + // slice[islice].z_int_0 = slice[islice].z_0; + // slice[islice].z_int_e = slice[islice].z_e; + // slice[islice].iatom_0 = (islice == 0)?0:(thick[islice-1].iatom_e+1); + // slice[islice].iatom_e = thick[islice].iatom_e; + // slice[islice] .ithk = islice; + // } + // return slice; + // } + + // Vctr, edev_cpu> slice(z_slice.size()-1); + // for(auto islice = 0; islicespec_slic_typ) + // { + // case esst_plns_proj: + // { + // slice[islice].z_int_0 = slice[islice].z_0; + // slice[islice].z_int_e = slice[islice].z_e; + // Inc_Borders = false; + // } + // break; + // case esst_dz_proj: + // { + // slice[islice].z_int_0 = slice[islice].z_0; + // slice[islice].z_int_e = slice[islice].z_e; + // Inc_Borders = false; + // } + // break; + // case esst_dz_sub: + // { + // T z_m = slice[islice].z_m(); + + // slice[islice].z_int_0 = ::fmin(z_m - patoms->R_int_max, slice[islice].z_0); + // slice[islice].z_int_e = ::fmax(z_m + patoms->R_int_max, slice[islice].z_e); + // Inc_Borders = true; + // } + // break; + // } + + // fd_by_z(patoms->z, slice[islice].z_int_0, slice[islice].z_int_e, slice[islice].iatom_0, slice[islice].iatom_e, Inc_Borders); + // + // slice[islice].ithk = -1; + // } + + // // set thickness index + // for(auto ithk = 0; ithk &z, T z_e, dt_bool Inc_Borders) + //{ + // dt_int32 iz_e =-1; + // z_e = (Inc_Borders)?z_e+Epsilon::rel:z_e; + + // if (z_e &z, T z_0, T z_e, dt_int32& iz_0, dt_int32& iz_e, dt_bool Inc_Borders) + //{ + // z_0 = (Inc_Borders)?(z_0-Epsilon::rel):z_0; + // z_e = (Inc_Borders)?(z_e+Epsilon::rel):z_e; + + // if ((z_0>z_e)||(z.back() iz_e)||(z[iz_e] < z_0)||(z_e < z[iz_0])) + // { + // iz_0 = 1; + // iz_e = 0; + // } + //} + }; + + } + +#endif diff --git a/src/spec_slic_in_parm.hpp b/src/spec_slic_in_parm.hpp new file mode 100755 index 00000000..d00156e8 --- /dev/null +++ b/src/spec_slic_in_parm.hpp @@ -0,0 +1,158 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef SPEC_SLIC_IN_PARM_H + #define SPEC_SLIC_IN_PARM_H + + #include "const_enum_mt.cuh" + #include "r_2d.h" + #include "cgpu_vctr.cuh" + + namespace mt + { + template + class Spec_Slic_In_Parm + { + public: + using value_type = T; + + eSpec_Slic_Typ typ; // esst_plns_proj = 1, esst_dz_proj = 2, esst_plns_sub = 3, esst_dz_sub = 4, esst_user_def = 5, esst_auto = 6 + T sli_thick; // slice thickness + eSpec_Slic_Sel_Typ sel_typ; // essso_tag = 1, essso_z = 2 + dt_int32 sel_tag; // tag + dt_int32 sel_Z; // atomic number + R_2d sel_z_lim; // [z_0, z_e] + Vctr_cpu z_plns; // z planes positions + + Spec_Slic_In_Parm(): typ( esst_plns_proj), sli_thick(0), sel_typ(0), + sel_tag(0), sel_Z(0), sel_z_lim{0, 0} {} + + template + void assign(Spec_Slic_In_Parm& spec_slic_in_parm) + { + if (this != &spec_slic_in_parm) + { + typ = spec_slic_in_parm.typ; + sli_thick = T(spec_slic_in_parm.sli_thick); + sel_typ = spec_slic_in_parm.sel_typ; + sel_tag = spec_slic_in_parm.sel_tag; + sel_Z = spec_slic_in_parm.sel_Z; + sel_z_lim = spec_slic_in_parm.sel_z_lim; + z_plns = spec_slic_in_parm.z_plns; + } + } + + void set_in_data(const eSpec_Slic_Typ& typ, const T& sli_thick, const eSpec_Slic_Sel_Typ& sel_typ, + const dt_int32& sel_tag, const dt_int32& sel_Z, const R_2d& sel_z_lim, const Vctr_cpu& z_plns) + { + this->typ = typ; + this->sli_thick = sli_thick; + this->sel_typ = sel_typ; + this->sel_tag = sel_tag; + this->sel_Z = sel_Z; + this->sel_z_lim = sel_z_lim; + this->z_plns = z_plns; + + set_dep_var(); + } + + void set_dep_var() + { + sel_Z = fcn_max(sel_Z, 0); + + if (!is_spec_slic_by_user_def()) + { + z_plns.clear_shrink_to_fit(); + } + else + { + if (is_spec_slic_sel_typ_by_z() && (sel_z_lim.y + Spec_Slic_In_Parm& operator=(Spec_Slic_In_Parm& spec_slic_in_parm) + { + assign(spec_slic_in_parm); + return *this; + } + + void clear() + { + typ = esst_plns_proj; + sli_thick = 0; + el_typ = 0; + sel_tag = 0; + sel_Z = 0; + sel_z_lim = 0; + } + + dt_bool is_spec_slic_by_plns_proj() + { + return mt::is_spec_slic_by_plns_proj(typ); + } + + dt_bool is_spec_slic_by_dz_proj() + { + return mt::is_spec_slic_by_dz_proj(typ); + } + + dt_bool is_spec_slic_by_plns_sub() + { + return mt::is_spec_slic_by_plns_sub(typ); + } + + dt_bool is_spec_slic_by_dz_sub() + { + return mt::is_spec_slic_by_dz_sub(typ); + } + + dt_bool is_spec_slic_by_user_def() + { + return mt::is_spec_slic_by_user_def(typ); + } + + dt_bool is_spec_slic_by_auto() + { + return mt::is_spec_slic_by_auto(typ); + } + + dt_bool is_spec_slic_by_planes() + { + return mt::is_spec_slic_by_planes(typ); + } + + dt_bool is_spec_slic_sel_typ_by_tag() + { + return mt::is_spec_slic_sel_typ_by_tag(sel_typ); + } + + dt_bool is_spec_slic_sel_typ_by_z() + { + return mt::is_spec_slic_sel_typ_by_z(sel_typ); + } + }; + + template + using Vctr_Spec_Slic_In_Parm = Vctr_cpu>; + } + +#endif diff --git a/src/stream.cuh b/src/stream.cuh deleted file mode 100644 index 24a18617..00000000 --- a/src/stream.cuh +++ /dev/null @@ -1,356 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef STREAM_H -#define STREAM_H - -#include - -#include -#include - -namespace mt -{ - template - struct Stream; - - template <> - struct Stream - { - public: - static const eDevice device = e_host; - - std::mutex stream_mutex; - - Stream(): nx(0), ny(0), nxy(0), nstream(0), n_act_stream(0), - stream(nullptr){} - - Stream(int new_nstream): nx(0), ny(0), nxy(0), nstream(0), - n_act_stream(0), stream(nullptr) - { - resize(new_nstream); - } - - ~Stream(){ destroy(); nstream = 1; n_act_stream = 1; } - - int size() const - { - return nstream; - } - - void resize(int new_nstream) - { - new_nstream = max(1, new_nstream); - - destroy(); - - nstream = new_nstream; - if(nstream > 1) - { - stream = new std::thread[nstream-1]; - } - - set_n_act_stream(size()); - } - - std::thread& operator[](const int i){ return stream[i]; } - - const std::thread& operator[](const int i) const { return stream[i]; } - - void synchronize() - { - destroy(); - - if(nstream > 1) - { - stream = new std::thread[nstream-1]; - } - } - - void set_n_act_stream(const int &new_n_act_stream) - { - n_act_stream = (new_n_act_stream<0)?0:min(size(), new_n_act_stream); - } - - void set_grid(const int &nx_i, const int &ny_i) - { - nx = nx_i; - ny = ny_i; - nxy = nx*ny; - } - - Range_2d get_range(const int &istream) - { - Range_2d range; - - int qnxy = nxy/n_act_stream; - range.ixy_0 = istream*qnxy; - range.ixy_e = (istream+1)*qnxy; - - int qnx = nx/n_act_stream; - range.ix_0 = istream*qnx; - range.ix_e = (istream+1)*qnx; - range.iy_0 = 0; - range.iy_e = ny; - - if(istream == n_act_stream-1) - { - range.ix_e += (nx - qnx*n_act_stream); - range.ixy_e += (nxy - qnxy*n_act_stream); - } - return range; - } - - Range_2d get_range_yx(const int &istream) - { - Range_2d range; - - int qnxy = nxy/n_act_stream; - range.ixy_0 = istream*qnxy; - range.ixy_e = (istream+1)*qnxy; - - int qny = ny/n_act_stream; - range.iy_0 = istream*qny; - range.iy_e = (istream+1)*qny; - range.ix_0 = 0; - range.ix_e = nx; - - if(istream == n_act_stream-1) - { - range.iy_e += (ny - qny*n_act_stream); - range.ixy_e += (nxy - qnxy*n_act_stream); - } - return range; - } - - template - void exec(TFn &fn, TArgs &...arg) - { - if(n_act_stream < 1) - { - return; - } - - for(auto istream = 0; istream < n_act_stream-1; istream++) - { - stream[istream] = std::thread(std::bind(fn, get_range(istream), std::ref(arg)...)); - } - - fn(get_range(n_act_stream-1), std::ref(arg)...); - - synchronize(); - } - - template - void exec_matrix(TFn &fn, TArgs &...arg) - { - if(n_act_stream < 1) - { - return; - } - - auto thr_fn_m = [&](const Range_2d &range, TArgs &...arg) - { - for(auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for(auto iy = range.iy_0; iy < range.iy_e; iy++) - { - fn(ix, iy, arg...); - } - } - }; - - for(auto istream = 0; istream < n_act_stream-1; istream++) - { - stream[istream] = std::thread(std::bind(thr_fn_m, get_range(istream), std::ref(arg)...)); - } - - thr_fn_m(get_range(n_act_stream-1), std::ref(arg)...); - - synchronize(); - } - - template - void exec_vector(TFn &fn, TArgs &...arg) - { - if(n_act_stream < 1) - { - return; - } - - auto thr_fn_v = [&](const Range_2d &range, TArgs &...arg) - { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - fn(ixy, arg...); - } - }; - - for(auto istream = 0; istream < n_act_stream-1; istream++) - { - stream[istream] = std::thread(std::bind(thr_fn_v, get_range(istream), std::ref(arg)...)); - } - - thr_fn_v(get_range(n_act_stream-1), std::ref(arg)...); - - synchronize(); - } - - int n_act_stream; - private: - int nx; - int ny; - int nxy; - - int nstream; - std::thread *stream; - - void destroy() - { - if(nstream < 0) - { - return; - } - - for(auto i = 0; i < nstream-1; i++) - { - if(stream[i].joinable()) - { - stream[i].join(); - } - } - - delete [] stream; - }; - }; - - template <> - struct Stream - { - public: - static const eDevice device = e_device; - - Stream(): nx(0), ny(0), nxy(0), n_act_stream(0){} - - Stream(int new_nstream): nx(0), ny(0), nxy(0), n_act_stream(0) - { - resize(new_nstream); - } - - ~Stream(){ destroy(); n_act_stream = 0; } - - int size() const - { - return static_cast(stream.size()); - } - - void resize(int new_nstream) - { - new_nstream = max(1, new_nstream); - - destroy(); - - stream.resize(new_nstream); - - for(auto i = 0; i < stream.size(); i++) - { - cudaStreamCreate(&(stream[i])); - } - - set_n_act_stream(size()); - } - - cudaStream_t& operator[](const int i){ return stream[i]; } - - const cudaStream_t& operator[](const int i) const { return stream[i]; } - - void synchronize() - { - cudaDeviceSynchronize(); - } - - void set_n_act_stream(const int &new_n_act_stream) - { - n_act_stream = (new_n_act_stream<0)?0:min(size(), new_n_act_stream); - } - - void set_grid(const int &nx_i, const int &ny_i) - { - nx = nx_i; - ny = ny_i; - nxy = nx*ny; - } - - Range_2d get_range(const int &istream) - { - Range_2d range; - - int qnxy = nxy/n_act_stream; - range.ixy_0 = istream*qnxy; - range.ixy_e = (istream+1)*qnxy; - - int qnx = nx/n_act_stream; - range.ix_0 = istream*qnx; - range.ix_e = (istream+1)*qnx; - range.iy_0 = 0; - range.iy_e = ny; - - if(istream == n_act_stream-1) - { - range.ix_e += (nx - qnx*n_act_stream); - range.ixy_e += (nxy - qnxy*n_act_stream); - } - return range; - } - - template - void exec(TFn &fn) - { - // for(auto istream = 0; istream < n_act_stream; istream++) - // { - // stream[istream] = std::thread(fn, get_range(istream)); - // } - // synchronize(); - } - - int n_act_stream; - - std::vector stream; - private: - int nx; - int ny; - int nxy; - - void destroy() - { - if(stream.empty()) - { - return; - } - - cudaDeviceSynchronize(); - - for(auto i = 0; i < stream.size(); i++) - { - cudaStreamDestroy(stream[i]); - } - } - }; -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/stream_cpu.h b/src/stream_cpu.h new file mode 100755 index 00000000..33515f1c --- /dev/null +++ b/src/stream_cpu.h @@ -0,0 +1,137 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include +#include + +#include "const_enum.h" +#include "type_traits_gen.h" +#include "kahan_sum.h" +#include "ithread_rect_1d.h" +#include "ithread_rect_2d.h" +#include "ithread_rect_3d.h" + +/* forward declaration */ +namespace mt +{ +#ifndef STREAM_DEC + #define STREAM_DEC + template class Stream; +#endif +} + +/* derived class */ +namespace mt +{ + using Stream_cpu = Stream; +} + +/* template specialization cpu stream */ +namespace mt +{ + template <> + class Stream + { + public: + static const eDev device = edev_cpu; + + std::mutex stream_mutex; + + Stream(); + + Stream(const dt_int32& n_stream); + + Stream(const dt_int32& n_stream, const dt_shape& shape); + + ~Stream(); + + dt_int32 size() const; + + dt_bool is_single_thread() const; + + void resize(const dt_int32& n_stream); + + std::thread& operator[](const dt_int32& iy); + + const std::thread& operator[](const dt_int32& iy) const; + + void synchronize(); + + void set_n_stream_act(const dt_int32& n_stream_act); + + void set_grid(const dt_shape& shape); + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx); + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny); + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz); + + template + enable_if_edim_1> + get_ithread_rect_xd(dt_int32 istm=0); + + template + enable_if_edim_2> + get_ithread_rect_xd(dt_int32 istm=0); + + template + enable_if_edim_3> + get_ithread_rect_xd(dt_int32 istm=0); + + /***************************************************************************************/ + template + enable_if_edim_1 + exec_xd_krn(const dt_int32& nx, TFcn& fcn, TArgs& ...arg); + + template + enable_if_edim_2 + exec_xd_krn(const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs& ...arg); + + template + enable_if_edim_3 + exec_xd_krn(const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs& ...arg); + + /***************************************************************************************/ + template + enable_if_edim_1 + exec_xd_fcn(const dt_int32& nx, TFcn& fcn, TArgs& ...arg); + + template + enable_if_edim_2 + exec_xd_fcn(const dt_int32& nx, const dt_int32& ny, TFcn& fcn, TArgs& ...arg); + + template + enable_if_edim_3 + exec_xd_fcn(const dt_int32& nx, const dt_int32& ny, const dt_int32& nz, TFcn& fcn, TArgs& ...arg); + + void cleanup(); + + dt_int32 n_stream_act; + private: + dt_shape shape; + + dt_int32 n_stream; + std::thread *stream; + }; +} + +#include "detail/stream_cpu.inl" \ No newline at end of file diff --git a/src/stream_gpu.h b/src/stream_gpu.h new file mode 100755 index 00000000..6b320996 --- /dev/null +++ b/src/stream_gpu.h @@ -0,0 +1,114 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include + +#ifdef __CUDACC__ + #include + #include +#endif + +#include "const_enum.h" +#include "type_traits_gen.h" +#include "kahan_sum.h" +#include "ithread_rect_1d.h" +#include "ithread_rect_2d.h" +#include "ithread_rect_3d.h" + +/* forward declaration */ +namespace mt +{ +#ifndef STREAM_DEC + #define STREAM_DEC + template class Stream; +#endif +} + +/* derived class */ +namespace mt +{ + using Stream_gpu = Stream; +} + +/* template specialization gpu stream */ +namespace mt +{ +#ifdef __CUDACC__ + template <> + class Stream + { + public: + static const eDev device = edev_gpu; + + Stream(); + + Stream(const dt_int32& n_stream); + + Stream(const dt_int32& n_stream, const dt_shape& shape); + + ~Stream(); + + dt_int32 size() const; + + void resize(const dt_int32& n_stream); + + cudaStream_t& operator[](const dt_int32& iy); + + const cudaStream_t& operator[](const dt_int32& iy) const; + + void synchronize(); + + void set_n_stream_act(const dt_int32& n_stream_act); + + void set_grid(const dt_shape& shape); + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx); + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny); + + void set_n_stream_act_grid(const dt_int32& n_stream_act, const dt_int32& nx, const dt_int32& ny, const dt_int32& nz); + + template + enable_if_edim_1> + get_ithread_rect_xd(dt_int32 istm=0); + + template + enable_if_edim_2> + get_ithread_rect_xd(dt_int32 istm=0); + + template + enable_if_edim_3> + get_ithread_rect_xd(dt_int32 istm=0); + + void cleanup(); + + dt_int32 n_stream_act; + + private: + dt_shape shape; + + dt_int32 n_stream; + + std::vector stream; + }; +#endif +} + +#include "detail/stream_gpu.inl" \ No newline at end of file diff --git a/src/system_config.h b/src/system_config.h new file mode 100755 index 00000000..550a4b60 --- /dev/null +++ b/src/system_config.h @@ -0,0 +1,75 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "vctr_cpu.h" + +namespace mt +{ + class System_Config + { + public: + ePrecision precision; + eDev device; // eprc_float32 = 1, eprc_float64 = 2 + dt_int32 cpu_n_proc; // number of Cores CPU + dt_int32 cpu_n_thread; // number of threads + + Vctr_cpu gpu_device; // gpu devices + dt_int32 gpu_n_stream; // number of streams + + dt_int32 gpu_n_avbl; // number of selected gpus + dt_int32 n_stream; // number of streams + dt_int32 idx_0; // parameter position + + System_Config(); + + System_Config(const System_Config &system_config); + + System_Config& operator=(const System_Config &system_config); + + void set_dep_var(); + + void set_gpu(dt_int32 gpu_ind=-1); + + void set_gpu_by_ind(dt_int32 gpu_ind); + + dt_int32 get_n_sel_gpu(); + + dt_int32 get_sel_gpu(); + + dt_bool is_cpu() const; + + dt_bool is_gpu() const; + + dt_bool is_float32() const; + + dt_bool is_float64() const; + + dt_bool is_float32_cpu() const; + + dt_bool is_float64_cpu() const; + + dt_bool is_float32_gpu() const; + + dt_bool is_float64_gpu() const; + }; +} + +#include "detail/system_config.inl" \ No newline at end of file diff --git a/src/tem_simulation.cuh b/src/tem_simulation.cuh old mode 100644 new mode 100755 index 0cf0585e..dea0a27c --- a/src/tem_simulation.cuh +++ b/src/tem_simulation.cuh @@ -1,522 +1,602 @@ -/* - * This file is part of MULTEM. - * Copyright 2014 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef TEM_SIMULATION_H -#define TEM_SIMULATION_H - -#include -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" -#include "cgpu_fcns.cuh" -#include "energy_loss.cuh" -#include "wave_function.cuh" -#include "timing.cuh" -#include "matlab_mex.cuh" - -namespace mt -{ - template - class Multislice - { - public: - using T_r = T; - using T_c = complex; - - static const eDevice device = dev; - - static bool ext_stop_sim; - static int ext_niter; - static int ext_iter; - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i, FFT *fft2_i) - { - input_multislice = input_multislice_i; - stream = stream_i; - fft_2d = fft2_i; - - if(input_multislice->is_EELS_EFTEM()) - { - energy_loss.set_input_data(input_multislice, stream, fft_2d); - psi_thk.resize(input_multislice->grid_2d.nxy()); - if(input_multislice->eels_fr.is_Mixed_Channelling()) - { - trans_thk.resize(input_multislice->grid_2d.nxy()); - } - } - - wave_function.set_input_data(input_multislice, stream, fft_2d); - } - - template - void operator()(TOutput_multislice &output_multislice) - { - if(input_multislice->is_STEM_ISTEM()) - { - STEM_ISTEM(output_multislice); - } - else if(input_multislice->is_CBED_CBEI()) - { - CBED_CBEI(output_multislice); - } - else if(input_multislice->is_ED_HRTEM()) - { - ED_HRTEM(output_multislice); - } - else if(input_multislice->is_PED_HCTEM()) - { - PED_HCTEM(output_multislice); - } - else if(input_multislice->is_EWFS_EWRS()) - { - EWFS_EWRS(output_multislice); - } - else if(input_multislice->is_EELS_EFTEM()) - { - EELS_EFTEM(output_multislice); - } - } - - private: - template - void STEM_ISTEM(TOutput_multislice &output_multislice) - { - ext_niter = input_multislice->scanning.size()*input_multislice->number_conf(); - ext_iter = 0; - /*****************************************************************/ - - T_r w_pr_0 = input_multislice->get_phonon_rot_weight(); - - output_multislice.init(); - - input_multislice->iscan.resize(1); - input_multislice->beam_x.resize(1); - input_multislice->beam_y.resize(1); - - if(input_multislice->is_STEM() && input_multislice->pn_coh_contrib) - { - for(auto iscan = 0; iscan < input_multislice->scanning.size(); iscan++) - { - output_multislice.init_psi_coh(); - input_multislice->iscan[0] = iscan; - input_multislice->set_iscan_beam_position(); - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - wave_function.set_incident_wave(wave_function.psi_z); - wave_function.psi(w_pr_0, wave_function.psi_z, output_multislice); - - ext_iter++; - if(ext_stop_sim) break; - } - wave_function.set_m2psi_coh(output_multislice); - - if(ext_stop_sim) break; - } - } - else - { - if(input_multislice->is_illu_mod_full_integration()) - { - Q1 qt; - Q2 qs; - - ext_niter *= qt.size(); - - // Load quadratures - cond_lens_temporal_spatial_quadratures(input_multislice->cond_lens, qt, qs); - double c_10_0 = input_multislice->cond_lens.c_10; - - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - - // temporal incoherence - for(auto itemp = 0; itempcond_lens.set_defocus(c_10); - - for(auto iscan = 0; iscan < input_multislice->scanning.size(); iscan++) - { - input_multislice->iscan[0] = iscan; - input_multislice->set_iscan_beam_position(); - wave_function.set_incident_wave(wave_function.psi_z); - wave_function.psi(w, wave_function.psi_z, output_multislice); - - ext_iter++; - if(ext_stop_sim) break; - } - if(ext_stop_sim) break; - } - if(ext_stop_sim) break; - } - - wave_function.set_m2psi_coh(output_multislice); - - input_multislice->cond_lens.set_defocus(c_10_0); - } - else - { - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - for(auto iscan = 0; iscan < input_multislice->scanning.size(); iscan++) - { - input_multislice->iscan[0] = iscan; - input_multislice->set_iscan_beam_position(); - wave_function.set_incident_wave(wave_function.psi_z); - wave_function.psi(w_pr_0, wave_function.psi_z, output_multislice); - - ext_iter++; - if(ext_stop_sim) break; - } - if(ext_stop_sim) break; - } - - wave_function.set_m2psi_coh(output_multislice); - } - } - } - - template - void CBED_CBEI(TOutput_multislice &output_multislice) - { - output_multislice.init(); - - if(input_multislice->is_illu_mod_full_integration()) - { - Q1 qt; - Q2 qs; - - // Load quadratures - cond_lens_temporal_spatial_quadratures(input_multislice->cond_lens, qt, qs); - - /*****************************************************************/ - double w_pr_0 = input_multislice->get_phonon_rot_weight(); - double c_10_0 = input_multislice->cond_lens.c_10; - const int nbeams = input_multislice->number_of_beams(); - - Vector beam_x(nbeams); - Vector beam_y(nbeams); - - ext_niter = qs.size()*qt.size()*input_multislice->number_conf(); - ext_iter = 0; - - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - - // spatial incoherence - for(auto ispat = 0; ispatiw_x[ibeam] + qs.x[ispat]; - beam_y[ibeam] = input_multislice->iw_y[ibeam] + qs.y[ispat]; - } - - // temporal incoherence - for(auto itemp = 0; itempcond_lens.set_defocus(c_10); - wave_function.set_incident_wave(wave_function.psi_z, beam_x, beam_y); - wave_function.psi(w, wave_function.psi_z, output_multislice); - - ext_iter++; - if(ext_stop_sim) break; - } - if(ext_stop_sim) break; - } - - if(ext_stop_sim) break; - } - wave_function.set_m2psi_coh(output_multislice); - - input_multislice->cond_lens.set_defocus(c_10_0); - input_multislice->set_beam_position(input_multislice->iw_x, input_multislice->iw_y); - } - else - { - EWFS_EWRS(output_multislice); - } - } - - template - void ED_HRTEM(TOutput_multislice &output_multislice) - { - EWFS_EWRS(output_multislice); - } - - template - void PED_HCTEM(TOutput_multislice &output_multislice) - { - ext_niter = input_multislice->nrot*input_multislice->number_conf(); - ext_iter = 0; - /*****************************************************************/ - - T_r w = input_multislice->get_phonon_rot_weight(); - - output_multislice.init(); - - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - for(auto irot = 0; irot < input_multislice->nrot; irot++) - { - input_multislice->set_phi(irot); - wave_function.set_incident_wave(wave_function.psi_z); - wave_function.psi(w, wave_function.psi_z, output_multislice); - - ext_iter++; - if(ext_stop_sim) break; - } - if(ext_stop_sim) break; - } - - wave_function.set_m2psi_coh(output_multislice); - } - - template - void EWFS_EWRS(TOutput_multislice &output_multislice) - { - ext_niter = input_multislice->number_conf(); - ext_iter = 0; - /*****************************************************************/ - - T_r w = input_multislice->get_phonon_rot_weight(); - - output_multislice.init(); - - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - - wave_function.set_incident_wave(wave_function.psi_z); - - wave_function.psi(w, wave_function.psi_z, output_multislice); - - ext_iter++; - if(ext_stop_sim) break; - } - - wave_function.set_m2psi_coh(output_multislice); - } - - template - void EELS_EFTEM(TOutput_multislice &output_multislice) - { - ext_niter = wave_function.slicing.slice.size()*input_multislice->number_conf(); - ext_iter = 0; - - if(input_multislice->is_EELS()) - { - ext_niter *= input_multislice->scanning.size(); - } - /*****************************************************************/ - - T_r w = input_multislice->get_phonon_rot_weight(); - - auto psi = [&](T_r w, Vector &psi_z, TOutput_multislice &output_multislice) - { - T_r gx_0 = input_multislice->gx_0(); - T_r gy_0 = input_multislice->gy_0(); - - for(auto islice = 0; islice < wave_function.slicing.slice.size(); islice++) - { - if(input_multislice->eels_fr.is_Mixed_Channelling()) - { - wave_function.trans(islice, wave_function.slicing.slice.size()-1, trans_thk); - } - - for(auto iatoms = wave_function.slicing.slice[islice].iatom_0; iatoms <= wave_function.slicing.slice[islice].iatom_e; iatoms++) - { - if(wave_function.atoms.Z[iatoms] == input_multislice->eels_fr.Z) - { - input_multislice->set_eels_fr_atom(iatoms, wave_function.atoms); - energy_loss.set_atom_type(input_multislice->eels_fr); - - for(auto ikn = 0; ikn < energy_loss.kernel.size(); ikn++) - { - mt::multiply(*stream, energy_loss.kernel[ikn], psi_z, wave_function.psi_z); - wave_function.psi(islice, wave_function.slicing.slice.size()-1, w, trans_thk, output_multislice); - } - } - - if(ext_stop_sim) break; - } - wave_function.psi_slice(gx_0, gy_0, islice, psi_z); - - ext_iter++; - if(ext_stop_sim) break; - } - }; - - output_multislice.init(); - - input_multislice->iscan.resize(1); - input_multislice->beam_x.resize(1); - input_multislice->beam_y.resize(1); - - if(input_multislice->is_EELS()) - { - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - for(auto iscan = 0; iscan < input_multislice->scanning.size(); iscan++) - { - input_multislice->iscan[0] = iscan; - input_multislice->set_iscan_beam_position(); - wave_function.set_incident_wave(psi_thk); - psi(w, psi_thk, output_multislice); - - if(ext_stop_sim) break; - } - - if(ext_stop_sim) break; - } - } - else - { - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - wave_function.set_incident_wave(psi_thk); - psi(w, psi_thk, output_multislice); - - if(ext_stop_sim) break; - } - } - } - - template - void EDX(TOutput_multislice &output_multislice) - { - ext_niter = wave_function.slicing.slice.size()*input_multislice->number_conf(); - ext_iter = 0; - - if(input_multislice->is_EELS()) - { - ext_niter *= input_multislice->scanning.size(); - } - /*****************************************************************/ - - T_r w = input_multislice->get_phonon_rot_weight(); - - auto psi = [&](T_r w, Vector &psi_z, TOutput_multislice &output_multislice) - { - T_r gx_0 = input_multislice->gx_0(); - T_r gy_0 = input_multislice->gy_0(); - - for(auto islice = 0; islice < wave_function.slicing.slice.size(); islice++) - { - if(input_multislice->eels_fr.is_Mixed_Channelling()) - { - wave_function.trans(islice, wave_function.slicing.slice.size()-1, trans_thk); - } - - for(auto iatoms = wave_function.slicing.slice[islice].iatom_0; iatoms <= wave_function.slicing.slice[islice].iatom_e; iatoms++) - { - if(wave_function.atoms.Z[iatoms] == input_multislice->eels_fr.Z) - { - input_multislice->set_eels_fr_atom(iatoms, wave_function.atoms); - energy_loss.set_atom_type(input_multislice->eels_fr); - - for(auto ikn = 0; ikn < energy_loss.kernel.size(); ikn++) - { - mt::multiply(*stream, energy_loss.kernel[ikn], psi_z, wave_function.psi_z); - wave_function.psi(islice, wave_function.slicing.slice.size()-1, w, trans_thk, output_multislice); - } - } - - if(ext_stop_sim) break; - } - wave_function.psi_slice(gx_0, gy_0, islice, psi_z); - - ext_iter++; - if(ext_stop_sim) break; - } - }; - - output_multislice.init(); - - input_multislice->iscan.resize(1); - input_multislice->beam_x.resize(1); - input_multislice->beam_y.resize(1); - - if(input_multislice->is_EELS()) - { - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - for(auto iscan = 0; iscan < input_multislice->scanning.size(); iscan++) - { - input_multislice->iscan[0] = iscan; - input_multislice->set_iscan_beam_position(); - wave_function.set_incident_wave(psi_thk); - psi(w, psi_thk, output_multislice); - - if(ext_stop_sim) break; - } - - if(ext_stop_sim) break; - } - } - else - { - for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) - { - wave_function.move_atoms(iconf); - wave_function.set_incident_wave(psi_thk); - psi(w, psi_thk, output_multislice); - - if(ext_stop_sim) break; - } - } - } - - Input_Multislice *input_multislice; - Stream *stream; - FFT *fft_2d; - - Wave_Function wave_function; - Energy_Loss energy_loss; - - Vector psi_thk; - Vector trans_thk; - }; - - template - bool Multislice::ext_stop_sim = false; - - template - int Multislice::ext_niter = 0; - - template - int Multislice::ext_iter = 0; -} // namespace mt - -#endif +/* + * This file is part of Multem. + * Copyright 2014 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TEM_SIMULATION_H + #define TEM_SIMULATION_H + + #include + #include "math_mt.h" + #include "types.cuh" + #include "type_traits_gen.h" + #include "in_classes.cuh" + #include "output_multem.hpp" + #include "fcns_cpu.h" + #include "fcns_gpu.h" + #include "fcns_gpu.h" + #include "energy_loss.cuh" + #include "wave_function.cuh" + #include "timing.cuh" + + namespace mt + { + template + class Tem_Simulation + { + public: + using T_r = T; + using T_c = complex; + + static const eDev device = Dev; + + static dt_bool ext_stop_sim; + static dt_int32 ext_niter; + static dt_int32 ext_iter; + + Tem_Simulation(): multem_in_parm(nullptr) {} + + Tem_Simulation(Multem_In_Parm *multem_in_parm_i) + { + set_in_data(multem_in_parm_i); + } + + void set_in_data(Multem_In_Parm *multem_in_parm_i) + { + multem_in_parm = multem_in_parm_i; + + stream.resize(multem_in_parm->system_config.n_stream); + + fft_2d.create_plan_2d(multem_in_parm->grid_2d.ny, multem_in_parm->grid_2d.nx, multem_in_parm->system_config.n_stream); + + if (multem_in_parm->is_EELS_EFTEM()) + { + energy_loss.set_in_data(multem_in_parm, &stream, &fft_2d); + psi_thk.resize(multem_in_parm->grid_2d.size()); + if (multem_in_parm->eels_fr.is_Mixed_Chan()) + { + trans_thk.resize(multem_in_parm->grid_2d.size()); + } + } + + wave_function.set_in_data(multem_in_parm, &stream, &fft_2d); + } + + template + void operator()(TOutput_multislice &output_multem) + { + if (multem_in_parm->is_STEM_ISTEM()) + { + STEM_ISTEM(output_multem); + } + else if (multem_in_parm->is_CBED_CBEI()) + { + CBED_CBEI(output_multem); + } + else if (multem_in_parm->is_ED_HRTEM()) + { + ED_HRTEM(output_multem); + } + else if (multem_in_parm->is_PED_HCTEM()) + { + PED_HCTEM(output_multem); + } + else if (multem_in_parm->is_EWFS_EWRS()) + { + EWFS_EWRS(output_multem); + } + else if (multem_in_parm->is_EELS_EFTEM()) + { + EELS_EFTEM(output_multem); + } + + stream.synchronize(); + + output_multem.gather(); + output_multem.clean_temporal(); + } + + void cleanup() + { + psi_thk.clear(); + trans_thk.clear(); + + fft_2d.cleanup(); + stream.cleanup(); + } + + private: + template + void STEM_ISTEM(TOutput_multislice &output_multem) + { + ext_niter = multem_in_parm->scanning.size()*multem_in_parm->number_pn_conf(); + ext_iter = 0; + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + output_multem.init(); + + multem_in_parm->ibeam.resize(1); + multem_in_parm->beam_x.resize(1); + multem_in_parm->beam_y.resize(1); + + + if (multem_in_parm->is_STEM() && multem_in_parm->atomic_vib.coh_contrib) + { + for(auto ibeam = 0; ibeam < multem_in_parm->scanning.size(); ibeam++) + { + output_multem.init_psi_coh(); + multem_in_parm->ibeam[0] = ibeam; + multem_in_parm->set_iscan_beam_position(); + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + wave_function.set_m2psi_coh(output_multem); + + if (ext_stop_sim) break; + } + } + else + { + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + for(auto ibeam = 0; ibeam < multem_in_parm->scanning.size(); ibeam++) + { + multem_in_parm->ibeam[0] = ibeam; + multem_in_parm->set_iscan_beam_position(); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + if (ext_stop_sim) break; + } + + wave_function.set_m2psi_coh(output_multem); + } + } + + template + void CBED_CBEI(TOutput_multislice &output_multem) + { + output_multem.init(); + + multem_in_parm->ibeam.resize(1); + multem_in_parm->beam_x.resize(1); + multem_in_parm->beam_y.resize(1); + + Quad_Coef_1d qt; + Quad_Coef_2d qs; + + // Load quadratures + cond_lens_temporal_spatial_quadratures(multem_in_parm->cond_lens, qt, qs); + + /***************************************************************************************/ + dt_float64 w_pr_0 = multem_in_parm->get_phonon_rot_weight(); + dt_float64 c_10_0 = multem_in_parm->cond_lens.c_10; + const dt_int32 n_beams = multem_in_parm->number_of_beams(); + + ext_niter = qs.size()*qt.size()*multem_in_parm->number_pn_conf(); + ext_iter = 0; + + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + + for(auto ibeam=0; ibeamibeam[0] = ibeam; + multem_in_parm->beam_x[0] = multem_in_parm->beam_x[ibeam]; + multem_in_parm->beam_y[0] = multem_in_parm->beam_y[ibeam]; + + // spatial incoherence + for(auto ispat = 0; ispatbeam_x[0]; + auto beam_y = qs.y[ispat] + multem_in_parm->beam_y[0]; + + // temporal incoherence + for(auto itemp = 0; itempcond_lens.set_defocus(c_10); + wave_function.set_incident_wave(wave_function.psi_z, beam_x, beam_y); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + } + } + + if (ext_stop_sim) break; + } + wave_function.set_m2psi_coh(output_multem); + + multem_in_parm->cond_lens.set_defocus(c_10_0); + multem_in_parm->set_beam_position(multem_in_parm->beam_x, multem_in_parm->beam_y); + } + + template + void ED_HRTEM(TOutput_multislice &output_multem) + { + EWFS_EWRS(output_multem); + } + + template + void PED_HCTEM(TOutput_multislice &output_multem) + { + ext_niter = multem_in_parm->nrot*multem_in_parm->number_pn_conf(); + ext_iter = 0; + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + output_multem.init(); + + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + for(auto irot = 0; irot < multem_in_parm->nrot; irot++) + { + multem_in_parm->set_phi(irot); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + if (ext_stop_sim) break; + } + + wave_function.set_m2psi_coh(output_multem); + } + + template + void EWFS_EWRS(TOutput_multislice &output_multem) + { + ext_niter = multem_in_parm->number_pn_conf(); + ext_iter = 0; + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + output_multem.init(); + + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + + wave_function.set_incident_wave(wave_function.psi_z); + + wave_function.psi(w, wave_function.psi_z, output_multem); + + ext_iter++; + if (ext_stop_sim) break; + } + + wave_function.set_m2psi_coh(output_multem); + } + + template + void EELS_EFTEM(TOutput_multislice &output_multem) + { + ext_niter = wave_function.slicing.slice.size()*multem_in_parm->number_pn_conf(); + ext_iter = 0; + + if (multem_in_parm->is_STEM_ISTEM_EELS()) + { + ext_niter *= multem_in_parm->scanning.size(); + } + /***************************************************************************************/ + + T_r w = multem_in_parm->get_phonon_rot_weight(); + + auto psi = [&](T_r w, Vctr& psi_z, TOutput_multislice &output_multem) + { + T_r gx_0 = multem_in_parm->gx_0(); + T_r gy_0 = multem_in_parm->gy_0(); + + for(auto islice = 0; islice < wave_function.slicing.slice.size(); islice++) + { + if (multem_in_parm->eels_fr.is_Mixed_Chan()) + { + wave_function.trans(islice, wave_function.slicing.slice.size()-1, trans_thk); + } + + for(auto iatoms = wave_function.slicing.slice[islice].iatom_0; iatoms <= wave_function.slicing.slice[islice].iatom_e; iatoms++) + { + if (wave_function.atoms.Z[iatoms] == multem_in_parm->eels_fr.Z) + { + multem_in_parm->set_eels_fr_atom(iatoms, wave_function.atoms); + energy_loss.set_atom_type(multem_in_parm->eels_fr); + + for(auto ikn = 0; ikn < energy_loss.kernel.size(); ikn++) + { + mt::ew_mult(stream, energy_loss.kernel[ikn], psi_z, wave_function.psi_z); + wave_function.psi(islice, wave_function.slicing.slice.size()-1, w, trans_thk, output_multem); + } + } + + if (ext_stop_sim) break; + } + wave_function.psi_slice(gx_0, gy_0, islice, psi_z); + + ext_iter++; + if (ext_stop_sim) break; + } + }; + + output_multem.init(); + + multem_in_parm->ibeam.resize(1); + multem_in_parm->beam_x.resize(1); + multem_in_parm->beam_y.resize(1); + + if (multem_in_parm->is_STEM_ISTEM_EELS()) + { + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + for(auto ibeam = 0; ibeam < multem_in_parm->scanning.size(); ibeam++) + { + multem_in_parm->ibeam[0] = ibeam; + multem_in_parm->set_iscan_beam_position(); + wave_function.set_incident_wave(psi_thk); + psi(w, psi_thk, output_multem); + + if (ext_stop_sim) break; + } + + if (ext_stop_sim) break; + } + } + else + { + for(auto iconf = multem_in_parm->atomic_vib.iconf_0; iconf <= multem_in_parm->atomic_vib.nconf; iconf++) + { + wave_function.move_atoms(iconf); + wave_function.set_incident_wave(psi_thk); + psi(w, psi_thk, output_multem); + + if (ext_stop_sim) break; + } + } + } + + Multem_In_Parm *multem_in_parm; + Stream stream; + FFT fft_2d; + + Wave_Function wave_function; + Energy_Loss energy_loss; + + Vctr psi_thk; + Vctr trans_thk; + }; + + template + dt_bool Tem_Simulation::ext_stop_sim = false; + + template + dt_int32 Tem_Simulation::ext_niter = 0; + + template + dt_int32 Tem_Simulation::ext_iter = 0; + + template + class Multem + { + public: + Multem(): n_devices(1), multem_in_parm(nullptr) {} + + Multem(Multem_In_Parm *multem_in_parm_i) + { + set_in_data(multem_in_parm_i); + } + + void set_in_data(Multem_In_Parm *multem_in_parm_i) + { + multem_in_parm = multem_in_parm_i; + n_devices = 1; + if (multem_in_parm->is_STEM_ISTEM()||multem_in_parm->is_CBED_CBEI()) + { + n_devices = multem_in_parm->system_config.get_n_sel_gpu(); + } + output_multem_v.resize(n_devices); + } + + template + void operator()(TOutput_Multem &output_multem) + { + if (multem_in_parm->is_STEM_ISTEM()) + { + STEM_ISTEM(output_multem); + } + else if (multem_in_parm->is_CBED_CBEI()) + { + CBED_CBEI(output_multem); + } + else if (multem_in_parm->is_ED_HRTEM()) + { + ED_HRTEM(output_multem); + } + else if (multem_in_parm->is_PED_HCTEM()) + { + PED_HCTEM(output_multem); + } + else if (multem_in_parm->is_EWFS_EWRS()) + { + EWFS_EWRS(output_multem); + } + else if (multem_in_parm->is_EELS_EFTEM()) + { + EELS_EFTEM(output_multem); + } + } + private: + template + void STEM_ISTEM(TOutput_Multem &output_multem) + { + vector threads; + threads.reserve(n_devices); + + auto stem_istem_thr =[&](dt_int32 ithr) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.scanning.type = espt_user_def; + multem_in_parm_thr.scanning.R = multem_in_parm->extract_beam_pos(ithr, n_devices); + multem_in_parm_thr.set_dep_var(); + + multem_in_parm_thr.system_config.set_gpu_by_ind(ithr); + + Tem_Simulation tem_simulation(&multem_in_parm_thr); + output_multem_v[ithr].set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem_v[ithr]); + tem_simulation.cleanup(); + }; + + for(auto ithr=0; ithr + void CBED_CBEI(TOutput_Multem &output_multem) + { + vector threads; + threads.reserve(n_devices); + + auto cbed_cbei_thr =[&](dt_int32 ithr) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.beam_x = multem_in_parm->extract_probe_pos_x(ithr, n_devices); + multem_in_parm_thr.beam_y = multem_in_parm->extract_probe_pos_y(ithr, n_devices); + multem_in_parm_thr.set_dep_var(); + + multem_in_parm_thr.system_config.set_gpu_by_ind(ithr); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem_v[ithr].set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem_v[ithr]); + tem_simulation.cleanup(); + }; + + for(auto ithr=0; ithr + void ED_HRTEM(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + template + void PED_HCTEM(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + template + void EWFS_EWRS(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + template + void EELS_EFTEM(TOutput_Multem &output_multem) + { + Multem_In_Parm multem_in_parm_thr = *multem_in_parm; + multem_in_parm_thr.system_config.set_gpu_by_ind(0); + + Tem_Simulation tem_simulation; + tem_simulation.set_in_data(&multem_in_parm_thr); + output_multem.set_in_data(&multem_in_parm_thr); + + tem_simulation(output_multem); + tem_simulation.cleanup(); + } + + dt_int32 n_devices; + Multem_In_Parm *multem_in_parm; + vector> output_multem_v; + }; + + } + +#endif diff --git a/src/timing.cuh b/src/timing.cuh old mode 100644 new mode 100755 index f92e0ce0..d46458c2 --- a/src/timing.cuh +++ b/src/timing.cuh @@ -1,121 +1,121 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef TIMING_H -#define TIMING_H - -#include "types.cuh" -#include - -#ifdef __CUDACC__ - #include - #include -#endif - -namespace mt -{ - template - struct Timing; - - template<> - struct Timing - { - public: - - Timing() - { - cudaEventCreate(&start); - cudaEventCreate(&stop); - } - - ~Timing() - { - free(); - } - - void tic() - { - cudaEventRecord(start); - } - - void toc() - { - cudaEventRecord(stop); - } - - float elapsed_ms() - { - //cudaDeviceSynchronize(); - cudaEventSynchronize(stop); - - float milliseconds = 0; - cudaEventElapsedTime(&milliseconds, start, stop); - - return milliseconds; - } - - float elapsed_s() - { - return elapsed_ms()/1000; - } - - private: - cudaEvent_t start; - cudaEvent_t stop; - - void free() - { - cudaEventDestroy(start); - cudaEventDestroy(stop); - } - }; - - - template<> - struct Timing - { - public: - void tic() - { - start = std::chrono::high_resolution_clock::now(); - } - - void toc() - { - stop = std::chrono::high_resolution_clock::now(); - } - - float elapsed_ms() - { - float milliseconds = std::chrono::duration_cast(stop-start).count()*1e-3; - - return milliseconds; - } - - float elapsed_s() - { - return elapsed_ms()/1000; - } - - private: - std::chrono::high_resolution_clock::time_point start; - std::chrono::high_resolution_clock::time_point stop; - }; -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TIMING_H +#define TIMING_H + +#include "types.cuh" +#include + +#ifdef __CUDACC__ + #include + #include +#endif + +namespace mt +{ + template + struct Timing; + + template <> + struct Timing + { + public: + + Timing() + { + cudaEventCreate(&start); + cudaEventCreate(&stop); + } + + ~Timing() + { + free(); + } + + void tic() + { + cudaEventRecord(start); + } + + void toc() + { + cudaEventRecord(stop); + } + + dt_float32 elapsed_ms() + { + // cudaDeviceSynchronize(); + cudaEventSynchronize(stop); + + dt_float32 milliseconds = 0; + cudaEventElapsedTime(&milliseconds, start, stop); + + return milliseconds; + } + + dt_float32 elapsed_s() + { + return elapsed_ms()/1000; + } + + private: + cudaEvent_t start; + cudaEvent_t stop; + + void free() + { + cudaEventDestroy(start); + cudaEventDestroy(stop); + } + }; + + + template <> + struct Timing + { + public: + void tic() + { + start = std::chrono::high_resolution_clock::now(); + } + + void toc() + { + stop = std::chrono::high_resolution_clock::now(); + } + + dt_float32 elapsed_ms() + { + dt_float32 milliseconds = std::chrono::duration_cast(stop-start).count()*1e-3; + + return milliseconds; + } + + dt_float32 elapsed_s() + { + return elapsed_ms()/1000; + } + + private: + std::chrono::high_resolution_clock::time_point start; + std::chrono::high_resolution_clock::time_point stop; + }; +} + #endif \ No newline at end of file diff --git a/src/tomography.cuh b/src/tomography.cuh deleted file mode 100644 index e00eb32a..00000000 --- a/src/tomography.cuh +++ /dev/null @@ -1,393 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef TOMOGRAPHY_H -#define TOMOGRAPHY_H - -#include -#include - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "lin_alg_def.cuh" -#include "stream.cuh" -#include "atomic_data.hpp" -#include "input_tomography.cuh" -#include "output_tomography.hpp" -#include "box_occ.hpp" -#include "cubic_spline.hpp" - -namespace mt -{ - template - class Tomography - { - public: - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - Tomography(): input_tomography(nullptr), rand_trial(0), chi2_0(0), Temp_max(0), - Temp_min(0), rTemp(0), chi2(0), chi2_n(0), chi2_opt(0){} - - void set_input_data(Input_Tomography *input_tomography_i) - { - input_tomography = input_tomography_i; - atoms.assign(input_tomography->atoms); - box.set_input_data(input_tomography->r0_min, input_tomography->grid_2d.lx, input_tomography->grid_2d.ly, input_tomography->grid_2d.lx); - - image.resize(input_tomography->image.size()); - assign_input_image(); - - chi2_0 = 0; - T IA_exp = 0; - for(auto irot = 0; irot< image.size(); irot++) - { - chi2_0 += mt::sum_square(input_tomography->grid_2d, image[irot]); - IA_exp += mt::sum(input_tomography->grid_2d, image[irot]); - } - IA_exp = IA_exp*input_tomography->grid_2d.dRx*input_tomography->grid_2d.dRy/(atoms.size()*image.size()); - - T IA_sim = 0; - for(auto ir = 0; irr.size(); ir++) - { - T &r = input_tomography->r[ir]; - T &fr = input_tomography->fr[ir]; - IA_sim += r*fr; - } - IA_sim = IA_sim*(input_tomography->r[1]-input_tomography->r[0]); - - T IA_factor = IA_exp/(c_2Pi*IA_sim); - - for(auto ir = 0; irr.size(); ir++) - { - T &fr = input_tomography->fr[ir]; - fr = fr*IA_factor; - } - - /***************************************************************************/ - Atomic_Data atomic_data; - atomic_data.Load_Data(ePT_Lobato_0_12); - - atom_type_host.resize(c_nAtomsTypes); - atom_type.resize(c_nAtomsTypes); - mt::Cubic_Spline spline; - for(auto i = 0; igrid_2d.dR_min(), atom_type_host[i]); - if(input_tomography->Z == Z) - { - mt::assign(input_tomography->r, atom_type_host[i].R); - mt::square(input_tomography->r, atom_type_host[i].R2); - spline.set_points(atom_type_host[i].R2, input_tomography->fr); - spline.get_coeff(atom_type_host[i].ciVR); - atom_type_host[i].R_min = 0; - atom_type_host[i].R2_min = pow(atom_type_host[i].R_min, 2); - atom_type_host[i].R_max = atom_type_host[i].R.back(); - atom_type_host[i].R2_max = pow(atom_type_host[i].R_max, 2); - } - atom_type[i].assign(atom_type_host[i]); - } - - /***************************************************************************/ - stream.resize(input_tomography->nstream); - - int nv = max(input_tomography->grid_2d.nx_dRx(2*input_tomography->grid_2d.lx), input_tomography->grid_2d.ny_dRy(2*input_tomography->grid_2d.ly)); - stream_data.resize(stream.size()); - for(auto i = 0; i - void run(Output_Tomography &output_tomography) - { - init_point(); - - // T Temp = Temp_max; - // while (Temp>Temp_min) - // { - // for(auto itemp = 0; itemp rand.temp()) - // { - // p = p + 1; - // chi2 = chi2_n; - // atoms.r = atoms.r_n; - // set_atom_range(); - // } - // } - - // for(int iatoms = 0; iatoms, e_host> iv; - Vector, e_host> v; - }; - - void set_atom_Ip(int Z_i, const r3d &r_i, Stream &stream, Vector, e_host> &atom_Ip) - { - for(auto istream = 0; istream < stream.n_act_stream; istream++) - { - int iZ = Z_i-1; - atom_Ip[istream].x = r_i.x; - atom_Ip[istream].y = r_i.y; - atom_Ip[istream].R2_max = atom_type[iZ].R2_max; - atom_Ip[istream].R2 = raw_pointer_cast(atom_type[iZ].R2.data()); - atom_Ip[istream].set_ix0_ixn(input_tomography->grid_2d, atom_type[iZ].R_max); - atom_Ip[istream].set_iy0_iyn(input_tomography->grid_2d, atom_type[iZ].R_max); - atom_Ip[istream].c0 = raw_pointer_cast(atom_type[iZ].ciVR.c0.data()); - atom_Ip[istream].c1 = raw_pointer_cast(atom_type[iZ].ciVR.c1.data()); - atom_Ip[istream].c2 = raw_pointer_cast(atom_type[iZ].ciVR.c2.data()); - atom_Ip[istream].c3 = raw_pointer_cast(atom_type[iZ].ciVR.c3.data()); - atom_Ip[istream].iv = raw_pointer_cast(stream_data.iv[istream].data()); - atom_Ip[istream].v = raw_pointer_cast(stream_data.v[istream].data()); - - } - } - - void set_atom_range(const r3d &r_i, const T &df, const r3d &r_min, const r3d &r_max, r3d &r_0, r3d &r_d) - { - r3d dr = (r_max-r_min)*df; - r_0 = fmax(r_min, r_i-dr); - r_d = fmin(r_max, r_i+dr)-r_0; - } - - r3d move_atom(const r3d &r_0, const r3d &r_d) - { - for(auto itrial = 0; itrial < rand_trial; itrial++) - { - auto r = r_0+r_d*rand(); - if(box.check_r_min(atoms, r)) - { - return r; - } - } - return r_0; - } - - T atom_cost_function(const r3d &r_i) - { - stream.set_n_act_stream(1); - T chi2 = 0; - for(auto irot = 0; irotangle.size(); irot++) - { - auto Rm = get_rotation_matrix(input_tomography->angle[irot], input_tomography->spec_rot_u0); - auto r = r_i.rotate(Rm, input_tomography->spec_rot_center_p); - set_atom_Ip(input_tomography->Z, r, stream, atom_Ip); - chi2 += mt::atom_cost_function(input_tomography->grid_2d, atom_Ip[0], image[irot]); - } - return chi2; - } - - void subtract_atom_in_all_rot(const r3d &r_i) - { - stream.set_n_act_stream(1); - for(auto irot = 0; irotangle.size(); irot++) - { - auto Rm = get_rotation_matrix(input_tomography->angle[irot], input_tomography->spec_rot_u0); - auto r = r_i.rotate(Rm, input_tomography->spec_rot_center_p); - set_atom_Ip(input_tomography->Z, r, stream, atom_Ip); - mt::subtract_atom(stream, input_tomography->grid_2d, atom_Ip, image[irot]); - } - } - - void set_atoms_range() - { - for(int iatoms = 0; iatomsangle.size(); irot++) - { - auto Rm = get_rotation_matrix(input_tomography->angle[irot], input_tomography->spec_rot_u0); - for(int iatoms = 0; iatomsspec_rot_center_p); - // r = r.rotate(Rm, input_tomography->spec_rot_center_p); - set_atom_Ip(input_tomography->Z, r, stream, atom_Ip); - mt::subtract_atom(stream, input_tomography->grid_2d, atom_Ip, image[irot]); - } - chi2 += mt::sum_square(input_tomography->grid_2d, image[irot]); - } - return chi2; - } - - void assign_input_image() - { - for(auto irot = 0; irot< image.size(); irot++) - { - mt::assign(input_tomography->image[irot], image[irot]); - } - } - - inline T range_factor(const T &p) - { - T m = 2.0; - T p1 = 0.6; - T p2 = 0.4; - - if(p>p1) - { - return 1.0 + m*(p-p1)/p2; - } - else if(p *input_tomography; - - Stream stream; - - Box_Occ box; - Rand_3d rand; - int rand_trial; - T chi2_0; - - T Temp_max; - T Temp_min; - T rTemp; - - T chi2; - T chi2_n; - T chi2_opt; - - Atom_Data_Sa atoms; - Vector, e_host> image; - Vector, e_host> atom_Ip; - Stream_Data stream_data; - - Vector, e_host> atom_type_host; // Atom types - Vector, e_host> atom_type; // Atom types - }; - -} // namespace mt -#endif \ No newline at end of file diff --git a/src/traits.cuh b/src/traits.cuh deleted file mode 100644 index 04b04234..00000000 --- a/src/traits.cuh +++ /dev/null @@ -1,332 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef TRAITS_H -#define TRAITS_H - -#include -#include "math.cuh" -#include "types.cuh" - -namespace mt -{ - template - struct is_bool: std::integral_constant::value> {}; - - template - struct is_int: std::integral_constant::value || std::is_same::value> {}; - - template - struct is_float: std::integral_constant::value> {}; - - template - struct is_double: std::integral_constant::value> {}; - - template - struct is_real: std::integral_constant::value || is_double::value> {}; - - template - struct is_cfloat: std::integral_constant>::value> {}; - - template - struct is_cdouble: std::integral_constant>::value> {}; - - template - struct is_complex: std::integral_constant::value || is_cdouble::value> {}; - - template - struct is_fundamental: std::integral_constant::value || is_complex::value> {}; - - template - struct is_enum_bool: std::integral_constant::value || is_bool::value> {}; - - namespace detail_traits - { - template - struct check_type - { - typedef void type; - }; - - template - struct has_value_type - { - static const bool value = false; - }; - - template - struct has_value_type::type> - { - static const bool value = true; - }; - - template - struct get_value_type_r - { - using type = typename TVector::value_type; - }; - - template - struct get_value_type_r::value>::type> - { - using type = typename TVector::value_type::value_type; - }; - - template - struct has_device_member: std::integral_constant {}; - - template - struct has_device_member::value>::type> - { - struct Fallback { int device; }; - struct Derived: T, Fallback {}; - - template struct ChT; - - template static char (&f(ChT*))[1]; - template static char (&f(...))[2]; - - static const bool value = sizeof(f(0)) == 2; - }; - } - - /**************************Output data type**************************/ - template - using Data_Type = typename std::conditional, complex>::type>::type >::type; - - - template - using Value_type = typename TVector::value_type; - - template - using Value_type_r = typename detail_traits::get_value_type_r::type; - - template - using Size_type = typename TVector::size_type; - - template - struct is_host_vector: std::integral_constant {}; - - template - struct is_host_vector::value>::type>: std::integral_constant>>::value || std::is_same>>::value> {}; - - template - struct is_device_vector: std::integral_constant {}; - - template - struct is_device_vector::value>::type>: std::integral_constant>>::value> {}; - - template - struct is_complex_host_vector: std::integral_constant::value && is_complex::value> {}; - - template - struct is_complex_device_vector: std::integral_constant::value && is_complex::value> {}; - - template - struct is_host_device_vector: std::integral_constant::value || is_device_vector::value> {}; - - template - struct is_Vector: std::integral_constant::value):((dev == e_host)?is_host_vector::value:is_device_vector::value)> {}; - - template - struct is_host_device: std::integral_constant::value> {}; - - template - struct is_host_device::value>::type>: std::integral_constant {}; - - template - struct is_host: std::integral_constant::value> {}; - - template - struct is_device: std::integral_constant::value> {}; - - template - struct is_dev_host: std::integral_constant {}; - - template - struct is_dev_device: std::integral_constant {}; - - template - struct is_host_vector_and_host_vector: std::integral_constant::value && is_host_vector::value> {}; - - template - struct is_host_vector_and_device_vector: std::integral_constant::value && is_device_vector::value> {}; - - template - struct is_device_vector_and_host_vector: std::integral_constant::value && is_host_vector::value> {}; - - template - struct is_device_vector_and_device_vector: std::integral_constant::value && is_device_vector::value> {}; - - template - struct is_complex_host_vector_and_host_vector: std::integral_constant::value && is_host_vector::value> {}; - - template - struct is_complex_device_vector_and_device_vector: std::integral_constant::value && is_device_vector::value> {}; - - template - struct is_complex_vector_and_real_vector: std::integral_constant::value && is_real::value> {}; - - template - using enable_if_real_host_vector = typename std::enable_if::value && is_real::value, U>::type; - - template - using enable_if_complex_host_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_host_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_real_device_vector = typename std::enable_if::value && is_real::value, U>::type; - - template - using enable_if_complex_device_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_device_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_host_vector_and_device_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_device_vector_and_host_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_host_vector_and_host_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_device_vector_and_device_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_complex_host_vector_and_host_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_complex_device_vector_and_device_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_complex_vector_and_real_vector = typename std::enable_if::value, U>::type; - - template - using enable_if_host = typename std::enable_if::value, U>::type; - - template - using enable_if_device = typename std::enable_if::value, U>::type; - - template - using enable_if_dev_host = typename std::enable_if::value, U>::type; - - template - using enable_if_dev_device = typename std::enable_if::value, U>::type; - - template - using enable_if_float = typename std::enable_if::value, U>::type; - - template - using enable_if_double = typename std::enable_if::value, U>::type; - - template - using enable_if_real = typename std::enable_if::value, U>::type; - - template - using enable_if_cfloat = typename std::enable_if::value, U>::type; - - template - using enable_if_cdouble = typename std::enable_if::value, U>::type; - - template - using enable_if_complex = typename std::enable_if::value, U>::type; - - template - using enable_if_int = typename std::enable_if::value, U>::type; - - template - using enable_if_bool = typename std::enable_if::value, U>::type; - - template - using enable_if_floating_point = typename std::enable_if::value, U>::type; - - template - using enable_if_enum_bool = typename std::enable_if::value, U>::type; - - template - using enable_if_pointer = typename std::enable_if::value, U>::type; - - template - using enable_if_STEM = typename std::enable_if::type; - - template - using enable_if_ISTEM = typename std::enable_if::type; - - template - using enable_if_CBED = typename std::enable_if::type; - - template - using enable_if_CBEI = typename std::enable_if::type; - - template - using enable_if_ED = typename std::enable_if::type; - - template - using enable_if_HRTEM = typename std::enable_if::type; - - template - using enable_if_PED = typename std::enable_if::type; - - template - using enable_if_HCTEM = typename std::enable_if::type; - - template - using enable_if_EWFS = typename std::enable_if::type; - - template - using enable_if_EWRS = typename std::enable_if::type; - - template - using enable_if_EELS = typename std::enable_if::type; - - template - using enable_if_EFTEM = typename std::enable_if::type; - - template - using enable_if_ProbeFS = typename std::enable_if::type; - - template - using enable_if_ProbeRS = typename std::enable_if::type; - - - /*********************************type***********************************/ - template - enable_if_float, int> - matrix_type(TVector &vector){ return 1; } - - template - enable_if_double, int> - matrix_type(TVector &vector){ return 2; } - - template - enable_if_cfloat, int> - matrix_type(TVector &vector){ return 3; } - - template - enable_if_cdouble, int> - matrix_type(TVector &vector){ return 4; } - -} // namespace mt - -#endif diff --git a/src/transmission_function.cuh b/src/transmission_function.cuh deleted file mode 100644 index 389e3e88..00000000 --- a/src/transmission_function.cuh +++ /dev/null @@ -1,228 +0,0 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef TRANSMISSION_FUNCTION_H -#define TRANSMISSION_FUNCTION_H - -#include "math.cuh" -#include "types.cuh" -#include "traits.cuh" -#include "stream.cuh" -#include "quadrature.hpp" -#include "memory_info.cuh" -#include "input_multislice.cuh" -#include "output_multislice.hpp" -#include "projected_potential.cuh" - -namespace mt -{ - template - class Transmission_Function: public Projected_Potential - { - public: - using T_r = T; - using T_c = complex; - using size_type = std::size_t; - - Transmission_Function(): Projected_Potential(), fft_2d(nullptr){} - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i, FFT *fft2_i) - { - Projected_Potential::set_input_data(input_multislice_i, stream_i); - fft_2d = fft2_i; - - trans_0.resize(this->input_multislice->grid_2d.nxy()); - - if(!this->input_multislice->slice_storage) - { - memory_slice.clear(); - return; - } - - int n_slice_sig = (this->input_multislice->pn_dim.z)?(int)ceil(3.0*this->atoms.sigma_max/this->input_multislice->grid_2d.dz):0; - int n_slice_req = this->slicing.slice.size() + 2*n_slice_sig; - - memory_slice.set_input_data(n_slice_req, this->input_multislice->grid_2d.nxy()); - - if(memory_slice.is_potential()) - { - memory_slice.resize_vector(this->input_multislice->grid_2d.nxy(), Vp_v); - } - else if(memory_slice.is_transmission()) - { - memory_slice.resize_vector(this->input_multislice->grid_2d.nxy(), trans_v); - } - } - - void trans(T_r w, Vector &V0_i, Vector &Trans_o) - { - mt::transmission_function(*(this->stream), this->input_multislice->grid_2d, this->input_multislice->interaction_model, w, V0_i, Trans_o); - - if(this->input_multislice->grid_2d.bwl) - { - fft_2d->forward(Trans_o); - mt::bandwidth_limit(*(this->stream), this->input_multislice->grid_2d, Trans_o); - fft_2d->inverse(Trans_o); - } - } - - void trans(const int &islice, Vector &trans_0) - { - if(islice < memory_slice.n_slice_cur(this->slicing.slice.size())) - { - if(memory_slice.is_potential()) - { - trans(this->input_multislice->Vr_factor(), Vp_v[islice], trans_0); - } - else if(memory_slice.is_transmission()) - { - mt::assign(trans_v[islice], trans_0); - } - } - else - { - Projected_Potential::operator()(islice, this->V_0); - //this->operator()(islice, this->V_0); - trans(this->input_multislice->Vr_factor(), this->V_0, trans_0); - } - } - - void trans(const int &islice_0, const int &islice_e, Vector &trans_0) - { - Projected_Potential::operator()(islice_0, islice_e, this->V_0); - //this->operator()(islice_0, islice_e, this->V_0); - trans(this->input_multislice->Vr_factor(), this->V_0, trans_0); - } - - template - void trans(const int &islice, TOutput_multislice &output_multislice) - { - trans(islice, trans_0); - mt::copy_to_host(output_multislice.stream, trans_0, output_multislice.trans[0]); - } - - void move_atoms(const int &fp_iconf) - { - Projected_Potential::move_atoms(fp_iconf); - - // Calculate transmission functions - for(auto islice = 0; islice< memory_slice.n_slice_cur(this->slicing.slice.size()); islice++) - { - if(memory_slice.is_potential()) - { - Projected_Potential::operator()(islice, Vp_v[islice]); - } - else if(memory_slice.is_transmission()) - { - Projected_Potential::operator()(islice, this->V_0); - trans(this->input_multislice->Vr_factor(), this->V_0, trans_v[islice]); - } - } - } - - void transmit(const int &islice, Vector &psi_io) - { - trans(islice, trans_0); - mt::multiply(*(this->stream), trans_0, psi_io); - } - - Vector trans_0; - private: - struct Memory_Slice - { - public: - int n_slice_req; - int n_slice_Allow; - eSlice_Memory_Type slice_mem_type; - - Memory_Slice(): n_slice_req(0), n_slice_Allow(0), slice_mem_type(eSMT_none){} - - void clear() - { - n_slice_req = n_slice_Allow = 0; - slice_mem_type = eSMT_none; - } - - void set_input_data(const int &nSlice_req_i, const int &nxy_i) - { - n_slice_req = nSlice_req_i; - double free_memory = get_free_memory() - 10; - - if(number_slices(free_memory, nxy_i) >= n_slice_req) - { - slice_mem_type = eSMT_Transmission; - n_slice_Allow = number_slices(free_memory, nxy_i); - } - else - { - slice_mem_type = eSMT_Potential; - n_slice_Allow = number_slices(free_memory, nxy_i); - } - n_slice_Allow = min(n_slice_Allow, n_slice_req); - - if(n_slice_Allow == 0 ) - { - slice_mem_type = eSMT_none; - } - } - - template - void resize_vector(const int &nxy_i, U &vector) - { - vector.resize(n_slice_Allow); - for(auto i = 0; i < n_slice_Allow; i++) - { - vector[i].resize(nxy_i); - } - } - - int n_slice_cur(const int &n_slice_i) - { - return min(n_slice_Allow, n_slice_i); - } - - bool is_transmission() const - { - return slice_mem_type == eSMT_Transmission; - } - - bool is_potential() const - { - return slice_mem_type == eSMT_Potential; - } - - private: - template - int number_slices(const double &memory, const int &nxy) - { - return static_cast(floor(memory/mt::sizeMb(nxy))); - } - }; - - Memory_Slice memory_slice; - - protected: - Vector, e_host> trans_v; - Vector, e_host> Vp_v; - - FFT *fft_2d; - }; - -} // namespace mt - -#endif \ No newline at end of file diff --git a/src/type_traits_gen.h b/src/type_traits_gen.h new file mode 100755 index 00000000..982a36b7 --- /dev/null +++ b/src/type_traits_gen.h @@ -0,0 +1,882 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include + +#include "macros.h" +#include "const_enum.h" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +/* same decay */ +namespace mt +{ + template + struct is_same_decay: std::integral_constant::type, typename std::decay::type>::value> {}; + + template + struct is_diff_decay: std::integral_constant::value> {}; +} + +/* enable if */ +namespace mt +{ + template + using enable_if_same_decay = typename std::enable_if::value, V>::type; + + template + using enable_if_diff_decay = typename std::enable_if::value, V>::type; +} + +/* enum types - verification */ +namespace mt +{ + dt_bool is_ebool(const eData_Typ& ed_typ) + { + return edt_bool == ed_typ; + } + + dt_bool is_eint8(const eData_Typ& ed_typ) + { + return edt_int8 == ed_typ; + } + + dt_bool is_euint8(const eData_Typ& ed_typ) + { + return edt_uint8 == ed_typ; + } + + dt_bool is_eint16(const eData_Typ& ed_typ) + { + return edt_int16 == ed_typ; + } + + dt_bool is_euint16(const eData_Typ& ed_typ) + { + return edt_uint16 == ed_typ; + } + + dt_bool is_eint32(const eData_Typ& ed_typ) + { + return edt_int32 == ed_typ; + } + + dt_bool is_euint32(const eData_Typ& ed_typ) + { + return edt_uint32 == ed_typ; + } + + dt_bool is_eint64(const eData_Typ& ed_typ) + { + return edt_int64 == ed_typ; + } + + dt_bool is_euint64(const eData_Typ& ed_typ) + { + return edt_uint64 == ed_typ; + } + + dt_bool is_efloat32(const eData_Typ& ed_typ) + { + return edt_float32 == ed_typ; + } + + dt_bool is_efloat64(const eData_Typ& ed_typ) + { + return edt_float64 == ed_typ; + } + + dt_bool is_ecint8(const eData_Typ& ed_typ) + { + return edt_cint8 == ed_typ; + } + + dt_bool is_ecuint8(const eData_Typ& ed_typ) + { + return edt_cuint8 == ed_typ; + } + + dt_bool is_ecint16(const eData_Typ& ed_typ) + { + return edt_cint16 == ed_typ; + } + + dt_bool is_ecuint16(const eData_Typ& ed_typ) + { + return edt_cuint16 == ed_typ; + } + + dt_bool is_ecint32(const eData_Typ& ed_typ) + { + return edt_cint32 == ed_typ; + } + + dt_bool is_ecuint32(const eData_Typ& ed_typ) + { + return edt_cuint32 == ed_typ; + } + + dt_bool is_ecint64(const eData_Typ& ed_typ) + { + return edt_cint64 == ed_typ; + } + + dt_bool is_ecuint64(const eData_Typ& ed_typ) + { + return edt_cuint64 == ed_typ; + } + + dt_bool is_ecfloat32(const eData_Typ& ed_typ) + { + return edt_cfloat32 == ed_typ; + } + + dt_bool is_ecfloat64(const eData_Typ& ed_typ) + { + return edt_cfloat64 == ed_typ; + } +} + +/* real types - verification */ +namespace mt +{ + template + struct is_bool : std::integral_constant::value> {}; + + template + struct is_enum : std::integral_constant::type>::value> {}; + + template + struct is_enum_bool: std::integral_constant::value || is_bool::value> {}; + + template + struct is_int8 : std::integral_constant::value> {}; + + template + struct is_uint8 : std::integral_constant::value> {}; + + template + struct is_int16 : std::integral_constant::value> {}; + + template + struct is_uint16 : std::integral_constant::value> {}; + + template + struct is_int32 : std::integral_constant::value> {}; + + template + struct is_uint32 : std::integral_constant::value> {}; + + template + struct is_int64 : std::integral_constant::value> {}; + + template + struct is_uint64 : std::integral_constant::value> {}; + + template + struct is_float32 : std::integral_constant::value> {}; + + template + struct is_float64 : std::integral_constant::value> {}; + + template + struct is_int: std::integral_constant::value || is_uint8::value \ + || is_int16::value || is_uint16::value || is_int32::value || is_uint32::value \ + || is_int64::value || is_uint64::value> {}; + + template + struct is_float : std::integral_constant::value || is_float64::value> {}; + + template + struct is_real : std::integral_constant::value || is_int8::value \ + || is_uint8::value || is_int16::value || is_uint16::value || is_int32::value \ + || is_uint32::value || is_int64::value || is_uint64::value || is_float::value> {}; +} + +/* std complex types - verification */ +namespace mt +{ + template ::type> + struct is_std_cint8 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint8 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cint16 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint16 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cint32 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint32 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cint64 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cuint64 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cfloat32 : std::integral_constant::value> {}; + + template ::type> + struct is_std_cfloat64 : std::integral_constant::value> {}; + + template + struct is_std_cfloat : std::integral_constant::value || is_std_cfloat64::value> {}; + + template + struct is_std_cmplx : std::integral_constant::value \ + || is_std_cuint8::value || is_std_cint16::value || is_std_cuint16::value || is_std_cint32::value \ + || is_std_cuint32::value || is_std_cint64::value || is_std_cuint64::value || is_std_cfloat::value> {}; +} + +/* thrust types - verification */ +namespace mt +{ +#ifdef __CUDACC__ + template + struct is_thr_cint8: std::integral_constant::value> {}; + + template + struct is_thr_cuint8: std::integral_constant::value> {}; + + template + struct is_thr_cint16: std::integral_constant::value> {}; + + template + struct is_thr_cuint16: std::integral_constant::value> {}; + + template + struct is_thr_cint32: std::integral_constant::value> {}; + + template + struct is_thr_cuint32: std::integral_constant::value> {}; + + template + struct is_thr_cint64: std::integral_constant::value> {}; + + template + struct is_thr_cuint64: std::integral_constant::value> {}; + + template + struct is_thr_cfloat32: std::integral_constant::value> {}; + + template + struct is_thr_cfloat64: std::integral_constant::value> {}; + + template + struct is_thr_cfloat: std::integral_constant::value || is_thr_cfloat64::value> {}; + + template + struct is_thr_cmplx: std::integral_constant::value \ + || is_thr_cuint8::value || is_thr_cint16::value || is_thr_cuint16::value || is_thr_cint32::value \ + || is_thr_cuint32::value || is_thr_cint64::value || is_thr_cuint64::value || is_thr_cfloat::value> {}; +#endif +} + +/* complex types - verification */ +namespace mt +{ +#ifdef __CUDACC__ + template + struct is_cint8: std::integral_constant::value || is_thr_cint8::value> {}; + + template + struct is_cuint8: std::integral_constant::value || is_thr_cuint8::value> {}; + + template + struct is_cint16: std::integral_constant::value || is_thr_cint16::value> {}; + + template + struct is_cuint16: std::integral_constant::value || is_thr_cuint16::value> {}; + + template + struct is_cint32: std::integral_constant::value || is_thr_cint32::value> {}; + + template + struct is_cuint32: std::integral_constant::value || is_thr_cuint32::value> {}; + + template + struct is_cint64: std::integral_constant::value || is_thr_cint64::value> {}; + + template + struct is_cuint64: std::integral_constant::value || is_thr_cuint64::value> {}; + + template + struct is_cfloat32: std::integral_constant::value || is_thr_cfloat32::value> {}; + + template + struct is_cfloat64: std::integral_constant::value || is_thr_cfloat64::value> {}; + + template + struct is_cmplx: std::integral_constant::value || is_thr_cmplx::value> {}; +#else + template + struct is_cint8: std::integral_constant::value> {}; + + template + struct is_cuint8: std::integral_constant::value> {}; + + template + struct is_cint16: std::integral_constant::value> {}; + + template + struct is_cuint16: std::integral_constant::value> {}; + + template + struct is_cint32: std::integral_constant::value> {}; + + template + struct is_cuint32: std::integral_constant::value> {}; + + template + struct is_cint64: std::integral_constant::value> {}; + + template + struct is_cuint64: std::integral_constant::value> {}; + + template + struct is_cfloat32: std::integral_constant::value> {}; + + template + struct is_cfloat64: std::integral_constant::value> {}; + + template + struct is_cmplx: std::integral_constant::value> {}; +#endif + + template + struct is_cfloat: std::integral_constant::value || is_cfloat64::value> {}; + + template + struct is_number: std::integral_constant::value || is_cmplx::value> {}; +} + +/* real types - enable */ +namespace mt +{ + template + using enable_if_bool = typename std::enable_if::value, U>::type; + + template + using enable_if_enum = typename std::enable_if::value, U>::type; + + template + using enable_if_enum_bool = typename std::enable_if::value, U>::type; + + template + using enable_if_int8 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_int16 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_int32 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_int64 = typename std::enable_if::value, U>::type; + + template + using enable_if_uint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_float32 = typename std::enable_if::value, U>::type; + + template + using enable_if_float64 = typename std::enable_if::value, U>::type; + + template + using enable_if_int = typename std::enable_if::value, U>::type; + + template + using enable_if_float = typename std::enable_if::value, U>::type; + + template + using enable_if_float_float = typename std::enable_if::value && is_float::value, V>::type; + + template + using enable_if_real = typename std::enable_if::value, U>::type; + + template + using enable_if_real_real = typename std::enable_if::value && is_real::value, V>::type; +} + +/* std complex types - enable */ +namespace mt +{ + template + using enable_if_std_cint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cuint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cfloat32 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cfloat64 = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cfloat = typename std::enable_if::value, U>::type; + + template + using enable_if_std_cmplx = typename std::enable_if::value, U>::type; +} + +/* thrust complex types - enable */ +namespace mt +{ +#ifdef __CUDACC__ + template + using enable_if_thr_cint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cuint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cfloat32 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cfloat64 = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cfloat = typename std::enable_if::value, U>::type; + + template + using enable_if_thr_cmplx = typename std::enable_if::value, U>::type; +#endif +} + +/* complex types - enable */ +namespace mt +{ + template + using enable_if_cint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint8 = typename std::enable_if::value, U>::type; + + template + using enable_if_cint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint16 = typename std::enable_if::value, U>::type; + + template + using enable_if_cint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint32 = typename std::enable_if::value, U>::type; + + template + using enable_if_cint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_cuint64 = typename std::enable_if::value, U>::type; + + template + using enable_if_cfloat32 = typename std::enable_if::value, U>::type; + + template + using enable_if_cfloat64 = typename std::enable_if::value, U>::type; + + template + using enable_if_cfloat = typename std::enable_if::value, U>::type; + + template + using enable_if_cmplx = typename std::enable_if::value, U>::type; + + template + using enable_if_cmplx_cmplx = typename std::enable_if::value && is_cmplx::value, V>::type; + + template + using enable_if_number = typename std::enable_if::value, U>::type; + + template + using enable_if_number_number = typename std::enable_if::value && is_number::value, V>::type; +} + +/* eDev/eDim - verification */ +namespace mt +{ + dt_bool is_edev_cpu(const eDev& edev) + { + return edev_cpu == edev; + } + + dt_bool is_edev_gpu(const eDev& edev) + { + return edev_gpu == edev; + } + + dt_bool is_edim_1(const eDim& edim) + { + return edim_1 == edim; + } + + dt_bool is_edim_2(const eDim& edim) + { + return edim_2 == edim; + } + + dt_bool is_edim_3(const eDim& edim) + { + return edim_3 == edim; + } +} + +/* ptr/eDev/eDim - enable */ +namespace mt +{ + template + using enable_if_ptr = typename std::enable_if::value, U>::type; + + template + using enable_if_edev_cpu = typename std::enable_if::type; + + template + using enable_if_edev_gpu = typename std::enable_if::type; + + template + using enable_if_edim_1 = typename std::enable_if::type; + + template + using enable_if_edim_2 = typename std::enable_if::type; + + template + using enable_if_edim_3 = typename std::enable_if::type; +} + +/* types conversion */ +namespace mt +{ + template + using chg_btw_int32_int64 = typename std::conditional::value, dt_int64, dt_int32>::type; + + // ! change to complementary floating point type: this include complex number +#ifdef __CUDACC__ + template + using chg_2_compl_float_type = typename std::conditional::value, dt_float64, \ + typename std::conditional::value, dt_float32, \ + typename std::conditional::value, std::complex, \ + typename std::conditional::value, std::complex, \ + typename std::conditional::value, thrust::complex, thrust::complex>::type>::type>::type>::type>::type; +#else + template + using chg_2_compl_float_type = typename std::conditional::value, dt_float64, \ + typename std::conditional::value, dt_float32, \ + typename std::conditional::value, std::complex, std::complex>::type>::type>::type; +#endif + + // ! large type sel + template + using sel_lg_type = typename std::conditional::value && is_float32::value, dt_float32, \ + typename std::conditional::value && is_float32::value, dt_float64, \ + typename std::conditional::value && is_float64::value, dt_float64, \ + typename std::conditional::value && is_int::value, T, \ + typename std::conditional::value && is_float::value, U, dt_float64>::type>::type>::type>::type>::type; /* types - enable */ +} + +/* detail_traits */ +namespace mt +{ + namespace detail_traits + { + template + struct check_type + { + typedef void type; + }; + + /************************************ value type****************************************/ + template + struct sValue_type + { + using type = T; + }; + + template + struct sValue_type::type> + { + using type = typename T::value_type; + }; + + template + struct sValue_type_r + { + using type = typename sValue_type::type; + }; + + template + struct sValue_type_r::type> + { + using type = typename T::value_type::value_type; + }; + + /************************************* size type ***************************************/ + template + struct sSize_type + { + using type = T; + }; + + template + struct sSize_type::type> + { + using type = typename T::size_type; + }; + + template + struct sSize_type_r + { + using type = typename sSize_type::type; + }; + + template + struct sSize_type_r::type> + { + using type = typename T::value_type::size_type; + }; + } +} + +/* vector value type - extraction */ +namespace mt +{ + template + using Value_type = typename detail_traits::sValue_type::type; + + template + using Value_type_r = typename detail_traits::sValue_type_r::type; +} + +/* vector size type - extraction */ +namespace mt +{ + template + using Size_type = typename detail_traits::sSize_type::type; + + template + using Size_type_r = typename detail_traits::sSize_type_r::type; +} + +/* vector type - verification */ +namespace mt +{ + template + struct is_vctr_cpu: std::integral_constant {}; + + template + struct is_vctr_gpu: std::integral_constant {}; + + template + struct is_vctr: std::integral_constant::value || is_vctr_gpu::value> {}; + + template + struct is_vctr_and_vctr: std::integral_constant::value || is_vctr::value> {}; + + /***************************************************************************************/ + template + struct is_rvctr_cpu: std::integral_constant::value && is_real::value> {}; + + template + struct is_vctr_rgpu: std::integral_constant::value && is_real::value> {}; + + template + struct is_rvctr: std::integral_constant::value || is_vctr_rgpu::value> {}; + + /***************************************************************************************/ + template + struct is_cvctr_cpu: std::integral_constant::value && is_cmplx::value> {}; + + template + struct is_cvctr_gpu: std::integral_constant::value && is_cmplx::value> {}; + + template + struct is_cvctr: std::integral_constant::value || is_cvctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_vctr_cpu_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_vctr_cpu_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + template + struct is_vctr_gpu_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_vctr_gpu_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + /***************************************************************************************/ + template + struct is_cvctr_cpu_and_vctr_cpu: std::integral_constant::value && is_vctr_cpu::value> {}; + + template + struct is_cvctr_cpu_and_rvctr_cpu: std::integral_constant::value && is_rvctr_cpu::value> {}; + + template + struct is_cvctr_gpu_and_vctr_gpu: std::integral_constant::value && is_vctr_gpu::value> {}; + + template + struct is_cvctr_gpu_and_vctr_rgpu: std::integral_constant::value && is_vctr_rgpu::value> {}; + + template + struct is_cvctr_and_rvctr: std::integral_constant::value && is_rvctr::value> {}; +} + +/* vector type - enable */ +namespace mt +{ + template + using enable_if_vctr_cpu = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_gpu = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_and_vctr = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_rvctr_cpu = typename std::enable_if::value, U>::type; + + template + using enable_if_vctr_rgpu = typename std::enable_if::value, U>::type; + + template + using enable_if_rvctr = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + template + using enable_if_cvctr_cpu = typename std::enable_if::value, U>::type; + + template + using enable_if_cvctr_gpu = typename std::enable_if::value, U>::type; + + template + using enable_if_cvctr = typename std::enable_if::value, U>::type; + + /***************************************************************************************/ + template + using enable_if_vctr_cpu_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_cpu_and_vctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_gpu_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_vctr_gpu_and_vctr_gpu = typename std::enable_if::value, V>::type; + + /***************************************************************************************/ + template + using enable_if_cvctr_cpu_and_vctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_cpu_and_rvctr_cpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_gpu_and_vctr_gpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_gpu_and_vctr_rgpu = typename std::enable_if::value, V>::type; + + template + using enable_if_cvctr_and_rvctr = typename std::enable_if::value, V>::type; +} + +/* matrxi type - enable */ +namespace mt +{ + template + enable_if_float32, dt_int32> + matrix_type(TVctr& vector){ return 1; } + + template + enable_if_float64, dt_int32> + matrix_type(TVctr& vector){ return 2; } + + template + enable_if_cfloat32, dt_int32> + matrix_type(TVctr& vector){ return 3; } + + template + enable_if_cfloat64, dt_int32> + matrix_type(TVctr& vector){ return 4; } +} \ No newline at end of file diff --git a/src/type_traits_mt.cuh b/src/type_traits_mt.cuh new file mode 100755 index 00000000..82c0aa5a --- /dev/null +++ b/src/type_traits_mt.cuh @@ -0,0 +1,100 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TYPE_TRAITS_MT_H + #define TYPE_TRAITS_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + + #include "const_enum_mt.cuh" + #include "type_traits_gen.h" + + namespace mt + { + /***************************************************************************************/ + template + using enable_if_eappt_doyle_0_4 = typename std::enable_if::type; + + template + using enable_if_eappt_peng_0_4 = typename std::enable_if::type; + + template + using enable_if_eappt_peng_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_kirkland_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_weickenmeier_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_lobato_0_12 = typename std::enable_if::type; + + template + using enable_if_eappt_peng_ion_0_4 = typename std::enable_if::type; + + /****************************** types ********************************/ + template + using enable_if_STEM = typename std::enable_if::type; + + template + using enable_if_ISTEM = typename std::enable_if::type; + + template + using enable_if_CBED = typename std::enable_if::type; + + template + using enable_if_CBEI = typename std::enable_if::type; + + template + using enable_if_ED = typename std::enable_if::type; + + template + using enable_if_HRTEM = typename std::enable_if::type; + + template + using enable_if_PED = typename std::enable_if::type; + + template + using enable_if_HCTEM = typename std::enable_if::type; + + template + using enable_if_EWFS = typename std::enable_if::type; + + template + using enable_if_EWRS = typename std::enable_if::type; + + template + using enable_if_EELS = typename std::enable_if::type; + + template + using enable_if_EFTEM = typename std::enable_if::type; + + template + using enable_if_ProbeFS = typename std::enable_if::type; + + template + using enable_if_ProbeRS = typename std::enable_if::type; + + } + +#endif diff --git a/src/types.cuh b/src/types.cuh old mode 100644 new mode 100755 index 02b659c9..8dc051c4 --- a/src/types.cuh +++ b/src/types.cuh @@ -1,5126 +1,453 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef TYPES_H -#define TYPES_H - -#ifndef DEVICE_CALLABLE - #ifdef __CUDACC__ - #define DEVICE_CALLABLE __host__ __device__ - #define FORCE_INLINE __forceinline__ - #else - #define DEVICE_CALLABLE - #define FORCE_INLINE inline - #endif -#endif - -//#ifdef __CUDACC__ -// #pragma message("Cuda TYPES_H") -//#else -// #pragma message("nonCuda TYPES_H") -//#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "math.cuh" -#include "lin_alg_def.cuh" - -#include -#include -#include -#include -#include - -using std::vector; -using thrust::device_vector; -using thrust::host_vector; -using thrust::raw_pointer_cast; - -namespace mt -{ - const double c_Ha = 27.2113850656389; // Hartree to electron-Volt - const double c_a0 = 0.52917721077817892; // Bohr radius - const double c_Potf = 47.877645145863056; // - const double c_2Pi2a0 = 10.445539456905012; // 2*pi^2*a0 - - const double c_H = 6.62606876e-34; // Planck's constant - J s - const double c_bH = 1.054571596e-34; // h/(2*pi) - J s - const double c_C = 2.99792458e+8; // Velocity of light - m s^-1 - const double c_Qe = 1.602176462e-19; // Elementary charge - const double c_me = 9.10938291e-31; // Electron rest mass [kg] - const double c_mp = 1.672621637e-27; // Proton rest mass [kg] - const double c_KB = 1.3806504e-23; // Boltzmann's constant - J K^-1 - const double c_Na = 6.0221415e+23; // Avogadro's Number - mol^-1 - - const double c_E = 2.7182818284590452354; // e (base of natural log) - - const double c_Pi = 3.141592653589793238463; // pi - const double c_iPi = 0.3183098861837906715378; // 1.0/pi - const double c_i2Pi = 1.570796326794896619231; // pi/2 - const double c_i3Pi = 1.047197551196597746154; // pi/3 - const double c_i4Pi = 0.7853981633974483096157; // pi/4 - const double c_2Pi = 6.283185307179586476925; // 2*pi - const double c_3Pi = 9.424777960769379715388; // 3*pi - const double c_4Pi = 12.56637061435917295385; // 4*pi - const double c_Pi2 = 9.869604401089358618834; // pi^2 - const double c_Pi3 = 31.00627668029982017548; // pi^3 - const double c_Pi4 = 97.4090910340024372364; // pi^4 - const double c_Pii2 = 1.772453850905516027298; // pi^(1/2) - const double c_Pii3 = 1.46459188756152326302; // pi^(1/3) - const double c_Pii4 = 1.331335363800389712798; // pi^(1/4) - - const double c_2i2 = 1.414213562373095048802; // 2^(1/2) - const double c_3i2 = 1.732050807568877293527; // 3^(1/2) - const double c_5i2 = 2.236067977499789696409; // 5^(1/2) - const double c_7i2 = 2.645751311064590590502; // 7^(1/2) - - const double c_hwhm_2_sigma = 0.84932180028801907; // hwhm to sigma 1/(sqrt(2*log(2))) - const double c_fwhm_2_sigma = 0.42466090014400953; // fwhm to sigma 1/(2*sqrt(2*log(2))) - const double c_iehwgd_2_sigma = 0.70710678118654746; // iehwgd to sigma 1/sqrt(2) - - const double c_mrad_2_rad = 1.0e-03; // mrad-->rad - const double c_deg_2_rad = 0.01745329251994329576924; // degrees-->rad - const double c_mm_2_Angs = 1.0e+07; // mm-->Angstrom - const double c_eV_2_keV = 1e-03; // ev-->keV - - const int c_cSynCPU = 5; - - const int c_nAtomsTypes = 103; - const int c_nAtomsIons = 15; - const int c_nqz = 128; - const int c_nR = 128; - - const int c_thrnxny = 16; - const int c_thrnxy = 256; - const double c_Vrl = 0.015; - - const int cSizeofI = sizeof(int); - const int cSizeofRD = sizeof(double); - const int cSizeofRF = sizeof(float); - const int cSizeofCD = 2*cSizeofRD; - - /******************************modify vector******************************/ - enum eInput_Atoms - { - eIA_yes = 1, eIA_no = 2 - }; - - /******************************modify vector******************************/ - enum eModify_Vector - { - eMV_yes = 1, eMV_no = 2 - }; - - /******************************e_device type******************************/ - enum eDevice - { - e_host = 1, e_device = 2, e_host_device = 3 - }; - - /******************************Slice memory type******************************/ - enum eSlice_Memory_Type - { - eSMT_Transmission = 1, eSMT_Potential = 2, eSMT_none = 3 - }; - - /******************************Microscope effects*****************************/ - enum eIllumination_Model - { - eIM_Coherent = 1, eIM_Partial_Coherent = 2, eIM_Trans_Cross_Coef = 3, eIM_Full_Integration = 4, eIM_none = 5 - }; - - /******************************Spatial and temporal***************************/ - enum eTemporal_Spatial_Incoh - { - eTSI_Temporal_Spatial = 1, eTSI_Temporal = 2, eTSI_Spatial = 3, eTSI_none = 4 - }; - - /********************************MULTEM type**********************************/ - enum ePrecision - { - eP_float = 1, eP_double = 2 - }; - - /*************************************data type******************************/ - enum eData_Type - { - eDT_float = 1, eDT_double = 2, eDT_cfloat = 3, eDT_cdouble = 4 - }; - - /*****************************Show Data Type**********************************/ - enum eShow_CData - { - eSCD_CReal = 1, eSCD_CImag = 2, eSCD_CMod = 3, eSCD_CPhase = 4 - }; - - /*********************************Operation mode******************************/ - enum eOperation_Mode - { - eOM_Normal = 1, eOM_Advanced = 2 - }; - - /****************************lens variable type******************************/ - enum eLens_Var_Type - { - eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, - eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, - eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 - }; - - /*****************************simulation type********************************/ - enum eTEM_Sim_Type - { - eTEMST_STEM = 11, eTEMST_ISTEM = 12, - eTEMST_CBED = 21, eTEMST_CBEI = 22, - eTEMST_ED = 31, eTEMST_HRTEM = 32, - eTEMST_PED = 41, eTEMST_HCTEM = 42, - eTEMST_EWFS = 51, eTEMST_EWRS = 52, - eTEMST_EELS = 61, eTEMST_EFTEM = 62, - eTEMST_IWFS = 71, eTEMST_IWRS = 72, - eTEMST_PPFS = 81, eTEMST_PPRS = 82, // projected potential - eTEMST_TFFS = 91, eTEMST_TFRS = 92, // transmission function - eTEMST_PropFS = 101, eTEMST_PropRS = 102 // propagate - }; - - /*************************simulation data output*****************************/ - enum eTEM_Output_Type - { - eTEMOT_image_tot_coh = 1, eTEMOT_image_tot = 2, - eTEMOT_m2psi_tot_coh = 3, eTEMOT_m2psi_tot = 4, - eTEMOT_m2psi_tot_psi_coh = 5, eTEMOT_psi_coh = 6, - eTEMOT_psi_0 = 7, eTEMOT_V = 8, eTEMOT_trans = 9 - }; - - /******************Electron specimen interaction model**********************/ - enum eElec_Spec_Int_Model - { - eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 - }; - - /*****************************Frozen lattice model**************************/ - enum ePhonon_Model - { - ePM_Still_Atom = 1, ePM_Absorptive_Model = 2, ePM_Frozen_Phonon = 3 - }; - - /*******************************Extract data********************************/ - enum ePhonon_Model_Output - { - eFMO_Total = 1, eFMO_Coherent = 2 - }; - - /*********************Projected_Potential Slicing Type**********************/ - enum ePotential_Slicing - { - ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - }; - - /********************Projected_Potential parameterization******************/ - enum ePotential_Type - { - ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, - ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6, ePT_none = 0 - }; - - /***************************Incident Wave Type******************************/ - enum eIncident_Wave_Type - { - eIWT_Plane_Wave = 1, eIWT_Convergent_Wave = 2, eIWT_User_Define_Wave = 3, eIWT_Auto = 4 - }; - - enum eRot_Point_Type - { - eRPT_geometric_center = 1, eRPT_User_Define = 2 - }; - - /*****************************Real or Fourier space**************************/ - enum eSpace - { - eS_Real = 1, eS_Reciprocal = 2 - }; - - /****************************Defocus plane type*****************************/ - enum eMatch_Border - { - eMB_Min = 1, eMB_Max = 2, eMB_MinMax = 3 - }; - - /****************************Amorphous layer Type***************************/ - enum eAmorp_Lay_Type - { - eALT_Top = 1, eALT_Bottom = 2, eALT_Middle= 3, eALT_none = 4 - }; - - /****************************Defocus plane type*****************************/ - enum eZero_Defocus_Type - { - eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 - }; - - /*******************************thick Type*********************************/ - enum eThick_Type - { - eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 - }; - - /******************************Scanning Type*******************************/ - enum eScanning_Type - { - eST_Line = 1, eST_Area = 2 - }; - /******************************grid_2d Type*******************************/ - enum eGrid_Type - { - eGT_Regular = 1, eGT_Quadratic = 2 - }; - - /******************************Detector type*******************************/ - enum eDetector_Type - { - eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 - }; - - /********************************Channelling type*************************/ - enum eChannelling_Type - { - eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 - }; - - /*******************************Output type*******************************/ - enum eOutput_Type - { - eOT_Matlab = 1, eOT_Vector = 2 - }; - - /****************************Data selection type**************************/ - enum eDat_Sel_Type - { - eDST_Closest = 1, eDST_Less_Than = 2, eDST_Greater_Than = 3 - }; - - /**************************structuring element****************************/ - enum eStr_Ele - { - eSE_Disk = 1, eSE_Square = 2 - }; - - /******************************operation**********************************/ - enum eOP { - eOP_N=1, eOP_T=2, eOP_C=3 - }; - - /********************************Exec type********************************/ - enum eET { - eET_Matrix=1, eET_Vector=2 - }; - - template - void get_bn(const T &R, const int &nR, const T &dR, const T &R_max, const bool &pbc, int &iR0, int &iRn); - - template - struct r2d; - - template - X norm(const r2d& r); - - template - struct r3d; - - template - X norm(const r3d& r); - - namespace host_device_detail - { - template - DEVICE_CALLABLE FORCE_INLINE - T tapering(const T &x_tap, const T &alpha, const T &x); - - template - DEVICE_CALLABLE FORCE_INLINE - void kh_sum(T &sum_v, T v, T &error); - } - - template - class Atom_Data; - - /*********************************Epsilon***********************************/ - template - DEVICE_CALLABLE FORCE_INLINE - T epsilon_eps(){ return 0; } - - template<> - DEVICE_CALLABLE FORCE_INLINE - double epsilon_eps(){ return 10.0*DBL_EPSILON; } - - template<> - DEVICE_CALLABLE FORCE_INLINE - float epsilon_eps(){ return 10.0*FLT_EPSILON; } - - template - DEVICE_CALLABLE FORCE_INLINE - T epsilon_abs(){ return 0; } - - template<> - DEVICE_CALLABLE FORCE_INLINE - double epsilon_abs(){ return 1e-13; } - - template<> - DEVICE_CALLABLE FORCE_INLINE - float epsilon_abs(){ return 1e-5f; } - - template - DEVICE_CALLABLE FORCE_INLINE - T epsilon_rel(){ return 0; } - - template<> - DEVICE_CALLABLE FORCE_INLINE - double epsilon_rel(){ return 1e-8; } - - template<> - DEVICE_CALLABLE FORCE_INLINE - float epsilon_rel(){ return 1e-4f; } - - template - struct Epsilon - { - static const T eps; - static const T abs; - static const T rel; - }; - - template - const T Epsilon::eps = 0; - - template - const T Epsilon::abs = 0; - - template - const T Epsilon::rel = 0; - - template <> - const double Epsilon::eps = 10.0*DBL_EPSILON; - - template <> - const double Epsilon::abs = 1e-13; - - template <> - const double Epsilon::rel = 1e-8; - - template <> - const float Epsilon::eps = 10.0*FLT_EPSILON; - - template <> - const float Epsilon::abs = 1e-5f; - - template <> - const float Epsilon::rel = 1e-4f; - - struct Grid_BT - { - dim3 Blk; // Blocks - dim3 Thr; // Threads - - }; - - /*******************forward declarations********************/ - template - struct is_fundamental; - - template - DEVICE_CALLABLE FORCE_INLINE - T get_lambda(const T &E_0); - - template - DEVICE_CALLABLE FORCE_INLINE - T get_sigma(const T &E_0); - - template - DEVICE_CALLABLE FORCE_INLINE - T get_gamma(const T &E_0); - - /************************vector type***********************/ - //template - //eData_Type Vector_Type_to_Data_Type() - //{ - // if(is_float) - // { - // return eDT_float; - // } - // else if(is_double) - // { - // return eDT_double; - // } - // else if(is_cfloat) - // { - // return eDT_cfloat; - // } - // else(is_cdouble) - // { - // return eDT_cdouble; - // } - //} - - /**************************vector**************************/ - template - using Vector = typename std::conditional::value || - std::is_same>::value || std::is_same>::value, host_vector, vector>::type, device_vector>::type; - - template - struct rVector - { - public: - using value_type = T; - using size_type = std::size_t; - - int m_size; - T *V; - - rVector(): m_size(0), V(nullptr){} - - size_type size() const - { - return m_size; - } - - rVector(const rVector &vector) - { - m_size = vector.m_size; - V = vector.V; - } - - rVector(Vector &vector) - { - m_size = vector.size(); - V = raw_pointer_cast(vector.data()); - } - - rVector(Vector &vector) - { - m_size = vector.size(); - V = raw_pointer_cast(vector.data()); - } - - //rVector(host_vector &vector) - //{ - // m_size = vector.size(); - // V = raw_pointer_cast(vector.data()); - //} - - //rVector(device_vector &vector) - //{ - // m_size = vector.size(); - // V = raw_pointer_cast(vector.data()); - //} - DEVICE_CALLABLE FORCE_INLINE - T& operator[](const int i){ return V[i]; } - - DEVICE_CALLABLE FORCE_INLINE - const T& operator[](const int i) const { return V[i]; } - }; - - template - DEVICE_CALLABLE FORCE_INLINE - double sizeMb(const int &n) - { - return static_cast(n*sizeof(T)/1048576.0); - } - - // static member function are not supported for the cuda compiler - template - DEVICE_CALLABLE FORCE_INLINE - bool isEqual(const T &a, const T &b); - - template <> - DEVICE_CALLABLE FORCE_INLINE - bool isEqual(const int &a, const int &b) - { - return a == b; - } - - template <> - DEVICE_CALLABLE FORCE_INLINE - bool isEqual(const float &a, const float &b) - { - const float eps_abs = 1e-5f; - const float eps_rel = 1e-4f; - - // Check if the numbers are really close -- needed when comparing numbers near zero. - float diff = fabs(a - b); - if (diff <= eps_abs) - return true; - - // Otherwise fall back to Knuth's algorithm - return diff <= ((fabs(a) - DEVICE_CALLABLE FORCE_INLINE - bool isEqual(const double &a, const double &b) - { - const double eps_abs = 1e-13; - const double eps_rel = 1e-8; - - // Check if the numbers are really close -- needed when comparing numbers near zero. - double diff = fabs(a - b); - if (diff <= eps_abs) - return true; - - // Otherwise fall back to Knuth's algorithm - return diff <= ((fabs(a) - DEVICE_CALLABLE FORCE_INLINE - bool isZero(const T &x) - { - return isEqual(x, 0); - } - - template - DEVICE_CALLABLE FORCE_INLINE - bool isZero(const T &x, const U &y) - { - return isEqual(x, 0) && isEqual(y, 0); - } - - template - DEVICE_CALLABLE FORCE_INLINE - bool isZero(const r2d &r) - { - return isZero(r.x, r.y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - bool nonZero(const T &x) - { - return !isEqual(x, 0); - } - - template - DEVICE_CALLABLE FORCE_INLINE - bool nonZero(const T &x, const U &y) - { - return !(isEqual(x, 0) || isEqual(y, 0)); - } - - template - DEVICE_CALLABLE FORCE_INLINE - bool nonZero(const r2d &r) - { - return nonZero(r.x, r.y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T Div(const T &x, const U &y) - { - return (isEqual(y, 0))?0:static_cast(x)/static_cast(y); - } - - template - DEVICE_CALLABLE FORCE_INLINE - bool Check_Bound(const T &x, const T &x_min, const T &x_max) - { - return (x_min <= x) && (x <= x_max); - } - - template - DEVICE_CALLABLE FORCE_INLINE - bool Check_Bound(const T &x, const T &x_min, const T &x_max, const U &y, const U &y_min, const U &y_max) - { - return (x_min <= x) && (x <= x_max) && (y_min <= y) && (y <= y_max); - } - - - /******************************Ranges************************************/ - struct Range_1d - { - int ix_0; // initial index - int ix_e; // final index - int ixy_0; // initial index - int ixy_e; // final index - Range_1d(): ix_0(0), ix_e(0), ixy_0(0), ixy_e(0){} - - Range_1d(int ix_0i, int ix_ei): ix_0(ix_0i), ix_e(ix_ei) - { - ixy_0 = 0; - ixy_e = nx(); - } - - template - Range_1d(const TGrid &grid_1d){ set_grid(grid_1d); } - - void clear() - { - ix_0 = 0; - ix_e = 0; - ixy_0 = 0; - ixy_e = 0; - } - - int nx() const { return (ix_e-ix_0);} - - void clip_ix(int ix_0i, int ix_ei) - { - ix_0 = min(ix_ei, max(ix_0i, ix_0)); - ix_e = min(ix_ei, max(ix_0i, ix_e)); - } - - void set_ascending_index() - { - if(ix_0>ix_e) - { - std::swap(ix_0, ix_e); - } - } - - template - void set_grid(const TGrid &grid_1d) - { - ix_0 = 0; - ix_e = grid_1d.nx; - ixy_0 = 0; - ixy_e = grid_1d.nx; - } - }; - - struct Range_2d - { - int ix_0; // initial index - int ix_e; // final index - int iy_0; // initial index - int iy_e; // final index - int ixy_0; // initial index - int ixy_e; // final index - Range_2d(): ix_0(0), ix_e(0), - iy_0(0), iy_e(0), ixy_0(0), ixy_e(0){} - - Range_2d(int ix_0i, int ix_ei, int iy_0i, int iy_ei): ix_0(ix_0i), ix_e(ix_ei), - iy_0(iy_0i), iy_e(iy_ei) - { - ixy_0 = 0; - ixy_e = nxy(); - } - - template - Range_2d(const TGrid &grid_2d){ set_grid(grid_2d); } - - void clear() - { - ix_0 = 0; - ix_e = 0; - iy_0 = 0; - iy_e = 0; - ixy_0 = 0; - ixy_e = 0; - } - - template - void set_grid(const TGrid &grid_2d) - { - ix_0 = 0; - ix_e = grid_2d.nx; - iy_0 = 0; - iy_e = grid_2d.ny; - ixy_0 = 0; - ixy_e = grid_2d.nxy(); - } - - DEVICE_CALLABLE FORCE_INLINE - int nx() const { return (ix_e-ix_0);} - - DEVICE_CALLABLE FORCE_INLINE - int ny() const { return (iy_e-iy_0);} - - DEVICE_CALLABLE FORCE_INLINE - int nxy() const { return (nx()*ny());} - - DEVICE_CALLABLE FORCE_INLINE - void clip_ix(int ix_0i, int ix_ei) - { - ix_0 = min(ix_ei, max(ix_0i, ix_0)); - ix_e = min(ix_ei, max(ix_0i, ix_e)); - } - - DEVICE_CALLABLE FORCE_INLINE - void clip_iy(int iy_0i, int iy_ei) - { - iy_0 = min(iy_ei, max(iy_0i, iy_0)); - iy_e = min(iy_ei, max(iy_0i, iy_e)); - } - - DEVICE_CALLABLE FORCE_INLINE - void set_ascending_index() - { - if(ix_0>ix_e) - { - std::swap(ix_0, ix_e); - } - - if(iy_0>iy_e) - { - std::swap(iy_0, iy_e); - } - } - - DEVICE_CALLABLE FORCE_INLINE - bool chk_ix_bound(const int &ix) const - { - return (ix_0<=ix) && (ix - struct Border_1d - { - T lx; - - T xb_0; - T xb_e; - - Border_1d(T lxi=T(), T xb_0i=T(), T xb_ei=T()): lx(lxi), xb_0(xb_0i), xb_e(xb_ei){} - - template - Border_1d(T lxi, int nptr, X *ptr): lx(lxi) - { - if(nptr>0) - { - xb_0 = ptr[0]; - xb_e = (nptr>1)?ptr[1]:0; - } - else - { - xb_0 = 0; - xb_e = 0; - } - } - - Border_1d(T lxi, T dx): lx(lxi) - { - set_bd(dx); - } - - template - Border_1d& operator=(Border_1d &border_1d) - { - lx = border_1d.lx; - xb_0 = border_1d.xb_0; - xb_e = border_1d.xb_e; - return *this; - } - - inline - void set_bd(const T &dx) - { - xb_0 = max(xb_0, max(dx, T(0))); - xb_e = max(xb_e, max(-dx, T(0))); - } - - T lx_wb() const - { - return ::fmax(x_e()-x_0(), T(0)); - } - - T x_c() const - { - return 0.5*(x_e()+x_0()); - } - - T x_0() const - { - return xb_0; - } - - T x_e() const - { - return lx-xb_e; - } - - T xb_max() const - { - return max(xb_0, xb_e); - } - - T xb_min() const - { - return min(xb_0, xb_e); - } - - // percentaje of the total length - T radius_ptl(T p) const - { - return (1-0.5*p)*lx_wb()/2; - } - - bool chk_bound(const T &x) const - { - return (x_0()<=x) && (x<=x_e()); - } - - void shift(T dx) - { - xb_0 = ::fmax(xb_0+dx, T(0)); - xb_e = ::fmax(xb_e-dx, T(0)); - } - - void clear() - { - xb_0 = xb_e = 0; - } - }; - - template - struct Border_2d - { - T lx; - T ly; - - T xb_0; - T xb_e; - T yb_0; - T yb_e; - - Border_2d(T lxi=T(), T lyi=T(), T xb_0i=T(), T xb_ei=T(), - T yb_0i=T(), T yb_ei=T()): lx(lxi), ly(lyi), - xb_0(xb_0i), xb_e(xb_ei), yb_0(yb_0i), yb_e(yb_ei){} - - template - Border_2d(T lxi, T lyi, int nptr, X *ptr, bool b_swap = false): lx(lxi), ly(lyi) - { - if(nptr>0) - { - xb_0 = ptr[0]; - xb_e = (nptr>1)?ptr[1]:0; - yb_0 = (nptr>2)?ptr[2]:0; - yb_e = (nptr>3)?ptr[3]:0; - } - else - { - xb_0 = 0; - xb_e = 0; - yb_0 = 0; - yb_e = 0; - } - - if(b_swap) - { - thrust::swap(xb_0, yb_0); - thrust::swap(xb_e, yb_e); - } - } - - Border_2d(T lxi, T lyi, r2d rd): lx(lxi), ly(lyi) - { - set_bd(rd); - } - - template - Border_2d& operator=(Border_2d &border_2d) - { - lx = border_2d.lx; - ly = border_2d.ly; - xb_0 = border_2d.xb_0; - xb_e = border_2d.xb_e; - yb_0 = border_2d.yb_0; - yb_e = border_2d.yb_e; - return *this; - } - - inline - void set_bd(const r2d &rd) - { - xb_0 = max(xb_0, max(rd.x, T(0))); - xb_e = max(xb_e, max(-rd.x, T(0))); - - yb_0 = max(yb_0, max(rd.y, T(0))); - yb_e = max(yb_e, max(-rd.y, T(0))); - } - - T lx_wb() const - { - return ::fmax(x_e()-x_0(), T(0)); - } - - T ly_wb() const - { - return ::fmax(y_e()-y_0(), T(0)); - } - - T x_c() const - { - return 0.5*(x_e()+x_0()); - } - - T y_c() const - { - return 0.5*(y_e()+y_0()); - } - - T x_0() const - { - return xb_0; - } - - T y_0() const - { - return yb_0; - } - - T x_e() const - { - return lx-xb_e; - } - - T y_e() const - { - return ly-yb_e; - } - - T xb_max() const - { - return max(xb_0, xb_e); - } - - T xb_min() const - { - return min(xb_0, xb_e); - } - - T yb_max() const - { - return max(yb_0, yb_e); - } - - T yb_min() const - { - return min(yb_0, yb_e); - } - - // percentaje of the total length - T radius_ptl(T p) const - { - return (1-0.5*p)*::fmin(lx_wb(), ly_wb())/2; - } - - bool chk_x_bound(const T &x) const - { - return (x_0()<=x) && (x<=x_e()); - } - - bool chk_y_bound(const T &y) const - { - return (y_0()<=y) && (y<=y_e()); - } - - bool chk_bound(const T &x, const T &y) const - { - return chk_x_bound(x)&&chk_y_bound(y); - } - - void shift(r2d dr) - { - xb_0 = ::fmax(xb_0+dr.x, T(0)); - xb_e = ::fmax(xb_e-dr.x, T(0)); - - yb_0 = ::fmax(yb_0+dr.y, T(0)); - yb_e = ::fmax(yb_e-dr.y, T(0)); - } - - void clear() - { - xb_0 = xb_e = yb_0 = yb_e = 0; - } - }; - - /************************Amorphous layer information*************************/ - template - struct Amorp_Lay_Info - { - Amorp_Lay_Info(): z_0(0), z_e(0), dz(2), region(0), type(eALT_none) {}; - - T z_0; // Initial z-position - T z_e; // Final z-position - T dz; // Slice thickness - int region; // Region - eAmorp_Lay_Type type; // amorphous layer type - - template - Amorp_Lay_Info& operator=(TAmorp_Lay_Info &amorp_lay_info) - { - z_0 = amorp_lay_info.z_0; - z_e = amorp_lay_info.z_e; - dz = amorp_lay_info.dz; - region = amorp_lay_info.region; - type = amorp_lay_info.type; - return *this; - } - - T lz() const { return fabs(z_e-z_0); } - bool is_at_top() const { return type==eALT_Top; }; - bool is_at_bottom() const { return type==eALT_Bottom; }; - bool is_at_middle() const { return type==eALT_Middle; }; - - void set_region(Atom_Data &atoms) - { - if(lz()<1e-4) - { - region = 0; - return; - } - - int f_region = 0; - int c_region = 0; - for(auto iatoms = 0; iatoms < atoms.size(); iatoms++) - { - auto z = atoms.z[iatoms]; - if((z_0(round(T(f_region)/T(c_region))); - } - }; - - /*************************slice thickness*****************/ - template - struct Slice - { - Slice(): z_0(0), z_e(0), z_int_0(0), - z_int_e(0), iatom_0(1), iatom_e(0), ithk(-1){} - - T z_0; // Initial z-position - T z_e; // Final z-position - T z_int_0; // Initial z-position - T z_int_e; // Final z-position - int iatom_0; // Index to initial z-position - int iatom_e; // Index to final z-position - int ithk; // thick index - - T dz() const { return fabs(z_e-z_0); } - - T z_m() const { return 0.5*(z_e+z_0); } - }; - - /************************Thickness*************************/ - template - struct Thick - { - Thick(): z(0), z_zero_def_plane(0), z_back_prop(0), - islice(0), iatom_e(0) {} - - T z; // z - T z_zero_def_plane; // z: Zero defocus - T z_back_prop; // z: Back propagation - - int islice; // slice position - int iatom_e; // Last atom index - }; - - /**********************Identify planes*********************/ - template - struct Identify_Planes - { - using TVector = Vector; - using TVector_I = Vector; - - public: - Identify_Planes(): dv(0.1){} - - // Identify planes: Require v to be sorted - TVector operator()(TVector &v) - { - TVector v_plane; - - if(v.size()==0) - { - return v_plane; - } - - // min and max element - T v_min = v.front(); - T v_max = v.back(); - - // calculate hist and correct it - auto v_hist = hist(v, dv, v_min, v_max); - - if(v_hist.size()==1) - { - v_plane.push_back(thrust::reduce(v.begin(), v.end())/T(v.size())); - return v_plane; - } - - // calculate layer limits - TVector v_lim; - v_lim.reserve(v_hist.size()); - - for(auto iz = 0; iz < v_hist.size()-1; iz++) - { - if((v_hist[iz]>0) && (v_hist[iz+1]==0)) - { - v_lim.push_back(v.front()+(iz+1)*dv); - } - } - v_lim.push_back(v.back()+dv); - - // calculate planes - v_plane.reserve(v_lim.size()); - - T v_m = v.front(); - T v_m_ee = 0; - int v_c = 1; - int izl = 0; - for(auto iz = 0; iz < v.size(); iz++) - { - auto v_v = v[iz]; - - if(v_vint - { - return static_cast(floor(a/b+v_eps)); - }; - - T s_v = v_max-v_min; - const int nv = max(1, quot(s_v, dv))+1; - - switch (mb) - { - case eMB_Min: - { - v_plane.resize(nv); - for(auto iv=0; iv(ceil(v_l/dv)); - - TVector_I v_hist(nbins, 0); - for(auto iv = 0; iv< v.size(); iv++) - { - auto v_id = double(v[iv]); - auto ih = static_cast(floor((v_id-v_min)/dv)); - auto v_imin = v_min + (ih-1)*dv; - auto v_imax = v_imin + dv; - - if(v_id= 0; ik--) - { - v_imin = v_min + (ik-1)*dv; - v_imax = v_imin + dv; - if((v_imin<=v_id) && (v_idv_imax) - { - for (auto ik = ih; ik < nbins; ik++) - { - v_imin = v_min + ik*dv; - v_imax = v_imin + dv; - if((v_imin<=v_id) && (v_id - struct Q1 - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - size_type size() const - { - return x.size(); - } - - void clear() - { - x.clear(); - w.clear(); - } - - void reserve(const size_type &new_size) - { - x.reserve(new_size); - w.reserve(new_size); - } - - void resize(const size_type &new_size, const value_type &value = value_type()) - { - x.resize(new_size, value); - w.resize(new_size, value); - } - - void shrink_to_fit() - { - x.shrink_to_fit(); - w.shrink_to_fit(); - } - - template - void assign(TQ1 &q1) - { - x.assign(q1.x.begin(), q1.x.end()); - w.assign(q1.w.begin(), q1.w.end()); - } - - Vector x; - Vector w; - }; - - template - struct rQ1 - { - using value_type = T; - - rQ1(): m_size(0), x(nullptr), w(nullptr){} - - template - rQ1& operator = (TQ1 &q1) - { - m_size = q1.size(); - x = raw_pointer_cast(q1.x.data()); - w = raw_pointer_cast(q1.w.data()); - return *this; - } - - template - rQ1(TQ1 &q1) - { - *this = q1; - } - - int m_size; - T *x; - T *w; - }; - - /***********************quadrature xy**********************/ - template - struct Q2 - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - size_type size() const - { - return x.size(); - } - - void clear() - { - x.clear(); - y.clear(); - w.clear(); - } - - void reserve(const size_type &new_size) - { - x.reserve(new_size); - y.reserve(new_size); - w.reserve(new_size); - } - - void resize(const size_type &new_size, const value_type &value = value_type()) - { - x.resize(new_size, value); - y.resize(new_size, value); - w.resize(new_size, value); - } - - void shrink_to_fit() - { - x.shrink_to_fit(); - y.shrink_to_fit(); - w.shrink_to_fit(); - } - - template - void assign(TQ2 &q2) - { - x.assign(q2.x.begin(), q2.x.end()); - y.assign(q2.y.begin(), q2.y.end()); - w.assign(q2.w.begin(), q2.w.end()); - } - - Vector x; - Vector y; - Vector w; - }; - - template - struct rQ2 - { - using value_type = T; - - rQ2(): m_size(0), x(nullptr), y(nullptr), w(nullptr){} - - template - rQ2& operator = (TQ2 &q2) - { - m_size = q2.size(); - x = raw_pointer_cast(q2.x.data()); - y = raw_pointer_cast(q2.y.data()); - w = raw_pointer_cast(q2.w.data()); - return *this; - } - - template - rQ2(TQ2 &q2) - { - *this = q2; - } - - int m_size; - T *x; - T *y; - T *w; - }; - - /***********Lineal and non-Lineal Coefficients************/ - template - struct PP_Coef - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - size_type size() const - { - return cl.size(); - } - - void fill(const value_type &value = value_type()) - { - thrust::fill(cl.begin(), cl.end(), value); - thrust::fill(cnl.begin(), cnl.end(), value); - } - - void resize(const size_type &new_size, const value_type &value = value_type()) - { - cl.resize(new_size, value); - cnl.resize(new_size, value); - } - - template - void assign(TPP_Coef &pp_coef) - { - cl.assign(pp_coef.cl.begin(), pp_coef.cl.end()); - cnl.assign(pp_coef.cnl.begin(), pp_coef.cnl.end()); - } - - Vector cl; // Lineal coefficients fep - Vector cnl; // Non-Lineal coefficients fep - - }; - - template - struct rPP_Coef - { - using value_type = T; - - rPP_Coef(): m_size(0), cl(nullptr), cnl(nullptr){} - - template - rPP_Coef& operator = (TPP_Coef &rhs) - { - m_size = rhs.size(); - cl = raw_pointer_cast(rhs.cl.data()); - cnl = raw_pointer_cast(rhs.cnl.data()); - return *this; - } - - template - rPP_Coef(TPP_Coef &pp_coef) - { - *this = pp_coef; - } - - int m_size; - T *cl; - T *cnl; - }; - - /************Cubic interpolation coefficients*************/ - template - struct CI_Coef - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - size_type size() const - { - return c0.size(); - } - - void resize(const size_type &new_size, const value_type &value = value_type()) - { - c0.resize(new_size, value); - c1.resize(new_size, value); - c2.resize(new_size, value); - c3.resize(new_size, value); - } - - template - void assign(TCI_Coef &ci_coef) - { - c0.assign(ci_coef.c0.begin(), ci_coef.c0.end()); - c1.assign(ci_coef.c1.begin(), ci_coef.c1.end()); - c2.assign(ci_coef.c2.begin(), ci_coef.c2.end()); - c3.assign(ci_coef.c3.begin(), ci_coef.c3.end()); - } - - Vector c0; // zero coefficient - Vector c1; // first coefficient - Vector c2; // second coefficient - Vector c3; // third coefficient - }; - - template - struct rCI_Coef - { - using value_type = T; - - rCI_Coef(): m_size(0), c0(nullptr), c1(nullptr), c2(nullptr), c3(nullptr){} - - template - rCI_Coef& operator = (TCI_Coef &ci_coef) - { - m_size = ci_coef.size(); - c0 = raw_pointer_cast(ci_coef.c0.data()); - c1 = raw_pointer_cast(ci_coef.c1.data()); - c2 = raw_pointer_cast(ci_coef.c2.data()); - c3 = raw_pointer_cast(ci_coef.c3.data()); - return *this; - } - - template - rCI_Coef(TCI_Coef &ci_coef) - { - *this = ci_coef; - } - - int m_size; - T *c0; - T *c1; - T *c2; - T *c3; - }; - - /******************************pair************************************/ - template - struct sPair - { - using value_type = T; - - int idx; // index - T value; // Value - - }; - - /******************************Dim 3************************************/ - struct FP_Dim - { - bool x; - bool y; - bool z; - - FP_Dim(): x(true), y(true), z(false){} - - void set(const int &Dim) - { - switch(Dim) - { - case 111: - { - x = true; - y = true; - z = true; - } - break; - case 110: - { - x = true; - y = true; - z = false; - } - break; - case 101: - { - x = true; - y = false; - z = true; - } - break; - case 11: - { - x = false; - y = true; - z = true; - } - break; - case 100: - { - x = true; - y = false; - z = false; - } - break; - case 10: - { - x = false; - y = true; - z = false; - } - break; - case 1: - { - x = false; - y = false; - z = true; - } - break; - } - } - }; - - /**********************closest prime factorization**********************/ - struct Prime_Num - { - public: - Prime_Num() - { - load_number(); - } - - int operator()(int64_t n, eDat_Sel_Type dst = eDST_Closest) - { - auto p_idx = std::min_element(number.begin(), number.end(), [&n](int64_t p0, int64_t pe){ return std::abs(n-p0)(*p_idx); - - switch(dst) - { - case eDST_Less_Than: - { - if(pn>=n) - { - pn = static_cast(*(p_idx-1)); - } - } - break; - case eDST_Greater_Than: - { - if(pn<=n) - { - pn = static_cast(*(p_idx+1)); - } - } - break; - } - return pn; - } - - private: - std::vector number; - - void load_number() - { - int64_t b_2 = 2, b_3 = 3, b_5 = 5, b_7 = 7; - int np2 = 16, np3 = 7, np5 = 5, np7 = 4; - int64_t prime_0 = 64; - int64_t prime_e = static_cast(std::pow(b_2, 16)); - - - number.reserve(np2*np3*np5*np7); - for(auto ie=1; ie<7; ie++) - { - auto p = static_cast(std::pow(b_2, ie)); - number.push_back(p); - } - - for(auto ip7=0; ip7(std::pow(b_7, ip7)); - - for(auto ip5=0; ip5(std::pow(b_5, ip5)); - - for(auto ip3=0; ip3(std::pow(b_3, ip3)); - - for(auto ip2=1; ip2(std::pow(b_2, ip2)); - - auto p = p7*p5*p3*p2; - - if((prime_0 - struct Grid_1d - { - using value_type = T; - - int nx; // Number of pixels in x direction - - int nxh; // Half number of pixels in x direction - - T lx; // Box m_size in x direction(Angstroms) - T dz; // slice thicknes - - bool bwl; // Band-width limit - bool pbc_x; // Peridic boundary contions - - T Rx_0; // starting Rx - - T dRx; // x-sampling in real space - - T dgx; // x-sampling in reciprocal space - - T gl2_max; // Squared of the maximun limited frequency - T alpha; // 1/(1+exp(alpha*(x^2-x_c^2))) - - inline - Grid_1d(): nx(0), nxh(0), lx(0), dz(0), - pbc_x(true), bwl(true), Rx_0(0), dRx(0), dgx(0), gl2_max(0){} - - Grid_1d(int nx_i) - { - lx = nx_i; - set_input_data(nx_i, lx); - } - - Grid_1d(int nx_i, T lx_i, T dz_i = 0.5, bool bwl_i = false, bool pbc_x_i = false, T Rx_0_i=0) - { - set_input_data(nx_i, lx_i, dz_i, bwl_i, pbc_x_i, Rx_0_i); - } - - inline - void set_input_data(int nx_i, T lx_i, T dz_i = 0.5, bool bwl_i = false, bool pbc_x_i = false, T Rx_0_i=0) - { - nx = nx_i; - nxh = nx/2; - lx = lx_i; - dz = dz_i; - bwl = bwl_i; - pbc_x = pbc_x_i; - Rx_0 = Rx_0_i; - dRx = mt::Div(lx, nx); - dgx = mt::Div(1.0, lx); - gl2_max = ::square(gl_max()); - - // y = 1/(1+exp(alpha*(x^2-x_c^2))) - T dg0 = 0.25, fg0 = 1e-02; - alpha = log(1.0/fg0-1.0)/(::square(gl_max()+dg0)-gl2_max); - } - - inline - void set_R_0(T Rx_0_i) - { - Rx_0 = Rx_0_i; - } - - template - void assign(TGrid &grid_1d) - { - set_input_data(grid_1d.nx, grid_1d.lx, grid_1d.dz, grid_1d.bwl, grid_1d.pbc_x, grid_1d.Rx_0); - } - - template - Grid_1d& operator=(TGrid &grid_1d) - { - assign(grid_1d); - return *this; - } - - // Maximun limited frequency - DEVICE_CALLABLE FORCE_INLINE - T gl_max() const - { - return 2.0*g_max()/3.0; - } - - DEVICE_CALLABLE FORCE_INLINE - T nx_r() const { return T(nx); } - - DEVICE_CALLABLE FORCE_INLINE - T lxh() const { return 0.5*lx; } - - DEVICE_CALLABLE FORCE_INLINE - int Rx_c() const { return (Rx_0 + lxh()); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int floor_dRx(const T &x) const { return static_cast(floor((x-Rx_0)/dRx)); } - - DEVICE_CALLABLE FORCE_INLINE - int ceil_dRx(const T &x) const { return static_cast(ceil((x-Rx_0)/dRx)); } - - // lower bound - DEVICE_CALLABLE FORCE_INLINE - int lb_index_x(const T &x) const - { - return min(nx, max(0, floor_dRx(x))); - } - - // upper bound - DEVICE_CALLABLE FORCE_INLINE - int ub_index_x(const T &x) const - { - return min(nx, max(0, ceil_dRx(x))); - } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - bool ckb_bound(const T &x) const - { - const T eps = epsilon_abs(); - const T x_0 = Rx_first()-eps; - const T x_e = Rx_last()+eps; - return ((xx_e))?false:true; - } - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - void set_x_bound(T &x) const - { - x = ::fmin(::fmax(x, Rx_first()), Rx_last()); - } - /*********************************************************/ - // index - DEVICE_CALLABLE FORCE_INLINE - int ix(const T &x) const - { - return lb_index_x(x); - } - - // range - DEVICE_CALLABLE FORCE_INLINE - Range_1d index_range(T x, const T &radius) const - { - Range_1d r; - - r.ix_0 = lb_index_x(x - radius); - r.ix_e = ub_index_x(x + radius); - - r.ixy_0 = 0; - r.ixy_e = r.ix_e-r.ix_0; - - return r; - } - - /*********************************************************/ - // Maximun frequency - DEVICE_CALLABLE FORCE_INLINE - T g_max() const { return static_cast(nxh)*dgx; } - - // Squared of the maximun frequency - DEVICE_CALLABLE FORCE_INLINE - T g2_max() const { return pow(g_max(), 2); } - - DEVICE_CALLABLE FORCE_INLINE - int nx_dRx(const T &lx) const { return ceil_dRx(lx); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int igx(const int &ix) const { return ix-nxh; } - - DEVICE_CALLABLE FORCE_INLINE - T gx(const int &ix, T gx_0=T()) const { return (igx(ix)*dgx-gx_0); } - - DEVICE_CALLABLE FORCE_INLINE - T g2(const int &ix, T gx_0=T()) const { return ::square(gx(ix, gx_0)); } - - DEVICE_CALLABLE FORCE_INLINE - T g(const int &ix, T gx_0=T()) const { return fabs(gx(ix, gx_0)); } - - - DEVICE_CALLABLE FORCE_INLINE - T gx_first() const { return gx(0); } - - DEVICE_CALLABLE FORCE_INLINE - T gx_last() const { return gx(nx-1); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int iRx(const int &ix) const { return ix; } - - DEVICE_CALLABLE FORCE_INLINE - T Rx(const int &ix, T x0=T()) const { return (iRx(ix)*dRx+Rx_0-x0); } - - DEVICE_CALLABLE FORCE_INLINE - T R2(const int &ix, T x0=T()) const { return ::square(Rx(ix, x0)); } - - DEVICE_CALLABLE FORCE_INLINE - T R(const int &ix, T x0=T()) const { return fabs(Rx(ix, x0)); } - - - DEVICE_CALLABLE FORCE_INLINE - T Rx_first() const { return Rx(0); } - - DEVICE_CALLABLE FORCE_INLINE - T Rx_last() const { return Rx(nx-1); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int igx_shift(const int &ix) const { return (ix - struct Grid_2d - { - using value_type = T; - - int nx; // Number of pixels in x direction - int ny; // Number of pixels in y direction - - int nxh; // Half number of pixels in x direction - int nyh; // Half number of pixels in y direction - - T lx; // Box m_size in x direction(Angstroms) - T ly; // Box m_size in y direction(Angstroms) - T dz; // slice thicknes - - bool bwl; // Band-width limit - bool pbc_xy; // Peridic boundary contions - - T Rx_0; // starting Rx - T Ry_0; // starting Ry - - T dRx; // x-sampling in real space - T dRy; // y-sampling in real space - - T dgx; // x-sampling in reciprocal space - T dgy; // y-sampling in reciprocal space - - T gl2_max; // Squared of the maximun limited frequency - T alpha; // 1/(1+exp(alpha*(x^2-x_c^2))) - - inline - Grid_2d(): nx(0), ny(0), nxh(0), nyh(0), - lx(0), ly(0), dz(0), pbc_xy(true), bwl(false), - Rx_0(0), Ry_0(0), dRx(0), dRy(0), dgx(0), dgy(0), gl2_max(0){} - - Grid_2d(int nx_i, int ny_i) - { - lx = nx_i; - ly = ny_i; - set_input_data(nx_i, ny_i, lx, ly); - } - - Grid_2d(int nx_i, int ny_i, T lx_i, T ly_i, T dz_i = 0.5, bool bwl_i = false, - bool pbc_xy_i = false, T Rx_0_i=0, T Ry_0_i=0) - { - set_input_data(nx_i, ny_i, lx_i, ly_i, dz_i, bwl_i, pbc_xy_i, Rx_0_i, Ry_0_i); - } - - inline - void set_input_data(int nx_i, int ny_i, T lx_i, T ly_i, T dz_i = 0.5, - bool bwl_i = false, bool pbc_xy_i = false, T Rx_0_i=0, T Ry_0_i=0) - { - nx = nx_i; - ny = ny_i; - nxh = nx/2; - nyh = ny/2; - lx = lx_i; - ly = ly_i; - dz = dz_i; - bwl = bwl_i; - pbc_xy = pbc_xy_i; - Rx_0 = Rx_0_i; - Ry_0 = Ry_0_i; - dRx = mt::Div(lx, nx); - dRy = mt::Div(ly, ny); - dgx = mt::Div(T(1.0), lx); - dgy = mt::Div(T(1.0), ly); - gl2_max = ::square(gl_max()); - - // y = 1/(1+exp(alpha*(x^2-x_c^2))) - T dg0 = 0.25, fg0 = 1e-02; - alpha = log(1.0/fg0-1.0)/(::square(gl_max()+dg0)-gl2_max); - } - - inline - void set_R_0(T Rx_0_i, T Ry_0_i) - { - Rx_0 = Rx_0_i; - Ry_0 = Ry_0_i; - } - - template - void assign(TGrid &grid_2d) - { - set_input_data(grid_2d.nx, grid_2d.ny, grid_2d.lx, grid_2d.ly, grid_2d.dz, grid_2d.bwl, grid_2d.pbc_xy, grid_2d.Rx_0, grid_2d.Ry_0); - } - - template - Grid_2d& operator=(TGrid &grid_2d) - { - assign(grid_2d); - return *this; - } - - /************index periodic boundary conditions************/ - // https:// en.wikipedia.org/wiki/Periodic_boundary_conditions - - DEVICE_CALLABLE FORCE_INLINE - int iRx_pbc(const int &ix) const - { - return (ix - static_cast(floor(Rx(ix)/lx))*nx); - } - - DEVICE_CALLABLE FORCE_INLINE - int iRy_pbc(const int &iy) const - { - return (iy - static_cast(floor(Ry(iy)/ly))*ny); - } - - DEVICE_CALLABLE FORCE_INLINE - void iRx_iRy_pbc(int &ix, int &iy) - { - ix = iRx_pbc(ix); - iy = iRy_pbc(iy); - } - - DEVICE_CALLABLE FORCE_INLINE - int ind_row_pbc(const int &ix, const int &iy) const { return iRy_pbc(iy)*nx+iRx_pbc(ix); } - - DEVICE_CALLABLE FORCE_INLINE - int ind_col_pbc(const int &ix, const int &iy) const { return iRx_pbc(ix)*ny+iRy_pbc(iy); } - - DEVICE_CALLABLE FORCE_INLINE - int ind_col_pbc_shift(int ix, int iy) - { - iRx_iRy_pbc(ix, iy); - iRx_iRy_shift(ix, iy); - return ix*ny+iy; - } - - /*********************************************************/ - // Maximun limited frequency - DEVICE_CALLABLE FORCE_INLINE - T gl_max() const - { - return 2.0*g_max()/3.0; - } - - DEVICE_CALLABLE FORCE_INLINE - int nxy() const { return nx*ny; } - - T inxy() const { return 1.0/nxy_r(); } - - DEVICE_CALLABLE FORCE_INLINE - T nx_r() const { return T(nx); } - - DEVICE_CALLABLE FORCE_INLINE - T ny_r() const { return T(ny); } - - DEVICE_CALLABLE FORCE_INLINE - T nxy_r() const { return T(nx*ny); } - - DEVICE_CALLABLE FORCE_INLINE - int nx_ny_min() const { return min(nx, ny); } - - DEVICE_CALLABLE FORCE_INLINE - int nx_ny_max() const { return max(nx, ny); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int lx_ly_min() const { return min(lx, ly); } - - DEVICE_CALLABLE FORCE_INLINE - int lx_ly_max() const { return max(lx, ly); } - - DEVICE_CALLABLE FORCE_INLINE - T lxh() const { return 0.5*lx; } - - DEVICE_CALLABLE FORCE_INLINE - T lyh() const { return 0.5*ly; } - - DEVICE_CALLABLE FORCE_INLINE - int lxh_lyh_min() const { return min(lxh(), lyh()); } - - DEVICE_CALLABLE FORCE_INLINE - int lxh_lyh_max() const { return max(lxh(), lyh()); } - - DEVICE_CALLABLE FORCE_INLINE - int Rx_c() const { return (Rx_0 + lxh()); } - - DEVICE_CALLABLE FORCE_INLINE - int Ry_c() const { return (Ry_0 + lyh()); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int floor_dR_min(const T &x) const { return static_cast(floor((x-R_0_min())/dR_min())); } - - DEVICE_CALLABLE FORCE_INLINE - int floor_dRx(const T &x) const { return static_cast(floor((x-Rx_0)/dRx)); } - - DEVICE_CALLABLE FORCE_INLINE - int floor_dRy(const T &y) const { return static_cast(floor((y-Ry_0)/dRy)); } - - DEVICE_CALLABLE FORCE_INLINE - int ceil_dR_min(const T &x) const { return static_cast(ceil((x-R_0_min())/dR_min())); } - - DEVICE_CALLABLE FORCE_INLINE - int ceil_dRx(const T &x) const { return static_cast(ceil((x-Rx_0)/dRx)); } - - DEVICE_CALLABLE FORCE_INLINE - int ceil_dRy(const T &y) const { return static_cast(ceil((y-Ry_0)/dRy)); } - - // lower bound - DEVICE_CALLABLE FORCE_INLINE - int lb_index_x(const T &x) const - { - return min(nx, max(0, floor_dRx(x))); - } - - // upper bound - DEVICE_CALLABLE FORCE_INLINE - int ub_index_x(const T &x) const - { - return min(nx, max(0, ceil_dRx(x))); - } - - // lower bound - DEVICE_CALLABLE FORCE_INLINE - int lb_index_y(const T &y) const - { - return min(ny, max(0, floor_dRy(y))); - } - - // upper bound - DEVICE_CALLABLE FORCE_INLINE - int ub_index_y(const T &y) const - { - return min(ny, max(0, floor_dRy(y))); - } - /*********************************************************/ - - DEVICE_CALLABLE FORCE_INLINE - bool ckb_x_bound(const T &x) const - { - const T eps = epsilon_abs(); - const T x_0 = Rx_first()-eps; - const T x_e = Rx_last()+eps; - return ((xx_e))?false:true; - } - - DEVICE_CALLABLE FORCE_INLINE - bool ckb_y_bound(const T &y) const - { - const T eps = epsilon_abs(); - const T y_0 = Ry_first()-eps; - const T y_e = Ry_last()+eps; - return ((yy_e))?false:true; - } - - DEVICE_CALLABLE FORCE_INLINE - bool ckb_bound(const r2d &p) const - { - return (ckb_x_bound(p.x) && ckb_y_bound(p.y)); - } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - void set_x_bound(T &x) const - { - x = ::fmin(::fmax(x, Rx_first()), Rx_last()); - } - - DEVICE_CALLABLE FORCE_INLINE - void set_y_bound(T &y) const - { - y = ::fmin(::fmax(y, Ry_first()), Ry_last()); - } - - DEVICE_CALLABLE FORCE_INLINE - void set_bound(r2d &p) const - { - set_x_bound(p.x); - set_y_bound(p.y); - } - /*********************************************************/ - // index - DEVICE_CALLABLE FORCE_INLINE - int ixy(const T &x, const T &y) const - { - auto ix = lb_index_x(x); - auto iy = lb_index_y(y); - return ind_col(ix, iy); - } - - // range - DEVICE_CALLABLE FORCE_INLINE - Range_2d index_range(r2d p, T radius) const - { - Range_2d r; - - r.ix_0 = lb_index_x(p.x - radius); - r.ix_e = ub_index_x(p.x + radius); - - r.iy_0 = lb_index_y(p.y - radius); - r.iy_e = ub_index_y(p.y + radius); - - r.ixy_0 = 0; - r.ixy_e = (r.ix_e-r.ix_0)*(r.iy_e-r.iy_0); - - return r; - } - - Range_2d index_range(r2d p, T f0, T a, T b, T c) - { - Range_2d r; - - T d = log(f0); - T dd = c*c-4*a*b; - - T radius_x = sqrt(4*b*d/dd); - T radius_y = sqrt(4*a*d/dd); - - r.ix_0 = ub_index_x(p.x - radius_x); - r.ix_e = lb_index_x(p.x + radius_x); - - r.iy_0 = ub_index_y(p.y - radius_y); - r.iy_e = lb_index_y(p.y + radius_y); - - r.ixy_0 = 0; - r.ixy_e = (r.ix_e-r.ix_0)*(r.iy_e-r.iy_0); - - return r; - }; - - /*********************************************************/ - // Maximun frequency - DEVICE_CALLABLE FORCE_INLINE - T g_max() const { return ::fmin(static_cast(nxh)*dgx, static_cast(nyh)*dgy); } - - // Squared of the maximun frequency - DEVICE_CALLABLE FORCE_INLINE - T g2_max() const { return ::square(g_max()); } - - DEVICE_CALLABLE FORCE_INLINE - T R_0_min() const { return ::fmin(Rx_0, Ry_0); } - - DEVICE_CALLABLE FORCE_INLINE - T dR_min() const { return ::fmin(dRx, dRy); } - - DEVICE_CALLABLE FORCE_INLINE - T dg_min() const { return ::fmin(dgx, dgy); } - - DEVICE_CALLABLE FORCE_INLINE - int nx_dRx(const T &lx) const { return static_cast(ceil(lx/dRx)); } - - DEVICE_CALLABLE FORCE_INLINE - int ny_dRy(const T &ly) const { return static_cast(ceil(ly/dRy)); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int igx(const int &ix) const { return (ix-nxh); } - - DEVICE_CALLABLE FORCE_INLINE - int igy(const int &iy) const { return (iy-nyh); } - - DEVICE_CALLABLE FORCE_INLINE - T gx(const int &ix, T gx_0=T()) const { return (igx(ix)*dgx-gx_0); } - - DEVICE_CALLABLE FORCE_INLINE - T gy(const int &iy, T gy_0=T()) const { return (igy(iy)*dgy-gy_0); } - - DEVICE_CALLABLE FORCE_INLINE - T gx2(const int &ix, T gx_0=T()) const { return ::square(gx(ix, gx_0)); } - - DEVICE_CALLABLE FORCE_INLINE - T gy2(const int &iy, T gy_0=T()) const { return ::square(gy(iy, gy_0)); } - - DEVICE_CALLABLE FORCE_INLINE - T g2(const int &ix, const int &iy, T gx_0=T(), T gy_0=T())const { return (gx2(ix, gx_0)+gy2(iy, gy_0)); } - - DEVICE_CALLABLE FORCE_INLINE - T g(const int &ix, const int &iy, T gx_0=T(), T gy_0=T()) const { return sqrt(g2(ix, iy, gx_0, gy_0)); } - - - DEVICE_CALLABLE FORCE_INLINE - T gx_first() const { return gx(0); } - - DEVICE_CALLABLE FORCE_INLINE - T gx_last() const { return gx(nx-1); } - - DEVICE_CALLABLE FORCE_INLINE - T gy_first() const { return gy(0); } - - DEVICE_CALLABLE FORCE_INLINE - T gy_last() const { return gy(ny-1); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int iRx(const int &ix) const { return ix; } - - DEVICE_CALLABLE FORCE_INLINE - int iRy(const int &iy) const { return iy; } - - DEVICE_CALLABLE FORCE_INLINE - T Rx(const int &ix, T x0=T()) const { return (iRx(ix)*dRx+Rx_0-x0); } - - DEVICE_CALLABLE FORCE_INLINE - T Ry(const int &iy, T y0=T()) const { return (iRy(iy)*dRy+Ry_0-y0); } - - DEVICE_CALLABLE FORCE_INLINE - T Rx2(const int &ix, T x0=T()) const { return ::square(Rx(ix, x0)); } - - DEVICE_CALLABLE FORCE_INLINE - T Ry2(const int &iy, T y0=T()) const { return ::square(Ry(iy, y0)); } - - DEVICE_CALLABLE FORCE_INLINE - T R2(const int &ix, const int &iy, T x0=T(), T y0=T()) const { return (Rx2(ix, x0)+Ry2(iy, y0)); } - - DEVICE_CALLABLE FORCE_INLINE - T R(const int &ix, const int &iy, T x0=T(), T y0=T()) const { return sqrt(R2(ix, iy, x0, y0)); } - - DEVICE_CALLABLE FORCE_INLINE - T Rx_first() const { return Rx(0); } - - DEVICE_CALLABLE FORCE_INLINE - T Rx_last() const { return Rx(nx-1); } - - DEVICE_CALLABLE FORCE_INLINE - T Ry_first() const { return Ry(0); } - - DEVICE_CALLABLE FORCE_INLINE - T Ry_last() const { return Ry(ny-1); } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - int igx_shift(const int &ix) const { return (ix - struct Detector - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - Detector(): type(eDT_Circular){} - - size_type size() const - { - size_type size_out = 0; - switch (type) - { - case eDT_Circular: - { - size_out = g_inner.size(); - } - break; - case eDT_Radial: - { - size_out = fx.size(); - } - break; - case eDT_Matrix: - { - size_out = fR.size(); - } - break; - } - return size_out; - } - - void clear() - { - g_inner.clear(); - g_outer.clear(); - fx.clear(); - fR.clear(); - fn.clear(); - grid_1d.clear(); - grid_2d.clear(); - } - - void resize(const size_type &new_size) - { - switch (type) - { - case eDT_Circular: - { - g_inner.resize(new_size); - g_outer.resize(new_size); - } - break; - case eDT_Radial: - { - fx.resize(new_size); - fn.resize(new_size); - grid_1d.resize(new_size); - } - break; - case eDT_Matrix: - { - fR.resize(new_size); - fn.resize(new_size); - grid_2d.resize(new_size); - } - break; - } - } - - template - void assign(TDetector &detector) - { - type = detector.type; - g_inner.assign(detector.g_inner.begin(), detector.g_inner.end()); - g_outer.assign(detector.g_outer.begin(), detector.g_outer.end()); - - fx.resize(detector.fx.size()); - for(auto i= 0; i - Detector& operator=(TDetector &detector) - { - assign(detector); - return *this; - } - - bool is_detector_circular() const - { - return mt::is_detector_circular(type); - } - - bool is_detector_radial() const - { - return mt::is_detector_radial(type); - } - - bool is_detector_matrix() const - { - return mt::is_detector_matrix(type); - } - - eDetector_Type type; // eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 - Vector g_inner; // Inner aperture Ang^-1 - Vector g_outer; // Outer aperture Ang^-1 - Vector, e_host> fx; // radial sensitivity value - Vector, e_host> fR; // 2D sensitivity value - std::vector> grid_1d; // grid_1d - std::vector> grid_2d; // grid_2d - std::vector fn; // file names - }; - - /********************STEM Intensity***********************/ - template - struct Det_Int - { - using value_type = typename TVector::value_type; - using size_type = std::size_t; - - static const eDevice device = e_host; - - size_type size() const - { - return image.size(); - } - - Vector image; - }; - - /****************************lens***************************/ - template - struct Lens - { - using value_type = T; - - int m; // Momentum of the vortex - - T c_10; // Defocus (�) - T c_12; // 2-fold astigmatism (�) - T phi_12; // Azimuthal angle of 2-fold astigmatism (rad) - - T c_21; // Axial coma (�) - T phi_21; // Azimuthal angle of axial coma (rad) - T c_23; // 3-fold astigmatism (�) - T phi_23; // Azimuthal angle of 3-fold astigmatism (rad) - - T c_30; // 3rd order spherical aberration (�) - T c_32; // Axial star aberration (�) - T phi_32; // Azimuthal angle of axial star aberration (rad) - T c_34; // 4-fold astigmatism (�) - T phi_34; // Azimuthal angle of 4-fold astigmatism (rad) - - T c_41; // 4th order axial coma (�) - T phi_41; // Azimuthal angle of 4th order axial coma (rad) - T c_43; // 3-lobe aberration (�) - T phi_43; // Azimuthal angle of 3-lobe aberration (rad) - T c_45; // 5-fold astigmatism (�) - T phi_45; // Azimuthal angle of 5-fold astigmatism (rad) - - T c_50; // 5th order spherical aberration (�) - T c_52; // 5th order axial star aberration (�) - T phi_52; // Azimuthal angle of 5th order axial star aberration (rad) - T c_54; // 5th order rosette aberration (�) - T phi_54; // Azimuthal angle of 5th order rosette aberration (rad) - T c_56; // 6-fold astigmatism (�) - T phi_56; // Azimuthal angle of 6-fold astigmatism (rad) - - T inner_aper_ang; // Inner aperture (rad); - T outer_aper_ang; // Outer aperture (rad); - - T ti_a; // Height proportion of a normalized Gaussian [0, 1] - T ti_sigma; // Standard deviation of the defocus spread function for the Gaussian component: - T ti_beta; // Standard deviation of the defocus spread function for the Exponential component: - int ti_npts; // Number of integration points of the defocus spread function - - T ti_iehwgd; // e^-1 half-width value of the Gaussian distribution - - T si_a; // Height proportion of a normalized Gaussian [0, 1] - T si_sigma; // Standard deviation of the source spread function for the Gaussian component: For parallel ilumination(�^-1); otherwise (�) - T si_beta; // Standard deviation of the source spread function for the Exponential component: For parallel ilumination(�^-1); otherwise (�) - int si_rad_npts; // Number of radial integration points - int si_azm_npts; // Number of azimuth integration points - - T si_iehwgd; // e^-1 half-width value of the Gaussian distribution - T si_theta_c; // divergence semi-angle (rad) - - eZero_Defocus_Type zero_defocus_type; // Defocus type: eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 - T zero_defocus_plane; // plane - - T gamma; // Relativistic factor - T lambda; // wavelength(Angstrom) - T lambda2; // wavelength(Angstrom)^2 - - T c_c_10; // -pi*c_10*lambda - T c_c_12; // -pi*c_12*lambda - - T c_c_21; // -2*pi*c_21*lambda^2/3 - T c_c_23; // -2*pi*c_23*lambda^2/3 - - T c_c_30; // -pi*c_30*lambda^3/2 - T c_c_32; // -pi*c_32*lambda^3/2 - T c_c_34; // -pi*c_34*lambda^3/2 - - T c_c_41; // -2*pi*c_41*lambda^4/5 - T c_c_43; // -2*pi*c_43*lambda^4/5 - T c_c_45; // -2*pi*c_45*lambda^4/5 - - T c_c_50; // -pi*c_50*lambda^5/3 - T c_c_52; // -pi*c_52*lambda^5/3 - T c_c_54; // -pi*c_54*lambda^5/3 - T c_c_56; // -pi*c_56*lambda^5/3 - - T g2_min; // inner_aper_ang/lambda - T g2_max; // outer_aper_ang/lambda - int ngxs; // Number of source sampling points x - int ngys; // Number of source sampling points y - T dgxs; // source sampling m_size; - T dgys; // source sampling m_size; - T g2_maxs; // q maximum square; - - Lens(): m(0), c_10(0), c_12(0), phi_12(0), c_21(0), phi_21(0), c_23(0), phi_23(0), - c_30(0), c_32(0), phi_32(0), c_34(0), phi_34(0), - c_41(0), phi_41(0), c_43(0), phi_43(0), c_45(0), phi_45(0), - c_50(0), c_52(0), phi_52(0), c_54(0), phi_54(0), c_56(0), phi_56(0), - inner_aper_ang(0), outer_aper_ang(0), ti_a(1.0), ti_sigma(0), ti_beta(0), ti_npts(0), ti_iehwgd(0), - si_a(1.0), si_sigma(0), si_beta(0), si_rad_npts(0), si_azm_npts(0), si_iehwgd(0), si_theta_c(0), - zero_defocus_plane(0), gamma(0), lambda(0), lambda2(0), - g2_min(0), g2_max(0), ngxs(0), ngys(0), dgxs(0), dgys(0), g2_maxs(0), - c_c_10(0), c_c_12(0), c_c_21(0), c_c_23(0), c_c_30(0), c_c_32(0), c_c_34(0), c_c_41(0), - c_c_43(0), c_c_45(0), c_c_50(0), c_c_52(0), c_c_54(0), c_c_56(0) {} - - void set_input_data(T E_0, Grid_2d &grid_2d) - { - gamma = get_gamma(E_0); - - lambda = get_lambda(E_0); - lambda2 = pow(lambda, 2); - - c_c_10 = (isZero(c_10))?0:-c_Pi*c_10*lambda; - c_c_12 = (isZero(c_12))?0:-c_Pi*c_12*lambda; - - c_c_21 = (isZero(c_21))?0:-2.0*c_Pi*c_21*pow(lambda, 2)/3.0; - c_c_23 = (isZero(c_23))?0:-2.0*c_Pi*c_23*pow(lambda, 2)/3.0; - - c_c_30 = (isZero(c_30))?0:-c_Pi*c_30*pow(lambda, 3)/2.0; - c_c_32 = (isZero(c_32))?0:-c_Pi*c_32*pow(lambda, 3)/2.0; - c_c_34 = (isZero(c_34))?0:-c_Pi*c_34*pow(lambda, 3)/2.0; - - c_c_41 = (isZero(c_41))?0:-2.0*c_Pi*c_41*pow(lambda, 4)/5.0; - c_c_43 = (isZero(c_43))?0:-2.0*c_Pi*c_43*pow(lambda, 4)/5.0; - c_c_45 = (isZero(c_45))?0:-2.0*c_Pi*c_45*pow(lambda, 4)/5.0; - - c_c_50 = (isZero(c_50))?0:-c_Pi*c_50*pow(lambda, 5)/3.0; - c_c_52 = (isZero(c_52))?0:-c_Pi*c_52*pow(lambda, 5)/3.0; - c_c_54 = (isZero(c_54))?0:-c_Pi*c_54*pow(lambda, 5)/3.0; - c_c_56 = (isZero(c_56))?0:-c_Pi*c_56*pow(lambda, 5)/3.0; - - g2_min = (isZero(inner_aper_ang)||(inner_aper_ang<0))?0:pow(sin(inner_aper_ang)/lambda, 2); - g2_max = (isZero(outer_aper_ang)||(outer_aper_ang<0))?grid_2d.g2_max(): pow(sin(outer_aper_ang)/lambda, 2); - - ti_a = max(T(0), min(T(1), ti_a)); - set_ti_sigma(ti_sigma); - ti_beta = max(T(0), ti_beta); - ti_npts = max(1, ti_npts); - - si_a = max(T(0), min(T(1), si_a)); - set_si_sigma(si_sigma); - si_beta = max(T(0), si_beta); - si_rad_npts = max(1, si_rad_npts); - si_azm_npts = max(1, si_azm_npts); - - T gmaxs = 3.5*si_sigma; - g2_maxs = gmaxs*gmaxs; - T dgs = gmaxs/static_cast(si_rad_npts); - - int n; - n = (dgs(floor(grid_2d.dgx/dgs)+1):1; - ngxs = static_cast(floor(n*gmaxs/grid_2d.dgx)) + 1; - dgxs = gmaxs/ngxs; - - n = (dgs(floor(grid_2d.dgy/dgs)+1):1; - ngys = static_cast(floor(n*gmaxs/grid_2d.dgy)) + 1; - dgys = gmaxs/ngys; - } - - void set_ti_sigma(T ti_sigma_i) - { - ti_sigma = max(T(0), ti_sigma_i); - ti_iehwgd = c_2i2*ti_sigma; - } - - void set_si_sigma(T si_sigma_i) - { - si_sigma = max(T(0), si_sigma_i); - si_iehwgd = c_2i2*si_sigma; - si_theta_c = asin(si_iehwgd*lambda); - } - - void set_defocus(T f_i) - { - c_10 = f_i; - c_c_10 = (isZero(c_10))?0:-c_Pi*c_10*lambda; - } - - T get_zero_defocus_plane(const T &z_min, const T &z_max) - { - T z = 0; - switch(zero_defocus_type) - { - case eZDT_First: - { - z = z_min; - } - break; - case eZDT_Middle: - { - z = 0.5*(z_min + z_max); - } - break; - case eZDT_Last: - { - z = z_max; - } - break; - default: - { - z = zero_defocus_plane; - } - } - return z; - }; - - bool is_zero_defocus_type_First() - { - return zero_defocus_type == eZDT_First; - } - - bool is_zero_defocus_type_Middle() - { - return zero_defocus_type == eZDT_Middle; - } - - bool is_zero_defocus_type_Last() - { - return zero_defocus_type == eZDT_Last; - } - - bool is_zero_defocus_type_User_Define() - { - return zero_defocus_type == eZDT_User_Define; - } - - template - void assign(TLens &lens) - { - m = lens.m; - c_10 = lens.c_10; - c_12 = lens.c_12; - phi_12 = lens.phi_12; - - c_21 = lens.c_21; - phi_21 = lens.phi_21; - c_23 = lens.c_23; - phi_23 = lens.phi_23; - - c_30 = lens.c_30; - c_32 = lens.c_32; - phi_32 = lens.phi_32; - c_34 = lens.c_34; - phi_34 = lens.phi_34; - - c_41 = lens.c_41; - phi_41 = lens.phi_41; - c_43 = lens.c_43; - phi_43 = lens.phi_43; - c_45 = lens.c_45; - phi_45 = lens.phi_45; - - c_50 = lens.c_50; - c_52 = lens.c_52; - phi_52 = lens.phi_52; - c_54 = lens.c_54; - phi_54 = lens.phi_54; - c_56 = lens.c_56; - phi_56 = lens.phi_56; - - inner_aper_ang = lens.inner_aper_ang; - outer_aper_ang = lens.outer_aper_ang; - - ti_sigma = lens.ti_sigma; - ti_npts = lens.ti_npts; - ti_iehwgd = lens.ti_iehwgd; - - si_sigma = lens.si_sigma; - si_rad_npts = lens.si_rad_npts; - si_iehwgd = lens.si_iehwgd; - si_theta_c = lens.si_theta_c; - - gamma = lens.gamma; - lambda = lens.lambda; - lambda2 = lens.lambda2; - - c_c_10 = lens.c_c_10; - c_c_12 = lens.c_c_12; - - c_c_21 = lens.c_c_21; - c_c_23 = lens.c_c_23; - - c_c_30 = lens.c_c_30; - c_c_32 = lens.c_c_32; - c_c_34 = lens.c_c_34; - - c_c_41 = lens.c_c_41; - c_c_43 = lens.c_c_43; - c_c_45 = lens.c_c_45; - - c_c_50 = lens.c_c_50; - c_c_52 = lens.c_c_52; - c_c_54 = lens.c_c_54; - c_c_56 = lens.c_c_56; - - g2_min = lens.g2_min; - g2_max = lens.g2_max; - - ngxs = lens.ngxs; - ngys = lens.ngys; - dgxs = lens.dgxs; - dgys = lens.dgys; - g2_maxs = lens.g2_maxs; - } - - template - Lens& operator=(TLens &lens) - { - assign(lens); - return *this; - } - - inline - T gxs(const int &ix) const { return static_cast(ix)*dgxs; } - - inline - T gys(const int &iy) const { return static_cast(iy)*dgys; } - - inline - T g2s(const int &ix, const int &iy) const - { - T gxi = gxs(ix); - T gyi = gys(iy); - return gxi*gxi + gyi*gyi; - } - - /************************************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T ti_sigma2() const - { - return ti_sigma*ti_sigma; - } - - DEVICE_CALLABLE FORCE_INLINE - T ti_beta2() const - { - return ti_beta*ti_beta; - } - - DEVICE_CALLABLE FORCE_INLINE - T si_sigma2() const - { - return si_sigma*si_sigma; - } - - DEVICE_CALLABLE FORCE_INLINE - T si_beta2() const - { - return si_beta*si_beta; - } - - /************************************************************************/ - DEVICE_CALLABLE FORCE_INLINE - bool is_phi_required() const - { - auto bb = nonZero(m)||nonZero(c_12)||nonZero(c_21)||nonZero(c_23)||nonZero(c_32)||nonZero(c_34); - bb = bb||nonZero(c_41)||nonZero(c_43)||nonZero(c_45)||nonZero(c_52)||nonZero(c_54)||nonZero(c_56); - return bb; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_m(const T &phi) const - { - return (nonZero(phi))?(m*phi):0; - } - - /************************************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T eval_c_10(const T &g2) const - { - return (nonZero(c_10))?(c_c_10*g2):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_12(const T &g2, const T &phi) const - { - return (nonZero(c_12))?(c_c_12*g2*sin(2*(phi-phi_12))):0; - } - - /************************************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T eval_c_21(const T &g3, const T &phi) const - { - return (nonZero(c_21))?(c_c_21*g3*sin(phi-phi_21)):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_23(const T &g3, const T &phi) const - { - return (nonZero(c_23))?(c_c_23*g3*sin(3*(phi-phi_23))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_21_c_23(const T &g3, const T &phi) const - { - return (eval_c_21(g3, phi) + eval_c_23(g3, phi)); - } - /************************************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T eval_c_30(const T &g4) const - { - return (nonZero(c_30))?(c_c_30*g4):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_32(const T &g4, const T &phi) const - { - return (nonZero(c_32))?(c_c_32*g4*sin(2*(phi-phi_32))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_34(const T &g4, const T &phi) const - { - return (nonZero(c_34))?(c_c_34*g4*sin(4*(phi-phi_34))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_32_c_34(const T &g4, const T &phi) const - { - return (eval_c_32(g4, phi) + eval_c_34(g4, phi)); - } - /************************************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T eval_c_41(const T &g5, const T &phi) const - { - return (nonZero(c_41))?(c_c_41*g5*sin(phi-phi_41)):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_43(const T &g5, const T &phi) const - { - return (nonZero(c_43))?(c_c_43*g5*sin(3*(phi-phi_43))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_45(const T &g5, const T &phi) const - { - return (nonZero(c_45))?(c_c_45*g5*sin(5*(phi-phi_45))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_41_c_43_c_45(const T &g5, const T &phi) const - { - return (eval_c_41(g5, phi) + eval_c_43(g5, phi) + eval_c_45(g5, phi)); - } - /************************************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T eval_c_50(const T &g6) const - { - return (nonZero(c_50))?(c_c_50*g6):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_52(const T &g6, const T &phi) const - { - return (nonZero(c_52))?(c_c_52*g6*sin(2*(phi-phi_52))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_54(const T &g6, const T &phi) const - { - return (nonZero(c_54))?(c_c_54*g6*sin(4*(phi-phi_54))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_56(const T &g6, const T &phi) const - { - return (nonZero(c_56))?(c_c_56*g6*sin(6*(phi-phi_56))):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_c_52_c_54_c_56(const T &g6, const T &phi) const - { - return (eval_c_52(g6, phi) + eval_c_54(g6, phi) + eval_c_56(g6, phi)); - } - }; - - /****************************EELS***************************/ - template - struct EELS - { - using value_type = T; - - inline - EELS(): space(eS_Real), E_0(0), E_loss(0), ge(0), ge2(0), gc(0), gc2(0), - m_selection(0), collection_angle(0), channelling_type(eCT_Double_Channelling), - g_collection(0), factor(0), Z(0), x(0), y(0), occ(0){} - - inline - void set_input_data(eSpace space_i, T E_0_i, T E_loss_i, int m_selection_i, T collection_angle_i, eChannelling_Type channelling_type_i, int Z_i) - { - space = space_i; - E_0 = E_0_i; - E_loss = E_loss_i; - T gamma = get_gamma(E_0); - T lambda = get_lambda(E_0); - - T theta = get_theta(E_loss, E_0); - - ge = theta/(lambda*gamma*gamma); - ge2 = pow(gamma*ge, 2); - gc = sqrt(2.0*theta)/lambda; - gc2 = pow(gc, 2); - - m_selection = m_selection_i; - collection_angle = collection_angle_i; - g_collection = collection_angle/lambda; - channelling_type = channelling_type_i; - - Z = Z_i; - } - - template - void assign(TEELS &eels) - { - set_input_data(eels.space, eels.E_0, eels.E_loss, eels.m_selection, eels.collection_angle, eels.channelling_type, eels.Z); - factor = eels.factor; - x = eels.x; - y = eels.y; - occ = eels.occ; - } - - template - EELS& operator=(TEELS &eels) - { - assign(eels); - return *this; - } - - // effective scattering angle - inline - T get_theta(const T &E_loss, const T &E_0) - { - T emass = 510.99906; - T x = (emass + E_0)/(2*emass + E_0); - return E_loss*x/E_0; - } - - bool is_Single_Channelling() const - { - return channelling_type == eCT_Single_Channelling; - } - - bool is_Mixed_Channelling() const - { - return channelling_type == eCT_Mixed_Channelling; - } - - bool is_Double_Channelling() const - { - return channelling_type == eCT_Double_Channelling; - } - - eSpace space; - T E_0; - T E_loss; // Energy loss - T ge; // relativistic corrected effective scattering momentum transfer - T ge2; // ge square - T gc; // ge cut-off at the Bethe Ridge - T gc2; // gc square - int m_selection; // selection rule - T collection_angle; // Collection half angle(rad) - eChannelling_Type channelling_type; - - T factor; - int Z; // Atomic type - T x; - T y; - T occ; - T g_collection; - }; - - /**************************atoms for Suppos**************************/ - template - class Atom_Data_Sp{ - public: - using value_type = T; - using size_type = std::size_t; - - Atom_Data_Sp(): l_x(0), l_y(0), - x_min(0), x_max(0), - y_min(0), y_max(0), - a_min(0), a_max(0), - sigma_min(0), sigma_max(0), - x_mean(0), y_mean(0), - x_std(0), y_std(0), - s_x(0), s_y(0){} - - size_type size() const - { - return x.size(); - } - - bool empty() const - { - return size() == 0; - } - - // resize number of atoms - void resize(const size_type &new_size, const value_type &value = value_type()) - { - x.resize(new_size, value); - x.shrink_to_fit(); - - y.resize(new_size, value); - y.shrink_to_fit(); - - a.resize(new_size, value); - a.shrink_to_fit(); - - sigma.resize(new_size, value); - sigma.shrink_to_fit(); - } - - // reserve - void reserve(const size_type &new_size) - { - x.reserve(new_size); - y.reserve(new_size); - a.reserve(new_size); - sigma.reserve(new_size); - } - - // reserve - void push_back(T x_i, T y_i, T a_i, T sigma_i) - { - x.push_back(x_i); - y.push_back(y_i); - a.push_back(a_i); - sigma.push_back(sigma_i); - } - - // set atoms - void set_atoms(const size_type &nr_atoms_i, const size_type &nc_atoms_i, double *atoms_i, T l_x_i = 0, T l_y_i = 0, bool pbc_xy_i = false) - { - resize(nr_atoms_i); - - l_x = l_x_i; - l_y = l_y_i; - - T dl = 1e-04; - T lx_b = l_x - dl; - T ly_b = l_y - dl; - - size_type j = 0; - for(auto i = 0; i < size(); i++) - { - auto atom = read_atom(nr_atoms_i, nc_atoms_i, atoms_i, i); - if((!pbc_xy_i)||((atom.x &atoms, bool pbc_xy_i = false) - { - resize(atoms.size()); - - l_x = atoms.l_x; - l_y = atoms.l_y; - - T dl = 1e-04; - T lx_b = l_x - dl; - T ly_b = l_y - dl; - - size_type j = 0; - for(auto i = 0; i < size(); i++) - { - if((!pbc_xy_i)||((atoms.x[i](size()); - - x_mean /= nAtoms; - y_mean /= nAtoms; - - x_std = sqrt(x_std/nAtoms - x_mean*x_mean); - y_std = sqrt(y_std/nAtoms - y_mean*y_mean); - - s_x = x_max - x_min; - s_y = y_max - y_min; - - if(isZero(l_x)) - { - l_x = s_x; - } - - if(isZero(l_y)) - { - l_y = s_y; - } - } - - T l_x; // Box m_size-x - T l_y; // Box m_size-y - - Vector x; - Vector y; - Vector a; - Vector sigma; - - T x_min; - T x_max; - - T y_min; - T y_max; - - T a_min; - T a_max; - - T sigma_min; - T sigma_max; - - T x_mean; - T y_mean; - - T x_std; - T y_std; - - T s_x; // m_size-x - T s_y; // m_size-y - - private: - struct Atom - { - T x; - T y; - T a; - T sigma; - - Atom():x(0), y(0), a(0), sigma(0){}; - }; - - template - Atom read_atom(const int &nr, const int &nc, TIn *atoms, const int &iatoms) - { - Atom atom; - atom.x = atoms[0*nr + iatoms]; // x-position - atom.y = atoms[1*nr + iatoms]; // y-position - atom.a = (nc>2)?atoms[2*nr + iatoms]:1.0; // height - atom.sigma = (nc>3)?atoms[3*nr + iatoms]:1.0; // standard deviation - - return atom; - } - }; - - template - struct Atom_Sp - { - public: - using value_type = T; - static const eDevice device = dev; - - T x; - T y; - T occ; - T R2_max; - T *R2; - T *c3; - T *c2; - T *c1; - T *c0; - - int ix_0; - int nx; - int iy_0; - int ny; - - T a; - T alpha; - T dtR; - T R2_tap; - T tap_cf; - - int *iv; - T *v; - - Atom_Sp(): x(0), y(0), occ(1), R2_max(0), R2(nullptr), c3(nullptr), c2(nullptr), - c1(nullptr), c0(nullptr), ix_0(0), nx(1), iy_0(0), ny(1), a(0), alpha(0), - dtR(0), R2_tap(0), tap_cf(0), iv(nullptr), v(nullptr){} - - inline - void set_ix0_ixn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(x, grid_2d.nx, grid_2d.dRx, R_max, grid_2d.pbc_xy, ix_0, nx); - } - - inline - void set_iy0_iyn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(y, grid_2d.ny, grid_2d.dRy, R_max, grid_2d.pbc_xy, iy_0, ny); - } - - inline - Grid_BT get_eval_cubic_poly_gridBT() - { - Grid_BT grid_bt; - grid_bt.Blk = dim3((ny+c_thrnxny-1)/c_thrnxny, (nx+c_thrnxny-1)/c_thrnxny); - grid_bt.Thr = dim3(c_thrnxny, c_thrnxny); - return grid_bt; - } - }; - - /**************************atoms for Superpositon************************/ - template - struct Gauss_Sp - { - public: - using value_type = T; - - T x; - T y; - T R2_max; - - int ix_0; - int iy_0; - int nx; - int ny; - - T a; - T alpha; - T R2_tap; - T tap_cf; - - int *iv; - T *v; - - Gauss_Sp(): x(0), y(0), R2_max(0), ix_0(0), iy_0(0), nx(1), ny(1), - a(0), alpha(0), R2_tap(0), tap_cf(0), iv(nullptr), v(nullptr){} - - - DEVICE_CALLABLE FORCE_INLINE - T operator()(const T &R2) const - { - const T tap = host_device_detail::tapering(R2_tap, tap_cf, R2); - const T y = a*exp(-alpha*R2)*tap; - return y; - } - - inline - void set_ix0_ixn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(x, grid_2d.nx, grid_2d.dRx, R_max, grid_2d.pbc_xy, ix_0, nx); - } - - inline - void set_iy0_iyn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(y, grid_2d.ny, grid_2d.dRy, R_max, grid_2d.pbc_xy, iy_0, ny); - } - }; - - template - class Input_Gauss_Spt - { - public: - using value_type = T; - - T ff_sigma; - Grid_2d grid_2d; - Atom_Data_Sp atoms; - - Input_Gauss_Spt(): ff_sigma(3){}; - - T alpha(const int &iatoms) const - { - return 0.5/pow(atoms.sigma[iatoms], 2); - } - - T R_max(const int &iatoms) const - { - return ff_sigma*atoms.sigma[iatoms]; - } - - // maximum number of pixels - int get_nv() - { - auto l_x = atoms.l_x + 2*ff_sigma*atoms.sigma_max; - auto l_y = atoms.l_y + 2*ff_sigma*atoms.sigma_max; - return max(grid_2d.nx_dRx(l_x), grid_2d.ny_dRy(l_y)); - } - }; - - /***********************atoms for simulated annealing***********************/ - template - class Atom_Data_Sa{ - public: - using value_type = T; - using size_type = std::size_t; - - size_type size() const - { - return Z.size(); - } - - bool empty() const - { - return size() == 0; - } - - template - void assign(TAtom_SA &atom_sa) - { - Z.assign(atom_sa.Z.begin(), atom_sa.Z.end()); - - r_min.assign(atom_sa.r_min.begin(), atom_sa.r_min.end()); - r_max.assign(atom_sa.r_max.begin(), atom_sa.r_max.end()); - r_0.assign(atom_sa.r_0.begin(), atom_sa.r_0.end()); - r_d.assign(atom_sa.r_d.begin(), atom_sa.r_d.end()); - - r.assign(atom_sa.r.begin(), atom_sa.r.end()); - r_n.assign(atom_sa.r_n.begin(), atom_sa.r_n.end()); - r_opt.assign(atom_sa.r_opt.begin(), atom_sa.r_opt.end()); - - chi2.assign(atom_sa.chi2.begin(), atom_sa.chi2.end()); - chi2_n.assign(atom_sa.chi2_n.begin(), atom_sa.chi2_n.end()); - chi2_opt.assign(atom_sa.chi2_opt.begin(), atom_sa.chi2_opt.end()); - - df.assign(atom_sa.df.begin(), atom_sa.df.end()); - } - - // resize number of atoms - void resize(const size_type &new_size, const value_type &value = value_type()) - { - Z.resize(new_size, value); - - r_min.resize(new_size, value); - r_max.resize(new_size, value); - r_0.resize(new_size, value); - r_d.resize(new_size, value); - - r.resize(new_size, value); - r_n.resize(new_size, value); - r_opt.resize(new_size, value); - - chi2.resize(new_size, value); - chi2_n.resize(new_size, value); - chi2_opt.resize(new_size, value); - - df.resize(new_size, value); - - } - - // set atoms - void set_atoms(const size_type &natoms_i, double *atoms_i, double *atoms_min_i, double *atoms_max_i) - { - resize(natoms_i); - - for(auto iatoms = 0; iatoms < size(); iatoms++) - { - Z[iatoms] = static_cast(atoms_i[0*natoms_i + iatoms]); // Atomic number - r[iatoms].x = atoms_i[1*natoms_i + iatoms]; // x-position - r[iatoms].y = atoms_i[2*natoms_i + iatoms]; // y-position - r[iatoms].z = atoms_i[3*natoms_i + iatoms]; // z-position - - r_min[iatoms].x = atoms_min_i[0*natoms_i + iatoms]; // x-position - r_min[iatoms].y = atoms_min_i[1*natoms_i + iatoms]; // y-position - r_min[iatoms].z = atoms_min_i[2*natoms_i + iatoms]; // z-position - - r_max[iatoms].x = atoms_max_i[0*natoms_i + iatoms]; // x-position - r_max[iatoms].y = atoms_max_i[1*natoms_i + iatoms]; // y-position - r_max[iatoms].z = atoms_max_i[2*natoms_i + iatoms]; // z-position - - r_0[iatoms] = r_min[iatoms]; - r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; - - df[iatoms] = 1; - } - } - - // set atoms - void set_atoms(const size_type &natoms_i, double *atoms_i, r3d d_i) - { - resize(natoms_i); - - for(auto iatoms = 0; iatoms < size(); iatoms++) - { - Z[iatoms] = static_cast(atoms_i[0*natoms_i + iatoms]); // Atomic number - - r[iatoms].x = atoms_i[0*natoms_i + iatoms]; // x-position - r[iatoms].y = atoms_i[1*natoms_i + iatoms]; // y-position - r[iatoms].z = atoms_i[2*natoms_i + iatoms]; // z-position - - r_min[iatoms] = r - d_i; - r_max[iatoms] = r + d_i; - - r_0[iatoms] = r_min[iatoms]; - r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; - - df[iatoms] = 1; - } - } - - void set_range(int Z_i, r3d r_min_i, r3d r_max_i) - { - for(auto iatoms = 0; iatoms < size(); iatoms++) - { - Z[iatoms] = Z_i; - - r_min[iatoms] = r_min_i; - r_max[iatoms] = r_max_i; - r_0[iatoms] = r_min[iatoms]; - r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; - df[iatoms] = 1; - } - } - - inline - T norm(const int &iatoms, const r3d &r) - { - auto rd = r_n[iatoms]-r; - return mt::norm(rd); - } - - Vector Z; - - Vector, e_host> r_min; - Vector, e_host> r_max; - Vector, e_host> r_0; - Vector, e_host> r_d; - - Vector, e_host> r; - Vector, e_host> r_n; - Vector, e_host> r_opt; - - Vector chi2; - Vector chi2_n; - Vector chi2_opt; - - Vector df; - }; - - template - struct Atom_Sa - { - public: - using value_type = T; - - T x; - T y; - T R2_max; - T *R2; - T *c3; - T *c2; - T *c1; - T *c0; - - int ix_0; - int ixn; - int iy_0; - int iyn; - - int *iv; - T *v; - - Atom_Sa(): x(0), y(0), R2_max(0), R2(nullptr), c3(nullptr), c2(nullptr), c1(nullptr), - c0(nullptr), ix_0(1), ixn(0), iy_0(0), iyn(0), iv(nullptr), v(nullptr){} - - inline - void set_ix0_ixn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(x, grid_2d.nx, grid_2d.dRx, R_max, grid_2d.pbc_xy, ix_0, ixn); - } - - inline - void set_iy0_iyn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(y, grid_2d.ny, grid_2d.dRy, R_max, grid_2d.pbc_xy, iy_0, iyn); - } - - inline - Grid_BT get_eval_cubic_poly_gridBT() - { - Grid_BT grid_bt; - grid_bt.Blk = dim3((iyn+c_thrnxny-1)/c_thrnxny, (ixn+c_thrnxny-1)/c_thrnxny); - grid_bt.Thr = dim3(c_thrnxny, c_thrnxny); - return grid_bt; - } - }; - - /*****************************Potential**************************/ - template - struct Atom_Vp - { - public: - using value_type = T; - - int charge; - T x; - T y; - T z0h; - T zeh; - bool split; - T occ; - T R2_min; - T R2_max; - T *R2; - T *cl; - T *cnl; - T *c3; - T *c2; - T *c1; - T *c0; - int ix_0; - int nx; - int iy_0; - int ny; - - T R2_tap; - T tap_cf; - - int *iv; - T *v; - - Atom_Vp(): charge(0), x(0), y(0), z0h(0), zeh(0), split(false), occ(1), R2_min(0), R2_max(0), - R2(nullptr), cl(nullptr), cnl(nullptr), c3(nullptr), c2(nullptr), c1(nullptr), - c0(nullptr), ix_0(1), nx(0), iy_0(0), ny(0), R2_tap(0), tap_cf(0), iv(nullptr), v(nullptr){} - - void set_ix0_ixn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(x, grid_2d.nx, grid_2d.dRx, R_max, grid_2d.pbc_xy, ix_0, nx); - } - - void set_iy0_iyn(const Grid_2d &grid_2d, const T &R_max) - { - get_bn(y, grid_2d.ny, grid_2d.dRy, R_max, grid_2d.pbc_xy, iy_0, ny); - } - }; - - /*****************************Atomic Coefficients**************************/ - template - struct Atom_Coef - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - Atom_Coef(): charge(0), tag(0), R_min(0), R_max(0), R_tap(0), tap_cf(0){} - - template - void assign(TAtom_Coef &atom_coef) - { - charge = atom_coef.charge; - tag = atom_coef.tag; - - R_min = atom_coef.R_min; - R_max = atom_coef.R_max; - - R_tap = atom_coef.R_tap; - tap_cf = atom_coef.tap_cf; - - feg.assign(atom_coef.feg); - fxg.assign(atom_coef.fxg); - Pr.assign(atom_coef.Pr); - Vr.assign(atom_coef.Vr); - VR.assign(atom_coef.VR); - - R.assign(atom_coef.R.begin(), atom_coef.R.end()); - R2.assign(atom_coef.R2.begin(), atom_coef.R2.end()); - ciVR.assign(atom_coef.ciVR); - } - - template - Atom_Coef& operator=(TAtom_Coef &atom_coef) - { - assign(atom_coef); - return *this; - } - - // Minimum interaction radius squared - T R2_min() const { return pow(R_min, 2); } - - // Maximum interaction radius squared - T R2_max() const { return pow(R_max, 2); } - - // Tapering radius squared - T R2_tap() const { return pow(R_tap, 2); } - - int charge; // Charge - T tag; // tag - - T R_min; // Minimum interaction radius - T R_max; // Maximum interaction radius - T R_tap; // Tapering radius - T tap_cf; // Tapering cosine factor - - PP_Coef feg; // Electron scattering factor coefficients - PP_Coef fxg; // X-ray scattering factor coefficients - PP_Coef Pr; // Projected_Potential coefficients - PP_Coef Vr; // Projected_Potential coefficients - PP_Coef VR; // Projected potential coefficients - - Vector R; // R - Vector R2; // R2 - CI_Coef ciVR; // Look up table - Projected potential coefficients - - }; - - /********************************Atomic type*******************************/ - template - struct Atom_Type - { - using value_type = T; - using size_type = std::size_t; - - static const eDevice device = dev; - - Atom_Type(): Z(0), m(0), A(0), rn_e(0), rn_c(0), ra_e(0), ra_c(0){} - - template - void assign(TAtom_Type &atom_type) - { - Z = atom_type.Z; - m = atom_type.m; - A = atom_type.A; - rn_e = atom_type.rn_e; - rn_c = atom_type.rn_c; - ra_e = atom_type.ra_e; - ra_c = atom_type.ra_c; - - coef.resize(atom_type.coef.size()); - for(auto i= 0; i - Atom_Type& operator=(TAtom_Type &atom_type) - { - assign(atom_type); - return *this; - } - - int check_charge(const int &charge) const - { - for(auto i= 0; i* feg(const int &charge) - { - int icharge = charge_to_idx(charge); - return &(coef[icharge].feg); - }; - - PP_Coef* fxg(const int &charge) - { - int icharge = charge_to_idx(charge); - return &(coef[icharge].fxg); - }; - - PP_Coef* Pr(const int &charge) - { - int icharge = charge_to_idx(charge); - return &(coef[icharge].Pr); - }; - - PP_Coef* Vr(const int &charge) - { - int icharge = charge_to_idx(charge); - return &(coef[icharge].Vr); - }; - - PP_Coef* VR(const int &charge) - { - int icharge = charge_to_idx(charge); - return &(coef[icharge].VR); - }; - - int Z; // Atomic number - T m; // Atomic mass - int A; // Mass number - T rn_e; // Experimental Nuclear radius - T rn_c; // Calculated Nuclear radius - T ra_e; // Experimental atomic radius - T ra_c; // Calculated atomic radius - - Vector, e_host> coef; // atomic coefficients - }; - - /********************************Scanning**********************************/ - template - struct Scanning - { - public: - using value_type = T; - using size_type = std::size_t; - - eScanning_Type type; // 1: Line, 2: Area, - eGrid_Type grid_type; // 1: regular, 2: quadratic - bool pbc; // periodic boundary conditions - bool spxs; // square pixel size - int ns; // Number of sampling points - int nx; - int ny; - T x0; // Initial scanning position in x - T y0; // Initial scanning in y - T xe; // final scanning position in x - T ye; // final scanning position in y - T dRx; - T dRy; - - Vector x; - Vector y; - Vector r; - - size_type size() const - { - return x.size(); - } - - Scanning(): type(eST_Line), grid_type(eGT_Regular), pbc(false), spxs(true), ns(1), - nx(0), dRx(0), dRy(0), ny(0), x0(0), y0(0), xe(0), ye(0) {}; - - template - void assign(TScanning &scanning) - { - type = scanning.type; - grid_type = scanning.grid_type; - pbc = scanning.pbc; - spxs = scanning.spxs; - ns = scanning.ns; - nx = scanning.nx; - ny = scanning.ny; - x0 = scanning.x0; - y0 = scanning.y0; - xe = scanning.xe; - ye = scanning.ye; - dRx = scanning.dRx; - dRy = scanning.dRy; - - x = scanning.x; - y = scanning.y; - r = scanning.r; - } - - template - Scanning& operator=(TScanning &scanning) - { - assign(scanning); - return *this; - } - - void set_default() - { - type = eST_Line; - grid_type = eGT_Regular; - pbc = false; - spxs = true; - ns = 1; - x0 = y0 = 0; - xe = ye = 0; - } - - int nxy() const { return nx*ny; } - - T Rx(const int &ix) const - { - T x = 0; - switch (grid_type) - { - case eGT_Regular: - { - x = x0 + ix*dRx; - } - break; - case eGT_Quadratic: - { - x = x0 + pow(ix*dRx, 2); - } - break; - } - return x; - } - - T Ry(const int &iy) const - { - T y = 0; - switch (grid_type) - { - case eGT_Regular: - { - y = y0 + iy*dRy; - } - break; - case eGT_Quadratic: - { - y = y0 + pow(iy*dRy, 2); - } - break; - } - return y; - } - - void set_grid() - { - if(ns <= 0) - { - ns = nx = ny = 0; - x.clear(); - y.clear(); - r.clear(); - return; - } - - nx = ny = ns; - if(is_line()) - { - T xu = xe-x0; - T yu = ye-y0; - T ds = sqrt(yu*yu+xu*xu); - T theta = atan2(yu, xu); - T cos_theta = cos(theta); - cos_theta = (isZero(cos_theta))?0:cos_theta; - T sin_theta = sin(theta); - theta = (isZero(theta))?0:theta; - - switch (grid_type) - { - case eGT_Regular: - { - dRx = ds*cos_theta/((pbc)?ns:(ns-1)); - dRy = ds*sin_theta/((pbc)?ns:(ns-1)); - } - break; - case eGT_Quadratic: - { - dRx = sqrt(ds*cos_theta)/((pbc)?ns:(ns-1)); - dRy = sqrt(ds*sin_theta)/((pbc)?ns:(ns-1)); - } - break; - } - - x.resize(ns); - y.resize(ns); - r.resize(ns); - - for(auto i = 0; i < ns; i++) - { - x[i] = Rx(i); - y[i] = Ry(i); - r[i] = sqrt(pow(x[i]-x0, 2)+pow(y[i]-y0, 2)); - } - } - else - { - T xu = xe-x0; - T yu = ye-y0; - if(fabs(xu)>fabs(yu)) - { - dRx = xu/((pbc)?ns:(ns-1)); - dRy = std::copysign(dRx, yu); - ny = int(floor(yu/dRy+Epsilon::rel+0.5)); - ny += (pbc)?0:1; - - if (!spxs) - { - dRy = yu/((pbc)?ny:(ny-1)); - } - } - else - { - dRy = yu/((pbc)?ns:(ns-1)); - dRx = std::copysign(dRy, xu); - nx = int(floor(xu/dRx+Epsilon::rel+0.5)); - nx += (pbc)?0:1; - - if (!spxs) - { - dRx = xu/((pbc)?nx:(nx-1)); - } - } - - x.resize(nxy()); - y.resize(nxy()); - - for(auto ix = 0; ix - struct In_Rad_Schr - { - T E_0; // Acceleration Voltage - ePotential_Type potential_type; // Parameterization type - int n; // Principal quantum number - int nr; // Number of grid points - int natomsM; // Number of atoms - T *atomsM; // atoms - }; - - /*****************************e_device properties**************************/ - struct Device_Properties - { - int id; - std::string name; - int compute_capability; - double total_memory_size; // Mb - double free_memory_size; // Mb - - Device_Properties(): id(0), name(""), compute_capability(0), - total_memory_size(0), free_memory_size(0){} - }; - - /*****************************e_device properties**************************/ - struct Host_Properties - { - int nprocessors; - int nthreads; - double total_memory_size; // Mb - double free_memory_size; // Mb - - Host_Properties(): nprocessors(0), nthreads(0), total_memory_size(0), - free_memory_size(0){} - }; - - /*******************forward declarations********************/ - bool is_gpu_available(); - - int number_of_gpu_available(); - - /************************Host device configuration************************/ - class System_Configuration - { - public: - ePrecision precision; - eDevice device; // eP_float = 1, eP_double = 2 - int cpu_ncores; // Number of Cores CPU - int cpu_nthread; // Number of threads - int gpu_device; // GPU device - int gpu_nstream; // Number of streams - - int nstream; - bool active; - - System_Configuration(): precision(eP_double), device(e_host), cpu_ncores(1), - cpu_nthread(4), gpu_device(0), gpu_nstream(8), nstream(1), active(true){}; - - void validate_parameters() - { - // check precision - if(!(is_float() || is_double())) - { - precision = eP_float; - } - - // check cpu or gpu - if(!(is_host() || is_device())) - { - device = e_host; - } - if(is_device()) - { - #ifdef __CUDACC__ - if(!is_gpu_available()) - { - device = mt::e_host; - n_gpu = 0; - } - else - { - n_gpu = number_of_gpu_available(); - gpu_device = min(max(0, gpu_device), n_gpu-1); - } - #endif - } - - cpu_nthread = max(1, cpu_nthread); - gpu_nstream = max(1, gpu_nstream); - nstream = (is_host())?cpu_nthread:gpu_nstream; - } - - void set_device() - { - if(is_device()) - { - #ifdef __CUDACC__ - cudaSetDevice(gpu_device); - #endif - } - else - { - - device = mt::e_host; - } - } - - int get_device() - { - int idx_dev = -1; - if(is_device()) - { - #ifdef __CUDACC__ - cudaGetDevice(&idx_dev); - #endif - } - - return idx_dev; - } - - bool is_host() const - { - return device == mt::e_host; - } - - bool is_device() const - { - return device == mt::e_device; - } - - bool is_float() const - { - return precision == mt::eP_float; - } - - bool is_double() const - { - return precision == mt::eP_double; - } - - bool is_float_host() const - { - return is_float() && is_host(); - } - - bool is_double_host() const - { - return is_double() && is_host(); - } - - bool is_float_device() const - { - return is_float() && is_device(); - } - - bool is_double_device() const - { - return is_double() && is_device(); - } - - private: - int n_gpu; - }; - - /************************regions*************************/ - template - struct Region - { - public: - using T = typename TVector::value_type; - using size_type = std::size_t; - - TVector Rx; - TVector Ry; - TVector R2; - TVector Ixy; - - T R_max; - T Rx_sf; - T Ry_sf; - T Rxy_sc; - - T Ixy_sf; - T Ixy_sc; - - Region(): Rx_sf(0), Ry_sf(0), Rxy_sc(1), Ixy_sf(0), Ixy_sc(1) - { - } - - void clear() - { - Rx.clear(); - Ry.clear(); - R2.clear(); - Ixy.clear(); - } - - void reserve(const size_type &new_size) - { - Rx.reserve(new_size); - Ry.reserve(new_size); - R2.reserve(new_size); - Ixy.reserve(new_size); - } - - void shrink_to_fit() - { - Rx.shrink_to_fit(); - Ry.shrink_to_fit(); - R2.shrink_to_fit(); - Ixy.shrink_to_fit(); - } - - TVector sft_Ixy(T bg) - { - TVector Ixy_s; - Ixy_s.reserve(Ixy.size()); - - for(auto ixy=0; ixy &grid_2d, TVector &Im_s, T x, T y) - { - TVector v = Ixy; - - T R2_max = pow(R_max, 2); - - r2d p(x, y); - auto range = grid_2d.index_range(p, R_max); - int iv = 0; - for (auto ix = range.ix_0; ix < range.ix_e; ix++) - { - for (auto iy = range.iy_0; iy < range.iy_e; iy++) - { - T r2 = grid_2d.R2(ix, iy, p.x, p.y); - if (r2 < R2_max) - { - v[iv++] -= Im_s[grid_2d.ind_col(ix, iy)]/Ixy_sc; - } - } - } - return v; - } - - TVector sft_Ixy(Grid_2d &grid_2d, TVector &Im_s, T x, T y, T a, T s) - { - TVector v = sub_region_to_Ixy(grid_2d, Im_s, x*Rxy_sc+Rx_sf, y*Rxy_sc+Ry_sf); - - T alpha = 0.5/pow(s, 2); - T r2_l = pow(4.0*s, 2); - for(auto im = 0; im < v.size(); im++) - { - T rx = Rx[im]-x; - T ry = Ry[im]-y; - T r2 = rx*rx+ry*ry; - if(r2 &grid_2d, TVector &Im_s, TVector &x, TVector &y, TVector &A, TVector &S) - { - TVector v = sub_region_to_Ixy(grid_2d, Im_s, x[0]*Rxy_sc+Rx_sf, y[0]*Rxy_sc+Ry_sf); - - for(auto ip = 0; ip < x.size(); ip++) - { - T a = A[ip]; - T b = S[ip]; - T alpha = 0.5/pow(b, 2); - T r2_l = pow(4.0*b, 2); - for(auto im = 0; im < v.size(); im++) - { - T rx = Rx[im]-x[ip]; - T ry = Ry[im]-y[ip]; - T r2 = rx*rx+ry*ry; - if(r2 sft_x_y(T x, T y) const - { - x = sft_Rx(x); - y = sft_Ry(y); - return r2d(x, y); - } - }; - - /***********************************************/ - template - class Gauss_1d{ - public: - using value_type = T; - - T sigma; - T alpha; - T Rx2_l; - T x_c; - T k; - bool b_norm; - - Gauss_1d(): sigma(1), Rx2_l(0), - x_c(0), k(0), b_norm(false){} - - Gauss_1d(T x_c_i, T sigma_i) - { - set_input_data(x_c_i, sigma_i); - } - - Gauss_1d(Border_1d &bd_i, T sigma_i, bool b_norm_i = true) - { - set_input_data(bd_i, sigma_i, b_norm_i); - } - - inline - void set_input_data(T x_c_i, T sigma_i) - { - sigma = sigma_i; - alpha = 0.5/(sigma*sigma); - Rx2_l = 1e+6*sigma; - x_c = x_c_i; - k = 0; - b_norm = false; - } - - inline - void set_input_data(Border_1d &bd_i, T sigma_i, bool b_norm_i = true) - { - sigma = sigma_i; - alpha = 0.5/(sigma*sigma); - Rx2_l = pow(bd_i.lx_wb()/2, 2); - x_c = bd_i.x_c(); - k = exp(-alpha*Rx2_l); - b_norm = b_norm_i; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_norm(const T &Rx2) const - { - return (Rx2<=Rx2_l)?((b_norm)?::fmax(T(0), (this->operator()(Rx2)-k)/(1-k)):this->operator()(Rx2)):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T operator()(const T &Rx2) const - { - return exp(-alpha*Rx2); - } - }; - - template - class Gauss_2d{ - public: - using value_type = T; - - T sigma; - T alpha; - T R2_l; - T x_c; - T y_c; - T k; - bool b_norm; - - Gauss_2d(): sigma(1), R2_l(0), - x_c(0), y_c(0), k(0), b_norm(false){} - - Gauss_2d(T x_c_i, T y_c_i, T sigma_i) - { - set_input_data(x_c_i, y_c_i, sigma_i); - } - - Gauss_2d(Border_2d &bd_i, T sigma_i, bool b_norm_i = true) - { - set_input_data(bd_i, sigma_i, b_norm_i); - } - - inline - void set_input_data(T x_c_i, T y_c_i, T sigma_i) - { - sigma = sigma_i; - alpha = 0.5/(sigma*sigma); - R2_l = 1e+6*sigma; - x_c = x_c_i; - y_c = y_c_i; - k = 0; - b_norm = false; - } - - inline - void set_input_data(Border_2d &bd_i, T sigma_i, bool b_norm_i = true) - { - sigma = sigma_i; - alpha = 0.5/(sigma*sigma); - R2_l = pow(min(bd_i.lx_wb(), bd_i.ly_wb())/2, 2); - x_c = bd_i.x_c(); - y_c = bd_i.y_c(); - k = exp(-alpha*R2_l); - b_norm = b_norm_i; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_norm(const T &R2) const - { - return (R2<=R2_l)?((b_norm)?::fmax(T(0), (this->operator()(R2)-k)/(1-k)):this->operator()(R2)):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T operator()(const T &R2) const - { - return exp(-alpha*R2); - } - }; - - /***********************************************/ - template - class Hanning_1d{ - public: - using value_type = T; - - T lx; - T cx; - T Rx_l; - T x_c; - T k; - bool b_norm; - - Hanning_1d(): lx(1), cx(0), Rx_l(0), - x_c(0), k(0), b_norm(false){} - - Hanning_1d(T x_c_i, T lx_i, T k_i) - { - set_input_data(x_c_i, lx_i, k_i); - } - - Hanning_1d(Border_1d &bd_i, T k_i, bool b_norm_i = true) - { - set_input_data(bd_i, k_i, b_norm_i); - } - - inline - void set_input_data(T x_c_i, T lx_i, T k_i) - { - lx = lx_i; - cx = c_Pi/lx; - Rx_l = lx/2; - x_c = x_c_i; - k = (k_i>1)?1.0/k_i:pow(sin(0.5*c_Pi*k_i), 2); - b_norm = false; - } - - inline - void set_input_data(Border_1d &bd_i, T k_i, bool b_norm_i = true) - { - lx = bd_i.lx_wb(); - cx = c_Pi/lx; - Rx_l = lx/2; - x_c = bd_i.x_c(); - k = (k_i>1)?1.0/k_i:pow(sin(0.5*c_Pi*k_i), 2); - b_norm = b_norm_i; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_norm(const T &Rx) const - { - T v = (fabs(Rx)<=Rx_l)?((b_norm)?::fmax(T(0), this->operator()(Rx)):this->operator()(Rx)):0; - return (v>k)?1.0:v/k; - } - - DEVICE_CALLABLE FORCE_INLINE - T operator()(const T &Rx) const - { - return ::square(cos(cx*Rx)); - } - }; - - template - class Hanning_2d{ - public: - using value_type = T; - - T lx; - T ly; - T cxy; - T R_l; - T x_c; - T y_c; - T k; - bool b_norm; - - Hanning_2d(): lx(1), ly(1), cxy(0), R_l(0), - x_c(0), y_c(0), k(0), b_norm(false){} - - Hanning_2d(T x_c_i, T y_c_i, T ly_i, T lx_i, T k_i) - { - set_input_data(x_c_i, y_c_i, lx_i, ly_i, k_i); - } - - Hanning_2d(Border_2d &bd_i, T k_i, bool b_norm_i = true) - { - set_input_data(bd_i, k_i, b_norm_i); - } - - inline - void set_input_data(T x_c_i, T y_c_i, T ly_i, T lx_i, T k_i) - { - lx = lx_i; - ly = lx_i; - cxy = c_Pi/min(lx, ly); - R_l = min(lx, ly)/2; - x_c = x_c_i; - y_c = y_c_i; - k = (k_i>1)?1.0/k_i:pow(sin(0.5*c_Pi*k_i), 2); - b_norm = false; - } - - inline - void set_input_data(Border_2d &bd_i, T k_i, bool b_norm_i = true) - { - lx = bd_i.lx_wb(); - ly = bd_i.ly_wb(); - cxy = c_Pi/min(lx, ly); - R_l = min(lx, ly)/2; - x_c = bd_i.x_c(); - y_c = bd_i.y_c(); - k = (k_i>1)?1.0/k_i:pow(sin(0.5*c_Pi*k_i), 2); - b_norm = b_norm_i; - } - - DEVICE_CALLABLE FORCE_INLINE - T eval_norm(const T &R) const - { - T v = (fabs(R)<=R_l)?((b_norm)?::fmax(T(0), this->operator()(R)):this->operator()(R)):0; - return (v>k)?1.0:v/k; - } - - DEVICE_CALLABLE FORCE_INLINE - T operator()(const T &R) const - { - return ::square(cos(cxy*R)); - } - }; - - /***********************************************/ - template - class Butterworth_1d{ - public: - using value_type = T; - - T radius; - T R02; - T Rx2_l; - T x_c; - T k; - int n; - bool b_norm; - - Butterworth_1d(): radius(0), R02(0), Rx2_l(0), - x_c(0), k(0), n(16), b_norm(false){} - - Butterworth_1d(T x_c_i, T radius_i, int n_i) - { - set_input_data(x_c_i, radius_i, n_i); - } - - Butterworth_1d(Border_1d &bd_i, T radius_i, int n_i, bool b_norm_i = true) - { - set_input_data(bd_i, radius_i, n_i, b_norm_i); - } - - inline - void set_input_data(T x_c_i, T radius_i, int n_i) - { - n = n_i; - radius = radius_i; - R02 = ::square(radius); - Rx2_l = 1e+6*radius; - x_c = x_c_i; - k = 0; - b_norm = false; - } - - inline - void set_input_data(Border_1d &bd_i, T radius_i, int n_i, bool b_norm_i = true) - { - n = n_i; - radius = radius_i; - R02 = pow(radius, 2); - Rx2_l = pow(bd_i.lx_wb()/2, 2); - x_c = bd_i.x_c(); - k = 1.0/(1.0+pow(Rx2_l/R02, n)); - b_norm = b_norm_i; - } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T eval_norm(const T &Rx2) const - { - return (Rx2<=Rx2_l)?((b_norm)?::fmax(T(0), (this->operator()(Rx2)-k)/(1-k)):this->operator()(Rx2)):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T operator()(const T &Rx2) const - { - return 1.0/(1.0+pow(Rx2/R02, n)); - } - }; - - template - class Butterworth_2d{ - public: - using value_type = T; - - T radius; - T R02; - T R2_l; - T x_c; - T y_c; - T k; - int n; - bool b_norm; - - Butterworth_2d(): radius(0), R02(0), R2_l(0), - x_c(0), y_c(0), k(0), n(16), b_norm(false){} - - Butterworth_2d(T x_c_i, T y_c_i, T radius_i, int n_i) - { - set_input_data(x_c_i, y_c_i, radius_i, n_i); - } - - Butterworth_2d(Border_2d &bd_i, T radius_i, int n_i, bool b_norm_i = true) - { - set_input_data(bd_i, radius_i, n_i, b_norm_i); - } - - inline - void set_input_data(T x_c_i, T y_c_i, T radius_i, int n_i) - { - n = n_i; - radius = radius_i; - R02 = pow(radius, 2); - R2_l = 1e+6*radius; - x_c = x_c_i; - y_c = y_c_i; - k = 0; - b_norm = false; - } - - inline - void set_input_data(Border_2d &bd_i, T radius_i, int n_i, bool b_norm_i = true) - { - n = n_i; - radius = radius_i; - R02 = pow(radius, 2); - R2_l = pow(min(bd_i.lx_wb(), bd_i.ly_wb())/2, 2); - x_c = bd_i.x_c(); - y_c = bd_i.y_c(); - k = 1.0/(1.0+pow(R2_l/R02, n)); - b_norm = b_norm_i; - } - - /*********************************************************/ - DEVICE_CALLABLE FORCE_INLINE - T eval_norm(const T &R2) const - { - return (R2<=R2_l)?((b_norm)?::fmax(T(0), (this->operator()(R2)-k)/(1-k)):this->operator()(R2)):0; - } - - DEVICE_CALLABLE FORCE_INLINE - T operator()(const T &R2) const - { - return (1.0/(1.0+pow(R2/R02, n))); - } - }; - - /********Affine parameters shx and scy*********/ - template - struct Afp_2 - { - r2d f; - r2d ds; - T chi2; - - Afp_2():f(T(0), T(1)), ds(T(0), T(0)), chi2(0){} - - Afp_2(const r2d &f_i, const r2d &ds_i, const T &chi2_i):f(f_i), ds(ds_i), chi2(chi2_i){} - - template - Afp_2& operator=(TAfp_2 &afp_2) - { - f = afp_2.f; - ds = afp_2.ds; - chi2 = afp_2.chi2; - - return *this; - } - }; - -} // namespace mt - -#endif \ No newline at end of file +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "const_enum.h" +#include "type_traits_gen.h" +#include "math_mt.h" +#include "r_2d.h" +#include "r_3d.h" +#include "fcns_cgpu_gen.h" +#include "vctr_cpu.h" +#include "grid_2d.h" + +namespace mt +{ + /********************************* 2d array of vectors *********************************/ + template + struct AV_2d + { + using value_type = Value_type; + + AV_2d():m_dim_0(0), m_dim_1(0), m_size(0), m_size_a(0), m_d_size(0) {} + + AV_2d(dt_int32 rows, dt_int32 cols, dt_int32 d_size, dt_int32 size_a=-1) + { + set_size(rows, cols, d_size, size_a); + } + + void clear() + { + for(auto ik = 0; ik < m_size_a; ik++) + { + m_data[ik].clear(); + } + m_data.clear(); + } + + void shrink_to_fit() + { + for(auto ik = 0; ik < m_size_a; ik++) + { + m_data[ik].shrink_to_fit(); + } + m_data.shrink_to_fit(); + } + + void clear_shrink_to_fit() + { + clear(); + shrink_to_fit(); + } + + void set_size(dt_int32 dim_0, dt_int32 dim_1, dt_int32 d_size, dt_int32 size_a=-1) + { + m_dim_0 = dim_0; + m_dim_1 = dim_1; + m_size = m_dim_0*m_dim_1; + m_size_a = (size_a<0)?m_size:min(m_size, size_a); + m_d_size = max(0, d_size); + + m_data.resize(m_size); + + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + m_data[ik].resize(m_d_size); + } + } + } + + dt_bool sub_2_ind(const dt_int32 ix_0, const dt_int32 ix_1) const + { + return (ix_0 + m_dim_0*ix_1); + } + + dt_bool exists(const dt_int32 ix_0, const dt_int32 ix_1) const + { + return (sub_2_ind(ix_0, ix_1) < m_size_a); + } + + template + void assign(TAV_2d &av_2d) + { + set_size(av_2d.dim_0(), av_2d.dim_1(), av_2d.d_size(), av_2d.size_a()); + + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + thrust::copy(av_2d[ik].begin(), av_2d[ik].end(), m_data[ik].begin()); + } + } + } + + template + void cpy_allow_data(TAV_2d &av_2d) + { + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + thrust::copy(m_data[ik].begin(), m_data[ik].end(), av_2d[ik].begin()); + } + } + } + + template + AV_2d& operator=(const TAV_2d &av_2d) + { + assign(av_2d); + return *this; + } + + CGPU_EXEC_INL + TVctr& operator[](const dt_int32 idx) { return m_data[idx]; } + + CGPU_EXEC_INL + const TVctr& operator[](const dt_int32 idx) const { return m_data[idx]; } + + TVctr& operator()(const dt_int32 ix_0, const dt_int32 ix_1) + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + const TVctr& operator()(const dt_int32 ix_0, const dt_int32 ix_1) const + { + return m_data[sub_2_ind(ix_0, ix_1)]; + } + + value_type& operator()(const dt_int32 ix_0, const dt_int32 ix_1, const dt_int32 id) + { + return m_data[sub_2_ind(ix_0, ix_1)][id]; + } + + const value_type& operator()(const dt_int32 ix_0, const dt_int32 ix_1, const dt_int32 id) const + { + return m_data[sub_2_ind(ix_0, ix_1)][id]; + } + + dt_int32 dim_0() const + { + return m_dim_0; + } + + dt_int32 dim_1() const + { + return m_dim_1; + } + + dt_int32 size() const + { + return m_size; + } + + dt_int32 size_a() const + { + return m_size_a; + } + + dt_int32 d_size() const + { + return m_d_size; + } + + void fill(value_type value) + { + if (m_d_size>0) + { + for(auto ik = 0; ik < m_size_a; ik++) + { + thrust::fill(m_data[ik].begin(), m_data[ik].end(), value); + } + } + } + + dt_int32 m_dim_0; + dt_int32 m_dim_1; + dt_int32 m_size; + dt_int32 m_size_a; + dt_int32 m_d_size; + Vctr_cpu m_data; + }; + + /***************************** atoms for simulated annealing ***************************/ + template + class Atom_Data_Sa{ + public: + using value_type = T; + using size_type = dt_uint64; + + size_type size() const + { + return Z.size(); + } + + dt_bool empty() const + { + return size() == 0; + } + + template + void assign(TAtom_SA &atom_sa) + { + Z.assign(atom_sa.Z.begin(), atom_sa.Z.end()); + + r_min.assign(atom_sa.r_min.begin(), atom_sa.r_min.end()); + r_max.assign(atom_sa.r_max.begin(), atom_sa.r_max.end()); + r_0.assign(atom_sa.r_0.begin(), atom_sa.r_0.end()); + r_d.assign(atom_sa.r_d.begin(), atom_sa.r_d.end()); + + r.assign(atom_sa.r.begin(), atom_sa.r.end()); + r_n.assign(atom_sa.r_n.begin(), atom_sa.r_n.end()); + r_opt.assign(atom_sa.r_opt.begin(), atom_sa.r_opt.end()); + + chi2.assign(atom_sa.chi2.begin(), atom_sa.chi2.end()); + chi2_n.assign(atom_sa.chi2_n.begin(), atom_sa.chi2_n.end()); + chi2_opt.assign(atom_sa.chi2_opt.begin(), atom_sa.chi2_opt.end()); + + df.assign(atom_sa.df.begin(), atom_sa.df.end()); + } + + // resize number of atoms + void resize(const size_type& new_size, const value_type& value = value_type()) + { + Z.resize(new_size, value); + + r_min.resize(new_size, value); + r_max.resize(new_size, value); + r_0.resize(new_size, value); + r_d.resize(new_size, value); + + r.resize(new_size, value); + r_n.resize(new_size, value); + r_opt.resize(new_size, value); + + chi2.resize(new_size, value); + chi2_n.resize(new_size, value); + chi2_opt.resize(new_size, value); + + df.resize(new_size, value); + + } + + // set atoms + void set_ptc(const size_type& natoms_i, dt_float64 *atoms_i, dt_float64 *atoms_min_i, dt_float64 *atoms_max_i) + { + resize(natoms_i); + + for(auto iatoms = 0; iatoms < size(); iatoms++) + { + Z[iatoms] = static_cast(atoms_i[0*natoms_i + iatoms]); // atomic number + r[iatoms].x = atoms_i[1*natoms_i + iatoms]; // x-position + r[iatoms].y = atoms_i[2*natoms_i + iatoms]; // y-position + r[iatoms].z = atoms_i[3*natoms_i + iatoms]; // z-position + + r_min[iatoms].x = atoms_min_i[0*natoms_i + iatoms]; // x-position + r_min[iatoms].y = atoms_min_i[1*natoms_i + iatoms]; // y-position + r_min[iatoms].z = atoms_min_i[2*natoms_i + iatoms]; // z-position + + r_max[iatoms].x = atoms_max_i[0*natoms_i + iatoms]; // x-position + r_max[iatoms].y = atoms_max_i[1*natoms_i + iatoms]; // y-position + r_max[iatoms].z = atoms_max_i[2*natoms_i + iatoms]; // z-position + + r_0[iatoms] = r_min[iatoms]; + r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; + + df[iatoms] = 1; + } + } + + // set atoms + void set_ptc(const size_type& natoms_i, dt_float64 *atoms_i, R_3d d_i) + { + resize(natoms_i); + + for(auto iatoms = 0; iatoms < size(); iatoms++) + { + Z[iatoms] = static_cast(atoms_i[0*natoms_i + iatoms]); // atomic number + + r[iatoms].x = atoms_i[0*natoms_i + iatoms]; // x-position + r[iatoms].y = atoms_i[1*natoms_i + iatoms]; // y-position + r[iatoms].z = atoms_i[2*natoms_i + iatoms]; // z-position + + r_min[iatoms] = r - d_i; + r_max[iatoms] = r + d_i; + + r_0[iatoms] = r_min[iatoms]; + r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; + + df[iatoms] = 1; + } + } + + void set_range(dt_int32 Z_i, R_3d r_min_i, R_3d r_max_i) + { + for(auto iatoms = 0; iatoms < size(); iatoms++) + { + Z[iatoms] = Z_i; + + r_min[iatoms] = r_min_i; + r_max[iatoms] = r_max_i; + r_0[iatoms] = r_min[iatoms]; + r_d[iatoms] = r_max[iatoms]-r_min[iatoms]; + df[iatoms] = 1; + } + } + + inline + T norm_2(const dt_int32& iatoms, const R_3d& r) + { + auto rd = r_n[iatoms]-r; + return mt::norm_2(rd); + } + + Vctr Z; + + Vctr, edev_cpu> r_min; + Vctr, edev_cpu> r_max; + Vctr, edev_cpu> r_0; + Vctr, edev_cpu> r_d; + + Vctr, edev_cpu> r; + Vctr, edev_cpu> r_n; + Vctr, edev_cpu> r_opt; + + Vctr chi2; + Vctr chi2_n; + Vctr chi2_opt; + + Vctr df; + }; + + template + struct Atom_Sa + { + public: + using value_type = T; + + T x; + T y; + T R2_max; + T* r2; + T* c3; + T* c2; + T* c1; + T* c0; + + dt_int32 ix_0; + dt_int32 ix_n; + dt_int32 iy_0; + dt_int32 iy_n; + + dt_int32 *iv; + T* v; + + Atom_Sa(): x(0), y(0), R2_max(0), r2(nullptr), c3(nullptr), c2(nullptr), c1(nullptr), + c0(nullptr), ix_0(1), ix_n(0), iy_0(0), iy_n(0), iv(nullptr), v(nullptr) {} + + inline + void set_ix0_ixn(const Grid_2d& grid_2d, const T& r_max) + { + fcn_get_idx_0_idx_n(x, r_max, grid_2d.drx, grid_2d.pbc_x, grid_2d.nx, ix_0, ix_n); + } + + inline + void set_iy0_iyn(const Grid_2d& grid_2d, const T& r_max) + { + fcn_get_idx_0_idx_n(y, r_max, grid_2d.dry, grid_2d.pbc_y, grid_2d.ny, iy_0, iy_n); + } + + #ifdef __CUDACC__ + inline + D_Grid_Blk get_eval_cubic_poly_gridBT() + { + D_Grid_Blk d_grid_blk; + d_grid_blk.grid = dim3((iy_n+c_thr_2d_x-1)/c_thr_2d_x, (ix_n+c_thr_2d_y-1)/c_thr_2d_y); + d_grid_blk.blk = dim3(c_thr_2d_x, c_thr_2d_y); + return d_grid_blk; + } + #endif + }; + + /************************* affine parameters for shx and scy ***************************/ + template + struct Atp_1 + { + R_2d f; + R_2d tr; + T chi2; + + Atp_1():f(T(0), T(1)), tr(T(0), T(0)), chi2(0) {} + + Atp_1(const R_2d& f_i, const R_2d& tr_i, const T& chi2_i): f(f_i), tr(tr_i), chi2(chi2_i) {} + + template + Atp_1& operator=(TAtp_1 &atp_1) + { + f = atp_1.f; + tr = atp_1.tr; + chi2 = atp_1.chi2; + + return *this; + } + }; + + /*************************** affine parameters for rotation ****************************/ + template + struct Atp_2 + { + T theta; + R_2d tr; + T chi2; + + Atp_2():theta(T(0)), tr(T(0), T(0)), chi2(0) {} + + Atp_2(const T& theta_i, const R_2d& tr_i, const T& chi2_i): theta(theta_i), tr(tr_i), chi2(chi2_i) {} + + template + Atp_2& operator=(TAtp_2 &atp_2) + { + theta = atp_2.theta; + tr = atp_2.tr; + chi2 = atp_2.chi2; + + return *this; + } + }; +} \ No newline at end of file diff --git a/src/types_mt.cuh b/src/types_mt.cuh new file mode 100755 index 00000000..5c40c1e6 --- /dev/null +++ b/src/types_mt.cuh @@ -0,0 +1,332 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef TYPES_MT_H + #define TYPES_MT_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + #include + #include + #include + #include + + #include "const_enum_mt.cuh" + #include "math_mt.h" + #include "type_traits_gen.h" + #include "fcns_cgpu_gen.h" + #include "r_2d.h" + #include "r_3d.h" + #include "particles.cuh" + #include "types.cuh" + + namespace mt + { + /******************* spec layer information *********************/ + template + class Spec_Lay_Info + { + public: + R_3d bs; // box size + R_3d r_0; // initial position + dt_int32 tag; // tag + eSpec_Lay_Pos type; // specimen layer type + T sli_thick; // slice thickness + + Spec_Lay_Info(): bs(), r_0(), tag(c_dflt_tag), type(eslp_none), sli_thick(2) {}; + + Spec_Lay_Info(const R_3d& bs, R_3d r_0 = R_3d(), dt_int32 tag = c_dflt_tag, + eSpec_Lay_Pos type = eslp_none, T sli_thick = 2.0): bs(bs), r_0(r_0), tag(tag), type(type), sli_thick(sli_thick) {}; + + Spec_Lay_Info& operator=(Spec_Lay_Info &spec_lay_info) + { + if (this != &spec_lay_info) + { + bs = spec_lay_info.bs; + r_0 = spec_lay_info.r_0; + sli_thick = spec_lay_info.sli_thick; + tag = spec_lay_info.tag; + type = spec_lay_info.type; + } + + return *this; + } + + template + Spec_Lay_Info& operator=(Spec_Lay_Info &spec_lay_info) + { + assign(spec_lay_info); + + return *this; + } + + template + void assign(const Spec_Lay_Info& spec_lay_info) + { + if ((void*)this != (void*)&spec_lay_info) + { + bs = spec_lay_info.bs; + r_0 = spec_lay_info.r_0; + r_e = spec_lay_info.r_e; + sli_thick = T(spec_lay_info.sli_thick); + tag = spec_lay_info.tag; + type = spec_lay_info.type; + } + } + + R_3d r_e() const + { + return r_0 + bs; + }; + + T z_e() const + { + return r_0.z + bs.z; + }; + + dt_bool is_spec_lay_top() const + { + return is_spec_lay_top(type); + }; + + dt_bool is_spec_lay_bottom() const + { + return is_spec_lay_bottom(type); + }; + + dt_bool is_spec_lay_middle() const + { + return is_spec_lay_middle(type); + }; + + dt_bool is_spec_lay_user_def() const + { + return is_spec_lay_user_def(type); + }; + + void set_region(Ptc_Atom& atoms) + { + if (bs.z<1e-4) + { + tag = 0; + return; + } + + dt_int32 f_region = 0; + dt_int32 c_region = 0; + const T z_0 = r_0.z; + const T z_e = z_e(); + for(auto iatoms = 0; iatoms < atoms.size(); iatoms++) + { + auto z = atoms.z[iatoms]; + if ((z_0(::round(T(f_region)/T(c_region))); + } + }; + + template + using Vctr_Spec_Lay_Info = Vctr_std>; + + + /**************************** thickness ******************************/ + template + struct Thick + { + Thick(): z(0), z_zero_def_plane(0), z_back_prop(0), + islice(0), iatom_e(0) {} + + T z; // z + T z_zero_def_plane; // z: Zero defocus + T z_back_prop; // z: Back propagation + + dt_int32 islice; // slice position + dt_int32 iatom_e; // Last atom index + }; + + /************************** stem fetector ****************************/ + template + struct Detector + { + using value_type = T; + using size_type = dt_int32; + + static const eDev device = Dev; + + Detector(): type(mt::edt_circular) {} + + size_type size() const + { + size_type size_out = 0; + switch (type) + { + case mt::edt_circular: + { + size_out = g_inner.size(); + } + break; + case mt::edt_radial: + { + size_out = fx.size(); + } + break; + case mt::edt_matrix: + { + size_out = fR.size(); + } + break; + } + return size_out; + } + + void clear() + { + g_inner.clear(); + g_outer.clear(); + fx.clear(); + fR.clear(); + fcn.clear(); + grid_1d.clear(); + grid_2d.clear(); + } + + void resize(const size_type& new_size) + { + switch (type) + { + case mt::edt_circular: + { + g_inner.resize(new_size); + g_outer.resize(new_size); + } + break; + case mt::edt_radial: + { + fx.resize(new_size); + fcn.resize(new_size); + grid_1d.resize(new_size); + } + break; + case mt::edt_matrix: + { + fR.resize(new_size); + fcn.resize(new_size); + grid_2d.resize(new_size); + } + break; + } + } + + template + void assign(TDetector &detector) + { + type = detector.type; + g_inner.assign(detector.g_inner.begin(), detector.g_inner.end()); + g_outer.assign(detector.g_outer.begin(), detector.g_outer.end()); + + fx.resize(detector.fx.size()); + for(auto i = 0; i + Detector& operator=(TDetector &detector) + { + assign(detector); + return *this; + } + + dt_bool is_detector_circular() const + { + return mt::is_detector_circular(type); + } + + dt_bool is_detector_radial() const + { + return mt::is_detector_radial(type); + } + + dt_bool is_detector_matrix() const + { + return mt::is_detector_matrix(type); + } + + eDetector_Typ type; // mt::edt_circular = 1, mt::edt_radial = 2, mt::edt_matrix = 3 + Vctr g_inner; // Inner aperture Ang^-1 + Vctr g_outer; // Outer aperture Ang^-1 + Vctr, edev_cpu> fx; // radial sensitivity value + Vctr, edev_cpu> fR; // 2D sensitivity value + std::vector> grid_1d; // grid_1d + std::vector> grid_2d; // grid_2d + std::vector fcn; // file names + }; + + /************************* stem intensity ****************************/ + template + struct Det_Int + { + using value_type = typename TVctr::value_type; + using size_type = dt_int32; + + static const eDev device = edev_cpu; + + size_type size() const + { + return image.size(); + } + + Vctr image; + }; + + /******************** radial schrodinger equation ********************/ + template + class In_Rad_Schr + { + public: + T E_0; // Acceleration Voltage + eAtomic_Pot_Parm_Typ atomic_pot_parm_typ; // Parameterization type + dt_int32 n; // Principal quantum number + dt_int32 nr; // number of grid points + dt_int32 natomsM; // number of atoms + T* atomsM; // atoms + }; + } + +#endif \ No newline at end of file diff --git a/src/vctr_cpu.h b/src/vctr_cpu.h new file mode 100755 index 00000000..39c93a8b --- /dev/null +++ b/src/vctr_cpu.h @@ -0,0 +1,506 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is destroy software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include + +#include "memcpy.cuh" +#include "r_2d.h" +#include "r_3d.h" +#include "mx_2x2.h" +#include "mx_3x3.h" + +#include "pvctr.h" + +#ifdef __CUDACC__ + #include + #include + #include +#endif + +/* vector forward declaration */ +namespace mt +{ +#ifndef VCTR_DEC + #define VCTR_DEC + template class Vctr; + + template class pVctr; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Vctr_std = std::vector; + + template + using Vctr_cpu = Vctr; + + /***************************************************************************************/ + using Vctr_uint32_cpu = Vctr_cpu; + + using Vctr_int32_cpu = Vctr_cpu; + + using Vctr_uint64_cpu = Vctr_cpu; + + using Vctr_int64_cpu = Vctr_cpu; + + /***************************************************************************************/ + template + using Vctr_r_2d = Vctr, Dev>; + + template + using Vctr_r_2d_cpu = Vctr, edev_cpu>; + + /***************************************************************************************/ + template + using Vctr_r_3d = Vctr, Dev>; + + template + using Vctr_r_3d_cpu = Vctr, edev_cpu>; + + /***************************************************************************************/ + template + using Vctr_Mx_2x2 = Vctr, Dev>; + + template + using Vctr_Mx_2x2_cpu = Vctr, edev_cpu>; + + /***************************************************************************************/ + template + using Vctr_Mx_3x3 = Vctr, Dev>; + + template + using Vctr_Mx_3x3_cpu = Vctr, edev_cpu>; +} + +/* cpu vector */ +namespace mt +{ + template + class Vctr + { + public: + using value_type = T; + using size_type = dt_int64; + static const eDev device = edev_cpu; + + mutable T* m_data; + size_type m_s0; + size_type m_s1; + size_type m_s2; + size_type m_s3; + size_type m_size; + size_type m_capacity; + + size_type m_pitch_s1; + size_type m_pitch_s2; + size_type m_pitch_s3; + + /************************************* constructors ************************************/ + explicit Vctr(); + + Vctr(const dt_init_list_f64& data); + + Vctr(size_type s0); + + Vctr(size_type s0, const T& value); + + explicit Vctr(const dt_shape_st& shape); + + explicit Vctr(const dt_shape_st& shape, const T& value); + + /* copy constructor */ + Vctr(const Vctr& vctr); + + /* Move constructor */ + Vctr(Vctr&& vctr); + + /* converting constructor */ + template + Vctr(const Vctr& vctr); + + template + Vctr(U* first, U* last); + + template > + Vctr(U *p, dt_int64 n_p, dt_int64 icol=0); + + template + Vctr(const std::vector& vctr); + + // from cpu pVctr to Vctr + template + Vctr(const pVctr& pvctr); + +#ifdef __CUDACC__ + template + Vctr(const Vctr& vctr); + + template + Vctr(const thrust::host_vector& vctr); + + template + Vctr(const thrust::device_vector& vctr); + + // from gpu pVctr to Vctr + template + Vctr(const pVctr& pvctr); +#endif + ~Vctr(); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Vctr& operator=(const Vctr& vctr); + + /* Move assignment operator */ + Vctr& operator=(Vctr&& vctr); + + /* converting assignment operator */ + template + Vctr& operator=(const Vctr& vctr); + + template + Vctr& operator=(const std::vector& vctr); + +#ifdef __CUDACC__ + template + Vctr& operator=(const Vctr& vctr); + + template + Vctr& operator=(const thrust::host_vector& vctr); + + template + Vctr& operator=(const thrust::device_vector& vctr); +#endif + + template + void assign(const Vctr& vctr, U* pvctr_cpu = nullptr); + + template + void assign(U* first, U* last); + + // from cpu pVctr to Vctr + template + void assign(const pVctr& pvctr); + +#ifdef __CUDACC__ + template + void assign(const thrust::device_ptr& first, const thrust::device_ptr& last, U* pvctr_cpu = nullptr); + + // from gpu pVctr to Vctr + template + void assign(const pVctr& pvctr); +#endif + + template + void assign(const std::vector& vctr, U* pvctr_cpu = nullptr); + +#ifdef __CUDACC__ + template + void assign(const Vctr& vctr, U* pvctr_cpu = nullptr); + + template + void assign(const thrust::host_vector& vctr, U* pvctr_cpu = nullptr); + + template + void assign(const thrust::device_vector& vctr, U* pvctr_cpu = nullptr); +#endif + /**************** user define conversion operators *******************/ + pVctr_cpu_32 ptr_32() const; + + pVctr_cpu_64 ptr_64() const; + + operator pVctr_cpu_32() const; + + operator pVctr_cpu_64() const; + + /* user define conversion */ + operator std::vector() const; + + /* user define conversion in which T is the complemented precision */ + template > + operator std::vector() const; + +#ifdef __CUDACC__ + /* user define conversion to output type std::vector> */ + template > + operator std::vector>() const; + + /* user define conversion to output type std::vector> */ + template > + operator std::vector>() const; + + /***************************************************************************************/ + /* user define conversion */ + operator thrust::host_vector() const; + + /* user define conversion in which T is the complemented precision */ + template > + operator thrust::host_vector() const; + + /* user define conversion to output type thrust::host_vector> */ + template > + operator thrust::host_vector>() const; + + /* user define conversion to output type thrust::host_vector> */ + template > + operator thrust::host_vector>() const; + + /***************************************************************************************/ + /* user define conversion */ + operator thrust::device_vector() const; + + /* user define conversion in which T is the complemented precision */ + template > + operator thrust::device_vector() const; +#endif + /***************************************************************************************/ + template + void cpy_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr); + + template + void cpy_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr); + +#ifdef __CUDACC__ + template + void cpy_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr); + + template + void cpy_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr); +#endif + + /***************************************************************************************/ + template > + void cpy_real_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr); + + template > + void cpy_real_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr); + +#ifdef __CUDACC__ + template > + void cpy_real_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr); + + template > + void cpy_real_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr); +#endif + + /***************************************************************************************/ + template > + void cpy_imag_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr); + + template > + void cpy_imag_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr); + +#ifdef __CUDACC__ + template > + void cpy_imag_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr); + + template > + void cpy_imag_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr); +#endif + + /***************************************************************************************/ + template > + void set_pos_from_cpu_ptr(U *p, size_type n_p, dt_int64 icol=0); + + template > + void cpy_pos_to_cpu_ptr(U *p, size_type icol=0); + + /***************************************************************************************/ + void resize(const dt_shape_st& shape); + + void resize(const dt_shape_st& shape, const T& value); + + void reserve(const dt_shape_st& shape); + + void shrink_to_fit(); + + template + void push_back(const U& val); + + template + void push_back(const Vctr& vctr); + + void pop_back(); + + void fill(T val); + + /***************************************************************************************/ + size_type s0() const; + + size_type s1() const; + + size_type s2() const; + + size_type s3() const; + + dt_int32 s0_32() const; + + dt_int32 s1_32() const; + + dt_int32 s2_32() const; + + dt_int32 s3_32() const; + + dt_int64 s0_64() const; + + dt_int64 s1_64() const; + + dt_int64 s2_64() const; + + dt_int64 s3_64() const; + + size_type s0h() const; + + size_type s1h() const; + + size_type s2h() const; + + size_type s3h() const; + + dt_shape_st shape() const; + + dt_shape_st shape_2d_trs() const; + + size_type shape_size() const; + + size_type pitch_s1() const; + + size_type pitch_s2() const; + + size_type pitch_s3() const; + + size_type size() const; + + dt_int32 size_32() const; + + dt_int64 size_64() const; + + iGrid_1d igrid_1d() const; + + iGrid_2d igrid_2d() const; + + iGrid_3d igrid_3d() const; + + iGrid_1d_64 igrid_1d_64() const; + + iGrid_2d_64 igrid_2d_64() const; + + iGrid_3d_64 igrid_3d_64() const; + + size_type capacity() const; + + dt_bool empty() const; + + dt_bool is_1d() const; + + void clear(); + + void clear_shrink_to_fit(); + + size_type sub_2_ind(const size_type& ix_0) const; + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1) const; + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const; + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const; + + T& operator[](const size_type& iy); + + const T& operator[](const size_type& iy) const; + + T& operator()(const size_type& iy); + + const T& operator()(const size_type& iy) const; + + T& operator()(const size_type& ix_0, const size_type& ix_1); + + const T& operator()(const size_type& ix_0, const size_type& ix_1) const; + + T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2); + + const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const; + + T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3); + + const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const; + + T* begin(); + + const T* begin() const; + + T* end(); + + const T* end() const; + + T* data(); + + const T* data() const; + + template + U data_cast(); + + template + const U data_cast() const; + + T& front(); + + const T& front() const; + + T& back(); + + const T& back() const; + + // set shape + void set_shape(const dt_shape_st& shape); + + void trs_shape_2d(); + + template + void set_shape(const Vctr& vctr, dt_bool bb_size = true); + + #ifdef __CUDACC__ + FCNS_DEF_GPU_GRID_BLK_VCTR; + #endif + + private: + + void set_picth(); + + void set_capacity(size_type size_r); + + void set_shape_cstr(dt_shape_st& shape); + + // reallocate and copy memory + void allocate(dt_shape_st shape, dt_bool bb_reserve=false); + + // destroy memory on the device + void init(); + + // destroy memory on the device + void destroy(); + }; +} + + +#include "detail/vctr_cpu.inl" \ No newline at end of file diff --git a/src/vctr_gpu.h b/src/vctr_gpu.h new file mode 100755 index 00000000..cbdf22c7 --- /dev/null +++ b/src/vctr_gpu.h @@ -0,0 +1,464 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is destroy software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "vctr_cpu.h" + +/* vector forward declaration */ +namespace mt +{ +#ifndef VCTR_DEC + #define VCTR_DEC + template class Vctr; + + template class pVctr; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Vctr_gpu = Vctr; + + /***************************************************************************************/ + using Vctr_uint32_gpu = Vctr_gpu; + + using Vctr_int32_gpu = Vctr_gpu; + + using Vctr_uint64_gpu = Vctr_gpu; + + using Vctr_int64_gpu = Vctr_gpu; + + /***************************************************************************************/ + template + using Vctr_r_2d_gpu = Vctr, edev_gpu>; + + /***************************************************************************************/ + template + using Vctr_r_3d_gpu = Vctr, edev_gpu>; + + /***************************************************************************************/ + template + using Vctr_Mx_2x2_gpu = Vctr, edev_gpu>; + + /***************************************************************************************/ + template + using Vctr_Mx_3x3_gpu = Vctr, edev_gpu>; +} + +#ifdef __CUDACC__ +/* gpu vector */ +namespace mt +{ + template + class Vctr + { + public: + using value_type = T; + using size_type = dt_int64; + static const eDev device = edev_gpu; + + mutable T* m_data; + size_type m_s0; + size_type m_s1; + size_type m_s2; + size_type m_s3; + size_type m_size; + size_type m_capacity; + + size_type m_pitch_s1; + size_type m_pitch_s2; + size_type m_pitch_s3; + + /************************************* constructors ************************************/ + explicit Vctr(); + + Vctr(const dt_init_list_f64& data); + + Vctr(size_type s0); + + Vctr(size_type s0, const T& value); + + explicit Vctr(const dt_shape_st& shape); + + explicit Vctr(const dt_shape_st& shape, const T& value); + + /* copy constructor */ + Vctr(const Vctr& vctr); + + /* Move constructor */ + Vctr(Vctr&& vctr); + + /* converting constructor */ + template + Vctr(const Vctr& vctr); + + template + Vctr(U* first, U* last); + + template > + Vctr(U *p, dt_int64 n_p, size_type icol=0); + + template + Vctr(const std::vector& vctr); + + // from gpu pVctr to Vctr + template + Vctr(const pVctr& pvctr); + + // from cpu pVctr to Vctr + template + Vctr(const pVctr& pvctr); + + template + Vctr(const Vctr& vctr); + + template + Vctr(const thrust::host_vector& vctr); + + template + Vctr(const thrust::device_vector& vctr); + + ~Vctr(); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + Vctr& operator=(const Vctr& vctr); + + /* Move assignment operator */ + Vctr& operator=(Vctr&& vctr); + + /* converting assignment operator */ + template + Vctr& operator=(const Vctr& vctr); + + template + Vctr& operator=(const std::vector& vctr); + + template + Vctr& operator=(const Vctr& vctr); + + template + Vctr& operator=(const thrust::host_vector& vctr); + + template + Vctr& operator=(const thrust::device_vector& vctr); + + template + void assign(const Vctr& vctr, T* pvctr_cpu = nullptr); + + template + void assign(U* first, U* last); + + // from gpu pVctr to Vctr + template + void assign(const pVctr& pvctr); + + template + void assign(const thrust::device_ptr& first, const thrust::device_ptr& last, T* pvctr_cpu = nullptr); + + // from cpu pVctr to Vctr + template + void assign(const pVctr& pvctr); + + template + void assign(const std::vector& vctr, T* pvctr_cpu = nullptr); + + template + void assign(const Vctr& vctr, T* pvctr_cpu = nullptr); + + template + void assign(const thrust::host_vector& vctr, T* pvctr_cpu = nullptr); + + template + void assign(const thrust::device_vector& vctr, T* pvctr_cpu = nullptr); + + /**************** user define conversion operators *******************/ + pVctr_gpu_32 ptr_32() const; + + pVctr_gpu_64 ptr_64() const; + + /* user define conversion for pointer Vctr */ + operator pVctr_gpu_32() const; + + operator pVctr_gpu_64() const; + + /* user define conversion */ + operator std::vector() const; + + /* user define conversion in which T is the complemented precision */ + template > + operator std::vector() const; + + /* user define conversion to output type std::vector> */ + template > + operator std::vector>() const; + + /* user define conversion to output type std::vector> */ + template > + operator std::vector>() const; + + /* user define conversion */ + operator thrust::host_vector() const; + + /* user define conversion in which T is the complemented precision */ + template > + operator thrust::host_vector() const; + + /* user define conversion to output type thrust::host_vector> */ + template > + operator thrust::host_vector>() const; + + /* user define conversion to output type thrust::host_vector> */ + template > + operator thrust::host_vector>() const; + + /***************************************************************************************/ + /* user define conversion */ + operator thrust::device_vector() const; + + /* user define conversion in which T is the complemented precision */ + template > + operator thrust::device_vector() const; + + /***************************************************************************************/ + template + void cpy_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr); + + template + void cpy_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr); + + template + void cpy_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr); + + template + void cpy_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr); + + /***************************************************************************************/ + template > + void cpy_real_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr); + + template > + void cpy_real_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr); + + template > + void cpy_real_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr); + + template > + void cpy_real_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr); + + /***************************************************************************************/ + template > + void cpy_imag_to_cpu_ptr(U* pdata, size_type n_data, T* pvctr_cpu = nullptr); + + template > + void cpy_imag_to_cpu_ptr(U* first, U* last, T* pvctr_cpu = nullptr); + + template > + void cpy_imag_to_gpu_ptr(U* pdata, size_type n_data, U* pvctr_cpu = nullptr); + + template > + void cpy_imag_to_gpu_ptr(U* first, U* last, U* pvctr_cpu = nullptr); + + /***************************************************************************************/ + template > + void set_pos_from_cpu_ptr(U *p, size_type n_p, dt_int64 icol=0); + + template > + void cpy_pos_to_cpu_ptr(U *p, size_type icol=0); + + /***************************************************************************************/ + void resize(const dt_shape_st& shape); + + void resize(const dt_shape_st& shape, const T& value); + + void reserve(const dt_shape_st& shape); + + void shrink_to_fit(); + + template + void push_back(const U& val); + + template + void push_back(const Vctr& vctr); + + void pop_back(); + + void fill(T val); + + /***************************************************************************************/ + size_type s0() const; + + size_type s1() const; + + size_type s2() const; + + size_type s3() const; + + dt_int32 s0_32() const; + + dt_int32 s1_32() const; + + dt_int32 s2_32() const; + + dt_int32 s3_32() const; + + dt_int64 s0_64() const; + + dt_int64 s1_64() const; + + dt_int64 s2_64() const; + + dt_int64 s3_64() const; + + size_type s0h() const; + + size_type s1h() const; + + size_type s2h() const; + + size_type s3h() const; + + dt_shape_st shape() const; + + dt_shape_st shape_2d_trs() const; + + size_type shape_size() const; + + size_type pitch_s1() const; + + size_type pitch_s2() const; + + size_type pitch_s3() const; + + size_type size() const; + + dt_int32 size_32() const; + + dt_int64 size_64() const; + + iGrid_1d igrid_1d() const; + + iGrid_2d igrid_2d() const; + + iGrid_3d igrid_3d() const; + + iGrid_1d_64 igrid_1d_64() const; + + iGrid_2d_64 igrid_2d_64() const; + + iGrid_3d_64 igrid_3d_64() const; + + size_type capacity() const; + + dt_bool empty() const; + + dt_bool is_1d() const; + + void clear(); + + void clear_shrink_to_fit(); + + size_type sub_2_ind(const size_type& ix_0) const; + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1) const; + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const; + + size_type sub_2_ind(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const; + + // T& operator[](const size_type& iy); + + // const T& operator[](const size_type& iy) const; + + // T& operator()(const size_type& iy); + + // const T& operator()(const size_type& iy) const; + + // T& operator()(const size_type& ix_0, const size_type& ix_1); + + // const T& operator()(const size_type& ix_0, const size_type& ix_1) const; + + // T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2); + + // const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2) const; + + // T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3); + + // const T& operator()(const size_type& ix_0, const size_type& ix_1, const size_type& ix_2, const size_type& ix_3) const; + + thrust::device_ptr begin() noexcept; + + const thrust::device_ptr begin() const; + + thrust::device_ptr end() noexcept; + + const thrust::device_ptr end() const; + + T* data(); + + const T* data() const; + + template + U data_cast(); + + template + const U data_cast() const; + + // T& front(); + + // const T& front() const; + + // T& back(); + + // const T& back() const; + + // set shape + void set_shape(const dt_shape_st& shape); + + void trs_shape_2d(); + + template + void set_shape(const Vctr& vctr, dt_bool bb_size = true); + + FCNS_DEF_GPU_GRID_BLK_VCTR; + + private: + + void set_picth(); + + void set_capacity(size_type size_r); + + void set_shape_cstr(dt_shape_st& shape); + + // reallocate and copy memory + void allocate(dt_shape_st shape, dt_bool bb_reserve=false); + + // initialization + void init(); + + // destroy memory on the device + void destroy(); + }; +} + +#include "detail/vctr_gpu.inl" + +#endif \ No newline at end of file diff --git a/src/wave_function.cuh b/src/wave_function.cuh old mode 100644 new mode 100755 index 7250e8f1..76cd3f27 --- a/src/wave_function.cuh +++ b/src/wave_function.cuh @@ -1,330 +1,387 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef WAVE_FUNCTION_H -#define WAVE_FUNCTION_H - -#include "math.cuh" -#include "types.cuh" -#include "fft.cuh" -#include "input_multislice.cuh" -#include "cpu_fcns.hpp" -#include "gpu_fcns.cuh" -#include "cgpu_fcns.cuh" -#include "transmission_function.cuh" -#include "incident_wave.cuh" -#include "propagator.cuh" -#include "microscope_effects.cuh" - -namespace mt -{ - template - class Wave_Function: public Transmission_Function - { - public: - using T_r = T; - using T_c = complex; - using TVector_r = Vector; - using TVector_c = Vector; - using size_type = std::size_t; - - Wave_Function(): Transmission_Function(){} - - void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i, FFT *fft2_i) - { - psi_z.resize(input_multislice_i->grid_2d.nxy()); - m2psi_z.resize(input_multislice_i->grid_2d.nxy()); - - if(input_multislice_i->is_STEM()) - { - detector.assign(input_multislice_i->detector); - if(input_multislice_i->is_detector_matrix()) - { - for(auto i = 0; igrid_2d, detector.fR[i]); - } - } - } - - incident_wave.set_input_data(input_multislice_i, stream_i, fft2_i); - - propagator.set_input_data(input_multislice_i, stream_i, fft2_i); - - if(input_multislice_i->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM()) - { - microscope_effects.set_input_data(input_multislice_i, stream_i, fft2_i); - } - - Transmission_Function::set_input_data(input_multislice_i, stream_i, fft2_i); - } - - void phase_multiplication(const T_r &gxu, const T_r &gyu, TVector_c &psi_i, TVector_c &psi_o) - { - if(this->input_multislice->dp_Shift || isZero(gxu, gyu)) - { - if (psi_i.data() != psi_o.data()) - { - psi_o.assign(psi_i.begin(), psi_i.end()); - } - return; - } - - mt::exp_r_factor_2d(*(this->stream), this->input_multislice->grid_2d, c_2Pi*gxu, c_2Pi*gyu, psi_i, psi_o); - } - - void phase_multiplication(const T_r &gxu, const T_r &gyu, TVector_c &psi_io) - { - phase_multiplication(gxu, gyu, psi_io, psi_io); - } - - TVector_c* get_psi(const eSpace &space, const T_r &gxu, const T_r &gyu, - T_r z, TVector_c &psi_i) - { - TVector_c *psi_o = &(this->trans_0); - phase_multiplication(gxu, gyu, psi_i, *psi_o); - propagator(space, gxu, gyu, z, *psi_o); - - return psi_o; - } - - T_r integrated_intensity_over_det(T_r w_i, const int &iDet, TVector_c &psi_z) - { - T_r int_val = 0; - switch (detector.type) - { - case mt::eDT_Circular: - { - auto g_inner = detector.g_inner[iDet]; - auto g_outer = detector.g_outer[iDet]; - - int_val = w_i*mt::sum_square_over_Det(*(this->stream), this->input_multislice->grid_2d, g_inner, g_outer, psi_z); - } - break; - case mt::eDT_Radial: - { - int_val = 0; - } - break; - case mt::eDT_Matrix: - { - int_val = w_i*mt::sum_square_over_Det(*(this->stream), this->input_multislice->grid_2d, detector.fR[iDet], psi_z); - } - break; - } - - return int_val; - } - - template - void set_m2psi_tot_psi_coh(TVector_c &psi_z_i, const T_r &gxu, const T_r &gyu, - const int &islice, const T_r &w_i, TOutput_multislice &output_multislice) - { - int ithk = this->slicing.slice[islice].ithk; - if(0 <= ithk) - { - auto *psi_z_o = get_psi(this->input_multislice->get_simulation_space(), gxu, gyu, this->slicing.thick[ithk].z_back_prop, psi_z_i); - - if(this->input_multislice->is_STEM()) - { - for(auto iDet = 0; iDetinput_multislice->iscan[0]; - output_multislice.image_tot[ithk].image[iDet][iscan] += integrated_intensity_over_det(w_i, iDet, *psi_z_o); - } - - if(this->input_multislice->pn_coh_contrib) - { - output_multislice.add_scale_psi_coh(ithk, w_i, *psi_z_o); - } - } - else if(this->input_multislice->is_EWFS_EWRS_SC()) - { - output_multislice.set_crop_shift_psi_coh(ithk, *psi_z_o); - } - else if(this->input_multislice->is_EWFS_EWRS()) - { - output_multislice.add_scale_crop_shift_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); - output_multislice.add_scale_crop_shift_psi_coh(ithk, w_i, *psi_z_o); - } - else if(this->input_multislice->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM()) - { - microscope_effects(*psi_z_o, m2psi_z); - output_multislice.add_scale_crop_shift_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); - - if(this->input_multislice->pn_coh_contrib) - { - output_multislice.add_scale_psi_coh(ithk, w_i, *psi_z_o); - } - } - else - { - output_multislice.add_scale_crop_shift_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); - - if(this->input_multislice->pn_coh_contrib) - { - output_multislice.add_scale_psi_coh(ithk, w_i, *psi_z_o); - } - } - } - } - - template - void set_m2psi_coh(TOutput_multislice &output_multislice) - { - if(!this->input_multislice->pn_coh_contrib || this->input_multislice->is_EWFS_EWRS()) - { - return; - } - - int n_thk = this->input_multislice->thick.size(); - - if(this->input_multislice->is_STEM()) - { - for(auto ithk = 0; ithk < n_thk; ithk++) - { - output_multislice.from_psi_coh_2_phi(ithk, psi_z); - for(auto iDet = 0; iDetinput_multislice->iscan[0]; - output_multislice.image_coh[ithk].image[iDet][iscan] = integrated_intensity_over_det(1, iDet, psi_z); - } - } - } - else if(this->input_multislice->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM()) - { - for(auto ithk = 0; ithk < n_thk; ithk++) - { - output_multislice.from_psi_coh_2_phi(ithk, psi_z); - microscope_effects(psi_z, m2psi_z); - output_multislice.set_crop_shift_m2psi_coh(ithk, m2psi_z); - } - } - else - { - for(auto ithk = 0; ithk < n_thk; ithk++) - { - output_multislice.from_psi_coh_2_phi(ithk, psi_z); - output_multislice.add_scale_crop_shift_m2psi_coh_from_psi(ithk, 1.0, psi_z); - } - } - } - - template - void psi_slice(const T_r &gxu, const T_r &gyu, const int &islice, TVector_c &psi_z) - { - this->transmit(islice, psi_z); - - if(this->input_multislice->is_multislice()) - { - propagator(eS_Real, gxu, gyu, this->dz(islice), psi_z); - } - } - - template - void psi(T_r w_i, TVector_c &psi_z, TOutput_multislice &output_multislice) - { - T_r gx_0 = this->input_multislice->gx_0(); - T_r gy_0 = this->input_multislice->gy_0(); - - for(auto islice = 0; isliceslicing.slice.size(); islice++) - { - psi_slice(gx_0, gy_0, islice, psi_z); - - set_m2psi_tot_psi_coh(psi_z, gx_0, gy_0, islice, w_i, output_multislice); - } - } - - template - void psi(int islice_0, int islice_e, T_r w_i, TVector_c &trans, TOutput_multislice &output_multislice) - { - int ithk = this->slicing.slice[islice_e].ithk; - if(0 <= ithk) - { - T_r gx_0 = this->input_multislice->gx_0(); - T_r gy_0 = this->input_multislice->gy_0(); - - if(this->input_multislice->eels_fr.is_Single_Channelling()) - { - T_r dz = this->dz_m(islice_0, islice_e); - propagator(eS_Real, gx_0, gy_0, dz, psi_z); - } - else if(this->input_multislice->eels_fr.is_Mixed_Channelling()) - { - T_r dz = 0.5*this->dz_m(islice_0, islice_e); - propagator(eS_Real, gx_0, gy_0, dz, psi_z); - mt::multiply(*(this->stream), trans, psi_z); - propagator(eS_Real, gx_0, gy_0, dz, psi_z); - } - else if(this->input_multislice->eels_fr.is_Double_Channelling()) - { - for(auto islice = islice_0; islice<= islice_e; islice++) - { - psi_slice(gx_0, gy_0, islice, psi_z); - } - } - - phase_multiplication(gx_0, gy_0, psi_z); - propagator(eS_Reciprocal, gx_0, gy_0, this->slicing.thick[ithk].z_back_prop, psi_z); - - if(this->input_multislice->is_EELS()) - { - int iscan = this->input_multislice->iscan[0]; - output_multislice.image_tot[ithk].image[0][iscan] += w_i*mt::sum_square_over_Det(*(this->stream), this->input_multislice->grid_2d, 0, this->input_multislice->eels_fr.g_collection, psi_z); - } - else - { - mt::hard_aperture(*(this->stream), this->input_multislice->grid_2d, this->input_multislice->eels_fr.g_collection, 1.0, psi_z); - microscope_effects(psi_z, m2psi_z); - output_multislice.add_scale_crop_shift_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); - } - } - } - - void set_incident_wave(TVector_c &psi, Vector &beam_x, Vector &beam_y) - { - T_r gxu = 0; - T_r gyu = 0; - auto z_init = this->slicing.z_m(0); - - incident_wave(psi, gxu, gyu, beam_x, beam_y, z_init); - } - - void set_incident_wave(TVector_c &psi) - { - auto &beam_x = this->input_multislice->beam_x; - auto &beam_y = this->input_multislice->beam_y; - - set_incident_wave(psi, beam_x, beam_y); - } - - Propagator propagator; - - TVector_c psi_z; - TVector_r m2psi_z; - - Detector detector; - Microscope_Effects microscope_effects; - Incident_Wave incident_wave; - - //mt::Timing time; - }; - -} // namespace mt - +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef WAVE_FUNCTION_H +#define WAVE_FUNCTION_H + +#include "math_mt.h" +#include "types.cuh" +#include "cgpu_fft.cuh" +#include "in_classes.cuh" +#include "fcns_cpu.h" +#include "fcns_gpu.h" +#include "fcns_gpu.h" +#include "transmission_fcn.cuh" +#include "incident_wave.cuh" +#include "propagator.cuh" +#include "microscope_effects.cuh" + +#include "timing.cuh" + +#include + +namespace mt +{ + template + class Wave_Function: public Transmission_Fcn + { + public: + using T_r = T; + using T_c = complex; + using TVctr_r = Vctr; + using TVctr_c = Vctr; + using size_type = dt_uint64; + + Wave_Function(): Transmission_Fcn() {} + + void set_in_data(Multem_In_Parm *multem_in_parm_i, Stream *stream_i, FFT *fft2_i) + { + psi_z.resize(multem_in_parm_i->grid_2d.size()); + m2psi_z.resize(multem_in_parm_i->grid_2d.size()); + + if (multem_in_parm_i->is_STEM()) + { + detector.assign(multem_in_parm_i->detector); + if (multem_in_parm_i->is_detector_matrix()) + { + for(auto i = 0; igrid_2d, detector.fR[i]); + } + } + } + + incident_wave.set_in_data(multem_in_parm_i, stream_i, fft2_i); + + propagator.set_in_data(multem_in_parm_i, stream_i, fft2_i); + + if (multem_in_parm_i->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS()) + { + microscope_effects.set_in_data(multem_in_parm_i, stream_i, fft2_i); + } + + Transmission_Fcn::set_in_data(multem_in_parm_i, stream_i, fft2_i); + } + + void phase_multiplication(const T_r &gxu, const T_r &gyu, TVctr_c& psi_i, TVctr_c& psi_o) + { + if (this->multem_in_parm->dp_Shift || fcn_is_zero(gxu, gyu)) + { + if (psi_i.data() != psi_o.data()) + { + psi_o.assign(psi_i.begin(), psi_i.end()); + } + return; + } + + mt::fcn_rs_exp_factor_2d(*(this->stream), this->multem_in_parm->grid_2d, c_2pi*gxu, c_2pi*gyu, psi_i, psi_o); + } + + void phase_multiplication(const T_r &gxu, const T_r &gyu, TVctr_c& psi_io) + { + phase_multiplication(gxu, gyu, psi_io, psi_io); + } + + TVctr_c* get_psi(const eSpace &space, const T_r &gxu, const T_r &gyu, + T_r z, TVctr_c& psi_i) + { + TVctr_c *psi_o = &(this->trans_0); + phase_multiplication(gxu, gyu, psi_i, *psi_o); + propagator(space, gxu, gyu, z, *psi_o); + + return psi_o; + } + + T_r integrated_intensity_over_det(T_r w_i, const dt_int32& iDet, TVctr_c& psi_z) + { + T_r int_val = 0; + switch (detector.type) + { + case mt::edt_circular: + { + auto g_inner = detector.g_inner[iDet]; + auto g_outer = detector.g_outer[iDet]; + + int_val = w_i*mt::fcn_int_det_ring_norm_2(*(this->stream), this->multem_in_parm->grid_2d, g_inner, g_outer, psi_z); + } + break; + case mt::edt_radial: + { + int_val = 0; + } + break; + case mt::edt_matrix: + { + int_val = w_i*mt::fcn_int_det_ring_norm_2(*(this->stream), this->multem_in_parm->grid_2d, detector.fR[iDet], psi_z); + } + break; + } + + return int_val; + } + + template + void set_m2psi_tot_psi_coh(TVctr_c& psi_z_i, const T_r &gxu, const T_r &gyu, + const dt_int32& islice, const T_r &w_i, TOutput_multislice &output_multem) + { + dt_int32 ithk = this->slicing.slice[islice].ithk; + if (0 <= ithk) + { + auto *psi_z_o = get_psi(this->multem_in_parm->get_simulation_space(), gxu, gyu, this->slicing.thick[ithk].z_back_prop, psi_z_i); + + if (this->multem_in_parm->is_STEM()) + { + for(auto iDet = 0; iDetmultem_in_parm->ibeam[0]; + output_multem.image_tot(ithk, iDet, ibeam) += integrated_intensity_over_det(w_i, iDet, *psi_z_o); + } + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk, 0, w_i, *psi_z_o); + } + } + else if (this->multem_in_parm->is_EWFS_EWRS_SC()) + { + output_multem.set_crop_sft_psi_coh(ithk, *psi_z_o); + } + else if (this->multem_in_parm->is_EWFS_EWRS()) + { + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); + output_multem.add_sc_crop_sft_psi_coh(ithk, w_i, *psi_z_o); + } + else if (this->multem_in_parm->is_CBED()) + { + dt_int32 ithk_beam = (this->multem_in_parm->thick.size()==1)?this->multem_in_parm->ibeam[0]:ithk; + + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk_beam, w_i, *psi_z_o); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk_beam, w_i, *psi_z_o); + } + } + else if (this->multem_in_parm->is_CBEI()) + { + dt_int32 ithk_beam = (this->multem_in_parm->thick.size()==1)?this->multem_in_parm->ibeam[0]:ithk; + + microscope_effects(*psi_z_o, m2psi_z); + output_multem.add_sc_crop_sft_m2psi_tot_from_m2psi(ithk_beam, w_i, m2psi_z); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk_beam, w_i, *psi_z_o); + } + } + else if (this->multem_in_parm->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS()) + { + microscope_effects(*psi_z_o, m2psi_z); + output_multem.add_sc_crop_sft_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk, w_i, *psi_z_o); + } + } + else + { + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); + + if (this->multem_in_parm->atomic_vib.coh_contrib) + { + output_multem.add_sc_psi_coh(ithk, w_i, *psi_z_o); + } + } + + // this->stream->synchronize(); + } + } + + template + void set_m2psi_coh(TOutput_multislice &output_multem) + { + if (!this->multem_in_parm->atomic_vib.coh_contrib || this->multem_in_parm->is_EWFS_EWRS()) + { + return; + } + + dt_int32 n_thk = this->multem_in_parm->thick.size(); + + if (this->multem_in_parm->is_STEM()) + { + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + for(auto iDet = 0; iDetmultem_in_parm->ibeam[0]; + output_multem.image_coh(ithk, iDet, ibeam) = integrated_intensity_over_det(1, iDet, psi_z); + } + } + } + else if (this->multem_in_parm->is_CBED()) + { + n_thk = (n_thk==1)?this->multem_in_parm->number_of_beams():n_thk; + + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + output_multem.add_sc_crop_sft_m2psi_coh_from_psi(ithk, 1.0, psi_z); + } + } + else if (this->multem_in_parm->is_CBEI()) + { + n_thk = (n_thk==1)?this->multem_in_parm->number_of_beams():n_thk; + + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + microscope_effects(psi_z, m2psi_z); + output_multem.set_crop_sft_m2psi_coh(ithk, m2psi_z); + } + } + else if (this->multem_in_parm->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEMRS()) + { + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + microscope_effects(psi_z, m2psi_z); + output_multem.set_crop_sft_m2psi_coh(ithk, m2psi_z); + } + } + else + { + for(auto ithk = 0; ithk < n_thk; ithk++) + { + output_multem.from_psi_coh_2_phi(ithk, psi_z); + output_multem.add_sc_crop_sft_m2psi_coh_from_psi(ithk, 1.0, psi_z); + } + } + + // this->stream->synchronize(); + } + + template + void psi_slice(const T_r &gxu, const T_r &gyu, const dt_int32& islice, TVctr_c& psi_z) + { + this->transmit(islice, psi_z); + + if (this->multem_in_parm->is_multislice()) + { + // time.tic(); + propagator(esp_real, gxu, gyu, this->sli_thick(islice), psi_z); + // time.toc(); + // mexPrintf("time = %7.5f\n", time.elapsed_ms()); + } + } + + template + void psi(T_r w_i, TVctr_c& psi_z, TOutput_multislice &output_multem) + { + T_r gx_0 = this->multem_in_parm->gx_0(); + T_r gy_0 = this->multem_in_parm->gy_0(); + + for(auto islice = 0; isliceslicing.slice.size(); islice++) + { + psi_slice(gx_0, gy_0, islice, psi_z); + + set_m2psi_tot_psi_coh(psi_z, gx_0, gy_0, islice, w_i, output_multem); + } + } + + template + void psi(dt_int32 islice_0, dt_int32 islice_e, T_r w_i, TVctr_c& trans, TOutput_multislice &output_multem) + { + dt_int32 ithk = this->slicing.slice[islice_e].ithk; + if (0 <= ithk) + { + T_r gx_0 = this->multem_in_parm->gx_0(); + T_r gy_0 = this->multem_in_parm->gy_0(); + + if (this->multem_in_parm->eels_fr.is_Single_Chan()) + { + T_r sli_thick = this->dz_m(islice_0, islice_e); + propagator(esp_real, gx_0, gy_0, sli_thick, psi_z); + } + else if (this->multem_in_parm->eels_fr.is_Mixed_Chan()) + { + T_r sli_thick = 0.5*this->dz_m(islice_0, islice_e); + propagator(esp_real, gx_0, gy_0, sli_thick, psi_z); + mt::ew_mult(*(this->stream), trans, psi_z); + propagator(esp_real, gx_0, gy_0, sli_thick, psi_z); + } + else if (this->multem_in_parm->eels_fr.is_Double_Chan()) + { + for(auto islice = islice_0; islice<= islice_e; islice++) + { + psi_slice(gx_0, gy_0, islice, psi_z); + } + } + + phase_multiplication(gx_0, gy_0, psi_z); + propagator(esp_fourier, gx_0, gy_0, this->slicing.thick[ithk].z_back_prop, psi_z); + + if (this->multem_in_parm->is_STEM_ISTEM_EELS()) + { + dt_int32 ibeam = this->multem_in_parm->ibeam[0]; + output_multem.image_tot(ithk, 0, ibeam) += w_i*mt::fcn_int_det_ring_norm_2(*(this->stream), this->multem_in_parm->grid_2d, 0, this->multem_in_parm->eels_fr.g_coll, psi_z); + } + if (this->multem_in_parm->is_EFTEMRS()) + { + microscope_effects(psi_z, m2psi_z); + output_multem.add_sc_crop_sft_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); + } + else + { + output_multem.add_sc_crop_sft_m2psi_tot_from_psi(ithk, w_i, psi_z); + } + } + } + + void set_incident_wave(TVctr_c& psi, Beam_Pos_2d& beam_pos) + { + T_r gxu = 0; + T_r gyu = 0; + auto z_init = this->slicing.z_m(0); + + incident_wave(psi, gxu, gyu, beam_pos, z_init); + } + + void set_incident_wave(TVctr_c& psi) + { + auto &beam_pos = this->multem_in_parm->beam_pos; + + set_incident_wave(psi, beam_pos); + } + + Propagator propagator; + + TVctr_c psi_z; + TVctr_r m2psi_z; + + Detector detector; + Microscope_Effects microscope_effects; + Incident_Wave incident_wave; + + mt::Timing time; + }; + +} + #endif \ No newline at end of file diff --git a/src/wd_butwth.h b/src/wd_butwth.h new file mode 100755 index 00000000..40773b04 --- /dev/null +++ b/src/wd_butwth.h @@ -0,0 +1,79 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "fcn_butwth.h" +#include "wd_fcn.h" + +/* template definition */ +namespace mt +{ +#ifndef WD_FCN_DEC + #define WD_FCN_DEC + template class Wd_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Wd_Butwth_xd = Wd_fcn_xd; + + template + using Wd_Butwth_1d = Wd_fcn_xd; + + template + using Wd_Butwth_2d = Wd_fcn_xd; + + template + using Wd_Butwth_3d = Wd_fcn_xd; +} + +/* template specialization */ +namespace mt +{ + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(); + + Wd_fcn_xd(const R_xd& r, const dt_int32& n, const T& r_wd, const T& r_max); + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wd_fcn_xd& operator=(const Wdb_fcn_xd& wd); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const dt_int32& n, const T& r_wd, const T& r_max); + + }; +} + +#include "detail/wd_butwth.inl" \ No newline at end of file diff --git a/src/wd_exp.h b/src/wd_exp.h new file mode 100755 index 00000000..603e175a --- /dev/null +++ b/src/wd_exp.h @@ -0,0 +1,78 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "fcn_exp.h" +#include "wd_fcn.h" + +/* template definition */ +namespace mt +{ +#ifndef WD_FCN_DEC + #define WD_FCN_DEC + template class Wd_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Wd_Exp_xd = Wd_fcn_xd; + + template + using Wd_Exp_1d = Wd_fcn_xd; + + template + using Wd_Exp_2d = Wd_fcn_xd; + + template + using Wd_Exp_3d = Wd_fcn_xd; +} + +/* template specialization */ +namespace mt +{ + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(); + + Wd_fcn_xd(const R_xd& r, const T& beta, const T& r_wd, const T& r_max); + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wd_fcn_xd& operator=(const Wdb_fcn_xd& wd); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& beta, const T& r_wd, const T& r_max); + }; +} + +#include "detail/wd_exp.inl" \ No newline at end of file diff --git a/src/wd_fcn.h b/src/wd_fcn.h new file mode 100755 index 00000000..c9f5ce57 --- /dev/null +++ b/src/wd_fcn.h @@ -0,0 +1,88 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "const_enum.h" +#include "r_2d.h" +#include "r_3d.h" + +/* template definition */ +namespace mt +{ +#ifndef FCN_ELEM_DEC + #define FCN_ELEM_DEC + template class Fcn_Elem; +#endif +} + +/* template definition */ +namespace mt +{ + template class Wdb_fcn_xd; +} + +/* base class fcn window */ +namespace mt +{ + template + class Wdb_fcn_xd: public Fcn_Elem + { + public: + using value_type = T; + + R_xd r; + T r_wd_2; + T r_max_2; + T sft; + T sc; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wdb_fcn_xd(); + + /* copy constructor */ + CGPU_EXEC + Wdb_fcn_xd(const Wdb_fcn_xd& wd); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wdb_fcn_xd& operator=(const Wdb_fcn_xd& wd); + + CGPU_EXEC + void assign(const Wdb_fcn_xd& wd); + + /***************************************************************************************/ + CGPU_EXEC + void clear(); + + CGPU_EXEC + T eval_r2(const T& r2) const; + + CGPU_EXEC + T eval_r2(const R_2d& r2) const; + + CGPU_EXEC + T eval_r2(const R_3d& r2) const; + + void set_in_data(const R_xd& r, const T& r_wd, const T& r_max); + }; +} + +#include "detail/wd_fcn.inl" \ No newline at end of file diff --git a/src/wd_fermi.h b/src/wd_fermi.h new file mode 100755 index 00000000..4ece8acd --- /dev/null +++ b/src/wd_fermi.h @@ -0,0 +1,78 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "fcn_fermi.h" +#include "wd_fcn.h" + +/* template definition */ +namespace mt +{ +#ifndef WD_FCN_DEC + #define WD_FCN_DEC + template class Wd_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Wd_Fermi_xd = Wd_fcn_xd; + + template + using Wd_Fermi_1d = Wd_fcn_xd; + + template + using Wd_Fermi_2d = Wd_fcn_xd; + + template + using Wd_Fermi_3d = Wd_fcn_xd; +} + +/* template specialization */ +namespace mt +{ + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(); + + Wd_fcn_xd(const R_xd& r, const T& alpha, const T& r_wd, const T& r_max); + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wd_fcn_xd& operator=(const Wdb_fcn_xd& wd); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& alpha, const T& r_wd, const T& r_max); + }; +} + +#include "detail/wd_fermi.inl" \ No newline at end of file diff --git a/src/wd_gauss.h b/src/wd_gauss.h new file mode 100755 index 00000000..1e4f6299 --- /dev/null +++ b/src/wd_gauss.h @@ -0,0 +1,78 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "fcn_gauss.h" +#include "wd_fcn.h" + +/* template definition */ +namespace mt +{ +#ifndef WD_FCN_DEC + #define WD_FCN_DEC + template class Wd_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Wd_Gauss_xd = Wd_fcn_xd; + + template + using Wd_Gauss_1d = Wd_fcn_xd; + + template + using Wd_Gauss_2d = Wd_fcn_xd; + + template + using Wd_Gauss_3d = Wd_fcn_xd; +} + +/* template specialization*/ +namespace mt +{ + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(); + + Wd_fcn_xd(const R_xd& r, const T& sigma, const T& r_wd, const T& r_max); + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wd_fcn_xd& operator=(const Wdb_fcn_xd& wd); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& sigma, const T& r_wd, const T& r_max); + }; +} + +#include "detail/wd_gauss.inl" \ No newline at end of file diff --git a/src/wd_hann.h b/src/wd_hann.h new file mode 100755 index 00000000..1b60417f --- /dev/null +++ b/src/wd_hann.h @@ -0,0 +1,79 @@ +/* +* This file is part of Multem. +* Copyright 2022 Ivan Lobato +* +* Multem is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version of the License, or +* (at your option) any later version. +* +* Multem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details.Gauss_wd_ +* +* You should have received a copy of the GNU General Public License +* along with Multem. If not, see . +*/ + +#pragma once + +#include "fcn_hann.h" +#include "wd_fcn.h" + +/* template definition */ +namespace mt +{ +#ifndef WD_FCN_DEC + #define WD_FCN_DEC + template class Wd_fcn_xd; +#endif +} + +/* derived class */ +namespace mt +{ + template + using Wd_Hann_xd = Wd_fcn_xd; + + template + using Wd_Hann_1d = Wd_fcn_xd; + + template + using Wd_Hann_2d = Wd_fcn_xd; + + template + using Wd_Hann_3d = Wd_fcn_xd; +} + +/* template specialization */ +namespace mt +{ + template + class Wd_fcn_xd: public Wdb_fcn_xd + { + public: + using value_type = T; + + /************************************* constructors ************************************/ + CGPU_EXEC + Wd_fcn_xd(); + + Wd_fcn_xd(const R_xd& r, const T& l, const T& r_wd, const T& r_max); + + /* copy constructor */ + CGPU_EXEC + Wd_fcn_xd(const Wd_fcn_xd& wd); + + /******************************** assignment operators *********************************/ + /* copy assignment operator */ + CGPU_EXEC + Wd_fcn_xd& operator=(const Wdb_fcn_xd& wd); + + /***************************************************************************************/ + void set_in_data(const R_xd& r, const T& l, const T& r_wd, const T& r_max); + + }; +} + +#include "detail/wd_hann.inl" \ No newline at end of file diff --git a/src/xtl_build.hpp b/src/xtl_build.hpp old mode 100644 new mode 100755 index faadeab3..a28b690b --- a/src/xtl_build.hpp +++ b/src/xtl_build.hpp @@ -1,164 +1,277 @@ -/* - * This file is part of MULTEM. - * Copyright 2020 Ivan Lobato - * - * MULTEM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MULTEM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MULTEM. If not, see . - */ - -#ifndef XTL_BUILD_H -#define XTL_BUILD_H - -#ifdef _MSC_VER -#pragma once -#endif// _MSC_VER - -#include -#include - -#include "types.cuh" -#include "atomic_data_mt.hpp" - -namespace mt -{ - template - class Crystal_Spec{ - public: - Crystal_Spec(): na(0), nb(0), nc(0), a(0), b(0), c(0){}; - - void operator()(const int &na_i, const int &nb_i, const int &nc_i, T a_i, T b_i, T c_i, Vector, e_host> &ulay_i, Atom_Data &Atoms_o) - { - na = na_i; - nb = nb_i; - nc = nc_i; - - a = a_i; - b = b_i; - c = c_i; - - ulay.resize(ulay_i.size()); - lays.resize(ulay_i.size()); - - for(auto i = 0; i < ulay.size(); i++) - { - ulay[i].set_atoms(ulay_i[i]); - lays[i].resize(ulay[i].size()*(na+1)*(nb+1)); - } - - auto nAtomslays = stack_layers(na, nb, a, b, c, ulay, lays); - Atoms_o.resize(nc*nAtomslays + lays[0].size()); - - Atoms_o.l_x = static_cast(na)*a; - Atoms_o.l_y = static_cast(nb)*b; - - std::size_t l = 0; - for(auto k = 0; k < nc; k++) - { - for(auto i = 0; i < lays.size(); i++) - { - for(auto j = 0; j < lays[i].size(); j++) - { - Atoms_o.Z[l] = lays[i].Z[j]; - Atoms_o.x[l] = lays[i].x[j]; - Atoms_o.y[l] = lays[i].y[j]; - Atoms_o.z[l] = lays[i].z[j] + c*static_cast(k); - Atoms_o.sigma[l] = lays[i].sigma[j]; - Atoms_o.occ[l] = lays[i].occ[j]; - Atoms_o.region[l] = lays[i].region[j]; - Atoms_o.charge[l] = lays[i].charge[j]; - l++; - } - } - } - - // Last layer - for(auto j = 0; j < lays[0].size(); j++) - { - Atoms_o.Z[l] = lays[0].Z[j]; - Atoms_o.charge[l] = lays[0].charge[j]; - Atoms_o.x[l] = lays[0].x[j]; - Atoms_o.y[l] = lays[0].y[j]; - Atoms_o.z[l] = lays[0].z[j] + c*static_cast(nc); - Atoms_o.sigma[l] = lays[0].sigma[j]; - Atoms_o.occ[l] = lays[0].occ[j]; - Atoms_o.region[l] = lays[0].region[j]; - Atoms_o.charge[l] = lays[0].charge[j]; - l++; - } - Atoms_o.get_statistic(); - } - - private: - void ulayer_2_layer(const int &na, const int &nb, T a, T b, T c, Atom_Data &ulay, Atom_Data &lay) - { - T x, y; - - T xmin = 0.0 - Epsilon::rel; - T xmax = na*a + Epsilon::rel; - - T ymin = 0.0 - Epsilon::rel; - T ymax = nb*b + Epsilon::rel; - - std::size_t l = 0; - for(auto j = 0; j <= nb; j++) - { - for(auto i = 0; i <= na; i++) - { - for(auto k = 0; k < ulay.size(); k++) - { - x = (i + ulay.x[k])*a; - y = (j + ulay.y[k])*b; - if(Check_Bound(x, xmin, xmax, y, ymin, ymax)) - { - lay.Z[l] = ulay.Z[k]; - lay.x[l] = x; - lay.y[l] = y; - lay.z[l] = c*ulay.z[k]; - lay.sigma[l] = ulay.sigma[k]; - lay.occ[l] = ulay.occ[k]; - lay.region[l] = ulay.region[k]; - lay.charge[l] = ulay.charge[k]; - l++; - } - } - } - } - lay.resize(l); - } - - std::size_t stack_layers(const int &na, const int &nb, T a, T b, T c, Vector, e_host> &ulay, Vector, e_host> &lays) - { - std::size_t nAtoms_lays = 0; - for(auto i = 0; i < ulay.size(); i++) - { - ulayer_2_layer(na, nb, a, b, c, ulay[i], lays[i]); - nAtoms_lays += lays[i].size(); - } - return nAtoms_lays; - } - - int na; - int nb; - int nc; - - T a; - T b; - T c; - - Vector, e_host> ulay; - Vector, e_host> lays; - }; - -} // namespace mt - -#endif +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef XTL_BUILD_H + #define XTL_BUILD_H + + #ifdef _MSC_VER + #pragma once + #endif + + #include + #include + #include + + #include "types.cuh" + #include "particles.cuh" + #include "xtl_build_in_parm.hpp" + #include "space_group.hpp" + + namespace mt + { + // from space group number to xtl system number + dt_int32 xtl_sgn_2_csn(const dt_int32& sgn) + { + if (fcn_chk_bound(sgn, 1, 3)) // triclinic or anorthic + { + return 1; + } + else if (fcn_chk_bound(sgn, 3, 16)) // monoclinic + { + return 2; + } + else if (fcn_chk_bound(sgn, 16, 75)) // orthorhombic + { + return 3; + } + else if (fcn_chk_bound(sgn, 75, 143)) // tetragonal + { + return 4; + } + else if (fcn_chk_bound(sgn, 143, 168)) // rhombohedral or trigonal + { + return 5; + } + else if (fcn_chk_bound(sgn, 168, 195)) // hexagonal + { + return 6; + } + else if (fcn_chk_bound(sgn, 195, 231)) // cubic + { + return 7; + } + + return 1; + } + + // from xtl system string to xtl system number + dt_int32 xtl_css_2_csn(std::string cs_str) + { + fcn_str_rtrim_ip(cs_str); + + cs_str = mt::fcn_str_2_lower(cs_str); + //std::transform(cs_str.begin(), cs_str.end(), cs_str.begin(), ::tolower); + + if (fcn_str_cmp(cs_str, "triclinic")||fcn_str_cmp(cs_str, "a")) // triclinic or anorthic + { + return 1; + } + else if (fcn_str_cmp(cs_str, "monoclinic")||fcn_str_cmp(cs_str, "m")) // monoclinic + { + return 2; + } + else if (fcn_str_cmp(cs_str, "orthorhombic")||fcn_str_cmp(cs_str, "o")) // orthorhombic + { + return 3; + } + else if (fcn_str_cmp(cs_str, "tetragonal")||fcn_str_cmp(cs_str, "t")) // tetragonal + { + return 4; + } + else if (fcn_str_cmp(cs_str, "rhombohedral")||fcn_str_cmp(cs_str, "r")) // rhombohedral or trigonal + { + return 5; + } + else if (fcn_str_cmp(cs_str, "hexagonal")||fcn_str_cmp(cs_str, "h")) // hexagonal + { + return 6; + } + else if (fcn_str_cmp(cs_str, "cubic")||fcn_str_cmp(cs_str, "c")) // cubic + { + return 7; + } + + return 1; + } + + // from xtl system number to space group range + std::pair xtl_csn_2_sgr(const dt_int32& csn) + { + switch(csn) + { + case 1: // triclinic or anorthic + return {1, 2}; + case 2: // monoclinic + return {3, 15}; + case 3: // orthorhombic + return {16, 74}; + case 4: // tetragonal + return {75, 142}; + case 5: // rhombohedral or trigonal + return {143, 167}; + case 6: // hexagonal + return {168, 194}; + case 7: // cubic + return {195, 230}; + } + + return {0, 0}; + } + + // from xtl system string to space group range + std::pair xtl_css_2_sgr(const std::string& cs_str) + { + auto csn = xtl_css_2_csn(cs_str); + + return xtl_csn_2_sgr(csn); + } + + template + class Xtl_Build{ + public: + Xtl_Build(): n_a(0), n_b(0), n_c(0), a(0), b(0), c(0) {}; + + Xtl_Build(const Xtl_Build_In_Parm& xtl_build_in_parm) + { + set_in_data(xtl_build_in_parm); + } + + void set_in_data(const Xtl_Build_In_Parm& xtl_build_in_parm) + { + a = xtl_build_in_parm.a; + b = xtl_build_in_parm.b; + c = xtl_build_in_parm.c; + + alpha = xtl_build_in_parm.alpha; + beta = xtl_build_in_parm.beta; + gamma = xtl_build_in_parm.gamma; + + n_a = xtl_build_in_parm.n_a; + n_b = xtl_build_in_parm.n_b; + n_c = xtl_build_in_parm.n_c; + + sgn = xtl_build_in_parm.sgn; + pbc = xtl_build_in_parm.pbc; + + asym_uc = xtl_build_in_parm.asym_uc; + base = xtl_build_in_parm.base; + + if (xtl_build_in_parm.base.size()==0) + { + base = space_group(asym_uc, sgn); + } + } + + Ptc_Atom operator()() const + { + const auto dsm = direct_struct_metric(); + const R_3d box_n = R_3d(T(n_a), T(n_b), T(n_c)) + T(1e-4); + + const dt_int32 n_base = base.size(); + + dt_int32 nt_a = n_a; + dt_int32 nt_b = n_b; + dt_int32 nt_c = n_c; + + if (!pbc) + { + nt_a++; + nt_b++; + nt_c++; + } + else + { + nt_a = max(1, nt_a); + nt_b = max(1, nt_b); + nt_c = max(1, nt_c); + } + + Ptc_Atom xtl; + xtl.reserve(nt_a*nt_b*nt_c*n_base); + xtl.cols_used = base.cols_used; + + for(auto ic = 0; ic < nt_c; ic++) + { + for(auto ib = 0; ib < nt_b; ib++) + { + for(auto ia = 0; ia < nt_a; ia++) + { + for(auto ik = 0; ik < n_base; ik++) + { + auto atom = base.get(ik); + + atom.x += T(ia); + atom.y += T(ib); + atom.z += T(ic); + + if ((atom.x direct_struct_metric() const + { + T cos_alpha = cos(alpha); + T cos_beta = cos(beta); + T cos_gamma = cos(gamma); + + T sin_gamma = sin(gamma); + + T F_bga = cos_beta*cos_gamma - cos_alpha; + + T vol2 = ::square(a*b*c)*(1-::square(cos_alpha)-::square(cos_beta)-::square(cos_gamma)+2*cos_alpha*cos_beta*cos_gamma); + T vol = ::sqrt(vol2); + + return {a, 0, 0, b*cos_gamma, b*sin_gamma, 0, c*cos_beta, -c*F_bga/sin_gamma, vol/(a*b*sin_gamma)}; + } + + private: + + T a; // lattice constant a + T b; // lattice constant b + T c; // lattice constant c + + T alpha; // angle between b & c + T beta; // angle between c & a + T gamma; // angle between a & b + + dt_int32 n_a; + dt_int32 n_b; + dt_int32 n_c; + + dt_int32 sgn; // space group number + dt_bool pbc; + + Ptc_Atom asym_uc; // normalized positions in the asymmetric unit cell + Ptc_Atom base; // normalized positions of atom in the unit cell + Space_Group space_group; + }; + + } + +#endif diff --git a/src/xtl_build_in_parm.hpp b/src/xtl_build_in_parm.hpp new file mode 100755 index 00000000..2c4038d5 --- /dev/null +++ b/src/xtl_build_in_parm.hpp @@ -0,0 +1,61 @@ +/* + * This file is part of Multem. + * Copyright 2022 Ivan Lobato + * + * Multem is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version of the License, or + * (at your option) any later version. + * + * Multem is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Multem. If not, see . + */ + +#ifndef XTL_BUILD_IN_PARM_H + #define XTL_BUILD_IN_PARM_H + + #include "particles.cuh" + + /* xtl */ + namespace mt + { + /* Asymmetric Unit + The asymmetric unit is the smallest fraction of the unit cell that + can be rotated and translated using only the symmetry operators + allowed by the xtllographic symmetry to generate one unit cell. + */ + template + class Xtl_Build_In_Parm + { + public: + using value_type = T; + + T a; // lattice constant a + T b; // lattice constant b + T c; // lattice constant c + + T alpha; // angle between b & c + T beta; // angle between c & a + T gamma; // angle between a & b + + dt_int32 n_a; + dt_int32 n_b; + dt_int32 n_c; + + dt_int32 sgn; // space group number + dt_bool pbc; + + Ptc_Atom asym_uc; // normalized positions in the asymmetric unit cell + Ptc_Atom base; // normalized positions of atom in the unit cell + + Xtl_Build_In_Parm() : + a(0), b(0), c(0), alpha(0), beta(0), gamma(0), + n_a(0), n_b(0), n_c(0), sgn(1), pbc(false) {}; + }; + } +#endif \ No newline at end of file diff --git a/tutorial/MULTEM_image_simulation_software_Solutions.pdf b/tutorial/MULTEM_image_simulation_software_Solutions.pdf old mode 100644 new mode 100755 diff --git a/tutorial/MULTEM_image_simulation_software_Worksheet.pdf b/tutorial/MULTEM_image_simulation_software_Worksheet.pdf old mode 100644 new mode 100755 diff --git a/tutorial/MULTEM_solutions.pptx b/tutorial/MULTEM_solutions.pptx old mode 100644 new mode 100755 diff --git a/visual_studio_multem/multem.sln b/visual_studio_multem/multem.sln old mode 100644 new mode 100755 diff --git a/visual_studio_multem/multem/main.cu b/visual_studio_multem/multem/main.cu old mode 100644 new mode 100755 diff --git a/visual_studio_multem/multem/multem.vcxproj b/visual_studio_multem/multem/multem.vcxproj old mode 100644 new mode 100755 index 9846f5f1..beec24f6 --- a/visual_studio_multem/multem/multem.vcxproj +++ b/visual_studio_multem/multem/multem.vcxproj @@ -1,5 +1,5 @@ - + Debug @@ -19,97 +19,394 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + 15.0 {7AF61FF5-2F37-48B5-A7B5-0DB32777F186} - multem_stable + multem 10.0 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2 @@ -160,8 +457,8 @@ - D:\multem_stable\src;C:\Program Files\MATLAB\R2018a\extern\include;D:\research\Other_codes\lapacke\include;$(IncludePath) - D:\multem_stable\src;$(ReferencePath) + D:\multem\src;C:\Program Files\MATLAB\R2018a\extern\include;D:\research\Other_codes\lapacke\include;$(IncludePath) + D:\multem\src;$(ReferencePath) $(VC_IncludePath);$(WindowsSDK_IncludePath);C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\include; @@ -175,8 +472,8 @@ Disabled true true - D:\multem_stable\src;%(AdditionalUsingDirectories) - D:\multem_stable\src;%(AdditionalIncludeDirectories) + D:\multem\src;%(AdditionalUsingDirectories) + D:\multem\src;%(AdditionalIncludeDirectories) @@ -187,6 +484,10 @@ true C:\Program Files\MATLAB\R2021a\extern\include;D:\multem\src;%(AdditionalIncludeDirectories) + + + + @@ -216,6 +517,10 @@ true true + + + + diff --git a/visual_studio_multem/multem/multem.vcxproj.filters b/visual_studio_multem/multem/multem.vcxproj.filters deleted file mode 100644 index 4d56923e..00000000 --- a/visual_studio_multem/multem/multem.vcxproj.filters +++ /dev/null @@ -1,265 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Header Files - - - - - Source Files - - - \ No newline at end of file diff --git a/visual_studio_multem/multem/multem.vcxproj.user b/visual_studio_multem/multem/multem.vcxproj.user old mode 100644 new mode 100755 index 6e2aec7a..0f14913f --- a/visual_studio_multem/multem/multem.vcxproj.user +++ b/visual_studio_multem/multem/multem.vcxproj.user @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/vscode_multem/.goutputstream-O8V601 b/vscode_multem/.goutputstream-O8V601 new file mode 100755 index 00000000..c818371e --- /dev/null +++ b/vscode_multem/.goutputstream-O8V601 @@ -0,0 +1,17 @@ +{ + "folders": [ + { + "path": "../src" + }, + { + "path": "../mex_files_general" + }, + { + "path": "../mex_files_multem" + }, + { + "path": "../mex_files_test" + } + ], + "settings": {} +} diff --git a/vscode_multem/helloworld b/vscode_multem/helloworld new file mode 100755 index 00000000..74499f95 Binary files /dev/null and b/vscode_multem/helloworld differ diff --git a/vscode_multem/helloworld.cpp b/vscode_multem/helloworld.cpp new file mode 100755 index 00000000..ccd2f8de --- /dev/null +++ b/vscode_multem/helloworld.cpp @@ -0,0 +1,16 @@ +#include +#include +#include + +using namespace std; + +int main() +{ + vector msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"}; + + for (const string& word : msg) + { + cout << word << " "; + } + cout << endl; +} \ No newline at end of file diff --git a/vscode_multem/output/helloworld b/vscode_multem/output/helloworld new file mode 100755 index 00000000..ccdb9588 Binary files /dev/null and b/vscode_multem/output/helloworld differ diff --git a/vscode_multem/vscode_multem.code-workspace b/vscode_multem/vscode_multem.code-workspace new file mode 100755 index 00000000..27c89a93 --- /dev/null +++ b/vscode_multem/vscode_multem.code-workspace @@ -0,0 +1,20 @@ +{ + "folders": [ + { + "path": "../src" + }, + { + "path": "../mex_files_general" + }, + { + "path": "../mex_files_multem" + }, + { + "path": "../mex_files_test" + }, + { + "path": "." + } + ], + "settings": {} +}